iota_sdk/client/secret/
private_key.rs1use std::ops::Range;
7
8use async_trait::async_trait;
9use crypto::{
10 hashes::{blake2b::Blake2b256, Digest},
11 keys::bip44::Bip44,
12 signatures::{
13 ed25519,
14 secp256k1_ecdsa::{self, EvmAddress},
15 },
16};
17use zeroize::{Zeroize, Zeroizing};
18
19use super::{GenerateAddressOptions, SecretManage};
20use crate::{
21 client::{api::PreparedTransactionData, Error},
22 types::block::{
23 address::Ed25519Address, payload::transaction::TransactionPayload, signature::Ed25519Signature, unlock::Unlocks,
24 },
25};
26
27pub struct PrivateKeySecretManager(ed25519::SecretKey);
29
30impl std::fmt::Debug for PrivateKeySecretManager {
31 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
32 f.debug_tuple("PrivateKeySecretManager").finish()
33 }
34}
35
36#[async_trait]
37impl SecretManage for PrivateKeySecretManager {
38 type Error = Error;
39
40 async fn generate_ed25519_addresses(
41 &self,
42 _coin_type: u32,
43 _account_index: u32,
44 _address_indexes: Range<u32>,
45 _options: impl Into<Option<GenerateAddressOptions>> + Send,
46 ) -> Result<Vec<Ed25519Address>, Self::Error> {
47 let public_key = self.0.public_key().to_bytes();
48
49 let result = Blake2b256::digest(public_key).into();
51
52 crate::client::Result::Ok(vec![Ed25519Address::new(result)])
53 }
54
55 async fn generate_evm_addresses(
56 &self,
57 _coin_type: u32,
58 _account_index: u32,
59 _address_indexes: Range<u32>,
60 _options: impl Into<Option<GenerateAddressOptions>> + Send,
61 ) -> Result<Vec<EvmAddress>, Self::Error> {
62 Err(Error::SecretManagerMismatch)
64 }
65
66 async fn sign_ed25519(&self, msg: &[u8], _chain: Bip44) -> Result<Ed25519Signature, Self::Error> {
67 let public_key = self.0.public_key();
68 let signature = self.0.sign(msg);
69
70 Ok(Ed25519Signature::new(public_key, signature))
71 }
72
73 async fn sign_secp256k1_ecdsa(
74 &self,
75 _msg: &[u8],
76 _chain: Bip44,
77 ) -> Result<(secp256k1_ecdsa::PublicKey, secp256k1_ecdsa::RecoverableSignature), Self::Error> {
78 Err(Error::SecretManagerMismatch)
80 }
81
82 async fn sign_transaction_essence(
83 &self,
84 prepared_transaction_data: &PreparedTransactionData,
85 time: Option<u32>,
86 ) -> Result<Unlocks, Self::Error> {
87 super::default_sign_transaction_essence(self, prepared_transaction_data, time).await
88 }
89
90 async fn sign_transaction(
91 &self,
92 prepared_transaction_data: PreparedTransactionData,
93 ) -> Result<TransactionPayload, Self::Error> {
94 super::default_sign_transaction(self, prepared_transaction_data).await
95 }
96}
97
98impl PrivateKeySecretManager {
99 pub fn try_from_b58<T: AsRef<[u8]>>(b58: T) -> Result<Self, Error> {
101 let mut bytes = [0u8; ed25519::SecretKey::LENGTH];
102
103 if bs58::decode(b58.as_ref())
105 .onto(&mut bytes)
106 .map_err(|_| crypto::Error::PrivateKeyError)?
107 != ed25519::SecretKey::LENGTH
108 {
109 return Err(crypto::Error::PrivateKeyError.into());
111 }
112
113 let private_key = Self(ed25519::SecretKey::from_bytes(&bytes));
114
115 bytes.zeroize();
116
117 Ok(private_key)
118 }
119
120 pub fn try_from_hex(hex: impl Into<Zeroizing<String>>) -> Result<Self, Error> {
122 let mut bytes = prefix_hex::decode(hex.into())?;
123
124 let private_key = Self(ed25519::SecretKey::from_bytes(&bytes));
125
126 bytes.zeroize();
127
128 Ok(private_key)
129 }
130}