Newer
Older
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 Extrinsic = subxt::ext::sp_runtime::OpaqueExtrinsic;
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)]
/// Indexer URL
#[clap(short, long, default_value = "https://idx.gdev.cgeek.fr/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>,
/// Address
#[clap(short, long)]
address: Option<String>,
#[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,
},
/// Generate a revocation document for the provided account
GenRevocDoc,
OneshotBalance {
account: sp_core::crypto::AccountId32,
},
#[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,
},
Transfer {
balance: u64,
dest: sp_core::crypto::AccountId32,
#[clap(short = 'k')]
keep_alive: bool,
},
}
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<()> {
env_logger::init();
let args = Args::parse();
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
let (account_id, pair) = match (&args.address, &args.secret) {
(Some(address), Some(secret)) => {
let pair = Pair::from_string(secret, None)
.map_err(|_| anyhow!("Invalid secret {}", secret))?;
let address = sp_core::crypto::AccountId32::from_string(address)
.map_err(|_| anyhow!("Invalid address {}", address))?;
assert_eq!(
address,
pair.public().into(),
"Secret and address do not match."
);
(Some(pair.public().into()), Some(pair))
}
(None, Some(secret)) => {
let pair = Pair::from_string(secret, None)
.map_err(|_| anyhow!("Invalid secret {}", secret))?;
(Some(pair.public().into()), Some(pair))
}
(Some(address), None) => (
Some(
sp_core::crypto::AccountId32::from_str(address)
.map_err(|_| anyhow!("Invalid address {}", address))?,
),
None,
),
(None, None) => (None, None),
};
.fetch(&gdev::storage().system().account(account_id), None)
logs::info!("Account free balance: {}", account.data.free);
}
Subcommand::CreateOneshot { balance, dest } => {
commands::oneshot::create_oneshot_account(
pair.expect("This subcommand needs a secret."),
client,
balance,
dest,
)
.await?
}
Subcommand::ConsumeOneshot { dest, dest_oneshot } => {
commands::oneshot::consume_oneshot_account(
pair.expect("This subcommand needs a secret."),
client,
dest,
dest_oneshot,
)
.await?
}
Subcommand::ConsumeOneshotWithRemaining {
balance,
dest,
dest_oneshot,
remaining_to,
remaining_to_oneshot,
} => {
commands::oneshot::consume_oneshot_account_with_remaining(
pair.expect("This subcommand needs a secret."),
client,
balance,
dest,
dest_oneshot,
remaining_to,
remaining_to_oneshot,
)
.await?
Subcommand::Expire { blocks, sessions } => {
commands::expire::monitor_expirations(client, blocks, sessions, &args).await?
commands::revocation::gen_revoc_doc(
&client,
&pair.expect("This subcommand needs a secret."),
)
.await?
Subcommand::OneshotBalance { account } => {
commands::oneshot::oneshot_account_balance(client, account).await?
commands::net_test::repart(
pair.expect("This subcommand needs a secret."),
client,
target,
actual_repart,
)
.await?
commands::net_test::spam_roll(
pair.expect("This subcommand needs a secret."),
client,
actual_repart,
)
.await?
commands::sudo::set_key(
pair.expect("This subcommand needs a secret."),
client,
new_key,
)
.await?
Subcommand::Transfer {
balance,
dest,
keep_alive,
} => {
commands::transfer::transfer(
pair.expect("This subcommand needs a secret."),
client,
balance,
dest,
keep_alive,
)
.await?