diff --git a/compose-macros/src/lib.rs b/compose-macros/src/lib.rs index 34f00c3ad..f11c7c765 100644 --- a/compose-macros/src/lib.rs +++ b/compose-macros/src/lib.rs @@ -64,10 +64,8 @@ macro_rules! compose_extrinsic_offline { ($signer: expr, $call: expr, $params: expr) => {{ - use $crate::{ - primitives::{ExtrinsicParams, GenericAddress, SignedPayload, UncheckedExtrinsicV4}, - sp_core::{crypto::Pair, Public}, - sp_runtime::{generic::Era, traits::IdentifyAccount, MultiSigner}, + use $crate::primitives::{ + ExtrinsicParams, SignExtrinsic, SignedPayload, UncheckedExtrinsicV4, }; let extra = $params.signed_extra(); @@ -76,14 +74,7 @@ macro_rules! compose_extrinsic_offline { let signature = raw_payload.using_encoded(|payload| $signer.sign(payload)); - let multi_signer: MultiSigner = $signer.public().into(); - - UncheckedExtrinsicV4::new_signed( - $call, - GenericAddress::from(multi_signer.into_account()), - signature.into(), - extra, - ) + UncheckedExtrinsicV4::new_signed($call, $signer.extrinsic_address(), signature, extra) }}; } @@ -102,11 +93,8 @@ macro_rules! compose_extrinsic { $call: expr $(, $args: expr) *) => { { - #[allow(unused_imports)] // For when extrinsic does not use Compact - use $crate::codec::Compact; use $crate::log::debug; use $crate::primitives::UncheckedExtrinsicV4; - use $crate::sp_runtime::generic::Era; debug!("Composing generic extrinsic for module {:?} and call {:?}", $module, $call); let call = $crate::compose_call!($api.metadata().clone(), $module, $call $(, ($args)) *); @@ -117,10 +105,7 @@ macro_rules! compose_extrinsic { $api.extrinsic_params($api.get_nonce().unwrap()) ) } else { - UncheckedExtrinsicV4 { - signature: None, - function: call.clone(), - } + UncheckedExtrinsicV4::new_unsigned(call.clone()) } } }; diff --git a/examples/examples/batch_payout.rs b/examples/examples/batch_payout.rs index 33fc512f6..a8f7ed10c 100644 --- a/examples/examples/batch_payout.rs +++ b/examples/examples/batch_payout.rs @@ -12,13 +12,14 @@ */ use codec::{Decode, Encode}; -use kitchensink_runtime::Runtime; +use kitchensink_runtime::{Runtime, Signature}; use pallet_staking::{ActiveEraInfo, Exposure}; use serde_json::Value; use sp_keyring::AccountKeyring; use sp_runtime::{app_crypto::Ss58Codec, AccountId32}; use substrate_api_client::{ - rpc::JsonrpseeClient, Api, GetStorage, PlainTipExtrinsicParams, SubmitAndWatch, XtStatus, + rpc::JsonrpseeClient, Api, ExtrinsicSigner, GetStorage, PlainTipExtrinsicParams, + SubmitAndWatch, XtStatus, }; const MAX_BATCHED_TRANSACTION: u32 = 9; @@ -47,7 +48,7 @@ async fn main() { let alice = AccountKeyring::Alice.pair(); let client = JsonrpseeClient::with_default_url().unwrap(); let mut api = Api::<_, _, PlainTipExtrinsicParams, Runtime>::new(client).unwrap(); - api.set_signer(alice); + api.set_signer(ExtrinsicSigner::<_, Signature, Runtime>::new(alice)); // Give a valid validator account address, given one is westend chain validator account. let account = @@ -118,7 +119,7 @@ async fn main() { pub fn get_last_reward( account: &AccountId32, api: &substrate_api_client::Api< - sp_core::sr25519::Pair, + ExtrinsicSigner, JsonrpseeClient, PlainTipExtrinsicParams, Runtime, diff --git a/examples/examples/benchmark_bulk_xt.rs b/examples/examples/benchmark_bulk_xt.rs index 39d8ad4dd..ef47730de 100644 --- a/examples/examples/benchmark_bulk_xt.rs +++ b/examples/examples/benchmark_bulk_xt.rs @@ -18,12 +18,24 @@ // run this against test node with // > substrate-test-node --dev --execution native --ws-port 9979 -ltxpool=debug -use kitchensink_runtime::{BalancesCall, Runtime, RuntimeCall}; +use kitchensink_runtime::{AccountId, BalancesCall, Runtime, RuntimeCall, Signature}; +use sp_core::sr25519::Pair; use sp_keyring::AccountKeyring; use substrate_api_client::{ - rpc::JsonrpseeClient, Api, AssetTipExtrinsicParams, GenericAddress, SubmitExtrinsic, + rpc::JsonrpseeClient, Api, AssetTipExtrinsicParams, ExtrinsicSigner as GenericExtrinsicSigner, + SignExtrinsic, SubmitExtrinsic, }; +// Define an extrinsic signer type which sets the generic types of the `GenericExtrinsicSigner`. +// This way, the types don't have to be reassigned with every usage of this type and makes +// the code better readable. +type ExtrinsicSigner = GenericExtrinsicSigner; + +// To access the ExtrinsicAddress type of the Signer, we need to do this via the trait `SignExtrinsic`. +// For better code readability, we define a simple type here and, at the same time, assign the +// AccountId type of the `SignExtrinsic` trait. +type ExtrinsicAddressOf = >::ExtrinsicAddress; + #[tokio::main] async fn main() { env_logger::init(); @@ -34,9 +46,9 @@ async fn main() { // ! Careful: AssetTipExtrinsicParams is used here, because the substrate kitchensink runtime uses assets as tips. But for most // runtimes, the PlainTipExtrinsicParams needs to be used. let mut api = Api::<_, _, AssetTipExtrinsicParams, Runtime>::new(client).unwrap(); - api.set_signer(signer); + api.set_signer(ExtrinsicSigner::new(signer)); - let recipient = AccountKeyring::Bob.to_account_id(); + let recipient: ExtrinsicAddressOf = AccountKeyring::Bob.to_account_id().into(); // We use a manual nonce input here, because otherwise the api retrieves the nonce via getter and needs // to wait for the response of the node (and the actual execution of the previous extrinsic). // But because we want to spam the node with extrinsic, we simple monotonically increase the nonce, without @@ -46,7 +58,7 @@ async fn main() { while nonce < first_nonce + 500 { // Compose a balance extrinsic. let call = RuntimeCall::Balances(BalancesCall::transfer { - dest: GenericAddress::Id(recipient.clone()), + dest: recipient.clone(), value: 1_000_000, }); let xt = api.compose_extrinsic_offline(call, nonce); diff --git a/examples/examples/compose_extrinsic_offline.rs b/examples/examples/compose_extrinsic_offline.rs index e390f0e0d..77ea619d4 100644 --- a/examples/examples/compose_extrinsic_offline.rs +++ b/examples/examples/compose_extrinsic_offline.rs @@ -16,12 +16,12 @@ //! This example shows how to use the compose_extrinsic_offline macro which generates an extrinsic //! without asking the node for nonce and does not need to know the metadata -use kitchensink_runtime::{BalancesCall, Runtime, RuntimeCall}; +use kitchensink_runtime::{BalancesCall, Runtime, RuntimeCall, Signature}; use sp_keyring::AccountKeyring; use sp_runtime::{generic::Era, MultiAddress}; use substrate_api_client::{ - rpc::JsonrpseeClient, Api, AssetTipExtrinsicParams, GenericAdditionalParams, GetHeader, - SubmitAndWatch, XtStatus, + rpc::JsonrpseeClient, Api, AssetTipExtrinsicParams, ExtrinsicSigner, GenericAdditionalParams, + GetHeader, SubmitAndWatch, XtStatus, }; #[tokio::main] @@ -38,7 +38,7 @@ async fn main() { // ! Careful: AssetTipExtrinsicParams is used here, because the substrate kitchensink runtime uses assets as tips. But for most // runtimes, the PlainTipExtrinsicParams needs to be used. let mut api = Api::<_, _, AssetTipExtrinsicParams, Runtime>::new(client).unwrap(); - api.set_signer(signer); + api.set_signer(ExtrinsicSigner::<_, Signature, Runtime>::new(signer)); // Information for Era for mortal transactions (online). let last_finalized_header_hash = api.get_finalized_head().unwrap().unwrap(); diff --git a/examples/examples/contract_instantiate_with_code.rs b/examples/examples/contract_instantiate_with_code.rs index e753cb52b..694f8c7cc 100644 --- a/examples/examples/contract_instantiate_with_code.rs +++ b/examples/examples/contract_instantiate_with_code.rs @@ -16,11 +16,11 @@ //! This example is community maintained and not CI tested, therefore it may not work as is. use codec::Decode; -use kitchensink_runtime::Runtime; +use kitchensink_runtime::{AccountId, Runtime, Signature}; use sp_keyring::AccountKeyring; use substrate_api_client::{ - rpc::JsonrpseeClient, AccountId, Api, PlainTipExtrinsicParams, StaticEvent, SubmitAndWatch, - SubmitAndWatchUntilSuccess, XtStatus, + rpc::JsonrpseeClient, Api, ExtrinsicSigner, PlainTipExtrinsicParams, StaticEvent, + SubmitAndWatch, SubmitAndWatchUntilSuccess, SubscribeEvents, SubscribeFrameSystem, XtStatus, }; #[allow(unused)] @@ -45,7 +45,7 @@ async fn main() { // ! Careful: AssetTipExtrinsicParams is used here, because the substrate kitchensink runtime uses assets as tips. But for most // runtimes, the PlainTipExtrinsicParams needs to be used. let mut api = Api::<_, _, PlainTipExtrinsicParams, Runtime>::new(client).unwrap(); - api.set_signer(signer); + api.set_signer(ExtrinsicSigner::<_, Signature, Runtime>::new(signer)); println!("[+] Alice's Account Nonce is {}", api.get_nonce().unwrap()); diff --git a/examples/examples/custom_nonce.rs b/examples/examples/custom_nonce.rs index 60790a048..babb7bff6 100644 --- a/examples/examples/custom_nonce.rs +++ b/examples/examples/custom_nonce.rs @@ -16,12 +16,12 @@ //! This example shows how to use the compose_extrinsic_offline macro which generates an extrinsic //! without asking the node for nonce and does not need to know the metadata -use kitchensink_runtime::{BalancesCall, Runtime, RuntimeCall}; +use kitchensink_runtime::{BalancesCall, Runtime, RuntimeCall, Signature}; use sp_keyring::AccountKeyring; use sp_runtime::{generic::Era, MultiAddress}; use substrate_api_client::{ - rpc::JsonrpseeClient, Api, AssetTipExtrinsicParams, Error, GenericAdditionalParams, GetHeader, - SubmitAndWatch, UnexpectedTxStatus, XtStatus, + rpc::JsonrpseeClient, Api, AssetTipExtrinsicParams, Error, ExtrinsicSigner, + GenericAdditionalParams, GetHeader, SubmitAndWatch, UnexpectedTxStatus, XtStatus, }; #[tokio::main] @@ -34,7 +34,7 @@ async fn main() { // ! Careful: AssetTipExtrinsicParams is used here, because the substrate kitchensink runtime uses assets as tips. But for most // runtimes, the PlainTipExtrinsicParams needs to be used. let mut api = Api::<_, _, AssetTipExtrinsicParams, Runtime>::new(client).unwrap(); - api.set_signer(signer); + api.set_signer(ExtrinsicSigner::<_, Signature, Runtime>::new(signer)); // Information for Era for mortal transactions. let last_finalized_header_hash = api.get_finalized_head().unwrap().unwrap(); diff --git a/examples/examples/event_callback.rs b/examples/examples/event_callback.rs index 5c132e185..3af852c70 100644 --- a/examples/examples/event_callback.rs +++ b/examples/examples/event_callback.rs @@ -18,7 +18,7 @@ use codec::Decode; use kitchensink_runtime::Runtime; use log::debug; -use sp_core::{sr25519, H256 as Hash}; +use sp_core::H256 as Hash; use substrate_api_client::{ rpc::{HandleSubscription, JsonrpseeClient}, Api, PlainTipExtrinsicParams, SubscribeFrameSystem, @@ -35,8 +35,7 @@ async fn main() { // Initialize the api. let client = JsonrpseeClient::with_default_url().unwrap(); - let api = - Api::, Runtime>::new(client).unwrap(); + let api = Api::<(), _, PlainTipExtrinsicParams, Runtime>::new(client).unwrap(); println!("Subscribe to events"); let mut subscription = api.subscribe_system_events().unwrap(); diff --git a/examples/examples/event_error_details.rs b/examples/examples/event_error_details.rs index 4c6f7dc1b..10c89aa53 100644 --- a/examples/examples/event_error_details.rs +++ b/examples/examples/event_error_details.rs @@ -14,12 +14,13 @@ */ use codec::Decode; -use kitchensink_runtime::Runtime; +use kitchensink_runtime::{Runtime, Signature}; use sp_keyring::AccountKeyring; use sp_runtime::{AccountId32 as AccountId, MultiAddress}; use substrate_api_client::{ - rpc::JsonrpseeClient, Api, AssetTipExtrinsicParams, GetAccountInformation, StaticEvent, - SubmitAndWatchUntilSuccess, + rpc::JsonrpseeClient, Api, AssetTipExtrinsicParams, ExtrinsicSigner, GetAccountInformation, + Result, StaticEvent, SubmitAndWatch, SubmitAndWatchUntilSuccess, SubscribeEvents, + SubscribeFrameSystem, XtStatus, }; #[derive(Decode)] @@ -44,7 +45,7 @@ async fn main() { // ! Careful: AssetTipExtrinsicParams is used here, because the substrate kitchensink runtime uses assets as tips. But for most // runtimes, the PlainTipExtrinsicParams needs to be used. let mut api = Api::<_, _, AssetTipExtrinsicParams, Runtime>::new(client).unwrap(); - api.set_signer(alice_signer); + api.set_signer(ExtrinsicSigner::<_, Signature, Runtime>::new(alice_signer)); let alice = AccountKeyring::Alice.to_account_id(); let balance_of_alice = api.get_account_data(&alice).unwrap().unwrap().free; diff --git a/examples/examples/get_account_identity.rs b/examples/examples/get_account_identity.rs index 23887498a..e237bcbdd 100644 --- a/examples/examples/get_account_identity.rs +++ b/examples/examples/get_account_identity.rs @@ -16,13 +16,13 @@ //! Example to show how to get the account identity display name from the identity pallet. use frame_support::traits::Currency; -use kitchensink_runtime::Runtime as KitchensinkRuntime; +use kitchensink_runtime::{Runtime as KitchensinkRuntime, Signature}; use pallet_identity::{Data, IdentityInfo, Registration}; use sp_core::{crypto::Pair, H256}; use sp_keyring::AccountKeyring; use substrate_api_client::{ - compose_extrinsic, rpc::JsonrpseeClient, Api, AssetTipExtrinsicParams, GetStorage, - SubmitAndWatch, UncheckedExtrinsicV4, XtStatus, + compose_extrinsic, rpc::JsonrpseeClient, Api, AssetTipExtrinsicParams, ExtrinsicSigner, + GetStorage, SubmitAndWatch, UncheckedExtrinsicV4, XtStatus, }; type BalanceOf = <::Currency as Currency< @@ -43,7 +43,7 @@ async fn main() { let mut api = Api::<_, _, AssetTipExtrinsicParams, KitchensinkRuntime>::new(client) .unwrap(); - api.set_signer(signer.clone()); + api.set_signer(ExtrinsicSigner::<_, Signature, KitchensinkRuntime>::new(signer.clone())); // Fill Identity storage. let info = IdentityInfo::> { @@ -58,7 +58,7 @@ async fn main() { twitter: Data::None, }; - let xt: UncheckedExtrinsicV4<_, _> = + let xt: UncheckedExtrinsicV4<_, _, _, _> = compose_extrinsic!(&api, "Identity", "set_identity", Box::new(info.clone())); println!("[+] Composed Extrinsic:\n {:?}\n", xt); diff --git a/examples/examples/get_storage.rs b/examples/examples/get_storage.rs index 35fffbb2c..f87bf175e 100644 --- a/examples/examples/get_storage.rs +++ b/examples/examples/get_storage.rs @@ -16,9 +16,11 @@ //! Very simple example that shows how to get some simple storage values. use frame_system::AccountInfo as GenericAccountInfo; -use kitchensink_runtime::Runtime; +use kitchensink_runtime::{Runtime, Signature}; use sp_keyring::AccountKeyring; -use substrate_api_client::{rpc::JsonrpseeClient, Api, GetStorage, PlainTipExtrinsicParams}; +use substrate_api_client::{ + rpc::JsonrpseeClient, Api, ExtrinsicSigner, GetStorage, PlainTipExtrinsicParams, +}; type IndexFor = ::Index; type AccountDataFor = ::AccountData; @@ -54,7 +56,7 @@ async fn main() { // get Alice's AccountNonce with api.get_nonce() let signer = AccountKeyring::Alice.pair(); - api.set_signer(signer); + api.set_signer(ExtrinsicSigner::<_, Signature, Runtime>::new(signer)); println!("[+] Alice's Account Nonce is {}", api.get_nonce().unwrap()); // Get an vector of storage keys, numbering up to the given max keys and that start with the (optionally) given storage key prefix. diff --git a/examples/examples/sudo.rs b/examples/examples/sudo.rs index 21e35684f..01679ee5c 100644 --- a/examples/examples/sudo.rs +++ b/examples/examples/sudo.rs @@ -17,13 +17,25 @@ //! module, whereas the desired module and call are supplied as a string. use codec::Compact; -use kitchensink_runtime::Runtime; +use kitchensink_runtime::{AccountId, Runtime, Signature}; +use sp_core::sr25519::Pair; use sp_keyring::AccountKeyring; use substrate_api_client::{ compose_call, compose_extrinsic, rpc::JsonrpseeClient, Api, AssetTipExtrinsicParams, - GenericAddress, GetAccountInformation, SubmitAndWatch, UncheckedExtrinsicV4, XtStatus, + ExtrinsicSigner as GenericExtrinsicSigner, GetAccountInformation, SignExtrinsic, + SubmitAndWatch, UncheckedExtrinsicV4, XtStatus, }; +// Define an extrinsic signer type which sets the generic types of the `GenericExtrinsicSigner`. +// This way, the types don't have to be reassigned with every usage of this type and makes +// the code better readable. +type ExtrinsicSigner = GenericExtrinsicSigner; + +// To access the ExtrinsicAddress type of the Signer, we need to do this via the trait `SignExtrinsic`. +// For better code readability, we define a simple type here and, at the same time, assign the +// AccountId type of the `SignExtrinsic` trait. +type ExtrinsicAddressOf = >::ExtrinsicAddress; + #[tokio::main] async fn main() { env_logger::init(); @@ -32,7 +44,7 @@ async fn main() { let sudoer = AccountKeyring::Alice.pair(); let client = JsonrpseeClient::with_default_url().unwrap(); let mut api = Api::<_, _, AssetTipExtrinsicParams, Runtime>::new(client).unwrap(); - api.set_signer(sudoer); + api.set_signer(ExtrinsicSigner::new(sudoer)); // Set the recipient of newly issued funds. let recipient = AccountKeyring::Bob.to_account_id(); @@ -42,17 +54,19 @@ async fn main() { println!("[+] Recipients's Free Balance is now {}\n", recipient_balance); // Compose a call that should only be executable via Sudo. + let recipients_extrinsic_address: ExtrinsicAddressOf = + recipient.clone().into(); let new_balance = recipient_balance + 100; let call = compose_call!( api.metadata(), "Balances", "set_balance", - GenericAddress::Id(recipient.clone()), + recipients_extrinsic_address, Compact(new_balance), Compact(new_balance) ); - let xt: UncheckedExtrinsicV4<_, _> = compose_extrinsic!(&api, "Sudo", "sudo", call); + let xt: UncheckedExtrinsicV4<_, _, _, _> = compose_extrinsic!(&api, "Sudo", "sudo", call); // Send and watch extrinsic until in block. let block_hash = api diff --git a/examples/examples/transfer_with_tungstenite_client.rs b/examples/examples/transfer_with_tungstenite_client.rs index ac281a018..a5d568923 100755 --- a/examples/examples/transfer_with_tungstenite_client.rs +++ b/examples/examples/transfer_with_tungstenite_client.rs @@ -15,15 +15,15 @@ //! Very simple example that shows how to use a predefined extrinsic from the extrinsic module. -use kitchensink_runtime::Runtime; +use kitchensink_runtime::{Runtime, Signature}; use sp_core::{ crypto::{Pair, Ss58Codec}, sr25519, }; use sp_runtime::MultiAddress; use substrate_api_client::{ - rpc::TungsteniteRpcClient, Api, AssetTipExtrinsicParams, GetAccountInformation, SubmitAndWatch, - XtStatus, + rpc::TungsteniteRpcClient, Api, AssetTipExtrinsicParams, ExtrinsicSigner, + GetAccountInformation, SubmitAndWatch, XtStatus, }; fn main() { @@ -40,7 +40,7 @@ fn main() { // Initialize api and set the signer (sender) that is used to sign the extrinsics. let client = TungsteniteRpcClient::with_default_url(100); let mut api = Api::<_, _, AssetTipExtrinsicParams, Runtime>::new(client).unwrap(); - api.set_signer(alice.clone()); + api.set_signer(ExtrinsicSigner::<_, Signature, Runtime>::new(alice.clone())); // Retrieve bobs current balance. let bob = sr25519::Public::from_ss58check("5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty") diff --git a/examples/examples/transfer_with_ws_client.rs b/examples/examples/transfer_with_ws_client.rs index 0f2b14203..fbe93f8f5 100755 --- a/examples/examples/transfer_with_ws_client.rs +++ b/examples/examples/transfer_with_ws_client.rs @@ -15,14 +15,15 @@ //! Very simple example that shows how to use a predefined extrinsic from the extrinsic module. -use kitchensink_runtime::Runtime; +use kitchensink_runtime::{Runtime, Signature}; use sp_core::{ crypto::{Pair, Ss58Codec}, sr25519, }; use sp_runtime::MultiAddress; use substrate_api_client::{ - rpc::WsRpcClient, Api, AssetTipExtrinsicParams, GetAccountInformation, SubmitAndWatch, XtStatus, + rpc::WsRpcClient, Api, AssetTipExtrinsicParams, ExtrinsicSigner, GetAccountInformation, + SubmitAndWatch, XtStatus, }; fn main() { @@ -39,7 +40,7 @@ fn main() { // Initialize api and set the signer (sender) that is used to sign the extrinsics. let client = WsRpcClient::with_default_url(); let mut api = Api::<_, _, AssetTipExtrinsicParams, Runtime>::new(client).unwrap(); - api.set_signer(alice.clone()); + api.set_signer(ExtrinsicSigner::<_, Signature, Runtime>::new(alice.clone())); // Retrieve bobs current balance. let bob = sr25519::Public::from_ss58check("5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty") diff --git a/primitives/src/extrinsics.rs b/primitives/src/extrinsics.rs index 4876ae338..a4d46ad43 100644 --- a/primitives/src/extrinsics.rs +++ b/primitives/src/extrinsics.rs @@ -20,41 +20,46 @@ use alloc::vec::Vec; use codec::{Decode, Encode, Error, Input}; use core::fmt; -use sp_runtime::MultiSignature; - -pub use sp_runtime::{AccountId32 as AccountId, MultiAddress}; - -pub type AccountIndex = u64; - -pub type GenericAddress = sp_runtime::MultiAddress; +/// Call Index used a prefix of every extrinsic call. pub type CallIndex = [u8; 2]; +/// Current version of the [`UncheckedExtrinsic`] encoded format. +const V4: u8 = 4; + /// Mirrors the currently used Extrinsic format (V4) from substrate. Has less traits and methods though. /// The SingedExtra used does not need to implement SingedExtension here. +// see https://github.com/paritytech/substrate/blob/7d233c2446b5a60662400a0a4bcfb78bb3b79ff7/primitives/runtime/src/generic/unchecked_extrinsic.rs #[derive(Clone, Eq, PartialEq)] -pub struct UncheckedExtrinsicV4 { - pub signature: Option<(GenericAddress, MultiSignature, SignedExtra)>, +pub struct UncheckedExtrinsicV4 { + pub signature: Option<(Address, Signature, SignedExtra)>, pub function: Call, } -impl UncheckedExtrinsicV4 -where - Call: Encode, - SignedExtra: Encode, +impl + UncheckedExtrinsicV4 { + /// New instance of a signed extrinsic. pub fn new_signed( function: Call, - signed: GenericAddress, - signature: MultiSignature, + signed: Address, + signature: Signature, extra: SignedExtra, ) -> Self { UncheckedExtrinsicV4 { signature: Some((signed, signature, extra)), function } } + + /// New instance of an unsigned extrinsic. + pub fn new_unsigned(function: Call) -> Self { + Self { signature: None, function } + } } -impl fmt::Debug for UncheckedExtrinsicV4 +impl fmt::Debug + for UncheckedExtrinsicV4 where + Address: fmt::Debug, + Signature: fmt::Debug, Call: fmt::Debug, SignedExtra: fmt::Debug, { @@ -68,10 +73,11 @@ where } } -const V4: u8 = 4; - -impl Encode for UncheckedExtrinsicV4 +impl Encode + for UncheckedExtrinsicV4 where + Address: Encode, + Signature: Encode, Call: Encode, SignedExtra: Encode, { @@ -91,10 +97,13 @@ where } } -impl Decode for UncheckedExtrinsicV4 +impl Decode + for UncheckedExtrinsicV4 where - Call: Decode + Encode, - SignedExtra: Decode + Encode, + Address: Decode, + Signature: Decode, + Call: Decode, + SignedExtra: Decode, { fn decode(input: &mut I) -> Result { // This is a little more complicated than usual since the binary format must be compatible @@ -146,7 +155,7 @@ mod tests { use super::*; use crate::{ExtrinsicParams, GenericAdditionalParams, GenericExtrinsicParams, PlainTip}; use sp_core::{Pair, H256 as Hash}; - use sp_runtime::{generic::Era, testing::sr25519, MultiSignature}; + use sp_runtime::{generic::Era, testing::sr25519, AccountId32, MultiSignature}; #[test] fn encode_decode_roundtrip_works() { @@ -154,7 +163,7 @@ mod tests { let (pair, _) = sr25519::Pair::generate(); let signature = pair.sign(msg); let multi_sig = MultiSignature::from(signature); - let account: AccountId = pair.public().into(); + let account: AccountId32 = pair.public().into(); let tx_params = GenericAdditionalParams::, Hash>::new() .era(Era::mortal(8, 0), Hash::from([0u8; 32])); @@ -162,7 +171,7 @@ mod tests { GenericExtrinsicParams::new(0, 0, 0u32, Hash::from([0u8; 32]), tx_params); let xt = UncheckedExtrinsicV4::new_signed( vec![1, 1, 1], - account.into(), + account, multi_sig, default_extra.signed_extra(), ); diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index b613bd456..f3d607435 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -25,6 +25,7 @@ pub use pallet_traits::*; pub use rpc_numbers::*; pub use rpc_params::RpcParams; pub use serde_impls::*; +pub use signer::*; pub use types::*; pub mod extrinsic_params; @@ -33,4 +34,5 @@ pub mod pallet_traits; pub mod rpc_numbers; pub mod rpc_params; pub mod serde_impls; +pub mod signer; pub mod types; diff --git a/primitives/src/signer.rs b/primitives/src/signer.rs new file mode 100644 index 000000000..f1433aa10 --- /dev/null +++ b/primitives/src/signer.rs @@ -0,0 +1,92 @@ +/* + Copyright 2019 Supercomputing Systems AG + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +//! Signer used to sign extrinsic. + +use crate::FrameSystemConfig; +use codec::{Decode, Encode}; +use core::marker::PhantomData; +use sp_core::Pair; +use sp_runtime::traits::StaticLookup; + +pub trait SignExtrinsic { + type Signature; + type ExtrinsicAddress: Clone + Encode; + + /// Sign a given payload and return the resulting Signature. + fn sign(&self, payload: &[u8]) -> Self::Signature; + + /// Return the public account id of the key pair. + fn public_account_id(&self) -> &AccountId; + + /// Return the public address of the key pair. This is needed for the + /// extrinsic creation, as substrate requires a Lookup transformation + /// from Address to AccoundId. + fn extrinsic_address(&self) -> Self::ExtrinsicAddress; +} + +#[derive(Encode, Decode, Clone, PartialEq)] +pub struct ExtrinsicSigner +where + Signer: Pair, + Runtime: FrameSystemConfig, +{ + signer: Signer, + account_id: Runtime::AccountId, + extrinsic_address: ::Source, + _phantom: PhantomData, +} + +impl ExtrinsicSigner +where + Signer: Pair, + Runtime: FrameSystemConfig, + Runtime::AccountId: From, +{ + pub fn new(signer: Signer) -> Self { + let account_id: Runtime::AccountId = signer.public().into(); + let extrinsic_address = Runtime::Lookup::unlookup(account_id.clone()); + Self { signer, account_id, extrinsic_address, _phantom: Default::default() } + } + + pub fn signer(&self) -> &Signer { + &self.signer + } +} + +impl SignExtrinsic + for ExtrinsicSigner +where + Runtime: FrameSystemConfig, + Signer: Pair, + Signature: From, +{ + type Signature = Signature; + type ExtrinsicAddress = ::Source; + + fn sign(&self, payload: &[u8]) -> Self::Signature { + self.signer.sign(payload).into() + } + + fn public_account_id(&self) -> &Runtime::AccountId { + &self.account_id + } + + fn extrinsic_address(&self) -> Self::ExtrinsicAddress { + self.extrinsic_address.clone() + } +} diff --git a/src/api/api_client.rs b/src/api/api_client.rs index fefc612fb..c25895506 100644 --- a/src/api/api_client.rs +++ b/src/api/api_client.rs @@ -18,13 +18,11 @@ use crate::{ }; use ac_compose_macros::rpc_params; use ac_node_api::metadata::Metadata; -use ac_primitives::{Bytes, ExtrinsicParams, FrameSystemConfig, RuntimeVersion}; +use ac_primitives::{Bytes, ExtrinsicParams, FrameSystemConfig, RuntimeVersion, SignExtrinsic}; use codec::Decode; use core::convert::TryFrom; use frame_metadata::RuntimeMetadataPrefixed; use log::{debug, info}; -use sp_core::Pair; -use sp_runtime::MultiSignature; /// Api to talk with substrate-nodes /// @@ -209,23 +207,21 @@ where impl Api where - Signer: Pair, - MultiSignature: From, + Signer: SignExtrinsic, Client: Request, Params: ExtrinsicParams, Runtime: FrameSystemConfig, - Runtime::AccountId: From, { /// Get the public part of the api signer account. - pub fn signer_account(&self) -> Option { + pub fn signer_account(&self) -> Option<&Runtime::AccountId> { let pair = self.signer.as_ref()?; - Some(pair.public().into()) + Some(pair.public_account_id()) } /// Get nonce of self signer account. pub fn get_nonce(&self) -> Result { let account = self.signer_account().ok_or(Error::NoSigner)?; - self.get_account_info(&account) + self.get_account_info(account) .map(|acc_opt| acc_opt.map_or_else(|| 0u32.into(), |acc| acc.nonce)) } } diff --git a/src/api/rpc_api/author.rs b/src/api/rpc_api/author.rs index 25df82d19..7c9d7b2bb 100644 --- a/src/api/rpc_api/author.rs +++ b/src/api/rpc_api/author.rs @@ -37,12 +37,14 @@ pub trait SubmitExtrinsic { /// Submit an encodable extrinsic to the substrate node. /// Returns the extrinsic hash. - fn submit_extrinsic( + fn submit_extrinsic( &self, - extrinsic: UncheckedExtrinsicV4, + extrinsic: UncheckedExtrinsicV4, ) -> Result where + Address: Encode, Call: Encode, + Signature: Encode, SignedExtra: Encode; /// Submit an encoded, opaque extrsinic to the substrate node. @@ -58,12 +60,14 @@ where { type Hash = Runtime::Hash; - fn submit_extrinsic( + fn submit_extrinsic( &self, - extrinsic: UncheckedExtrinsicV4, + extrinsic: UncheckedExtrinsicV4, ) -> Result where + Address: Encode, Call: Encode, + Signature: Encode, SignedExtra: Encode, { self.submit_opaque_extrinsic(extrinsic.encode().into()) @@ -84,12 +88,14 @@ where { /// Submit an extrinsic an return a Subscription /// to watch the extrinsic progress. - fn submit_and_watch_extrinsic( + fn submit_and_watch_extrinsic( &self, - extrinsic: UncheckedExtrinsicV4, + extrinsic: UncheckedExtrinsicV4, ) -> Result> where + Address: Encode, Call: Encode, + Signature: Encode, SignedExtra: Encode; /// Submit an encoded, opaque extrinsic an return a Subscription to @@ -107,13 +113,15 @@ where /// hash of the block the extrinsic was included in /// - last known extrinsic (transaction) status /// This method is blocking. - fn submit_and_watch_extrinsic_until( + fn submit_and_watch_extrinsic_until( &self, - extrinsic: UncheckedExtrinsicV4, + extrinsic: UncheckedExtrinsicV4, watch_until: XtStatus, ) -> Result> where + Address: Encode, Call: Encode, + Signature: Encode, SignedExtra: Encode; /// Submit an encoded, opaque extrinsic and watch it until the desired status @@ -146,13 +154,15 @@ where /// - last known extrinsic (transaction) status /// - associated events of the extrinsic /// This method is blocking. - fn submit_and_watch_extrinsic_until_success( + fn submit_and_watch_extrinsic_until_success( &self, - extrinsic: UncheckedExtrinsicV4, + extrinsic: UncheckedExtrinsicV4, wait_for_finalized: bool, ) -> Result> where + Address: Encode, Call: Encode, + Signature: Encode, SignedExtra: Encode; /// Submit an encoded, opaque extrinsic and watch it until @@ -180,12 +190,14 @@ where Runtime: FrameSystemConfig, Runtime::Hashing: HashTrait, { - fn submit_and_watch_extrinsic( + fn submit_and_watch_extrinsic( &self, - extrinsic: UncheckedExtrinsicV4, + extrinsic: UncheckedExtrinsicV4, ) -> Result> where + Address: Encode, Call: Encode, + Signature: Encode, SignedExtra: Encode, { self.submit_and_watch_opaque_extrinsic(extrinsic.encode().into()) @@ -203,13 +215,15 @@ where .map_err(|e| e.into()) } - fn submit_and_watch_extrinsic_until( + fn submit_and_watch_extrinsic_until( &self, - extrinsic: UncheckedExtrinsicV4, + extrinsic: UncheckedExtrinsicV4, watch_until: XtStatus, ) -> Result> where + Address: Encode, Call: Encode, + Signature: Encode, SignedExtra: Encode, { self.submit_and_watch_opaque_extrinsic_until(extrinsic.encode().into(), watch_until) @@ -257,13 +271,15 @@ where Runtime::RuntimeBlock: BlockTrait + DeserializeOwned, Runtime::Hashing: HashTrait, { - fn submit_and_watch_extrinsic_until_success( + fn submit_and_watch_extrinsic_until_success( &self, - extrinsic: UncheckedExtrinsicV4, + extrinsic: UncheckedExtrinsicV4, wait_for_finalized: bool, ) -> Result> where + Address: Encode, Call: Encode, + Signature: Encode, SignedExtra: Encode, { self.submit_and_watch_opaque_extrinsic_until_success( diff --git a/src/api/rpc_api/frame_system.rs b/src/api/rpc_api/frame_system.rs index 9f138a995..d33e25aa2 100644 --- a/src/api/rpc_api/frame_system.rs +++ b/src/api/rpc_api/frame_system.rs @@ -19,13 +19,11 @@ use crate::{ }; use ac_compose_macros::rpc_params; use ac_primitives::{ - AccountInfo, ExtrinsicParams, FrameSystemConfig, StorageChangeSet, StorageKey, + AccountInfo, ExtrinsicParams, FrameSystemConfig, SignExtrinsic, StorageChangeSet, StorageKey, }; use alloc::{string::String, vec, vec::Vec}; use log::*; use serde::de::DeserializeOwned; -use sp_core::Pair; -use sp_runtime::MultiSignature; pub trait GetAccountInformation { type Index; @@ -42,8 +40,7 @@ pub trait GetAccountInformation { impl GetAccountInformation for Api where - Signer: Pair, - MultiSignature: From, + Signer: SignExtrinsic, Client: Request, Runtime: FrameSystemConfig, Params: ExtrinsicParams, diff --git a/src/extrinsic/balances.rs b/src/extrinsic/balances.rs index 18d208754..d4de4fe84 100644 --- a/src/extrinsic/balances.rs +++ b/src/extrinsic/balances.rs @@ -20,54 +20,60 @@ use crate::{api::Api, rpc::Request}; use ac_compose_macros::compose_extrinsic; use ac_primitives::{ - BalancesConfig, CallIndex, ExtrinsicParams, GenericAddress, UncheckedExtrinsicV4, + BalancesConfig, CallIndex, ExtrinsicParams, SignExtrinsic, UncheckedExtrinsicV4, }; use alloc::borrow::ToOwned; use codec::{Compact, Encode}; use serde::de::DeserializeOwned; -use sp_core::crypto::Pair; -use sp_runtime::{traits::GetRuntimeBlockType, MultiSignature, MultiSigner}; +use sp_runtime::traits::GetRuntimeBlockType; pub const BALANCES_MODULE: &str = "Balances"; pub const BALANCES_TRANSFER: &str = "transfer"; pub const BALANCES_SET_BALANCE: &str = "set_balance"; -pub type BalanceTransferFn = (CallIndex, GenericAddress, Compact); -pub type BalanceSetBalanceFn = - (CallIndex, GenericAddress, Compact, Compact); +pub type BalanceTransferFn = (CallIndex, Address, Compact); +pub type BalanceSetBalanceFn = + (CallIndex, Address, Compact, Compact); -pub type BalanceTransferXt = - UncheckedExtrinsicV4, SignedExtra>; -pub type BalanceSetBalanceXt = - UncheckedExtrinsicV4, SignedExtra>; +pub type BalanceTransferXt = + UncheckedExtrinsicV4, Signature, SignedExtra>; +pub type BalanceSetBalanceXt = + UncheckedExtrinsicV4, Signature, SignedExtra>; impl Api where - Signer: Pair, - MultiSignature: From, - MultiSigner: From, + Signer: SignExtrinsic, Client: Request, Runtime: GetRuntimeBlockType + BalancesConfig, Params: ExtrinsicParams, Compact: Encode, Runtime::Header: DeserializeOwned, Runtime::RuntimeBlock: DeserializeOwned, - Runtime::AccountId: From, { pub fn balance_transfer( &self, - to: GenericAddress, + to: Signer::ExtrinsicAddress, amount: Runtime::Balance, - ) -> BalanceTransferXt { + ) -> BalanceTransferXt< + Signer::ExtrinsicAddress, + Runtime::Balance, + Signer::Signature, + Params::SignedExtra, + > { compose_extrinsic!(self, BALANCES_MODULE, BALANCES_TRANSFER, to, Compact(amount)) } pub fn balance_set_balance( &self, - who: GenericAddress, + who: Signer::ExtrinsicAddress, free_balance: Runtime::Balance, reserved_balance: Runtime::Balance, - ) -> BalanceSetBalanceXt { + ) -> BalanceSetBalanceXt< + Signer::ExtrinsicAddress, + Runtime::Balance, + Signer::Signature, + Params::SignedExtra, + > { compose_extrinsic!( self, BALANCES_MODULE, diff --git a/src/extrinsic/common.rs b/src/extrinsic/common.rs index 254a612a8..29a89b200 100644 --- a/src/extrinsic/common.rs +++ b/src/extrinsic/common.rs @@ -19,11 +19,10 @@ use alloc::vec::Vec; use codec::{Decode, Encode}; -use sp_runtime::AccountId32; #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)] -pub struct PayoutStakers { - pub validator_stash: AccountId32, +pub struct PayoutStakers { + pub validator_stash: AccountId, pub era: u32, } #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] diff --git a/src/extrinsic/contracts.rs b/src/extrinsic/contracts.rs index 59f1c0185..e06003089 100644 --- a/src/extrinsic/contracts.rs +++ b/src/extrinsic/contracts.rs @@ -21,14 +21,13 @@ use crate::{api::Api, rpc::Request}; use ac_compose_macros::compose_extrinsic; use ac_primitives::{ - BalancesConfig, CallIndex, ContractsConfig, ExtrinsicParams, FrameSystemConfig, GenericAddress, + BalancesConfig, CallIndex, ContractsConfig, ExtrinsicParams, FrameSystemConfig, SignExtrinsic, UncheckedExtrinsicV4, }; use alloc::vec::Vec; use codec::{Compact, Encode}; use serde::de::DeserializeOwned; -use sp_core::crypto::Pair; -use sp_runtime::{traits::GetRuntimeBlockType, MultiSignature, MultiSigner}; +use sp_runtime::traits::GetRuntimeBlockType; pub const CONTRACTS_MODULE: &str = "Contracts"; pub const CONTRACTS_PUT_CODE: &str = "put_code"; @@ -44,39 +43,49 @@ type Salt = Vec; type GasLimit = Compact; type Endowment = Compact; type Value = Compact; -type Destination = GenericAddress; pub type ContractPutCodeFn = (CallIndex, GasLimit, Data); pub type ContractInstantiateFn = (CallIndex, Endowment, GasLimit, Hash, Data); pub type ContractInstantiateWithCodeFn = (CallIndex, Endowment, GasLimit, Code, Data, Salt); -pub type ContractCallFn = (CallIndex, Destination, Value, GasLimit, Data); +pub type ContractCallFn = (CallIndex, Address, Value, GasLimit, Data); -pub type ContractPutCodeXt = UncheckedExtrinsicV4; -pub type ContractInstantiateXt = - UncheckedExtrinsicV4, SignedExtra>; -pub type ContractInstantiateWithCodeXt = - UncheckedExtrinsicV4, SignedExtra>; -pub type ContractCallXt = - UncheckedExtrinsicV4, SignedExtra>; +pub type ContractPutCodeXt = + UncheckedExtrinsicV4; +pub type ContractInstantiateXt = + UncheckedExtrinsicV4, Signature, SignedExtra>; +pub type ContractInstantiateWithCodeXt = + UncheckedExtrinsicV4, Signature, SignedExtra>; +pub type ContractCallXt = + UncheckedExtrinsicV4, Signature, SignedExtra>; #[cfg(feature = "std")] type BalanceOf = <::Currency as frame_support::traits::Currency< ::AccountId, >>::Balance; +type ExtrinsicAddressOf = >::ExtrinsicAddress; +type SignatureOf = >::Signature; +type HashOf = ::Hash; +type AccountIdOf = ::AccountId; + +#[cfg(feature = "std")] +type ContractInstantiateXtOf = ContractInstantiateXt< + ExtrinsicAddressOf>, + SignatureOf>, + SignedExtra, + BalanceOf, + HashOf, +>; #[cfg(feature = "std")] impl Api where - Signer: Pair, - MultiSignature: From, - MultiSigner: From, + Signer: SignExtrinsic, Client: Request, Params: ExtrinsicParams, Runtime: GetRuntimeBlockType + ContractsConfig + BalancesConfig, Compact>: Encode + Clone, - Runtime::AccountId: From, Runtime::Currency: frame_support::traits::Currency, Runtime::Header: DeserializeOwned, Runtime::RuntimeBlock: DeserializeOwned, @@ -85,7 +94,7 @@ where &self, gas_limit: Gas, code: Data, - ) -> ContractPutCodeXt { + ) -> ContractPutCodeXt { compose_extrinsic!(self, CONTRACTS_MODULE, CONTRACTS_PUT_CODE, Compact(gas_limit), code) } @@ -95,7 +104,7 @@ where gas_limit: Gas, code_hash: Runtime::Hash, data: Data, - ) -> ContractInstantiateXt, Runtime::Hash> { + ) -> ContractInstantiateXtOf { compose_extrinsic!( self, CONTRACTS_MODULE, @@ -114,7 +123,12 @@ where code: Data, data: Data, salt: Data, - ) -> ContractInstantiateWithCodeXt> { + ) -> ContractInstantiateWithCodeXt< + Signer::ExtrinsicAddress, + Signer::Signature, + Params::SignedExtra, + BalanceOf, + > { compose_extrinsic!( self, CONTRACTS_MODULE, @@ -129,11 +143,16 @@ where pub fn contract_call( &self, - dest: GenericAddress, + dest: Signer::ExtrinsicAddress, value: BalanceOf, gas_limit: Gas, data: Data, - ) -> ContractCallXt> { + ) -> ContractCallXt< + Signer::ExtrinsicAddress, + Signer::Signature, + Params::SignedExtra, + BalanceOf, + > { compose_extrinsic!( self, CONTRACTS_MODULE, diff --git a/src/extrinsic/offline_extrinsic.rs b/src/extrinsic/offline_extrinsic.rs index b88806c81..7ef57e8a2 100644 --- a/src/extrinsic/offline_extrinsic.rs +++ b/src/extrinsic/offline_extrinsic.rs @@ -19,26 +19,22 @@ use crate::Api; use ac_compose_macros::compose_extrinsic_offline; -use ac_primitives::{ExtrinsicParams, FrameSystemConfig, UncheckedExtrinsicV4}; +use ac_primitives::{ExtrinsicParams, FrameSystemConfig, SignExtrinsic, UncheckedExtrinsicV4}; use codec::Encode; -use sp_core::Pair; -use sp_runtime::{MultiSignature, MultiSigner}; impl Api where - Signer: Pair, - MultiSignature: From, - MultiSigner: From, + Signer: SignExtrinsic, Params: ExtrinsicParams, Runtime: FrameSystemConfig, - Runtime::AccountId: From, { /// Wrapper around the `compose_extrinsic_offline!` macro to be less verbose. pub fn compose_extrinsic_offline( &self, call: Call, nonce: Runtime::Index, - ) -> UncheckedExtrinsicV4 { + ) -> UncheckedExtrinsicV4 + { match self.signer() { Some(signer) => compose_extrinsic_offline!(signer, call, self.extrinsic_params(nonce)), None => UncheckedExtrinsicV4 { signature: None, function: call }, diff --git a/src/extrinsic/staking.rs b/src/extrinsic/staking.rs index 75e6a8a25..395e7c97b 100644 --- a/src/extrinsic/staking.rs +++ b/src/extrinsic/staking.rs @@ -21,13 +21,12 @@ use super::common::*; use crate::{rpc::Request, Api}; use ac_compose_macros::compose_extrinsic; use ac_primitives::{ - BalancesConfig, CallIndex, ExtrinsicParams, GenericAddress, RewardDestination, StakingConfig, + BalancesConfig, CallIndex, ExtrinsicParams, RewardDestination, SignExtrinsic, StakingConfig, UncheckedExtrinsicV4, }; use codec::{Compact, Encode}; use serde::de::DeserializeOwned; -use sp_core::Pair; -use sp_runtime::{traits::GetRuntimeBlockType, AccountId32, MultiSignature, MultiSigner}; +use sp_runtime::traits::GetRuntimeBlockType; const STAKING_MODULE: &str = "Staking"; const STAKING_BOND: &str = "bond"; @@ -45,57 +44,58 @@ const FORCE_NO_ERA: &str = "force_no_era"; const STAKING_SET_PAYEE: &str = "set_payee"; const SET_VALIDATOR_COUNT: &str = "set_validator_count"; -pub type StakingBondFn = - (CallIndex, GenericAddress, Compact, RewardDestination); +pub type StakingBondFn = + (CallIndex, Address, Compact, RewardDestination
); pub type StakingBondExtraFn = (CallIndex, Compact); pub type StakingUnbondFn = (CallIndex, Compact); pub type StakingRebondFn = (CallIndex, Compact); pub type StakingWithdrawUnbondedFn = (CallIndex, u32); -pub type StakingNominateFn = (CallIndex, Vec); +pub type StakingNominateFn
= (CallIndex, Vec
); pub type StakingChillFn = CallIndex; -pub type StakingSetControllerFn = (CallIndex, GenericAddress); -pub type StakingPayoutStakersFn = (CallIndex, PayoutStakers); +pub type StakingSetControllerFn
= (CallIndex, Address); +pub type StakingPayoutStakersFn = (CallIndex, PayoutStakers); pub type StakingForceNewEraFn = (CallIndex, ForceEra); pub type StakingForceNewEraAlwaysFn = (CallIndex, ForceEra); pub type StakingForceNoEraFn = (CallIndex, ForceEra); -pub type StakingSetPayeeFn = (CallIndex, GenericAddress); +pub type StakingSetPayeeFn
= (CallIndex, Address); pub type StakingSetValidatorCountFn = (CallIndex, u32); -pub type StakingBondXt = - UncheckedExtrinsicV4, SignedExtra>; -pub type StakingBondExtraXt = - UncheckedExtrinsicV4, SignedExtra>; -pub type StakingUnbondXt = - UncheckedExtrinsicV4, SignedExtra>; -pub type StakingRebondXt = - UncheckedExtrinsicV4, SignedExtra>; -pub type StakingWithdrawUnbondedXt = - UncheckedExtrinsicV4; -pub type StakingNominateXt = UncheckedExtrinsicV4; -pub type StakingChillXt = UncheckedExtrinsicV4; -pub type StakingSetControllerXt = - UncheckedExtrinsicV4; -pub type StakingPayoutStakersXt = - UncheckedExtrinsicV4; -pub type StakingForceNewEraXt = - UncheckedExtrinsicV4; -pub type StakingForceNewEraAlwaysXt = - UncheckedExtrinsicV4; -pub type StakingForceNoEraXt = UncheckedExtrinsicV4; -pub type StakingSetPayeeXt = UncheckedExtrinsicV4; -pub type StakingSetValidatorCountXt = - UncheckedExtrinsicV4; +pub type StakingBondXt = + UncheckedExtrinsicV4, Signature, SignedExtra>; +pub type StakingBondExtraXt = + UncheckedExtrinsicV4, Signature, SignedExtra>; +pub type StakingUnbondXt = + UncheckedExtrinsicV4, Signature, SignedExtra>; +pub type StakingRebondXt = + UncheckedExtrinsicV4, Signature, SignedExtra>; +pub type StakingWithdrawUnbondedXt = + UncheckedExtrinsicV4; +pub type StakingNominateXt = + UncheckedExtrinsicV4, Signature, SignedExtra>; +pub type StakingChillXt = + UncheckedExtrinsicV4; +pub type StakingSetControllerXt = + UncheckedExtrinsicV4, Signature, SignedExtra>; +pub type StakingPayoutStakersXt = + UncheckedExtrinsicV4, Signature, SignedExtra>; +pub type StakingForceNewEraXt = + UncheckedExtrinsicV4; +pub type StakingForceNewEraAlwaysXt = + UncheckedExtrinsicV4; +pub type StakingForceNoEraXt = + UncheckedExtrinsicV4; +pub type StakingSetPayeeXt = + UncheckedExtrinsicV4, Signature, SignedExtra>; +pub type StakingSetValidatorCountXt = + UncheckedExtrinsicV4; // https://polkadot.js.org/docs/substrate/extrinsics#staking impl Api where - Signer: Pair, - MultiSignature: From, - MultiSigner: From, + Signer: SignExtrinsic, Client: Request, Params: ExtrinsicParams, Runtime: GetRuntimeBlockType + BalancesConfig + StakingConfig, - Runtime::AccountId: From, Compact: Encode, Runtime::Header: DeserializeOwned, Runtime::RuntimeBlock: DeserializeOwned, @@ -103,10 +103,15 @@ where /// Bond `value` amount to `controller` pub fn staking_bond( &self, - controller: GenericAddress, + controller: Signer::ExtrinsicAddress, value: Runtime::CurrencyBalance, - payee: RewardDestination, - ) -> StakingBondXt { + payee: RewardDestination, + ) -> StakingBondXt< + Signer::ExtrinsicAddress, + Signer::Signature, + Params::SignedExtra, + Runtime::CurrencyBalance, + > { compose_extrinsic!(self, STAKING_MODULE, STAKING_BOND, controller, Compact(value), payee) } @@ -114,7 +119,12 @@ where pub fn staking_bond_extra( &self, value: Runtime::CurrencyBalance, - ) -> StakingBondExtraXt { + ) -> StakingBondExtraXt< + Signer::ExtrinsicAddress, + Signer::Signature, + Params::SignedExtra, + Runtime::CurrencyBalance, + > { compose_extrinsic!(self, STAKING_MODULE, STAKING_BOND_EXTRA, Compact(value)) } @@ -124,7 +134,12 @@ where pub fn staking_unbond( &self, value: Runtime::CurrencyBalance, - ) -> StakingUnbondXt { + ) -> StakingUnbondXt< + Signer::ExtrinsicAddress, + Signer::Signature, + Params::SignedExtra, + Runtime::CurrencyBalance, + > { compose_extrinsic!(self, STAKING_MODULE, STAKING_UNBOND, Compact(value)) } @@ -132,7 +147,12 @@ where pub fn staking_rebond( &self, value: Runtime::CurrencyBalance, - ) -> StakingRebondXt { + ) -> StakingRebondXt< + Signer::ExtrinsicAddress, + Signer::Signature, + Params::SignedExtra, + Runtime::CurrencyBalance, + > { compose_extrinsic!(self, STAKING_MODULE, STAKING_REBOND, Compact(value)) } @@ -142,7 +162,8 @@ where pub fn staking_withdraw_unbonded( &self, num_slashing_spans: u32, - ) -> StakingWithdrawUnbondedXt { + ) -> StakingWithdrawUnbondedXt + { compose_extrinsic!(self, STAKING_MODULE, STAKING_WITHDRAW_UNBONDED, num_slashing_spans) } @@ -150,13 +171,15 @@ where /// Must be signed by the controller of the stash and called when EraElectionStatus is Closed. pub fn staking_nominate( &self, - targets: Vec, - ) -> StakingNominateXt { + targets: Vec, + ) -> StakingNominateXt { compose_extrinsic!(self, STAKING_MODULE, STAKING_NOMINATE, targets) } /// Stop nominating por validating. Effects take place in the next era - pub fn staking_chill(&self) -> StakingChillXt { + pub fn staking_chill( + &self, + ) -> StakingChillXt { compose_extrinsic!(self, STAKING_MODULE, STAKING_CHILL) } @@ -165,37 +188,54 @@ where /// Must be Signed by the stash, not the controller. pub fn staking_set_controller( &self, - controller: GenericAddress, - ) -> StakingSetControllerXt { + controller: Signer::ExtrinsicAddress, + ) -> StakingSetControllerXt { compose_extrinsic!(self, STAKING_MODULE, STAKING_SET_CONTROLLER, controller) } + /// Return the payout call for the given era pub fn payout_stakers( &self, era: u32, - account: AccountId32, - ) -> StakingPayoutStakersXt { + account: Runtime::AccountId, + ) -> StakingPayoutStakersXt< + Signer::ExtrinsicAddress, + Signer::Signature, + Params::SignedExtra, + Runtime::AccountId, + > { let value = PayoutStakers { validator_stash: account, era }; compose_extrinsic!(self, STAKING_MODULE, PAYOUT_STAKERS, value) } /// For New Era at the end of Next Session. - pub fn force_new_era(&self) -> StakingForceNewEraXt { + pub fn force_new_era( + &self, + ) -> StakingForceNewEraXt { compose_extrinsic!(self, STAKING_MODULE, FORCE_NEW_ERA, ForceEra {}) } /// Force there to be a new era at the end of sessions indefinitely. - pub fn force_new_era_always(&self) -> StakingForceNewEraAlwaysXt { + pub fn force_new_era_always( + &self, + ) -> StakingForceNewEraAlwaysXt + { compose_extrinsic!(self, STAKING_MODULE, FORCE_NEW_ERA_ALWAYS, ForceEra {}) } /// Force there to be no new eras indefinitely. - pub fn force_no_era(&self) -> StakingForceNewEraAlwaysXt { + pub fn force_no_era( + &self, + ) -> StakingForceNewEraAlwaysXt + { compose_extrinsic!(self, STAKING_MODULE, FORCE_NO_ERA, ForceEra {}) } /// Re-set the payment target for a controller. - pub fn set_payee(&self, payee: GenericAddress) -> StakingSetControllerXt { + pub fn set_payee( + &self, + payee: Signer::ExtrinsicAddress, + ) -> StakingSetControllerXt { compose_extrinsic!(self, STAKING_MODULE, STAKING_SET_PAYEE, payee) } @@ -203,7 +243,8 @@ where pub fn set_validator_count( &self, count: u32, - ) -> StakingSetValidatorCountXt { + ) -> StakingSetValidatorCountXt + { compose_extrinsic!(self, STAKING_MODULE, SET_VALIDATOR_COUNT, count) } } diff --git a/src/extrinsic/utility.rs b/src/extrinsic/utility.rs index 7c8d1e76a..3c164b690 100644 --- a/src/extrinsic/utility.rs +++ b/src/extrinsic/utility.rs @@ -20,34 +20,32 @@ use super::common::Batch; use crate::{rpc::Request, Api}; use ac_compose_macros::compose_extrinsic; -use ac_primitives::{BalancesConfig, CallIndex, ExtrinsicParams, UncheckedExtrinsicV4}; +use ac_primitives::{ + BalancesConfig, CallIndex, ExtrinsicParams, SignExtrinsic, UncheckedExtrinsicV4, +}; use alloc::{borrow::ToOwned, vec::Vec}; use codec::Encode; -use sp_core::Pair; -use sp_runtime::{traits::GetRuntimeBlockType, MultiSignature, MultiSigner}; +use sp_runtime::traits::GetRuntimeBlockType; const UTILITY_MODULE: &str = "Utility"; const UTILITY_BATCH: &str = "batch"; const UTILITY_FORCE_BATCH: &str = "force_batch"; pub type UtilityBatchFn = (CallIndex, Batch); -pub type UtilityBatchXt = - UncheckedExtrinsicV4, SignedExtra>; +pub type UtilityBatchXt = + UncheckedExtrinsicV4, Signature, SignedExtra>; impl Api where - Signer: Pair, - MultiSignature: From, - MultiSigner: From, + Signer: SignExtrinsic, Client: Request, Params: ExtrinsicParams, Runtime: GetRuntimeBlockType + BalancesConfig, - Runtime::AccountId: From, { pub fn batch( &self, calls: Vec, - ) -> UtilityBatchXt { + ) -> UtilityBatchXt { let calls = Batch { calls }; compose_extrinsic!(self, UTILITY_MODULE, UTILITY_BATCH, calls) } @@ -55,7 +53,7 @@ where pub fn force_batch( &self, calls: Vec, - ) -> UtilityBatchXt { + ) -> UtilityBatchXt { let calls = Batch { calls }; compose_extrinsic!(self, UTILITY_MODULE, UTILITY_FORCE_BATCH, calls) } diff --git a/testing/examples/author_tests.rs b/testing/examples/author_tests.rs index 6fc091791..7d21ba3b8 100644 --- a/testing/examples/author_tests.rs +++ b/testing/examples/author_tests.rs @@ -15,24 +15,29 @@ //! Tests for the author rpc interface functions. -use kitchensink_runtime::Runtime; +use kitchensink_runtime::{AccountId, Runtime, Signature}; +use sp_core::sr25519::Pair; use sp_keyring::AccountKeyring; use std::{thread, time::Duration}; use substrate_api_client::{ rpc::{HandleSubscription, JsonrpseeClient}, - Api, AssetTipExtrinsicParams, EventDetails, MultiAddress, SubmitAndWatch, - SubmitAndWatchUntilSuccess, SubmitExtrinsic, TransactionStatus, XtStatus, + Api, AssetTipExtrinsicParams, EventDetails, ExtrinsicSigner as GenericExtrinsicSigner, + SignExtrinsic, SubmitAndWatch, SubmitAndWatchUntilSuccess, SubmitExtrinsic, TransactionStatus, + XtStatus, }; +type ExtrinsicSigner = GenericExtrinsicSigner; +type ExtrinsicAddressOf = >::ExtrinsicAddress; + #[tokio::main] async fn main() { // Setup let client = JsonrpseeClient::with_default_url().unwrap(); let alice_pair = AccountKeyring::Alice.pair(); let mut api = Api::<_, _, AssetTipExtrinsicParams, Runtime>::new(client).unwrap(); - api.set_signer(alice_pair); + api.set_signer(ExtrinsicSigner::new(alice_pair)); - let bob = MultiAddress::Id(AccountKeyring::Bob.to_account_id()); + let bob: ExtrinsicAddressOf = AccountKeyring::Bob.to_account_id().into(); // Submit extrinisc. let xt0 = api.balance_transfer(bob.clone(), 1000); diff --git a/testing/examples/frame_system_tests.rs b/testing/examples/frame_system_tests.rs index 3b7484abe..a92d59e67 100644 --- a/testing/examples/frame_system_tests.rs +++ b/testing/examples/frame_system_tests.rs @@ -17,11 +17,11 @@ use codec::Decode; use frame_support::dispatch::DispatchInfo; -use kitchensink_runtime::Runtime; +use kitchensink_runtime::{Runtime, Signature}; use sp_keyring::AccountKeyring; use substrate_api_client::{ - rpc::JsonrpseeClient, Api, AssetTipExtrinsicParams, GetAccountInformation, StaticEvent, - SubscribeEvents, SubscribeFrameSystem, SystemApi, + rpc::JsonrpseeClient, Api, AssetTipExtrinsicParams, ExtrinsicSigner, GetAccountInformation, + StaticEvent, SubscribeEvents, SubscribeFrameSystem, SystemApi, }; /// Check out frame_system::Event::ExtrinsicSuccess: @@ -41,7 +41,7 @@ async fn main() { let client = JsonrpseeClient::with_default_url().unwrap(); let alice_pair = AccountKeyring::Alice.pair(); let mut api = Api::<_, _, AssetTipExtrinsicParams, Runtime>::new(client).unwrap(); - api.set_signer(alice_pair); + api.set_signer(ExtrinsicSigner::<_, Signature, Runtime>::new(alice_pair)); let alice = AccountKeyring::Alice.to_account_id(); diff --git a/testing/examples/pallet_transaction_payment_tests.rs b/testing/examples/pallet_transaction_payment_tests.rs index 10858a399..4354d3a44 100644 --- a/testing/examples/pallet_transaction_payment_tests.rs +++ b/testing/examples/pallet_transaction_payment_tests.rs @@ -16,10 +16,10 @@ //! Tests for the pallet transaction payment interface functions. use codec::Encode; -use kitchensink_runtime::Runtime; +use kitchensink_runtime::{Runtime, Signature}; use sp_keyring::AccountKeyring; use substrate_api_client::{ - rpc::JsonrpseeClient, Api, AssetTipExtrinsicParams, GenericAddress, GetBlock, + rpc::JsonrpseeClient, Api, AssetTipExtrinsicParams, ExtrinsicSigner, GetBlock, GetTransactionPayment, }; @@ -29,12 +29,12 @@ async fn main() { let client = JsonrpseeClient::with_default_url().unwrap(); let alice_pair = AccountKeyring::Alice.pair(); let mut api = Api::<_, _, AssetTipExtrinsicParams, Runtime>::new(client).unwrap(); - api.set_signer(alice_pair); + api.set_signer(ExtrinsicSigner::<_, Signature, Runtime>::new(alice_pair)); let bob = AccountKeyring::Bob.to_account_id(); let block_hash = api.get_block_hash(None).unwrap().unwrap(); - let encoded_xt = api.balance_transfer(GenericAddress::Id(bob), 1000000000000).encode(); + let encoded_xt = api.balance_transfer(bob.into(), 1000000000000).encode(); // Tests let _fee_details = api