#![allow(missing_docs)] use codec::Encode; use subxt::client::ClientState; use subxt::config::{ Config, ExtrinsicParams, ExtrinsicParamsEncoder, ExtrinsicParamsError, RefineParams, }; use subxt_signer::sr25519::dev; #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")] pub mod runtime {} // We don't need to construct this at runtime, // so an empty enum is appropriate: pub enum CustomConfig {} impl Config for CustomConfig { type Hash = subxt::utils::H256; type AccountId = subxt::utils::AccountId32; type Address = subxt::utils::MultiAddress; type Signature = subxt::utils::MultiSignature; type Hasher = subxt::config::substrate::BlakeTwo256; type Header = subxt::config::substrate::SubstrateHeader; type ExtrinsicParams = CustomExtrinsicParams; type AssetId = u32; } // This represents some arbitrary (and nonsensical) custom parameters that // will be attached to transaction extra and additional payloads: pub struct CustomExtrinsicParams { genesis_hash: T::Hash, tip: u128, foo: bool, } // We can provide a "pretty" interface to allow users to provide these: #[derive(Default)] pub struct CustomExtrinsicParamsBuilder { tip: u128, foo: bool, } impl CustomExtrinsicParamsBuilder { pub fn new() -> Self { Default::default() } pub fn tip(mut self, value: u128) -> Self { self.tip = value; self } pub fn enable_foo(mut self) -> Self { self.foo = true; self } } impl RefineParams for CustomExtrinsicParamsBuilder {} // Describe how to fetch and then encode the params: impl ExtrinsicParams for CustomExtrinsicParams { type Params = CustomExtrinsicParamsBuilder; // Gather together all of the params we will need to encode: fn new(client: &ClientState, params: Self::Params) -> Result { Ok(Self { genesis_hash: client.genesis_hash, tip: params.tip, foo: params.foo, }) } } impl RefineParams for CustomExtrinsicParams {} // Encode the relevant params when asked: impl ExtrinsicParamsEncoder for CustomExtrinsicParams { fn encode_extra_to(&self, v: &mut Vec) { (self.tip, self.foo).encode_to(v); } fn encode_additional_to(&self, v: &mut Vec) { self.genesis_hash.encode_to(v) } } #[tokio::main] async fn main() { // With the config defined, it can be handed to Subxt as follows: let client = subxt::OnlineClient::::new().await.unwrap(); let tx_payload = runtime::tx().system().remark(b"Hello".to_vec()); // Build your custom "Params": let tx_config = CustomExtrinsicParamsBuilder::new().tip(1234).enable_foo(); // And provide them when submitting a transaction: let _ = client .tx() .sign_and_submit_then_watch(&tx_payload, &dev::alice(), tx_config) .await; }