1use std::{collections::HashSet, fs, path::Path};
18
19use crate::{
20 accounts_dir::{
21 DiskKeyFileManager, KeyDirectory, KeyFileManager, RootDiskDirectory,
22 },
23 Error,
24};
25use cfxkey::Address;
26
27pub fn import_account(
29 path: &Path, dst: &dyn KeyDirectory,
30) -> Result<Address, Error> {
31 let key_manager = DiskKeyFileManager::default();
32 let existing_accounts = dst
33 .load()?
34 .into_iter()
35 .map(|a| a.address)
36 .collect::<HashSet<_>>();
37 let filename = path
38 .file_name()
39 .and_then(|n| n.to_str())
40 .map(|f| f.to_owned());
41 let account = fs::File::open(path)
42 .map_err(Into::into)
43 .and_then(|file| key_manager.read(filename, file))?;
44
45 let address = account.address;
46 if !existing_accounts.contains(&address) {
47 dst.insert(account)?;
48 }
49 Ok(address)
50}
51
52pub fn import_accounts(
54 src: &dyn KeyDirectory, dst: &dyn KeyDirectory,
55) -> Result<Vec<Address>, Error> {
56 let accounts = src.load()?;
57 let existing_accounts = dst
58 .load()?
59 .into_iter()
60 .map(|a| a.address)
61 .collect::<HashSet<_>>();
62
63 accounts
64 .into_iter()
65 .filter(|a| !existing_accounts.contains(&a.address))
66 .map(|a| {
67 let address = a.address;
68 dst.insert(a)?;
69 Ok(address)
70 })
71 .collect()
72}
73
74pub fn read_geth_accounts(testnet: bool) -> Vec<Address> {
77 RootDiskDirectory::at(dir::geth(testnet))
78 .load()
79 .map(|d| d.into_iter().map(|a| a.address).collect())
80 .unwrap_or_else(|_| Vec::new())
81}
82
83pub fn import_geth_accounts(
85 dst: &dyn KeyDirectory, desired: HashSet<Address>, testnet: bool,
86) -> Result<Vec<Address>, Error> {
87 let src = RootDiskDirectory::at(dir::geth(testnet));
88 let accounts = src.load()?;
89 let existing_accounts = dst
90 .load()?
91 .into_iter()
92 .map(|a| a.address)
93 .collect::<HashSet<_>>();
94
95 accounts
96 .into_iter()
97 .filter(|a| !existing_accounts.contains(&a.address))
98 .filter(|a| desired.contains(&a.address))
99 .map(|a| {
100 let address = a.address;
101 dst.insert(a)?;
102 Ok(address)
103 })
104 .collect()
105}