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