Skip to content

Commit

Permalink
executing txs by ledger
Browse files Browse the repository at this point in the history
  • Loading branch information
hardyjosh committed Jan 8, 2024
1 parent ddaf4ce commit 69969ea
Show file tree
Hide file tree
Showing 10 changed files with 2,369 additions and 81 deletions.
2,280 changes: 2,201 additions & 79 deletions Cargo.lock

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ serde = "1.0.160"
serde_bytes = "0.11.9"
tokio = { version = "1.28.0", features = ["full"] }
tracing = "0.1.37"
tracing-subscriber = "0.3.17"
tracing-subscriber = "0.3.17"
ethers = "2.0.7"
ethers-signers = { version = "2.0.8", features = ["ledger"] }
url = "2.5.0"
2 changes: 2 additions & 0 deletions crates/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +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" }
anyhow = "1.0.70"
clap = { version = "4.2.5", features = ["cargo", "derive"] }
graphql_client = "0.12.0"
Expand All @@ -24,4 +25,5 @@ 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"] }

15 changes: 14 additions & 1 deletion crates/cli/src/commands/deposit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,30 @@ use clap::Args;
use alloy_primitives::{U256, Address};
use rain_orderbook_bindings::IOrderBookV3::depositCall;
use alloy_sol_types::SolCall;
use rain_orderbook_transactions::execute::execute_transaction;
use crate::transaction::TransactionArgs;
use ethers_signers::{Ledger, HDPath};

#[derive(Parser)]
pub struct Deposit {
#[clap(flatten)]
deposit_args: DepositArgs
deposit_args: DepositArgs,
#[clap(flatten)]
transaction_args: TransactionArgs
}

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::<Address>()?,
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,
).await?;
Ok(())
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use clap::Subcommand;
use crate::commands::{Order, Deposit};

mod commands;
mod transaction;

#[derive(Subcommand)]
pub enum Orderbook {
Expand Down
19 changes: 19 additions & 0 deletions crates/cli/src/transaction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use clap::Args;

#[derive(Args)]
pub struct TransactionArgs {
#[arg(short, long, help = "Orderbook contract address")]
pub orderbook_address: String,

#[arg(short, long, help = "Derivation path of the Ledger wallet")]
pub derivation_path: Option<usize>,

#[arg(short, long, help = "Chain ID of the network")]
pub chain_id: u64,

#[arg(short, long, help = "RPC URL")]
pub rpc_url: String,

#[arg(short, long, help = "Blocknative API Key")]
pub blocknative_api_key: Option<String>,
}
18 changes: 18 additions & 0 deletions crates/transaction/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[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"
76 changes: 76 additions & 0 deletions crates/transaction/src/execute.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use alloy_primitives::{Address, U256, hex};
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<u8>,
tx_to: Address,
tx_value: U256,
rpc_url: String,
wallet: Ledger,
blocknative_api_key: Option<String>,
) -> anyhow::Result<TransactionReceipt> {
let provider = Provider::<Http>::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)
}
32 changes: 32 additions & 0 deletions crates/transaction/src/gasoracle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
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<String>,
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))
}
2 changes: 2 additions & 0 deletions crates/transaction/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod execute;
pub mod gasoracle;

0 comments on commit 69969ea

Please sign in to comment.