wallet: rpc: Add snake_case aliases for wallet funding options #36489

pull maflcko wants to merge 2 commits into bitcoin:master from maflcko:2610-rpc-wallet-fund-alias-snake-case changing 7 files +54 −18
  1. maflcko commented at 11:35 AM on October 9, 2026: member

    The options for wallet funding RPCs have several issues:

    • snake_case aliases are accepted by the server, but unsupported by bitcoin-cli, not mentioned in the docs and rejected by the schema.
    • If both the snake_case and camelCase are provided, the camelCase is silently ignored.
    • The server silently ignores subtract_fee_from_outputs. (reported by stutxo in #35317)

    Fix all issues, by:

    • Adding the snake_case aliases to the CLI, docs and the schema.
    • Rejecting if both are supplied.
    • Reading subtract_fee_from_outputs instead of silently ignoring it.
  2. DrahtBot added the label Wallet on Oct 9, 2026
  3. DrahtBot commented at 11:36 AM on October 9, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--006a51241073e994b41acfe9ec718e94-->

    External sites

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline and AI policy for information on the review process.

    Type Reviewers
    ACK Conradgabe
    Concept ACK psychemist, kevkevinpal

    If your review is incorrectly listed, please copy-paste <code>&lt;!--meta-tag:bot-skip--&gt;</code> into the comment that the bot should ignore.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #36257 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/36257.svg"></sub> (qa: assert_equals -> assert_true/assert_false by hodlinator)
    • #35302 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/35302.svg"></sub> (Silent Payments: Sending (take 2) by Eunovo)
    • #32857 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/32857.svg"></sub> (wallet: allow skipping script paths by Sjors)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  4. maflcko force-pushed on Oct 9, 2026
  5. DrahtBot added the label CI failed on Oct 9, 2026
  6. wallet: rpc: Add snake_case aliases for wallet funding options fac8ef10f4
  7. test: Use new named arg aliases in tests
    With the prior commit reverted, the tests here would all fail with
    (-8) Unknown named parameter ...
    faeb073ca6
  8. maflcko force-pushed on Oct 9, 2026
  9. maflcko commented at 1:22 PM on October 9, 2026: member

    The redered diff:

    <details><summary>schema and doc diff</summary>

    diff --git a/fundrawtransaction b/fundrawtransaction
    index fa5e2a7..e0dff59 100644
    --- a/fundrawtransaction
    +++ b/fundrawtransaction
    @@ -2,7 +2,7 @@ fundrawtransaction "hexstring" ( options iswitness )
     
     If the transaction has no inputs, they will be automatically selected to meet its out value.
     It will add at most one change output to the outputs.
    -No existing outputs will be modified unless "subtractFeeFromOutputs" is specified.
    +No existing outputs will be modified unless "subtract_fee_from_outputs" is specified.
     Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.
     The inputs added will not be signed, use signrawtransactionwithkey
     or signrawtransactionwithwallet for that.
    @@ -32,14 +32,14 @@ include_unsafe             (boolean, optional, default=false) Include inputs tha
                                  If that happens, you will need to fund the transaction with different inputs and republish it.
     minconf                      (numeric, optional, default=0) If add_inputs is specified, require inputs with at least this many confirmations.
     maxconf                      (numeric, optional) If add_inputs is specified, require inputs with at most this many confirmations.
    -changeAddress              (string, optional, default=automatic) The bitcoin address to receive the change
    -changePosition             (numeric, optional, default=random) The index of the change output
    +change_address               (string, optional, default=automatic) The bitcoin address to receive the change
    +change_position              (numeric, optional, default=random) The index of the change output
     change_type                  (string, optional, default=set by -changetype) The output type to use. Only valid if changeAddress is not specified. Options are "legacy", "p2sh-segwit", "bech32", "bech32m".
     includeWatching              (boolean, optional, default=false) (DEPRECATED) No longer used
    -lockUnspents               (boolean, optional, default=false) Lock selected unspent outputs
    +lock_unspents                (boolean, optional, default=false) Lock selected unspent outputs
     fee_rate                     (numeric or string, optional, default=not set, fall back to wallet fee estimation) Specify a fee rate in sat/vB.
     feeRate                      (numeric or string, optional, default=not set, fall back to wallet fee estimation) Specify a fee rate in BTC/kvB.
    -subtractFeeFromOutputs     (json array, optional, default=[]) The integers.
    +subtract_fee_from_outputs    (json array, optional, default=[]) The output indices to subtract the fee from.
                                  The fee will be equally deducted from the amount of each specified output.
                                  Those recipients will receive less bitcoins than you enter in their corresponding amount field.
                                  If no outputs are specified here, the sender pays the fee.
    diff --git a/getopenrpcinfo.full.json b/getopenrpcinfo.full.json
    index 4524013..ad0d73d 100644
    --- a/getopenrpcinfo.full.json
    +++ b/getopenrpcinfo.full.json
    @@ -3120,7 +3120,7 @@
             },
             {
                 "name": "fundrawtransaction",
    -            "description": "If the transaction has no inputs, they will be automatically selected to meet its out value.\nIt will add at most one change output to the outputs.\nNo existing outputs will be modified unless \"subtractFeeFromOutputs\" is specified.\nNote that inputs which were signed may need to be resigned after completion since in/outputs have been added.\nThe inputs added will not be signed, use signrawtransactionwithkey\nor signrawtransactionwithwallet for that.\nAll existing inputs must either have their previous output transaction be in the wallet\nor be in the UTXO set. Solving data must be provided for non-wallet inputs.\nNote that all inputs selected must be of standard form and P2SH scripts must be\nin the wallet using importdescriptors (to calculate fees).\nYou can see whether this is the case by checking the \"solvable\" field in the listunspent output.\nNote that if specifying an exact fee rate, the resulting transaction may have a higher fee rate\nif the transaction has unconfirmed inputs. This is because the wallet will attempt to make the\nentire package have the given fee rate, not the resulting transaction.",
    +            "description": "If the transaction has no inputs, they will be automatically selected to meet its out value.\nIt will add at most one change output to the outputs.\nNo existing outputs will be modified unless \"subtract_fee_from_outputs\" is specified.\nNote that inputs which were signed may need to be resigned after completion since in/outputs have been added.\nThe inputs added will not be signed, use signrawtransactionwithkey\nor signrawtransactionwithwallet for that.\nAll existing inputs must either have their previous output transaction be in the wallet\nor be in the UTXO set. Solving data must be provided for non-wallet inputs.\nNote that all inputs selected must be of standard form and P2SH scripts must be\nin the wallet using importdescriptors (to calculate fees).\nYou can see whether this is the case by checking the \"solvable\" field in the listunspent output.\nNote that if specifying an exact fee rate, the resulting transaction may have a higher fee rate\nif the transaction has unconfirmed inputs. This is because the wallet will attempt to make the\nentire package have the given fee rate, not the resulting transaction.",
                 "params": [
                     {
                         "name": "hexstring",
    @@ -3156,12 +3156,12 @@
                                     "type": "number",
                                     "description": "If add_inputs is specified, require inputs with at most this many confirmations."
                                 },
    -                            "changeAddress": {
    +                            "change_address": {
                                     "type": "string",
                                     "x-bitcoin-default-hint": "automatic",
                                     "description": "The bitcoin address to receive the change"
                                 },
    -                            "changePosition": {
    +                            "change_position": {
                                     "type": "number",
                                     "x-bitcoin-default-hint": "random",
                                     "description": "The index of the change output"
    @@ -3176,7 +3176,7 @@
                                     "default": false,
                                     "description": "(DEPRECATED) No longer used"
                                 },
    -                            "lockUnspents": {
    +                            "lock_unspents": {
                                     "type": "boolean",
                                     "default": false,
                                     "description": "Lock selected unspent outputs"
    @@ -3205,13 +3205,13 @@
                                     "x-bitcoin-default-hint": "not set, fall back to wallet fee estimation",
                                     "description": "Specify a fee rate in BTC/kvB."
                                 },
    -                            "subtractFeeFromOutputs": {
    +                            "subtract_fee_from_outputs": {
                                     "type": "array",
                                     "items": {
                                         "type": "number"
                                     },
                                     "default": [],
    -                                "description": "The integers.\nThe fee will be equally deducted from the amount of each specified output.\nThose recipients will receive less bitcoins than you enter in their corresponding amount field.\nIf no outputs are specified here, the sender pays the fee."
    +                                "description": "The output indices to subtract the fee from.\nThe fee will be equally deducted from the amount of each specified output.\nThose recipients will receive less bitcoins than you enter in their corresponding amount field.\nIf no outputs are specified here, the sender pays the fee."
                                 },
                                 "input_weights": {
                                     "type": "array",
    @@ -15380,12 +15380,12 @@
                                     "type": "number",
                                     "description": "If add_inputs is specified, require inputs with at most this many confirmations."
                                 },
    -                            "changeAddress": {
    +                            "change_address": {
                                     "type": "string",
                                     "x-bitcoin-default-hint": "automatic",
                                     "description": "The bitcoin address to receive the change"
                                 },
    -                            "changePosition": {
    +                            "change_position": {
                                     "type": "number",
                                     "x-bitcoin-default-hint": "random",
                                     "description": "The index of the change output"
    @@ -15400,7 +15400,7 @@
                                     "default": false,
                                     "description": "(DEPRECATED) No longer used"
                                 },
    -                            "lockUnspents": {
    +                            "lock_unspents": {
                                     "type": "boolean",
                                     "default": false,
                                     "description": "Lock selected unspent outputs"
    @@ -15429,7 +15429,7 @@
                                     "x-bitcoin-default-hint": "not set, fall back to wallet fee estimation",
                                     "description": "Specify a fee rate in BTC/kvB."
                                 },
    -                            "subtractFeeFromOutputs": {
    +                            "subtract_fee_from_outputs": {
                                     "type": "array",
                                     "items": {
                                         "type": "number"
    diff --git a/walletcreatefundedpsbt b/walletcreatefundedpsbt
    index f73e096..aee80c4 100644
    --- a/walletcreatefundedpsbt
    +++ b/walletcreatefundedpsbt
    @@ -46,14 +46,14 @@ include_unsafe             (boolean, optional, default=false) Include inputs tha
                                  If that happens, you will need to fund the transaction with different inputs and republish it.
     minconf                      (numeric, optional, default=0) If add_inputs is specified, require inputs with at least this many confirmations.
     maxconf                      (numeric, optional) If add_inputs is specified, require inputs with at most this many confirmations.
    -changeAddress              (string, optional, default=automatic) The bitcoin address to receive the change
    -changePosition             (numeric, optional, default=random) The index of the change output
    +change_address               (string, optional, default=automatic) The bitcoin address to receive the change
    +change_position              (numeric, optional, default=random) The index of the change output
     change_type                  (string, optional, default=set by -changetype) The output type to use. Only valid if changeAddress is not specified. Options are "legacy", "p2sh-segwit", "bech32", "bech32m".
     includeWatching              (boolean, optional, default=false) (DEPRECATED) No longer used
    -lockUnspents               (boolean, optional, default=false) Lock selected unspent outputs
    +lock_unspents                (boolean, optional, default=false) Lock selected unspent outputs
     fee_rate                     (numeric or string, optional, default=not set, fall back to wallet fee estimation) Specify a fee rate in sat/vB.
     feeRate                      (numeric or string, optional, default=not set, fall back to wallet fee estimation) Specify a fee rate in BTC/kvB.
    -subtractFeeFromOutputs     (json array, optional, default=[]) The outputs to subtract the fee from.
    +subtract_fee_from_outputs    (json array, optional, default=[]) The outputs to subtract the fee from.
                                  The fee will be equally deducted from the amount of each specified output.
                                  Those recipients will receive less bitcoins than you enter in their corresponding amount field.
                                  If no outputs are specified here, the sender pays the fee.
    

    </details>

  10. DrahtBot removed the label CI failed on Oct 9, 2026
  11. psychemist commented at 4:14 PM on October 9, 2026: none

    concept ACK

  12. in src/rpc/client.cpp:187 in faeb073ca6
     182 | @@ -183,11 +183,14 @@ static const CRPCConvertParam vRPCConvertParams[] =
     183 |      { "fundrawtransaction", 1, "minconf"},
     184 |      { "fundrawtransaction", 1, "maxconf"},
     185 |      { "fundrawtransaction", 1, "changePosition"},
     186 | +    { "fundrawtransaction", 1, "change_position"},
     187 |      { "fundrawtransaction", 1, "includeWatching"},
    


    kevkevinpal commented at 1:32 PM on October 10, 2026:

    is there any reason why we don't have a snake_case for includeWatching?


    kevkevinpal commented at 1:53 PM on October 10, 2026:

    Never mind I see includeWatching is marked deprecated

  13. in src/rpc/client.cpp:210 in faeb073ca6
     205 | @@ -203,11 +206,14 @@ static const CRPCConvertParam vRPCConvertParams[] =
     206 |      { "walletcreatefundedpsbt", 3, "minconf"},
     207 |      { "walletcreatefundedpsbt", 3, "maxconf"},
     208 |      { "walletcreatefundedpsbt", 3, "changePosition"},
     209 | +    { "walletcreatefundedpsbt", 3, "change_position"},
     210 |      { "walletcreatefundedpsbt", 3, "includeWatching"},
    


    kevkevinpal commented at 1:32 PM on October 10, 2026:

    is there any reason why we don't have a snake_case for includeWatching?


    kevkevinpal commented at 1:53 PM on October 10, 2026:

    Never mind I see includeWatching is marked deprecated

  14. in doc/release-notes-36489.md:1 in faeb073ca6


    kevkevinpal commented at 2:01 PM on October 10, 2026:

    Should we add in the release note that sending both camelCase and snake_case will now throw an error?

    For example change_address and changeAddress


    maflcko commented at 6:36 AM on October 12, 2026:

    I think that should be the obvious and expected behavior. No need to bloat the release notes with stuff that no user should be relying on.

  15. kevkevinpal commented at 2:01 PM on October 10, 2026: contributor

    Concept ACK

  16. Conradgabe commented at 9:20 AM on October 12, 2026: none

    tACK faeb073ca68348bc663c80b3f2b70d7014466b07

    i reproduced all 3 issues on master (05bc2f53ce), then verified the updates on regtest.

    on master subtract_fee_from_outputs is ignored, with PR the fee is subtracted from the output. PR errors "Do not set both" for CamelCase and snake case fields and bitcoin-cli -named walletcreatefundedpsbt ... change_position=0 lock_unspents=true works with the PR.

  17. DrahtBot requested review from kevkevinpal on Oct 12, 2026
  18. fametrano commented at 6:47 AM on October 25, 2026: none

    The schema now rejects changeAddress, changePosition, lockUnspents and subtractFeeFromOutputs, which the server still accepts.

    In getopenrpcinfo at faeb073ca68348bc663c80b3f2b70d7014466b07, the options object of fundrawtransaction and walletcreatefundedpsbt lists only the snake_case names, with additionalProperties: false. Nested properties carry no x-bitcoin-aliases. So the mismatch the description calls an issue is turned around, not removed: a client that validates against the schema refuses a camelCase request the server funds, and v32.0 shipped the camelCase names in this schema. Either the nested schema lists the aliases, or the camelCase names get a real deprecation, as #36488 does for confTarget. Today only the new error string calls them deprecated; the help and the release note do not.

    Two camelCase names remain in text a user reads. The change_type help still says "Only valid if changeAddress is not specified", and an out-of-range position still fails with "changePosition out of bounds".

    The rest matched. Without the change, subtract_fee_from_outputs was ignored and one spelling silently won when both were set. With it, all four options work in either spelling, in the options object, as named arguments and through bitcoin-cli -named, and setting both is rejected. I measured this on regtest against builds with and without this change, with calls sent through a client library I maintain. I can share the script and its output.

  19. maflcko commented at 9:13 AM on October 26, 2026: member

    The schema now rejects changeAddress, changePosition, lockUnspents and subtractFeeFromOutputs, which the server still accepts.

    Yes, I presume the schema rejecting the deprecated alias is intentional. This is the behavior before and after this pull request. (E.g. verbosity|verbose args behave the same before and after this pull). If the schema behavior should be changed, it should be done in a separate pull request, with a rationale and background for the change.


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-10-30 09:40 UTC