use super::{
CLIChainOpts,
config::SignerConfig,
parse_addr,
};
use crate::{
ErrorVariant,
call_with_config,
};
use anyhow::Result;
use contract_extrinsics::{
resolve_h160,
url_to_string,
};
use ink_env::Environment;
use serde::Serialize;
use std::{
fmt::{
Debug,
Display,
},
str::FromStr,
};
use subxt::{
Config,
OnlineClient,
backend::{
legacy::LegacyRpcMethods,
rpc::RpcClient,
},
config::HashFor,
ext::{
codec::Decode,
scale_decode::IntoVisitor,
},
};
#[derive(Debug, clap::Args)]
#[clap(
name = "account",
about = "Map and unmap accounts, display info about addresses"
)]
pub struct AccountCommand {
#[clap(name = "addr", long, env = "ADDR")]
addr: Option<String>,
#[clap(long)]
output_json: bool,
#[clap(flatten)]
chain_cli_opts: CLIChainOpts,
}
impl AccountCommand {
pub async fn handle(&self) -> Result<(), ErrorVariant> {
call_with_config!(self, run, self.chain_cli_opts.chain().config())
}
async fn run<C: Config + Environment + SignerConfig<C>>(
&self,
) -> Result<(), ErrorVariant>
where
<C as Config>::AccountId:
Serialize + Display + IntoVisitor + Decode + AsRef<[u8]> + FromStr,
HashFor<C>: IntoVisitor + Display,
<C as Environment>::Balance: Serialize + Debug + IntoVisitor + Display,
<<C as Config>::AccountId as FromStr>::Err:
Into<Box<dyn std::error::Error>> + Display,
{
let rpc_cli =
RpcClient::from_url(url_to_string(&self.chain_cli_opts.chain().url()))
.await
.map_err(|e| subxt::Error::Rpc(e.into()))?;
let client = OnlineClient::<C>::from_rpc_client(rpc_cli.clone()).await?;
let rpc = LegacyRpcMethods::<C>::new(rpc_cli.clone());
let addr = self
.addr
.as_ref()
.map(|c| parse_addr(c))
.transpose()?
.expect("Contract argument shall be present");
let account_id = resolve_h160::<C, C>(&addr, &rpc, &client).await?;
let account_data =
contract_extrinsics::get_account_data::<C, C>(&account_id, &rpc, &client)
.await?;
if self.output_json {
let output = serde_json::json!({
"account_id": format!("0x{}", hex::encode(account_id)),
"free": account_data.free,
});
println!("{}", serde_json::to_string_pretty(&output)?);
} else {
println!("Account Id: {account_id}");
println!("Free Balance: {}", account_data.free);
}
Ok(())
}
}