Skip to content

Commit

Permalink
feat: add balance command
Browse files Browse the repository at this point in the history
  • Loading branch information
xJonathanLEI committed Aug 9, 2023
1 parent aed137a commit f0b8e3d
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 0 deletions.
1 change: 1 addition & 0 deletions book/src/ref/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Starkli offers the following commands:
- state-update
- transaction-receipt
- chain-id
- balance
- nonce
- storage
- class-hash-at
Expand Down
3 changes: 3 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ enum Subcommands {
TransactionReceipt(TransactionReceipt),
#[clap(about = "Get Starknet network ID")]
ChainId(ChainId),
#[clap(about = "Get native gas token (currently ETH) balance")]
Balance(Balance),
#[clap(about = "Get nonce for a certain contract")]
Nonce(Nonce),
#[clap(about = "Get storage value for a slot at a contract")]
Expand Down Expand Up @@ -135,6 +137,7 @@ async fn run_command(cli: Cli) -> Result<()> {
Subcommands::StateUpdate(cmd) => cmd.run().await,
Subcommands::TransactionReceipt(cmd) => cmd.run().await,
Subcommands::ChainId(cmd) => cmd.run().await,
Subcommands::Balance(cmd) => cmd.run().await,
Subcommands::Nonce(cmd) => cmd.run().await,
Subcommands::Storage(cmd) => cmd.run().await,
Subcommands::ClassHashAt(cmd) => cmd.run().await,
Expand Down
90 changes: 90 additions & 0 deletions src/subcommands/balance.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use std::sync::Arc;

use anyhow::Result;
use bigdecimal::BigDecimal;
use clap::Parser;
use num_bigint::{BigUint, ToBigInt};
use starknet::{
core::types::{BlockId, BlockTag, FieldElement, FunctionCall},
macros::selector,
providers::Provider,
};

use crate::{
address_book::AddressBookResolver, decode::FeltDecoder, verbosity::VerbosityArgs, ProviderArgs,
};

/// The default ETH address: 0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7.
const DEFAULT_ETH_ADDRESS: FieldElement = FieldElement::from_mont([
4380532846569209554,
17839402928228694863,
17240401758547432026,
418961398025637529,
]);

#[derive(Debug, Parser)]
pub struct Balance {
#[clap(flatten)]
provider: ProviderArgs,
#[clap(help = "Account address")]
account_address: String,
#[clap(
long,
conflicts_with = "hex",
help = "Display raw balance amount in integer"
)]
raw: bool,
#[clap(
long,
conflicts_with = "raw",
help = "Display balance amount in hexadecimal representation"
)]
hex: bool,
#[clap(flatten)]
verbosity: VerbosityArgs,
}

impl Balance {
pub async fn run(self) -> Result<()> {
self.verbosity.setup_logging();

let provider = Arc::new(self.provider.into_provider());
let felt_decoder = FeltDecoder::new(AddressBookResolver::new(provider.clone()));

let account_address = felt_decoder
.decode_single_with_addr_fallback(&self.account_address)
.await?;

let result = provider
.call(
FunctionCall {
contract_address: DEFAULT_ETH_ADDRESS,
entry_point_selector: selector!("balanceOf"),
calldata: vec![account_address],
},
BlockId::Tag(BlockTag::Pending),
)
.await?;

if result.len() != 2 {
anyhow::bail!("unexpected call result size: {}", result.len());
}

let low = BigUint::from_bytes_be(&result[0].to_bytes_be());
let high = BigUint::from_bytes_be(&result[1].to_bytes_be());

let raw_balance: BigUint = (high << 128) + low;

if self.raw {
println!("{}", raw_balance);
} else if self.hex {
println!("{:#x}", raw_balance);
} else {
// `to_bigint()` from `BigUint` always returns `Some`.
let balance_dec = BigDecimal::new(raw_balance.to_bigint().unwrap(), 18);
println!("{}", balance_dec);
}

Ok(())
}
}
3 changes: 3 additions & 0 deletions src/subcommands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ pub use class_at::ClassAt;
mod class_hash_at;
pub use class_hash_at::ClassHashAt;

mod balance;
pub use balance::Balance;

mod nonce;
pub use nonce::Nonce;

Expand Down

0 comments on commit f0b8e3d

Please sign in to comment.