/root/bitcoin/src/interfaces/wallet.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2018-2022 The Bitcoin Core developers |
2 | | // Distributed under the MIT software license, see the accompanying |
3 | | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
4 | | |
5 | | #ifndef BITCOIN_INTERFACES_WALLET_H |
6 | | #define BITCOIN_INTERFACES_WALLET_H |
7 | | |
8 | | #include <addresstype.h> |
9 | | #include <common/signmessage.h> |
10 | | #include <consensus/amount.h> |
11 | | #include <interfaces/chain.h> |
12 | | #include <pubkey.h> |
13 | | #include <script/script.h> |
14 | | #include <support/allocators/secure.h> |
15 | | #include <util/fs.h> |
16 | | #include <util/result.h> |
17 | | #include <util/ui_change_type.h> |
18 | | |
19 | | #include <cstdint> |
20 | | #include <functional> |
21 | | #include <map> |
22 | | #include <memory> |
23 | | #include <string> |
24 | | #include <tuple> |
25 | | #include <type_traits> |
26 | | #include <utility> |
27 | | #include <vector> |
28 | | |
29 | | class CFeeRate; |
30 | | class CKey; |
31 | | enum class FeeReason; |
32 | | enum class OutputType; |
33 | | struct PartiallySignedTransaction; |
34 | | struct bilingual_str; |
35 | | namespace common { |
36 | | enum class PSBTError; |
37 | | } // namespace common |
38 | | namespace node { |
39 | | enum class TransactionError; |
40 | | } // namespace node |
41 | | namespace wallet { |
42 | | class CCoinControl; |
43 | | class CWallet; |
44 | | enum class AddressPurpose; |
45 | | enum isminetype : unsigned int; |
46 | | struct CRecipient; |
47 | | struct WalletContext; |
48 | | using isminefilter = std::underlying_type<isminetype>::type; |
49 | | } // namespace wallet |
50 | | |
51 | | namespace interfaces { |
52 | | |
53 | | class Handler; |
54 | | struct WalletAddress; |
55 | | struct WalletBalances; |
56 | | struct WalletTx; |
57 | | struct WalletTxOut; |
58 | | struct WalletTxStatus; |
59 | | struct WalletMigrationResult; |
60 | | |
61 | | using WalletOrderForm = std::vector<std::pair<std::string, std::string>>; |
62 | | using WalletValueMap = std::map<std::string, std::string>; |
63 | | |
64 | | //! Interface for accessing a wallet. |
65 | | class Wallet |
66 | | { |
67 | | public: |
68 | 0 | virtual ~Wallet() = default; |
69 | | |
70 | | //! Encrypt wallet. |
71 | | virtual bool encryptWallet(const SecureString& wallet_passphrase) = 0; |
72 | | |
73 | | //! Return whether wallet is encrypted. |
74 | | virtual bool isCrypted() = 0; |
75 | | |
76 | | //! Lock wallet. |
77 | | virtual bool lock() = 0; |
78 | | |
79 | | //! Unlock wallet. |
80 | | virtual bool unlock(const SecureString& wallet_passphrase) = 0; |
81 | | |
82 | | //! Return whether wallet is locked. |
83 | | virtual bool isLocked() = 0; |
84 | | |
85 | | //! Change wallet passphrase. |
86 | | virtual bool changeWalletPassphrase(const SecureString& old_wallet_passphrase, |
87 | | const SecureString& new_wallet_passphrase) = 0; |
88 | | |
89 | | //! Abort a rescan. |
90 | | virtual void abortRescan() = 0; |
91 | | |
92 | | //! Back up wallet. |
93 | | virtual bool backupWallet(const std::string& filename) = 0; |
94 | | |
95 | | //! Get wallet name. |
96 | | virtual std::string getWalletName() = 0; |
97 | | |
98 | | // Get a new address. |
99 | | virtual util::Result<CTxDestination> getNewDestination(const OutputType type, const std::string& label) = 0; |
100 | | |
101 | | //! Get public key. |
102 | | virtual bool getPubKey(const CScript& script, const CKeyID& address, CPubKey& pub_key) = 0; |
103 | | |
104 | | //! Sign message |
105 | | virtual SigningResult signMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) = 0; |
106 | | |
107 | | //! Return whether wallet has private key. |
108 | | virtual bool isSpendable(const CTxDestination& dest) = 0; |
109 | | |
110 | | //! Return whether wallet has watch only keys. |
111 | | virtual bool haveWatchOnly() = 0; |
112 | | |
113 | | //! Add or update address. |
114 | | virtual bool setAddressBook(const CTxDestination& dest, const std::string& name, const std::optional<wallet::AddressPurpose>& purpose) = 0; |
115 | | |
116 | | // Remove address. |
117 | | virtual bool delAddressBook(const CTxDestination& dest) = 0; |
118 | | |
119 | | //! Look up address in wallet, return whether exists. |
120 | | virtual bool getAddress(const CTxDestination& dest, |
121 | | std::string* name, |
122 | | wallet::isminetype* is_mine, |
123 | | wallet::AddressPurpose* purpose) = 0; |
124 | | |
125 | | //! Get wallet address list. |
126 | | virtual std::vector<WalletAddress> getAddresses() = 0; |
127 | | |
128 | | //! Get receive requests. |
129 | | virtual std::vector<std::string> getAddressReceiveRequests() = 0; |
130 | | |
131 | | //! Save or remove receive request. |
132 | | virtual bool setAddressReceiveRequest(const CTxDestination& dest, const std::string& id, const std::string& value) = 0; |
133 | | |
134 | | //! Display address on external signer |
135 | | virtual util::Result<void> displayAddress(const CTxDestination& dest) = 0; |
136 | | |
137 | | //! Lock coin. |
138 | | virtual bool lockCoin(const COutPoint& output, const bool write_to_db) = 0; |
139 | | |
140 | | //! Unlock coin. |
141 | | virtual bool unlockCoin(const COutPoint& output) = 0; |
142 | | |
143 | | //! Return whether coin is locked. |
144 | | virtual bool isLockedCoin(const COutPoint& output) = 0; |
145 | | |
146 | | //! List locked coins. |
147 | | virtual void listLockedCoins(std::vector<COutPoint>& outputs) = 0; |
148 | | |
149 | | //! Create transaction. |
150 | | virtual util::Result<CTransactionRef> createTransaction(const std::vector<wallet::CRecipient>& recipients, |
151 | | const wallet::CCoinControl& coin_control, |
152 | | bool sign, |
153 | | int& change_pos, |
154 | | CAmount& fee) = 0; |
155 | | |
156 | | //! Commit transaction. |
157 | | virtual void commitTransaction(CTransactionRef tx, |
158 | | WalletValueMap value_map, |
159 | | WalletOrderForm order_form) = 0; |
160 | | |
161 | | //! Return whether transaction can be abandoned. |
162 | | virtual bool transactionCanBeAbandoned(const uint256& txid) = 0; |
163 | | |
164 | | //! Abandon transaction. |
165 | | virtual bool abandonTransaction(const uint256& txid) = 0; |
166 | | |
167 | | //! Return whether transaction can be bumped. |
168 | | virtual bool transactionCanBeBumped(const uint256& txid) = 0; |
169 | | |
170 | | //! Create bump transaction. |
171 | | virtual bool createBumpTransaction(const uint256& txid, |
172 | | const wallet::CCoinControl& coin_control, |
173 | | std::vector<bilingual_str>& errors, |
174 | | CAmount& old_fee, |
175 | | CAmount& new_fee, |
176 | | CMutableTransaction& mtx) = 0; |
177 | | |
178 | | //! Sign bump transaction. |
179 | | virtual bool signBumpTransaction(CMutableTransaction& mtx) = 0; |
180 | | |
181 | | //! Commit bump transaction. |
182 | | virtual bool commitBumpTransaction(const uint256& txid, |
183 | | CMutableTransaction&& mtx, |
184 | | std::vector<bilingual_str>& errors, |
185 | | uint256& bumped_txid) = 0; |
186 | | |
187 | | //! Get a transaction. |
188 | | virtual CTransactionRef getTx(const uint256& txid) = 0; |
189 | | |
190 | | //! Get transaction information. |
191 | | virtual WalletTx getWalletTx(const uint256& txid) = 0; |
192 | | |
193 | | //! Get list of all wallet transactions. |
194 | | virtual std::set<WalletTx> getWalletTxs() = 0; |
195 | | |
196 | | //! Try to get updated status for a particular transaction, if possible without blocking. |
197 | | virtual bool tryGetTxStatus(const uint256& txid, |
198 | | WalletTxStatus& tx_status, |
199 | | int& num_blocks, |
200 | | int64_t& block_time) = 0; |
201 | | |
202 | | //! Get transaction details. |
203 | | virtual WalletTx getWalletTxDetails(const uint256& txid, |
204 | | WalletTxStatus& tx_status, |
205 | | WalletOrderForm& order_form, |
206 | | bool& in_mempool, |
207 | | int& num_blocks) = 0; |
208 | | |
209 | | //! Fill PSBT. |
210 | | virtual std::optional<common::PSBTError> fillPSBT(int sighash_type, |
211 | | bool sign, |
212 | | bool bip32derivs, |
213 | | size_t* n_signed, |
214 | | PartiallySignedTransaction& psbtx, |
215 | | bool& complete) = 0; |
216 | | |
217 | | //! Get balances. |
218 | | virtual WalletBalances getBalances() = 0; |
219 | | |
220 | | //! Get balances if possible without blocking. |
221 | | virtual bool tryGetBalances(WalletBalances& balances, uint256& block_hash) = 0; |
222 | | |
223 | | //! Get balance. |
224 | | virtual CAmount getBalance() = 0; |
225 | | |
226 | | //! Get available balance. |
227 | | virtual CAmount getAvailableBalance(const wallet::CCoinControl& coin_control) = 0; |
228 | | |
229 | | //! Return whether transaction input belongs to wallet. |
230 | | virtual wallet::isminetype txinIsMine(const CTxIn& txin) = 0; |
231 | | |
232 | | //! Return whether transaction output belongs to wallet. |
233 | | virtual wallet::isminetype txoutIsMine(const CTxOut& txout) = 0; |
234 | | |
235 | | //! Return debit amount if transaction input belongs to wallet. |
236 | | virtual CAmount getDebit(const CTxIn& txin, wallet::isminefilter filter) = 0; |
237 | | |
238 | | //! Return credit amount if transaction input belongs to wallet. |
239 | | virtual CAmount getCredit(const CTxOut& txout, wallet::isminefilter filter) = 0; |
240 | | |
241 | | //! Return AvailableCoins + LockedCoins grouped by wallet address. |
242 | | //! (put change in one group with wallet address) |
243 | | using CoinsList = std::map<CTxDestination, std::vector<std::tuple<COutPoint, WalletTxOut>>>; |
244 | | virtual CoinsList listCoins() = 0; |
245 | | |
246 | | //! Return wallet transaction output information. |
247 | | virtual std::vector<WalletTxOut> getCoins(const std::vector<COutPoint>& outputs) = 0; |
248 | | |
249 | | //! Get required fee. |
250 | | virtual CAmount getRequiredFee(unsigned int tx_bytes) = 0; |
251 | | |
252 | | //! Get minimum fee. |
253 | | virtual CAmount getMinimumFee(unsigned int tx_bytes, |
254 | | const wallet::CCoinControl& coin_control, |
255 | | int* returned_target, |
256 | | FeeReason* reason) = 0; |
257 | | |
258 | | //! Get tx confirm target. |
259 | | virtual unsigned int getConfirmTarget() = 0; |
260 | | |
261 | | // Return whether HD enabled. |
262 | | virtual bool hdEnabled() = 0; |
263 | | |
264 | | // Return whether the wallet is blank. |
265 | | virtual bool canGetAddresses() = 0; |
266 | | |
267 | | // Return whether private keys enabled. |
268 | | virtual bool privateKeysDisabled() = 0; |
269 | | |
270 | | // Return whether the wallet contains a Taproot scriptPubKeyMan |
271 | | virtual bool taprootEnabled() = 0; |
272 | | |
273 | | // Return whether wallet uses an external signer. |
274 | | virtual bool hasExternalSigner() = 0; |
275 | | |
276 | | // Get default address type. |
277 | | virtual OutputType getDefaultAddressType() = 0; |
278 | | |
279 | | //! Get max tx fee. |
280 | | virtual CAmount getDefaultMaxTxFee() = 0; |
281 | | |
282 | | // Remove wallet. |
283 | | virtual void remove() = 0; |
284 | | |
285 | | //! Return whether is a legacy wallet |
286 | | virtual bool isLegacy() = 0; |
287 | | |
288 | | //! Register handler for unload message. |
289 | | using UnloadFn = std::function<void()>; |
290 | | virtual std::unique_ptr<Handler> handleUnload(UnloadFn fn) = 0; |
291 | | |
292 | | //! Register handler for show progress messages. |
293 | | using ShowProgressFn = std::function<void(const std::string& title, int progress)>; |
294 | | virtual std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) = 0; |
295 | | |
296 | | //! Register handler for status changed messages. |
297 | | using StatusChangedFn = std::function<void()>; |
298 | | virtual std::unique_ptr<Handler> handleStatusChanged(StatusChangedFn fn) = 0; |
299 | | |
300 | | //! Register handler for address book changed messages. |
301 | | using AddressBookChangedFn = std::function<void(const CTxDestination& address, |
302 | | const std::string& label, |
303 | | bool is_mine, |
304 | | wallet::AddressPurpose purpose, |
305 | | ChangeType status)>; |
306 | | virtual std::unique_ptr<Handler> handleAddressBookChanged(AddressBookChangedFn fn) = 0; |
307 | | |
308 | | //! Register handler for transaction changed messages. |
309 | | using TransactionChangedFn = std::function<void(const uint256& txid, ChangeType status)>; |
310 | | virtual std::unique_ptr<Handler> handleTransactionChanged(TransactionChangedFn fn) = 0; |
311 | | |
312 | | //! Register handler for watchonly changed messages. |
313 | | using WatchOnlyChangedFn = std::function<void(bool have_watch_only)>; |
314 | | virtual std::unique_ptr<Handler> handleWatchOnlyChanged(WatchOnlyChangedFn fn) = 0; |
315 | | |
316 | | //! Register handler for keypool changed messages. |
317 | | using CanGetAddressesChangedFn = std::function<void()>; |
318 | | virtual std::unique_ptr<Handler> handleCanGetAddressesChanged(CanGetAddressesChangedFn fn) = 0; |
319 | | |
320 | | //! Return pointer to internal wallet class, useful for testing. |
321 | 0 | virtual wallet::CWallet* wallet() { return nullptr; } |
322 | | }; |
323 | | |
324 | | //! Wallet chain client that in addition to having chain client methods for |
325 | | //! starting up, shutting down, and registering RPCs, also has additional |
326 | | //! methods (called by the GUI) to load and create wallets. |
327 | | class WalletLoader : public ChainClient |
328 | | { |
329 | | public: |
330 | | //! Create new wallet. |
331 | | virtual util::Result<std::unique_ptr<Wallet>> createWallet(const std::string& name, const SecureString& passphrase, uint64_t wallet_creation_flags, std::vector<bilingual_str>& warnings) = 0; |
332 | | |
333 | | //! Load existing wallet. |
334 | | virtual util::Result<std::unique_ptr<Wallet>> loadWallet(const std::string& name, std::vector<bilingual_str>& warnings) = 0; |
335 | | |
336 | | //! Return default wallet directory. |
337 | | virtual std::string getWalletDir() = 0; |
338 | | |
339 | | //! Restore backup wallet |
340 | | virtual util::Result<std::unique_ptr<Wallet>> restoreWallet(const fs::path& backup_file, const std::string& wallet_name, std::vector<bilingual_str>& warnings) = 0; |
341 | | |
342 | | //! Migrate a wallet |
343 | | virtual util::Result<WalletMigrationResult> migrateWallet(const std::string& name, const SecureString& passphrase) = 0; |
344 | | |
345 | | //! Returns true if wallet stores encryption keys |
346 | | virtual bool isEncrypted(const std::string& wallet_name) = 0; |
347 | | |
348 | | //! Return available wallets in wallet directory. |
349 | | virtual std::vector<std::pair<std::string, std::string>> listWalletDir() = 0; |
350 | | |
351 | | //! Return interfaces for accessing wallets (if any). |
352 | | virtual std::vector<std::unique_ptr<Wallet>> getWallets() = 0; |
353 | | |
354 | | //! Register handler for load wallet messages. This callback is triggered by |
355 | | //! createWallet and loadWallet above, and also triggered when wallets are |
356 | | //! loaded at startup or by RPC. |
357 | | using LoadWalletFn = std::function<void(std::unique_ptr<Wallet> wallet)>; |
358 | | virtual std::unique_ptr<Handler> handleLoadWallet(LoadWalletFn fn) = 0; |
359 | | |
360 | | //! Return pointer to internal context, useful for testing. |
361 | 0 | virtual wallet::WalletContext* context() { return nullptr; } |
362 | | }; |
363 | | |
364 | | //! Information about one wallet address. |
365 | | struct WalletAddress |
366 | | { |
367 | | CTxDestination dest; |
368 | | wallet::isminetype is_mine; |
369 | | wallet::AddressPurpose purpose; |
370 | | std::string name; |
371 | | |
372 | | WalletAddress(CTxDestination dest, wallet::isminetype is_mine, wallet::AddressPurpose purpose, std::string name) |
373 | 0 | : dest(std::move(dest)), is_mine(is_mine), purpose(std::move(purpose)), name(std::move(name)) |
374 | 0 | { |
375 | 0 | } |
376 | | }; |
377 | | |
378 | | //! Collection of wallet balances. |
379 | | struct WalletBalances |
380 | | { |
381 | | CAmount balance = 0; |
382 | | CAmount unconfirmed_balance = 0; |
383 | | CAmount immature_balance = 0; |
384 | | bool have_watch_only = false; |
385 | | CAmount watch_only_balance = 0; |
386 | | CAmount unconfirmed_watch_only_balance = 0; |
387 | | CAmount immature_watch_only_balance = 0; |
388 | | |
389 | | bool balanceChanged(const WalletBalances& prev) const |
390 | 0 | { |
391 | 0 | return balance != prev.balance || unconfirmed_balance != prev.unconfirmed_balance || |
392 | 0 | immature_balance != prev.immature_balance || watch_only_balance != prev.watch_only_balance || |
393 | 0 | unconfirmed_watch_only_balance != prev.unconfirmed_watch_only_balance || |
394 | 0 | immature_watch_only_balance != prev.immature_watch_only_balance; |
395 | 0 | } |
396 | | }; |
397 | | |
398 | | // Wallet transaction information. |
399 | | struct WalletTx |
400 | | { |
401 | | CTransactionRef tx; |
402 | | std::vector<wallet::isminetype> txin_is_mine; |
403 | | std::vector<wallet::isminetype> txout_is_mine; |
404 | | std::vector<bool> txout_is_change; |
405 | | std::vector<CTxDestination> txout_address; |
406 | | std::vector<wallet::isminetype> txout_address_is_mine; |
407 | | CAmount credit; |
408 | | CAmount debit; |
409 | | CAmount change; |
410 | | int64_t time; |
411 | | std::map<std::string, std::string> value_map; |
412 | | bool is_coinbase; |
413 | | |
414 | 0 | bool operator<(const WalletTx& a) const { return tx->GetHash() < a.tx->GetHash(); } |
415 | | }; |
416 | | |
417 | | //! Updated transaction status. |
418 | | struct WalletTxStatus |
419 | | { |
420 | | int block_height; |
421 | | int blocks_to_maturity; |
422 | | int depth_in_main_chain; |
423 | | unsigned int time_received; |
424 | | uint32_t lock_time; |
425 | | bool is_trusted; |
426 | | bool is_abandoned; |
427 | | bool is_coinbase; |
428 | | bool is_in_main_chain; |
429 | | }; |
430 | | |
431 | | //! Wallet transaction output. |
432 | | struct WalletTxOut |
433 | | { |
434 | | CTxOut txout; |
435 | | int64_t time; |
436 | | int depth_in_main_chain = -1; |
437 | | bool is_spent = false; |
438 | | }; |
439 | | |
440 | | //! Migrated wallet info |
441 | | struct WalletMigrationResult |
442 | | { |
443 | | std::unique_ptr<Wallet> wallet; |
444 | | std::optional<std::string> watchonly_wallet_name; |
445 | | std::optional<std::string> solvables_wallet_name; |
446 | | fs::path backup_path; |
447 | | }; |
448 | | |
449 | | //! Return implementation of Wallet interface. This function is defined in |
450 | | //! dummywallet.cpp and throws if the wallet component is not compiled. |
451 | | std::unique_ptr<Wallet> MakeWallet(wallet::WalletContext& context, const std::shared_ptr<wallet::CWallet>& wallet); |
452 | | |
453 | | //! Return implementation of ChainClient interface for a wallet loader. This |
454 | | //! function will be undefined in builds where ENABLE_WALLET is false. |
455 | | std::unique_ptr<WalletLoader> MakeWalletLoader(Chain& chain, ArgsManager& args); |
456 | | |
457 | | } // namespace interfaces |
458 | | |
459 | | #endif // BITCOIN_INTERFACES_WALLET_H |