mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 12:51:05 +00:00
Rework Subxt API to support offline and dynamic transactions (#593)
* WIP API changes * debug impls * Get main crate compiling with first round of changes * Some tidy up * Add WithExtrinsicParams, and have SubstrateConfig + PolkadotConfig, not DefaultConfig * move transaction into extrinsic folder * Add runtime updates back to OnlineClient * rework to be 'client first' to fit better with storage + events * add support for events to Client * tidy dupe trait bound * Wire storage into client, but need to remove static reliance * various tidy up and start stripping codegen to remove bits we dont need now * First pass updating calls and constants codegen * WIP storage client updates * First pass migrated runtime storage over to new format * pass over codegen to generate StorageAddresses and throw other stuff out * don't need a Call trait any more * shuffle things around a bit * Various proc_macro fixes to get 'cargo check' working * organise what's exposed from subxt * Get first example working; balance_transfer_with_params * get balance_transfer example compiling * get concurrent_storage_requests.rs example compiling * get fetch_all_accounts example compiling * get a bunch more of the examples compiling * almost get final example working; type mismatch to look into * wee tweaks * move StorageAddress to separate file * pass Defaultable/Iterable info to StorageAddress in codegen * fix storage validation ne, and partial run through example code * Remove static iteration and strip a generic param from everything * fix doc tests in subxt crate * update test utils and start fixing frame tests * fix frame staking tests * fix the rest of the test compile issues, Borrow on storage values * cargo fmt * remove extra logging during tests * Appease clippy and no more need for into_iter on events * cargo fmt * fix dryRun tests by waiting for blocks * wait for blocks instead of sleeping or other test hacks * cargo fmt * Fix doc links * Traitify StorageAddress * remove out-of-date doc comments * optimise decoding storage a little * cleanup tx stuff, trait for TxPayload, remove Err type param and decode at runtime * clippy fixes * fix doc links * fix doc example * constant address trait for consistency * fix a typo and remove EncodeWithMetadata stuff * Put EventDetails behind a proper interface and allow decoding into top level event, too * fix docs * tweak StorageAddress docs * re-export StorageAddress at root for consistency * fix clippy things * Add support for dynamic values * fix double encoding of storage map key after refactor * clippy fix * Fixes and add a dynamic usage example (needs new scale_value release) * bump scale_value version * cargo fmt * Tweak event bits * cargo fmt * Add a test and bump scale-value to 0.4.0 to support this * remove unnecessary vec from dynamic example * Various typo/grammar fixes Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> * Address PR nits * Undo accidental rename in changelog * Small PR nits/tidyups * fix tests; codegen change against latest substrate * tweak storage address util names * move error decoding to DecodeError and expose * impl some basic traits on the extrinsic param builder Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com>
This commit is contained in:
@@ -2,20 +2,19 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot 0.9.18-4542a603cc-aarch64-macos.
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot polkadot 0.9.25-5174e9ae75b.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.18/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.25/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
|
||||
use sp_keyring::AccountKeyring;
|
||||
use subxt::{
|
||||
ClientBuilder,
|
||||
DefaultConfig,
|
||||
PairSigner,
|
||||
PolkadotExtrinsicParams,
|
||||
tx::PairSigner,
|
||||
OnlineClient,
|
||||
PolkadotConfig,
|
||||
};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
|
||||
@@ -26,23 +25,20 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
let signer = PairSigner::new(AccountKeyring::Alice.pair());
|
||||
|
||||
let api = ClientBuilder::new()
|
||||
.build()
|
||||
.await?
|
||||
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
|
||||
|
||||
// Submit the `transfer` extrinsic from Alice's account to Bob's.
|
||||
let dest = AccountKeyring::Bob.to_account_id().into();
|
||||
|
||||
// Obtain an extrinsic, calling the "transfer" function in
|
||||
// the "balances" pallet.
|
||||
let extrinsic = api.tx().balances().transfer(dest, 123_456_789_012_345)?;
|
||||
// Create a client to use:
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
// Sign and submit the extrinsic, returning its hash.
|
||||
let tx_hash = extrinsic.sign_and_submit_default(&signer).await?;
|
||||
// Create a transaction to submit:
|
||||
let tx = polkadot::tx()
|
||||
.balances()
|
||||
.transfer(dest, 123_456_789_012_345);
|
||||
|
||||
println!("Balance transfer extrinsic submitted: {}", tx_hash);
|
||||
// Submit the transaction with default params:
|
||||
let hash = api.tx().sign_and_submit_default(&tx, &signer).await?;
|
||||
|
||||
println!("Balance transfer extrinsic submitted: {}", hash);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -2,25 +2,24 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot 0.9.18-4542a603cc-aarch64-macos.
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot polkadot 0.9.25-5174e9ae75b.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.18/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.25/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
|
||||
use sp_keyring::AccountKeyring;
|
||||
use subxt::{
|
||||
extrinsic::{
|
||||
tx::{
|
||||
Era,
|
||||
PairSigner,
|
||||
PlainTip,
|
||||
PolkadotExtrinsicParamsBuilder as Params,
|
||||
},
|
||||
ClientBuilder,
|
||||
DefaultConfig,
|
||||
PairSigner,
|
||||
PolkadotExtrinsicParams,
|
||||
PolkadotExtrinsicParamsBuilder as Params,
|
||||
OnlineClient,
|
||||
PolkadotConfig,
|
||||
};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
|
||||
@@ -33,23 +32,21 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let signer = PairSigner::new(AccountKeyring::Alice.pair());
|
||||
let dest = AccountKeyring::Bob.to_account_id().into();
|
||||
|
||||
let api = ClientBuilder::new()
|
||||
.build()
|
||||
.await?
|
||||
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
|
||||
// Create a client to use:
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
// Create a transaction to submit:
|
||||
let tx = polkadot::tx()
|
||||
.balances()
|
||||
.transfer(dest, 123_456_789_012_345);
|
||||
|
||||
// Configure the transaction tip and era:
|
||||
let tx_params = Params::new()
|
||||
.tip(PlainTip::new(20_000_000_000))
|
||||
.era(Era::Immortal, *api.client.genesis());
|
||||
.era(Era::Immortal, api.genesis_hash());
|
||||
|
||||
// Send the transaction:
|
||||
let hash = api
|
||||
.tx()
|
||||
.balances()
|
||||
.transfer(dest, 123_456_789_012_345)?
|
||||
.sign_and_submit(&signer, tx_params)
|
||||
.await?;
|
||||
// submit the transaction:
|
||||
let hash = api.tx().sign_and_submit(&tx, &signer, tx_params).await?;
|
||||
|
||||
println!("Balance transfer extrinsic submitted: {}", hash);
|
||||
|
||||
|
||||
@@ -2,12 +2,19 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot polkadot 0.9.25-5174e9ae75b.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.25/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
|
||||
use futures::join;
|
||||
use sp_keyring::AccountKeyring;
|
||||
use subxt::{
|
||||
ClientBuilder,
|
||||
DefaultConfig,
|
||||
PolkadotExtrinsicParams,
|
||||
OnlineClient,
|
||||
PolkadotConfig,
|
||||
};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
|
||||
@@ -15,17 +22,18 @@ pub mod polkadot {}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let api = ClientBuilder::new()
|
||||
.build()
|
||||
.await?
|
||||
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
let addr = AccountKeyring::Bob.to_account_id();
|
||||
|
||||
// Construct storage addresses to access:
|
||||
let staking_bonded = polkadot::storage().staking().bonded(&addr);
|
||||
let staking_ledger = polkadot::storage().staking().ledger(&addr);
|
||||
|
||||
// For storage requests, we can join futures together to
|
||||
// await multiple futures concurrently:
|
||||
let a_fut = api.storage().staking().bonded(&addr, None);
|
||||
let b_fut = api.storage().staking().ledger(&addr, None);
|
||||
let a_fut = api.storage().fetch(&staking_bonded, None);
|
||||
let b_fut = api.storage().fetch(&staking_ledger, None);
|
||||
let (a, b) = join!(a_fut, b_fut);
|
||||
|
||||
println!("{a:?}, {b:?}");
|
||||
|
||||
@@ -2,21 +2,20 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot 0.9.18-4542a603cc-aarch64-macos.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.18/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
//! This example should compile but should aos fail to work, since we've modified the
|
||||
//! config to not align with a Polkadot node.
|
||||
|
||||
use sp_keyring::AccountKeyring;
|
||||
use subxt::{
|
||||
ClientBuilder,
|
||||
Config,
|
||||
DefaultConfig,
|
||||
PairSigner,
|
||||
PolkadotExtrinsicParams,
|
||||
config::{
|
||||
Config,
|
||||
SubstrateConfig,
|
||||
},
|
||||
tx::{
|
||||
PairSigner,
|
||||
SubstrateExtrinsicParams,
|
||||
},
|
||||
OnlineClient,
|
||||
};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
|
||||
@@ -33,32 +32,34 @@ impl Config for MyConfig {
|
||||
// polkadot runtime used, so some operations will fail. Normally when using a custom `Config`
|
||||
// impl types MUST match exactly those used in the actual runtime.
|
||||
type Index = u64;
|
||||
type BlockNumber = <DefaultConfig as Config>::BlockNumber;
|
||||
type Hash = <DefaultConfig as Config>::Hash;
|
||||
type Hashing = <DefaultConfig as Config>::Hashing;
|
||||
type AccountId = <DefaultConfig as Config>::AccountId;
|
||||
type Address = <DefaultConfig as Config>::Address;
|
||||
type Header = <DefaultConfig as Config>::Header;
|
||||
type Signature = <DefaultConfig as Config>::Signature;
|
||||
type Extrinsic = <DefaultConfig as Config>::Extrinsic;
|
||||
type BlockNumber = <SubstrateConfig as Config>::BlockNumber;
|
||||
type Hash = <SubstrateConfig as Config>::Hash;
|
||||
type Hashing = <SubstrateConfig as Config>::Hashing;
|
||||
type AccountId = <SubstrateConfig as Config>::AccountId;
|
||||
type Address = <SubstrateConfig as Config>::Address;
|
||||
type Header = <SubstrateConfig as Config>::Header;
|
||||
type Signature = <SubstrateConfig as Config>::Signature;
|
||||
type Extrinsic = <SubstrateConfig as Config>::Extrinsic;
|
||||
// ExtrinsicParams makes use of the index type, so we need to adjust it
|
||||
// too to align with our modified index type, above:
|
||||
type ExtrinsicParams = SubstrateExtrinsicParams<Self>;
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let api = ClientBuilder::new()
|
||||
.build()
|
||||
.await?
|
||||
.to_runtime_api::<polkadot::RuntimeApi<MyConfig, PolkadotExtrinsicParams<MyConfig>>>();
|
||||
|
||||
let signer = PairSigner::new(AccountKeyring::Alice.pair());
|
||||
let dest = AccountKeyring::Bob.to_account_id().into();
|
||||
|
||||
let hash = api
|
||||
.tx()
|
||||
// Create a client to use:
|
||||
let api = OnlineClient::<MyConfig>::new().await?;
|
||||
|
||||
// Create a transaction to submit:
|
||||
let tx = polkadot::tx()
|
||||
.balances()
|
||||
.transfer(dest, 10_000)?
|
||||
.sign_and_submit_default(&signer)
|
||||
.await?;
|
||||
.transfer(dest, 123_456_789_012_345);
|
||||
|
||||
// submit the transaction with default params:
|
||||
let hash = api.tx().sign_and_submit_default(&tx, &signer).await?;
|
||||
|
||||
println!("Balance transfer extrinsic submitted: {}", hash);
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! Example verified against polkadot 0.9.18-4542a603cc-aarch64-macos.
|
||||
|
||||
//! Example verified against polkadot polkadot 0.9.25-5174e9ae75b.
|
||||
#![allow(clippy::redundant_clone)]
|
||||
|
||||
#[subxt::subxt(
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
// Copyright 2019-2022 Parity Technologies (UK) Ltd.
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot polkadot 0.9.25-5174e9ae75b.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.25/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
|
||||
// This example showcases working with dynamic values rather than those that are generated via the subxt proc macro.
|
||||
|
||||
use sp_keyring::AccountKeyring;
|
||||
use subxt::{
|
||||
dynamic::Value,
|
||||
tx::PairSigner,
|
||||
OnlineClient,
|
||||
PolkadotConfig,
|
||||
};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
// 1. Dynamic Balance Transfer (the dynamic equivalent to the balance_transfer example).
|
||||
|
||||
let signer = PairSigner::new(AccountKeyring::Alice.pair());
|
||||
let dest = AccountKeyring::Bob.to_account_id();
|
||||
|
||||
// Create a transaction to submit:
|
||||
let tx = subxt::dynamic::tx(
|
||||
"Balances",
|
||||
"transfer",
|
||||
vec![
|
||||
// A value representing a MultiAddress<AccountId32, _>. We want the "Id" variant, and that
|
||||
// will ultimately contain the bytes for our destination address (there is a new type wrapping
|
||||
// the address, but our encoding will happily ignore such things and do it's best to line up what
|
||||
// we provide with what it needs).
|
||||
Value::unnamed_variant("Id", [Value::from_bytes(&dest)]),
|
||||
// A value representing the amount we'd like to transfer.
|
||||
Value::u128(123_456_789_012_345),
|
||||
],
|
||||
);
|
||||
|
||||
// submit the transaction with default params:
|
||||
let hash = api.tx().sign_and_submit_default(&tx, &signer).await?;
|
||||
println!("Balance transfer extrinsic submitted: {}", hash);
|
||||
|
||||
// 2. Dynamic constant access (the dynamic equivalent to the fetch_constants example).
|
||||
|
||||
let constant_address = subxt::dynamic::constant("Balances", "ExistentialDeposit");
|
||||
let existential_deposit = api.constants().at(&constant_address)?;
|
||||
println!("Existential Deposit: {}", existential_deposit);
|
||||
|
||||
// 3. Dynamic storage access
|
||||
|
||||
let storage_address = subxt::dynamic::storage(
|
||||
"System",
|
||||
"Account",
|
||||
vec![
|
||||
// Something that encodes to an AccountId32 is what we need for the map key here:
|
||||
Value::from_bytes(&dest),
|
||||
],
|
||||
);
|
||||
let account = api
|
||||
.storage()
|
||||
.fetch_or_default(&storage_address, None)
|
||||
.await?;
|
||||
println!("Bob's account details: {account}");
|
||||
|
||||
// 4. Dynamic storage iteration (the dynamic equivalent to the fetch_all_accounts example).
|
||||
|
||||
let storage_address = subxt::dynamic::storage_root("System", "Account");
|
||||
let mut iter = api.storage().iter(storage_address, 10, None).await?;
|
||||
while let Some((key, account)) = iter.next().await? {
|
||||
println!("{}: {}", hex::encode(key), account);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -2,18 +2,17 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot 0.9.18-4542a603cc-aarch64-macos.
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot polkadot 0.9.25-5174e9ae75b.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.18/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.25/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
|
||||
use subxt::{
|
||||
ClientBuilder,
|
||||
DefaultConfig,
|
||||
PolkadotExtrinsicParams,
|
||||
OnlineClient,
|
||||
PolkadotConfig,
|
||||
};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
|
||||
@@ -23,12 +22,11 @@ pub mod polkadot {}
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
let api = ClientBuilder::new()
|
||||
.build()
|
||||
.await?
|
||||
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
let mut iter = api.storage().system().account_iter(None).await?;
|
||||
let address = polkadot::storage().system().account_root();
|
||||
|
||||
let mut iter = api.storage().iter(address, 10, None).await?;
|
||||
|
||||
while let Some((key, account)) = iter.next().await? {
|
||||
println!("{}: {}", hex::encode(key), account.data.free);
|
||||
|
||||
@@ -2,18 +2,17 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot 0.9.18-4542a603cc-aarch64-macos.
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot polkadot 0.9.25-5174e9ae75b.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.18/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.25/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
|
||||
use subxt::{
|
||||
ClientBuilder,
|
||||
DefaultConfig,
|
||||
PolkadotExtrinsicParams,
|
||||
OnlineClient,
|
||||
PolkadotConfig,
|
||||
};
|
||||
|
||||
// Generate the API from a static metadata path.
|
||||
@@ -24,22 +23,14 @@ pub mod polkadot {}
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
// Upon connecting to the target polkadot node, the node's metadata is downloaded (referred to
|
||||
// as the runtime metadata).
|
||||
let api = ClientBuilder::new()
|
||||
.build()
|
||||
.await?
|
||||
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
|
||||
// Create a client to use:
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
// Constants are queried from the node's runtime metadata.
|
||||
// Query the `ExistentialDeposit` constant from the `Balances` pallet.
|
||||
let existential_deposit = api
|
||||
// This is the constants query.
|
||||
.constants()
|
||||
// Constant from the `Balances` pallet.
|
||||
.balances()
|
||||
// Constant name.
|
||||
.existential_deposit()?;
|
||||
// Build a constant address to query:
|
||||
let address = polkadot::constants().balances().existential_deposit();
|
||||
|
||||
// Look it up:
|
||||
let existential_deposit = api.constants().at(&address)?;
|
||||
|
||||
println!("Existential Deposit: {}", existential_deposit);
|
||||
|
||||
|
||||
@@ -2,24 +2,25 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot 0.9.18-4542a603cc-aarch64-macos.
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot polkadot 0.9.25-5174e9ae75b.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.18/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.25/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
|
||||
use sp_keyring::AccountKeyring;
|
||||
use subxt::{
|
||||
sp_core::{
|
||||
sr25519,
|
||||
Pair,
|
||||
ext::{
|
||||
sp_core::{
|
||||
sr25519,
|
||||
Pair,
|
||||
},
|
||||
sp_runtime::AccountId32,
|
||||
},
|
||||
sp_runtime::AccountId32,
|
||||
ClientBuilder,
|
||||
DefaultConfig,
|
||||
PolkadotExtrinsicParams,
|
||||
OnlineClient,
|
||||
PolkadotConfig,
|
||||
};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
|
||||
@@ -29,12 +30,11 @@ pub mod polkadot {}
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
let api = ClientBuilder::new()
|
||||
.build()
|
||||
.await?
|
||||
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
|
||||
// Create a client to use:
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
let era = api.storage().staking().active_era(None).await?.unwrap();
|
||||
let active_era_addr = polkadot::storage().staking().active_era();
|
||||
let era = api.storage().fetch(&active_era_addr, None).await?.unwrap();
|
||||
println!(
|
||||
"Staking active era: index: {:?}, start: {:?}",
|
||||
era.index, era.start
|
||||
@@ -51,19 +51,16 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!(" Alice//stash account id: {:?}", alice_stash_id);
|
||||
|
||||
// Map from all locked "stash" accounts to the controller account.
|
||||
let controller_acc_addr = polkadot::storage().staking().bonded(&alice_stash_id);
|
||||
let controller_acc = api
|
||||
.storage()
|
||||
.staking()
|
||||
.bonded(&alice_stash_id, None)
|
||||
.fetch(&controller_acc_addr, None)
|
||||
.await?
|
||||
.unwrap();
|
||||
println!(" account controlled by: {:?}", controller_acc);
|
||||
|
||||
let era_result = api
|
||||
.storage()
|
||||
.staking()
|
||||
.eras_reward_points(&era.index, None)
|
||||
.await?;
|
||||
let era_reward_addr = polkadot::storage().staking().eras_reward_points(&era.index);
|
||||
let era_result = api.storage().fetch(&era_reward_addr, None).await?;
|
||||
println!("Era reward points: {:?}", era_result);
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -2,18 +2,17 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot 0.9.18-4542a603cc-aarch64-macos.
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot polkadot 0.9.25-5174e9ae75b.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.18/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.25/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
|
||||
use subxt::{
|
||||
ClientBuilder,
|
||||
DefaultConfig,
|
||||
PolkadotExtrinsicParams,
|
||||
OnlineClient,
|
||||
PolkadotConfig,
|
||||
};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
|
||||
@@ -23,18 +22,15 @@ pub mod polkadot {}
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
let api = ClientBuilder::new()
|
||||
.build()
|
||||
.await?
|
||||
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
// Full metadata validation is not enabled by default; instead, the individual calls,
|
||||
// storage requests and constant accesses are runtime type checked against the node
|
||||
// metadata to ensure that they are compatible with the generated code.
|
||||
//
|
||||
// To make sure that all of our statically generated pallets are compatible with the
|
||||
// runtime node, we can run this check:
|
||||
api.validate_metadata()?;
|
||||
// Each individual request will be validated against the static code that was
|
||||
// used to construct it, if possible. We can also validate the entirety of the
|
||||
// statically generated code against some client at a given point in time using
|
||||
// this check. If it fails, then there is some breaking change between the metadata
|
||||
// used to generate this static code, and the runtime metadata from a node that the
|
||||
// client is using.
|
||||
polkadot::validate_codegen(&api)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -2,40 +2,28 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot 0.9.18-4542a603cc-aarch64-macos.
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot polkadot 0.9.25-5174e9ae75b.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.18/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.25/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
|
||||
use subxt::{
|
||||
ClientBuilder,
|
||||
DefaultConfig,
|
||||
PolkadotExtrinsicParams,
|
||||
OnlineClient,
|
||||
PolkadotConfig,
|
||||
};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
|
||||
pub mod polkadot {}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
let api = ClientBuilder::new()
|
||||
.set_url("wss://rpc.polkadot.io:443")
|
||||
.build()
|
||||
.await?
|
||||
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
let block_number = 1u32;
|
||||
|
||||
let block_hash = api
|
||||
.client
|
||||
.rpc()
|
||||
.block_hash(Some(block_number.into()))
|
||||
.await?;
|
||||
let block_hash = api.rpc().block_hash(Some(block_number.into())).await?;
|
||||
|
||||
if let Some(hash) = block_hash {
|
||||
println!("Block hash for block number {block_number}: {hash}");
|
||||
|
||||
@@ -2,41 +2,34 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot 0.9.18-f6d6ab005d-aarch64-macos.
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot polkadot 0.9.25-5174e9ae75b.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.13/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.25/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
|
||||
use subxt::{
|
||||
rpc::Subscription,
|
||||
sp_runtime::{
|
||||
ext::sp_runtime::{
|
||||
generic::Header,
|
||||
traits::BlakeTwo256,
|
||||
},
|
||||
ClientBuilder,
|
||||
DefaultConfig,
|
||||
PolkadotExtrinsicParams,
|
||||
rpc::Subscription,
|
||||
OnlineClient,
|
||||
PolkadotConfig,
|
||||
};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
|
||||
pub mod polkadot {}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
let api = ClientBuilder::new()
|
||||
.set_url("wss://rpc.polkadot.io:443")
|
||||
.build()
|
||||
.await?
|
||||
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
|
||||
let api =
|
||||
OnlineClient::<PolkadotConfig>::from_url("wss://rpc.polkadot.io:443").await?;
|
||||
|
||||
// For non-finalised blocks use `.subscribe_blocks()`
|
||||
let mut blocks: Subscription<Header<u32, BlakeTwo256>> =
|
||||
api.client.rpc().subscribe_finalized_blocks().await?;
|
||||
api.rpc().subscribe_finalized_blocks().await?;
|
||||
|
||||
while let Some(Ok(block)) = blocks.next().await {
|
||||
println!(
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
// Copyright 2019-2022 Parity Technologies (UK) Ltd.
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot polkadot 0.9.25-5174e9ae75b.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.25/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
|
||||
use codec::Decode;
|
||||
use subxt::{
|
||||
storage::address::{
|
||||
StorageHasher,
|
||||
StorageMapKey,
|
||||
},
|
||||
OnlineClient,
|
||||
PolkadotConfig,
|
||||
};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
|
||||
pub mod polkadot {}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
// Create a client to use:
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
// Example 1. Iterate over (keys, value) using the storage client.
|
||||
// This is the standard and most ergonomic approach.
|
||||
{
|
||||
let key_addr = polkadot::storage().xcm_pallet().version_notifiers_root();
|
||||
|
||||
let mut iter = api.storage().iter(key_addr, 10, None).await?;
|
||||
|
||||
println!("\nExample 1. Obtained keys:");
|
||||
while let Some((key, value)) = iter.next().await? {
|
||||
println!("Key: 0x{}", hex::encode(&key));
|
||||
println!(" Value: {}", value);
|
||||
}
|
||||
}
|
||||
|
||||
// Example 2. Iterate over fetched keys manually. Here, you forgo any static type
|
||||
// safety and work directly with the bytes on either side.
|
||||
{
|
||||
let key_addr = polkadot::storage().xcm_pallet().version_notifiers_root();
|
||||
|
||||
// Fetch at most 10 keys from below the prefix XcmPallet' VersionNotifiers.
|
||||
let keys = api
|
||||
.storage()
|
||||
.fetch_keys(&key_addr.to_root_bytes(), 10, None, None)
|
||||
.await?;
|
||||
|
||||
println!("Example 2. Obtained keys:");
|
||||
for key in keys.iter() {
|
||||
println!("Key: 0x{}", hex::encode(&key));
|
||||
|
||||
if let Some(storage_data) = api.storage().fetch_raw(&key.0, None).await? {
|
||||
// We know the return value to be `QueryId` (`u64`) from inspecting either:
|
||||
// - polkadot code
|
||||
// - polkadot.rs generated file under `version_notifiers()` fn
|
||||
// - metadata in json format
|
||||
let value = u64::decode(&mut &*storage_data)?;
|
||||
println!(" Value: {}", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Example 3. Custom iteration over double maps. Here, we manually append one lookup
|
||||
// key to the root and just iterate over the values underneath that.
|
||||
{
|
||||
let key_addr = polkadot::storage().xcm_pallet().version_notifiers_root();
|
||||
|
||||
// Obtain the root bytes (`twox_128("XcmPallet") ++ twox_128("VersionNotifiers")`).
|
||||
let mut query_key = key_addr.to_root_bytes();
|
||||
|
||||
// We know that the first key is a u32 (the `XcmVersion`) and is hashed by twox64_concat.
|
||||
// We can build a `StorageMapKey` that replicates that, and append those bytes to the above.
|
||||
StorageMapKey::new(&2u32, StorageHasher::Twox64Concat).to_bytes(&mut query_key);
|
||||
|
||||
// The final query key is essentially the result of:
|
||||
// `twox_128("XcmPallet") ++ twox_128("VersionNotifiers") ++ twox_64(2u32) ++ 2u32`
|
||||
println!("\nExample 3\nQuery key: 0x{}", hex::encode(&query_key));
|
||||
|
||||
let keys = api.storage().fetch_keys(&query_key, 10, None, None).await?;
|
||||
|
||||
println!("Obtained keys:");
|
||||
for key in keys.iter() {
|
||||
println!("Key: 0x{}", hex::encode(&key));
|
||||
|
||||
if let Some(storage_data) = api.storage().fetch_raw(&key.0, None).await? {
|
||||
// We know the return value to be `QueryId` (`u64`) from inspecting either:
|
||||
// - polkadot code
|
||||
// - polkadot.rs generated file under `version_notifiers()` fn
|
||||
// - metadata in json format
|
||||
let value = u64::decode(&mut &storage_data[..])?;
|
||||
println!(" Value: {}", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
// Copyright 2019-2022 Parity Technologies (UK) Ltd.
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot 0.9.18-4542a603cc-aarch64-macos.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.18/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
|
||||
use codec::Decode;
|
||||
use subxt::{
|
||||
rpc::Rpc,
|
||||
storage::{
|
||||
StorageClient,
|
||||
StorageKeyPrefix,
|
||||
},
|
||||
ClientBuilder,
|
||||
DefaultConfig,
|
||||
PolkadotExtrinsicParams,
|
||||
StorageEntryKey,
|
||||
StorageMapKey,
|
||||
};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
|
||||
pub mod polkadot {}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
let api = ClientBuilder::new()
|
||||
.build()
|
||||
.await?
|
||||
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
|
||||
|
||||
// Obtain the storage client wrapper from the API.
|
||||
let storage: StorageClient<_> = api.client.storage();
|
||||
|
||||
// The VersionNotifiers type of the XcmPallet is defined as:
|
||||
//
|
||||
// ```
|
||||
// All locations that we have requested version notifications from.
|
||||
// #[pallet::storage]
|
||||
// pub(super) type VersionNotifiers<T: Config> = StorageDoubleMap<
|
||||
// _,
|
||||
// Twox64Concat,
|
||||
// XcmVersion,
|
||||
// Blake2_128Concat,
|
||||
// VersionedMultiLocation,
|
||||
// QueryId,
|
||||
// OptionQuery,
|
||||
// >;
|
||||
// ```
|
||||
|
||||
// Example 1. Iterate over fetched keys manually.
|
||||
{
|
||||
// Fetch at most 10 keys from below the prefix XcmPallet' VersionNotifiers.
|
||||
let keys = storage
|
||||
.fetch_keys::<polkadot::xcm_pallet::storage::VersionNotifiers>(10, None, None)
|
||||
.await?;
|
||||
|
||||
println!("Example 1. Obtained keys:");
|
||||
for key in keys.iter() {
|
||||
println!("Key: 0x{}", hex::encode(&key));
|
||||
|
||||
if let Some(storage_data) = storage.fetch_raw(key.clone(), None).await? {
|
||||
// We know the return value to be `QueryId` (`u64`) from inspecting either:
|
||||
// - polkadot code
|
||||
// - polkadot.rs generated file under `version_notifiers()` fn
|
||||
// - metadata in json format
|
||||
let value = u64::decode(&mut &storage_data.0[..])?;
|
||||
println!(" Value: {}", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Example 2. Iterate over (keys, value) using the storage client.
|
||||
{
|
||||
let mut iter = storage
|
||||
.iter::<polkadot::xcm_pallet::storage::VersionNotifiers>(None)
|
||||
.await?;
|
||||
|
||||
println!("\nExample 2. Obtained keys:");
|
||||
while let Some((key, value)) = iter.next().await? {
|
||||
println!("Key: 0x{}", hex::encode(&key));
|
||||
println!(" Value: {}", value);
|
||||
}
|
||||
}
|
||||
|
||||
// Example 3. Iterate over (keys, value) using the polkadot API.
|
||||
{
|
||||
let mut iter = api
|
||||
.storage()
|
||||
.xcm_pallet()
|
||||
.version_notifiers_iter(None)
|
||||
.await?;
|
||||
|
||||
println!("\nExample 3. Obtained keys:");
|
||||
while let Some((key, value)) = iter.next().await? {
|
||||
println!("Key: 0x{}", hex::encode(&key));
|
||||
println!(" Value: {}", value);
|
||||
}
|
||||
}
|
||||
|
||||
// Example 4. Custom iteration over double maps.
|
||||
{
|
||||
// Obtain the inner RPC from the API.
|
||||
let rpc: &Rpc<_> = api.client.rpc();
|
||||
|
||||
// Obtain the prefixed `twox_128("XcmPallet") ++ twox_128("VersionNotifiers")`
|
||||
let prefix =
|
||||
StorageKeyPrefix::new::<polkadot::xcm_pallet::storage::VersionNotifiers>();
|
||||
// From the VersionNotifiers definition above, the first key is represented by
|
||||
// ```
|
||||
// Twox64Concat,
|
||||
// XcmVersion,
|
||||
// ```
|
||||
// while `XcmVersion` is `u32`.
|
||||
// Pass `2` as `XcmVersion` and concatenate the key to the prefix.
|
||||
let entry_key = StorageEntryKey::Map(vec![StorageMapKey::new(
|
||||
&2u32,
|
||||
::subxt::StorageHasher::Twox64Concat,
|
||||
)]);
|
||||
|
||||
// The final query key is:
|
||||
// `twox_128("XcmPallet") ++ twox_128("VersionNotifiers") ++ twox_64(2u32) ++ 2u32`
|
||||
let query_key = entry_key.final_key(prefix);
|
||||
println!("\nExample 4\nQuery key: 0x{}", hex::encode(&query_key));
|
||||
|
||||
let keys = rpc
|
||||
.storage_keys_paged(Some(query_key), 10, None, None)
|
||||
.await?;
|
||||
|
||||
println!("Obtained keys:");
|
||||
for key in keys.iter() {
|
||||
println!("Key: 0x{}", hex::encode(&key));
|
||||
|
||||
if let Some(storage_data) = storage.fetch_raw(key.clone(), None).await? {
|
||||
// We know the return value to be `QueryId` (`u64`) from inspecting either:
|
||||
// - polkadot code
|
||||
// - polkadot.rs generated file under `version_notifiers()` fn
|
||||
// - metadata in json format
|
||||
let value = u64::decode(&mut &storage_data.0[..])?;
|
||||
println!(" Value: {}", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -2,21 +2,20 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot 0.9.18-4542a603cc-aarch64-macos.
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot polkadot 0.9.25-5174e9ae75b.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.18/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.25/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
|
||||
use futures::StreamExt;
|
||||
use sp_keyring::AccountKeyring;
|
||||
use subxt::{
|
||||
ClientBuilder,
|
||||
DefaultConfig,
|
||||
PairSigner,
|
||||
PolkadotExtrinsicParams,
|
||||
tx::PairSigner,
|
||||
OnlineClient,
|
||||
PolkadotConfig,
|
||||
};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
|
||||
@@ -40,16 +39,13 @@ async fn simple_transfer() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let signer = PairSigner::new(AccountKeyring::Alice.pair());
|
||||
let dest = AccountKeyring::Bob.to_account_id().into();
|
||||
|
||||
let api = ClientBuilder::new()
|
||||
.build()
|
||||
.await?
|
||||
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<_>>>();
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
let balance_transfer_tx = polkadot::tx().balances().transfer(dest, 10_000);
|
||||
|
||||
let balance_transfer = api
|
||||
.tx()
|
||||
.balances()
|
||||
.transfer(dest, 10_000)?
|
||||
.sign_and_submit_then_watch_default(&signer)
|
||||
.sign_and_submit_then_watch_default(&balance_transfer_tx, &signer)
|
||||
.await?
|
||||
.wait_for_finalized_success()
|
||||
.await?;
|
||||
@@ -72,16 +68,13 @@ async fn simple_transfer_separate_events() -> Result<(), Box<dyn std::error::Err
|
||||
let signer = PairSigner::new(AccountKeyring::Alice.pair());
|
||||
let dest = AccountKeyring::Bob.to_account_id().into();
|
||||
|
||||
let api = ClientBuilder::new()
|
||||
.build()
|
||||
.await?
|
||||
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<_>>>();
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
let balance_transfer_tx = polkadot::tx().balances().transfer(dest, 10_000);
|
||||
|
||||
let balance_transfer = api
|
||||
.tx()
|
||||
.balances()
|
||||
.transfer(dest, 10_000)?
|
||||
.sign_and_submit_then_watch_default(&signer)
|
||||
.sign_and_submit_then_watch_default(&balance_transfer_tx, &signer)
|
||||
.await?
|
||||
.wait_for_finalized()
|
||||
.await?;
|
||||
@@ -123,21 +116,18 @@ async fn handle_transfer_events() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let signer = PairSigner::new(AccountKeyring::Alice.pair());
|
||||
let dest = AccountKeyring::Bob.to_account_id().into();
|
||||
|
||||
let api = ClientBuilder::new()
|
||||
.build()
|
||||
.await?
|
||||
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<_>>>();
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
let balance_transfer_tx = polkadot::tx().balances().transfer(dest, 10_000);
|
||||
|
||||
let mut balance_transfer_progress = api
|
||||
.tx()
|
||||
.balances()
|
||||
.transfer(dest, 10_000)?
|
||||
.sign_and_submit_then_watch_default(&signer)
|
||||
.sign_and_submit_then_watch_default(&balance_transfer_tx, &signer)
|
||||
.await?;
|
||||
|
||||
while let Some(ev) = balance_transfer_progress.next().await {
|
||||
let ev = ev?;
|
||||
use subxt::TransactionStatus::*;
|
||||
use subxt::tx::TxStatus::*;
|
||||
|
||||
// Made it into a block, but not finalized.
|
||||
if let InBlock(details) = ev {
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot 0.9.18-4542a603cc-aarch64-macos.
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot polkadot 0.9.25-5174e9ae75b.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.18/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.25/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
|
||||
@@ -14,10 +14,9 @@ use futures::StreamExt;
|
||||
use sp_keyring::AccountKeyring;
|
||||
use std::time::Duration;
|
||||
use subxt::{
|
||||
ClientBuilder,
|
||||
DefaultConfig,
|
||||
PairSigner,
|
||||
PolkadotExtrinsicParams,
|
||||
tx::PairSigner,
|
||||
OnlineClient,
|
||||
PolkadotConfig,
|
||||
};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
|
||||
@@ -29,41 +28,33 @@ pub mod polkadot {}
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
let api = ClientBuilder::new()
|
||||
.build()
|
||||
.await?
|
||||
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
|
||||
// Create a client to use:
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
// Subscribe to any events that occur:
|
||||
let mut event_sub = api.events().subscribe().await?;
|
||||
|
||||
// While this subscription is active, balance transfers are made somewhere:
|
||||
tokio::task::spawn(async {
|
||||
let signer = PairSigner::new(AccountKeyring::Alice.pair());
|
||||
let api =
|
||||
ClientBuilder::new()
|
||||
.build()
|
||||
.await
|
||||
.unwrap()
|
||||
.to_runtime_api::<polkadot::RuntimeApi<
|
||||
DefaultConfig,
|
||||
PolkadotExtrinsicParams<DefaultConfig>,
|
||||
>>();
|
||||
tokio::task::spawn({
|
||||
let api = api.clone();
|
||||
async move {
|
||||
let signer = PairSigner::new(AccountKeyring::Alice.pair());
|
||||
let mut transfer_amount = 1_000_000_000;
|
||||
|
||||
let mut transfer_amount = 1_000_000_000;
|
||||
// Make small balance transfers from Alice to Bob in a loop:
|
||||
loop {
|
||||
let transfer_tx = polkadot::tx().balances().transfer(
|
||||
AccountKeyring::Bob.to_account_id().into(),
|
||||
transfer_amount,
|
||||
);
|
||||
api.tx()
|
||||
.sign_and_submit_default(&transfer_tx, &signer)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Make small balance transfers from Alice to Bob in a loop:
|
||||
loop {
|
||||
api.tx()
|
||||
.balances()
|
||||
.transfer(AccountKeyring::Bob.to_account_id().into(), transfer_amount)
|
||||
.expect("compatible transfer call on runtime node")
|
||||
.sign_and_submit_default(&signer)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
tokio::time::sleep(Duration::from_secs(10)).await;
|
||||
transfer_amount += 100_000_000;
|
||||
tokio::time::sleep(Duration::from_secs(10)).await;
|
||||
transfer_amount += 100_000_000;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -72,29 +63,21 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let events = events?;
|
||||
let block_hash = events.block_hash();
|
||||
|
||||
// We can iterate, statically decoding all events if we want:
|
||||
println!("All events in block {block_hash:?}:");
|
||||
println!(" Static event details:");
|
||||
for event in events.iter() {
|
||||
let event = event?;
|
||||
println!(" {event:?}");
|
||||
}
|
||||
|
||||
// Or we can dynamically decode events:
|
||||
// We can dynamically decode events:
|
||||
println!(" Dynamic event details: {block_hash:?}:");
|
||||
for event in events.iter_raw() {
|
||||
for event in events.iter() {
|
||||
let event = event?;
|
||||
let is_balance_transfer = event
|
||||
.as_event::<polkadot::balances::events::Transfer>()?
|
||||
.is_some();
|
||||
let pallet = event.pallet;
|
||||
let variant = event.variant;
|
||||
let pallet = event.pallet_name();
|
||||
let variant = event.variant_name();
|
||||
println!(
|
||||
" {pallet}::{variant} (is balance transfer? {is_balance_transfer})"
|
||||
);
|
||||
}
|
||||
|
||||
// Or we can dynamically find the first transfer event, ignoring any others:
|
||||
// Or we can find the first transfer event, ignoring any others:
|
||||
let transfer_event =
|
||||
events.find_first::<polkadot::balances::events::Transfer>()?;
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot 0.9.18-4542a603cc-aarch64-macos.
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot polkadot 0.9.25-5174e9ae75b.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.18/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.25/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
|
||||
@@ -14,10 +14,9 @@ use futures::StreamExt;
|
||||
use sp_keyring::AccountKeyring;
|
||||
use std::time::Duration;
|
||||
use subxt::{
|
||||
ClientBuilder,
|
||||
DefaultConfig,
|
||||
PairSigner,
|
||||
PolkadotExtrinsicParams,
|
||||
tx::PairSigner,
|
||||
OnlineClient,
|
||||
PolkadotConfig,
|
||||
};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
|
||||
@@ -29,11 +28,8 @@ pub mod polkadot {}
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
// Subscribe to any events that occur:
|
||||
let api = ClientBuilder::new()
|
||||
.build()
|
||||
.await?
|
||||
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
|
||||
// Create a client to use:
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
// Subscribe to just balance transfer events, making use of `filter_events`
|
||||
// to select a single event type (note the 1-tuple) to filter out and return.
|
||||
@@ -43,29 +39,27 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.await?
|
||||
.filter_events::<(polkadot::balances::events::Transfer,)>();
|
||||
|
||||
// While this subscription is active, we imagine some balance transfers are made somewhere else:
|
||||
tokio::task::spawn(async {
|
||||
let signer = PairSigner::new(AccountKeyring::Alice.pair());
|
||||
let api =
|
||||
ClientBuilder::new()
|
||||
.build()
|
||||
.await
|
||||
.unwrap()
|
||||
.to_runtime_api::<polkadot::RuntimeApi<
|
||||
DefaultConfig,
|
||||
PolkadotExtrinsicParams<DefaultConfig>,
|
||||
>>();
|
||||
// While this subscription is active, balance transfers are made somewhere:
|
||||
tokio::task::spawn({
|
||||
let api = api.clone();
|
||||
async move {
|
||||
let signer = PairSigner::new(AccountKeyring::Alice.pair());
|
||||
let mut transfer_amount = 1_000_000_000;
|
||||
|
||||
// Make small balance transfers from Alice to Bob in a loop:
|
||||
loop {
|
||||
api.tx()
|
||||
.balances()
|
||||
.transfer(AccountKeyring::Bob.to_account_id().into(), 1_000_000_000)
|
||||
.expect("compatible transfer call on runtime node")
|
||||
.sign_and_submit_default(&signer)
|
||||
.await
|
||||
.unwrap();
|
||||
tokio::time::sleep(Duration::from_secs(10)).await;
|
||||
// Make small balance transfers from Alice to Bob in a loop:
|
||||
loop {
|
||||
let transfer_tx = polkadot::tx().balances().transfer(
|
||||
AccountKeyring::Bob.to_account_id().into(),
|
||||
transfer_amount,
|
||||
);
|
||||
api.tx()
|
||||
.sign_and_submit_default(&transfer_tx, &signer)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
tokio::time::sleep(Duration::from_secs(10)).await;
|
||||
transfer_amount += 100_000_000;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -2,67 +2,38 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot 0.9.18-f6d6ab005d-aarch64-macos.
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot polkadot 0.9.25-5174e9ae75b.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.18/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.25/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
|
||||
use sp_keyring::AccountKeyring;
|
||||
use std::time::Duration;
|
||||
use subxt::{
|
||||
ClientBuilder,
|
||||
DefaultConfig,
|
||||
PairSigner,
|
||||
PolkadotExtrinsicParams,
|
||||
OnlineClient,
|
||||
PolkadotConfig,
|
||||
};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
|
||||
pub mod polkadot {}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
let api = ClientBuilder::new()
|
||||
.build()
|
||||
.await?
|
||||
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
|
||||
// Create a client to use:
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
// Start a new tokio task to perform the runtime updates while
|
||||
// utilizing the API for other use cases.
|
||||
let update_client = api.client.updates();
|
||||
let update_client = api.subscribe_to_updates();
|
||||
tokio::spawn(async move {
|
||||
let result = update_client.perform_runtime_updates().await;
|
||||
println!("Runtime update failed with result={:?}", result);
|
||||
});
|
||||
|
||||
// Make multiple transfers to simulate a long running `subxt::Client` use-case.
|
||||
//
|
||||
// Meanwhile, the tokio task above will perform any necessary updates to keep in sync
|
||||
// with the node we've connected to. Transactions submitted in the vicinity of a runtime
|
||||
// update may still fail, however, owing to a race between the update happening and
|
||||
// subxt synchronising its internal state with it.
|
||||
let signer = PairSigner::new(AccountKeyring::Alice.pair());
|
||||
// Make small balance transfers from Alice to Bob:
|
||||
for _ in 0..10 {
|
||||
let hash = api
|
||||
.tx()
|
||||
.balances()
|
||||
.transfer(
|
||||
AccountKeyring::Bob.to_account_id().into(),
|
||||
123_456_789_012_345,
|
||||
)
|
||||
.unwrap()
|
||||
.sign_and_submit_default(&signer)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
println!("Balance transfer extrinsic submitted: {}", hash);
|
||||
tokio::time::sleep(Duration::from_secs(30)).await;
|
||||
}
|
||||
// If this client is kept in use a while, it'll update its metadata and such
|
||||
// as needed when the node it's pointed at updates.
|
||||
tokio::time::sleep(Duration::from_secs(10_000)).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot 0.9.18-4542a603cc-aarch64-macos.
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot polkadot 0.9.25-5174e9ae75b.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.18/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.25/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
|
||||
@@ -14,10 +14,9 @@ use futures::StreamExt;
|
||||
use sp_keyring::AccountKeyring;
|
||||
use std::time::Duration;
|
||||
use subxt::{
|
||||
ClientBuilder,
|
||||
DefaultConfig,
|
||||
PairSigner,
|
||||
PolkadotExtrinsicParams,
|
||||
tx::PairSigner,
|
||||
OnlineClient,
|
||||
PolkadotConfig,
|
||||
};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
|
||||
@@ -29,11 +28,8 @@ pub mod polkadot {}
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
// Subscribe to any events that occur:
|
||||
let api = ClientBuilder::new()
|
||||
.build()
|
||||
.await?
|
||||
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
|
||||
// Create a client to use:
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
// Subscribe to several balance related events. If we ask for more than one event,
|
||||
// we'll be given a correpsonding tuple of `Option`'s, with exactly one
|
||||
@@ -44,29 +40,27 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
polkadot::balances::events::Deposit,
|
||||
)>();
|
||||
|
||||
// While this subscription is active, we imagine some balance transfers are made somewhere else:
|
||||
tokio::task::spawn(async {
|
||||
let signer = PairSigner::new(AccountKeyring::Alice.pair());
|
||||
let api =
|
||||
ClientBuilder::new()
|
||||
.build()
|
||||
.await
|
||||
.unwrap()
|
||||
.to_runtime_api::<polkadot::RuntimeApi<
|
||||
DefaultConfig,
|
||||
PolkadotExtrinsicParams<DefaultConfig>,
|
||||
>>();
|
||||
// While this subscription is active, balance transfers are made somewhere:
|
||||
tokio::task::spawn({
|
||||
let api = api.clone();
|
||||
async move {
|
||||
let signer = PairSigner::new(AccountKeyring::Alice.pair());
|
||||
let mut transfer_amount = 1_000_000_000;
|
||||
|
||||
// Make small balance transfers from Alice to Bob in a loop:
|
||||
loop {
|
||||
api.tx()
|
||||
.balances()
|
||||
.transfer(AccountKeyring::Bob.to_account_id().into(), 1_000_000_000)
|
||||
.expect("compatible transfer call on runtime node")
|
||||
.sign_and_submit_default(&signer)
|
||||
.await
|
||||
.unwrap();
|
||||
tokio::time::sleep(Duration::from_secs(10)).await;
|
||||
// Make small balance transfers from Alice to Bob in a loop:
|
||||
loop {
|
||||
let transfer_tx = polkadot::tx().balances().transfer(
|
||||
AccountKeyring::Bob.to_account_id().into(),
|
||||
transfer_amount,
|
||||
);
|
||||
api.tx()
|
||||
.sign_and_submit_default(&transfer_tx, &signer)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
tokio::time::sleep(Duration::from_secs(10)).await;
|
||||
transfer_amount += 100_000_000;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user