From 9e18c1791ba1d772237231112850c91ea9e5280c Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 30 Oct 2024 09:44:03 +0100 Subject: [PATCH 01/18] remove substrate compat --- Cargo.lock | 63 ++++++++++------------- core/Cargo.toml | 3 +- core/src/config/mod.rs | 29 ----------- core/src/lib.rs | 5 -- core/src/macros.rs | 18 ------- core/src/tx/signer.rs | 75 ---------------------------- core/src/utils/account_id.rs | 30 +---------- core/src/utils/multi_address.rs | 32 +----------- core/src/utils/multi_signature.rs | 38 -------------- metadata/Cargo.toml | 2 +- signer/src/ecdsa.rs | 2 +- subxt/Cargo.toml | 13 ++--- subxt/src/lib.rs | 7 --- subxt/src/macros.rs | 9 +--- subxt/src/tx/mod.rs | 8 --- testing/integration-tests/Cargo.toml | 2 +- 16 files changed, 37 insertions(+), 299 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 113d639815..2d9495556d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -132,9 +132,9 @@ dependencies = [ [[package]] name = "alloy-rlp" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26154390b1d205a4a7ac7352aa2eb4f81f391399d4e2f546fb81a2f8bb383f62" +checksum = "da0822426598f95e45dd1ea32a738dac057529a709ee645fcc516ffa4cbde08f" dependencies = [ "arrayvec 0.7.4", "bytes", @@ -1377,9 +1377,9 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytemuck" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" +checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" [[package]] name = "byteorder" @@ -2304,9 +2304,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.128" +version = "1.0.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54ccead7d199d584d139148b04b4a368d1ec7556a1d9ea2548febb1b9d49f9a4" +checksum = "cbdc8cca144dce1c4981b5c9ab748761619979e515c3d53b5df385c677d1d007" dependencies = [ "cc", "cxxbridge-flags", @@ -2316,9 +2316,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.128" +version = "1.0.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77953e99f01508f89f55c494bfa867171ef3a6c8cea03d26975368f2121a5c1" +checksum = "c5764c3142ab44fcf857101d12c0ddf09c34499900557c764f5ad0597159d1fc" dependencies = [ "cc", "codespan-reporting", @@ -2331,15 +2331,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.128" +version = "1.0.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65777e06cc48f0cb0152024c77d6cf9e4bdb4408e7b48bea993d42fa0f5b02b6" +checksum = "d422aff542b4fa28c2ce8e5cc202d42dbf24702345c1fba3087b2d3f8a1b90ff" [[package]] name = "cxxbridge-macro" -version = "1.0.128" +version = "1.0.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98532a60dedaebc4848cb2cba5023337cc9ea3af16a5b062633fabfd9f18fb60" +checksum = "a1719100f31492cd6adeeab9a0f46cdbc846e615fdb66d7b398aa46ec7fdd06f" dependencies = [ "proc-macro2", "quote", @@ -3146,14 +3146,13 @@ dependencies = [ [[package]] name = "frame-support-procedural" -version = "30.0.3" +version = "30.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09237f309782a51551c12c4264a2cee5b870751004cdea29a6408ef8b9150c25" +checksum = "5e8f9b6bc1517a6fcbf0b2377e5c8c6d39f5bb7862b191a59a9992081d63972d" dependencies = [ "Inflector", "cfg-expr", "derive-syn-parse", - "docify", "expander", "frame-support-procedural-tools", "itertools 0.11.0", @@ -4356,9 +4355,9 @@ dependencies = [ [[package]] name = "linregress" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4de04dcecc58d366391f9920245b85ffa684558a5ef6e7736e754347c3aea9c2" +checksum = "a9eda9dcf4f2a99787827661f312ac3219292549c2ee992bf9a6248ffb066bf7" dependencies = [ "nalgebra", ] @@ -4565,13 +4564,12 @@ checksum = "685a9ac4b61f4e728e1d2c6a7844609c16527aeb5e6c865915c08e619c16410f" [[package]] name = "nalgebra" -version = "0.32.6" +version = "0.33.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5c17de023a86f59ed79891b2e5d5a94c705dbe904a5b5c9c952ea6221b03e4" +checksum = "3bf139e93ad757869338ad85239cb1d6c067b23b94e5846e637ca6328ee4be60" dependencies = [ "approx", "matrixmultiply", - "nalgebra-macros", "num-complex", "num-rational", "num-traits", @@ -4579,17 +4577,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "nalgebra-macros" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - [[package]] name = "nodrop" version = "0.1.14" @@ -4733,9 +4720,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.4" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] @@ -6929,9 +6916,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.13" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" +checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", "thiserror", @@ -7646,7 +7633,7 @@ dependencies = [ "gimli 0.28.1", "hashbrown 0.14.5", "log", - "object 0.36.4", + "object 0.36.5", "polkavm-common 0.10.0", "regalloc2 0.9.3", "rustc-demangle", @@ -8996,9 +8983,9 @@ dependencies = [ [[package]] name = "simba" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae" +checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa" dependencies = [ "approx", "num-complex", diff --git a/core/Cargo.toml b/core/Cargo.toml index 17c73a89e5..a02ea57dd6 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -32,7 +32,6 @@ std = [ "impl-serde/std", "primitive-types/std", ] -substrate-compat = ["polkadot-sdk/sp-core", "polkadot-sdk/sp-runtime", "polkadot-sdk/std"] [dependencies] codec = { package = "parity-scale-codec", workspace = true, default-features = false, features = ["derive"] } @@ -48,6 +47,7 @@ derive-where = { workspace = true } hex = { workspace = true, default-features = false, features = ["alloc"] } serde = { workspace = true, default-features = false, features = ["derive"] } serde_json = { workspace = true, default-features = false, features = ["raw_value", "alloc"] } +polkadot-sdk = { workspace = true, features = ["sp-crypto-hashing"] } hashbrown = { workspace = true } # For ss58 encoding AccountId32 to serialize them properly: @@ -57,7 +57,6 @@ blake2 = { workspace = true } # Provides some deserialization, types like U256/H256 and hashing impls like twox/blake256: impl-serde = { workspace = true, default-features = false } primitive-types = { workspace = true, default-features = false, features = ["codec", "serde_no_std", "scale-info"] } -polkadot-sdk = { workspace = true, features = ["sp-crypto-hashing"] } # Included if the "substrate-compat" feature is enabled. tracing = { workspace = true, default-features = false } diff --git a/core/src/config/mod.rs b/core/src/config/mod.rs index b9bcb52f0e..c083283b4c 100644 --- a/core/src/config/mod.rs +++ b/core/src/config/mod.rs @@ -16,7 +16,6 @@ pub mod polkadot; pub mod signed_extensions; pub mod substrate; -use crate::macros::cfg_substrate_compat; use codec::{Decode, Encode}; use core::fmt::Debug; use scale_decode::DecodeAsType; @@ -127,31 +126,3 @@ pub trait Header: Sized + Encode + Decode { Self::Hasher::hash_of(self) } } - -cfg_substrate_compat! { - /// implement subxt's Hasher and Header traits for some substrate structs - mod substrate_impls { - use super::*; - use polkadot_sdk::sp_runtime; - - impl Header for T - where - ::Number: Into, - { - type Number = T::Number; - type Hasher = T::Hashing; - - fn number(&self) -> Self::Number { - *self.number() - } - } - - impl Hasher for T { - type Output = T::Output; - - fn hash(s: &[u8]) -> Self::Output { - ::hash(s) - } - } - } -} diff --git a/core/src/lib.rs b/core/src/lib.rs index 3da4d29584..6a52ff9953 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -50,9 +50,4 @@ pub mod ext { pub use scale_decode; pub use scale_encode; pub use scale_value; - - cfg_substrate_compat! { - pub use polkadot_sdk::sp_runtime; - pub use polkadot_sdk::sp_core; - } } diff --git a/core/src/macros.rs b/core/src/macros.rs index 7b0117c959..ef4c4adc13 100644 --- a/core/src/macros.rs +++ b/core/src/macros.rs @@ -2,22 +2,6 @@ // This file is dual-licensed as Apache-2.0 or GPL-3.0. // see LICENSE for license details. -macro_rules! cfg_feature { - ($feature:literal, $($item:item)*) => { - $( - #[cfg(feature = $feature)] - #[cfg_attr(docsrs, doc(cfg(feature = $feature)))] - $item - )* - } -} - -macro_rules! cfg_substrate_compat { - ($($item:item)*) => { - crate::macros::cfg_feature!("substrate-compat", $($item)*); - }; -} - macro_rules! impl_from { ($module_path:path => $delegate_ty:ident :: $variant:ident) => { impl From<$module_path> for $delegate_ty { @@ -27,5 +11,3 @@ macro_rules! impl_from { } }; } - -pub(crate) use {cfg_feature, cfg_substrate_compat}; diff --git a/core/src/tx/signer.rs b/core/src/tx/signer.rs index 4351cb4e14..85f1b38bc8 100644 --- a/core/src/tx/signer.rs +++ b/core/src/tx/signer.rs @@ -5,7 +5,6 @@ //! A library to **sub**mit e**xt**rinsics to a //! [substrate](https://github.com/paritytech/substrate) node via RPC. -use crate::macros::cfg_substrate_compat; use crate::Config; /// Signing transactions requires a [`Signer`]. This is responsible for @@ -24,77 +23,3 @@ pub trait Signer { /// refused the operation. fn sign(&self, signer_payload: &[u8]) -> T::Signature; } - -cfg_substrate_compat! { - pub use pair_signer::PairSigner; -} - -// A signer suitable for substrate based chains. This provides compatibility with Substrate -// packages like sp_keyring and such, and so relies on sp_core and sp_runtime to be included. -#[cfg(feature = "substrate-compat")] -mod pair_signer { - use super::Signer; - use crate::Config; - use polkadot_sdk::sp_core::Pair as PairT; - use polkadot_sdk::sp_runtime::{ - traits::{IdentifyAccount, Verify}, - AccountId32 as SpAccountId32, MultiSignature as SpMultiSignature, - }; - - /// A [`Signer`] implementation that can be constructed from an [`sp_core::Pair`]. - #[derive(Clone, Debug)] - pub struct PairSigner { - account_id: T::AccountId, - signer: Pair, - } - - impl PairSigner - where - T: Config, - Pair: PairT, - // We go via an `sp_runtime::MultiSignature`. We can probably generalise this - // by implementing some of these traits on our built-in MultiSignature and then - // requiring them on all T::Signatures, to avoid any go-between. - ::Signer: From, - T::AccountId: From, - { - /// Creates a new [`Signer`] from an [`sp_core::Pair`]. - pub fn new(signer: Pair) -> Self { - let account_id = - ::Signer::from(signer.public()).into_account(); - Self { - account_id: account_id.into(), - signer, - } - } - - /// Returns the [`sp_core::Pair`] implementation used to construct this. - pub fn signer(&self) -> &Pair { - &self.signer - } - - /// Return the account ID. - pub fn account_id(&self) -> &T::AccountId { - &self.account_id - } - } - - impl Signer for PairSigner - where - T: Config, - Pair: PairT, - Pair::Signature: Into, - { - fn account_id(&self) -> T::AccountId { - self.account_id.clone() - } - - fn address(&self) -> T::Address { - self.account_id.clone().into() - } - - fn sign(&self, signer_payload: &[u8]) -> T::Signature { - self.signer.sign(signer_payload).into() - } - } -} diff --git a/core/src/utils/account_id.rs b/core/src/utils/account_id.rs index 714ccf2705..3fbb7fa89b 100644 --- a/core/src/utils/account_id.rs +++ b/core/src/utils/account_id.rs @@ -171,37 +171,11 @@ impl core::str::FromStr for AccountId32 { } } -// Improve compat with the substrate version if we're using those crates: -#[cfg(feature = "substrate-compat")] -mod substrate_impls { - use super::*; - use polkadot_sdk::{sp_core, sp_runtime}; - - impl From for AccountId32 { - fn from(value: sp_runtime::AccountId32) -> Self { - Self(value.into()) - } - } - impl From for AccountId32 { - fn from(value: sp_core::sr25519::Public) -> Self { - let acc: sp_runtime::AccountId32 = value.into(); - acc.into() - } - } - impl From for AccountId32 { - fn from(value: sp_core::ed25519::Public) -> Self { - let acc: sp_runtime::AccountId32 = value.into(); - acc.into() - } - } -} - #[cfg(test)] mod test { use super::*; - - use polkadot_sdk::sp_core::{self, crypto::Ss58Codec}; - use polkadot_sdk::sp_keyring::AccountKeyring; + use sp_core::{self, crypto::Ss58Codec}; + use sp_keyring::AccountKeyring; #[test] fn ss58_is_compatible_with_substrate_impl() { diff --git a/core/src/utils/multi_address.rs b/core/src/utils/multi_address.rs index ad0025351a..95506bc483 100644 --- a/core/src/utils/multi_address.rs +++ b/core/src/utils/multi_address.rs @@ -10,8 +10,7 @@ use alloc::vec::Vec; use codec::{Decode, Encode}; /// A multi-format address wrapper for on-chain accounts. This is a simplified version of Substrate's -/// `sp_runtime::MultiAddress`. To obtain more functionality, convert this into that type (this conversion -/// functionality is provided via `From` impls if the `substrate-compat` feature is enabled). +/// `sp_runtime::MultiAddress`. #[derive( Clone, Eq, @@ -43,32 +42,3 @@ impl From for MultiAddress From for MultiAddress { - fn from(value: sp_runtime::AccountId32) -> Self { - let val: AccountId32 = value.into(); - val.into() - } - } - - impl From> for MultiAddress - where - Id: Into, - { - fn from(value: sp_runtime::MultiAddress) -> Self { - match value { - sp_runtime::MultiAddress::Id(v) => Self::Id(v.into()), - sp_runtime::MultiAddress::Index(v) => Self::Index(v), - sp_runtime::MultiAddress::Raw(v) => Self::Raw(v), - sp_runtime::MultiAddress::Address32(v) => Self::Address32(v), - sp_runtime::MultiAddress::Address20(v) => Self::Address20(v), - } - } - } -} diff --git a/core/src/utils/multi_signature.rs b/core/src/utils/multi_signature.rs index 7413381278..0f1c623a4f 100644 --- a/core/src/utils/multi_signature.rs +++ b/core/src/utils/multi_signature.rs @@ -19,41 +19,3 @@ pub enum MultiSignature { /// An ECDSA/SECP256k1 signature (a 512-bit value, plus 8 bits for recovery ID). Ecdsa([u8; 65]), } - -// Improve compat with the substrate version if we're using those crates: -#[cfg(feature = "substrate-compat")] -mod substrate_impls { - use super::*; - use polkadot_sdk::{sp_core, sp_runtime}; - - impl From for MultiSignature { - fn from(value: sp_runtime::MultiSignature) -> Self { - match value { - sp_runtime::MultiSignature::Ed25519(s) => Self::Ed25519(s.0), - sp_runtime::MultiSignature::Sr25519(s) => Self::Sr25519(s.0), - sp_runtime::MultiSignature::Ecdsa(s) => Self::Ecdsa(s.0), - } - } - } - - impl From for MultiSignature { - fn from(value: sp_core::ed25519::Signature) -> Self { - let sig: sp_runtime::MultiSignature = value.into(); - sig.into() - } - } - - impl From for MultiSignature { - fn from(value: sp_core::sr25519::Signature) -> Self { - let sig: sp_runtime::MultiSignature = value.into(); - sig.into() - } - } - - impl From for MultiSignature { - fn from(value: sp_core::ecdsa::Signature) -> Self { - let sig: sp_runtime::MultiSignature = value.into(); - sig.into() - } - } -} diff --git a/metadata/Cargo.toml b/metadata/Cargo.toml index fb34cfa2fd..bfc367abe3 100644 --- a/metadata/Cargo.toml +++ b/metadata/Cargo.toml @@ -31,7 +31,7 @@ criterion = { workspace = true } scale-info = { workspace = true, features = ["bit-vec"] } [lib] -# Without this, libtest cli opts interfere with criteron benches: +# Without this, libtest cli opts interfere with criterion benches: bench = false [[bench]] diff --git a/signer/src/ecdsa.rs b/signer/src/ecdsa.rs index 69bda852e7..549af760a7 100644 --- a/signer/src/ecdsa.rs +++ b/signer/src/ecdsa.rs @@ -4,13 +4,13 @@ //! An ecdsa keypair implementation. use codec::Encode; -use polkadot_sdk::sp_crypto_hashing; use crate::crypto::{seed_from_entropy, DeriveJunction, SecretUri}; use core::{fmt::Display, str::FromStr}; use hex::FromHex; use secp256k1::{ecdsa::RecoverableSignature, Message, Secp256k1, SecretKey}; use secrecy::ExposeSecret; +use polkadot_sdk::sp_crypto_hashing; const SECRET_KEY_LENGTH: usize = 32; diff --git a/subxt/Cargo.toml b/subxt/Cargo.toml index e8fab06d7e..f29c97f3f9 100644 --- a/subxt/Cargo.toml +++ b/subxt/Cargo.toml @@ -63,11 +63,6 @@ jsonrpsee = [ "runtime" ] -# Enable this to pull in extra Substrate dependencies which make it possible to -# use the `sp_core::crypto::Pair` Signer implementation, as well as adding some -# `From` impls for types like `AccountId32`. Cannot be used with "web". -substrate-compat = ["subxt-core/substrate-compat"] - # Enable this to fetch and utilize the latest unstable metadata from a node. # The unstable metadata is subject to breaking changes and the subxt might # fail to decode the metadata properly. Use this to experiment with the @@ -94,6 +89,7 @@ futures = { workspace = true } hex = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true, features = ["default", "raw_value"] } +polkadot-sdk = { workspace = true, features = ["sp-crypto-hashing"] } thiserror = { workspace = true } tracing = { workspace = true } frame-metadata = { workspace = true } @@ -103,7 +99,6 @@ web-time = { workspace = true } # Provides some deserialization, types like U256/H256 and hashing impls like twox/blake256: impl-serde = { workspace = true } primitive-types = { workspace = true, features = ["codec", "scale-info", "serde"] } -polkadot-sdk = { workspace = true, features = ["sp-crypto-hashing"] } # Included if the "jsonrpsee" feature is enabled. jsonrpsee = { workspace = true, optional = true, features = ["jsonrpsee-types"] } @@ -135,7 +130,7 @@ bitvec = { workspace = true } codec = { workspace = true, features = ["derive", "bit-vec"] } scale-info = { workspace = true, features = ["bit-vec"] } tokio = { workspace = true, features = ["macros", "time", "rt-multi-thread", "sync"] } -polkadot-sdk = { workspace = true, features = ["sp-core", "sp-keyring", "sp-runtime", "sp-crypto-hashing"] } +polkadot-sdk = { workspace = true, features = ["sp-core", "sp-keyring", "sp-runtime", "std"] } assert_matches = { workspace = true } subxt-signer = { path = "../signer", features = ["unstable-eth"] } # Tracing subscriber is useful for light-client examples to ensure that @@ -165,8 +160,8 @@ path = "examples/setup_reconnecting_rpc_client.rs" required-features = ["reconnecting-rpc-client"] [package.metadata.docs.rs] -features = ["default", "substrate-compat", "unstable-light-client"] +features = ["default", "unstable-light-client"] rustdoc-args = ["--cfg", "docsrs"] [package.metadata.playground] -features = ["default", "substrate-compat", "unstable-light-client"] +features = ["default", "unstable-light-client"] diff --git a/subxt/src/lib.rs b/subxt/src/lib.rs index c0fa24e262..c88920a800 100644 --- a/subxt/src/lib.rs +++ b/subxt/src/lib.rs @@ -18,9 +18,6 @@ ))] compile_error!("subxt: exactly one of the 'web' and 'native' features should be used."); -#[cfg(all(feature = "web", feature = "substrate-compat"))] -compile_error!("subxt: the 'substrate-compat' feature is not compatible with the 'web' feature."); - // The guide is here. pub mod book; @@ -115,10 +112,6 @@ pub mod ext { cfg_jsonrpsee! { pub use jsonrpsee; } - - cfg_substrate_compat! { - pub use subxt_core::ext::{sp_runtime, sp_core}; - } } /// Generate a strongly typed API for interacting with a Substrate runtime from its metadata. diff --git a/subxt/src/macros.rs b/subxt/src/macros.rs index 4094d353fb..b3365ef4e6 100644 --- a/subxt/src/macros.rs +++ b/subxt/src/macros.rs @@ -12,12 +12,6 @@ macro_rules! cfg_feature { } } -macro_rules! cfg_substrate_compat { - ($($item:item)*) => { - crate::macros::cfg_feature!("substrate-compat", $($item)*); - }; -} - macro_rules! cfg_unstable_light_client { ($($item:item)*) => { crate::macros::cfg_feature!("unstable-light-client", $($item)*); @@ -64,8 +58,7 @@ macro_rules! cfg_reconnecting_rpc_client { } pub(crate) use { - cfg_feature, cfg_jsonrpsee, cfg_reconnecting_rpc_client, cfg_substrate_compat, - cfg_unstable_light_client, + cfg_feature, cfg_jsonrpsee, cfg_reconnecting_rpc_client, cfg_unstable_light_client, }; // Only used by light-client. diff --git a/subxt/src/tx/mod.rs b/subxt/src/tx/mod.rs index c7ad01dc99..6ab60edc06 100644 --- a/subxt/src/tx/mod.rs +++ b/subxt/src/tx/mod.rs @@ -9,17 +9,9 @@ //! additional and signed extra parameters are used when constructing an extrinsic, and is a part //! of the chain configuration (see [`crate::config::Config`]). -use crate::macros::cfg_substrate_compat; - mod tx_client; mod tx_progress; -// The PairSigner impl currently relies on Substrate bits and pieces, so make it an optional -// feature if we want to avoid needing sp_core and sp_runtime. -cfg_substrate_compat! { - pub use subxt_core::tx::signer::PairSigner; -} - pub use subxt_core::tx::payload::{dynamic, DefaultPayload, DynamicPayload, Payload}; pub use subxt_core::tx::signer::{self, Signer}; pub use tx_client::{ diff --git a/testing/integration-tests/Cargo.toml b/testing/integration-tests/Cargo.toml index e6b3eab125..38fbe18aff 100644 --- a/testing/integration-tests/Cargo.toml +++ b/testing/integration-tests/Cargo.toml @@ -36,7 +36,7 @@ serde = { workspace = true } scale-info = { workspace = true, features = ["bit-vec"] } polkadot-sdk = { workspace = true, features = ["sp-core"] } syn = { workspace = true } -subxt = { workspace = true, features = ["unstable-metadata", "native", "jsonrpsee", "substrate-compat", "reconnecting-rpc-client"] } +subxt = { workspace = true, features = ["unstable-metadata", "native", "jsonrpsee", "reconnecting-rpc-client"] } subxt-signer = { workspace = true, features = ["default"] } subxt-codegen = { workspace = true } subxt-metadata = { workspace = true } From 7e60d7759330bcff2823bb3ba7ab51506b129f89 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 30 Oct 2024 15:33:04 +0100 Subject: [PATCH 02/18] add hacky example --- subxt/examples/substrate_compat.rs | 300 +++++++++++++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100644 subxt/examples/substrate_compat.rs diff --git a/subxt/examples/substrate_compat.rs b/subxt/examples/substrate_compat.rs new file mode 100644 index 0000000000..9f07ec9633 --- /dev/null +++ b/subxt/examples/substrate_compat.rs @@ -0,0 +1,300 @@ +//! This example demonstrates how to use to add a layer for full functionality for types in substrate. +//! +//! Similar functionality was provided by the `substrate-compat` feature in the original `subxt` crate. +//! which is now removed. + +#![allow(missing_docs)] + +use std::ops::Deref; + +use polkadot_sdk::{sp_core, sp_runtime}; +use sp_core::Pair as _; +use subxt::{Config, OnlineClient, PolkadotConfig}; +use subxt_signer::sr25519::dev; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +/// AccountId32 for substrate compatibility. +#[derive(Clone, Debug)] +pub struct AccountId32(subxt::config::substrate::AccountId32); + +/// MultiAddress type for substrate compatibility. +#[derive(Clone, Debug)] +pub struct MultiAddress( + subxt::config::substrate::MultiAddress, +); + +/// A [`Signer`] implementation that can be constructed from an [`sp_core::Pair`]. +#[derive(Clone, Debug)] +pub struct PairSigner { + account_id: AccountId32, + signer: Pair, +} + +/// MultiSignature type for Substrate compatibility. +#[derive(Clone, Debug)] +pub struct MultiSignature(subxt::config::substrate::MultiSignature); + +mod account_impls { + use super::*; + + impl From for AccountId32 { + fn from(value: sp_runtime::AccountId32) -> Self { + let bytes: [u8; 32] = value.into(); + let subxt_acc: subxt::config::substrate::AccountId32 = bytes.into(); + subxt_acc.into() + } + } + impl From for AccountId32 { + fn from(value: sp_core::sr25519::Public) -> Self { + let acc: sp_runtime::AccountId32 = value.into(); + acc.into() + } + } + impl From for AccountId32 { + fn from(value: sp_core::ed25519::Public) -> Self { + let acc: sp_runtime::AccountId32 = value.into(); + acc.into() + } + } + impl From for AccountId32 { + fn from(value: subxt::config::substrate::AccountId32) -> Self { + Self(value) + } + } + + impl Deref for AccountId32 { + type Target = subxt::config::substrate::AccountId32; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } +} + +mod multi_addr_impls { + use super::*; + + impl From for MultiAddress { + fn from(value: sp_runtime::AccountId32) -> Self { + value.into() + } + } + + impl From> + for MultiAddress + { + fn from(value: subxt::config::substrate::MultiAddress) -> Self { + Self(value) + } + } + + impl From> for MultiAddress + where + Id: Into, + { + fn from(value: sp_runtime::MultiAddress) -> Self { + let inner = match value { + sp_runtime::MultiAddress::Id(v) => { + subxt::config::substrate::MultiAddress::Id(v.into()) + } + sp_runtime::MultiAddress::Index(v) => { + subxt::config::substrate::MultiAddress::Index(v) + } + sp_runtime::MultiAddress::Raw(v) => subxt::config::substrate::MultiAddress::Raw(v), + sp_runtime::MultiAddress::Address32(v) => { + subxt::config::substrate::MultiAddress::Address32(v) + } + sp_runtime::MultiAddress::Address20(v) => { + subxt::config::substrate::MultiAddress::Address20(v) + } + }; + inner.into() + } + } + + impl Deref for MultiAddress { + type Target = subxt::config::substrate::MultiAddress; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } +} + +mod multi_signature_impls { + use super::*; + + impl From for MultiSignature { + fn from(value: sp_runtime::MultiSignature) -> Self { + let inner = match value { + sp_runtime::MultiSignature::Ed25519(s) => { + subxt::config::substrate::MultiSignature::Ed25519(s.0) + } + sp_runtime::MultiSignature::Sr25519(s) => { + subxt::config::substrate::MultiSignature::Sr25519(s.0) + } + sp_runtime::MultiSignature::Ecdsa(s) => { + subxt::config::substrate::MultiSignature::Ecdsa(s.0) + } + }; + Self(inner) + } + } + + impl From for MultiSignature { + fn from(value: subxt::config::substrate::MultiSignature) -> Self { + Self(value) + } + } + + impl From for MultiSignature { + fn from(value: sp_core::ed25519::Signature) -> Self { + let sig: sp_runtime::MultiSignature = value.into(); + sig.into() + } + } + + impl From for MultiSignature { + fn from(value: sp_core::sr25519::Signature) -> Self { + let sig: sp_runtime::MultiSignature = value.into(); + sig.into() + } + } + + impl From for MultiSignature { + fn from(value: sp_core::ecdsa::Signature) -> Self { + let sig: sp_runtime::MultiSignature = value.into(); + sig.into() + } + } + + impl Deref for MultiSignature { + type Target = subxt::config::substrate::MultiSignature; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } +} + +mod pair_signer { + use super::*; + use polkadot_sdk::sp_core::Pair as PairT; + use polkadot_sdk::sp_runtime::{ + traits::{IdentifyAccount, Verify}, + AccountId32 as SpAccountId32, MultiSignature as SpMultiSignature, + }; + use subxt::tx::Signer; + + impl PairSigner + where + Pair: PairT, + ::Signer: From, + { + /// Creates a new [`Signer`] from an [`sp_core::Pair`]. + pub fn new(signer: Pair) -> Self { + let account_id = + ::Signer::from(signer.public()).into_account(); + Self { + account_id: account_id.into(), + signer, + } + } + + /// Returns the [`sp_core::Pair`] implementation used to construct this. + pub fn signer(&self) -> &Pair { + &self.signer + } + + /// Return the account ID. + pub fn account_id(&self) -> &subxt::config::substrate::AccountId32 { + &self.account_id.0 + } + } + + impl Signer for PairSigner + where + Pair: PairT, + Pair::Signature: Into<::Signature>, + { + fn account_id(&self) -> ::AccountId { + self.account_id.0.clone() + } + + fn address(&self) -> ::Address { + self.account_id.0.clone().into() + } + + fn sign(&self, signer_payload: &[u8]) -> ::Signature { + self.signer.sign(signer_payload).into() + } + } +} + +mod other_impls { + use super::*; + use polkadot_sdk::sp_runtime; + + impl Header for T + where + ::Number: Into, + { + type Number = T::Number; + type Hasher = T::Hashing; + + fn number(&self) -> Self::Number { + *self.number() + } + } + + impl Hasher for T { + type Output = T::Output; + + fn hash(s: &[u8]) -> Self::Output { + ::hash(s) + } + } +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + let signer: PairSigner<_> = { + let acc = sp_core::sr25519::Pair::from_string("//Alice", None).unwrap(); + PairSigner::new(acc) + }; + + let alice = signer.account_id().clone().into(); + + // Build a balance transfer extrinsic. + let balance_transfer_tx = polkadot::tx() + .balances() + .transfer_allow_death(alice, 10_000); + + /* + + This doesn't compile... + + // Submit the balance transfer extrinsic from Alice, and wait for it to be successful + // and in a finalized block. We get back the extrinsic events if all is well. + let events = api + .tx() + .sign_and_submit_then_watch_default(&balance_transfer_tx, &signer) + .await? + .wait_for_finalized_success() + .await?; + + // Find a Transfer event and print it. + let transfer_event = events.find_first::()?; + if let Some(event) = transfer_event { + println!("Balance transfer success: {event:?}"); + } + + */ + + Ok(()) +} From fdc1c4e47a09791d9d36347bf332a08d82b6cee2 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 31 Oct 2024 13:08:59 +0100 Subject: [PATCH 03/18] simplify substrate-compat example --- subxt/examples/substrate_compat.rs | 300 ----------------------------- 1 file changed, 300 deletions(-) delete mode 100644 subxt/examples/substrate_compat.rs diff --git a/subxt/examples/substrate_compat.rs b/subxt/examples/substrate_compat.rs deleted file mode 100644 index 9f07ec9633..0000000000 --- a/subxt/examples/substrate_compat.rs +++ /dev/null @@ -1,300 +0,0 @@ -//! This example demonstrates how to use to add a layer for full functionality for types in substrate. -//! -//! Similar functionality was provided by the `substrate-compat` feature in the original `subxt` crate. -//! which is now removed. - -#![allow(missing_docs)] - -use std::ops::Deref; - -use polkadot_sdk::{sp_core, sp_runtime}; -use sp_core::Pair as _; -use subxt::{Config, OnlineClient, PolkadotConfig}; -use subxt_signer::sr25519::dev; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -/// AccountId32 for substrate compatibility. -#[derive(Clone, Debug)] -pub struct AccountId32(subxt::config::substrate::AccountId32); - -/// MultiAddress type for substrate compatibility. -#[derive(Clone, Debug)] -pub struct MultiAddress( - subxt::config::substrate::MultiAddress, -); - -/// A [`Signer`] implementation that can be constructed from an [`sp_core::Pair`]. -#[derive(Clone, Debug)] -pub struct PairSigner { - account_id: AccountId32, - signer: Pair, -} - -/// MultiSignature type for Substrate compatibility. -#[derive(Clone, Debug)] -pub struct MultiSignature(subxt::config::substrate::MultiSignature); - -mod account_impls { - use super::*; - - impl From for AccountId32 { - fn from(value: sp_runtime::AccountId32) -> Self { - let bytes: [u8; 32] = value.into(); - let subxt_acc: subxt::config::substrate::AccountId32 = bytes.into(); - subxt_acc.into() - } - } - impl From for AccountId32 { - fn from(value: sp_core::sr25519::Public) -> Self { - let acc: sp_runtime::AccountId32 = value.into(); - acc.into() - } - } - impl From for AccountId32 { - fn from(value: sp_core::ed25519::Public) -> Self { - let acc: sp_runtime::AccountId32 = value.into(); - acc.into() - } - } - impl From for AccountId32 { - fn from(value: subxt::config::substrate::AccountId32) -> Self { - Self(value) - } - } - - impl Deref for AccountId32 { - type Target = subxt::config::substrate::AccountId32; - - fn deref(&self) -> &Self::Target { - &self.0 - } - } -} - -mod multi_addr_impls { - use super::*; - - impl From for MultiAddress { - fn from(value: sp_runtime::AccountId32) -> Self { - value.into() - } - } - - impl From> - for MultiAddress - { - fn from(value: subxt::config::substrate::MultiAddress) -> Self { - Self(value) - } - } - - impl From> for MultiAddress - where - Id: Into, - { - fn from(value: sp_runtime::MultiAddress) -> Self { - let inner = match value { - sp_runtime::MultiAddress::Id(v) => { - subxt::config::substrate::MultiAddress::Id(v.into()) - } - sp_runtime::MultiAddress::Index(v) => { - subxt::config::substrate::MultiAddress::Index(v) - } - sp_runtime::MultiAddress::Raw(v) => subxt::config::substrate::MultiAddress::Raw(v), - sp_runtime::MultiAddress::Address32(v) => { - subxt::config::substrate::MultiAddress::Address32(v) - } - sp_runtime::MultiAddress::Address20(v) => { - subxt::config::substrate::MultiAddress::Address20(v) - } - }; - inner.into() - } - } - - impl Deref for MultiAddress { - type Target = subxt::config::substrate::MultiAddress; - - fn deref(&self) -> &Self::Target { - &self.0 - } - } -} - -mod multi_signature_impls { - use super::*; - - impl From for MultiSignature { - fn from(value: sp_runtime::MultiSignature) -> Self { - let inner = match value { - sp_runtime::MultiSignature::Ed25519(s) => { - subxt::config::substrate::MultiSignature::Ed25519(s.0) - } - sp_runtime::MultiSignature::Sr25519(s) => { - subxt::config::substrate::MultiSignature::Sr25519(s.0) - } - sp_runtime::MultiSignature::Ecdsa(s) => { - subxt::config::substrate::MultiSignature::Ecdsa(s.0) - } - }; - Self(inner) - } - } - - impl From for MultiSignature { - fn from(value: subxt::config::substrate::MultiSignature) -> Self { - Self(value) - } - } - - impl From for MultiSignature { - fn from(value: sp_core::ed25519::Signature) -> Self { - let sig: sp_runtime::MultiSignature = value.into(); - sig.into() - } - } - - impl From for MultiSignature { - fn from(value: sp_core::sr25519::Signature) -> Self { - let sig: sp_runtime::MultiSignature = value.into(); - sig.into() - } - } - - impl From for MultiSignature { - fn from(value: sp_core::ecdsa::Signature) -> Self { - let sig: sp_runtime::MultiSignature = value.into(); - sig.into() - } - } - - impl Deref for MultiSignature { - type Target = subxt::config::substrate::MultiSignature; - - fn deref(&self) -> &Self::Target { - &self.0 - } - } -} - -mod pair_signer { - use super::*; - use polkadot_sdk::sp_core::Pair as PairT; - use polkadot_sdk::sp_runtime::{ - traits::{IdentifyAccount, Verify}, - AccountId32 as SpAccountId32, MultiSignature as SpMultiSignature, - }; - use subxt::tx::Signer; - - impl PairSigner - where - Pair: PairT, - ::Signer: From, - { - /// Creates a new [`Signer`] from an [`sp_core::Pair`]. - pub fn new(signer: Pair) -> Self { - let account_id = - ::Signer::from(signer.public()).into_account(); - Self { - account_id: account_id.into(), - signer, - } - } - - /// Returns the [`sp_core::Pair`] implementation used to construct this. - pub fn signer(&self) -> &Pair { - &self.signer - } - - /// Return the account ID. - pub fn account_id(&self) -> &subxt::config::substrate::AccountId32 { - &self.account_id.0 - } - } - - impl Signer for PairSigner - where - Pair: PairT, - Pair::Signature: Into<::Signature>, - { - fn account_id(&self) -> ::AccountId { - self.account_id.0.clone() - } - - fn address(&self) -> ::Address { - self.account_id.0.clone().into() - } - - fn sign(&self, signer_payload: &[u8]) -> ::Signature { - self.signer.sign(signer_payload).into() - } - } -} - -mod other_impls { - use super::*; - use polkadot_sdk::sp_runtime; - - impl Header for T - where - ::Number: Into, - { - type Number = T::Number; - type Hasher = T::Hashing; - - fn number(&self) -> Self::Number { - *self.number() - } - } - - impl Hasher for T { - type Output = T::Output; - - fn hash(s: &[u8]) -> Self::Output { - ::hash(s) - } - } -} - -#[tokio::main] -async fn main() -> Result<(), Box> { - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - let signer: PairSigner<_> = { - let acc = sp_core::sr25519::Pair::from_string("//Alice", None).unwrap(); - PairSigner::new(acc) - }; - - let alice = signer.account_id().clone().into(); - - // Build a balance transfer extrinsic. - let balance_transfer_tx = polkadot::tx() - .balances() - .transfer_allow_death(alice, 10_000); - - /* - - This doesn't compile... - - // Submit the balance transfer extrinsic from Alice, and wait for it to be successful - // and in a finalized block. We get back the extrinsic events if all is well. - let events = api - .tx() - .sign_and_submit_then_watch_default(&balance_transfer_tx, &signer) - .await? - .wait_for_finalized_success() - .await?; - - // Find a Transfer event and print it. - let transfer_event = events.find_first::()?; - if let Some(event) = transfer_event { - println!("Balance transfer success: {event:?}"); - } - - */ - - Ok(()) -} From e2ca34fa0c390df770aeec763a0935e2ef9194db Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 31 Oct 2024 13:09:38 +0100 Subject: [PATCH 04/18] simplify substrate-compat example --- subxt/examples/substrate_compat_signer.rs | 106 ++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 subxt/examples/substrate_compat_signer.rs diff --git a/subxt/examples/substrate_compat_signer.rs b/subxt/examples/substrate_compat_signer.rs new file mode 100644 index 0000000000..9685c09e9e --- /dev/null +++ b/subxt/examples/substrate_compat_signer.rs @@ -0,0 +1,106 @@ +//! This example demonstrates how to use to add a layer for full functionality for types in substrate. +//! +//! Similar functionality was provided by the `substrate-compat` feature in the original `subxt` crate. +//! which is now removed. + +#![allow(missing_docs)] + +use polkadot_sdk::sp_core::{sr25519, Pair as _}; +use subxt::{Config, OnlineClient, PolkadotConfig}; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +/// A concrete PairSigner implementation which relies on `sr25519::Pair` for signing +/// and that PolkadotConfig is the runtime configuration. +mod pair_signer { + use super::*; + use polkadot_sdk::sp_runtime::{ + traits::{IdentifyAccount, Verify}, + MultiSignature as SpMultiSignature, + }; + use subxt::{ + config::substrate::{AccountId32, MultiSignature}, + tx::Signer, + }; + + /// A [`Signer`] implementation for `polkadot_sdk::sp_core::sr25519::Pair`. + #[derive(Clone)] + pub struct PairSigner { + account_id: ::AccountId, + signer: sr25519::Pair, + } + + impl PairSigner { + /// Creates a new [`Signer`] from an [`sp_core::Pair`]. + pub fn new(signer: sr25519::Pair) -> Self { + let account_id = + ::Signer::from(signer.public()).into_account(); + Self { + // Convert `sp_core::AccountId32` to `subxt::config::substrate::AccountId32`. + account_id: AccountId32(account_id.into()), + signer, + } + } + + /// Returns the [`sp_core::sr25519::Pair`] implementation used to construct this. + pub fn signer(&self) -> &sr25519::Pair { + &self.signer + } + + /// Return the account ID. + pub fn account_id(&self) -> &AccountId32 { + &self.account_id + } + } + + impl Signer for PairSigner { + fn account_id(&self) -> ::AccountId { + self.account_id.clone() + } + + fn address(&self) -> ::Address { + self.account_id.clone().into() + } + + fn sign(&self, signer_payload: &[u8]) -> ::Signature { + let signature = self.signer.sign(signer_payload); + MultiSignature::Sr25519(signature.0) + } + } +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + let signer = { + let acc = sr25519::Pair::from_string("//Alice", None).unwrap(); + pair_signer::PairSigner::new(acc) + }; + + let alice = signer.account_id().clone().into(); + + // Build a balance transfer extrinsic. + let balance_transfer_tx = polkadot::tx() + .balances() + .transfer_allow_death(alice, 10_000); + + // Submit the balance transfer extrinsic from Alice, and wait for it to be successful + // and in a finalized block. We get back the extrinsic events if all is well. + let events = api + .tx() + .sign_and_submit_then_watch_default(&balance_transfer_tx, &signer) + .await? + .wait_for_finalized_success() + .await?; + + // Find a Transfer event and print it. + let transfer_event = events.find_first::()?; + if let Some(event) = transfer_event { + println!("Balance transfer success: {event:?}"); + } + + Ok(()) +} From ab56ad2fc6a01369ff7cabd6921835a89ce95740 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 31 Oct 2024 13:11:53 +0100 Subject: [PATCH 05/18] cargo fmt --- signer/src/ecdsa.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/signer/src/ecdsa.rs b/signer/src/ecdsa.rs index 549af760a7..4cf5dc62db 100644 --- a/signer/src/ecdsa.rs +++ b/signer/src/ecdsa.rs @@ -8,9 +8,9 @@ use codec::Encode; use crate::crypto::{seed_from_entropy, DeriveJunction, SecretUri}; use core::{fmt::Display, str::FromStr}; use hex::FromHex; +use polkadot_sdk::sp_crypto_hashing; use secp256k1::{ecdsa::RecoverableSignature, Message, Secp256k1, SecretKey}; use secrecy::ExposeSecret; -use polkadot_sdk::sp_crypto_hashing; const SECRET_KEY_LENGTH: usize = 32; From 68e0e7a7f15c9d98a827335954eb87f5e05528e8 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 31 Oct 2024 15:02:42 +0100 Subject: [PATCH 06/18] fix build --- core/src/utils/account_id.rs | 4 ++-- subxt/examples/substrate_compat_signer.rs | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/core/src/utils/account_id.rs b/core/src/utils/account_id.rs index 3fbb7fa89b..98234f2ce1 100644 --- a/core/src/utils/account_id.rs +++ b/core/src/utils/account_id.rs @@ -174,8 +174,8 @@ impl core::str::FromStr for AccountId32 { #[cfg(test)] mod test { use super::*; - use sp_core::{self, crypto::Ss58Codec}; - use sp_keyring::AccountKeyring; + use polkadot_sdk::sp_core::{self, crypto::Ss58Codec}; + use polkadot_sdk::sp_keyring::AccountKeyring; #[test] fn ss58_is_compatible_with_substrate_impl() { diff --git a/subxt/examples/substrate_compat_signer.rs b/subxt/examples/substrate_compat_signer.rs index 9685c09e9e..6f23bf093d 100644 --- a/subxt/examples/substrate_compat_signer.rs +++ b/subxt/examples/substrate_compat_signer.rs @@ -1,9 +1,10 @@ -//! This example demonstrates how to use to add a layer for full functionality for types in substrate. +//! This example demonstrates how to use to add a custom signer implementation to `subxt` +//! by using the signer implementation from polkadot-sdk. //! //! Similar functionality was provided by the `substrate-compat` feature in the original `subxt` crate. //! which is now removed. -#![allow(missing_docs)] +#![allow(missing_docs, unused)] use polkadot_sdk::sp_core::{sr25519, Pair as _}; use subxt::{Config, OnlineClient, PolkadotConfig}; From 3189731b68cb3628c1ec5ce6183483d5fe63d3e0 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 31 Oct 2024 16:28:50 +0100 Subject: [PATCH 07/18] add more examples --- subxt/examples/substrate_compat.rs | 208 ++++++++++++++++++++++ subxt/examples/substrate_compat_signer.rs | 20 ++- 2 files changed, 223 insertions(+), 5 deletions(-) create mode 100644 subxt/examples/substrate_compat.rs diff --git a/subxt/examples/substrate_compat.rs b/subxt/examples/substrate_compat.rs new file mode 100644 index 0000000000..a20b52da59 --- /dev/null +++ b/subxt/examples/substrate_compat.rs @@ -0,0 +1,208 @@ +#![allow(missing_docs, unused)] + +use codec::{Decode, Encode}; +use polkadot_sdk::sp_core::{self, sr25519, Pair as PairT}; +use polkadot_sdk::sp_runtime::{ + self, + traits::{IdentifyAccount, Verify}, + AccountId32 as SpAccountId32, MultiSignature as SpMultiSignature, +}; +use subxt::config::PolkadotExtrinsicParams; +use subxt::{Config, OnlineClient}; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +pub enum PolkadotConfig {} + +/// AccountId32 for substrate compatibility. +#[derive( + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + Debug, + scale_encode::EncodeAsType, + scale_decode::DecodeAsType, + scale_info::TypeInfo, +)] +pub struct AccountId32(subxt::config::substrate::AccountId32); + +impl From for AccountId32 { + fn from(acc: sp_runtime::AccountId32) -> Self { + Self(subxt::config::substrate::AccountId32(acc.into())) + } +} + +/// MultiAddress type for substrate compatibility. +#[derive( + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + Debug, + scale_encode::EncodeAsType, + scale_decode::DecodeAsType, + scale_info::TypeInfo, +)] +pub struct MultiAddress( + subxt::config::substrate::MultiAddress, +); + +impl From for MultiAddress { + fn from(a: AccountId) -> Self { + Self(subxt::config::substrate::MultiAddress::Id(a)) + } +} + +/// MultiAddress type for substrate compatibility. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug, scale_info::TypeInfo)] +pub struct MultiSignature(subxt::config::substrate::MultiSignature); + +impl From for MultiSignature { + fn from(value: sp_runtime::MultiSignature) -> Self { + let inner = match value { + sp_runtime::MultiSignature::Ed25519(s) => { + subxt::config::substrate::MultiSignature::Ed25519(s.0) + } + sp_runtime::MultiSignature::Sr25519(s) => { + subxt::config::substrate::MultiSignature::Sr25519(s.0) + } + sp_runtime::MultiSignature::Ecdsa(s) => { + subxt::config::substrate::MultiSignature::Ecdsa(s.0) + } + }; + Self(inner) + } +} + +impl From for MultiSignature { + fn from(value: sp_core::ed25519::Signature) -> Self { + let sig: sp_runtime::MultiSignature = value.into(); + sig.into() + } +} + +impl From for MultiSignature { + fn from(value: sp_core::sr25519::Signature) -> Self { + let sig: sp_runtime::MultiSignature = value.into(); + sig.into() + } +} + +impl From for MultiSignature { + fn from(value: sp_core::ecdsa::Signature) -> Self { + let sig: sp_runtime::MultiSignature = value.into(); + sig.into() + } +} + +impl subxt::Config for PolkadotConfig { + type Hash = ::Hash; + type AccountId = AccountId32; + type Address = MultiAddress; + type Signature = MultiSignature; + type Hasher = ::Hasher; + type Header = ::Header; + type ExtrinsicParams = PolkadotExtrinsicParams; + type AssetId = u32; +} + +/// A [`Signer`] implementation that can be constructed from an [`sp_core::Pair`]. +#[derive(Clone, Debug)] +pub struct PairSigner { + account_id: T::AccountId, + signer: Pair, +} + +impl PairSigner +where + T: Config, + Pair: PairT, + // We go via an `sp_runtime::MultiSignature`. We can probably generalise this + // by implementing some of these traits on our built-in MultiSignature and then + // requiring them on all T::Signatures, to avoid any go-between. + ::Signer: From, + T::AccountId: From, +{ + /// Creates a new [`Signer`] from an [`sp_core::Pair`]. + pub fn new(signer: Pair) -> Self { + let account_id = ::Signer::from(signer.public()).into_account(); + Self { + account_id: account_id.into(), + signer, + } + } + + /// Returns the [`sp_core::Pair`] implementation used to construct this. + pub fn signer(&self) -> &Pair { + &self.signer + } + + /// Return the account ID. + pub fn account_id(&self) -> &T::AccountId { + &self.account_id + } +} + +impl subxt::tx::Signer for PairSigner +where + T: Config, + Pair: PairT, + Pair::Signature: Into, +{ + fn account_id(&self) -> T::AccountId { + self.account_id.clone() + } + + fn address(&self) -> T::Address { + self.account_id.clone().into() + } + + fn sign(&self, signer_payload: &[u8]) -> T::Signature { + self.signer.sign(signer_payload).into() + } +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + tracing_subscriber::fmt::init(); + + // Create a new API client, configured to talk to Polkadot nodes. + let api = OnlineClient::::new().await?; + + let signer: PairSigner = { + let acc = sr25519::Pair::from_string("//Alice", None)?; + PairSigner::new(acc) + }; + + let dest = subxt_signer::sr25519::dev::bob().public_key().into(); + + // Build a balance transfer extrinsic. + let balance_transfer_tx = polkadot::tx() + .balances() + .transfer_allow_death(dest, 100_000); + + // Submit the balance transfer extrinsic from Alice, and wait for it to be successful + // and in a finalized block. We get back the extrinsic events if all is well. + let events = api + .tx() + .sign_and_submit_then_watch_default(&balance_transfer_tx, &signer) + .await? + .wait_for_finalized_success() + .await?; + + // Find a Transfer event and print it. + let transfer_event = events.find_first::()?; + if let Some(event) = transfer_event { + println!("Balance transfer success: {event:?}"); + } + + Ok(()) +} diff --git a/subxt/examples/substrate_compat_signer.rs b/subxt/examples/substrate_compat_signer.rs index 6f23bf093d..38330d821d 100644 --- a/subxt/examples/substrate_compat_signer.rs +++ b/subxt/examples/substrate_compat_signer.rs @@ -25,7 +25,7 @@ mod pair_signer { tx::Signer, }; - /// A [`Signer`] implementation for `polkadot_sdk::sp_core::sr25519::Pair`. + /// A [`Signer`] implementation for [`polkadot_sdk::sp_core::sr25519::Pair`]. #[derive(Clone)] pub struct PairSigner { account_id: ::AccountId, @@ -33,12 +33,20 @@ mod pair_signer { } impl PairSigner { - /// Creates a new [`Signer`] from an [`sp_core::Pair`]. + /// Creates a new [`Signer`] from an [`sp_core::sr25519::Pair`]. pub fn new(signer: sr25519::Pair) -> Self { let account_id = ::Signer::from(signer.public()).into_account(); Self { // Convert `sp_core::AccountId32` to `subxt::config::substrate::AccountId32`. + // + // This is necessary because we use `subxt::config::substrate::AccountId32` and no + // From/Into impls are provided between `sp_core::AccountId32` because `polkadot-sdk` isn't a direct + // dependency in subxt. + // + // This can also be done by provided a wrapper type around `subxt::config::substrate::AccountId32` to implement + // such conversions but that also most likely requires a custom `Config` with a separate `AccountId` type to work + // properly without additional hacks. account_id: AccountId32(account_id.into()), signer, } @@ -73,20 +81,22 @@ mod pair_signer { #[tokio::main] async fn main() -> Result<(), Box> { + tracing_subscriber::fmt::init(); + // Create a new API client, configured to talk to Polkadot nodes. let api = OnlineClient::::new().await?; let signer = { - let acc = sr25519::Pair::from_string("//Alice", None).unwrap(); + let acc = sr25519::Pair::from_string("//Alice", None)?; pair_signer::PairSigner::new(acc) }; - let alice = signer.account_id().clone().into(); + let dest = subxt_signer::sr25519::dev::bob().public_key().into(); // Build a balance transfer extrinsic. let balance_transfer_tx = polkadot::tx() .balances() - .transfer_allow_death(alice, 10_000); + .transfer_allow_death(dest, 100_000); // Submit the balance transfer extrinsic from Alice, and wait for it to be successful // and in a finalized block. We get back the extrinsic events if all is well. From a0aec2c25c6edbeb3d2b5a861ef22bdcff9df4b2 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 31 Oct 2024 16:39:08 +0100 Subject: [PATCH 08/18] fix nit --- subxt/examples/substrate_compat.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/subxt/examples/substrate_compat.rs b/subxt/examples/substrate_compat.rs index a20b52da59..72f464c189 100644 --- a/subxt/examples/substrate_compat.rs +++ b/subxt/examples/substrate_compat.rs @@ -15,6 +15,17 @@ pub mod polkadot {} pub enum PolkadotConfig {} +impl subxt::Config for PolkadotConfig { + type Hash = ::Hash; + type AccountId = AccountId32; + type Address = MultiAddress; + type Signature = MultiSignature; + type Hasher = ::Hasher; + type Header = ::Header; + type ExtrinsicParams = PolkadotExtrinsicParams; + type AssetId = u32; +} + /// AccountId32 for substrate compatibility. #[derive( Clone, @@ -103,17 +114,6 @@ impl From for MultiSignature { } } -impl subxt::Config for PolkadotConfig { - type Hash = ::Hash; - type AccountId = AccountId32; - type Address = MultiAddress; - type Signature = MultiSignature; - type Hasher = ::Hasher; - type Header = ::Header; - type ExtrinsicParams = PolkadotExtrinsicParams; - type AssetId = u32; -} - /// A [`Signer`] implementation that can be constructed from an [`sp_core::Pair`]. #[derive(Clone, Debug)] pub struct PairSigner { From b4e03dd0ff1dc07ed551eedfc35d0a991c829175 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Mon, 4 Nov 2024 10:16:02 +0100 Subject: [PATCH 09/18] fix test build --- testing/integration-tests/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/integration-tests/Cargo.toml b/testing/integration-tests/Cargo.toml index 38fbe18aff..9a1016ef4d 100644 --- a/testing/integration-tests/Cargo.toml +++ b/testing/integration-tests/Cargo.toml @@ -34,7 +34,7 @@ hex = { workspace = true } regex = { workspace = true } serde = { workspace = true } scale-info = { workspace = true, features = ["bit-vec"] } -polkadot-sdk = { workspace = true, features = ["sp-core"] } +polkadot-sdk = { workspace = true, features = ["sp-core", "std"] } syn = { workspace = true } subxt = { workspace = true, features = ["unstable-metadata", "native", "jsonrpsee", "reconnecting-rpc-client"] } subxt-signer = { workspace = true, features = ["default"] } From b749326af99f817557128cfe64a8cb473306dd3f Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Tue, 12 Nov 2024 13:33:51 +0100 Subject: [PATCH 10/18] Update subxt/examples/substrate_compat_signer.rs Co-authored-by: James Wilson --- subxt/examples/substrate_compat_signer.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/subxt/examples/substrate_compat_signer.rs b/subxt/examples/substrate_compat_signer.rs index 38330d821d..3845108edd 100644 --- a/subxt/examples/substrate_compat_signer.rs +++ b/subxt/examples/substrate_compat_signer.rs @@ -91,7 +91,10 @@ async fn main() -> Result<(), Box> { pair_signer::PairSigner::new(acc) }; - let dest = subxt_signer::sr25519::dev::bob().public_key().into(); + let dest = { + let acc = sr25519::Pair::from_string("//Bob", None)?; + MultiAddress::Address32(acc.public().0) + }; // Build a balance transfer extrinsic. let balance_transfer_tx = polkadot::tx() From 1db7212f19be2cad15ff728ff74c5290168bfad2 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 13 Nov 2024 09:26:16 +0100 Subject: [PATCH 11/18] keep only polkadot signer example --- subxt/examples/substrate_compat.rs | 208 ----------------------------- 1 file changed, 208 deletions(-) delete mode 100644 subxt/examples/substrate_compat.rs diff --git a/subxt/examples/substrate_compat.rs b/subxt/examples/substrate_compat.rs deleted file mode 100644 index 72f464c189..0000000000 --- a/subxt/examples/substrate_compat.rs +++ /dev/null @@ -1,208 +0,0 @@ -#![allow(missing_docs, unused)] - -use codec::{Decode, Encode}; -use polkadot_sdk::sp_core::{self, sr25519, Pair as PairT}; -use polkadot_sdk::sp_runtime::{ - self, - traits::{IdentifyAccount, Verify}, - AccountId32 as SpAccountId32, MultiSignature as SpMultiSignature, -}; -use subxt::config::PolkadotExtrinsicParams; -use subxt::{Config, OnlineClient}; - -#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] -pub mod polkadot {} - -pub enum PolkadotConfig {} - -impl subxt::Config for PolkadotConfig { - type Hash = ::Hash; - type AccountId = AccountId32; - type Address = MultiAddress; - type Signature = MultiSignature; - type Hasher = ::Hasher; - type Header = ::Header; - type ExtrinsicParams = PolkadotExtrinsicParams; - type AssetId = u32; -} - -/// AccountId32 for substrate compatibility. -#[derive( - Clone, - Eq, - PartialEq, - Ord, - PartialOrd, - Encode, - Decode, - Debug, - scale_encode::EncodeAsType, - scale_decode::DecodeAsType, - scale_info::TypeInfo, -)] -pub struct AccountId32(subxt::config::substrate::AccountId32); - -impl From for AccountId32 { - fn from(acc: sp_runtime::AccountId32) -> Self { - Self(subxt::config::substrate::AccountId32(acc.into())) - } -} - -/// MultiAddress type for substrate compatibility. -#[derive( - Clone, - Eq, - PartialEq, - Ord, - PartialOrd, - Encode, - Decode, - Debug, - scale_encode::EncodeAsType, - scale_decode::DecodeAsType, - scale_info::TypeInfo, -)] -pub struct MultiAddress( - subxt::config::substrate::MultiAddress, -); - -impl From for MultiAddress { - fn from(a: AccountId) -> Self { - Self(subxt::config::substrate::MultiAddress::Id(a)) - } -} - -/// MultiAddress type for substrate compatibility. -#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug, scale_info::TypeInfo)] -pub struct MultiSignature(subxt::config::substrate::MultiSignature); - -impl From for MultiSignature { - fn from(value: sp_runtime::MultiSignature) -> Self { - let inner = match value { - sp_runtime::MultiSignature::Ed25519(s) => { - subxt::config::substrate::MultiSignature::Ed25519(s.0) - } - sp_runtime::MultiSignature::Sr25519(s) => { - subxt::config::substrate::MultiSignature::Sr25519(s.0) - } - sp_runtime::MultiSignature::Ecdsa(s) => { - subxt::config::substrate::MultiSignature::Ecdsa(s.0) - } - }; - Self(inner) - } -} - -impl From for MultiSignature { - fn from(value: sp_core::ed25519::Signature) -> Self { - let sig: sp_runtime::MultiSignature = value.into(); - sig.into() - } -} - -impl From for MultiSignature { - fn from(value: sp_core::sr25519::Signature) -> Self { - let sig: sp_runtime::MultiSignature = value.into(); - sig.into() - } -} - -impl From for MultiSignature { - fn from(value: sp_core::ecdsa::Signature) -> Self { - let sig: sp_runtime::MultiSignature = value.into(); - sig.into() - } -} - -/// A [`Signer`] implementation that can be constructed from an [`sp_core::Pair`]. -#[derive(Clone, Debug)] -pub struct PairSigner { - account_id: T::AccountId, - signer: Pair, -} - -impl PairSigner -where - T: Config, - Pair: PairT, - // We go via an `sp_runtime::MultiSignature`. We can probably generalise this - // by implementing some of these traits on our built-in MultiSignature and then - // requiring them on all T::Signatures, to avoid any go-between. - ::Signer: From, - T::AccountId: From, -{ - /// Creates a new [`Signer`] from an [`sp_core::Pair`]. - pub fn new(signer: Pair) -> Self { - let account_id = ::Signer::from(signer.public()).into_account(); - Self { - account_id: account_id.into(), - signer, - } - } - - /// Returns the [`sp_core::Pair`] implementation used to construct this. - pub fn signer(&self) -> &Pair { - &self.signer - } - - /// Return the account ID. - pub fn account_id(&self) -> &T::AccountId { - &self.account_id - } -} - -impl subxt::tx::Signer for PairSigner -where - T: Config, - Pair: PairT, - Pair::Signature: Into, -{ - fn account_id(&self) -> T::AccountId { - self.account_id.clone() - } - - fn address(&self) -> T::Address { - self.account_id.clone().into() - } - - fn sign(&self, signer_payload: &[u8]) -> T::Signature { - self.signer.sign(signer_payload).into() - } -} - -#[tokio::main] -async fn main() -> Result<(), Box> { - tracing_subscriber::fmt::init(); - - // Create a new API client, configured to talk to Polkadot nodes. - let api = OnlineClient::::new().await?; - - let signer: PairSigner = { - let acc = sr25519::Pair::from_string("//Alice", None)?; - PairSigner::new(acc) - }; - - let dest = subxt_signer::sr25519::dev::bob().public_key().into(); - - // Build a balance transfer extrinsic. - let balance_transfer_tx = polkadot::tx() - .balances() - .transfer_allow_death(dest, 100_000); - - // Submit the balance transfer extrinsic from Alice, and wait for it to be successful - // and in a finalized block. We get back the extrinsic events if all is well. - let events = api - .tx() - .sign_and_submit_then_watch_default(&balance_transfer_tx, &signer) - .await? - .wait_for_finalized_success() - .await?; - - // Find a Transfer event and print it. - let transfer_event = events.find_first::()?; - if let Some(event) = transfer_event { - println!("Balance transfer success: {event:?}"); - } - - Ok(()) -} From 3386938869ba0d5e3ed21b2b124d45d09442ad95 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 13 Nov 2024 09:41:10 +0100 Subject: [PATCH 12/18] remove more substrate compat related stuff --- core/Cargo.toml | 4 +-- core/src/utils/account_id.rs | 2 -- subxt/src/book/usage/transactions.rs | 54 ++++++++++++++++++++++++---- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/core/Cargo.toml b/core/Cargo.toml index a02ea57dd6..464dbbc8d2 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -47,6 +47,7 @@ derive-where = { workspace = true } hex = { workspace = true, default-features = false, features = ["alloc"] } serde = { workspace = true, default-features = false, features = ["derive"] } serde_json = { workspace = true, default-features = false, features = ["raw_value", "alloc"] } +tracing = { workspace = true, default-features = false } polkadot-sdk = { workspace = true, features = ["sp-crypto-hashing"] } hashbrown = { workspace = true } @@ -58,9 +59,6 @@ blake2 = { workspace = true } impl-serde = { workspace = true, default-features = false } primitive-types = { workspace = true, default-features = false, features = ["codec", "serde_no_std", "scale-info"] } -# Included if the "substrate-compat" feature is enabled. -tracing = { workspace = true, default-features = false } - # AccountId20 keccak-hash = { workspace = true} diff --git a/core/src/utils/account_id.rs b/core/src/utils/account_id.rs index 98234f2ce1..c3802ce5a9 100644 --- a/core/src/utils/account_id.rs +++ b/core/src/utils/account_id.rs @@ -187,8 +187,6 @@ mod test { for keyring in keyrings { let substrate_account = keyring.to_account_id(); - // Avoid "From" impl hidden behind "substrate-compat" feature so that this test - // can work either way: let local_account = AccountId32(substrate_account.clone().into()); // Both should encode to ss58 the same way: diff --git a/subxt/src/book/usage/transactions.rs b/subxt/src/book/usage/transactions.rs index c40c304830..4fd5c6fcf6 100644 --- a/subxt/src/book/usage/transactions.rs +++ b/subxt/src/book/usage/transactions.rs @@ -67,7 +67,7 @@ //! 1. The `subxt_signer` crate provides a WASM compatible implementation of [`crate::tx::Signer`] //! for chains which require sr25519 or ecdsa signatures (requires the `subxt` feature to be enabled). //! 2. Alternately, Subxt can use instances of Substrate's `sp_core::Pair` to sign things by wrapping -//! them in a `crate::tx::PairSigner` (requires the `substrate-compat` feature to be enabled). +//! them in a new type pattern and implement `crate::tx::Signer`. //! //! Going for 1 leads to fewer dependencies being imported and WASM compatibility out of the box via //! the `web` feature flag. Going for 2 is useful if you're already using the Substrate dependencies or @@ -77,7 +77,6 @@ //! Let's see how to use each of these approaches: //! //! ```rust -//! # #[cfg(feature = "substrate-compat")] //! # { //! use subxt::config::PolkadotConfig; //! use std::str::FromStr; @@ -96,24 +95,67 @@ //! .expect("valid keypair"); //! //! //// 2. Use the corresponding `sp_core::Pair` impl: -//! use subxt::tx::PairSigner; +//! +//! use polkadot_sdk::sp_runtime::{ +//! traits::{IdentifyAccount, Verify}, +//! MultiSignature as SpMultiSignature, +//! }; //! use sp_core::Pair; +//! use subxt::config::substrate::{AccountId32, MultiSignature}; +//! use subxt::Config; +//! +//! #[derive(Clone)] +//! pub struct PairSigner { +//! account_id: ::AccountId, +//! signer: sp_core::sr25519::Pair, +//! } +//! +//! impl PairSigner { +//! pub fn new(signer: sp_core::sr25519::Pair) -> Self { +//! let account_id = +//! ::Signer::from(signer.public()).into_account(); +//! Self { +//! account_id: AccountId32(account_id.into()), +//! signer, +//! } +//! } +//! +//! /// Return the account ID. +//! pub fn account_id(&self) -> &AccountId32 { +//! &self.account_id +//! } +//! } +//! +//! impl subxt::tx::Signer for PairSigner { +//! fn account_id(&self) -> ::AccountId { +//! self.account_id.clone() +//! } +//! +//! fn address(&self) -> ::Address { +//! self.account_id.clone().into() +//! } +//! +//! fn sign(&self, signer_payload: &[u8]) -> ::Signature { +//! let signature = self.signer.sign(signer_payload); +//! MultiSignature::Sr25519(signature.0) +//! } +//! } //! //! // Get hold of a `Signer` for a test account: //! let alice = sp_keyring::AccountKeyring::Alice.pair(); -//! let alice = PairSigner::::new(alice); +//! let alice = PairSigner::new(alice); //! //! // Or generate a keypair, here from an SURI: //! let keypair = sp_core::sr25519::Pair::from_string("vessel ladder alter error federal sibling chat ability sun glass valve picture/0/1///Password", None) //! .expect("valid URI"); -//! let keypair = PairSigner::::new(keypair); +//! let keypair = PairSigner::new(keypair); //! # //! # // Test that these all impl Signer trait while we're here: //! # //! # fn is_subxt_signer(_signer: impl subxt::tx::Signer) {} //! # is_subxt_signer(subxt_signer::sr25519::dev::alice()); //! # is_subxt_signer(subxt_signer::ecdsa::dev::alice()); -//! # is_subxt_signer(PairSigner::::new(sp_keyring::AccountKeyring::Alice.pair())); +//! # is_subxt_signer(PairSigner::new(sp_keyring::AccountKeyring::Alice.pair())); //! # } //! ``` //! From ace5ed440bc23746fcfe31aeefd7817f8a8ccbb0 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 13 Nov 2024 17:48:18 +0100 Subject: [PATCH 13/18] fix example --- subxt/examples/substrate_compat_signer.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/subxt/examples/substrate_compat_signer.rs b/subxt/examples/substrate_compat_signer.rs index 3845108edd..22f62d7d32 100644 --- a/subxt/examples/substrate_compat_signer.rs +++ b/subxt/examples/substrate_compat_signer.rs @@ -7,6 +7,7 @@ #![allow(missing_docs, unused)] use polkadot_sdk::sp_core::{sr25519, Pair as _}; +use subxt::config::substrate::MultiAddress; use subxt::{Config, OnlineClient, PolkadotConfig}; #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] From 097eecb86caa1fb9e730611a38f50212ea112979 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 27 Nov 2024 10:57:12 +0100 Subject: [PATCH 14/18] link to substrate signer example in book --- subxt/src/book/usage/transactions.rs | 74 +--------------------------- 1 file changed, 2 insertions(+), 72 deletions(-) diff --git a/subxt/src/book/usage/transactions.rs b/subxt/src/book/usage/transactions.rs index 4fd5c6fcf6..7340ee81f7 100644 --- a/subxt/src/book/usage/transactions.rs +++ b/subxt/src/book/usage/transactions.rs @@ -66,8 +66,7 @@ //! There are two main ways to create a compatible signer instance: //! 1. The `subxt_signer` crate provides a WASM compatible implementation of [`crate::tx::Signer`] //! for chains which require sr25519 or ecdsa signatures (requires the `subxt` feature to be enabled). -//! 2. Alternately, Subxt can use instances of Substrate's `sp_core::Pair` to sign things by wrapping -//! them in a new type pattern and implement `crate::tx::Signer`. +//! 2. Alternately, implement your own [`crate::tx::Signer`] instance using the `polkadot-sdk` signer. //! //! Going for 1 leads to fewer dependencies being imported and WASM compatibility out of the box via //! the `web` feature flag. Going for 2 is useful if you're already using the Substrate dependencies or @@ -94,76 +93,7 @@ //! let keypair = sr25519::Keypair::from_uri(&uri) //! .expect("valid keypair"); //! -//! //// 2. Use the corresponding `sp_core::Pair` impl: -//! -//! use polkadot_sdk::sp_runtime::{ -//! traits::{IdentifyAccount, Verify}, -//! MultiSignature as SpMultiSignature, -//! }; -//! use sp_core::Pair; -//! use subxt::config::substrate::{AccountId32, MultiSignature}; -//! use subxt::Config; -//! -//! #[derive(Clone)] -//! pub struct PairSigner { -//! account_id: ::AccountId, -//! signer: sp_core::sr25519::Pair, -//! } -//! -//! impl PairSigner { -//! pub fn new(signer: sp_core::sr25519::Pair) -> Self { -//! let account_id = -//! ::Signer::from(signer.public()).into_account(); -//! Self { -//! account_id: AccountId32(account_id.into()), -//! signer, -//! } -//! } -//! -//! /// Return the account ID. -//! pub fn account_id(&self) -> &AccountId32 { -//! &self.account_id -//! } -//! } -//! -//! impl subxt::tx::Signer for PairSigner { -//! fn account_id(&self) -> ::AccountId { -//! self.account_id.clone() -//! } -//! -//! fn address(&self) -> ::Address { -//! self.account_id.clone().into() -//! } -//! -//! fn sign(&self, signer_payload: &[u8]) -> ::Signature { -//! let signature = self.signer.sign(signer_payload); -//! MultiSignature::Sr25519(signature.0) -//! } -//! } -//! -//! // Get hold of a `Signer` for a test account: -//! let alice = sp_keyring::AccountKeyring::Alice.pair(); -//! let alice = PairSigner::new(alice); -//! -//! // Or generate a keypair, here from an SURI: -//! let keypair = sp_core::sr25519::Pair::from_string("vessel ladder alter error federal sibling chat ability sun glass valve picture/0/1///Password", None) -//! .expect("valid URI"); -//! let keypair = PairSigner::new(keypair); -//! # -//! # // Test that these all impl Signer trait while we're here: -//! # -//! # fn is_subxt_signer(_signer: impl subxt::tx::Signer) {} -//! # is_subxt_signer(subxt_signer::sr25519::dev::alice()); -//! # is_subxt_signer(subxt_signer::ecdsa::dev::alice()); -//! # is_subxt_signer(PairSigner::new(sp_keyring::AccountKeyring::Alice.pair())); -//! # } -//! ``` -//! -//! See the `subxt_signer` crate or the `sp_core::Pair` docs for more ways to construct -//! and work with key pairs. -//! -//! If this isn't suitable/available, you can either implement [`crate::tx::Signer`] yourself to use -//! custom signing logic, or you can use some external signing logic, like so: +//! //// 2. See `subxt/examples/substrate_compat_signer.rs` how to use the polkadot-sdk signer with Subxt. //! //! ```rust,no_run //! # #[tokio::main] From 4377fbbfe5bf9965fc430bab537dc206c770f902 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 27 Nov 2024 11:24:32 +0100 Subject: [PATCH 15/18] Update subxt/src/book/usage/transactions.rs --- subxt/src/book/usage/transactions.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/subxt/src/book/usage/transactions.rs b/subxt/src/book/usage/transactions.rs index 7340ee81f7..271feac016 100644 --- a/subxt/src/book/usage/transactions.rs +++ b/subxt/src/book/usage/transactions.rs @@ -66,7 +66,8 @@ //! There are two main ways to create a compatible signer instance: //! 1. The `subxt_signer` crate provides a WASM compatible implementation of [`crate::tx::Signer`] //! for chains which require sr25519 or ecdsa signatures (requires the `subxt` feature to be enabled). -//! 2. Alternately, implement your own [`crate::tx::Signer`] instance using the `polkadot-sdk` signer. +//! 2. Alternately, implement your own [`crate::tx::Signer`] instance by wrapping it in a new type pattern. + This can be used to use the polkadot-sdk signer instead of subxt signer. //! //! Going for 1 leads to fewer dependencies being imported and WASM compatibility out of the box via //! the `web` feature flag. Going for 2 is useful if you're already using the Substrate dependencies or From ecfb2f5c2e46c8e37fbc818ee8e466f401288bb8 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 27 Nov 2024 11:25:33 +0100 Subject: [PATCH 16/18] Update subxt/src/book/usage/transactions.rs --- subxt/src/book/usage/transactions.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/subxt/src/book/usage/transactions.rs b/subxt/src/book/usage/transactions.rs index 271feac016..a93f5b838a 100644 --- a/subxt/src/book/usage/transactions.rs +++ b/subxt/src/book/usage/transactions.rs @@ -67,7 +67,6 @@ //! 1. The `subxt_signer` crate provides a WASM compatible implementation of [`crate::tx::Signer`] //! for chains which require sr25519 or ecdsa signatures (requires the `subxt` feature to be enabled). //! 2. Alternately, implement your own [`crate::tx::Signer`] instance by wrapping it in a new type pattern. - This can be used to use the polkadot-sdk signer instead of subxt signer. //! //! Going for 1 leads to fewer dependencies being imported and WASM compatibility out of the box via //! the `web` feature flag. Going for 2 is useful if you're already using the Substrate dependencies or From 816f8402b52acd5dc842bee941ad38b9ac98f460 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 27 Nov 2024 11:51:14 +0100 Subject: [PATCH 17/18] address grumbles --- subxt/src/book/usage/transactions.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/subxt/src/book/usage/transactions.rs b/subxt/src/book/usage/transactions.rs index a93f5b838a..1462abeb43 100644 --- a/subxt/src/book/usage/transactions.rs +++ b/subxt/src/book/usage/transactions.rs @@ -73,15 +73,17 @@ //! need additional signing algorithms that `subxt_signer` doesn't support, and don't care about WASM //! compatibility. //! -//! Let's see how to use each of these approaches: +//! Because 2 is more complex and require more code, we'll focus on 1 here. +//! For 2, see the example in `subxt/examples/substrate_compat_signer.rs` how +//! you can integrate things like sp_core's signer in subxt. +//! +//! Let's go through how to create a signer using the `subxt_signer` crate: //! //! ```rust //! # { //! use subxt::config::PolkadotConfig; //! use std::str::FromStr; -//! use polkadot_sdk::{sp_core, sp_keyring}; //! -//! //// 1. Use a `subxt_signer` impl: //! use subxt_signer::{SecretUri, sr25519}; //! //! // Get hold of a `Signer` for a test account: @@ -92,8 +94,9 @@ //! .expect("valid URI"); //! let keypair = sr25519::Keypair::from_uri(&uri) //! .expect("valid keypair"); +//!``` //! -//! //// 2. See `subxt/examples/substrate_compat_signer.rs` how to use the polkadot-sdk signer with Subxt. +//! After initializing the signer, let's also go through how to create a transaction and sign it: //! //! ```rust,no_run //! # #[tokio::main] From 84c92a45c89dc47ffeb6d23f66abb50e35e73f22 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Wed, 27 Nov 2024 12:37:11 +0100 Subject: [PATCH 18/18] fix nits --- subxt/src/book/usage/transactions.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/subxt/src/book/usage/transactions.rs b/subxt/src/book/usage/transactions.rs index 1462abeb43..2a23a6537e 100644 --- a/subxt/src/book/usage/transactions.rs +++ b/subxt/src/book/usage/transactions.rs @@ -80,7 +80,6 @@ //! Let's go through how to create a signer using the `subxt_signer` crate: //! //! ```rust -//! # { //! use subxt::config::PolkadotConfig; //! use std::str::FromStr; //!