diff --git a/README.md b/README.md index 640f0fda244b6a4f0c530e647fa4953deb763a30..a23d0ff8507f18acd066b1825cebfd2046cfdebe 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,10 @@ CLI client for [Duniter-V2S](https://git.duniter.org/nodes/rust/duniter-v2s/). +Using +- https://github.com/duniter/substrate +- https://github.com/duniter/subxt + ## Usage If using a different runtime, update the metadata for the client to compile: diff --git a/res/metadata.scale b/res/metadata.scale index 3ec2c111f3089edbf7b193d08cddc0ea353bec76..d7c41820b07a0a2e6198009041d239e70602a2d9 100644 Binary files a/res/metadata.scale and b/res/metadata.scale differ diff --git a/src/commands/transfer.rs b/src/commands/transfer.rs index 65c3b854a01f3165f638e572891699d992adf23e..82ea9e1c1bb287c01d8ade8969733ea8275bfefd 100644 --- a/src/commands/transfer.rs +++ b/src/commands/transfer.rs @@ -4,6 +4,9 @@ use anyhow::Result; use sp_core::{crypto::AccountId32, sr25519::Pair}; use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner}; +type Call = gdev::runtime_types::gdev_runtime::Call; +type BalancesCall = gdev::runtime_types::pallet_balances::pallet::Call; + pub async fn transfer( pair: Pair, client: Client, @@ -35,3 +38,33 @@ pub async fn transfer( Ok(()) } + +pub async fn transfer_multiple( + pair: Pair, + client: Client, + amount: u64, + dests: Vec<AccountId32>, +) -> Result<()> { + // build the list of transactions from the destination accounts + let transactions: Vec<Call> = dests + .into_iter() + .map(|dest| { + Call::Balances(BalancesCall::transfer_keep_alive { + dest: dest.into(), + value: amount, + }) + }) + .collect(); + + // wrap these calls in a batch call + client + .tx() + .sign_and_submit_then_watch( + &gdev::tx().utility().batch(transactions), + &PairSigner::new(pair.clone()), + BaseExtrinsicParamsBuilder::new(), + ) + .await?; + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index ac32f55bbf02ab262688606df23dce41225bbc45..c8e3cc9bbb1fdf3995dba5ad4d13b9c927337f02 100644 --- a/src/main.rs +++ b/src/main.rs @@ -127,11 +127,22 @@ pub enum Subcommand { new_key: sp_core::crypto::AccountId32, }, Transfer { - balance: u64, + /// Amount to transfer + amount: u64, + /// Destination address dest: sp_core::crypto::AccountId32, - #[clap(short = 'k')] + /// Prevent from going below account existential deposit + #[clap(short = 'k', long = "keep-alive")] keep_alive: bool, }, + /// Transfer the same amount for each space-separated address. + /// If an address appears mutiple times, it will get multiple times the same amount + TransferMultiple { + /// Amount given to each destination address + amount: u64, + /// List of target addresses + dests: Vec<sp_core::crypto::AccountId32>, + }, /// Rotate and set session keys UpdateKeys, } @@ -174,7 +185,7 @@ async fn main() -> Result<()> { println!("Account address: {}", account_id); } - let client = Client::new().await.unwrap(); + let client = Client::new().await?; if let Some(account_id) = &account_id { let account = client @@ -272,19 +283,28 @@ async fn main() -> Result<()> { .await? } Subcommand::Transfer { - balance, + amount, dest, keep_alive, } => { commands::transfer::transfer( pair.expect("This subcommand needs a secret."), client, - balance, + amount, dest, keep_alive, ) .await? } + Subcommand::TransferMultiple { amount, dests } => { + commands::transfer::transfer_multiple( + pair.expect("This subcommand needs a secret."), + client, + amount, + dests, + ) + .await? + } Subcommand::UpdateKeys => commands::smith::update_session_keys( pair.expect("This subcommand needs a secret."), client,