kms_secp256k1_api/services/mocks/
mock_casper_keys_service.rs1use crate::{
2 config::Config,
3 constants::{CASPER_SECP_LEN, CASPER_SECP_PREFIX},
4 services::{
5 crypto_service::CryptoService,
6 keys_service::{KeyEntry, KeysServiceTrait, SigEntry},
7 mocks::mock_keys_service::{KeyPair, MockKeysService},
8 },
9};
10use base64::Engine;
11use base64::engine::general_purpose::STANDARD;
12use casper_rust_wasm_sdk::{
13 SDK,
14 helpers::{public_key_from_secret_key, secret_key_secp256k1_generate},
15 types::{
16 transaction::Transaction, transaction_params::transaction_str_params::TransactionStrParams,
17 },
18};
19use regex::Regex;
20use tracing::error;
21
22pub struct MockCasperKeysService {
23 inner: MockKeysService,
24}
25
26#[async_trait::async_trait]
27impl KeysServiceTrait for MockCasperKeysService {
28 async fn create_key(&mut self, _config: &Config) -> Result<KeyEntry, String> {
29 let private_key = secret_key_secp256k1_generate()
30 .map_err(|e| format!("Failed to generate secret key: {e}"))?;
31 let private_key = private_key.to_pem().map_err(|e| e.to_string())?;
32
33 let address = public_key_from_secret_key(&private_key)
34 .map_err(|e| format!("Failed to get public key: {e}"))?; let public_key = address.replacen(CASPER_SECP_PREFIX, "", 1).clone(); let key_id = public_key.clone();
39
40 let public_key_base64 = STANDARD.encode(&public_key);
41
42 let key_pair = KeyPair {
44 public_key: public_key.clone(),
45 private_key,
46 address: address.clone(),
47 };
48
49 let key_entry = {
50 {
51 let mut keys = self.inner.keys.lock().await;
52 keys.entry(address.clone()).or_insert(key_pair);
53 } KeyEntry {
56 public_key: Some(public_key).into(),
57 address: address.into(),
58 public_key_base64: public_key_base64.into(),
59 key_id: key_id.into(),
60 }
61 };
62
63 Ok(key_entry)
64 }
65
66 async fn sign_transaction_hash(
67 &mut self,
68 config: &Config,
69 transaction_hash: &str,
70 key: &str,
71 ) -> Result<SigEntry, String> {
72 let key = Self::resolve_key(key);
73 let key_pair = {
74 let keys = self.inner.keys.lock().await;
75 keys.get(&key)
76 .ok_or_else(|| "Public key not found".to_string())?
77 .clone()
78 };
79
80 let public_key = key_pair.address;
81
82 let transaction_params = TransactionStrParams::default();
83 transaction_params.set_chain_name("casper-net-1");
84 transaction_params.set_initiator_addr(&public_key);
85 transaction_params.set_payment_amount("100000000");
86 let sdk = SDK::new(None, None, None);
87 let make_transfer = sdk
88 .make_transfer_transaction(None, &public_key, "2500000000", transaction_params, None)
89 .map_err(|e| format!("Failed to create transfer transaction: {e}"))?;
90
91 let mut transaction_str = make_transfer.to_json_string().unwrap_or_default();
92
93 let re = Regex::new(r#""hash"\s*:\s*"[^"]+""#).unwrap();
94 transaction_str = re
95 .replace(&transaction_str, format!(r#""hash": "{transaction_hash}""#))
96 .to_string();
97
98 let signed_tx = self
99 .sign_transaction(config, &transaction_str, &public_key)
100 .await
101 .unwrap_or_default();
102
103 let transaction: Transaction = Transaction::from_json_string(&signed_tx)
104 .map_err(|e| format!("Failed to parse transaction: {e}"))?;
105
106 let signature = transaction
107 .approvals()
108 .first()
109 .unwrap()
110 .signature()
111 .to_hex_string();
112
113 Ok(SigEntry {
114 address: public_key.clone().into(),
115 public_key: public_key.replacen(CASPER_SECP_PREFIX, "", 1).into(),
116 signature: signature.into(),
117 })
118 }
119
120 async fn sign_transaction(
121 &mut self,
122 _config: &Config,
123 transaction_str: &str,
124 key: &str,
125 ) -> Result<String, String> {
126 let mut transaction: Transaction = Transaction::from_json_string(transaction_str)
127 .map_err(|e| format!("Failed to parse transaction: {e}"))?;
128
129 let key = Self::resolve_key(key);
130 let key_pair = {
131 let keys = self.inner.keys.lock().await;
132 keys.get(&key)
133 .ok_or_else(|| "Public key not found".to_string())?
134 .clone()
135 };
136
137 let signed_tx = transaction.sign(&key_pair.private_key);
138
139 Ok(signed_tx.to_json_string().unwrap_or_default())
140 }
141
142 async fn verify(
143 &mut self,
144 transaction_hash_hex: &str,
145 signature_hex: &str,
146 key: &str,
147 ) -> Result<bool, String> {
148 let key = Self::resolve_key(key);
149 self.inner
150 .verify(transaction_hash_hex, signature_hex, &key)
151 .map_err(|e| {
152 let msg = format!("Signature verification failed: {e}");
153 error!("{}", msg);
154 msg
155 })
156 }
157
158 async fn verify_via_kms(
159 &mut self,
160 transaction_hash_hex: &str,
161 signature_hex: &str,
162 key: &str,
163 ) -> Result<bool, String> {
164 let key = Self::resolve_key(key);
165 self.inner
166 .verify_via_kms(transaction_hash_hex, signature_hex, &key)
167 .await
168 }
169
170 async fn delete_key(&mut self, key: &str) -> Result<bool, String> {
171 let key = Self::resolve_key(key);
172 Ok(self.inner.delete_key(&key).await)
173 }
174
175 async fn list_keys(&mut self) -> Result<Vec<KeyEntry>, String> {
176 Ok(self.inner.list_keys().await)
177 }
178}
179
180impl MockCasperKeysService {
181 pub fn new(config: Config, crypto_service: CryptoService) -> Result<Self, String> {
193 Ok(Self {
194 inner: MockKeysService::new(config, crypto_service),
195 })
196 }
197
198 fn resolve_key(key: &str) -> String {
199 if key.len() == CASPER_SECP_LEN {
200 key.to_string()
201 } else {
202 format!("{CASPER_SECP_PREFIX}{key}")
203 }
204 }
205}