Skip to content

Commit

Permalink
Add query wallet subcommand and query wallet balance CLI (#508)
Browse files Browse the repository at this point in the history
* Add query wallet subcommand and query wallet balancer CLI

* Add TODO to correctly parse ibc denom from str
  • Loading branch information
ljoss17 authored Dec 23, 2024
1 parent 17d9fdb commit 3e0c657
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 2 deletions.
80 changes: 80 additions & 0 deletions crates/cli/cli-components/src/impls/commands/queries/balance.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use core::fmt::Display;
use core::marker::PhantomData;

use cgp::prelude::*;
use hermes_relayer_components::build::traits::builders::chain_builder::CanBuildChain;
use hermes_relayer_components::chain::traits::types::chain_id::HasChainIdType;
use hermes_relayer_components::multi::types::index::Index;
use hermes_test_components::chain::traits::queries::balance::CanQueryBalance;

use crate::traits::build::CanLoadBuilder;
use crate::traits::command::CommandRunner;
use crate::traits::output::CanProduceOutput;
use crate::traits::parse::CanParseArg;

pub struct RunQueryBalanceCommand;

#[derive(Debug, clap::Parser, HasField)]
pub struct QueryBalanceArgs {
#[clap(
long = "chain",
required = true,
value_name = "CHAIN_ID",
help_heading = "REQUIRED",
help = "Identifier of the chain to query"
)]
chain_id: String,

#[clap(
long = "address",
required = true,
value_name = "ADDRESS",
help_heading = "REQUIRED",
help = "Wallet address to query for balance"
)]
address: String,

#[clap(
long = "denom",
required = true,
value_name = "DENOM",
help_heading = "REQUIRED",
help = "Token denom queried"
)]
denom: String,
}

impl<App, Args, Build, Chain> CommandRunner<App, Args> for RunQueryBalanceCommand
where
App: CanLoadBuilder<Builder = Build>
+ CanProduceOutput<Chain::Amount>
+ CanParseArg<Args, symbol!("chain_id"), Parsed = Chain::ChainId>
+ CanParseArg<Args, symbol!("address"), Parsed = Chain::Address>
+ CanParseArg<Args, symbol!("denom"), Parsed = Chain::Denom>
+ CanRaiseError<Build::Error>
+ CanRaiseError<Chain::Error>,
Build: CanBuildChain<Index<0>, Chain = Chain>,
Chain: HasChainIdType + CanQueryBalance,
Args: Async,
Chain::Amount: Display,
{
async fn run_command(app: &App, args: &Args) -> Result<App::Output, App::Error> {
let chain_id = app.parse_arg(args, PhantomData::<symbol!("chain_id")>)?;
let address = app.parse_arg(args, PhantomData::<symbol!("address")>)?;
let denom = app.parse_arg(args, PhantomData::<symbol!("denom")>)?;

let builder = app.load_builder().await?;

let chain = builder
.build_chain(PhantomData, &chain_id)
.await
.map_err(App::raise_error)?;

let balance = chain
.query_balance(&address, &denom)
.await
.map_err(App::raise_error)?;

Ok(app.produce_output(balance))
}
}
2 changes: 2 additions & 0 deletions crates/cli/cli-components/src/impls/commands/queries/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod balance;
pub mod chain;
pub mod chain_status;
pub mod client;
Expand All @@ -6,3 +7,4 @@ pub mod client_status;
pub mod connection;
pub mod connection_end;
pub mod consensus_state;
pub mod wallet;
24 changes: 24 additions & 0 deletions crates/cli/cli-components/src/impls/commands/queries/wallet.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use crate::impls::commands::queries::balance::QueryBalanceArgs;
use crate::traits::command::{CanRunCommand, CommandRunner};

pub struct RunQueryWalletSubCommand;

#[derive(Debug, clap::Subcommand)]
pub enum QueryWalletSubCommand {
/// Query wallet balance
Balance(QueryBalanceArgs),
}

impl<App> CommandRunner<App, QueryWalletSubCommand> for RunQueryWalletSubCommand
where
App: CanRunCommand<QueryBalanceArgs>,
{
async fn run_command(
app: &App,
subcommand: &QueryWalletSubCommand,
) -> Result<App::Output, App::Error> {
match subcommand {
QueryWalletSubCommand::Balance(args) => app.run_command(args).await,
}
}
}
6 changes: 6 additions & 0 deletions crates/cli/cli/src/commands/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ mod packet;
use hermes_cli_components::impls::commands::queries::chain::QueryChainSubCommand;
use hermes_cli_components::impls::commands::queries::client::QueryClientSubCommand;
use hermes_cli_components::impls::commands::queries::connection::QueryConnectionSubCommand;
use hermes_cli_components::impls::commands::queries::wallet::QueryWalletSubCommand;
use hermes_cli_components::traits::command::CanRunCommand;
use hermes_cli_framework::command::CommandRunner;
use hermes_cli_framework::output::Output;
Expand All @@ -34,6 +35,10 @@ pub enum QueryCommands {
/// Query all channels
Channels(QueryChannels),

/// Query information about wallet balance
#[clap(subcommand)]
Wallet(QueryWalletSubCommand),

/// Query information about chains
#[clap(subcommand)]
Chain(QueryChainSubCommand),
Expand All @@ -58,6 +63,7 @@ pub enum QueryCommands {
impl CommandRunner<HermesApp> for QueryCommands {
async fn run(&self, app: &HermesApp) -> Result<Output> {
match self {
Self::Wallet(cmd) => app.run_command(cmd).await,
Self::Chain(cmd) => app.run_command(cmd).await,
Self::Client(cmd) => app.run_command(cmd).await,
Self::Clients(cmd) => cmd.run(app).await,
Expand Down
15 changes: 15 additions & 0 deletions crates/cli/cli/src/contexts/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ use hermes_cli_components::impls::commands::client::create::{
use hermes_cli_components::impls::commands::client::update::{
RunUpdateClientCommand, UpdateClientArgs,
};
use hermes_cli_components::impls::commands::queries::balance::{
QueryBalanceArgs, RunQueryBalanceCommand,
};
use hermes_cli_components::impls::commands::queries::chain::{
QueryChainSubCommand, RunQueryChainSubCommand,
};
Expand All @@ -38,6 +41,9 @@ use hermes_cli_components::impls::commands::queries::connection_end::{
use hermes_cli_components::impls::commands::queries::consensus_state::{
QueryConsensusStateArgs, RunQueryConsensusStateCommand,
};
use hermes_cli_components::impls::commands::queries::wallet::{
QueryWalletSubCommand, RunQueryWalletSubCommand,
};
use hermes_cli_components::impls::commands::start::{RunStartRelayerCommand, StartRelayerArgs};
use hermes_cli_components::impls::config::get_config_path::GetDefaultConfigField;
use hermes_cli_components::impls::config::load_toml_config::LoadTomlConfig;
Expand All @@ -63,6 +69,7 @@ use hermes_cosmos_chain_components::types::payloads::client::CosmosCreateClientO
use hermes_cosmos_integration_tests::contexts::bootstrap::CosmosBootstrap;
use hermes_cosmos_relayer::contexts::build::CosmosBuilder;
use hermes_cosmos_relayer::contexts::chain::CosmosChain;
use hermes_cosmos_test_components::chain::types::denom::Denom;
use hermes_error::traits::wrap::WrapError;
use hermes_error::types::{Error, HermesError};
use hermes_logger::ProvideHermesLogger;
Expand Down Expand Up @@ -157,6 +164,10 @@ delegate_components! {

(QueryChainStatusArgs, symbol!("chain_id")): ParseFromString<ChainId>,

(QueryBalanceArgs, symbol!("chain_id")): ParseFromString<ChainId>,
(QueryBalanceArgs, symbol!("address")): ParseFromString<String>,
(QueryBalanceArgs, symbol!("denom")): ParseFromString<Denom>,

(StartRelayerArgs, symbol!("chain_id_a")): ParseFromString<ChainId>,
(StartRelayerArgs, symbol!("client_id_a")): ParseFromString<ClientId>,
(StartRelayerArgs, symbol!("chain_id_b")): ParseFromString<ChainId>,
Expand Down Expand Up @@ -195,6 +206,9 @@ delegate_components! {

QueryConnectionSubCommand: RunQueryConnectionSubCommand,
QueryConnectionEndArgs: RunQueryConnectionEndCommand,

QueryWalletSubCommand: RunQueryWalletSubCommand,
QueryBalanceArgs: RunQueryBalanceCommand,
}
}

Expand Down Expand Up @@ -256,6 +270,7 @@ pub trait CanUseHermesApp:
+ CanRunCommand<QueryConsensusStateArgs>
+ CanRunCommand<QueryClientStatusArgs>
+ CanRunCommand<QueryChainStatusArgs>
+ CanRunCommand<QueryBalanceArgs>
+ CanRunCommand<CreateClientArgs>
+ CanRunCommand<UpdateClientArgs>
+ CanRunCommand<BootstrapChainArgs>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use core::cmp::Ordering;
use core::fmt::{self, Display};

use serde::Serialize;

use crate::chain::types::denom::Denom;

#[derive(Debug, PartialEq, Eq, Clone)]
#[derive(Debug, PartialEq, Eq, Clone, Serialize)]
pub struct Amount {
pub quantity: u128,
pub denom: Denom,
Expand Down
23 changes: 22 additions & 1 deletion crates/cosmos/cosmos-test-components/src/chain/types/denom.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use core::fmt::{self, Display};
use std::str::FromStr;

#[derive(Debug, Clone)]
use serde::Serialize;

#[derive(Debug, Clone, Serialize)]
pub enum Denom {
Base(String),
Ibc {
Expand All @@ -23,6 +26,24 @@ impl Display for Denom {
}
}

impl FromStr for Denom {
type Err = String;

// TODO: Correctly parse Ibc denom
fn from_str(s: &str) -> Result<Self, Self::Err> {
if let Some(index) = s.find('/') {
let (before, after) = s.split_at(index);
Ok(Denom::Ibc {
path: before.to_owned(),
denom: "TBD".to_owned(),
hashed: after[1..].to_owned(),
})
} else {
Ok(Denom::Base(s.to_string()))
}
}
}

impl Denom {
pub fn base(denom: &str) -> Self {
Denom::Base(denom.to_string())
Expand Down

0 comments on commit 3e0c657

Please sign in to comment.