Skip to content

Commit

Permalink
feat(cast): adds support for gas, value, nonce for send cmd & value f…
Browse files Browse the repository at this point in the history
…or estimate cmd (gakonst#604)

* feat(cast): adds support for gas, value, nonce for send cmd & value for estimate cmd

* fix: spelling of -all

* fix: options for send + estimate cmd

* Apply suggestions from code review

Co-authored-by: Georgios Konstantopoulos <[email protected]>
  • Loading branch information
Janmajayamall and gakonst authored Jan 28, 2022
1 parent 28679a1 commit c1bb269
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 13 deletions.
38 changes: 31 additions & 7 deletions cast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ where
chain: Chain,
etherscan_api_key: Option<String>,
) -> Result<String> {
let (tx, func) = self.build_tx(from, to, Some(args), chain, etherscan_api_key).await?;
let (tx, func) = self.build_tx(from, to, Some(args), None, None, None, chain, etherscan_api_key).await?;
let tx = tx.into();
let res = self.provider.call(&tx, None).await?;

Expand Down Expand Up @@ -119,7 +119,7 @@ where
///
/// ```no_run
/// use cast::Cast;
/// use ethers_core::types::{Address, Chain};
/// use ethers_core::types::{Address, Chain, U256};
/// use ethers_providers::{Provider, Http};
/// use std::{str::FromStr, convert::TryFrom};
///
Expand All @@ -130,7 +130,10 @@ where
/// let to = Address::from_str("0xB3C95ff08316fb2F2e3E52Ee82F8e7b605Aa1304")?;
/// let sig = "greet(string)()";
/// let args = vec!["hello".to_owned()];
/// let data = cast.send(from, to, Some((sig, args)), Chain::Mainnet, None).await?;
/// let gas = U256::from_str("200000").unwrap();
/// let value = U256::from_str("1").unwrap();
/// let nonce = U256::from_str("1").unwrap();
/// let data = cast.send(from, to, Some((sig, args)), Some(gas), Some(value), Some(nonce), Chain::Mainnet, None).await?;
/// println!("{}", *data);
/// # Ok(())
/// # }
Expand All @@ -140,10 +143,14 @@ where
from: F,
to: T,
args: Option<(&str, Vec<String>)>,
gas: Option<U256>,
value: Option<U256>,
nonce: Option<U256>,
chain: Chain,
etherscan_api_key: Option<String>,
) -> Result<PendingTransaction<'_, M::Provider>> {
let (tx, _) = self.build_tx(from, to, args, chain, etherscan_api_key).await?;

let (tx, _) = self.build_tx(from, to, args, gas, value, nonce, chain, etherscan_api_key).await?;
let res = self.provider.send_transaction(tx, None).await?;

Ok::<_, eyre::Error>(res)
Expand Down Expand Up @@ -178,7 +185,7 @@ where
///
/// ```no_run
/// use cast::Cast;
/// use ethers_core::types::{Address, Chain};
/// use ethers_core::types::{Address, Chain, U256};
/// use ethers_providers::{Provider, Http};
/// use std::{str::FromStr, convert::TryFrom};
///
Expand All @@ -189,7 +196,8 @@ where
/// let to = Address::from_str("0xB3C95ff08316fb2F2e3E52Ee82F8e7b605Aa1304")?;
/// let sig = "greet(string)()";
/// let args = vec!["5".to_owned()];
/// let data = cast.estimate(from, to, Some((sig, args)), Chain::Mainnet, None).await?;
/// let value = U256::from_str("1").unwrap();
/// let data = cast.estimate(from, to, Some((sig, args)), Some(value), Chain::Mainnet, None).await?;
/// println!("{}", data);
/// # Ok(())
/// # }
Expand All @@ -199,10 +207,11 @@ where
from: F,
to: T,
args: Option<(&str, Vec<String>)>,
value: Option<U256>,
chain: Chain,
etherscan_api_key: Option<String>,
) -> Result<U256> {
let (tx, _) = self.build_tx(from, to, args, chain, etherscan_api_key).await?;
let (tx, _) = self.build_tx(from, to, args, None, value, None, chain, etherscan_api_key).await?;
let tx = tx.into();
let res = self.provider.estimate_gas(&tx).await?;

Expand All @@ -214,6 +223,9 @@ where
from: F,
to: T,
args: Option<(&str, Vec<String>)>,
gas: Option<U256>,
value: Option<U256>,
nonce: Option<U256>,
chain: Chain,
etherscan_api_key: Option<String>,
) -> Result<(TypedTransaction, Option<ethers_core::abi::Function>)> {
Expand Down Expand Up @@ -257,6 +269,18 @@ where
None
};

if let Some(gas) = gas {
tx = tx.gas(gas)
}

if let Some(value) = value {
tx = tx.value(value)
}

if let Some(nonce) = nonce {
tx = tx.nonce(nonce)
}

Ok((tx, func))
}

Expand Down
23 changes: 19 additions & 4 deletions cli/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ async fn main() -> eyre::Result<()> {
let provider = Provider::try_from(rpc_url)?;
println!("{}", Cast::new(&provider).transaction(hash, field, to_json).await?)
}
Subcommands::SendTx { eth, to, sig, cast_async, args } => {
Subcommands::SendTx { eth, to, sig, cast_async, args, gas, value, nonce } => {
let provider = Provider::try_from(eth.rpc_url()?)?;
let chain_id = Cast::new(&provider).chain_id().await?;

Expand All @@ -188,6 +188,9 @@ async fn main() -> eyre::Result<()> {
signer.address(),
to,
(sig, args),
gas,
value,
nonce,
eth.chain,
eth.etherscan_api_key,
cast_async,
Expand All @@ -200,6 +203,9 @@ async fn main() -> eyre::Result<()> {
signer.address(),
to,
(sig, args),
gas,
value,
nonce,
eth.chain,
eth.etherscan_api_key,
cast_async,
Expand All @@ -212,6 +218,9 @@ async fn main() -> eyre::Result<()> {
signer.address(),
to,
(sig, args),
gas,
value,
nonce,
eth.chain,
eth.etherscan_api_key,
cast_async,
Expand All @@ -226,6 +235,9 @@ async fn main() -> eyre::Result<()> {
from,
to,
(sig, args),
gas,
value,
nonce,
eth.chain,
eth.etherscan_api_key,
cast_async,
Expand All @@ -247,12 +259,12 @@ async fn main() -> eyre::Result<()> {
println!("Receipt: {:?}", receipt);
}
}
Subcommands::Estimate { eth, to, sig, args } => {
Subcommands::Estimate { eth, to, sig, args , value} => {
let provider = Provider::try_from(eth.rpc_url()?)?;
let cast = Cast::new(&provider);
let from = eth.sender().await;
let gas = cast
.estimate(from, to, Some((sig.as_str(), args)), eth.chain, eth.etherscan_api_key)
.estimate(from, to, Some((sig.as_str(), args)),value, eth.chain, eth.etherscan_api_key)
.await?;
println!("{}", gas);
}
Expand Down Expand Up @@ -564,6 +576,9 @@ async fn cast_send<M: Middleware, F: Into<NameOrAddress>, T: Into<NameOrAddress>
from: F,
to: T,
args: (String, Vec<String>),
gas: Option<U256>,
value: Option<U256>,
nonce: Option<U256>,
chain: Chain,
etherscan_api_key: Option<String>,
cast_async: bool,
Expand All @@ -576,7 +591,7 @@ where
let sig = args.0;
let params = args.1;
let params = if !sig.is_empty() { Some((&sig[..], params)) } else { None };
let pending_tx = cast.send(from, to, params, chain, etherscan_api_key).await?;
let pending_tx = cast.send(from, to, params, gas, value, nonce, chain, etherscan_api_key).await?;
let tx_hash = *pending_tx;

if cast_async {
Expand Down
10 changes: 9 additions & 1 deletion cli/src/opts/cast.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::{path::PathBuf, str::FromStr};

use clap::{Parser, Subcommand};
use ethers::types::{Address, BlockId, BlockNumber, NameOrAddress, H256};
use ethers::types::{Address, BlockId, BlockNumber, NameOrAddress, H256, U256};

use super::{ClapChain, EthereumOpts, Wallet};

Expand Down Expand Up @@ -147,6 +147,12 @@ pub enum Subcommands {
sig: String,
#[clap(help = "the list of arguments you want to call the function with")]
args: Vec<String>,
#[clap(long, help = "gas quantity for the transaction")]
gas: Option<U256>,
#[clap(long, help = "ether value (in wei) for the transaction")]
value: Option<U256>,
#[clap(long, help = "nonce for the transaction")]
nonce: Option<U256>,
#[clap(long, env = "CAST_ASYNC")]
cast_async: bool,
#[clap(flatten)]
Expand All @@ -171,6 +177,8 @@ pub enum Subcommands {
sig: String,
#[clap(help = "the list of arguments you want to call the function with")]
args: Vec<String>,
#[clap(long, help = "value for tx estimate (in wei)")]
value: Option<U256>,
#[clap(flatten)]
eth: EthereumOpts,
},
Expand Down
2 changes: 1 addition & 1 deletion cli/src/opts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ pub struct Wallet {
#[clap(long = "private-key", help = "Your private key string")]
pub private_key: Option<String>,

#[clap(long = "keystore", help = "Path to your keystore folder / file")]
#[clap(env = "ETH_KEYSTORE", long = "keystore", help = "Path to your keystore folder / file")]
pub keystore_path: Option<String>,

#[clap(long = "password", help = "Your keystore password", requires = "keystore-path")]
Expand Down

0 comments on commit c1bb269

Please sign in to comment.