/ src / wallet / rpc / spend.cpp
spend.cpp
   1  // Copyright (c) 2011-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  #include <common/messages.h>
   6  #include <consensus/validation.h>
   7  #include <core_io.h>
   8  #include <key_io.h>
   9  #include <node/types.h>
  10  #include <policy/policy.h>
  11  #include <policy/truc_policy.h>
  12  #include <rpc/rawtransaction_util.h>
  13  #include <rpc/util.h>
  14  #include <script/script.h>
  15  #include <util/rbf.h>
  16  #include <util/translation.h>
  17  #include <util/vector.h>
  18  #include <wallet/coincontrol.h>
  19  #include <wallet/feebumper.h>
  20  #include <wallet/fees.h>
  21  #include <wallet/rpc/util.h>
  22  #include <wallet/spend.h>
  23  #include <wallet/wallet.h>
  24  
  25  #include <univalue.h>
  26  
  27  using common::FeeModeFromString;
  28  using common::FeeModesDetail;
  29  using common::InvalidEstimateModeErrorMessage;
  30  using common::StringForFeeReason;
  31  using common::TransactionErrorString;
  32  using node::TransactionError;
  33  
  34  namespace wallet {
  35  std::vector<CRecipient> CreateRecipients(const std::vector<std::pair<CTxDestination, CAmount>>& outputs, const std::set<int>& subtract_fee_outputs)
  36  {
  37      std::vector<CRecipient> recipients;
  38      for (size_t i = 0; i < outputs.size(); ++i) {
  39          const auto& [destination, amount] = outputs.at(i);
  40          CRecipient recipient{destination, amount, subtract_fee_outputs.contains(i)};
  41          recipients.push_back(recipient);
  42      }
  43      return recipients;
  44  }
  45  
  46  static void InterpretFeeEstimationInstructions(const UniValue& conf_target, const UniValue& estimate_mode, const UniValue& fee_rate, UniValue& options)
  47  {
  48      if (options.exists("conf_target") || options.exists("estimate_mode")) {
  49          if (!conf_target.isNull() || !estimate_mode.isNull()) {
  50              throw JSONRPCError(RPC_INVALID_PARAMETER, "Pass conf_target and estimate_mode either as arguments or in the options object, but not both");
  51          }
  52      } else {
  53          options.pushKV("conf_target", conf_target);
  54          options.pushKV("estimate_mode", estimate_mode);
  55      }
  56      if (options.exists("fee_rate")) {
  57          if (!fee_rate.isNull()) {
  58              throw JSONRPCError(RPC_INVALID_PARAMETER, "Pass the fee_rate either as an argument, or in the options object, but not both");
  59          }
  60      } else {
  61          options.pushKV("fee_rate", fee_rate);
  62      }
  63      if (!options["conf_target"].isNull() && (options["estimate_mode"].isNull() || (options["estimate_mode"].get_str() == "unset"))) {
  64          throw JSONRPCError(RPC_INVALID_PARAMETER, "Specify estimate_mode");
  65      }
  66  }
  67  
  68  std::set<int> InterpretSubtractFeeFromOutputInstructions(const UniValue& sffo_instructions, const std::vector<std::string>& destinations)
  69  {
  70      std::set<int> sffo_set;
  71      if (sffo_instructions.isNull()) return sffo_set;
  72  
  73      for (const auto& sffo : sffo_instructions.getValues()) {
  74          int pos{-1};
  75          if (sffo.isStr()) {
  76              auto it = find(destinations.begin(), destinations.end(), sffo.get_str());
  77              if (it == destinations.end()) throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter 'subtract fee from output', destination %s not found in tx outputs", sffo.get_str()));
  78              pos = it - destinations.begin();
  79          } else if (sffo.isNum()) {
  80              pos = sffo.getInt<int>();
  81          } else {
  82              throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter 'subtract fee from output', invalid value type: %s", uvTypeName(sffo.type())));
  83          }
  84  
  85          if (sffo_set.contains(pos))
  86              throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter 'subtract fee from output', duplicated position: %d", pos));
  87          if (pos < 0)
  88              throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter 'subtract fee from output', negative position: %d", pos));
  89          if (pos >= int(destinations.size()))
  90              throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter 'subtract fee from output', position too large: %d", pos));
  91          sffo_set.insert(pos);
  92      }
  93      return sffo_set;
  94  }
  95  
  96  static UniValue FinishTransaction(const std::shared_ptr<CWallet> pwallet, const UniValue& options, CMutableTransaction& rawTx)
  97  {
  98      bool can_anti_fee_snipe = !options.exists("locktime");
  99  
 100      for (const CTxIn& tx_in : rawTx.vin) {
 101          // Checks sequence values consistent with DiscourageFeeSniping
 102          can_anti_fee_snipe = can_anti_fee_snipe && (tx_in.nSequence == CTxIn::MAX_SEQUENCE_NONFINAL || tx_in.nSequence == MAX_BIP125_RBF_SEQUENCE);
 103      }
 104  
 105      if (can_anti_fee_snipe) {
 106          LOCK(pwallet->cs_wallet);
 107          FastRandomContext rng_fast;
 108          DiscourageFeeSniping(rawTx, rng_fast, pwallet->chain(), pwallet->GetLastBlockHash(), pwallet->GetLastBlockHeight());
 109      }
 110  
 111      // Make a blank psbt
 112      PartiallySignedTransaction psbtx(rawTx);
 113  
 114      // First fill transaction with our data without signing,
 115      // so external signers are not asked to sign more than once.
 116      bool complete;
 117      pwallet->FillPSBT(psbtx, complete, std::nullopt, /*sign=*/false, /*bip32derivs=*/true);
 118      const auto err{pwallet->FillPSBT(psbtx, complete, std::nullopt, /*sign=*/true, /*bip32derivs=*/false)};
 119      if (err) {
 120          throw JSONRPCPSBTError(*err);
 121      }
 122  
 123      CMutableTransaction mtx;
 124      complete = FinalizeAndExtractPSBT(psbtx, mtx);
 125  
 126      UniValue result(UniValue::VOBJ);
 127  
 128      const bool psbt_opt_in{options.exists("psbt") && options["psbt"].get_bool()};
 129      bool add_to_wallet{options.exists("add_to_wallet") ? options["add_to_wallet"].get_bool() : true};
 130      if (psbt_opt_in || !complete || !add_to_wallet) {
 131          // Serialize the PSBT
 132          DataStream ssTx{};
 133          ssTx << psbtx;
 134          result.pushKV("psbt", EncodeBase64(ssTx.str()));
 135      }
 136  
 137      if (complete) {
 138          std::string hex{EncodeHexTx(CTransaction(mtx))};
 139          CTransactionRef tx(MakeTransactionRef(std::move(mtx)));
 140          result.pushKV("txid", tx->GetHash().GetHex());
 141          if (add_to_wallet && !psbt_opt_in) {
 142              pwallet->CommitTransaction(tx, {}, /*orderForm=*/{});
 143          } else {
 144              result.pushKV("hex", hex);
 145          }
 146      }
 147      result.pushKV("complete", complete);
 148  
 149      return result;
 150  }
 151  
 152  static void PreventOutdatedOptions(const UniValue& options)
 153  {
 154      if (options.exists("feeRate")) {
 155          throw JSONRPCError(RPC_INVALID_PARAMETER, "Use fee_rate (" + CURRENCY_ATOM + "/vB) instead of feeRate");
 156      }
 157      if (options.exists("changeAddress")) {
 158          throw JSONRPCError(RPC_INVALID_PARAMETER, "Use change_address instead of changeAddress");
 159      }
 160      if (options.exists("changePosition")) {
 161          throw JSONRPCError(RPC_INVALID_PARAMETER, "Use change_position instead of changePosition");
 162      }
 163      if (options.exists("lockUnspents")) {
 164          throw JSONRPCError(RPC_INVALID_PARAMETER, "Use lock_unspents instead of lockUnspents");
 165      }
 166      if (options.exists("subtractFeeFromOutputs")) {
 167          throw JSONRPCError(RPC_INVALID_PARAMETER, "Use subtract_fee_from_outputs instead of subtractFeeFromOutputs");
 168      }
 169  }
 170  
 171  UniValue SendMoney(CWallet& wallet, const CCoinControl &coin_control, std::vector<CRecipient> &recipients, mapValue_t map_value, bool verbose)
 172  {
 173      EnsureWalletIsUnlocked(wallet);
 174  
 175      // This function is only used by sendtoaddress and sendmany.
 176      // This should always try to sign, if we don't have private keys, don't try to do anything here.
 177      if (wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
 178          throw JSONRPCError(RPC_WALLET_ERROR, "Error: Private keys are disabled for this wallet");
 179      }
 180  
 181      // Shuffle recipient list
 182      std::shuffle(recipients.begin(), recipients.end(), FastRandomContext());
 183  
 184      // Send
 185      auto res = CreateTransaction(wallet, recipients, /*change_pos=*/std::nullopt, coin_control, true);
 186      if (!res) {
 187          throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, util::ErrorString(res).original);
 188      }
 189      const CTransactionRef& tx = res->tx;
 190      wallet.CommitTransaction(tx, std::move(map_value), /*orderForm=*/{});
 191      if (verbose) {
 192          UniValue entry(UniValue::VOBJ);
 193          entry.pushKV("txid", tx->GetHash().GetHex());
 194          entry.pushKV("fee_reason", StringForFeeReason(res->fee_calc.reason));
 195          return entry;
 196      }
 197      return tx->GetHash().GetHex();
 198  }
 199  
 200  
 201  /**
 202   * Update coin control with fee estimation based on the given parameters
 203   *
 204   * @param[in]     wallet            Wallet reference
 205   * @param[in,out] cc                Coin control to be updated
 206   * @param[in]     conf_target       UniValue integer; confirmation target in blocks, values between 1 and 1008 are valid per policy/fees/block_policy_estimator.h;
 207   * @param[in]     estimate_mode     UniValue string; fee estimation mode, valid values are "unset", "economical" or "conservative";
 208   * @param[in]     fee_rate          UniValue real; fee rate in sat/vB;
 209   *                                      if present, both conf_target and estimate_mode must either be null, or "unset"
 210   * @param[in]     override_min_fee  bool; whether to set fOverrideFeeRate to true to disable minimum fee rate checks and instead
 211   *                                      verify only that fee_rate is greater than 0
 212   * @throws a JSONRPCError if conf_target, estimate_mode, or fee_rate contain invalid values or are in conflict
 213   */
 214  static void SetFeeEstimateMode(const CWallet& wallet, CCoinControl& cc, const UniValue& conf_target, const UniValue& estimate_mode, const UniValue& fee_rate, bool override_min_fee)
 215  {
 216      if (!fee_rate.isNull()) {
 217          if (!conf_target.isNull()) {
 218              throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both conf_target and fee_rate. Please provide either a confirmation target in blocks for automatic fee estimation, or an explicit fee rate.");
 219          }
 220          if (!estimate_mode.isNull() && estimate_mode.get_str() != "unset") {
 221              throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both estimate_mode and fee_rate");
 222          }
 223          // Fee rates in sat/vB cannot represent more than 3 significant digits.
 224          cc.m_feerate = CFeeRate{AmountFromValue(fee_rate, /*decimals=*/3)};
 225          if (override_min_fee) cc.fOverrideFeeRate = true;
 226          // Default RBF to true for explicit fee_rate, if unset.
 227          if (!cc.m_signal_bip125_rbf) cc.m_signal_bip125_rbf = true;
 228          return;
 229      }
 230      if (!estimate_mode.isNull() && !FeeModeFromString(estimate_mode.get_str(), cc.m_fee_mode)) {
 231          throw JSONRPCError(RPC_INVALID_PARAMETER, InvalidEstimateModeErrorMessage());
 232      }
 233      if (!conf_target.isNull()) {
 234          cc.m_confirm_target = ParseConfirmTarget(conf_target, wallet.chain().estimateMaxBlocks());
 235      }
 236  }
 237  
 238  RPCHelpMan sendtoaddress()
 239  {
 240      return RPCHelpMan{
 241          "sendtoaddress",
 242          "Send an amount to a given address." +
 243          HELP_REQUIRING_PASSPHRASE,
 244                  {
 245                      {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to send to."},
 246                      {"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "The amount in " + CURRENCY_UNIT + " to send. eg 0.1"},
 247                      {"comment", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "A comment used to store what the transaction is for.\n"
 248                                           "This is not part of the transaction, just kept in your wallet."},
 249                      {"comment_to", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "A comment to store the name of the person or organization\n"
 250                                           "to which you're sending the transaction. This is not part of the \n"
 251                                           "transaction, just kept in your wallet."},
 252                      {"subtractfeefromamount", RPCArg::Type::BOOL, RPCArg::Default{false}, "The fee will be deducted from the amount being sent.\n"
 253                                           "The recipient will receive less bitcoins than you enter in the amount field."},
 254                      {"replaceable", RPCArg::Type::BOOL, RPCArg::DefaultHint{"wallet default"}, "Signal that this transaction can be replaced by a transaction (BIP 125)"},
 255                      {"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks"},
 256                      {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n"
 257                        + FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used"))},
 258                      {"avoid_reuse", RPCArg::Type::BOOL, RPCArg::Default{true}, "(only available if avoid_reuse wallet flag is set) Avoid spending from dirty addresses; addresses are considered\n"
 259                                           "dirty if they have previously been used in a transaction. If true, this also activates avoidpartialspends, grouping outputs by their addresses."},
 260                      {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."},
 261                      {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false}, "If true, return extra information about the transaction."},
 262                  },
 263                  {
 264                      RPCResult{"if verbose is not set or set to false",
 265                          RPCResult::Type::STR_HEX, "txid", "The transaction id."
 266                      },
 267                      RPCResult{"if verbose is set to true",
 268                          RPCResult::Type::OBJ, "", "",
 269                          {
 270                              {RPCResult::Type::STR_HEX, "txid", "The transaction id."},
 271                              {RPCResult::Type::STR, "fee_reason", "The transaction fee reason."}
 272                          },
 273                      },
 274                  },
 275                  RPCExamples{
 276                      "\nSend 0.1 BTC\n"
 277                      + HelpExampleCli("sendtoaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 0.1") +
 278                      "\nSend 0.1 BTC with a confirmation target of 6 blocks in economical fee estimate mode using positional arguments\n"
 279                      + HelpExampleCli("sendtoaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 0.1 \"donation\" \"sean's outpost\" false true 6 economical") +
 280                      "\nSend 0.1 BTC with a fee rate of 1.1 " + CURRENCY_ATOM + "/vB, subtract fee from amount, BIP125-replaceable, using positional arguments\n"
 281                      + HelpExampleCli("sendtoaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 0.1 \"drinks\" \"room77\" true true null \"unset\" null 1.1") +
 282                      "\nSend 0.2 BTC with a confirmation target of 6 blocks in economical fee estimate mode using named arguments\n"
 283                      + HelpExampleCli("-named sendtoaddress", "address=\"" + EXAMPLE_ADDRESS[0] + "\" amount=0.2 conf_target=6 estimate_mode=\"economical\"") +
 284                      "\nSend 0.5 BTC with a fee rate of 25 " + CURRENCY_ATOM + "/vB using named arguments\n"
 285                      + HelpExampleCli("-named sendtoaddress", "address=\"" + EXAMPLE_ADDRESS[0] + "\" amount=0.5 fee_rate=25")
 286                      + HelpExampleCli("-named sendtoaddress", "address=\"" + EXAMPLE_ADDRESS[0] + "\" amount=0.5 fee_rate=25 subtractfeefromamount=false replaceable=true avoid_reuse=true comment=\"2 pizzas\" comment_to=\"jeremy\" verbose=true")
 287                  },
 288          [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
 289  {
 290      std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
 291      if (!pwallet) return UniValue::VNULL;
 292  
 293      // Make sure the results are valid at least up to the most recent block
 294      // the user could have gotten from another RPC command prior to now
 295      pwallet->BlockUntilSyncedToCurrentChain();
 296  
 297      LOCK(pwallet->cs_wallet);
 298  
 299      // Wallet comments
 300      mapValue_t mapValue;
 301      if (!request.params[2].isNull() && !request.params[2].get_str().empty())
 302          mapValue["comment"] = request.params[2].get_str();
 303      if (!request.params[3].isNull() && !request.params[3].get_str().empty())
 304          mapValue["to"] = request.params[3].get_str();
 305  
 306      CCoinControl coin_control;
 307      if (!request.params[5].isNull()) {
 308          coin_control.m_signal_bip125_rbf = request.params[5].get_bool();
 309      }
 310  
 311      coin_control.m_avoid_address_reuse = GetAvoidReuseFlag(*pwallet, request.params[8]);
 312      // We also enable partial spend avoidance if reuse avoidance is set.
 313      coin_control.m_avoid_partial_spends |= coin_control.m_avoid_address_reuse;
 314  
 315      SetFeeEstimateMode(*pwallet, coin_control, /*conf_target=*/request.params[6], /*estimate_mode=*/request.params[7], /*fee_rate=*/request.params[9], /*override_min_fee=*/false);
 316  
 317      EnsureWalletIsUnlocked(*pwallet);
 318  
 319      UniValue address_amounts(UniValue::VOBJ);
 320      const std::string address = request.params[0].get_str();
 321      address_amounts.pushKV(address, request.params[1]);
 322  
 323      std::set<int> sffo_set;
 324      if (!request.params[4].isNull() && request.params[4].get_bool()) {
 325          sffo_set.insert(0);
 326      }
 327  
 328      std::vector<CRecipient> recipients{CreateRecipients(ParseOutputs(address_amounts), sffo_set)};
 329      const bool verbose{request.params[10].isNull() ? false : request.params[10].get_bool()};
 330  
 331      return SendMoney(*pwallet, coin_control, recipients, mapValue, verbose);
 332  },
 333      };
 334  }
 335  
 336  RPCHelpMan sendmany()
 337  {
 338      return RPCHelpMan{"sendmany",
 339          "Send multiple times. Amounts are double-precision floating point numbers." +
 340          HELP_REQUIRING_PASSPHRASE,
 341                  {
 342                      {"dummy", RPCArg::Type::STR, RPCArg::Default{"\"\""}, "Must be set to \"\" for backwards compatibility.",
 343                       RPCArgOptions{
 344                           .oneline_description = "\"\"",
 345                       }},
 346                      {"amounts", RPCArg::Type::OBJ_USER_KEYS, RPCArg::Optional::NO, "The addresses and amounts",
 347                          {
 348                              {"address", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "The bitcoin address is the key, the numeric amount (can be string) in " + CURRENCY_UNIT + " is the value"},
 349                          },
 350                      },
 351                      {"minconf", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "Ignored dummy value"},
 352                      {"comment", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "A comment"},
 353                      {"subtractfeefrom", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "The addresses.\n"
 354                                         "The fee will be equally deducted from the amount of each selected address.\n"
 355                                         "Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
 356                                         "If no addresses are specified here, the sender pays the fee.",
 357                          {
 358                              {"address", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Subtract fee from this address"},
 359                          },
 360                      },
 361                      {"replaceable", RPCArg::Type::BOOL, RPCArg::DefaultHint{"wallet default"}, "Signal that this transaction can be replaced by a transaction (BIP 125)"},
 362                      {"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks"},
 363                      {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n"
 364                        + FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used"))},
 365                      {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."},
 366                      {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false}, "If true, return extra information about the transaction."},
 367                  },
 368                  {
 369                      RPCResult{"if verbose is not set or set to false",
 370                          RPCResult::Type::STR_HEX, "txid", "The transaction id for the send. Only 1 transaction is created regardless of\n"
 371                  "the number of addresses."
 372                      },
 373                      RPCResult{"if verbose is set to true",
 374                          RPCResult::Type::OBJ, "", "",
 375                          {
 376                              {RPCResult::Type::STR_HEX, "txid", "The transaction id for the send. Only 1 transaction is created regardless of\n"
 377                  "the number of addresses."},
 378                              {RPCResult::Type::STR, "fee_reason", "The transaction fee reason."}
 379                          },
 380                      },
 381                  },
 382                  RPCExamples{
 383              "\nSend two amounts to two different addresses:\n"
 384              + HelpExampleCli("sendmany", "\"\" \"{\\\"" + EXAMPLE_ADDRESS[0] + "\\\":0.01,\\\"" + EXAMPLE_ADDRESS[1] + "\\\":0.02}\"") +
 385              "\nSend two amounts to two different addresses setting the confirmation and comment:\n"
 386              + HelpExampleCli("sendmany", "\"\" \"{\\\"" + EXAMPLE_ADDRESS[0] + "\\\":0.01,\\\"" + EXAMPLE_ADDRESS[1] + "\\\":0.02}\" 6 \"testing\"") +
 387              "\nSend two amounts to two different addresses, subtract fee from amount:\n"
 388              + HelpExampleCli("sendmany", "\"\" \"{\\\"" + EXAMPLE_ADDRESS[0] + "\\\":0.01,\\\"" + EXAMPLE_ADDRESS[1] + "\\\":0.02}\" 1 \"\" \"[\\\"" + EXAMPLE_ADDRESS[0] + "\\\",\\\"" + EXAMPLE_ADDRESS[1] + "\\\"]\"") +
 389              "\nAs a JSON-RPC call\n"
 390              + HelpExampleRpc("sendmany", "\"\", {\"" + EXAMPLE_ADDRESS[0] + "\":0.01,\"" + EXAMPLE_ADDRESS[1] + "\":0.02}, 6, \"testing\"")
 391                  },
 392          [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
 393  {
 394      std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
 395      if (!pwallet) return UniValue::VNULL;
 396  
 397      // Make sure the results are valid at least up to the most recent block
 398      // the user could have gotten from another RPC command prior to now
 399      pwallet->BlockUntilSyncedToCurrentChain();
 400  
 401      LOCK(pwallet->cs_wallet);
 402  
 403      if (!request.params[0].isNull() && !request.params[0].get_str().empty()) {
 404          throw JSONRPCError(RPC_INVALID_PARAMETER, "Dummy value must be set to \"\"");
 405      }
 406      UniValue sendTo = request.params[1].get_obj();
 407  
 408      mapValue_t mapValue;
 409      if (!request.params[3].isNull() && !request.params[3].get_str().empty())
 410          mapValue["comment"] = request.params[3].get_str();
 411  
 412      CCoinControl coin_control;
 413      if (!request.params[5].isNull()) {
 414          coin_control.m_signal_bip125_rbf = request.params[5].get_bool();
 415      }
 416  
 417      SetFeeEstimateMode(*pwallet, coin_control, /*conf_target=*/request.params[6], /*estimate_mode=*/request.params[7], /*fee_rate=*/request.params[8], /*override_min_fee=*/false);
 418  
 419      std::vector<CRecipient> recipients = CreateRecipients(
 420              ParseOutputs(sendTo),
 421              InterpretSubtractFeeFromOutputInstructions(request.params[4], sendTo.getKeys())
 422      );
 423      const bool verbose{request.params[9].isNull() ? false : request.params[9].get_bool()};
 424  
 425      return SendMoney(*pwallet, coin_control, recipients, std::move(mapValue), verbose);
 426  },
 427      };
 428  }
 429  
 430  RPCHelpMan settxfee()
 431  {
 432      return RPCHelpMan{
 433          "settxfee",
 434          "(DEPRECATED) Set the transaction fee rate in " + CURRENCY_UNIT + "/kvB for this wallet. Overrides the global -paytxfee command line parameter.\n"
 435                  "Can be deactivated by passing 0 as the fee. In that case automatic fee selection will be used by default.\n",
 436                  {
 437                      {"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "The transaction fee rate in " + CURRENCY_UNIT + "/kvB"},
 438                  },
 439                  RPCResult{
 440                      RPCResult::Type::BOOL, "", "Returns true if successful"
 441                  },
 442                  RPCExamples{
 443                      HelpExampleCli("settxfee", "0.00001")
 444              + HelpExampleRpc("settxfee", "0.00001")
 445                  },
 446          [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
 447  {
 448      std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
 449      if (!pwallet) return UniValue::VNULL;
 450  
 451      LOCK(pwallet->cs_wallet);
 452  
 453      if (!pwallet->chain().rpcEnableDeprecated("settxfee")) {
 454          throw JSONRPCError(RPC_METHOD_DEPRECATED, "settxfee is deprecated and will be fully removed in v31.0."
 455          "\nTo use settxfee restart bitcoind with -deprecatedrpc=settxfee.");
 456      }
 457  
 458      CAmount nAmount = AmountFromValue(request.params[0]);
 459      CFeeRate tx_fee_rate(nAmount, 1000);
 460      CFeeRate max_tx_fee_rate(pwallet->m_default_max_tx_fee, 1000);
 461      if (tx_fee_rate == CFeeRate(0)) {
 462          // automatic selection
 463      } else if (tx_fee_rate < pwallet->chain().relayMinFee()) {
 464          throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("txfee cannot be less than min relay tx fee (%s)", pwallet->chain().relayMinFee().ToString()));
 465      } else if (tx_fee_rate < pwallet->m_min_fee) {
 466          throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("txfee cannot be less than wallet min fee (%s)", pwallet->m_min_fee.ToString()));
 467      } else if (tx_fee_rate > max_tx_fee_rate) {
 468          throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("txfee cannot be more than wallet max tx fee (%s)", max_tx_fee_rate.ToString()));
 469      }
 470  
 471      pwallet->m_pay_tx_fee = tx_fee_rate;
 472      return true;
 473  },
 474      };
 475  }
 476  
 477  
 478  // Only includes key documentation where the key is snake_case in all RPC methods. MixedCase keys can be added later.
 479  static std::vector<RPCArg> FundTxDoc(bool solving_data = true)
 480  {
 481      std::vector<RPCArg> args = {
 482          {"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks", RPCArgOptions{.also_positional = true}},
 483          {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n"
 484            + FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used")), RPCArgOptions{.also_positional = true}},
 485          {
 486              "replaceable", RPCArg::Type::BOOL, RPCArg::DefaultHint{"wallet default"}, "Marks this transaction as BIP125-replaceable.\n"
 487              "Allows this transaction to be replaced by a transaction with higher fees"
 488          },
 489      };
 490      if (solving_data) {
 491          args.push_back({"solving_data", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "Keys and scripts needed for producing a final transaction with a dummy signature.\n"
 492          "Used for fee estimation during coin selection.",
 493              {
 494                  {
 495                      "pubkeys", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Public keys involved in this transaction.",
 496                      {
 497                          {"pubkey", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "A public key"},
 498                      }
 499                  },
 500                  {
 501                      "scripts", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Scripts involved in this transaction.",
 502                      {
 503                          {"script", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "A script"},
 504                      }
 505                  },
 506                  {
 507                      "descriptors", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Descriptors that provide solving data for this transaction.",
 508                      {
 509                          {"descriptor", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "A descriptor"},
 510                      }
 511                  },
 512              }
 513          });
 514      }
 515      return args;
 516  }
 517  
 518  CreatedTransactionResult FundTransaction(CWallet& wallet, const CMutableTransaction& tx, const std::vector<CRecipient>& recipients, const UniValue& options, CCoinControl& coinControl, bool override_min_fee)
 519  {
 520      // We want to make sure tx.vout is not used now that we are passing outputs as a vector of recipients.
 521      // This sets us up to remove tx completely in a future PR in favor of passing the inputs directly.
 522      CHECK_NONFATAL(tx.vout.empty());
 523      // Make sure the results are valid at least up to the most recent block
 524      // the user could have gotten from another RPC command prior to now
 525      wallet.BlockUntilSyncedToCurrentChain();
 526  
 527      std::optional<unsigned int> change_position;
 528      bool lockUnspents = false;
 529      if (!options.isNull()) {
 530          if (options.type() == UniValue::VBOOL) {
 531              // backward compatibility bool only fallback, does nothing
 532          } else {
 533              RPCTypeCheckObj(options,
 534                  {
 535                      {"add_inputs", UniValueType(UniValue::VBOOL)},
 536                      {"include_unsafe", UniValueType(UniValue::VBOOL)},
 537                      {"add_to_wallet", UniValueType(UniValue::VBOOL)},
 538                      {"changeAddress", UniValueType(UniValue::VSTR)},
 539                      {"change_address", UniValueType(UniValue::VSTR)},
 540                      {"changePosition", UniValueType(UniValue::VNUM)},
 541                      {"change_position", UniValueType(UniValue::VNUM)},
 542                      {"change_type", UniValueType(UniValue::VSTR)},
 543                      {"includeWatching", UniValueType(UniValue::VBOOL)},
 544                      {"include_watching", UniValueType(UniValue::VBOOL)},
 545                      {"inputs", UniValueType(UniValue::VARR)},
 546                      {"lockUnspents", UniValueType(UniValue::VBOOL)},
 547                      {"lock_unspents", UniValueType(UniValue::VBOOL)},
 548                      {"locktime", UniValueType(UniValue::VNUM)},
 549                      {"fee_rate", UniValueType()}, // will be checked by AmountFromValue() in SetFeeEstimateMode()
 550                      {"feeRate", UniValueType()}, // will be checked by AmountFromValue() below
 551                      {"psbt", UniValueType(UniValue::VBOOL)},
 552                      {"solving_data", UniValueType(UniValue::VOBJ)},
 553                      {"subtractFeeFromOutputs", UniValueType(UniValue::VARR)},
 554                      {"subtract_fee_from_outputs", UniValueType(UniValue::VARR)},
 555                      {"replaceable", UniValueType(UniValue::VBOOL)},
 556                      {"conf_target", UniValueType(UniValue::VNUM)},
 557                      {"estimate_mode", UniValueType(UniValue::VSTR)},
 558                      {"minconf", UniValueType(UniValue::VNUM)},
 559                      {"maxconf", UniValueType(UniValue::VNUM)},
 560                      {"input_weights", UniValueType(UniValue::VARR)},
 561                      {"max_tx_weight", UniValueType(UniValue::VNUM)},
 562                  },
 563                  true, true);
 564  
 565              if (options.exists("add_inputs")) {
 566                  coinControl.m_allow_other_inputs = options["add_inputs"].get_bool();
 567              }
 568  
 569              if (options.exists("changeAddress") || options.exists("change_address")) {
 570                  const std::string change_address_str = (options.exists("change_address") ? options["change_address"] : options["changeAddress"]).get_str();
 571                  CTxDestination dest = DecodeDestination(change_address_str);
 572  
 573                  if (!IsValidDestination(dest)) {
 574                      throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Change address must be a valid bitcoin address");
 575                  }
 576  
 577                  coinControl.destChange = dest;
 578              }
 579  
 580              if (options.exists("changePosition") || options.exists("change_position")) {
 581                  int pos = (options.exists("change_position") ? options["change_position"] : options["changePosition"]).getInt<int>();
 582                  if (pos < 0 || (unsigned int)pos > recipients.size()) {
 583                      throw JSONRPCError(RPC_INVALID_PARAMETER, "changePosition out of bounds");
 584                  }
 585                  change_position = (unsigned int)pos;
 586              }
 587  
 588              if (options.exists("change_type")) {
 589                  if (options.exists("changeAddress") || options.exists("change_address")) {
 590                      throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both change address and address type options");
 591                  }
 592                  if (std::optional<OutputType> parsed = ParseOutputType(options["change_type"].get_str())) {
 593                      coinControl.m_change_type.emplace(parsed.value());
 594                  } else {
 595                      throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown change type '%s'", options["change_type"].get_str()));
 596                  }
 597              }
 598  
 599              if (options.exists("lockUnspents") || options.exists("lock_unspents")) {
 600                  lockUnspents = (options.exists("lock_unspents") ? options["lock_unspents"] : options["lockUnspents"]).get_bool();
 601              }
 602  
 603              if (options.exists("include_unsafe")) {
 604                  coinControl.m_include_unsafe_inputs = options["include_unsafe"].get_bool();
 605              }
 606  
 607              if (options.exists("feeRate")) {
 608                  if (options.exists("fee_rate")) {
 609                      throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both fee_rate (" + CURRENCY_ATOM + "/vB) and feeRate (" + CURRENCY_UNIT + "/kvB)");
 610                  }
 611                  if (options.exists("conf_target")) {
 612                      throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both conf_target and feeRate. Please provide either a confirmation target in blocks for automatic fee estimation, or an explicit fee rate.");
 613                  }
 614                  if (options.exists("estimate_mode")) {
 615                      throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both estimate_mode and feeRate");
 616                  }
 617                  coinControl.m_feerate = CFeeRate(AmountFromValue(options["feeRate"]));
 618                  coinControl.fOverrideFeeRate = true;
 619              }
 620  
 621              if (options.exists("replaceable")) {
 622                  coinControl.m_signal_bip125_rbf = options["replaceable"].get_bool();
 623              }
 624  
 625              if (options.exists("minconf")) {
 626                  coinControl.m_min_depth = options["minconf"].getInt<int>();
 627  
 628                  if (coinControl.m_min_depth < 0) {
 629                      throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative minconf");
 630                  }
 631              }
 632  
 633              if (options.exists("maxconf")) {
 634                  coinControl.m_max_depth = options["maxconf"].getInt<int>();
 635  
 636                  if (coinControl.m_max_depth < coinControl.m_min_depth) {
 637                      throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("maxconf can't be lower than minconf: %d < %d", coinControl.m_max_depth, coinControl.m_min_depth));
 638                  }
 639              }
 640              SetFeeEstimateMode(wallet, coinControl, options["conf_target"], options["estimate_mode"], options["fee_rate"], override_min_fee);
 641          }
 642      }
 643  
 644      if (options.exists("solving_data")) {
 645          const UniValue solving_data = options["solving_data"].get_obj();
 646          if (solving_data.exists("pubkeys")) {
 647              for (const UniValue& pk_univ : solving_data["pubkeys"].get_array().getValues()) {
 648                  const CPubKey pubkey = HexToPubKey(pk_univ.get_str());
 649                  coinControl.m_external_provider.pubkeys.emplace(pubkey.GetID(), pubkey);
 650                  // Add witness script for pubkeys
 651                  const CScript wit_script = GetScriptForDestination(WitnessV0KeyHash(pubkey));
 652                  coinControl.m_external_provider.scripts.emplace(CScriptID(wit_script), wit_script);
 653              }
 654          }
 655  
 656          if (solving_data.exists("scripts")) {
 657              for (const UniValue& script_univ : solving_data["scripts"].get_array().getValues()) {
 658                  const std::string& script_str = script_univ.get_str();
 659                  if (!IsHex(script_str)) {
 660                      throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("'%s' is not hex", script_str));
 661                  }
 662                  std::vector<unsigned char> script_data(ParseHex(script_str));
 663                  const CScript script(script_data.begin(), script_data.end());
 664                  coinControl.m_external_provider.scripts.emplace(CScriptID(script), script);
 665              }
 666          }
 667  
 668          if (solving_data.exists("descriptors")) {
 669              for (const UniValue& desc_univ : solving_data["descriptors"].get_array().getValues()) {
 670                  const std::string& desc_str  = desc_univ.get_str();
 671                  FlatSigningProvider desc_out;
 672                  std::string error;
 673                  std::vector<CScript> scripts_temp;
 674                  auto descs = Parse(desc_str, desc_out, error, true);
 675                  if (descs.empty()) {
 676                      throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Unable to parse descriptor '%s': %s", desc_str, error));
 677                  }
 678                  for (auto& desc : descs) {
 679                      desc->Expand(0, desc_out, scripts_temp, desc_out);
 680                  }
 681                  coinControl.m_external_provider.Merge(std::move(desc_out));
 682              }
 683          }
 684      }
 685  
 686      if (options.exists("input_weights")) {
 687          for (const UniValue& input : options["input_weights"].get_array().getValues()) {
 688              Txid txid = Txid::FromUint256(ParseHashO(input, "txid"));
 689  
 690              const UniValue& vout_v = input.find_value("vout");
 691              if (!vout_v.isNum()) {
 692                  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");
 693              }
 694              int vout = vout_v.getInt<int>();
 695              if (vout < 0) {
 696                  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout cannot be negative");
 697              }
 698  
 699              const UniValue& weight_v = input.find_value("weight");
 700              if (!weight_v.isNum()) {
 701                  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing weight key");
 702              }
 703              int64_t weight = weight_v.getInt<int64_t>();
 704              const int64_t min_input_weight = GetTransactionInputWeight(CTxIn());
 705              CHECK_NONFATAL(min_input_weight == 165);
 706              if (weight < min_input_weight) {
 707                  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, weight cannot be less than 165 (41 bytes (size of outpoint + sequence + empty scriptSig) * 4 (witness scaling factor)) + 1 (empty witness)");
 708              }
 709              if (weight > MAX_STANDARD_TX_WEIGHT) {
 710                  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, weight cannot be greater than the maximum standard tx weight of %d", MAX_STANDARD_TX_WEIGHT));
 711              }
 712  
 713              coinControl.SetInputWeight(COutPoint(txid, vout), weight);
 714          }
 715      }
 716  
 717      if (options.exists("max_tx_weight")) {
 718          coinControl.m_max_tx_weight = options["max_tx_weight"].getInt<int>();
 719      }
 720  
 721      if (tx.version == TRUC_VERSION) {
 722          if (!coinControl.m_max_tx_weight.has_value() || coinControl.m_max_tx_weight.value() > TRUC_MAX_WEIGHT) {
 723              coinControl.m_max_tx_weight = TRUC_MAX_WEIGHT;
 724          }
 725      }
 726  
 727      if (recipients.empty())
 728          throw JSONRPCError(RPC_INVALID_PARAMETER, "TX must have at least one output");
 729  
 730      auto txr = FundTransaction(wallet, tx, recipients, change_position, lockUnspents, coinControl);
 731      if (!txr) {
 732          throw JSONRPCError(RPC_WALLET_ERROR, ErrorString(txr).original);
 733      }
 734      return *txr;
 735  }
 736  
 737  static void SetOptionsInputWeights(const UniValue& inputs, UniValue& options)
 738  {
 739      if (options.exists("input_weights")) {
 740          throw JSONRPCError(RPC_INVALID_PARAMETER, "Input weights should be specified in inputs rather than in options.");
 741      }
 742      if (inputs.size() == 0) {
 743          return;
 744      }
 745      UniValue weights(UniValue::VARR);
 746      for (const UniValue& input : inputs.getValues()) {
 747          if (input.exists("weight")) {
 748              weights.push_back(input);
 749          }
 750      }
 751      options.pushKV("input_weights", std::move(weights));
 752  }
 753  
 754  RPCHelpMan fundrawtransaction()
 755  {
 756      return RPCHelpMan{
 757          "fundrawtransaction",
 758          "If the transaction has no inputs, they will be automatically selected to meet its out value.\n"
 759                  "It will add at most one change output to the outputs.\n"
 760                  "No existing outputs will be modified unless \"subtractFeeFromOutputs\" is specified.\n"
 761                  "Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n"
 762                  "The inputs added will not be signed, use signrawtransactionwithkey\n"
 763                  "or signrawtransactionwithwallet for that.\n"
 764                  "All existing inputs must either have their previous output transaction be in the wallet\n"
 765                  "or be in the UTXO set. Solving data must be provided for non-wallet inputs.\n"
 766                  "Note that all inputs selected must be of standard form and P2SH scripts must be\n"
 767                  "in the wallet using importdescriptors (to calculate fees).\n"
 768                  "You can see whether this is the case by checking the \"solvable\" field in the listunspent output.\n"
 769                  "Note that if specifying an exact fee rate, the resulting transaction may have a higher fee rate\n"
 770                  "if the transaction has unconfirmed inputs. This is because the wallet will attempt to make the\n"
 771                  "entire package have the given fee rate, not the resulting transaction.\n",
 772                  {
 773                      {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of the raw transaction"},
 774                      {"options", RPCArg::Type::OBJ_NAMED_PARAMS, RPCArg::Optional::OMITTED, "",
 775                          Cat<std::vector<RPCArg>>(
 776                          {
 777                              {"add_inputs", RPCArg::Type::BOOL, RPCArg::Default{true}, "For a transaction with existing inputs, automatically include more if they are not enough."},
 778                              {"include_unsafe", RPCArg::Type::BOOL, RPCArg::Default{false}, "Include inputs that are not safe to spend (unconfirmed transactions from outside keys and unconfirmed replacement transactions).\n"
 779                                                            "Warning: the resulting transaction may become invalid if one of the unsafe inputs disappears.\n"
 780                                                            "If that happens, you will need to fund the transaction with different inputs and republish it."},
 781                              {"minconf", RPCArg::Type::NUM, RPCArg::Default{0}, "If add_inputs is specified, require inputs with at least this many confirmations."},
 782                              {"maxconf", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "If add_inputs is specified, require inputs with at most this many confirmations."},
 783                              {"changeAddress", RPCArg::Type::STR, RPCArg::DefaultHint{"automatic"}, "The bitcoin address to receive the change"},
 784                              {"changePosition", RPCArg::Type::NUM, RPCArg::DefaultHint{"random"}, "The index of the change output"},
 785                              {"change_type", RPCArg::Type::STR, RPCArg::DefaultHint{"set by -changetype"}, "The output type to use. Only valid if changeAddress is not specified. Options are " + FormatAllOutputTypes() + "."},
 786                              {"includeWatching", RPCArg::Type::BOOL, RPCArg::Default{false}, "(DEPRECATED) No longer used"},
 787                              {"lockUnspents", RPCArg::Type::BOOL, RPCArg::Default{false}, "Lock selected unspent outputs"},
 788                              {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."},
 789                              {"feeRate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_UNIT + "/kvB."},
 790                              {"subtractFeeFromOutputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "The integers.\n"
 791                                                            "The fee will be equally deducted from the amount of each specified output.\n"
 792                                                            "Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
 793                                                            "If no outputs are specified here, the sender pays the fee.",
 794                                  {
 795                                      {"vout_index", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The zero-based output index, before a change output is added."},
 796                                  },
 797                              },
 798                              {"input_weights", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "Inputs and their corresponding weights",
 799                                  {
 800                                      {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "",
 801                                          {
 802                                              {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
 803                                              {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output index"},
 804                                              {"weight", RPCArg::Type::NUM, RPCArg::Optional::NO, "The maximum weight for this input, "
 805                                                  "including the weight of the outpoint and sequence number. "
 806                                                  "Note that serialized signature sizes are not guaranteed to be consistent, "
 807                                                  "so the maximum DER signatures size of 73 bytes should be used when considering ECDSA signatures."
 808                                                  "Remember to convert serialized sizes to weight units when necessary."},
 809                                          },
 810                                      },
 811                                  },
 812                               },
 813                              {"max_tx_weight", RPCArg::Type::NUM, RPCArg::Default{MAX_STANDARD_TX_WEIGHT}, "The maximum acceptable transaction weight.\n"
 814                                                            "Transaction building will fail if this can not be satisfied."},
 815                          },
 816                          FundTxDoc()),
 817                          RPCArgOptions{
 818                              .skip_type_check = true,
 819                              .oneline_description = "options",
 820                          }},
 821                      {"iswitness", RPCArg::Type::BOOL, RPCArg::DefaultHint{"depends on heuristic tests"}, "Whether the transaction hex is a serialized witness transaction.\n"
 822                          "If iswitness is not present, heuristic tests will be used in decoding.\n"
 823                          "If true, only witness deserialization will be tried.\n"
 824                          "If false, only non-witness deserialization will be tried.\n"
 825                          "This boolean should reflect whether the transaction has inputs\n"
 826                          "(e.g. fully valid, or on-chain transactions), if known by the caller."
 827                      },
 828                  },
 829                  RPCResult{
 830                      RPCResult::Type::OBJ, "", "",
 831                      {
 832                          {RPCResult::Type::STR_HEX, "hex", "The resulting raw transaction (hex-encoded string)"},
 833                          {RPCResult::Type::STR_AMOUNT, "fee", "Fee in " + CURRENCY_UNIT + " the resulting transaction pays"},
 834                          {RPCResult::Type::NUM, "changepos", "The position of the added change output, or -1"},
 835                      }
 836                                  },
 837                                  RPCExamples{
 838                              "\nCreate a transaction with no inputs\n"
 839                              + HelpExampleCli("createrawtransaction", "\"[]\" \"{\\\"myaddress\\\":0.01}\"") +
 840                              "\nAdd sufficient unsigned inputs to meet the output value\n"
 841                              + HelpExampleCli("fundrawtransaction", "\"rawtransactionhex\"") +
 842                              "\nSign the transaction\n"
 843                              + HelpExampleCli("signrawtransactionwithwallet", "\"fundedtransactionhex\"") +
 844                              "\nSend the transaction\n"
 845                              + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"")
 846                                  },
 847          [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
 848  {
 849      std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
 850      if (!pwallet) return UniValue::VNULL;
 851  
 852      // parse hex string from parameter
 853      CMutableTransaction tx;
 854      bool try_witness = request.params[2].isNull() ? true : request.params[2].get_bool();
 855      bool try_no_witness = request.params[2].isNull() ? true : !request.params[2].get_bool();
 856      if (!DecodeHexTx(tx, request.params[0].get_str(), try_no_witness, try_witness)) {
 857          throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
 858      }
 859      UniValue options = request.params[1];
 860      std::vector<std::pair<CTxDestination, CAmount>> destinations;
 861      for (const auto& tx_out : tx.vout) {
 862          CTxDestination dest;
 863          ExtractDestination(tx_out.scriptPubKey, dest);
 864          destinations.emplace_back(dest, tx_out.nValue);
 865      }
 866      std::vector<std::string> dummy(destinations.size(), "dummy");
 867      std::vector<CRecipient> recipients = CreateRecipients(
 868              destinations,
 869              InterpretSubtractFeeFromOutputInstructions(options["subtractFeeFromOutputs"], dummy)
 870      );
 871      CCoinControl coin_control;
 872      // Automatically select (additional) coins. Can be overridden by options.add_inputs.
 873      coin_control.m_allow_other_inputs = true;
 874      // Clear tx.vout since it is not meant to be used now that we are passing outputs directly.
 875      // This sets us up for a future PR to completely remove tx from the function signature in favor of passing inputs directly
 876      tx.vout.clear();
 877      auto txr = FundTransaction(*pwallet, tx, recipients, options, coin_control, /*override_min_fee=*/true);
 878  
 879      UniValue result(UniValue::VOBJ);
 880      result.pushKV("hex", EncodeHexTx(*txr.tx));
 881      result.pushKV("fee", ValueFromAmount(txr.fee));
 882      result.pushKV("changepos", txr.change_pos ? (int)*txr.change_pos : -1);
 883  
 884      return result;
 885  },
 886      };
 887  }
 888  
 889  RPCHelpMan signrawtransactionwithwallet()
 890  {
 891      return RPCHelpMan{
 892          "signrawtransactionwithwallet",
 893          "Sign inputs for raw transaction (serialized, hex-encoded).\n"
 894                  "The second optional argument (may be null) is an array of previous transaction outputs that\n"
 895                  "this transaction depends on but may not yet be in the block chain." +
 896          HELP_REQUIRING_PASSPHRASE,
 897                  {
 898                      {"hexstring", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction hex string"},
 899                      {"prevtxs", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "The previous dependent transaction outputs",
 900                          {
 901                              {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "",
 902                                  {
 903                                      {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
 904                                      {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},
 905                                      {"scriptPubKey", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The output script"},
 906                                      {"redeemScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2SH) redeem script"},
 907                                      {"witnessScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2WSH or P2SH-P2WSH) witness script"},
 908                                      {"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::OMITTED, "(required for Segwit inputs) the amount spent"},
 909                                  },
 910                              },
 911                          },
 912                      },
 913                      {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"DEFAULT for Taproot, ALL otherwise"}, "The signature hash type. Must be one of\n"
 914              "       \"DEFAULT\"\n"
 915              "       \"ALL\"\n"
 916              "       \"NONE\"\n"
 917              "       \"SINGLE\"\n"
 918              "       \"ALL|ANYONECANPAY\"\n"
 919              "       \"NONE|ANYONECANPAY\"\n"
 920              "       \"SINGLE|ANYONECANPAY\""},
 921                  },
 922                  RPCResult{
 923                      RPCResult::Type::OBJ, "", "",
 924                      {
 925                          {RPCResult::Type::STR_HEX, "hex", "The hex-encoded raw transaction with signature(s)"},
 926                          {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"},
 927                          {RPCResult::Type::ARR, "errors", /*optional=*/true, "Script verification errors (if there are any)",
 928                          {
 929                              {RPCResult::Type::OBJ, "", "",
 930                              {
 931                                  {RPCResult::Type::STR_HEX, "txid", "The hash of the referenced, previous transaction"},
 932                                  {RPCResult::Type::NUM, "vout", "The index of the output to spent and used as input"},
 933                                  {RPCResult::Type::ARR, "witness", "",
 934                                  {
 935                                      {RPCResult::Type::STR_HEX, "witness", ""},
 936                                  }},
 937                                  {RPCResult::Type::STR_HEX, "scriptSig", "The hex-encoded signature script"},
 938                                  {RPCResult::Type::NUM, "sequence", "Script sequence number"},
 939                                  {RPCResult::Type::STR, "error", "Verification or signing error related to the input"},
 940                              }},
 941                          }},
 942                      }
 943                  },
 944                  RPCExamples{
 945                      HelpExampleCli("signrawtransactionwithwallet", "\"myhex\"")
 946              + HelpExampleRpc("signrawtransactionwithwallet", "\"myhex\"")
 947                  },
 948          [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
 949  {
 950      const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
 951      if (!pwallet) return UniValue::VNULL;
 952  
 953      CMutableTransaction mtx;
 954      if (!DecodeHexTx(mtx, request.params[0].get_str())) {
 955          throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input.");
 956      }
 957  
 958      // Sign the transaction
 959      LOCK(pwallet->cs_wallet);
 960      EnsureWalletIsUnlocked(*pwallet);
 961  
 962      // Fetch previous transactions (inputs):
 963      std::map<COutPoint, Coin> coins;
 964      for (const CTxIn& txin : mtx.vin) {
 965          coins[txin.prevout]; // Create empty map entry keyed by prevout.
 966      }
 967      pwallet->chain().findCoins(coins);
 968  
 969      // Parse the prevtxs array
 970      ParsePrevouts(request.params[1], nullptr, coins);
 971  
 972      std::optional<int> nHashType = ParseSighashString(request.params[2]);
 973      if (!nHashType) {
 974          nHashType = SIGHASH_DEFAULT;
 975      }
 976  
 977      // Script verification errors
 978      std::map<int, bilingual_str> input_errors;
 979  
 980      bool complete = pwallet->SignTransaction(mtx, coins, *nHashType, input_errors);
 981      UniValue result(UniValue::VOBJ);
 982      SignTransactionResultToJSON(mtx, complete, coins, input_errors, result);
 983      return result;
 984  },
 985      };
 986  }
 987  
 988  // Definition of allowed formats of specifying transaction outputs in
 989  // `bumpfee`, `psbtbumpfee`, `send` and `walletcreatefundedpsbt` RPCs.
 990  static std::vector<RPCArg> OutputsDoc()
 991  {
 992      return
 993      {
 994          {"", RPCArg::Type::OBJ_USER_KEYS, RPCArg::Optional::OMITTED, "",
 995              {
 996                  {"address", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "A key-value pair. The key (string) is the bitcoin address,\n"
 997                           "the value (float or string) is the amount in " + CURRENCY_UNIT + ""},
 998              },
 999          },
1000          {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "",
1001              {
1002                  {"data", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "A key-value pair. The key must be \"data\", the value is hex-encoded data that becomes a part of an OP_RETURN output"},
1003              },
1004          },
1005      };
1006  }
1007  
1008  static RPCHelpMan bumpfee_helper(std::string method_name)
1009  {
1010      const bool want_psbt = method_name == "psbtbumpfee";
1011      const std::string incremental_fee{CFeeRate(DEFAULT_INCREMENTAL_RELAY_FEE).ToString(FeeEstimateMode::SAT_VB)};
1012  
1013      return RPCHelpMan{method_name,
1014          "Bumps the fee of a transaction T, replacing it with a new transaction B.\n"
1015          + std::string(want_psbt ? "Returns a PSBT instead of creating and signing a new transaction.\n" : "") +
1016          "A transaction with the given txid must be in the wallet.\n"
1017          "The command will pay the additional fee by reducing change outputs or adding inputs when necessary.\n"
1018          "It may add a new change output if one does not already exist.\n"
1019          "All inputs in the original transaction will be included in the replacement transaction.\n"
1020          "The command will fail if the wallet or mempool contains a transaction that spends one of T's outputs.\n"
1021          "By default, the new fee will be calculated automatically using the estimatesmartfee RPC.\n"
1022          "The user can specify a confirmation target for estimatesmartfee.\n"
1023          "Alternatively, the user can specify a fee rate in " + CURRENCY_ATOM + "/vB for the new transaction.\n"
1024          "At a minimum, the new fee rate must be high enough to pay an additional new relay fee (incrementalfee\n"
1025          "returned by getnetworkinfo) to enter the node's mempool.\n"
1026          "* WARNING: before version 0.21, fee_rate was in " + CURRENCY_UNIT + "/kvB. As of 0.21, fee_rate is in " + CURRENCY_ATOM + "/vB. *\n",
1027          {
1028              {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The txid to be bumped"},
1029              {"options", RPCArg::Type::OBJ_NAMED_PARAMS, RPCArg::Optional::OMITTED, "",
1030                  {
1031                      {"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks\n"},
1032                      {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"},
1033                               "\nSpecify a fee rate in " + CURRENCY_ATOM + "/vB instead of relying on the built-in fee estimator.\n"
1034                               "Must be at least " + incremental_fee + " higher than the current transaction fee rate.\n"
1035                               "WARNING: before version 0.21, fee_rate was in " + CURRENCY_UNIT + "/kvB. As of 0.21, fee_rate is in " + CURRENCY_ATOM + "/vB.\n"},
1036                      {"replaceable", RPCArg::Type::BOOL, RPCArg::Default{true},
1037                               "Whether the new transaction should be\n"
1038                               "marked bip-125 replaceable. If true, the sequence numbers in the transaction will\n"
1039                               "be set to 0xfffffffd. If false, any input sequence numbers in the\n"
1040                               "transaction will be set to 0xfffffffe\n"
1041                               "so the new transaction will not be explicitly bip-125 replaceable (though it may\n"
1042                               "still be replaceable in practice, for example if it has unconfirmed ancestors which\n"
1043                               "are replaceable).\n"},
1044                      {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n"
1045                                + FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used"))},
1046                      {"outputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "The outputs specified as key-value pairs.\n"
1047                               "Each key may only appear once, i.e. there can only be one 'data' output, and no address may be duplicated.\n"
1048                               "At least one output of either type must be specified.\n"
1049                               "Cannot be provided if 'original_change_index' is specified.",
1050                          OutputsDoc(),
1051                          RPCArgOptions{.skip_type_check = true}},
1052                      {"original_change_index", RPCArg::Type::NUM, RPCArg::DefaultHint{"not set, detect change automatically"}, "The 0-based index of the change output on the original transaction. "
1053                                                                                                                              "The indicated output will be recycled into the new change output on the bumped transaction. "
1054                                                                                                                              "The remainder after paying the recipients and fees will be sent to the output script of the "
1055                                                                                                                              "original change output. The change output’s amount can increase if bumping the transaction "
1056                                                                                                                              "adds new inputs, otherwise it will decrease. Cannot be used in combination with the 'outputs' option."},
1057                  },
1058                  RPCArgOptions{.oneline_description="options"}},
1059          },
1060          RPCResult{
1061              RPCResult::Type::OBJ, "", "", Cat(
1062                  want_psbt ?
1063                  std::vector<RPCResult>{{RPCResult::Type::STR, "psbt", "The base64-encoded unsigned PSBT of the new transaction."}} :
1064                  std::vector<RPCResult>{{RPCResult::Type::STR_HEX, "txid", "The id of the new transaction."}},
1065              {
1066                  {RPCResult::Type::STR_AMOUNT, "origfee", "The fee of the replaced transaction."},
1067                  {RPCResult::Type::STR_AMOUNT, "fee", "The fee of the new transaction."},
1068                  {RPCResult::Type::ARR, "errors", "Errors encountered during processing (may be empty).",
1069                  {
1070                      {RPCResult::Type::STR, "", ""},
1071                  }},
1072              })
1073          },
1074          RPCExamples{
1075      "\nBump the fee, get the new transaction\'s " + std::string(want_psbt ? "psbt" : "txid") + "\n" +
1076              HelpExampleCli(method_name, "<txid>")
1077          },
1078          [want_psbt](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1079  {
1080      std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
1081      if (!pwallet) return UniValue::VNULL;
1082  
1083      if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && !pwallet->IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER) && !want_psbt) {
1084          throw JSONRPCError(RPC_WALLET_ERROR, "bumpfee is not available with wallets that have private keys disabled. Use psbtbumpfee instead.");
1085      }
1086  
1087      Txid hash{Txid::FromUint256(ParseHashV(request.params[0], "txid"))};
1088  
1089      CCoinControl coin_control;
1090      // optional parameters
1091      coin_control.m_signal_bip125_rbf = true;
1092      std::vector<CTxOut> outputs;
1093  
1094      std::optional<uint32_t> original_change_index;
1095  
1096      if (!request.params[1].isNull()) {
1097          UniValue options = request.params[1];
1098          RPCTypeCheckObj(options,
1099              {
1100                  {"confTarget", UniValueType(UniValue::VNUM)},
1101                  {"conf_target", UniValueType(UniValue::VNUM)},
1102                  {"fee_rate", UniValueType()}, // will be checked by AmountFromValue() in SetFeeEstimateMode()
1103                  {"replaceable", UniValueType(UniValue::VBOOL)},
1104                  {"estimate_mode", UniValueType(UniValue::VSTR)},
1105                  {"outputs", UniValueType()}, // will be checked by AddOutputs()
1106                  {"original_change_index", UniValueType(UniValue::VNUM)},
1107              },
1108              true, true);
1109  
1110          if (options.exists("confTarget") && options.exists("conf_target")) {
1111              throw JSONRPCError(RPC_INVALID_PARAMETER, "confTarget and conf_target options should not both be set. Use conf_target (confTarget is deprecated).");
1112          }
1113  
1114          auto conf_target = options.exists("confTarget") ? options["confTarget"] : options["conf_target"];
1115  
1116          if (options.exists("replaceable")) {
1117              coin_control.m_signal_bip125_rbf = options["replaceable"].get_bool();
1118          }
1119          SetFeeEstimateMode(*pwallet, coin_control, conf_target, options["estimate_mode"], options["fee_rate"], /*override_min_fee=*/false);
1120  
1121          // Prepare new outputs by creating a temporary tx and calling AddOutputs().
1122          if (!options["outputs"].isNull()) {
1123              if (options["outputs"].isArray() && options["outputs"].empty()) {
1124                  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, output argument cannot be an empty array");
1125              }
1126              CMutableTransaction tempTx;
1127              AddOutputs(tempTx, options["outputs"]);
1128              outputs = tempTx.vout;
1129          }
1130  
1131          if (options.exists("original_change_index")) {
1132              original_change_index = options["original_change_index"].getInt<uint32_t>();
1133          }
1134      }
1135  
1136      // Make sure the results are valid at least up to the most recent block
1137      // the user could have gotten from another RPC command prior to now
1138      pwallet->BlockUntilSyncedToCurrentChain();
1139  
1140      LOCK(pwallet->cs_wallet);
1141  
1142      EnsureWalletIsUnlocked(*pwallet);
1143  
1144  
1145      std::vector<bilingual_str> errors;
1146      CAmount old_fee;
1147      CAmount new_fee;
1148      CMutableTransaction mtx;
1149      feebumper::Result res;
1150      // Targeting feerate bump.
1151      res = feebumper::CreateRateBumpTransaction(*pwallet, hash, coin_control, errors, old_fee, new_fee, mtx, /*require_mine=*/ !want_psbt, outputs, original_change_index);
1152      if (res != feebumper::Result::OK) {
1153          switch(res) {
1154              case feebumper::Result::INVALID_ADDRESS_OR_KEY:
1155                  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, errors[0].original);
1156                  break;
1157              case feebumper::Result::INVALID_REQUEST:
1158                  throw JSONRPCError(RPC_INVALID_REQUEST, errors[0].original);
1159                  break;
1160              case feebumper::Result::INVALID_PARAMETER:
1161                  throw JSONRPCError(RPC_INVALID_PARAMETER, errors[0].original);
1162                  break;
1163              case feebumper::Result::WALLET_ERROR:
1164                  throw JSONRPCError(RPC_WALLET_ERROR, errors[0].original);
1165                  break;
1166              default:
1167                  throw JSONRPCError(RPC_MISC_ERROR, errors[0].original);
1168                  break;
1169          }
1170      }
1171  
1172      UniValue result(UniValue::VOBJ);
1173  
1174      // For bumpfee, return the new transaction id.
1175      // For psbtbumpfee, return the base64-encoded unsigned PSBT of the new transaction.
1176      if (!want_psbt) {
1177          if (!feebumper::SignTransaction(*pwallet, mtx)) {
1178              if (pwallet->IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER)) {
1179                  throw JSONRPCError(RPC_WALLET_ERROR, "Transaction incomplete. Try psbtbumpfee instead.");
1180              }
1181              throw JSONRPCError(RPC_WALLET_ERROR, "Can't sign transaction.");
1182          }
1183  
1184          Txid txid;
1185          if (feebumper::CommitTransaction(*pwallet, hash, std::move(mtx), errors, txid) != feebumper::Result::OK) {
1186              throw JSONRPCError(RPC_WALLET_ERROR, errors[0].original);
1187          }
1188  
1189          result.pushKV("txid", txid.GetHex());
1190      } else {
1191          PartiallySignedTransaction psbtx(mtx);
1192          bool complete = false;
1193          const auto err{pwallet->FillPSBT(psbtx, complete, std::nullopt, /*sign=*/false, /*bip32derivs=*/true)};
1194          CHECK_NONFATAL(!err);
1195          CHECK_NONFATAL(!complete);
1196          DataStream ssTx{};
1197          ssTx << psbtx;
1198          result.pushKV("psbt", EncodeBase64(ssTx.str()));
1199      }
1200  
1201      result.pushKV("origfee", ValueFromAmount(old_fee));
1202      result.pushKV("fee", ValueFromAmount(new_fee));
1203      UniValue result_errors(UniValue::VARR);
1204      for (const bilingual_str& error : errors) {
1205          result_errors.push_back(error.original);
1206      }
1207      result.pushKV("errors", std::move(result_errors));
1208  
1209      return result;
1210  },
1211      };
1212  }
1213  
1214  RPCHelpMan bumpfee() { return bumpfee_helper("bumpfee"); }
1215  RPCHelpMan psbtbumpfee() { return bumpfee_helper("psbtbumpfee"); }
1216  
1217  RPCHelpMan send()
1218  {
1219      return RPCHelpMan{
1220          "send",
1221          "EXPERIMENTAL warning: this call may be changed in future releases.\n"
1222          "\nSend a transaction.\n",
1223          {
1224              {"outputs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The outputs specified as key-value pairs.\n"
1225                      "Each key may only appear once, i.e. there can only be one 'data' output, and no address may be duplicated.\n"
1226                      "At least one output of either type must be specified.\n"
1227                      "For convenience, a dictionary, which holds the key-value pairs directly, is also accepted.",
1228                  OutputsDoc(),
1229                  RPCArgOptions{.skip_type_check = true}},
1230              {"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks"},
1231              {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n"
1232                + FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used"))},
1233              {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."},
1234              {"options", RPCArg::Type::OBJ_NAMED_PARAMS, RPCArg::Optional::OMITTED, "",
1235                  Cat<std::vector<RPCArg>>(
1236                  {
1237                      {"add_inputs", RPCArg::Type::BOOL, RPCArg::DefaultHint{"false when \"inputs\" are specified, true otherwise"},"Automatically include coins from the wallet to cover the target amount.\n"},
1238                      {"include_unsafe", RPCArg::Type::BOOL, RPCArg::Default{false}, "Include inputs that are not safe to spend (unconfirmed transactions from outside keys and unconfirmed replacement transactions).\n"
1239                                                            "Warning: the resulting transaction may become invalid if one of the unsafe inputs disappears.\n"
1240                                                            "If that happens, you will need to fund the transaction with different inputs and republish it."},
1241                      {"minconf", RPCArg::Type::NUM, RPCArg::Default{0}, "If add_inputs is specified, require inputs with at least this many confirmations."},
1242                      {"maxconf", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "If add_inputs is specified, require inputs with at most this many confirmations."},
1243                      {"add_to_wallet", RPCArg::Type::BOOL, RPCArg::Default{true}, "When false, returns a serialized transaction which will not be added to the wallet or broadcast"},
1244                      {"change_address", RPCArg::Type::STR, RPCArg::DefaultHint{"automatic"}, "The bitcoin address to receive the change"},
1245                      {"change_position", RPCArg::Type::NUM, RPCArg::DefaultHint{"random"}, "The index of the change output"},
1246                      {"change_type", RPCArg::Type::STR, RPCArg::DefaultHint{"set by -changetype"}, "The output type to use. Only valid if change_address is not specified. Options are " + FormatAllOutputTypes() + "."},
1247                      {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB.", RPCArgOptions{.also_positional = true}},
1248                      {"include_watching", RPCArg::Type::BOOL, RPCArg::Default{"false"}, "(DEPRECATED) No longer used"},
1249                      {"inputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Specify inputs instead of adding them automatically.",
1250                          {
1251                            {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", {
1252                              {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
1253                              {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},
1254                              {"sequence", RPCArg::Type::NUM, RPCArg::DefaultHint{"depends on the value of the 'replaceable' and 'locktime' arguments"}, "The sequence number"},
1255                              {"weight", RPCArg::Type::NUM, RPCArg::DefaultHint{"Calculated from wallet and solving data"}, "The maximum weight for this input, "
1256                                          "including the weight of the outpoint and sequence number. "
1257                                          "Note that signature sizes are not guaranteed to be consistent, "
1258                                          "so the maximum DER signatures size of 73 bytes should be used when considering ECDSA signatures."
1259                                          "Remember to convert serialized sizes to weight units when necessary."},
1260                            }},
1261                          },
1262                      },
1263                      {"locktime", RPCArg::Type::NUM, RPCArg::DefaultHint{"locktime close to block height to prevent fee sniping"}, "Raw locktime. Non-0 value also locktime-activates inputs"},
1264                      {"lock_unspents", RPCArg::Type::BOOL, RPCArg::Default{false}, "Lock selected unspent outputs"},
1265                      {"psbt", RPCArg::Type::BOOL,  RPCArg::DefaultHint{"automatic"}, "Always return a PSBT, implies add_to_wallet=false."},
1266                      {"subtract_fee_from_outputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Outputs to subtract the fee from, specified as integer indices.\n"
1267                      "The fee will be equally deducted from the amount of each specified output.\n"
1268                      "Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
1269                      "If no outputs are specified here, the sender pays the fee.",
1270                          {
1271                              {"vout_index", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The zero-based output index, before a change output is added."},
1272                          },
1273                      },
1274                      {"max_tx_weight", RPCArg::Type::NUM, RPCArg::Default{MAX_STANDARD_TX_WEIGHT}, "The maximum acceptable transaction weight.\n"
1275                                                    "Transaction building will fail if this can not be satisfied."},
1276                  },
1277                  FundTxDoc()),
1278                  RPCArgOptions{.oneline_description="options"}},
1279                  {"version", RPCArg::Type::NUM, RPCArg::Default{DEFAULT_WALLET_TX_VERSION}, "Transaction version"},
1280          },
1281          RPCResult{
1282              RPCResult::Type::OBJ, "", "",
1283                  {
1284                      {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"},
1285                      {RPCResult::Type::STR_HEX, "txid", /*optional=*/true, "The transaction id for the send. Only 1 transaction is created regardless of the number of addresses."},
1286                      {RPCResult::Type::STR_HEX, "hex", /*optional=*/true, "If add_to_wallet is false, the hex-encoded raw transaction with signature(s)"},
1287                      {RPCResult::Type::STR, "psbt", /*optional=*/true, "If more signatures are needed, or if add_to_wallet is false, the base64-encoded (partially) signed transaction"}
1288                  }
1289          },
1290          RPCExamples{""
1291          "\nSend 0.1 BTC with a confirmation target of 6 blocks in economical fee estimate mode\n"
1292          + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.1}' 6 economical\n") +
1293          "Send 0.2 BTC with a fee rate of 1.1 " + CURRENCY_ATOM + "/vB using positional arguments\n"
1294          + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.2}' null \"unset\" 1.1\n") +
1295          "Send 0.2 BTC with a fee rate of 1 " + CURRENCY_ATOM + "/vB using the options argument\n"
1296          + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.2}' null \"unset\" null '{\"fee_rate\": 1}'\n") +
1297          "Send 0.3 BTC with a fee rate of 25 " + CURRENCY_ATOM + "/vB using named arguments\n"
1298          + HelpExampleCli("-named send", "outputs='{\"" + EXAMPLE_ADDRESS[0] + "\": 0.3}' fee_rate=25\n") +
1299          "Create a transaction that should confirm the next block, with a specific input, and return result without adding to wallet or broadcasting to the network\n"
1300          + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.1}' 1 economical '{\"add_to_wallet\": false, \"inputs\": [{\"txid\":\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\", \"vout\":1}]}'")
1301          },
1302          [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1303          {
1304              std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
1305              if (!pwallet) return UniValue::VNULL;
1306  
1307              UniValue options{request.params[4].isNull() ? UniValue::VOBJ : request.params[4]};
1308              InterpretFeeEstimationInstructions(/*conf_target=*/request.params[1], /*estimate_mode=*/request.params[2], /*fee_rate=*/request.params[3], options);
1309              PreventOutdatedOptions(options);
1310  
1311  
1312              bool rbf{options.exists("replaceable") ? options["replaceable"].get_bool() : pwallet->m_signal_rbf};
1313              UniValue outputs(UniValue::VOBJ);
1314              outputs = NormalizeOutputs(request.params[0]);
1315              std::vector<CRecipient> recipients = CreateRecipients(
1316                      ParseOutputs(outputs),
1317                      InterpretSubtractFeeFromOutputInstructions(options["subtract_fee_from_outputs"], outputs.getKeys())
1318              );
1319              CCoinControl coin_control;
1320              coin_control.m_version = self.Arg<uint32_t>("version");
1321              CMutableTransaction rawTx = ConstructTransaction(options["inputs"], request.params[0], options["locktime"], rbf, coin_control.m_version);
1322              // Automatically select coins, unless at least one is manually selected. Can
1323              // be overridden by options.add_inputs.
1324              coin_control.m_allow_other_inputs = rawTx.vin.size() == 0;
1325              if (options.exists("max_tx_weight")) {
1326                  coin_control.m_max_tx_weight = options["max_tx_weight"].getInt<int>();
1327              }
1328  
1329              SetOptionsInputWeights(options["inputs"], options);
1330              // Clear tx.vout since it is not meant to be used now that we are passing outputs directly.
1331              // This sets us up for a future PR to completely remove tx from the function signature in favor of passing inputs directly
1332              rawTx.vout.clear();
1333              auto txr = FundTransaction(*pwallet, rawTx, recipients, options, coin_control, /*override_min_fee=*/false);
1334  
1335              CMutableTransaction tx = CMutableTransaction(*txr.tx);
1336              return FinishTransaction(pwallet, options, tx);
1337          }
1338      };
1339  }
1340  
1341  RPCHelpMan sendall()
1342  {
1343      return RPCHelpMan{"sendall",
1344          "EXPERIMENTAL warning: this call may be changed in future releases.\n"
1345          "\nSpend the value of all (or specific) confirmed UTXOs and unconfirmed change in the wallet to one or more recipients.\n"
1346          "Unconfirmed inbound UTXOs and locked UTXOs will not be spent. Sendall will respect the avoid_reuse wallet flag.\n"
1347          "If your wallet contains many small inputs, either because it received tiny payments or as a result of accumulating change, consider using `send_max` to exclude inputs that are worth less than the fees needed to spend them.\n",
1348          {
1349              {"recipients", RPCArg::Type::ARR, RPCArg::Optional::NO, "The sendall destinations. Each address may only appear once.\n"
1350                  "Optionally some recipients can be specified with an amount to perform payments, but at least one address must appear without a specified amount.\n",
1351                  {
1352                      {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "A bitcoin address which receives an equal share of the unspecified amount."},
1353                      {"", RPCArg::Type::OBJ_USER_KEYS, RPCArg::Optional::OMITTED, "",
1354                          {
1355                              {"address", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "A key-value pair. The key (string) is the bitcoin address, the value (float or string) is the amount in " + CURRENCY_UNIT + ""},
1356                          },
1357                      },
1358                  },
1359              },
1360              {"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks"},
1361              {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n"
1362                + FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used"))},
1363              {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."},
1364              {
1365                  "options", RPCArg::Type::OBJ_NAMED_PARAMS, RPCArg::Optional::OMITTED, "",
1366                  Cat<std::vector<RPCArg>>(
1367                      {
1368                          {"add_to_wallet", RPCArg::Type::BOOL, RPCArg::Default{true}, "When false, returns the serialized transaction without broadcasting or adding it to the wallet"},
1369                          {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB.", RPCArgOptions{.also_positional = true}},
1370                          {"include_watching", RPCArg::Type::BOOL, RPCArg::Default{false}, "(DEPRECATED) No longer used"},
1371                          {"inputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Use exactly the specified inputs to build the transaction. Specifying inputs is incompatible with the send_max, minconf, and maxconf options.",
1372                              {
1373                                  {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "",
1374                                      {
1375                                          {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
1376                                          {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},
1377                                          {"sequence", RPCArg::Type::NUM, RPCArg::DefaultHint{"depends on the value of the 'replaceable' and 'locktime' arguments"}, "The sequence number"},
1378                                      },
1379                                  },
1380                              },
1381                          },
1382                          {"locktime", RPCArg::Type::NUM, RPCArg::DefaultHint{"locktime close to block height to prevent fee sniping"}, "Raw locktime. Non-0 value also locktime-activates inputs"},
1383                          {"lock_unspents", RPCArg::Type::BOOL, RPCArg::Default{false}, "Lock selected unspent outputs"},
1384                          {"psbt", RPCArg::Type::BOOL,  RPCArg::DefaultHint{"automatic"}, "Always return a PSBT, implies add_to_wallet=false."},
1385                          {"send_max", RPCArg::Type::BOOL, RPCArg::Default{false}, "When true, only use UTXOs that can pay for their own fees to maximize the output amount. When 'false' (default), no UTXO is left behind. send_max is incompatible with providing specific inputs."},
1386                          {"minconf", RPCArg::Type::NUM, RPCArg::Default{0}, "Require inputs with at least this many confirmations."},
1387                          {"maxconf", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "Require inputs with at most this many confirmations."},
1388                          {"version", RPCArg::Type::NUM, RPCArg::Default{DEFAULT_WALLET_TX_VERSION}, "Transaction version"},
1389                      },
1390                      FundTxDoc()
1391                  ),
1392                  RPCArgOptions{.oneline_description="options"}
1393              },
1394          },
1395          RPCResult{
1396              RPCResult::Type::OBJ, "", "",
1397                  {
1398                      {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"},
1399                      {RPCResult::Type::STR_HEX, "txid", /*optional=*/true, "The transaction id for the send. Only 1 transaction is created regardless of the number of addresses."},
1400                      {RPCResult::Type::STR_HEX, "hex", /*optional=*/true, "If add_to_wallet is false, the hex-encoded raw transaction with signature(s)"},
1401                      {RPCResult::Type::STR, "psbt", /*optional=*/true, "If more signatures are needed, or if add_to_wallet is false, the base64-encoded (partially) signed transaction"}
1402                  }
1403          },
1404          RPCExamples{""
1405          "\nSpend all UTXOs from the wallet with a fee rate of 1 " + CURRENCY_ATOM + "/vB using named arguments\n"
1406          + HelpExampleCli("-named sendall", "recipients='[\"" + EXAMPLE_ADDRESS[0] + "\"]' fee_rate=1\n") +
1407          "Spend all UTXOs with a fee rate of 1.1 " + CURRENCY_ATOM + "/vB using positional arguments\n"
1408          + HelpExampleCli("sendall", "'[\"" + EXAMPLE_ADDRESS[0] + "\"]' null \"unset\" 1.1\n") +
1409          "Spend all UTXOs split into equal amounts to two addresses with a fee rate of 1.5 " + CURRENCY_ATOM + "/vB using the options argument\n"
1410          + HelpExampleCli("sendall", "'[\"" + EXAMPLE_ADDRESS[0] + "\", \"" + EXAMPLE_ADDRESS[1] + "\"]' null \"unset\" null '{\"fee_rate\": 1.5}'\n") +
1411          "Leave dust UTXOs in wallet, spend only UTXOs with positive effective value with a fee rate of 10 " + CURRENCY_ATOM + "/vB using the options argument\n"
1412          + HelpExampleCli("sendall", "'[\"" + EXAMPLE_ADDRESS[0] + "\"]' null \"unset\" null '{\"fee_rate\": 10, \"send_max\": true}'\n") +
1413          "Spend all UTXOs with a fee rate of 1.3 " + CURRENCY_ATOM + "/vB using named arguments and sending a 0.25 " + CURRENCY_UNIT + " to another recipient\n"
1414          + HelpExampleCli("-named sendall", "recipients='[{\"" + EXAMPLE_ADDRESS[1] + "\": 0.25}, \""+ EXAMPLE_ADDRESS[0] + "\"]' fee_rate=1.3\n")
1415          },
1416          [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1417          {
1418              std::shared_ptr<CWallet> const pwallet{GetWalletForJSONRPCRequest(request)};
1419              if (!pwallet) return UniValue::VNULL;
1420              // Make sure the results are valid at least up to the most recent block
1421              // the user could have gotten from another RPC command prior to now
1422              pwallet->BlockUntilSyncedToCurrentChain();
1423  
1424              UniValue options{request.params[4].isNull() ? UniValue::VOBJ : request.params[4]};
1425              InterpretFeeEstimationInstructions(/*conf_target=*/request.params[1], /*estimate_mode=*/request.params[2], /*fee_rate=*/request.params[3], options);
1426              PreventOutdatedOptions(options);
1427  
1428  
1429              std::set<std::string> addresses_without_amount;
1430              UniValue recipient_key_value_pairs(UniValue::VARR);
1431              const UniValue& recipients{request.params[0]};
1432              for (unsigned int i = 0; i < recipients.size(); ++i) {
1433                  const UniValue& recipient{recipients[i]};
1434                  if (recipient.isStr()) {
1435                      UniValue rkvp(UniValue::VOBJ);
1436                      rkvp.pushKV(recipient.get_str(), 0);
1437                      recipient_key_value_pairs.push_back(std::move(rkvp));
1438                      addresses_without_amount.insert(recipient.get_str());
1439                  } else {
1440                      recipient_key_value_pairs.push_back(recipient);
1441                  }
1442              }
1443  
1444              if (addresses_without_amount.size() == 0) {
1445                  throw JSONRPCError(RPC_INVALID_PARAMETER, "Must provide at least one address without a specified amount");
1446              }
1447  
1448              CCoinControl coin_control;
1449  
1450              SetFeeEstimateMode(*pwallet, coin_control, options["conf_target"], options["estimate_mode"], options["fee_rate"], /*override_min_fee=*/false);
1451  
1452              if (options.exists("minconf")) {
1453                  if (options["minconf"].getInt<int>() < 0)
1454                  {
1455                      throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid minconf (minconf cannot be negative): %s", options["minconf"].getInt<int>()));
1456                  }
1457  
1458                  coin_control.m_min_depth = options["minconf"].getInt<int>();
1459              }
1460  
1461              if (options.exists("maxconf")) {
1462                  coin_control.m_max_depth = options["maxconf"].getInt<int>();
1463  
1464                  if (coin_control.m_max_depth < coin_control.m_min_depth) {
1465                      throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("maxconf can't be lower than minconf: %d < %d", coin_control.m_max_depth, coin_control.m_min_depth));
1466                  }
1467              }
1468  
1469              if (options.exists("version")) {
1470                  coin_control.m_version = options["version"].getInt<int>();
1471              }
1472  
1473              if (coin_control.m_version == TRUC_VERSION) {
1474                  coin_control.m_max_tx_weight = TRUC_MAX_WEIGHT;
1475              } else {
1476                  coin_control.m_max_tx_weight = MAX_STANDARD_TX_WEIGHT;
1477              }
1478  
1479              const bool rbf{options.exists("replaceable") ? options["replaceable"].get_bool() : pwallet->m_signal_rbf};
1480  
1481              FeeCalculation fee_calc_out;
1482              CFeeRate fee_rate{GetMinimumFeeRate(*pwallet, coin_control, &fee_calc_out)};
1483              // Do not, ever, assume that it's fine to change the fee rate if the user has explicitly
1484              // provided one
1485              if (coin_control.m_feerate && fee_rate > *coin_control.m_feerate) {
1486                 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Fee rate (%s) is lower than the minimum fee rate setting (%s)", coin_control.m_feerate->ToString(FeeEstimateMode::SAT_VB), fee_rate.ToString(FeeEstimateMode::SAT_VB)));
1487              }
1488              if (fee_calc_out.reason == FeeReason::FALLBACK && !pwallet->m_allow_fallback_fee) {
1489                  // eventually allow a fallback fee
1490                  throw JSONRPCError(RPC_WALLET_ERROR, "Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee.");
1491              }
1492  
1493              CMutableTransaction rawTx{ConstructTransaction(options["inputs"], recipient_key_value_pairs, options["locktime"], rbf, coin_control.m_version)};
1494              LOCK(pwallet->cs_wallet);
1495  
1496              CAmount total_input_value(0);
1497              bool send_max{options.exists("send_max") ? options["send_max"].get_bool() : false};
1498              if (options.exists("inputs") && options.exists("send_max")) {
1499                  throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot combine send_max with specific inputs.");
1500              } else if (options.exists("inputs") && (options.exists("minconf") || options.exists("maxconf"))) {
1501                  throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot combine minconf or maxconf with specific inputs.");
1502              } else if (options.exists("inputs")) {
1503                  for (const CTxIn& input : rawTx.vin) {
1504                      if (pwallet->IsSpent(input.prevout)) {
1505                          throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Input not available. UTXO (%s:%d) was already spent.", input.prevout.hash.ToString(), input.prevout.n));
1506                      }
1507                      const CWalletTx* tx{pwallet->GetWalletTx(input.prevout.hash)};
1508                      if (!tx || input.prevout.n >= tx->tx->vout.size() || !pwallet->IsMine(tx->tx->vout[input.prevout.n])) {
1509                          throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Input not found. UTXO (%s:%d) is not part of wallet.", input.prevout.hash.ToString(), input.prevout.n));
1510                      }
1511                      if (pwallet->GetTxDepthInMainChain(*tx) == 0) {
1512                          if (tx->tx->version == TRUC_VERSION && coin_control.m_version != TRUC_VERSION) {
1513                              throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Can't spend unconfirmed version 3 pre-selected input with a version %d tx", coin_control.m_version));
1514                          } else if (coin_control.m_version == TRUC_VERSION && tx->tx->version != TRUC_VERSION) {
1515                              throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Can't spend unconfirmed version %d pre-selected input with a version 3 tx", tx->tx->version));
1516                          }
1517                      }
1518                      total_input_value += tx->tx->vout[input.prevout.n].nValue;
1519                  }
1520              } else {
1521                  CoinFilterParams coins_params;
1522                  coins_params.min_amount = 0;
1523                  for (const COutput& output : AvailableCoins(*pwallet, &coin_control, fee_rate, coins_params).All()) {
1524                      if (send_max && fee_rate.GetFee(output.input_bytes) > output.txout.nValue) {
1525                          continue;
1526                      }
1527                      // we are spending an unconfirmed TRUC transaction, so lower max weight
1528                      if (output.depth == 0 && coin_control.m_version == TRUC_VERSION) {
1529                          coin_control.m_max_tx_weight = TRUC_CHILD_MAX_WEIGHT;
1530                      }
1531                      CTxIn input(output.outpoint.hash, output.outpoint.n, CScript(), rbf ? MAX_BIP125_RBF_SEQUENCE : CTxIn::SEQUENCE_FINAL);
1532                      rawTx.vin.push_back(input);
1533                      total_input_value += output.txout.nValue;
1534                  }
1535              }
1536  
1537              std::vector<COutPoint> outpoints_spent;
1538              outpoints_spent.reserve(rawTx.vin.size());
1539  
1540              for (const CTxIn& tx_in : rawTx.vin) {
1541                  outpoints_spent.push_back(tx_in.prevout);
1542              }
1543  
1544              // estimate final size of tx
1545              const TxSize tx_size{CalculateMaximumSignedTxSize(CTransaction(rawTx), pwallet.get())};
1546              if (tx_size.vsize == -1) {
1547                  throw JSONRPCError(RPC_WALLET_ERROR, "Unable to determine the size of the transaction, the wallet contains unsolvable descriptors");
1548              }
1549              const CAmount fee_from_size{fee_rate.GetFee(tx_size.vsize)};
1550              const std::optional<CAmount> total_bump_fees{pwallet->chain().calculateCombinedBumpFee(outpoints_spent, fee_rate)};
1551              CAmount effective_value = total_input_value - fee_from_size - total_bump_fees.value_or(0);
1552  
1553              if (fee_from_size > pwallet->m_default_max_tx_fee) {
1554                  throw JSONRPCError(RPC_WALLET_ERROR, TransactionErrorString(TransactionError::MAX_FEE_EXCEEDED).original);
1555              }
1556  
1557              if (effective_value <= 0) {
1558                  if (send_max) {
1559                      throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Total value of UTXO pool too low to pay for transaction, try using lower feerate.");
1560                  } else {
1561                      throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Total value of UTXO pool too low to pay for transaction. Try using lower feerate or excluding uneconomic UTXOs with 'send_max' option.");
1562                  }
1563              }
1564  
1565              // If this transaction is too large, e.g. because the wallet has many UTXOs, it will be rejected by the node's mempool.
1566              if (tx_size.weight > coin_control.m_max_tx_weight) {
1567                  throw JSONRPCError(RPC_WALLET_ERROR, "Transaction too large.");
1568              }
1569  
1570              CAmount output_amounts_claimed{0};
1571              for (const CTxOut& out : rawTx.vout) {
1572                  output_amounts_claimed += out.nValue;
1573              }
1574  
1575              if (output_amounts_claimed > total_input_value) {
1576                  throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Assigned more value to outputs than available funds.");
1577              }
1578  
1579              const CAmount remainder{effective_value - output_amounts_claimed};
1580              if (remainder < 0) {
1581                  throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds for fees after creating specified outputs.");
1582              }
1583  
1584              const CAmount per_output_without_amount{remainder / (long)addresses_without_amount.size()};
1585  
1586              bool gave_remaining_to_first{false};
1587              for (CTxOut& out : rawTx.vout) {
1588                  CTxDestination dest;
1589                  ExtractDestination(out.scriptPubKey, dest);
1590                  std::string addr{EncodeDestination(dest)};
1591                  if (addresses_without_amount.count(addr) > 0) {
1592                      out.nValue = per_output_without_amount;
1593                      if (!gave_remaining_to_first) {
1594                          out.nValue += remainder % addresses_without_amount.size();
1595                          gave_remaining_to_first = true;
1596                      }
1597                      if (IsDust(out, pwallet->chain().relayDustFee())) {
1598                          // Dynamically generated output amount is dust
1599                          throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Dynamically assigned remainder results in dust output.");
1600                      }
1601                  } else {
1602                      if (IsDust(out, pwallet->chain().relayDustFee())) {
1603                          // Specified output amount is dust
1604                          throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Specified output amount to %s is below dust threshold.", addr));
1605                      }
1606                  }
1607              }
1608  
1609              const bool lock_unspents{options.exists("lock_unspents") ? options["lock_unspents"].get_bool() : false};
1610              if (lock_unspents) {
1611                  for (const CTxIn& txin : rawTx.vin) {
1612                      pwallet->LockCoin(txin.prevout, /*persist=*/false);
1613                  }
1614              }
1615  
1616              return FinishTransaction(pwallet, options, rawTx);
1617          }
1618      };
1619  }
1620  
1621  RPCHelpMan walletprocesspsbt()
1622  {
1623      return RPCHelpMan{
1624          "walletprocesspsbt",
1625          "Update a PSBT with input information from our wallet and then sign inputs\n"
1626                  "that we can sign for." +
1627          HELP_REQUIRING_PASSPHRASE,
1628                  {
1629                      {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction base64 string"},
1630                      {"sign", RPCArg::Type::BOOL, RPCArg::Default{true}, "Also sign the transaction when updating (requires wallet to be unlocked)"},
1631                      {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"DEFAULT for Taproot, ALL otherwise"}, "The signature hash type to sign with if not specified by the PSBT. Must be one of\n"
1632              "       \"DEFAULT\"\n"
1633              "       \"ALL\"\n"
1634              "       \"NONE\"\n"
1635              "       \"SINGLE\"\n"
1636              "       \"ALL|ANYONECANPAY\"\n"
1637              "       \"NONE|ANYONECANPAY\"\n"
1638              "       \"SINGLE|ANYONECANPAY\""},
1639                      {"bip32derivs", RPCArg::Type::BOOL, RPCArg::Default{true}, "Include BIP 32 derivation paths for public keys if we know them"},
1640                      {"finalize", RPCArg::Type::BOOL, RPCArg::Default{true}, "Also finalize inputs if possible"},
1641                  },
1642                  RPCResult{
1643                      RPCResult::Type::OBJ, "", "",
1644                      {
1645                          {RPCResult::Type::STR, "psbt", "The base64-encoded partially signed transaction"},
1646                          {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"},
1647                          {RPCResult::Type::STR_HEX, "hex", /*optional=*/true, "The hex-encoded network transaction if complete"},
1648                      }
1649                  },
1650                  RPCExamples{
1651                      HelpExampleCli("walletprocesspsbt", "\"psbt\"")
1652                  },
1653          [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1654  {
1655      const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
1656      if (!pwallet) return UniValue::VNULL;
1657  
1658      const CWallet& wallet{*pwallet};
1659      // Make sure the results are valid at least up to the most recent block
1660      // the user could have gotten from another RPC command prior to now
1661      wallet.BlockUntilSyncedToCurrentChain();
1662  
1663      // Unserialize the transaction
1664      PartiallySignedTransaction psbtx;
1665      std::string error;
1666      if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
1667          throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
1668      }
1669  
1670      // Get the sighash type
1671      std::optional<int> nHashType = ParseSighashString(request.params[2]);
1672  
1673      // Fill transaction with our data and also sign
1674      bool sign = request.params[1].isNull() ? true : request.params[1].get_bool();
1675      bool bip32derivs = request.params[3].isNull() ? true : request.params[3].get_bool();
1676      bool finalize = request.params[4].isNull() ? true : request.params[4].get_bool();
1677      bool complete = true;
1678  
1679      if (sign) EnsureWalletIsUnlocked(*pwallet);
1680  
1681      const auto err{wallet.FillPSBT(psbtx, complete, nHashType, sign, bip32derivs, nullptr, finalize)};
1682      if (err) {
1683          throw JSONRPCPSBTError(*err);
1684      }
1685  
1686      UniValue result(UniValue::VOBJ);
1687      DataStream ssTx{};
1688      ssTx << psbtx;
1689      result.pushKV("psbt", EncodeBase64(ssTx.str()));
1690      result.pushKV("complete", complete);
1691      if (complete) {
1692          CMutableTransaction mtx;
1693          // Returns true if complete, which we already think it is.
1694          CHECK_NONFATAL(FinalizeAndExtractPSBT(psbtx, mtx));
1695          DataStream ssTx_final;
1696          ssTx_final << TX_WITH_WITNESS(mtx);
1697          result.pushKV("hex", HexStr(ssTx_final));
1698      }
1699  
1700      return result;
1701  },
1702      };
1703  }
1704  
1705  RPCHelpMan walletcreatefundedpsbt()
1706  {
1707      return RPCHelpMan{
1708          "walletcreatefundedpsbt",
1709          "Creates and funds a transaction in the Partially Signed Transaction format.\n"
1710                  "Implements the Creator and Updater roles.\n"
1711                  "All existing inputs must either have their previous output transaction be in the wallet\n"
1712                  "or be in the UTXO set. Solving data must be provided for non-wallet inputs.\n",
1713                  {
1714                      {"inputs", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "Leave empty to add inputs automatically. See add_inputs option.",
1715                          {
1716                              {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "",
1717                                  {
1718                                      {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
1719                                      {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},
1720                                      {"sequence", RPCArg::Type::NUM, RPCArg::DefaultHint{"depends on the value of the 'locktime' and 'options.replaceable' arguments"}, "The sequence number"},
1721                                      {"weight", RPCArg::Type::NUM, RPCArg::DefaultHint{"Calculated from wallet and solving data"}, "The maximum weight for this input, "
1722                                          "including the weight of the outpoint and sequence number. "
1723                                          "Note that signature sizes are not guaranteed to be consistent, "
1724                                          "so the maximum DER signatures size of 73 bytes should be used when considering ECDSA signatures."
1725                                          "Remember to convert serialized sizes to weight units when necessary."},
1726                                  },
1727                              },
1728                          },
1729                          },
1730                      {"outputs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The outputs specified as key-value pairs.\n"
1731                              "Each key may only appear once, i.e. there can only be one 'data' output, and no address may be duplicated.\n"
1732                              "At least one output of either type must be specified.\n"
1733                              "For compatibility reasons, a dictionary, which holds the key-value pairs directly, is also\n"
1734                              "accepted as second parameter.",
1735                          OutputsDoc(),
1736                          RPCArgOptions{.skip_type_check = true}},
1737                      {"locktime", RPCArg::Type::NUM, RPCArg::Default{0}, "Raw locktime. Non-0 value also locktime-activates inputs"},
1738                      {"options", RPCArg::Type::OBJ_NAMED_PARAMS, RPCArg::Optional::OMITTED, "",
1739                          Cat<std::vector<RPCArg>>(
1740                          {
1741                              {"add_inputs", RPCArg::Type::BOOL, RPCArg::DefaultHint{"false when \"inputs\" are specified, true otherwise"}, "Automatically include coins from the wallet to cover the target amount.\n"},
1742                              {"include_unsafe", RPCArg::Type::BOOL, RPCArg::Default{false}, "Include inputs that are not safe to spend (unconfirmed transactions from outside keys and unconfirmed replacement transactions).\n"
1743                                                            "Warning: the resulting transaction may become invalid if one of the unsafe inputs disappears.\n"
1744                                                            "If that happens, you will need to fund the transaction with different inputs and republish it."},
1745                              {"minconf", RPCArg::Type::NUM, RPCArg::Default{0}, "If add_inputs is specified, require inputs with at least this many confirmations."},
1746                              {"maxconf", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "If add_inputs is specified, require inputs with at most this many confirmations."},
1747                              {"changeAddress", RPCArg::Type::STR, RPCArg::DefaultHint{"automatic"}, "The bitcoin address to receive the change"},
1748                              {"changePosition", RPCArg::Type::NUM, RPCArg::DefaultHint{"random"}, "The index of the change output"},
1749                              {"change_type", RPCArg::Type::STR, RPCArg::DefaultHint{"set by -changetype"}, "The output type to use. Only valid if changeAddress is not specified. Options are " + FormatAllOutputTypes() + "."},
1750                              {"includeWatching", RPCArg::Type::BOOL, RPCArg::Default{false}, "(DEPRECATED) No longer used"},
1751                              {"lockUnspents", RPCArg::Type::BOOL, RPCArg::Default{false}, "Lock selected unspent outputs"},
1752                              {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."},
1753                              {"feeRate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_UNIT + "/kvB."},
1754                              {"subtractFeeFromOutputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "The outputs to subtract the fee from.\n"
1755                                                            "The fee will be equally deducted from the amount of each specified output.\n"
1756                                                            "Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
1757                                                            "If no outputs are specified here, the sender pays the fee.",
1758                                  {
1759                                      {"vout_index", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The zero-based output index, before a change output is added."},
1760                                  },
1761                              },
1762                              {"max_tx_weight", RPCArg::Type::NUM, RPCArg::Default{MAX_STANDARD_TX_WEIGHT}, "The maximum acceptable transaction weight.\n"
1763                                                            "Transaction building will fail if this can not be satisfied."},
1764                          },
1765                          FundTxDoc()),
1766                          RPCArgOptions{.oneline_description="options"}},
1767                      {"bip32derivs", RPCArg::Type::BOOL, RPCArg::Default{true}, "Include BIP 32 derivation paths for public keys if we know them"},
1768                      {"version", RPCArg::Type::NUM, RPCArg::Default{DEFAULT_WALLET_TX_VERSION}, "Transaction version"},
1769                  },
1770                  RPCResult{
1771                      RPCResult::Type::OBJ, "", "",
1772                      {
1773                          {RPCResult::Type::STR, "psbt", "The resulting raw transaction (base64-encoded string)"},
1774                          {RPCResult::Type::STR_AMOUNT, "fee", "Fee in " + CURRENCY_UNIT + " the resulting transaction pays"},
1775                          {RPCResult::Type::NUM, "changepos", "The position of the added change output, or -1"},
1776                      }
1777                                  },
1778                                  RPCExamples{
1779                              "\nCreate a PSBT with automatically picked inputs that sends 0.5 BTC to an address and has a fee rate of 2 sat/vB:\n"
1780                              + HelpExampleCli("walletcreatefundedpsbt", "\"[]\" \"[{\\\"" + EXAMPLE_ADDRESS[0] + "\\\":0.5}]\" 0 \"{\\\"add_inputs\\\":true,\\\"fee_rate\\\":2}\"")
1781                              + "\nCreate the same PSBT as the above one instead using named arguments:\n"
1782                              + HelpExampleCli("-named walletcreatefundedpsbt", "outputs=\"[{\\\"" + EXAMPLE_ADDRESS[0] + "\\\":0.5}]\" add_inputs=true fee_rate=2")
1783                                  },
1784          [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1785  {
1786      std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
1787      if (!pwallet) return UniValue::VNULL;
1788  
1789      CWallet& wallet{*pwallet};
1790      // Make sure the results are valid at least up to the most recent block
1791      // the user could have gotten from another RPC command prior to now
1792      wallet.BlockUntilSyncedToCurrentChain();
1793  
1794      UniValue options{request.params[3].isNull() ? UniValue::VOBJ : request.params[3]};
1795  
1796      CCoinControl coin_control;
1797      coin_control.m_version = self.Arg<uint32_t>("version");
1798  
1799      const UniValue &replaceable_arg = options["replaceable"];
1800      const bool rbf{replaceable_arg.isNull() ? wallet.m_signal_rbf : replaceable_arg.get_bool()};
1801      CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf, coin_control.m_version);
1802      UniValue outputs(UniValue::VOBJ);
1803      outputs = NormalizeOutputs(request.params[1]);
1804      std::vector<CRecipient> recipients = CreateRecipients(
1805              ParseOutputs(outputs),
1806              InterpretSubtractFeeFromOutputInstructions(options["subtractFeeFromOutputs"], outputs.getKeys())
1807      );
1808      // Automatically select coins, unless at least one is manually selected. Can
1809      // be overridden by options.add_inputs.
1810      coin_control.m_allow_other_inputs = rawTx.vin.size() == 0;
1811      SetOptionsInputWeights(request.params[0], options);
1812      // Clear tx.vout since it is not meant to be used now that we are passing outputs directly.
1813      // This sets us up for a future PR to completely remove tx from the function signature in favor of passing inputs directly
1814      rawTx.vout.clear();
1815      auto txr = FundTransaction(wallet, rawTx, recipients, options, coin_control, /*override_min_fee=*/true);
1816  
1817      // Make a blank psbt
1818      PartiallySignedTransaction psbtx(CMutableTransaction(*txr.tx));
1819  
1820      // Fill transaction with out data but don't sign
1821      bool bip32derivs = request.params[4].isNull() ? true : request.params[4].get_bool();
1822      bool complete = true;
1823      const auto err{wallet.FillPSBT(psbtx, complete, std::nullopt, /*sign=*/false, /*bip32derivs=*/bip32derivs)};
1824      if (err) {
1825          throw JSONRPCPSBTError(*err);
1826      }
1827  
1828      // Serialize the PSBT
1829      DataStream ssTx{};
1830      ssTx << psbtx;
1831  
1832      UniValue result(UniValue::VOBJ);
1833      result.pushKV("psbt", EncodeBase64(ssTx.str()));
1834      result.pushKV("fee", ValueFromAmount(txr.fee));
1835      result.pushKV("changepos", txr.change_pos ? (int)*txr.change_pos : -1);
1836      return result;
1837  },
1838      };
1839  }
1840  } // namespace wallet