Skip to content
Snippets Groups Projects
Commit 8b2da794 authored by Hugo Trentesaux's avatar Hugo Trentesaux Committed by Hugo Trentesaux
Browse files

move account commands to subcommand

parent f3407daa
No related branches found
No related tags found
No related merge requests found
......@@ -16,11 +16,11 @@ If using a different runtime, update the metadata for the client to compile:
Send 10 ĞD from Alice to Ferdie:
cargo run -- --url ws://localhost:9944 --secret //Alice transfer 1000 5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL
cargo run -- --url ws://localhost:9944 --secret //Alice account transfer 1000 5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL
List certifications and session keys that will expire within one month:
cargo run -- --url wss://gdev.p2p.legal:443/ws expire --blocks 432000
cargo run -- --url wss://gdev.p2p.legal:443/ws smith expire --blocks 432000
For more examples see [in the example file](./doc/example.md).
......@@ -55,8 +55,8 @@ Now the command `duniter-rpc` will open an SSH session and a bridge to your RPC
When your node is ready to forge blocks, rotate keys and go online:
```bash
gcli --secret "my secret phrase" update-keys
gcli --secret "my secret phrase" go-online
gcli --secret "my secret phrase" smith update-keys
gcli --secret "my secret phrase" smith go-online
```
### Keys
......
......@@ -42,11 +42,9 @@ gcli --network gdev config save
# get duniter current block
gcli current-block
# get balance of test1 account
gcli --address 5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa balance
gcli --address 5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa account balance
# get information about test1 identity (needs indexer)
gcli identity get --username test1
# show address of given secret
gcli --secret "pipe paddle ketchup filter life ice feel embody glide quantum ride usage"//2 show-address
```
## Indexer commands
......
use crate::indexer::*;
use crate::*;
use anyhow::{anyhow, Result};
use std::collections::{hash_map, HashMap};
pub struct IdentityCache {
......@@ -23,7 +22,7 @@ impl IdentityCache {
&mut self,
identity_id: u32,
parent_hash: sp_core::H256,
) -> Result<String> {
) -> anyhow::Result<String> {
Ok(match self.identities.entry(identity_id) {
hash_map::Entry::Occupied(entry) => entry.get().clone(),
hash_map::Entry::Vacant(entry) => entry
......
use crate::*;
/// define account subcommands
#[derive(Clone, Default, Debug, clap::Parser)]
pub enum Subcommand {
/// Fetch account balance
#[default]
Balance,
/// Transfer some currency to an account
Transfer {
/// Amount to transfer
amount: u64,
/// Destination address
dest: AccountId,
/// 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<AccountId>,
},
}
/// handle account commands
pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<()> {
let mut data = data.build_client().await?.build_indexer().await?;
match command {
Subcommand::Balance => {
data = data
.build_address()
.fetch_system_properties()
.await?;
commands::account::get_balance(data).await?
}
Subcommand::Transfer {
amount,
dest,
keep_alive,
} => {
data = data.build_client().await?;
commands::transfer::transfer(
&data,
amount,
dest,
keep_alive,
)
.await?;
}
Subcommand::TransferMultiple { amount, dests } => {
data = data.build_client().await?;
commands::transfer::transfer_multiple(&data,
amount,
dests,
)
.await?;
}
};
Ok(())
}
/// get balance
pub async fn get_balance(data: Data) -> Result<(), anyhow::Error> {
let account_id = data.address();
......
use crate::*;
use anyhow::Result;
use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner};
/// define technical committee subcommands
#[derive(Clone, Default, Debug, clap::Parser)]
......
use crate::*;
use anyhow::Result;
use futures::join;
use std::collections::BTreeMap;
pub async fn monitor_expirations(data: &Data, blocks: u32, sessions: u32) -> Result<()> {
pub async fn monitor_expirations(data: &Data, blocks: u32, sessions: u32) -> anyhow::Result<()> {
let client = data.client();
let indexer = data.indexer.clone();
......
......@@ -5,7 +5,6 @@ use crate::runtime::runtime_types::common_runtime::entities::IdtyData;
use crate::runtime::runtime_types::pallet_identity::types::*;
use crate::runtime::runtime_types::sp_core::sr25519::Signature;
use crate::runtime::runtime_types::sp_runtime::MultiSignature;
use sp_core::{crypto::AccountId32, sr25519::Pair};
use std::str::FromStr;
/// define identity subcommands
......@@ -84,7 +83,7 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<(
/// get identity
pub async fn get_identity(
data: &Data,
mut account_id: Option<AccountId32>,
mut account_id: Option<AccountId>,
mut identity_id: Option<u32>,
mut username: Option<String>,
) -> Result<(), anyhow::Error> {
......@@ -107,7 +106,7 @@ pub async fn get_identity(
))?;
if let Some(pubkey) = indexer.pubkey_by_username(username).await? {
// convert string to accountid
let fetched_account_id = AccountId32::from_str(&pubkey).map_err(|e| anyhow!(e))?;
let fetched_account_id = AccountId::from_str(&pubkey).map_err(|e| anyhow!(e))?;
// in the future, also ask indexer the identity index
identity_id = get_idty_index_by_account_id(client, &fetched_account_id).await?;
account_id = Some(fetched_account_id);
......@@ -127,7 +126,7 @@ pub async fn get_identity(
"Account id: {}",
account_id
.as_ref()
.map_or(String::new(), AccountId32::to_string)
.map_or(String::new(), AccountId::to_string)
);
println!(
"Identity id: {}",
......@@ -145,7 +144,7 @@ pub async fn get_identity(
/// get identity index by account id
pub async fn get_idty_index_by_account_id(
client: &Client,
account_id: &AccountId32,
account_id: &AccountId,
) -> Result<Option<u32>, anyhow::Error> {
Ok(client
.storage()
......@@ -160,7 +159,7 @@ pub async fn get_idty_index_by_account_id(
pub async fn get_identity_by_index(
client: &Client,
idty_index: u32,
) -> Result<Option<IdtyValue<u32, AccountId32, IdtyData>>, anyhow::Error> {
) -> Result<Option<IdtyValue<u32, AccountId, IdtyData>>, anyhow::Error> {
Ok(client
.storage()
.fetch(&runtime::storage().identity().identities(idty_index), None)
......@@ -171,7 +170,7 @@ pub async fn get_identity_by_index(
pub async fn create_identity(
pair: Pair,
client: &Client,
target: AccountId32,
target: AccountId,
) -> Result<(), subxt::Error> {
let progress = client
.tx()
......
use crate::*;
use anyhow::{anyhow, Result};
use sp_core::{crypto::AccountId32, sr25519::Pair, DeriveJunction, Pair as _};
use subxt::{
ext::sp_runtime::MultiAddress,
tx::{BaseExtrinsicParamsBuilder, PairSigner},
};
use sp_core::DeriveJunction;
use subxt::ext::sp_runtime::MultiAddress;
pub async fn repart(
pair: Pair,
client: &Client,
target: u32,
actual_repart: Option<u32>,
) -> Result<()> {
) -> anyhow::Result<()> {
let mut pairs = Vec::new();
for i in actual_repart.unwrap_or_default()..target {
let pair_i = pair
......@@ -48,9 +44,9 @@ pub async fn repart(
Ok(())
}
pub async fn spam_roll(pair: Pair, client: &Client, actual_repart: usize) -> Result<()> {
pub async fn spam_roll(pair: Pair, client: &Client, actual_repart: usize) -> anyhow::Result<()> {
let mut nonce = 0;
let mut pairs = Vec::<(PairSigner<Runtime, Pair>, AccountId32)>::with_capacity(actual_repart);
let mut pairs = Vec::<(PairSigner<Runtime, Pair>, AccountId)>::with_capacity(actual_repart);
for i in 0..actual_repart {
let pair_i = pair
.derive(std::iter::once(DeriveJunction::hard::<u32>(i as u32)), None)
......@@ -63,7 +59,7 @@ pub async fn spam_roll(pair: Pair, client: &Client, actual_repart: usize) -> Res
loop {
let mut watchers = Vec::with_capacity(actual_repart);
for i in 0..(actual_repart - 1) {
let dest: AccountId32 = pairs[i + 1].1.clone();
let dest: AccountId = pairs[i + 1].1.clone();
let watcher = client
.tx()
.create_signed_with_nonce(
......@@ -78,7 +74,7 @@ pub async fn spam_roll(pair: Pair, client: &Client, actual_repart: usize) -> Res
log::info!("send 1 cent from //{} to //{}", i, i + 1);
watchers.push(watcher);
}
let dest: AccountId32 = pairs[0].1.clone();
let dest: AccountId = pairs[0].1.clone();
let watcher = client
.tx()
.sign_and_submit_then_watch(
......
use crate::*;
use std::ops::Deref;
use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner};
type SessionKeys = [u8; 128];
......
use crate::*;
use sp_core::{crypto::AccountId32, sr25519::Pair};
use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner};
/// set sudo key
pub async fn set_key(
pair: Pair,
client: &Client,
new_key: AccountId32,
) -> Result<(), subxt::Error> {
pub async fn set_key(pair: Pair, client: &Client, new_key: AccountId) -> Result<(), subxt::Error> {
let progress = client
.tx()
.sign_and_submit_then_watch(
......
use crate::*;
use sp_core::{crypto::AccountId32, sr25519::Pair};
use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner};
#[cfg(any(feature = "dev", feature = "gdev"))] // find how to get runtime calls
type Call = runtime::runtime_types::gdev_runtime::RuntimeCall;
type BalancesCall = runtime::runtime_types::pallet_balances::pallet::Call;
/// transfer balance to target
pub async fn transfer(
pair: Pair,
client: &Client,
data: &Data,
balance: u64,
dest: AccountId32,
dest: AccountId,
keep_alive: bool,
) -> Result<(), subxt::Error> {
let progress = if keep_alive {
client
data.client()
.tx()
.sign_and_submit_then_watch(
&runtime::tx().balances().transfer(dest.into(), balance),
&PairSigner::new(pair),
&PairSigner::new(data.keypair()),
BaseExtrinsicParamsBuilder::new(),
)
.await?
} else {
client
data.client()
.tx()
.sign_and_submit_then_watch(
&runtime::tx()
.balances()
.transfer_keep_alive(dest.into(), balance),
&PairSigner::new(pair),
&PairSigner::new(data.keypair()),
BaseExtrinsicParamsBuilder::new(),
)
.await?
......@@ -44,11 +41,11 @@ pub async fn transfer(
Ok(())
}
/// transfer balance to multiple target
pub async fn transfer_multiple(
pair: Pair,
client: &Client,
data: &Data,
amount: u64,
dests: Vec<AccountId32>,
dests: Vec<AccountId>,
) -> Result<(), subxt::Error> {
// build the list of transactions from the destination accounts
let transactions: Vec<Call> = dests
......@@ -62,11 +59,12 @@ pub async fn transfer_multiple(
.collect();
// wrap these calls in a batch call
let progress = client
let progress = data
.client()
.tx()
.sign_and_submit_then_watch(
&runtime::tx().utility().batch(transactions),
&PairSigner::new(pair.clone()),
&PairSigner::new(data.keypair()),
BaseExtrinsicParamsBuilder::new(),
)
.await?;
......
use anyhow::{anyhow, Result};
use crate::*;
use clap::builder::OsStr;
use sp_core::{
crypto::{AccountId32, Pair as _, Ss58Codec},
sr25519::Pair,
};
use sp_core::crypto::Ss58Codec;
use std::str::FromStr;
#[allow(dead_code)]
......@@ -50,7 +48,7 @@ impl From<SecretFormat> for OsStr {
}
}
pub fn pair_from_str(secret_format: SecretFormat, secret: &str) -> Result<Pair> {
pub fn pair_from_str(secret_format: SecretFormat, secret: &str) -> anyhow::Result<Pair> {
match secret_format {
SecretFormat::Seed => {
let mut seed = [0; 32];
......@@ -81,12 +79,12 @@ pub fn get_keys(
address: &Option<String>,
secret: &Option<String>,
needed_keys: NeededKeys,
) -> Result<(Option<AccountId32>, Option<Pair>)> {
) -> anyhow::Result<(Option<AccountId>, Option<Pair>)> {
// Get from args
let mut account_id = match (address, secret) {
(Some(address), Some(secret)) => {
let pair = pair_from_str(secret_format, secret)?;
let address = AccountId32::from_string(address)
let address = AccountId::from_string(address)
.map_err(|_| anyhow!("Invalid address {}", address))?;
assert_eq!(
address,
......@@ -99,9 +97,9 @@ pub fn get_keys(
let pair = pair_from_str(secret_format, secret)?;
return Ok((Some(pair.public().into()), Some(pair)));
}
(Some(address), None) => Some(
AccountId32::from_str(address).map_err(|_| anyhow!("Invalid address {}", address))?,
),
(Some(address), None) => {
Some(AccountId::from_str(address).map_err(|_| anyhow!("Invalid address {}", address))?)
}
(None, None) => None,
};
......
......@@ -157,11 +157,6 @@ impl From<anyhow::Error> for GcliError {
#[derive(Clone, Debug, clap::Subcommand, Default)]
pub enum Subcommand {
/// Fetch account balance
#[default]
Balance,
/// Show address corresponding to given arguments
ShowAddress,
#[clap(hide = true)]
Repart {
// Number of transactions per block to target
......@@ -174,27 +169,14 @@ pub enum Subcommand {
SpamRoll {
actual_repart: usize,
},
Transfer {
/// Amount to transfer
amount: u64,
/// Destination address
dest: AccountId,
/// 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<AccountId>,
},
/// Get information about runtime
RuntimeInfo,
#[default]
/// Check current block
CurrentBlock,
/// Account subcommands
#[clap(subcommand)]
Account(commands::account::Subcommand),
/// Identity subcommands
#[clap(subcommand)]
Identity(commands::identity::Subcommand),
......@@ -228,19 +210,6 @@ async fn main() -> Result<(), GcliError> {
let mut data = Data::new(args.clone());
match args.subcommand {
Subcommand::Balance => {
data = data
.build_address()
.build_client()
.await?
.fetch_system_properties()
.await?;
commands::account::get_balance(data).await?
}
Subcommand::ShowAddress => {
data = data.build_address();
println!("address is: {}", data.address());
}
Subcommand::Repart {
target,
actual_repart,
......@@ -277,45 +246,6 @@ async fn main() -> Result<(), GcliError> {
)
.await?
}
Subcommand::Transfer {
amount,
dest,
keep_alive,
} => {
data = data.build_client().await?;
commands::transfer::transfer(
get_keys(
args.secret_format,
&args.address,
&args.secret,
NeededKeys::Secret,
)?
.1
.unwrap(),
data.client(),
amount,
dest,
keep_alive,
)
.await?;
}
Subcommand::TransferMultiple { amount, dests } => {
data = data.build_client().await?;
commands::transfer::transfer_multiple(
get_keys(
args.secret_format,
&args.address,
&args.secret,
NeededKeys::Secret,
)?
.1
.unwrap(),
data.client(),
amount,
dests,
)
.await?;
}
Subcommand::RuntimeInfo => {
data = data.build_client().await?.fetch_system_properties().await?;
commands::runtime::runtime_info(data).await;
......@@ -332,6 +262,7 @@ async fn main() -> Result<(), GcliError> {
.unwrap()
);
}
Subcommand::Account(subcommand) => commands::account::handle_command(data, subcommand).await?,
Subcommand::Identity(subcommand) => commands::identity::handle_command(data, subcommand).await?,
Subcommand::Smith(subcommand) => commands::smith::handle_command(data, subcommand).await?,
Subcommand::Tech(subcommand) => commands::collective::handle_command(data, subcommand).await?,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment