Forked from
clients / Rust / Ğcli-v2s
121 commits behind the upstream repository.
-
Pascal Engélibert authoredPascal Engélibert authored
main.rs 10.02 KiB
mod cache;
mod commands;
mod indexer;
mod keys;
use keys::*;
use anyhow::Result;
use clap::Parser;
use codec::Encode;
use sp_core::H256;
#[subxt::subxt(runtime_metadata_path = "res/metadata.scale")]
pub mod gdev {}
pub type Client = subxt::OnlineClient<GdevConfig>;
pub enum GdevConfig {}
impl subxt::config::Config for GdevConfig {
type Index = u32;
type BlockNumber = u32;
type Hash = sp_core::H256;
type Hashing = subxt::ext::sp_runtime::traits::BlakeTwo256;
type AccountId = subxt::ext::sp_runtime::AccountId32;
type Address = subxt::ext::sp_runtime::MultiAddress<Self::AccountId, u32>;
type Header = subxt::ext::sp_runtime::generic::Header<
Self::BlockNumber,
subxt::ext::sp_runtime::traits::BlakeTwo256,
>;
type Signature = subxt::ext::sp_runtime::MultiSignature;
type ExtrinsicParams = subxt::tx::BaseExtrinsicParams<Self, Tip>;
}
#[derive(Copy, Clone, Debug, Default, Encode)]
pub struct Tip {
#[codec(compact)]
tip: u64,
}
impl Tip {
pub fn new(amount: u64) -> Self {
Tip { tip: amount }
}
}
impl From<u64> for Tip {
fn from(n: u64) -> Self {
Self::new(n)
}
}
#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
pub struct Args {
#[clap(subcommand)]
pub subcommand: Subcommand,
/// Indexer URL
#[clap(
short,
long,
default_value = "https://gdev-indexer.p2p.legal/v1/graphql"
)]
indexer: String,
/// Do not use indexer
#[clap(long)]
no_indexer: bool,
/// Secret key or BIP39 mnemonic
/// (eventually followed by derivation path)
#[clap(short, long)]
secret: Option<String>,
/// Secret key format (seed, substrate)
#[clap(short = 'S', long, default_value = SecretFormat::Substrate)]
secret_format: SecretFormat,
/// Address
#[clap(short, long)]
address: Option<String>,
/// Websocket RPC endpoint
#[clap(short, long, default_value = "ws://localhost:9944")]
url: String,
}
#[derive(Debug, clap::Subcommand)]
pub enum Subcommand {
CreateOneshot {
balance: u64,
dest: sp_core::crypto::AccountId32,
},
ConsumeOneshot {
dest: sp_core::crypto::AccountId32,
#[clap(long = "oneshot")]
dest_oneshot: bool,
},
ConsumeOneshotWithRemaining {
balance: u64,
dest: sp_core::crypto::AccountId32,
#[clap(long = "one")]
dest_oneshot: bool,
remaining_to: sp_core::crypto::AccountId32,
#[clap(long = "rem-one")]
remaining_to_oneshot: bool,
},
/// List upcoming expirations that require an action
Expire {
/// Show certs that expire within less than this number of blocks
#[clap(short, long, default_value_t = 100800)]
blocks: u32,
/// Show authorities that should rotate keys within less than this number of sessions
#[clap(short, long, default_value_t = 100)]
sessions: u32,
},
/// Fetch identity
Identity {
#[clap(short = 'p', long = "pubkey")]
account_id: Option<sp_core::crypto::AccountId32>,
#[clap(short = 'i', long = "identity")]
identity_id: Option<u32>,
#[clap(short = 'u', long = "username")]
username: Option<String>,
},
/// Generate a revocation document for the provided account
GenRevocDoc,
GoOffline,
GoOnline,
OneshotBalance {
account: sp_core::crypto::AccountId32,
},
/// List online authorities
Online,
#[clap(hide = true)]
Repart {
// Number of transactions per block to target
target: u32,
#[clap(short = 'o', long = "old-repart")]
// Old/actual repartition
actual_repart: Option<u32>,
},
#[clap(hide = true)]
SpamRoll {
actual_repart: usize,
},
SudoSetKey {
new_key: sp_core::crypto::AccountId32,
},
/// List members of the technical committee
TechMembers,
/// List proposals to the technical committee
TechProposals,
/// Vote a proposal to the technical committee
TechVote {
/// Proposal hash
hash: H256,
/// Proposal index
index: u32,
/// Vote (0=against, 1=for)
vote: u8,
},
Transfer {
/// Amount to transfer
amount: u64,
/// Destination address
dest: sp_core::crypto::AccountId32,
/// 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,
}
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<()> {
env_logger::init();
let args = Args::parse();
/*if let Some(account_id) = &account_id {
println!("Account address: {account_id}");
}*/
/*if let Some(account_id) = &account_id {
let account = client
.storage()
.fetch(&gdev::storage().system().account(account_id), None)
.await?
.expect("Cannot fetch account");
logs::info!("Account free balance: {}", account.data.free);
}*/
match args.subcommand {
Subcommand::CreateOneshot { balance, dest } => {
commands::oneshot::create_oneshot_account(
get_keys(
args.secret_format,
&args.address,
&args.secret,
NeededKeys::Secret,
)?
.1
.unwrap(),
Client::from_url(&args.url).await.unwrap(),
balance,
dest,
)
.await?
}
Subcommand::ConsumeOneshot { dest, dest_oneshot } => {
commands::oneshot::consume_oneshot_account(
get_keys(
args.secret_format,
&args.address,
&args.secret,
NeededKeys::Secret,
)?
.1
.unwrap(),
Client::from_url(&args.url).await.unwrap(),
dest,
dest_oneshot,
)
.await?
}
Subcommand::ConsumeOneshotWithRemaining {
balance,
dest,
dest_oneshot,
remaining_to,
remaining_to_oneshot,
} => {
commands::oneshot::consume_oneshot_account_with_remaining(
get_keys(
args.secret_format,
&args.address,
&args.secret,
NeededKeys::Secret,
)?
.1
.unwrap(),
Client::from_url(&args.url).await.unwrap(),
balance,
dest,
dest_oneshot,
remaining_to,
remaining_to_oneshot,
)
.await?
}
Subcommand::Expire { blocks, sessions } => {
commands::expire::monitor_expirations(
Client::from_url(&args.url).await.unwrap(),
blocks,
sessions,
&args,
)
.await?
}
Subcommand::Identity {
ref account_id,
identity_id,
ref username,
} => {
commands::identity::get_identity(
Client::from_url(&args.url).await.unwrap(),
account_id.clone(),
identity_id,
username.clone(),
&args,
)
.await?
}
Subcommand::GenRevocDoc => {
commands::revocation::gen_revoc_doc(
&Client::from_url(&args.url).await.unwrap(),
&get_keys(
args.secret_format,
&args.address,
&args.secret,
NeededKeys::Secret,
)?
.1
.unwrap(),
)
.await?
}
Subcommand::GoOffline => {
commands::smith::go_offline(
get_keys(
args.secret_format,
&args.address,
&args.secret,
NeededKeys::Secret,
)?
.1
.unwrap(),
Client::from_url(&args.url).await.unwrap(),
)
.await?
}
Subcommand::GoOnline => {
commands::smith::go_online(
get_keys(
args.secret_format,
&args.address,
&args.secret,
NeededKeys::Secret,
)?
.1
.unwrap(),
Client::from_url(&args.url).await.unwrap(),
)
.await?
}
Subcommand::OneshotBalance { account } => {
commands::oneshot::oneshot_account_balance(
Client::from_url(&args.url).await.unwrap(),
account,
)
.await?
}
Subcommand::Online => {
commands::smith::online(Client::from_url(&args.url).await.unwrap(), &args).await?
}
Subcommand::Repart {
target,
actual_repart,
} => {
commands::net_test::repart(
get_keys(
args.secret_format,
&args.address,
&args.secret,
NeededKeys::Secret,
)?
.1
.unwrap(),
Client::from_url(&args.url).await.unwrap(),
target,
actual_repart,
)
.await?
}
Subcommand::SpamRoll { actual_repart } => {
commands::net_test::spam_roll(
get_keys(
args.secret_format,
&args.address,
&args.secret,
NeededKeys::Secret,
)?
.1
.unwrap(),
Client::from_url(&args.url).await.unwrap(),
actual_repart,
)
.await?
}
Subcommand::SudoSetKey { new_key } => {
commands::sudo::set_key(
get_keys(
args.secret_format,
&args.address,
&args.secret,
NeededKeys::Secret,
)?
.1
.unwrap(),
Client::from_url(&args.url).await.unwrap(),
new_key,
)
.await?
}
Subcommand::TechMembers => {
commands::collective::technical_committee_members(
Client::from_url(&args.url).await.unwrap(),
&args,
)
.await?
}
Subcommand::TechProposals => {
commands::collective::technical_committee_proposals(
Client::from_url(&args.url).await.unwrap(),
)
.await?
}
Subcommand::TechVote { hash, index, vote } => {
let vote = match vote {
0 => false,
1 => true,
_ => panic!("Vote must be written 0 if you disagree, or 1 if you agree."),
};
commands::collective::technical_committee_vote(
get_keys(
args.secret_format,
&args.address,
&args.secret,
NeededKeys::Secret,
)?
.1
.unwrap(),
Client::from_url(&args.url).await.unwrap(),
hash, //H256::from_str(&hash).expect("Invalid hash formatting"),
index,
vote,
)
.await?
}
Subcommand::Transfer {
amount,
dest,
keep_alive,
} => {
commands::transfer::transfer(
get_keys(
args.secret_format,
&args.address,
&args.secret,
NeededKeys::Secret,
)?
.1
.unwrap(),
Client::from_url(&args.url).await.unwrap(),
amount,
dest,
keep_alive,
)
.await?
}
Subcommand::TransferMultiple { amount, dests } => {
commands::transfer::transfer_multiple(
get_keys(
args.secret_format,
&args.address,
&args.secret,
NeededKeys::Secret,
)?
.1
.unwrap(),
Client::from_url(&args.url).await.unwrap(),
amount,
dests,
)
.await?
}
Subcommand::UpdateKeys => commands::smith::update_session_keys(
get_keys(
args.secret_format,
&args.address,
&args.secret,
NeededKeys::Secret,
)?
.1
.unwrap(),
Client::from_url(&args.url).await.unwrap(),
)
.await
.unwrap(),
}
Ok(())
}