1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use crate::crypto::{
address::Address,
bip32::{DerivedPublicKey, DerivedSecretKey},
bip39::Mnemonic,
bip44::ChildNumber,
Algorithm,
};
use crate::types::{AccountIdentifier, CurveType, PublicKey};
use anyhow::Result;
pub struct Signer {
secp256k1: DerivedSecretKey,
secp256k1_recoverable: DerivedSecretKey,
secp256r1: DerivedSecretKey,
ed25519: DerivedSecretKey,
sr25519: DerivedSecretKey,
}
impl Signer {
pub fn new(mnemonic: &Mnemonic, password: &str) -> Result<Self> {
let secp256k1 = DerivedSecretKey::new(mnemonic, password, Algorithm::EcdsaSecp256k1)?;
let secp256k1_recoverable =
DerivedSecretKey::new(mnemonic, password, Algorithm::EcdsaRecoverableSecp256k1)?;
let secp256r1 = DerivedSecretKey::new(mnemonic, password, Algorithm::EcdsaSecp256r1)?;
let ed25519 = DerivedSecretKey::new(mnemonic, password, Algorithm::Ed25519)?;
let sr25519 = DerivedSecretKey::new(mnemonic, password, Algorithm::Sr25519)?;
Ok(Self {
secp256k1,
secp256k1_recoverable,
secp256r1,
ed25519,
sr25519,
})
}
pub fn generate() -> Result<Self> {
let mnemonic = crate::mnemonic::generate_mnemonic()?;
Self::new(&mnemonic, "")
}
pub fn master_key(&self, algorithm: Algorithm) -> Result<&DerivedSecretKey> {
Ok(match algorithm {
Algorithm::EcdsaSecp256k1 => &self.secp256k1,
Algorithm::EcdsaRecoverableSecp256k1 => &self.secp256k1_recoverable,
Algorithm::EcdsaSecp256r1 => &self.secp256r1,
Algorithm::Ed25519 => &self.ed25519,
Algorithm::Sr25519 => &self.sr25519,
})
}
pub fn bip44_account(
&self,
algorithm: Algorithm,
coin: u32,
account: u32,
) -> Result<DerivedSecretKey> {
self.master_key(algorithm)?
.derive(ChildNumber::hardened_from_u32(44))?
.derive(ChildNumber::hardened_from_u32(coin))?
.derive(ChildNumber::hardened_from_u32(account))
}
}
pub trait RosettaPublicKey {
fn to_rosetta(&self) -> PublicKey;
}
impl RosettaPublicKey for DerivedPublicKey {
fn to_rosetta(&self) -> PublicKey {
PublicKey {
curve_type: match self.public_key().algorithm() {
Algorithm::EcdsaSecp256k1 => CurveType::Secp256k1,
Algorithm::EcdsaRecoverableSecp256k1 => CurveType::Secp256k1,
Algorithm::EcdsaSecp256r1 => CurveType::Secp256r1,
Algorithm::Ed25519 => CurveType::Edwards25519,
Algorithm::Sr25519 => CurveType::Schnorrkel,
},
hex_bytes: hex::encode(self.public_key().to_bytes()),
}
}
}
pub trait RosettaAccount {
fn to_rosetta(&self) -> AccountIdentifier;
}
impl RosettaAccount for Address {
fn to_rosetta(&self) -> AccountIdentifier {
AccountIdentifier {
address: self.address().into(),
sub_account: None,
metadata: None,
}
}
}