wallet.h raw

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