Add subxt_signer crate for native & WASM compatible signing (#1016)

* Add and use subxt-signer crate for WASM compatible signing

* cargo fmt

* dev keypairs already references

* WIP fix various breakages

* re-jig features to be simpler and various test fixes etc

* doc and web fix

* fix various bits and pieces

* fix a test I broke

* dev-deps can't be linked to in docs, hrmph

* cargo fmt

* another doc link

* document the subxt_signer crate more thoroughly

* move feature flag for consistency

* more docs, no default subxt feature flag on signer, update release instrs

* Add missing license header

* unwrap_inner => into_inner

* extend a test a little to better check derive junctions

* note more clearly that the crypto bits come from sp_core::crypto
This commit is contained in:
James Wilson
2023-06-20 11:32:12 +01:00
committed by GitHub
parent d091c091ae
commit b4eb406ee5
52 changed files with 1388 additions and 302 deletions
-4
View File
@@ -16,8 +16,6 @@
//! We can use the statically generated interface to build constant queries:
//!
//! ```rust,no_run
//! use sp_keyring::AccountKeyring;
//!
//! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_full.scale")]
//! pub mod polkadot {}
//!
@@ -27,10 +25,8 @@
//! Alternately, we can dynamically construct a constant query:
//!
//! ```rust,no_run
//! use sp_keyring::AccountKeyring;
//! use subxt::dynamic::Value;
//!
//! let account = AccountKeyring::Alice.to_account_id();
//! let storage_query = subxt::dynamic::constant("System", "BlockLength");
//! ```
//!
-4
View File
@@ -22,8 +22,6 @@
//! We can use the statically generated interface to build runtime calls:
//!
//! ```rust,no_run
//! use sp_keyring::AccountKeyring;
//!
//! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")]
//! pub mod polkadot {}
//!
@@ -33,10 +31,8 @@
//! Alternately, we can dynamically construct a runtime call:
//!
//! ```rust,no_run
//! use sp_keyring::AccountKeyring;
//! use subxt::dynamic::Value;
//!
//! let account = AccountKeyring::Alice.to_account_id();
//! let runtime_call = subxt::dynamic::runtime_api_call(
//! "Metadata",
//! "metadata_versions",
+4 -6
View File
@@ -16,12 +16,12 @@
//! We can use the statically generated interface to build storage queries:
//!
//! ```rust,no_run
//! use sp_keyring::AccountKeyring;
//! use subxt_signer::sr25519::dev;
//!
//! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")]
//! pub mod polkadot {}
//!
//! let account = AccountKeyring::Alice.to_account_id().into();
//! let account = dev::alice().public_key().into();
//! let storage_query = polkadot::storage().system().account(&account);
//! ```
//!
@@ -29,10 +29,10 @@
//! validated until it's submitted:
//!
//! ```rust,no_run
//! use sp_keyring::AccountKeyring;
//! use subxt_signer::sr25519::dev;
//! use subxt::dynamic::Value;
//!
//! let account = AccountKeyring::Alice.to_account_id();
//! let account = dev::alice().public_key();
//! let storage_query = subxt::dynamic::storage("System", "Account", vec![
//! Value::from_bytes(account)
//! ]);
@@ -43,8 +43,6 @@
//! will only be available on static constructors when iteration is actually possible):
//!
//! ```rust,no_run
//! use sp_keyring::AccountKeyring;
//!
//! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")]
//! pub mod polkadot {}
//!
+42 -17
View File
@@ -60,28 +60,54 @@
//! ## Signing it
//!
//! You'll normally need to sign an extrinsic to prove that it originated from an account that you
//! control. To do this, you will typically first create an [`crate::tx::Signer`], which tells Subxt
//! who the extrinsic is from, and takes care of signing the relevant details to prove this.
//! control. To do this, you will typically first create a [`crate::tx::Signer`] instance, which tells
//! Subxt who the extrinsic is from, and takes care of signing the relevant details to prove this.
//!
//! Subxt provides a [`crate::tx::PairSigner`] which implements this trait (if the
//! `substrate-compat` feature is enabled) which accepts any valid [`sp_core::Pair`] and uses that
//! to sign transactions:
//! 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 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).
//!
//! 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
//! 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:
//!
//! ```rust
//! use subxt::config::PolkadotConfig;
//! use std::str::FromStr;
//!
//! //// 1. Use a `subxt_signer` impl:
//! use subxt_signer::{ SecretUri, sr25519 };
//!
//! // Get hold of a `Signer` for a test account:
//! let alice = sr25519::dev::alice();
//!
//! // Or generate a keypair, here from an SURI:
//! let uri = SecretUri::from_str("vessel ladder alter error federal sibling chat ability sun glass valve picture/0/1///Password")
//! .expect("valid URI");
//! let keypair = sr25519::Keypair::from_uri(&uri)
//! .expect("valid keypair");
//!
//! //// 2. Use the corresponding `sp_core::Pair` impl:
//! use subxt::tx::PairSigner;
//! use sp_core::Pair;
//! use subxt::config::PolkadotConfig;
//!
//! // Get hold of a `Signer` given a test account:
//! let pair = sp_keyring::AccountKeyring::Alice.pair();
//! let signer = PairSigner::<PolkadotConfig,_>::new(pair);
//! // Get hold of a `Signer` for a test account:
//! let alice = sp_keyring::AccountKeyring::Alice.pair();
//! let alice = PairSigner::<PolkadotConfig,_>::new(alice);
//!
//! // Or generate an `sr25519` keypair to use:
//! let (pair, _, _) = sp_core::sr25519::Pair::generate_with_phrase(Some("password"));
//! let signer = PairSigner::<PolkadotConfig,_>::new(pair);
//! // 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::<PolkadotConfig,_>::new(keypair);
//! ```
//!
//! See the [`sp_core::Pair`] docs for more ways to generate them.
//! See the `subxt_signer::sr25519::Keypair` 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:
@@ -118,10 +144,9 @@
//! let signature;
//! let address;
//! # use subxt::tx::Signer;
//! # let pair = sp_keyring::AccountKeyring::Alice.pair();
//! # let signer = subxt::tx::PairSigner::<PolkadotConfig,_>::new(pair);
//! # signature = signer.sign(&signer_payload);
//! # address = signer.address();
//! # let signer = subxt_signer::sr25519::dev::alice();
//! # signature = signer.sign(&signer_payload).into();
//! # address = signer.public_key().to_address();
//!
//! // Now we can build an tx, which one can call `submit` or `submit_and_watch`
//! // on to submit to a node and optionally watch the status.