cargo_tangle/
keys.rs

1use clap::builder::PossibleValue;
2use clap::ValueEnum;
3use color_eyre::eyre::eyre;
4use gadget_sdk::keystore::backend::fs::FilesystemKeystore;
5use gadget_sdk::keystore::backend::mem::InMemoryKeystore;
6use gadget_sdk::keystore::backend::GenericKeyStore;
7use gadget_sdk::keystore::Backend;
8use gadget_sdk::parking_lot::RawRwLock;
9use std::path::PathBuf;
10use std::str::FromStr;
11use w3f_bls::serialize::SerializableToBytes;
12
13#[derive(thiserror::Error, Debug)]
14pub enum Error {
15    #[error("Unknown key type: {0}")]
16    UnknownKeyType(String),
17}
18
19#[derive(Clone, Debug)]
20pub enum KeyType {
21    Sr25519,
22    Ed25519,
23    Ecdsa,
24    Bls381,
25    BlsBn254,
26}
27
28impl ValueEnum for KeyType {
29    fn value_variants<'a>() -> &'a [Self] {
30        &[
31            Self::Sr25519,
32            Self::Ed25519,
33            Self::Ecdsa,
34            Self::Bls381,
35            Self::BlsBn254,
36        ]
37    }
38
39    fn to_possible_value(&self) -> Option<PossibleValue> {
40        Some(match self {
41            Self::Sr25519 => PossibleValue::new("sr25519").help("Schnorrkel/Ristretto x25519"),
42            Self::Ed25519 => PossibleValue::new("ed25519").help("Edwards Curve 25519"),
43            Self::Ecdsa => {
44                PossibleValue::new("ecdsa").help("Elliptic Curve Digital Signature Algorithm")
45            }
46            Self::Bls381 => PossibleValue::new("bls381").help("Boneh-Lynn-Shacham on BLS12-381"),
47            Self::BlsBn254 => PossibleValue::new("blsbn254").help("Boneh-Lynn-Shacham on BN254"),
48        })
49    }
50}
51
52impl FromStr for KeyType {
53    type Err = Error;
54
55    fn from_str(s: &str) -> Result<Self, Self::Err> {
56        let lower = s.to_lowercase();
57        match lower.as_str() {
58            "sr25519" => Ok(Self::Sr25519),
59            "ed25519" => Ok(Self::Ed25519),
60            "ecdsa" => Ok(Self::Ecdsa),
61            "bls381" => Ok(Self::Bls381),
62            "blsbn254" => Ok(Self::BlsBn254),
63            _ => Err(Error::UnknownKeyType(lower)),
64        }
65    }
66}
67
68pub fn generate_key(
69    key_type: KeyType,
70    output: Option<PathBuf>,
71    seed: Option<&[u8]>,
72    show_secret: bool,
73) -> color_eyre::Result<()> {
74    let keystore: GenericKeyStore<RawRwLock> = match output {
75        None => GenericKeyStore::Mem(InMemoryKeystore::new()),
76        Some(file_path) => {
77            // Filesystem Keystore
78            GenericKeyStore::Fs(FilesystemKeystore::open(file_path)?)
79        }
80    };
81
82    let (public, secret) = match key_type {
83        KeyType::Sr25519 => {
84            let public_key = keystore.sr25519_generate_new(seed)?;
85            let secret = keystore
86                .expose_sr25519_secret(&public_key)?
87                .ok_or(eyre!("Failed to expose secret"))?;
88            (
89                hex::encode(public_key.to_bytes()),
90                hex::encode(secret.to_bytes()),
91            )
92        }
93        KeyType::Ed25519 => {
94            let public_key = keystore.ed25519_generate_new(seed)?;
95            let secret = keystore
96                .expose_ed25519_secret(&public_key)?
97                .ok_or(eyre!("Failed to expose secret"))?;
98            (hex::encode(public_key), hex::encode(secret))
99        }
100        KeyType::Ecdsa => {
101            let public_key = keystore.ecdsa_generate_new(seed)?;
102            let secret = keystore
103                .expose_ecdsa_secret(&public_key)?
104                .ok_or(eyre!("Failed to expose secret"))?;
105            (
106                hex::encode(public_key.to_sec1_bytes()),
107                hex::encode(secret.to_bytes()),
108            )
109        }
110        KeyType::Bls381 => {
111            let public_key = keystore.bls381_generate_new(seed)?;
112            let secret = keystore
113                .expose_bls381_secret(&public_key)?
114                .ok_or(eyre!("Failed to expose secret"))?;
115            (
116                hex::encode(public_key.0.to_string()),
117                hex::encode(secret.to_bytes()),
118            )
119        }
120        KeyType::BlsBn254 => {
121            let public_key = keystore.bls_bn254_generate_new(seed)?;
122            let secret = keystore
123                .expose_bls_bn254_secret(&public_key)?
124                .ok_or(eyre!("Failed to expose secret"))?;
125            (public_key.g1().to_string(), secret.0.to_string())
126        }
127    };
128
129    eprintln!("Generated {:?} key:", key_type);
130    eprintln!("Public key: {}", public);
131    if show_secret || keystore.is_mem() {
132        eprintln!("Private key: {}", secret);
133    }
134
135    Ok(())
136}