Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
sysio::wallet::wallet_manager Class Reference

#include <wallet_manager.hpp>

Public Member Functions

 wallet_manager ()
 
 wallet_manager (const wallet_manager &)=delete
 
 wallet_manager (wallet_manager &&)=delete
 
wallet_manageroperator= (const wallet_manager &)=delete
 
wallet_manageroperator= (wallet_manager &&)=delete
 
 ~wallet_manager ()
 
void set_dir (const boost::filesystem::path &p)
 
void set_timeout (const std::chrono::seconds &t)
 
void set_timeout (int64_t secs)
 
chain::signed_transaction sign_transaction (const chain::signed_transaction &txn, const flat_set< public_key_type > &keys, const chain::chain_id_type &id)
 
chain::signature_type sign_digest (const chain::digest_type &digest, const public_key_type &key)
 
std::string create (const std::string &name)
 
void open (const std::string &name)
 
std::vector< std::string > list_wallets ()
 
map< public_key_type, private_key_typelist_keys (const string &name, const string &pw)
 
flat_set< public_key_typeget_public_keys ()
 
void lock_all ()
 Locks all the unlocked wallets.
 
void lock (const std::string &name)
 
void unlock (const std::string &name, const std::string &password)
 
void import_key (const std::string &name, const std::string &wif_key)
 
void remove_key (const std::string &name, const std::string &password, const std::string &key)
 
string create_key (const std::string &name, const std::string &key_type)
 
void own_and_use_wallet (const string &name, std::unique_ptr< wallet_api > &&wallet)
 Takes ownership of a wallet to use.
 

Detailed Description

Provides associate of wallet name to wallet and manages the interaction with each wallet.

The name of the wallet is also used as part of the file name by soft_wallet. See wallet_manager::create. No const methods because timeout may cause lock_all() to be called.

Definition at line 18 of file wallet_manager.hpp.

Constructor & Destructor Documentation

◆ wallet_manager() [1/3]

sysio::wallet::wallet_manager::wallet_manager ( )

Definition at line 25 of file wallet_manager.cpp.

25 {
26#ifdef __APPLE__
27 try {
28 wallets.emplace("SecureEnclave", std::make_unique<se_wallet>());
29 } catch(const std::exception& ) {}
30#endif
31}

◆ wallet_manager() [2/3]

sysio::wallet::wallet_manager::wallet_manager ( const wallet_manager & )
delete

◆ wallet_manager() [3/3]

sysio::wallet::wallet_manager::wallet_manager ( wallet_manager && )
delete

◆ ~wallet_manager()

sysio::wallet::wallet_manager::~wallet_manager ( )

Definition at line 33 of file wallet_manager.cpp.

33 {
34 //not really required, but may spook users
35 if(wallet_dir_lock)
36 boost::filesystem::remove(lock_path);
37}

Member Function Documentation

◆ create()

std::string sysio::wallet::wallet_manager::create ( const std::string & name)

Create a new wallet. A new wallet is created in file dir/{name}.wallet see set_dir. The new wallet is unlocked after creation.

Parameters
nameof the wallet and name of the file without ext .wallet.
Returns
Plaintext password that is needed to unlock wallet. Caller is responsible for saving password otherwise they will not be able to unlock their wallet. Note user supplied passwords are not supported.
Exceptions
fc::exceptionif wallet with name already exists (or filename already exists)

Definition at line 57 of file wallet_manager.cpp.

57 {
58 check_timeout();
59
60 SYS_ASSERT(valid_filename(name), wallet_exception, "Invalid filename, path not allowed in wallet name ${n}", ("n", name));
61
62 auto wallet_filename = dir / (name + file_ext);
63
64 if (fc::exists(wallet_filename)) {
65 SYS_THROW(chain::wallet_exist_exception, "Wallet with name: '${n}' already exists at ${path}", ("n", name)("path",fc::path(wallet_filename)));
66 }
67
68 std::string password = gen_password();
69 wallet_data d;
70 auto wallet = make_unique<soft_wallet>(d);
71 wallet->set_password(password);
72 wallet->set_wallet_filename(wallet_filename.string());
73 wallet->unlock(password);
74 wallet->lock();
75 wallet->unlock(password);
76
77 // Explicitly save the wallet file here, to ensure it now exists.
78 wallet->save_wallet_file();
79
80 // If we have name in our map then remove it since we want the emplace below to replace.
81 // This can happen if the wallet file is removed while eos-walletd is running.
82 auto it = wallets.find(name);
83 if (it != wallets.end()) {
84 wallets.erase(it);
85 }
86 wallets.emplace(name, std::move(wallet));
87
88 return password;
89}
const uint8_t password[]
Definition attest.c:39
#define SYS_THROW(exc_type, FORMAT,...)
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
Definition exceptions.hpp:7
wraps boost::filesystem::path to provide platform independent path manipulation.
bool exists(const path &p)
std::string gen_password()
bool valid_filename(const string &name)
constexpr auto file_ext
Immutable except for fc::from_variant.
Definition name.hpp:43
CK_ULONG d
Here is the call graph for this function:

◆ create_key()

string sysio::wallet::wallet_manager::create_key ( const std::string & name,
const std::string & key_type )

Creates a key within the specified wallet. Wallet must be opened and unlocked

Parameters
nameof the wallet to create key in
typeof key to create
Exceptions
fc::exceptionif wallet not found or locked, or if the wallet cannot create said type of key
Returns
The public key of the created key

Definition at line 213 of file wallet_manager.cpp.

213 {
214 check_timeout();
215 if (wallets.count(name) == 0) {
216 SYS_THROW(chain::wallet_nonexistent_exception, "Wallet not found: ${w}", ("w", name));
217 }
218 auto& w = wallets.at(name);
219 if (w->is_locked()) {
220 SYS_THROW(chain::wallet_locked_exception, "Wallet is locked: ${w}", ("w", name));
221 }
222
223 string upper_key_type = boost::to_upper_copy<std::string>(key_type);
224 return w->create_key(upper_key_type);
225}
struct @108 key_type

◆ get_public_keys()

flat_set< public_key_type > sysio::wallet::wallet_manager::get_public_keys ( )
Returns
A set of public keys from all unlocked wallets, use with chain_controller::get_required_keys.

Definition at line 138 of file wallet_manager.cpp.

138 {
139 check_timeout();
140 SYS_ASSERT(!wallets.empty(), wallet_not_available_exception, "You don't have any wallet!");
141 flat_set<public_key_type> result;
142 bool is_all_wallet_locked = true;
143 for (const auto& i : wallets) {
144 if (!i.second->is_locked()) {
145 result.merge(i.second->list_public_keys());
146 }
147 is_all_wallet_locked &= i.second->is_locked();
148 }
149 SYS_ASSERT(!is_all_wallet_locked, wallet_locked_exception, "You don't have any unlocked wallet!");
150 return result;
151}

◆ import_key()

void sysio::wallet::wallet_manager::import_key ( const std::string & name,
const std::string & wif_key )

Import private key into specified wallet. Imports a WIF Private Key into specified wallet. Wallet must be opened and unlocked.

Parameters
namethe name of the wallet to import into.
wif_keythe WIF Private Key to import, e.g. 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
Exceptions
fc::exceptionif wallet not found or locked.

Definition at line 188 of file wallet_manager.cpp.

188 {
189 check_timeout();
190 if (wallets.count(name) == 0) {
191 SYS_THROW(chain::wallet_nonexistent_exception, "Wallet not found: ${w}", ("w", name));
192 }
193 auto& w = wallets.at(name);
194 if (w->is_locked()) {
195 SYS_THROW(chain::wallet_locked_exception, "Wallet is locked: ${w}", ("w", name));
196 }
197 w->import_key(wif_key);
198}

◆ list_keys()

map< public_key_type, private_key_type > sysio::wallet::wallet_manager::list_keys ( const string & name,
const string & pw )
Returns
A list of private keys from a wallet provided password is correct to said wallet

Definition at line 126 of file wallet_manager.cpp.

126 {
127 check_timeout();
128
129 if (wallets.count(name) == 0)
130 SYS_THROW(chain::wallet_nonexistent_exception, "Wallet not found: ${w}", ("w", name));
131 auto& w = wallets.at(name);
132 if (w->is_locked())
133 SYS_THROW(chain::wallet_locked_exception, "Wallet is locked: ${w}", ("w", name));
134 w->check_password(pw); //throws if bad password
135 return w->list_keys();
136}

◆ list_wallets()

std::vector< std::string > sysio::wallet::wallet_manager::list_wallets ( )
Returns
A list of wallet names with " *" appended if the wallet is unlocked.

Definition at line 113 of file wallet_manager.cpp.

113 {
114 check_timeout();
115 std::vector<std::string> result;
116 for (const auto& i : wallets) {
117 if (i.second->is_locked()) {
118 result.emplace_back(i.first);
119 } else {
120 result.emplace_back(i.first + " *");
121 }
122 }
123 return result;
124}

◆ lock()

void sysio::wallet::wallet_manager::lock ( const std::string & name)

Lock the specified wallet. No-op if wallet already locked.

Parameters
namethe name of the wallet to lock.
Exceptions
fc::exceptionif wallet with name not found.

Definition at line 163 of file wallet_manager.cpp.

163 {
164 check_timeout();
165 if (wallets.count(name) == 0) {
166 SYS_THROW(chain::wallet_nonexistent_exception, "Wallet not found: ${w}", ("w", name));
167 }
168 auto& w = wallets.at(name);
169 if (w->is_locked()) {
170 return;
171 }
172 w->lock();
173}

◆ lock_all()

void sysio::wallet::wallet_manager::lock_all ( )

Definition at line 154 of file wallet_manager.cpp.

154 {
155 // no call to check_timeout since we are locking all anyway
156 for (auto& i : wallets) {
157 if (!i.second->is_locked()) {
158 i.second->lock();
159 }
160 }
161}

◆ open()

void sysio::wallet::wallet_manager::open ( const std::string & name)

Open an existing wallet file dir/{name}.wallet. Note this does not unlock the wallet, see wallet_manager::unlock.

Parameters
nameof the wallet file (minus ext .wallet) to open.
Exceptions
fc::exceptionif unable to find/open the wallet file.

Definition at line 91 of file wallet_manager.cpp.

91 {
92 check_timeout();
93
94 SYS_ASSERT(valid_filename(name), wallet_exception, "Invalid filename, path not allowed in wallet name ${n}", ("n", name));
95
96 wallet_data d;
97 auto wallet = std::make_unique<soft_wallet>(d);
98 auto wallet_filename = dir / (name + file_ext);
99 wallet->set_wallet_filename(wallet_filename.string());
100 if (!wallet->load_wallet_file()) {
101 SYS_THROW(chain::wallet_nonexistent_exception, "Unable to open file: ${f}", ("f", wallet_filename.string()));
102 }
103
104 // If we have name in our map then remove it since we want the emplace below to replace.
105 // This can happen if the wallet file is added while eos-walletd is running.
106 auto it = wallets.find(name);
107 if (it != wallets.end()) {
108 wallets.erase(it);
109 }
110 wallets.emplace(name, std::move(wallet));
111}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ operator=() [1/2]

wallet_manager & sysio::wallet::wallet_manager::operator= ( const wallet_manager & )
delete

◆ operator=() [2/2]

wallet_manager & sysio::wallet::wallet_manager::operator= ( wallet_manager && )
delete

◆ own_and_use_wallet()

void sysio::wallet::wallet_manager::own_and_use_wallet ( const string & name,
std::unique_ptr< wallet_api > && wallet )

Definition at line 269 of file wallet_manager.cpp.

269 {
270 if(wallets.find(name) != wallets.end())
271 SYS_THROW(wallet_exception, "Tried to use wallet name that already exists.");
272 wallets.emplace(name, std::move(wallet));
273}

◆ remove_key()

void sysio::wallet::wallet_manager::remove_key ( const std::string & name,
const std::string & password,
const std::string & key )

Removes a key from the specified wallet. Wallet must be opened and unlocked.

Parameters
namethe name of the wallet to remove the key from.
passwordthe plaintext password returned from create.
keythe Public Key to remove, e.g. SYS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
Exceptions
fc::exceptionif wallet not found or locked or key is not removed.

Definition at line 200 of file wallet_manager.cpp.

200 {
201 check_timeout();
202 if (wallets.count(name) == 0) {
203 SYS_THROW(chain::wallet_nonexistent_exception, "Wallet not found: ${w}", ("w", name));
204 }
205 auto& w = wallets.at(name);
206 if (w->is_locked()) {
207 SYS_THROW(chain::wallet_locked_exception, "Wallet is locked: ${w}", ("w", name));
208 }
209 w->check_password(password); //throws if bad password
210 w->remove_key(key);
211}

◆ set_dir()

void sysio::wallet::wallet_manager::set_dir ( const boost::filesystem::path & p)
inline

Set the path for location of wallet files.

Parameters
ppath to override default ./ location of wallet files.

Definition at line 29 of file wallet_manager.hpp.

29 {
30 dir = p;
31 initialize_lock();
32 }
const mie::Vuint & p
Definition bn.cpp:27

◆ set_timeout() [1/2]

void sysio::wallet::wallet_manager::set_timeout ( const std::chrono::seconds & t)

Set the timeout for locking all wallets. If set then after t seconds of inactivity then lock_all(). Activity is defined as any wallet_manager method call below.

Definition at line 39 of file wallet_manager.cpp.

39 {
40 timeout = t;
41 auto now = std::chrono::system_clock::now();
42 timeout_time = now + timeout;
43 SYS_ASSERT(timeout_time >= now && timeout_time.time_since_epoch().count() > 0, invalid_lock_timeout_exception, "Overflow on timeout_time, specified ${t}, now ${now}, timeout_time ${timeout_time}",
44 ("t", t.count())("now", now.time_since_epoch().count())("timeout_time", timeout_time.time_since_epoch().count()));
45}

◆ set_timeout() [2/2]

void sysio::wallet::wallet_manager::set_timeout ( int64_t secs)
inline
See also
wallet_manager::set_timeout(const std::chrono::seconds& t)
Parameters
secsThe timeout in seconds.

Definition at line 41 of file wallet_manager.hpp.

41{ set_timeout(std::chrono::seconds(secs)); }
void set_timeout(const std::chrono::seconds &t)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sign_digest()

chain::signature_type sysio::wallet::wallet_manager::sign_digest ( const chain::digest_type & digest,
const public_key_type & key )

Sign digest with the private keys specified via their public keys.

Parameters
digestthe digest to sign.
keythe public key of the corresponding private key to sign the digest with
Returns
signature over the digest
Exceptions
fc::exceptionif corresponding private keys not found in unlocked wallets

Definition at line 253 of file wallet_manager.cpp.

253 {
254 check_timeout();
255
256 try {
257 for (const auto& i : wallets) {
258 if (!i.second->is_locked()) {
259 std::optional<signature_type> sig = i.second->try_sign_digest(digest, key);
260 if (sig)
261 return *sig;
262 }
263 }
265
266 SYS_THROW(chain::wallet_missing_pub_key_exception, "Public key not found in unlocked wallets ${k}", ("k", key));
267}
#define FC_LOG_AND_RETHROW()
fc::sha256 digest(const T &value)
Definition digest.hpp:9
Here is the call graph for this function:

◆ sign_transaction()

chain::signed_transaction sysio::wallet::wallet_manager::sign_transaction ( const chain::signed_transaction & txn,
const flat_set< public_key_type > & keys,
const chain::chain_id_type & id )

Sign transaction with the private keys specified via their public keys. Use chain_controller::get_required_keys to determine which keys are needed for txn.

Parameters
txnthe transaction to sign.
keysthe public keys of the corresponding private keys to sign the transaction with
idthe chain_id to sign transaction with.
Returns
txn signed
Exceptions
fc::exceptionif corresponding private keys not found in unlocked wallets

Definition at line 228 of file wallet_manager.cpp.

228 {
229 check_timeout();
230 chain::signed_transaction stxn(txn);
231
232 for (const auto& pk : keys) {
233 bool found = false;
234 for (const auto& i : wallets) {
235 if (!i.second->is_locked()) {
236 std::optional<signature_type> sig = i.second->try_sign_digest(stxn.sig_digest(id, stxn.context_free_data), pk);
237 if (sig) {
238 stxn.signatures.push_back(*sig);
239 found = true;
240 break; // inner for
241 }
242 }
243 }
244 if (!found) {
245 SYS_THROW(chain::wallet_missing_pub_key_exception, "Public key not found in unlocked wallets ${k}", ("k", pk));
246 }
247 }
248
249 return stxn;
250}
Here is the call graph for this function:

◆ unlock()

void sysio::wallet::wallet_manager::unlock ( const std::string & name,
const std::string & password )

Unlock the specified wallet. The wallet remains unlocked until lock is called or program exit.

Parameters
namethe name of the wallet to lock.
passwordthe plaintext password returned from create.
Exceptions
fc::exceptionif wallet not found or invalid password or already unlocked.

Definition at line 175 of file wallet_manager.cpp.

175 {
176 check_timeout();
177 if (wallets.count(name) == 0) {
178 open( name );
179 }
180 auto& w = wallets.at(name);
181 if (!w->is_locked()) {
182 SYS_THROW(chain::wallet_unlocked_exception, "Wallet is already unlocked: ${w}", ("w", name));
183 return;
184 }
185 w->unlock(password);
186}
void open(const std::string &name)
Here is the call graph for this function:

The documentation for this class was generated from the following files: