mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 17:28:00 +00:00
Support for keyring in runtimes (#2044)
This functionality is required for #1984. This PR enables [`sp-keyring`](https://github.com/paritytech/polkadot-sdk/blob/21d36b7b4229c4d5225944f197918cde23fda4ea/substrate/primitives/keyring/src/sr25519.rs#L31-L40) in `no-std` environments, allowing to generate the public key (e.g. `AccountKeyring::Alice.public().to_ss58check()`), which can be later used in the any of built-in [_runtime-genesis-config_ variant](https://github.com/paritytech/polkadot-sdk/blob/21d36b7b4229c4d5225944f197918cde23fda4ea/polkadot/node/service/src/chain_spec.rs#L1066-L1073). The proposal is as follows: - expose [`core::Pair` trait](https://github.com/paritytech/polkadot-sdk/blob/d6f15306282e3de848a09c9aa9cba6f95a7811f0/substrate/primitives/core/src/crypto.rs#L832) in `no-std`, - `full_crypto` feature enables `sign` method, - `std` feature enables `generate_with_phrase` and `generate` methods (randomness is required), - All other functionality, currently gated by `full_crypto` will be available unconditionally (`no-std`): -- `from_string` -- `from_string_with_seed` -- `from seed` -- `from_seed_slice` -- `from_phrase` -- `derive` -- `verify` --- Depends on https://github.com/rust-bitcoin/rust-bip39/pull/57 --------- Co-authored-by: command-bot <> Co-authored-by: Davide Galassi <davxy@datawok.net>
This commit is contained in:
committed by
GitHub
parent
1ead59773e
commit
a756baf3b2
@@ -18,7 +18,6 @@
|
||||
//! Cryptographic utilities.
|
||||
|
||||
use crate::{ed25519, sr25519};
|
||||
#[cfg(feature = "std")]
|
||||
use bip39::{Language, Mnemonic};
|
||||
use codec::{Decode, Encode, MaxEncodedLen};
|
||||
#[cfg(feature = "std")]
|
||||
@@ -26,7 +25,6 @@ use itertools::Itertools;
|
||||
#[cfg(feature = "std")]
|
||||
use rand::{rngs::OsRng, RngCore};
|
||||
use scale_info::TypeInfo;
|
||||
#[cfg(feature = "std")]
|
||||
pub use secrecy::{ExposeSecret, SecretString};
|
||||
use sp_runtime_interface::pass_by::PassByInner;
|
||||
#[doc(hidden)]
|
||||
@@ -41,10 +39,7 @@ pub use ss58_registry::{from_known_address_format, Ss58AddressFormat, Ss58Addres
|
||||
/// Trait to zeroize a memory buffer.
|
||||
pub use zeroize::Zeroize;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub use crate::address_uri::AddressUri;
|
||||
#[cfg(any(feature = "std", feature = "full_crypto"))]
|
||||
pub use crate::address_uri::Error as AddressUriError;
|
||||
pub use crate::address_uri::{AddressUri, Error as AddressUriError};
|
||||
|
||||
/// The root phrase for our publicly known keys.
|
||||
pub const DEV_PHRASE: &str =
|
||||
@@ -82,7 +77,6 @@ impl<S, T: UncheckedFrom<S>> UncheckedInto<T> for S {
|
||||
/// An error with the interpretation of a secret.
|
||||
#[cfg_attr(feature = "std", derive(thiserror::Error))]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[cfg(feature = "full_crypto")]
|
||||
pub enum SecretStringError {
|
||||
/// The overall format was invalid (e.g. the seed phrase contained symbols).
|
||||
#[cfg_attr(feature = "std", error("Invalid format {0}"))]
|
||||
@@ -104,7 +98,6 @@ pub enum SecretStringError {
|
||||
InvalidPath,
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "full_crypto"))]
|
||||
impl From<AddressUriError> for SecretStringError {
|
||||
fn from(e: AddressUriError) -> Self {
|
||||
Self::InvalidFormat(e)
|
||||
@@ -114,7 +107,6 @@ impl From<AddressUriError> for SecretStringError {
|
||||
/// An error when deriving a key.
|
||||
#[cfg_attr(feature = "std", derive(thiserror::Error))]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[cfg(feature = "full_crypto")]
|
||||
pub enum DeriveError {
|
||||
/// A soft key was found in the path (and is unsupported).
|
||||
#[cfg_attr(feature = "std", error("Soft key in path"))]
|
||||
@@ -125,7 +117,6 @@ pub enum DeriveError {
|
||||
/// a new secret key from an existing secret key and, in the case of `SoftRaw` and `SoftIndex`
|
||||
/// a new public key from an existing public key.
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Encode, Decode)]
|
||||
#[cfg(any(feature = "full_crypto", feature = "serde"))]
|
||||
pub enum DeriveJunction {
|
||||
/// Soft (vanilla) derivation. Public keys have a correspondent derivation.
|
||||
Soft([u8; JUNCTION_ID_LEN]),
|
||||
@@ -133,7 +124,6 @@ pub enum DeriveJunction {
|
||||
Hard([u8; JUNCTION_ID_LEN]),
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "full_crypto", feature = "serde"))]
|
||||
impl DeriveJunction {
|
||||
/// Consume self to return a soft derive junction with the same chain code.
|
||||
pub fn soften(self) -> Self {
|
||||
@@ -192,7 +182,6 @@ impl DeriveJunction {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "full_crypto", feature = "serde"))]
|
||||
impl<T: AsRef<str>> From<T> for DeriveJunction {
|
||||
fn from(j: T) -> DeriveJunction {
|
||||
let j = j.as_ref();
|
||||
@@ -812,7 +801,6 @@ mod dummy {
|
||||
/// assert_eq!("0xe5be9a5092b81bca64be81d212e7f2f9eba183bb7a90954f7b76361f6edb5c0a", suri.phrase.expose_secret());
|
||||
/// assert!(suri.password.is_none());
|
||||
/// ```
|
||||
#[cfg(feature = "std")]
|
||||
pub struct SecretUri {
|
||||
/// The phrase to derive the private key.
|
||||
///
|
||||
@@ -824,7 +812,6 @@ pub struct SecretUri {
|
||||
pub junctions: Vec<DeriveJunction>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl sp_std::str::FromStr for SecretUri {
|
||||
type Err = SecretStringError;
|
||||
|
||||
@@ -845,7 +832,6 @@ impl sp_std::str::FromStr for SecretUri {
|
||||
/// Trait suitable for typical cryptographic PKI key pair type.
|
||||
///
|
||||
/// For now it just specifies how to create a key from a phrase and derivation path.
|
||||
#[cfg(feature = "full_crypto")]
|
||||
pub trait Pair: CryptoType + Sized {
|
||||
/// The type which is used to encode a public key.
|
||||
type Public: Public + Hash;
|
||||
@@ -878,21 +864,19 @@ pub trait Pair: CryptoType + Sized {
|
||||
#[cfg(feature = "std")]
|
||||
fn generate_with_phrase(password: Option<&str>) -> (Self, String, Self::Seed) {
|
||||
let mnemonic = Mnemonic::generate(12).expect("Mnemonic generation always works; qed");
|
||||
let phrase = mnemonic.word_iter().join(" ");
|
||||
let phrase = mnemonic.words().join(" ");
|
||||
let (pair, seed) = Self::from_phrase(&phrase, password)
|
||||
.expect("All phrases generated by Mnemonic are valid; qed");
|
||||
(pair, phrase.to_owned(), seed)
|
||||
}
|
||||
|
||||
/// Returns the KeyPair from the English BIP39 seed `phrase`, or an error if it's invalid.
|
||||
#[cfg(feature = "std")]
|
||||
fn from_phrase(
|
||||
phrase: &str,
|
||||
password: Option<&str>,
|
||||
) -> Result<(Self, Self::Seed), SecretStringError> {
|
||||
let mnemonic = Mnemonic::parse_in(Language::English, phrase)
|
||||
.map_err(|_| SecretStringError::InvalidPhrase)?;
|
||||
|
||||
let (entropy, entropy_len) = mnemonic.to_entropy_array();
|
||||
let big_seed =
|
||||
substrate_bip39::seed_from_entropy(&entropy[0..entropy_len], password.unwrap_or(""))
|
||||
@@ -928,6 +912,7 @@ pub trait Pair: CryptoType + Sized {
|
||||
fn from_seed_slice(seed: &[u8]) -> Result<Self, SecretStringError>;
|
||||
|
||||
/// Sign a message.
|
||||
#[cfg(feature = "full_crypto")]
|
||||
fn sign(&self, message: &[u8]) -> Self::Signature;
|
||||
|
||||
/// Verify a signature on a message. Returns true if the signature is good.
|
||||
@@ -962,7 +947,6 @@ pub trait Pair: CryptoType + Sized {
|
||||
/// Notably, integer junction indices may be legally prefixed with arbitrary number of zeros.
|
||||
/// Similarly an empty password (ending the SURI with `///`) is perfectly valid and will
|
||||
/// generally be equivalent to no password at all.
|
||||
#[cfg(feature = "std")]
|
||||
fn from_string_with_seed(
|
||||
s: &str,
|
||||
password_override: Option<&str>,
|
||||
@@ -996,7 +980,6 @@ pub trait Pair: CryptoType + Sized {
|
||||
/// Interprets the string `s` in order to generate a key pair.
|
||||
///
|
||||
/// See [`from_string_with_seed`](Pair::from_string_with_seed) for more extensive documentation.
|
||||
#[cfg(feature = "std")]
|
||||
fn from_string(s: &str, password_override: Option<&str>) -> Result<Self, SecretStringError> {
|
||||
Self::from_string_with_seed(s, password_override).map(|x| x.0)
|
||||
}
|
||||
@@ -1054,7 +1037,6 @@ where
|
||||
/// Type which has a particular kind of crypto associated with it.
|
||||
pub trait CryptoType {
|
||||
/// The pair key type of this crypto.
|
||||
#[cfg(feature = "full_crypto")]
|
||||
type Pair: Pair;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user