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