1use crate::{
18 json::{OpaqueKeyFile, Uuid},
19 Error, OpaqueSecret,
20};
21use cfx_types::H256;
22use cfxkey::{Address, Message, Password, Public, Secret, Signature};
23use std::{
24 cmp::Ordering,
25 hash::{Hash, Hasher},
26 path::PathBuf,
27};
28
29#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
31pub enum SecretVaultRef {
32 Root,
34 Vault(String),
36}
37
38#[derive(Debug, Clone)]
40pub struct StoreAccountRef {
41 pub address: Address,
43 pub vault: SecretVaultRef,
45}
46
47impl PartialOrd for StoreAccountRef {
48 fn partial_cmp(&self, other: &StoreAccountRef) -> Option<Ordering> {
49 Some(self.cmp(other))
50 }
51}
52
53impl PartialEq for StoreAccountRef {
54 fn eq(&self, other: &Self) -> bool { self.address == other.address }
55}
56impl Eq for StoreAccountRef {}
57
58impl Ord for StoreAccountRef {
59 fn cmp(&self, other: &Self) -> Ordering {
60 self.address
61 .cmp(&other.address)
62 .then_with(|| self.vault.cmp(&other.vault))
63 }
64}
65
66impl Hash for StoreAccountRef {
67 fn hash<H: Hasher>(&self, state: &mut H) { self.address.hash(state); }
68}
69
70impl ::std::borrow::Borrow<Address> for StoreAccountRef {
71 fn borrow(&self) -> &Address { &self.address }
72}
73
74pub trait SimpleSecretStore: Send + Sync {
76 fn insert_account(
78 &self, vault: SecretVaultRef, secret: Secret, password: &Password,
79 ) -> Result<StoreAccountRef, Error>;
80 fn insert_derived(
82 &self, vault: SecretVaultRef, account_ref: &StoreAccountRef,
83 password: &Password, derivation: Derivation,
84 ) -> Result<StoreAccountRef, Error>;
85 fn change_password(
87 &self, account: &StoreAccountRef, old_password: &Password,
88 new_password: &Password,
89 ) -> Result<(), Error>;
90 fn export_account(
92 &self, account: &StoreAccountRef, password: &Password,
93 ) -> Result<OpaqueKeyFile, Error>;
94 fn remove_account(
96 &self, account: &StoreAccountRef, password: &Password,
97 ) -> Result<(), Error>;
98 fn generate_derived(
100 &self, account_ref: &StoreAccountRef, password: &Password,
101 derivation: Derivation,
102 ) -> Result<Address, Error>;
103 fn sign(
105 &self, account: &StoreAccountRef, password: &Password,
106 message: &Message,
107 ) -> Result<Signature, Error>;
108 fn sign_derived(
110 &self, account_ref: &StoreAccountRef, password: &Password,
111 derivation: Derivation, message: &Message,
112 ) -> Result<Signature, Error>;
113 fn decrypt(
115 &self, account: &StoreAccountRef, password: &Password,
116 shared_mac: &[u8], message: &[u8],
117 ) -> Result<Vec<u8>, Error>;
118 fn agree(
120 &self, account: &StoreAccountRef, password: &Password, other: &Public,
121 ) -> Result<Secret, Error>;
122
123 fn accounts(&self) -> Result<Vec<StoreAccountRef>, Error>;
125 fn account_ref(&self, address: &Address) -> Result<StoreAccountRef, Error>;
129
130 fn create_vault(
132 &self, name: &str, password: &Password,
133 ) -> Result<(), Error>;
134 fn open_vault(&self, name: &str, password: &Password) -> Result<(), Error>;
136 fn close_vault(&self, name: &str) -> Result<(), Error>;
138 fn list_vaults(&self) -> Result<Vec<String>, Error>;
140 fn list_opened_vaults(&self) -> Result<Vec<String>, Error>;
142 fn change_vault_password(
144 &self, name: &str, new_password: &Password,
145 ) -> Result<(), Error>;
146 fn change_account_vault(
148 &self, vault: SecretVaultRef, account: StoreAccountRef,
149 ) -> Result<StoreAccountRef, Error>;
150 fn get_vault_meta(&self, name: &str) -> Result<String, Error>;
152 fn set_vault_meta(&self, name: &str, meta: &str) -> Result<(), Error>;
154}
155
156pub trait SecretStore: SimpleSecretStore {
158 fn raw_secret(
160 &self, account: &StoreAccountRef, password: &Password,
161 ) -> Result<OpaqueSecret, Error>;
162
163 fn sign_with_secret(
165 &self, secret: &OpaqueSecret, message: &Message,
166 ) -> Result<Signature, Error> {
167 Ok(::cfxkey::sign(&secret.0, message)?)
168 }
169
170 fn import_wallet(
172 &self, vault: SecretVaultRef, json: &[u8], password: &Password,
173 gen_id: bool,
174 ) -> Result<StoreAccountRef, Error>;
175 fn copy_account(
177 &self, new_store: &dyn SimpleSecretStore, new_vault: SecretVaultRef,
178 account: &StoreAccountRef, password: &Password,
179 new_password: &Password,
180 ) -> Result<(), Error>;
181 fn test_password(
183 &self, account: &StoreAccountRef, password: &Password,
184 ) -> Result<bool, Error>;
185
186 fn public(
188 &self, account: &StoreAccountRef, password: &Password,
189 ) -> Result<Public, Error>;
190
191 fn uuid(&self, account: &StoreAccountRef) -> Result<Uuid, Error>;
193 fn name(&self, account: &StoreAccountRef) -> Result<String, Error>;
195 fn meta(&self, account: &StoreAccountRef) -> Result<String, Error>;
197
198 fn set_name(
200 &self, account: &StoreAccountRef, name: String,
201 ) -> Result<(), Error>;
202 fn set_meta(
204 &self, account: &StoreAccountRef, meta: String,
205 ) -> Result<(), Error>;
206
207 fn local_path(&self) -> PathBuf;
209 fn list_geth_accounts(&self, testnet: bool) -> Vec<Address>;
211 fn import_geth_accounts(
213 &self, vault: SecretVaultRef, desired: Vec<Address>, testnet: bool,
214 ) -> Result<Vec<StoreAccountRef>, Error>;
215}
216
217impl StoreAccountRef {
218 pub fn root(address: Address) -> Self {
220 StoreAccountRef::new(SecretVaultRef::Root, address)
221 }
222
223 pub fn vault(vault_name: &str, address: Address) -> Self {
225 StoreAccountRef::new(
226 SecretVaultRef::Vault(vault_name.to_owned()),
227 address,
228 )
229 }
230
231 pub fn new(vault_ref: SecretVaultRef, address: Address) -> Self {
233 StoreAccountRef {
234 vault: vault_ref,
235 address,
236 }
237 }
238}
239
240pub struct IndexDerivation {
242 pub soft: bool,
244 pub index: u32,
246}
247
248pub enum Derivation {
250 Hierarchical(Vec<IndexDerivation>),
252 SoftHash(H256),
254 HardHash(H256),
256}