Skip to content

Commit

Permalink
feat: hd wallet generation, token deceimal types
Browse files Browse the repository at this point in the history
feat: id proof, estimate gas, allocate, get allocation
  • Loading branch information
hopeyen committed Jan 5, 2024
1 parent 9e1852e commit ae344d2
Show file tree
Hide file tree
Showing 11 changed files with 698 additions and 80 deletions.
39 changes: 36 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion docs/client_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ After determining the subfile CID, client should supply a local path for writing
--free-query-auth-token 'Bearer imfreeee' \
--mnemonic "sheriff obscure trick beauty army fat wink legal flee leader section suit" \
--chain-id 421614 \
--verifier 0xfC24cE7a4428A6B89B52645243662A02BA734ECF
--verifier 0xfC24cE7a4428A6B89B52645243662A02BA734ECF \
--provider [arbitrum-sepolia-rpc-endpoint]
```


Expand Down
4 changes: 3 additions & 1 deletion subfile-exchange/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ path = "src/main.rs"
alloy-sol-types = { version = "0.5.0", features = ["eip712-serde"] }
alloy-primitives = { version = "0.5.0", features = ["serde"] }
anyhow = "1.0"
bs58 = "0.5.0"
base64 = "0.21"
build-info = "0.0.34"
bytes = "1.0"
Expand All @@ -28,6 +29,7 @@ ethers = "2.0.11"
# ethers = {version = "2.0.11", features = [ "abigen-online" ]}
ethers-core = "2.0.11"
futures = { version = "0.3", features = ["compat"] }
hdwallet = "0.4.1"
hex = "0.4.3"
http = "0.2"
hyper = { version = "0.14.27", features = [ "server" ]}
Expand All @@ -43,7 +45,7 @@ secp256k1 = "0.28.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_yaml = "0.9"
sha2 = "0.10.8"
sha2 = "0.10"
tap_core = { version = "0.7.0", git = "https://github.com/semiotic-ai/timeline-aggregation-protocol" }
tempfile = "3.2.0"
tokio = { version = "1.28", features = ["time", "sync", "macros", "test-util", "rt-multi-thread"] }
Expand Down
67 changes: 35 additions & 32 deletions subfile-exchange/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use tracing::subscriber::SetGlobalDefaultError;
use tracing_subscriber::EnvFilter;
use tracing_subscriber::FmtSubscriber;

use crate::util::parse_key;

#[derive(Clone, Debug, Parser, Serialize, Deserialize)]
#[command(
name = "subfile-exchange",
Expand Down Expand Up @@ -51,67 +53,68 @@ impl Cli {
pub enum Role {
Downloader(DownloaderArgs),
Publisher(PublisherArgs),
Server(ServerArgs),
Wallet(WalletArgs),
}

#[derive(Clone, Debug, Args, Serialize, Deserialize, Default)]
#[group(required = false, multiple = true)]
pub struct ServerArgs {
pub struct WalletArgs {
#[arg(
long,
value_name = "HOST",
default_value = "127.0.0.1",
env = "HOST",
help = "Subfile server host"
)]
pub host: String,
pub host: Option<String>,
#[arg(
long,
value_name = "PORT",
default_value = "5678",
env = "PORT",
help = "Subfile server port"
)]
pub port: usize,
// Taking from config right now, later can read from DB table for managing server states
#[arg(
long,
value_name = "SUBFILES",
env = "SUBFILES",
value_delimiter = ',',
help = "Comma separated list of IPFS hashes and local location of the subfiles to serve upon start-up; format: [ipfs_hash:local_path]"
)]
pub subfiles: Vec<String>,
pub port: Option<usize>,
#[clap(
long,
value_name = "free-query-auth-token",
env = "FREE_QUERY_AUTH_TOKEN",
help = "Auth token that clients can use to query for free"
value_name = "KEY",
value_parser = parse_key,
env = "PRIVATE_KEY",
hide_env_values = true,
help = "Private key to the Graphcast ID wallet (Precendence over mnemonics)",
)]
pub free_query_auth_token: Option<String>,
pub private_key: Option<String>,
#[clap(
long,
value_name = "admin-auth-token",
env = "ADMIN_AUTH_TOKEN",
help = "Admin Auth token for server management"
value_name = "KEY",
value_parser = parse_key,
env = "MNEMONIC",
hide_env_values = true,
help = "Mnemonic to the Graphcast ID wallet (first address of the wallet is used; Only one of private key or mnemonic is needed)",
)]
pub admin_auth_token: Option<String>,
pub mnemonic: Option<String>,
#[clap(
long,
value_name = "mnemonic",
env = "MNEMONIC",
help = "Mnemonic for the operator wallet"
value_name = "provider_url",
env = "PROVIDER",
help = "Blockchain provider endpoint"
)]
pub mnemonic: String,
//TODO: More complex price management
#[arg(
pub provider: String,
//TODO: chain id should be resolvable through provider
// #[clap(
// long,
// value_name = "chain_id",
// env = "CHAIN_ID",
// help = "Protocol network's Chain ID"
// )]
// pub chain_id: u64,
#[clap(
long,
value_name = "PRICE_PER_BYTE",
default_value = "1",
env = "PRICE_PER_BYTE",
help = "Price per byte; price do not currently have a unit, perhaps use DAI or GRT, refer to TAP"
value_name = "verifier",
env = "VERIFIER",
help = "TAP verifier contract address"
)]
pub price_per_byte: f32,
pub verifier: Option<String>,
}

#[derive(Clone, Debug, Args, Serialize, Deserialize, Default)]
Expand Down
2 changes: 2 additions & 0 deletions subfile-exchange/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub enum Error {
InvalidPriceFormat(String),
ContractError(String),
ObjectStoreError(object_store::Error),
WalletError(ethers::signers::WalletError),
}

impl fmt::Display for Error {
Expand All @@ -35,6 +36,7 @@ impl fmt::Display for Error {
Error::InvalidPriceFormat(ref msg) => write!(f, "Price format error: {}", msg),
Error::ContractError(ref msg) => write!(f, "Contract call error: {}", msg),
Error::ObjectStoreError(ref err) => write!(f, "Object store error: {}", err),
Error::WalletError(ref err) => write!(f, "Wallet error: {}", err),
}
}
}
Expand Down
18 changes: 15 additions & 3 deletions subfile-exchange/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,23 @@ async fn main() {
}
}
}
Role::Server(server_args) => {
Role::Wallet(wallet_args) => {
tracing::info!(
server = tracing::field::debug(&server_args),
"Use subfile-service crate"
server = tracing::field::debug(&wallet_args),
"Use the provided wallet to send transactions"
);

// Server enable payments through the staking contract,
// assume indexer is already registered on the staking registry contract
//1. `allocate` - indexer address, Qm hash in bytes32, token amount, allocation_id, metadata: utils.hexlify(Array(32).fill(0)), allocation_id_proof
//2. `close_allocate` -allocationID: String, poi: BytesLike (0x0 32bytes)
//3. `close_allocate` and then `allocate`
// receipt validation and storage is handled by the indexer-service framework
// receipt redemption is handled by indexer-agent

// Client payments - assume client signer is valid (should work without gateways)
//1. `deposit` - to a sender address and an amount
//2. `depositMany` - to Vec<sender address, an amount>
}
}
}
12 changes: 6 additions & 6 deletions subfile-exchange/src/subfile_client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ impl SubfileDownloader {
.expect("Read subfile");

let wallet = build_wallet(&args.mnemonic).expect("Mnemonic build wallet");
//TODO: Factor away from client, Transactions could be a separate entity
let transaction_manager = TransactionManager::new(&args.provider, wallet.clone()).await;
tracing::info!(
transaction_manager = tracing::field::debug(&transaction_manager),
"transaction_manager"
);
let signing_key = wallet.signer().to_bytes();
let secp256k1_private_key =
SecretKey::from_slice(&signing_key).expect("Private key from wallet");
Expand All @@ -67,12 +73,6 @@ impl SubfileDownloader {
)
.await;

//TODO: Factor away from client, Transactions could be a separate entity
let transaction_manager = TransactionManager::new(&args.provider, wallet.clone()).await;
tracing::info!(
transaction_manager = tracing::field::debug(&transaction_manager),
"transaction_manager"
);

SubfileDownloader {
http_client: reqwest::Client::new(),
Expand Down
34 changes: 10 additions & 24 deletions subfile-exchange/src/transaction_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ use std::fs;
use std::str::FromStr;
use std::sync::Arc;

use crate::errors::Error;
pub mod staking;

/// Contracts: (contract name, contract object)
pub type NetworkContracts =
HashMap<String, Contract<SignerMiddleware<Provider<Http>, Wallet<SigningKey>>>>;
HashMap<String, ContractClient>;
/// Contracts: (contract name, contract address)
pub type ContractAddresses = HashMap<String, H160>;
/// Client with provider endpoint and a wallet
pub type ContractClient = SignerMiddleware<Provider<Http>, Wallet<SigningKey>>;

#[derive(Debug)]
Expand All @@ -22,26 +25,6 @@ pub struct TransactionManager {
contracts: NetworkContracts,
}

abigen!(
L2Staking,
"abis/L2Staking.json",
// "npm:@graphprotocol/contracts@latest/dist/abis/L2Staking.json",
event_derives(serde::Deserialize, serde::Serialize)
);

/// Test function to simply call a read fn of a contract
async fn controller(client: &ContractClient, contract_addr: H160) -> Result<H160, Error> {
let contract = L2Staking::new(contract_addr, Arc::new(client.clone()));

let value = contract
.controller()
.call()
.await
.map_err(|e| Error::ContractError(e.to_string()))?;

Ok(value)
}

impl TransactionManager {
// Constructor to create a new instance
pub async fn new(
Expand All @@ -59,12 +42,15 @@ impl TransactionManager {
// Initiate contract instances
let contracts = NetworkContracts::new();
// Test reading the function
let _ = controller(&client, *contract_addresses.get("L2Staking").unwrap()).await?;

let value = staking::controller(&client, *contract_addresses.get("L2Staking").unwrap()).await?;
println!("controller value: {:#?}", value);
let value = staking::allocate(&client, *contract_addresses.get("L2Staking").unwrap()).await?;
println!("allocate value: {:#?}", value);
Ok(TransactionManager { client, contracts })
}
}

/// Track network contract addresses given an address book in json
fn network_contract_addresses(
file_path: &str,
chain_id: &str,
Expand Down
Loading

0 comments on commit ae344d2

Please sign in to comment.