diff --git a/Cargo.lock b/Cargo.lock index 1ddcc93e2..28ffe718f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -47,6 +47,18 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloy-ethers-typecast" +version = "0.2.0" +source = "git+https://github.com/rainlanguage/alloy-ethers-typecast?rev=d35a8e08ef240c4a66177f6de4e1de6fcb165b5f#d35a8e08ef240c4a66177f6de4e1de6fcb165b5f" +dependencies = [ + "alloy-primitives", + "anyhow", + "ethers", + "ethers-signers", + "log", +] + [[package]] name = "alloy-json-abi" version = "0.5.4" @@ -69,6 +81,7 @@ dependencies = [ "cfg-if", "const-hex", "derive_more", + "getrandom", "hex-literal", "itoa", "keccak-asm", @@ -2840,16 +2853,15 @@ dependencies = [ name = "rain_orderbook_cli" version = "0.0.4" dependencies = [ + "alloy-ethers-typecast", "alloy-primitives", "alloy-sol-types", "anyhow", "clap", - "ethers-signers", "graphql_client", "once_cell", "rain_orderbook_bindings", "rain_orderbook_subgraph_queries", - "rain_orderbook_transactions", "reqwest", "rust-bigint", "serde", @@ -2875,19 +2887,6 @@ dependencies = [ "tracing-subscriber", ] -[[package]] -name = "rain_orderbook_transactions" -version = "0.0.4" -dependencies = [ - "alloy-primitives", - "anyhow", - "ethers", - "ethers-signers", - "reqwest", - "tracing", - "url", -] - [[package]] name = "rand" version = "0.8.5" diff --git a/Cargo.toml b/Cargo.toml index 73d9ccf98..527fdadad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,4 @@ serde_bytes = "0.11.9" tokio = { version = "1.28.0", features = ["full"] } tracing = "0.1.37" tracing-subscriber = "0.3.17" -ethers = "2.0.7" -ethers-signers = { version = "2.0.8", features = ["ledger"] } url = "2.5.0" \ No newline at end of file diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 9d6daeb45..eca545941 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -11,7 +11,7 @@ homepage = "https://github.com/rainprotocol/rain.orderbook" [dependencies] rain_orderbook_subgraph_queries = { path = "../subgraph" } rain_orderbook_bindings = { path = "../bindings" } -rain_orderbook_transactions = { path = "../transaction" } +alloy-ethers-typecast = { git = "https://github.com/rainlanguage/alloy-ethers-typecast", rev = "d35a8e08ef240c4a66177f6de4e1de6fcb165b5f" } anyhow = "1.0.70" clap = { version = "4.2.5", features = ["cargo", "derive"] } graphql_client = "0.12.0" @@ -25,5 +25,4 @@ tracing = "0.1.37" tracing-subscriber = "0.3.17" alloy-primitives = "0.5.4" alloy-sol-types = { version = "0.5.4" } -ethers-signers = { version = "2.0.8", features = ["ledger"] } diff --git a/crates/cli/src/commands/deposit.rs b/crates/cli/src/commands/deposit.rs index f26e537d3..635428fa3 100644 --- a/crates/cli/src/commands/deposit.rs +++ b/crates/cli/src/commands/deposit.rs @@ -1,38 +1,46 @@ -use crate::transaction::TransactionArgs; -use alloy_primitives::{Address, U256}; +use crate::transaction::CliTransactionArgs; +use alloy_ethers_typecast::client::LedgerClient; +use alloy_ethers_typecast::request_shim::AlloyTransactionRequest; +use alloy_ethers_typecast::transaction::ExecutableTransaction; +use alloy_primitives::{Address, U256, U64}; use alloy_sol_types::SolCall; use anyhow::Result; use clap::Args; use clap::Parser; -use ethers_signers::{HDPath, Ledger}; use rain_orderbook_bindings::IOrderBookV3::depositCall; -use rain_orderbook_transactions::execute::execute_transaction; #[derive(Parser)] pub struct Deposit { #[clap(flatten)] deposit_args: DepositArgs, #[clap(flatten)] - transaction_args: TransactionArgs, + transaction_args: CliTransactionArgs, } impl Deposit { pub async fn execute(self) -> Result<()> { - let deposit_call = self.deposit_args.to_deposit_call()?; - let call_data = deposit_call.abi_encode(); - execute_transaction( - call_data, - self.transaction_args.orderbook_address.parse::
()?, - U256::from(0), - self.transaction_args.rpc_url, - Ledger::new( - HDPath::LedgerLive(self.transaction_args.derivation_path.unwrap_or(0)), - self.transaction_args.chain_id, - ) - .await?, - self.transaction_args.blocknative_api_key, + let call_data = self.deposit_args.to_deposit_call()?.abi_encode(); + + let tx = AlloyTransactionRequest::default() + .with_to(self.transaction_args.orderbook_address.parse::
()?) + .with_data(call_data.clone()) + .with_chain_id(U64::from(self.transaction_args.chain_id)); + + let ledger_client = LedgerClient::new( + self.transaction_args.derivation_path, + self.transaction_args.chain_id, + self.transaction_args.rpc_url.clone(), ) .await?; + + let transaction = + ExecutableTransaction::from_alloy_transaction_request(tx, ledger_client.client).await?; + + transaction + .execute() + .await + .map_err(|e| anyhow::anyhow!(e))?; + Ok(()) } } diff --git a/crates/cli/src/transaction.rs b/crates/cli/src/transaction.rs index 489e55fa8..61cca1447 100644 --- a/crates/cli/src/transaction.rs +++ b/crates/cli/src/transaction.rs @@ -1,7 +1,7 @@ use clap::Args; #[derive(Args)] -pub struct TransactionArgs { +pub struct CliTransactionArgs { #[arg(short, long, help = "Orderbook contract address")] pub orderbook_address: String, @@ -13,7 +13,4 @@ pub struct TransactionArgs { #[arg(short, long, help = "RPC URL")] pub rpc_url: String, - - #[arg(short, long, help = "Blocknative API Key")] - pub blocknative_api_key: Option, } diff --git a/crates/transaction/Cargo.toml b/crates/transaction/Cargo.toml deleted file mode 100644 index 8abeb87c3..000000000 --- a/crates/transaction/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "rain_orderbook_transactions" -version = "0.0.4" -edition = "2021" -license = "CAL-1.0" -description = "Rain Orderbook CLI." -homepage = "https://github.com/rainprotocol/rain.orderbook" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -ethers = "2.0.7" -ethers-signers = { version = "2.0.8", features = ["ledger"] } -url = "2.5.0" -reqwest = { version = "0.11.17", features = ["json"] } -anyhow = "1.0.70" -alloy-primitives = "0.5.4" -tracing = "0.1.37" diff --git a/crates/transaction/src/execute.rs b/crates/transaction/src/execute.rs deleted file mode 100644 index 77f86e617..000000000 --- a/crates/transaction/src/execute.rs +++ /dev/null @@ -1,76 +0,0 @@ -use alloy_primitives::{hex, Address, U256}; -use ethers::prelude::SignerMiddleware; -use ethers::types::TransactionReceipt; -use ethers::{ - providers::{Http, Middleware, Provider}, - types::{Eip1559TransactionRequest, H160, U64}, - utils::parse_units, -}; -use ethers_signers::Ledger; -use std::str::FromStr; -use tracing::{info, warn}; - -use crate::gasoracle::gas_price_oracle; - -/// Sign and submit transaction on chain via [Ledger] wallet. -/// -/// # Arguments -/// * `tx_data` - Abi encoded transaction data, encoded with the function selector. -/// * `tx_to` - [Eip1559TransactionRequest::to] -/// * `tx_value` - [Eip1559TransactionRequest::value] -/// * `rpc_url` - Network RPC -/// * `wallet` - [Ledger] wallet instance -/// * `blocknative_api_key` - Optional Blocknative API Key. -/// -pub async fn execute_transaction( - tx_data: Vec, - tx_to: Address, - tx_value: U256, - rpc_url: String, - wallet: Ledger, - blocknative_api_key: Option, -) -> anyhow::Result { - let provider = Provider::::try_from(rpc_url.clone())?; - - let chain_id = provider.clone().get_chainid().await.unwrap().as_u64(); - let client = SignerMiddleware::new_with_provider_chain(provider, wallet).await?; - - let to_address = H160::from_str(&tx_to.to_string()).unwrap(); - - let mut tx = Eip1559TransactionRequest::new(); - - tx.to = Some(to_address.into()); - tx.value = Some(ethers::types::U256::from_dec_str(tx_value.to_string().as_str()).unwrap()); - tx.data = Some(ethers::types::Bytes::from(tx_data)); - tx.chain_id = Some(U64::from_dec_str(&chain_id.to_string()).unwrap()); - - match gas_price_oracle(blocknative_api_key, chain_id).await { - Ok((max_priority, max_fee)) => { - let max_priority: ethers::types::U256 = - parse_units(max_priority.to_string(), 9).unwrap().into(); - let max_fee: ethers::types::U256 = parse_units(max_fee.to_string(), 9).unwrap().into(); - - tx.max_priority_fee_per_gas = Some(max_priority); - tx.max_fee_per_gas = Some(max_fee); - } - Err(_) => { - warn!("BLOCKNATIVE UNSUPPORTED NETWORK"); - } - }; - - let pending_tx = client.send_transaction(tx, None).await?; - - info!("Transaction submitted. Awaiting block confirmations..."); - let tx_confirmation = pending_tx.confirmations(1).await?; - - let tx_receipt = match tx_confirmation { - Some(receipt) => receipt, - None => return Err(anyhow::anyhow!("Transaction failed")), - }; - info!("Transaction Confirmed!!"); - info!( - "✅ Hash : 0x{}", - hex::encode(tx_receipt.transaction_hash.as_bytes()) - ); - Ok(tx_receipt) -} diff --git a/crates/transaction/src/gasoracle.rs b/crates/transaction/src/gasoracle.rs deleted file mode 100644 index b2d4dd64e..000000000 --- a/crates/transaction/src/gasoracle.rs +++ /dev/null @@ -1,32 +0,0 @@ -use ethers::middleware::gas_oracle::GasCategory; -use ethers::prelude::gas_oracle::blocknative::Response as BlockNativeResponse; -use reqwest::{header::AUTHORIZATION, Client}; -use url::Url; - -/// Bloacknative Base Url for fetching blockprices -static BLOCKNATIVE_BLOCKPRICES_URL: &str = "https://api.blocknative.com/gasprices/blockprices"; - -/// Blocknative Gas Oracle. -/// Returns max priority fee and max fee from blocknative api. -/// -/// # Arguments -/// * `api_key` - Optional blocknative api key. -/// * `chain_id` - Network Chain Id. -/// -pub async fn gas_price_oracle( - api_key: Option, - chain_id: u64, -) -> anyhow::Result<(f64, f64)> { - let client = Client::new(); - let mut url = Url::parse(BLOCKNATIVE_BLOCKPRICES_URL)?; - url.set_query(Some(format!("chainid={}", chain_id).as_str())); - let mut request = client.get(url); - if let Some(api_key) = api_key.as_ref() { - request = request.header(AUTHORIZATION, api_key); - } - let response: BlockNativeResponse = request.send().await?.error_for_status()?.json().await?; - let fastest = response - .estimate_from_category(&GasCategory::Fastest) - .unwrap(); - Ok((fastest.max_priority_fee_per_gas, fastest.max_fee_per_gas)) -} diff --git a/crates/transaction/src/lib.rs b/crates/transaction/src/lib.rs deleted file mode 100644 index 38b3a5d0b..000000000 --- a/crates/transaction/src/lib.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod execute; -pub mod gasoracle;