64 result.
tx = wtx.GetTx();
66 for (
const auto& txin : result.
tx->vin) {
72 for (
const auto& txout : result.
tx->vout) {
83 result.
time = wtx.GetTxTime();
84 result.
from = wtx.m_from;
100 wtx.state<TxStateConfirmed>() ? wtx.state<TxStateConfirmed>()->confirmed_block_height :
101 wtx.state<TxStateBlockConflicted>() ? wtx.state<TxStateBlockConflicted>()->conflicting_block_height :
102 std::numeric_limits<int>::max();
106 result.
lock_time = wtx.GetTx()->nLockTime;
116 const CWalletTx& wtx,
121 result.
txout = wtx.GetTx()->vout[n];
122 result.
time = wtx.GetTxTime();
132 result.
txout = output.txout;
133 result.
time = output.time;
139class WalletImpl :
public Wallet
144 bool encryptWallet(
const SecureString& wallet_passphrase)
override
146 return m_wallet->EncryptWallet(wallet_passphrase);
148 bool isCrypted()
override {
return m_wallet->HasEncryptionKeys(); }
149 bool lock()
override {
return m_wallet->Lock(); }
151 bool isLocked()
override {
return m_wallet->IsLocked(); }
155 return m_wallet->ChangeWalletPassphrase(old_wallet_passphrase, new_wallet_passphrase);
157 void abortRescan()
override {
m_wallet->Scanner().Abort(); }
158 bool backupWallet(
const std::string& filename)
override {
return m_wallet->BackupWallet(filename); }
159 std::string getWalletName()
override {
return m_wallet->GetName(); }
163 return m_wallet->GetNewDestination(type, label);
169 return provider->GetPubKey(address, pub_key);
178 SigningResult signMessage(
const std::string& message,
const PKHash& pkhash, std::string& str_sig)
override
180 return m_wallet->SignMessage(message, pkhash, str_sig);
187 bool setAddressBook(
const CTxDestination& dest,
const std::string&
name,
const std::optional<AddressPurpose>& purpose)
override
193 return m_wallet->DelAddressBook(dest);
200 const auto& entry =
m_wallet->FindAddressBookEntry(dest,
false);
201 if (!entry)
return false;
203 *
name = entry->GetLabel();
211 std::vector<WalletAddress> getAddresses()
override
214 std::vector<WalletAddress> result;
216 if (is_change) return;
217 bool is_mine = m_wallet->IsMine(dest);
219 result.emplace_back(dest, is_mine, purpose.value_or(is_mine ? AddressPurpose::RECEIVE : AddressPurpose::SEND), label);
223 std::vector<std::string> getAddressReceiveRequests()
override {
225 return m_wallet->GetAddressReceiveRequests();
227 bool setAddressReceiveRequest(
const CTxDestination& dest,
const std::string&
id,
const std::string& value)
override {
241 WalletBatch batch{
m_wallet->GetDatabase()};
242 return value.empty() ?
m_wallet->EraseAddressReceiveRequest(batch, dest,
id)
243 :
m_wallet->SetAddressReceiveRequest(batch, dest,
id, value);
248 return m_wallet->DisplayAddress(dest);
250 bool lockCoin(
const COutPoint& output,
const bool write_to_db)
override
253 return m_wallet->LockCoin(output, write_to_db);
255 bool unlockCoin(
const COutPoint& output)
override
258 return m_wallet->UnlockCoin(output);
260 bool isLockedCoin(
const COutPoint& output)
override
263 return m_wallet->IsLockedCoin(output);
265 void listLockedCoins(std::vector<COutPoint>& outputs)
override
268 return m_wallet->ListLockedCoins(outputs);
271 const CCoinControl& coin_control,
273 std::optional<unsigned int> change_pos)
override
281 m_wallet->CommitTransaction(std::move(tx), std::nullopt, std::nullopt, std::nullopt,
messages);
283 bool transactionCanBeAbandoned(
const Txid& txid)
override {
return m_wallet->TransactionCanBeAbandoned(txid); }
284 bool abandonTransaction(
const Txid& txid)
override
287 return m_wallet->AbandonTransaction(txid);
289 bool transactionCanBeBumped(
const Txid& txid)
override
293 bool createBumpTransaction(
const Txid& txid,
294 const CCoinControl& coin_control,
295 std::vector<bilingual_str>& errors,
300 std::vector<CTxOut> outputs;
304 bool commitBumpTransaction(
const Txid& txid,
306 std::vector<bilingual_str>& errors,
307 Txid& bumped_txid)
override
315 auto mi =
m_wallet->mapWallet.find(txid);
316 if (mi !=
m_wallet->mapWallet.end()) {
317 return mi->second.GetTx();
324 auto mi =
m_wallet->mapWallet.find(txid);
325 if (mi !=
m_wallet->mapWallet.end()) {
326 return MakeWalletTx(*
m_wallet, mi->second);
330 std::set<WalletTx> getWalletTxs()
override
333 std::set<WalletTx> result;
334 for (
const auto& entry :
m_wallet->mapWallet) {
335 result.emplace(MakeWalletTx(*
m_wallet, entry.second));
339 bool tryGetTxStatus(
const Txid& txid,
342 int64_t& block_time)
override
345 if (!locked_wallet) {
348 auto mi =
m_wallet->mapWallet.find(txid);
349 if (mi ==
m_wallet->mapWallet.end()) {
352 num_blocks =
m_wallet->GetLastBlockHeight();
355 tx_status = MakeWalletTxStatus(*
m_wallet, mi->second);
361 std::vector<std::string>& payment_requests,
363 int& num_blocks)
override
366 auto mi =
m_wallet->mapWallet.find(txid);
367 if (mi !=
m_wallet->mapWallet.end()) {
368 num_blocks =
m_wallet->GetLastBlockHeight();
369 in_mempool = mi->second.InMempool();
371 payment_requests = mi->second.m_payment_requests;
372 tx_status = MakeWalletTxStatus(*
m_wallet, mi->second);
373 return MakeWalletTx(*
m_wallet, mi->second);
380 bool& complete)
override
382 return m_wallet->FillPSBT(psbtx, options, complete, n_signed);
384 std::vector<wallet::ImportResult> importDescriptors(std::vector<wallet::ImportDescriptorRequest>& requests)
override
392 result.
balance = bal.m_mine_trusted;
402 if (!locked_wallet) {
405 block_hash =
m_wallet->GetLastBlockHash();
406 balances = getBalances();
410 CAmount getAvailableBalance(
const CCoinControl& coin_control)
override
415 if (coin_control.HasSelected()) {
417 CoinSelectionParams params(
rng);
420 total_amount += res->GetTotalAmount();
425 if (coin_control.m_allow_other_inputs) {
431 bool txinIsMine(
const CTxIn& txin)
override
436 bool txoutIsMine(
const CTxOut& txout)
override
451 CoinsList listCoins()
override
456 auto&
group = result[entry.first];
457 for (
const auto& coin : entry.second) {
458 group.emplace_back(coin.outpoint,
464 std::vector<WalletTxOut> getCoins(
const std::vector<COutPoint>& outputs)
override
467 std::vector<WalletTxOut> result;
468 result.reserve(outputs.size());
469 for (
const auto& output : outputs) {
470 result.emplace_back();
472 if (it !=
m_wallet->mapWallet.end()) {
473 int depth =
m_wallet->GetTxDepthInMainChain(it->second);
475 result.back() = MakeWalletTxOut(*
m_wallet, it->second, output.
n, depth);
482 CAmount getMinimumFee(
unsigned int tx_bytes,
483 const CCoinControl& coin_control,
484 std::optional<int>* returned_target,
489 if (returned_target) *returned_target = min_fee_rate.returned_target;
490 if (reason) *reason = min_fee_rate.fee_reason;
493 unsigned int getConfirmTarget()
override {
return m_wallet->m_confirm_target; }
494 bool hdEnabled()
override {
return m_wallet->IsHDEnabled(); }
495 bool canGetAddresses()
override {
return m_wallet->CanGetAddresses(); }
498 bool taprootEnabled()
override {
500 return spk_man !=
nullptr;
502 OutputType getDefaultAddressType()
override {
return m_wallet->m_default_address_type; }
504 void remove()
override
508 std::unique_ptr<Handler> handleUnload(UnloadFn fn)
override
512 std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn)
override
516 std::unique_ptr<Handler> handleStatusChanged(StatusChangedFn fn)
override
520 std::unique_ptr<Handler> handleAddressBookChanged(AddressBookChangedFn fn)
override
523 [fn](
const CTxDestination& address,
const std::string& label,
bool is_mine,
526 std::unique_ptr<Handler> handleTransactionChanged(TransactionChangedFn fn)
override
529 [fn](
const Txid& txid,
ChangeType status) { fn(txid, status); }));
531 std::unique_ptr<Handler> handleCanGetAddressesChanged(CanGetAddressesChangedFn fn)
override
555 ~WalletLoaderImpl()
override {
stop(); }
558 void registerRpcs()
override
562 JSONRPCRequest wallet_request = request;
563 wallet_request.context = &m_context;
564 return command.actor(wallet_request, result, last_handler);
578 void setMockTime(int64_t time)
override {
return SetMockTime(std::chrono::seconds{time}); }
579 void schedulerMockForward(std::chrono::seconds delta)
override {
Assert(
m_context.scheduler)->MockForward(delta); }
584 DatabaseOptions options;
587 options.require_create =
true;
588 options.create_flags = wallet_creation_flags;
589 options.create_passphrase = passphrase;
600 DatabaseOptions options;
603 options.require_existing =
true;
612 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)
override
617 if (!error.
empty()) {
628 .watchonly_wallet_name = res->watchonly_wallet_name,
629 .solvables_wallet_name = res->solvables_wallet_name,
630 .backup_path = res->backup_path,
634 bool isEncrypted(
const std::string& wallet_name)
override
637 auto it = std::find_if(wallets.begin(), wallets.end(), [&](std::shared_ptr<CWallet> w){ return w->GetName() == wallet_name; });
638 if (it != wallets.end())
return (*it)->HasEncryptionKeys();
641 DatabaseOptions options;
642 options.require_existing =
true;
650 if (!
db)
return false;
651 return WalletBatch(*db).IsEncrypted();
653 std::string getWalletDir()
override
657 std::vector<std::pair<std::string, std::string>> listWalletDir()
override
659 std::vector<std::pair<std::string, std::string>> paths;
661 paths.emplace_back(fs::PathToString(path),
format);
665 std::vector<std::unique_ptr<Wallet>> getWallets()
override
667 std::vector<std::unique_ptr<Wallet>> wallets;
673 std::unique_ptr<Handler> handleLoadWallet(
LoadWalletFn fn)
override
692 return std::make_unique<wallet::WalletLoaderImpl>(chain,
args);
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
int64_t CAmount
Amount in satoshis (Can be negative)
#define CHECK_NONFATAL(condition)
Identity function.
#define Assert(val)
Identity function.
A reference to a CKey: the Hash160 of its serialized public key.
An outpoint - a combination of a transaction hash and an index n into its vout.
An encapsulated public key.
Simple class for background tasks that should be run periodically or once "after a while".
Serialized script, used inside transaction inputs and outputs.
An input of a transaction.
An output of a transaction.
A version of CTransaction with the PSBT format.
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
Helper for findBlock to selectively return pieces of block data.
Generic interface for managing an event handler or callback function registered with another interfac...
Interface for accessing a wallet.
Wallet chain client that in addition to having chain client methods for starting up,...
The util::Expected class provides a standard way for low-level functions to return either error value...
static std::string PathToString(const path &path)
Convert path object to a byte string.
static int sign(const secp256k1_context *ctx, struct signer_secrets *signer_secrets, struct signer *signer, const secp256k1_musig_keyagg_cache *cache, const unsigned char *msg32, unsigned char *sig64)
std::unique_ptr< WalletLoader > MakeWalletLoader(Chain &chain, ArgsManager &args)
Return implementation of ChainClient interface for a wallet loader.
std::unique_ptr< Handler > MakeSignalHandler(btcsignals::connection connection)
Return handler wrapping a btcsignals connection.
std::unique_ptr< Wallet > MakeWallet(wallet::WalletContext &context, const std::shared_ptr< wallet::CWallet > &wallet)
Return implementation of Wallet interface.
bilingual_str ErrorString(const Result< T > &result)
Result CreateRateBumpTransaction(CWallet &wallet, const Txid &txid, const CCoinControl &coin_control, std::vector< bilingual_str > &errors, CAmount &old_fee, CAmount &new_fee, CMutableTransaction &mtx, bool require_mine, const std::vector< CTxOut > &outputs, std::optional< uint32_t > original_change_index)
Create bumpfee transaction based on feerate estimates.
bool TransactionCanBeBumped(const CWallet &wallet, const Txid &txid)
Return whether transaction can be bumped.
bool SignTransaction(CWallet &wallet, CMutableTransaction &mtx)
Sign the new transaction,.
Result CommitTransaction(CWallet &wallet, const Txid &txid, CMutableTransaction &&mtx, std::vector< bilingual_str > &errors, Txid &bumped_txid)
Commit the bumpfee transaction.
void StartWallets(WalletContext &context)
Complete startup of wallets.
bool OutputIsChange(const CWallet &wallet, const CTxOut &txout)
void ReadDatabaseArgs(const ArgsManager &args, DatabaseOptions &options)
std::shared_ptr< CWallet > LoadWallet(WalletContext &context, const std::string &name, std::optional< bool > load_on_start, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
util::Result< CreatedTransactionResult > CreateTransaction(CWallet &wallet, const std::vector< CRecipient > &vecSend, std::optional< unsigned int > change_pos, const CCoinControl &coin_control, bool sign)
Create a new transaction paying the recipients with a set of coins selected by SelectCoins(); Also cr...
std::vector< std::shared_ptr< CWallet > > GetWallets(WalletContext &context)
util::Result< MigrationResult > MigrateLegacyToDescriptor(const std::string &wallet_name, const SecureString &passphrase, WalletContext &context, bool load_wallet)
Do all steps to migrate a legacy wallet to a descriptor wallet.
util::Result< CoinsResult > FetchSelectedInputs(const CWallet &wallet, const CCoinControl &coin_control, const CoinSelectionParams &coin_selection_params)
Fetch and validate coin control selected inputs.
bool CachedTxIsTrusted(const CWallet &wallet, const CWalletTx &wtx, std::set< Txid > &trusted_parents)
MinimumFeeRateResult GetMinimumFeeRate(const CWallet &wallet, const CCoinControl &coin_control)
Estimate the minimum fee rate considering user set parameters and the required fee.
std::vector< ImportResult > ProcessDescriptorsImport(CWallet &wallet, std::vector< ImportDescriptorRequest > &requests)
CAmount GetMinimumFee(const MinimumFeeRateResult &min_fee_rate, unsigned int nTxBytes)
Return the minimum fee for this size given a fee rate result.
bool VerifyWallets(WalletContext &context)
Responsible for reading and validating the -wallet arguments and verifying the wallet database.
std::unique_ptr< interfaces::Handler > HandleLoadWallet(WalletContext &context, LoadWalletFn load_wallet)
fs::path GetWalletDir()
Get the path of the wallet directory.
std::unique_ptr< WalletDatabase > MakeWalletDatabase(const std::string &name, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error_string)
std::map< CTxDestination, std::vector< COutput > > ListCoins(const CWallet &wallet)
Return list of available coins and locked coins grouped by non-change output address.
CAmount CachedTxGetDebit(const CWallet &wallet, const CWalletTx &wtx, bool avoid_reuse)
std::shared_ptr< CWallet > RestoreWallet(WalletContext &context, const fs::path &backup_file, const std::string &wallet_name, std::optional< bool > load_on_start, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings, bool load_after_restore, bool allow_unnamed)
CAmount CachedTxGetChange(const CWallet &wallet, const CWalletTx &wtx)
CAmount CachedTxGetCredit(const CWallet &wallet, const CWalletTx &wtx, bool avoid_reuse)
AddressPurpose
Address purpose field that has been been stored with wallet sending and receiving addresses since BIP...
util::Result< std::string > ExportWatchOnlyWallet(const CWallet &wallet, const fs::path &destination, WalletContext &context)
Make a new watchonly wallet file containing the public descriptors from this wallet The exported watc...
Balance GetBalance(const CWallet &wallet, const int min_depth, bool avoid_reuse, bool include_nonmempool)
void UnloadWallets(WalletContext &context)
std::shared_ptr< CWallet > CreateWallet(WalletContext &context, const std::string &name, std::optional< bool > load_on_start, DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
bool LoadWallets(WalletContext &context)
Load wallet databases.
@ WALLET_FLAG_EXTERNAL_SIGNER
Indicates that the wallet needs an external signer.
@ WALLET_FLAG_DISABLE_PRIVATE_KEYS
CAmount GetRequiredFee(const CWallet &wallet, unsigned int nTxBytes)
Return the minimum required absolute fee for this size based on the required fee rate.
std::span< const CRPCCommand > GetWalletRPCCommands()
bool InputIsMine(const CWallet &wallet, const CTxIn &txin)
CTxDestination getNewDestination(CWallet &w, OutputType output_type)
Returns a new destination, of an specific type, from the wallet.
CAmount OutputGetCredit(const CWallet &wallet, const CTxOut &txout)
std::vector< std::pair< fs::path, std::string > > ListDatabases(const fs::path &wallet_dir)
Recursively list database paths in directory.
bool RemoveWallet(WalletContext &context, const std::shared_ptr< CWallet > &wallet, std::optional< bool > load_on_start, std::vector< bilingual_str > &warnings)
CoinsResult AvailableCoins(const CWallet &wallet, const CCoinControl *coinControl, std::optional< CFeeRate > feerate, const CoinFilterParams ¶ms)
Populate the CoinsResult struct with vectors of available COutputs, organized by OutputType.
is a home for public enum and struct type definitions that are used internally by node code,...
std::shared_ptr< const CTransaction > CTransactionRef
static bool verify(const CScriptNum10 &bignum, const CScriptNum &scriptnum)
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
A mutable version of CTransaction.
Instructions for how a PSBT should be signed or filled with information.
Information about one wallet address.
Collection of wallet balances.
CAmount nonmempool_balance
CAmount unconfirmed_balance
std::vector< bool > txin_is_mine
std::optional< std::string > comment
std::vector< CTxDestination > txout_address
std::vector< bool > txout_address_is_mine
std::optional< std::string > comment_to
std::vector< bool > txout_is_change
std::vector< bool > txout_is_mine
std::optional< std::string > message
std::optional< std::string > from
Wallet transaction output.
Updated transaction status.
unsigned int time_received
CAmount m_mine_trusted
Trusted, at depth=GetBalance.min_depth or more.
CAmount GetTotalAmount() const
WalletContext struct containing references to state shared between CWallet instances,...
#define TRY_LOCK(cs, name)
FuzzedDataProvider provider
#define EXCLUSIVE_LOCKS_REQUIRED(...)
ChangeType
General change type (added, updated, removed).
void SetMockTime(std::chrono::time_point< NodeClock, std::chrono::seconds > mock)
std::list< CRPCCommand > m_rpc_commands
std::shared_ptr< CWallet > m_wallet
std::vector< std::unique_ptr< Handler > > m_rpc_handlers
const std::vector< std::string > m_wallet_filenames
std::function< void(std::unique_ptr< interfaces::Wallet > wallet)> LoadWalletFn
std::shared_ptr< CWallet > wallet