{
 "number": 36539,
 "repo": "bitcoin/bitcoin",
 "url": "https://github.com/bitcoin/bitcoin/pull/36539",
 "title": "gui: Use PSBT v0",
 "author": "davidgumberg",
 "author_association": "MEMBER",
 "created_at": "2026-10-15T08:18:12Z",
 "updated_at": "2026-10-31T00:29:14Z",
 "description_hash": "74da3b758d23c15b",
 "age_days": 17,
 "draft": false,
 "labels": [
  "GUI",
  "Needs Backport (32.x)"
 ],
 "milestone": "32.2",
 "base": "master",
 "head_sha": "3fdc45d1fa2a6f32f251aa6f639a52bbfd5245b0",
 "head_ref": "2026-10-15-psbt-gui",
 "head_repo": "davidgumberg/bitcoin",
 "head_history": [
  {
   "t": "2026-10-18T22:58:05Z",
   "sha": "f0777e68550cc100ab0341515c5c34bac45fc7a4"
  },
  {
   "t": "2026-10-26T16:22:26Z",
   "sha": "f87dd183b955823cf50f971452555de5fecea3c6"
  },
  {
   "t": "2026-10-26T16:26:16Z",
   "sha": "3fdc45d1fa2a6f32f251aa6f639a52bbfd5245b0"
  }
 ],
 "additions": 24,
 "deletions": 10,
 "changed_files": 8,
 "commit_count": 2,
 "size_bucket": "S",
 "mergeable_state": "clean",
 "bot": {
  "drahtbot": {
   "present": true,
   "reviews": {
    "ack": [
     {
      "login": "Sjors",
      "url": "https://github.com/bitcoin/bitcoin/pull/36539#issuecomment-6441810241"
     },
     {
      "login": "w0xlt",
      "url": "https://github.com/bitcoin/bitcoin/pull/36539#pullrequestreview-5673480077"
     }
    ]
   },
   "conflicts": []
  }
 },
 "acks_parsed": {
  "Sjors": {
   "kind": "ack",
   "hash": "3fdc45d1fa2a6f32f251aa6f639a52bbfd5245b0",
   "t": "2026-10-27T12:24:44Z",
   "stale": false
  },
  "w0xlt": {
   "kind": "ack",
   "hash": "3fdc45d1fa2a6f32f251aa6f639a52bbfd5245b0",
   "t": "2026-10-27T19:59:51Z",
   "stale": false
  }
 },
 "acks_tally": {
  "ack": 2,
  "stale_ack": 0,
  "concept_ack": 0,
  "approach_ack": 0,
  "nack": 0,
  "concept_nack": 0,
  "approach_nack": 0
 },
 "reviews": {
  "approved": 0,
  "changes_requested": 0,
  "distinct_reviewers": [
   "Sjors",
   "achow101",
   "fanquake",
   "hebasto",
   "w0xlt"
  ]
 },
 "signals": {
  "needs_rebase": false,
  "ci_failed": false,
  "mergeable_state": "clean",
  "last_author_activity": "2026-10-26T16:27:19Z",
  "last_reviewer_activity": "2026-10-27T19:59:51Z",
  "last_reviewer": "w0xlt",
  "author_silent_days": 6,
  "waiting_on_author_days": 5,
  "days_since_update": 2
 },
 "refs": {
  "mentioned": [],
  "depends_on": [],
  "fixes": [],
  "linked_issues": [],
  "references": [],
  "conflicts": []
 },
 "stack": {
  "shares_commits_with": [],
  "based_on": [],
  "base_for": []
 },
 "review_paths": [
  "src/wallet/feebumper.cpp"
 ],
 "body": "This fixes: https://github.com/bitcoin/bitcoin/issues/36518\n\nThere is no test added here for the bump fee PSBT's being v0, since there aren't any existing tests for watch only wallet feebumping in the GUI. If reviewers insist on this I can add it, but I wanted to keep the diff minimal. I have tested this manually.\n\nAFAIU for the external signer stuff it shouldn't matter much whether it's v0 or v2, since users are very unlikely to be using HWI software that doesn't speak v0, but out of caution I've set the external signer PSBT to v0 for the GUI.\n\n_This PR originally took the approach of adding a checkbox, ([davidgumberg/gui/2026-10-15-psbt-gui](https://github.com/davidgumberg/gui/tree/2026-10-15-psbt-gui)), but this was dropped to simplify backporting past string freeze._\n\n_LLM Disclosure: The previous approach was drafted using an LLM, but this branch was written by me. I used an LLM to explore adding a fee bump watchonly GUI test, and decided against it._",
 "commits": [
  {
   "sha": "23dcb03a2c6b9fed84896ac4d751ba9e8034a6bf",
   "date": "2026-10-26T16:26:03Z",
   "message": "gui: wallet: Use v0 PSBT\n\nPSBTv2 is not very interesting for current GUI users, and defaulting to\nit causes issues for existing users. To make this change minimal and\navoid touching strings, this commit, only changes the default back\ninstead of making the version configurable.\n\nThe external signer PSBT will still be version 2, and I've added an\nexplicit argument here to show that. This will break users who are using\nHWI versions < 2.1.0.\n(https://github.com/bitcoin-core/HWI/releases/tag/2.1.0)"
  },
  {
   "sha": "3fdc45d1fa2a6f32f251aa6f639a52bbfd5245b0",
   "date": "2026-10-26T16:26:03Z",
   "message": "refactor: psbt: Don't set a default version for PSBT constructor"
  }
 ],
 "timeline": [
  {
   "t": "2026-10-16T00:53:14Z",
   "kind": "comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "text": "@achow101 @polespinasa",
   "id": "c:6205516345",
   "url": "https://github.com/bitcoin/bitcoin/pull/36539#issuecomment-6205516345",
   "hash": "528756f6321282a4",
   "edited": null
  },
  {
   "t": "2026-10-16T01:12:45Z",
   "kind": "comment",
   "who": "achow101",
   "assoc": "MEMBER",
   "text": "I don't think we should be adding any GUI elements for a PR targeting a backport, particularly as it adds strings for translation. We can do v0 only in the GUI I guess.",
   "id": "c:6205749329",
   "url": "https://github.com/bitcoin/bitcoin/pull/36539#issuecomment-6205749329",
   "hash": "dc93be201dac4ed0",
   "edited": null
  },
  {
   "t": "2026-10-16T04:45:23Z",
   "kind": "comment",
   "who": "fanquake",
   "assoc": "MEMBER",
   "text": "cc @hebasto",
   "id": "c:6208279333",
   "url": "https://github.com/bitcoin/bitcoin/pull/36539#issuecomment-6208279333",
   "hash": "753e1355e5d90af8",
   "edited": null
  },
  {
   "t": "2026-10-17T08:13:27Z",
   "kind": "comment",
   "who": "Sjors",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nThat seems fine for now if it's easier. There could be a (release) note to use the RPC for v2 when needed.",
   "id": "c:6231604993",
   "url": "https://github.com/bitcoin/bitcoin/pull/36539#issuecomment-6231604993",
   "hash": "6d0e4fbaf805d77e",
   "edited": null
  },
  {
   "t": "2026-10-18T22:58:05Z",
   "kind": "force_push",
   "who": "davidgumberg",
   "commit": "f0777e68550cc100ab0341515c5c34bac45fc7a4",
   "id": "push:f0777e68550cc100ab0341515c5c34bac45fc7a4"
  },
  {
   "t": "2026-10-18T23:11:00Z",
   "kind": "comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "text": "I've pushed so that the GUI just returns v0 PSBT's.",
   "id": "c:6256342443",
   "url": "https://github.com/bitcoin/bitcoin/pull/36539#issuecomment-6256342443",
   "hash": "71cd780d6a2a90eb",
   "edited": null
  },
  {
   "t": "2026-10-20T02:41:25Z",
   "kind": "comment",
   "who": "Sjors",
   "assoc": "MEMBER",
   "text": "Code review f0777e68550cc100ab0341515c5c34bac45fc7a4.\n\n[quoted text omitted]\nI think it's better to consistently use v2 for external signers, both from the GUI and RPC.",
   "id": "c:6282081305",
   "url": "https://github.com/bitcoin/bitcoin/pull/36539#issuecomment-6282081305",
   "hash": "0aaf32398dbf8134",
   "edited": null
  },
  {
   "t": "2026-10-20T02:43:00Z",
   "kind": "review_comment",
   "who": "Sjors",
   "assoc": "MEMBER",
   "path": "src/wallet/feebumper.cpp",
   "commit": "3fdc45d1fa2a6f32f251aa6f639a52bbfd5245b0",
   "in_reply_to": null,
   "text": "You can use the same comment in the regular send path, if you take my suggestion above.",
   "id": "rc:4320941030",
   "url": "https://github.com/bitcoin/bitcoin/pull/36539#discussion_r4320941030",
   "hash": "5e0b288c1487cafc",
   "edited": null
  },
  {
   "t": "2026-10-20T17:15:12Z",
   "kind": "comment",
   "who": "w0xlt",
   "assoc": "CONTRIBUTOR",
   "text": "The GUI fee bump with an external signer still uses v2 (`WalletModel::bumpFee` -> `signBumpTransaction` -> `feebumper::SignTransaction`, pinned to v2 and shared with RPC `bumpfee`).\n\nSuggestion: a `psbt_version` param can be added to `feebumper::SignTransaction/signBumpTransaction`, with the GUI passing 0 and RPC keeping 2.\n\ndiff\n\n```diff\ndiff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h\nindex 8862f94fab..da140f721e 100644\n--- a/src/interfaces/wallet.h\n+++ b/src/interfaces/wallet.h\n@@ -175,7 +175,7 @@ public:\n         CMutableTransaction& mtx) = 0;\n\n     //! Sign bump transaction.\n-    virtual bool signBumpTransaction(CMutableTransaction& mtx) = 0;\n+    virtual bool signBumpTransaction(CMutableTransaction& mtx, uint32_t psbt_version) = 0;\n\n     //! Commit bump transaction.\n     virtual bool commitBumpTransaction(const Txid& txid,\ndiff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp\nindex 2422b88579..95454e2265 100644\n--- a/src/qt/walletmodel.cpp\n+++ b/src/qt/walletmodel.cpp\n@@ -524,7 +524,7 @@ bool WalletModel::bumpFee(Txid hash, Txid& new_hash)\n     assert(!m_wallet->privateKeysDisabled() || wallet().hasExternalSigner());\n\n     // sign bumped transaction\n-    if (!m_wallet->signBumpTransaction(mtx)) {\n+    if (!m_wallet->signBumpTransaction(mtx, /*psbt_version=*/0)) {\n         QMessageBox::critical(nullptr, tr(\"Fee bump error\"), tr(\"Can't sign transaction.\"));\n         return false;\n     }\ndiff --git a/src/wallet/feebumper.cpp b/src/wallet/feebumper.cpp\nindex ab64fd8cda..1c7288aedd 100644\n--- a/src/wallet/feebumper.cpp\n+++ b/src/wallet/feebumper.cpp\n@@ -336,13 +336,12 @@ Result CreateRateBumpTransaction(CWallet& wallet, const Txid& txid, const CCoinC\n     return Result::OK;\n }\n\n-bool SignTransaction(CWallet& wallet, CMutableTransaction& mtx) {\n+bool SignTransaction(CWallet& wallet, CMutableTransaction& mtx, uint32_t psbt_version) {\n     LOCK(wallet.cs_wallet);\n\n     if (wallet.IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER)) {\n-        // Make a blank PSBT, this means that users will need to have an\n-        // external signer software that supports BIP-0370.\n-        PartiallySignedTransaction psbtx(mtx, /*version=*/2);\n+        // Make a blank psbt\n+        PartiallySignedTransaction psbtx(mtx, psbt_version);\n\n         // First fill transaction with our data without signing,\n         // so external signers are not asked to sign more than once.\ndiff --git a/src/wallet/feebumper.h b/src/wallet/feebumper.h\nindex 4e0befe412..62faea52af 100644\n--- a/src/wallet/feebumper.h\n+++ b/src/wallet/feebumper.h\n@@ -58,9 +58,10 @@ Result CreateRateBumpTransaction(CWallet& wallet,\n     std::optional<uint32_t> original_change_index = std::nullopt);\n\n //! Sign the new transaction,\n+//! @param psbt_version PSBT version passed to an external signer, if the wallet uses one\n //! @return false if the tx couldn't be found or if it was\n //! impossible to create the signature(s)\n-bool SignTransaction(CWallet& wallet, CMutableTransaction& mtx);\n+bool SignTransaction(CWallet& wallet, CMutableTransaction& mtx, uint32_t psbt_version);\n\n //! Commit the bumpfee transaction.\n //! @return success in case of CWallet::CommitTransaction was successful,\ndiff --git a/src/wallet/interfaces.cpp b/src/wallet/interfaces.cpp\nindex a7d24ca0b9..3a70e88c3a 100644\n--- a/src/wallet/interfaces.cpp\n+++ b/src/wallet/interfaces.cpp\n@@ -300,7 +300,7 @@ public:\n         std::vector<CTxOut> outputs; // just an empty list of new recipients for now\n         return feebumper::CreateRateBumpTransaction(*m_wallet.get(), txid, coin_control, errors, old_fee, new_fee, mtx, /* require_mine= */ true, outputs) == feebumper::Result::OK;\n     }\n-    bool signBumpTransaction(CMutableTransaction& mtx) override { return feebumper::SignTransaction(*m_wallet.get(), mtx); }\n+    bool signBumpTransaction(CMutableTransaction& mtx, uint32_t psbt_version) override { return feebumper::SignTransaction(*m_wallet.get(), mtx, psbt_version); }\n     bool commitBumpTransaction(const Txid& txid,\n         CMutableTransaction&& mtx,\n         std::vector<bilingual_str>& errors,\ndiff --git a/src/wallet/rpc/spend.cpp b/src/wallet/rpc/spend.cpp\nindex e228298c0c..9de3464675 100644\n--- a/src/wallet/rpc/spend.cpp\n+++ b/src/wallet/rpc/spend.cpp\n@@ -1138,7 +1138,8 @@ static RPCMethod bumpfee_helper(std::string method_name)\n     // For bumpfee, return the new transaction id.\n     // For psbtbumpfee, return the base64-encoded unsigned PSBT of the new transaction.\n     if (!want_psbt) {\n-        if (!feebumper::SignTransaction(*pwallet, mtx)) {\n+        // External signers must support BIP-0370 (PSBT v2)\n+        if (!feebumper::SignTransaction(*pwallet, mtx, /*psbt_version=*/2)) {\n             if (pwallet->IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER)) {\n                 throw JSONRPCError(RPC_WALLET_ERROR, \"Transaction incomplete. Try psbtbumpfee instead.\");\n             }\n```",
   "id": "c:6296730894",
   "url": "https://github.com/bitcoin/bitcoin/pull/36539#issuecomment-6296730894",
   "hash": "7245c1f35de90393",
   "edited": null
  },
  {
   "t": "2026-10-21T11:07:00Z",
   "kind": "comment",
   "who": "fanquake",
   "assoc": "MEMBER",
   "text": "Pushed this to the `32.1` milestone.",
   "id": "c:6314422168",
   "url": "https://github.com/bitcoin/bitcoin/pull/36539#issuecomment-6314422168",
   "hash": "7f7bce2e2be70f12",
   "edited": null
  },
  {
   "t": "2026-10-26T16:22:26Z",
   "kind": "force_push",
   "who": "davidgumberg",
   "commit": "f87dd183b955823cf50f971452555de5fecea3c6",
   "id": "push:f87dd183b955823cf50f971452555de5fecea3c6"
  },
  {
   "t": "2026-10-26T16:26:16Z",
   "kind": "force_push",
   "who": "davidgumberg",
   "commit": "3fdc45d1fa2a6f32f251aa6f639a52bbfd5245b0",
   "id": "push:3fdc45d1fa2a6f32f251aa6f639a52bbfd5245b0"
  },
  {
   "t": "2026-10-26T16:26:56Z",
   "kind": "comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "text": "I've modified this so that the external signer PSBT's are v2, this breaks support with external signer software that doesn't know about v2, which is quite reasonable I think, so I've added a release note about that.",
   "id": "c:6421305322",
   "url": "https://github.com/bitcoin/bitcoin/pull/36539#issuecomment-6421305322",
   "hash": "2d1c853b47e4124a",
   "edited": null
  },
  {
   "t": "2026-10-26T16:27:19Z",
   "kind": "review_comment",
   "who": "davidgumberg",
   "assoc": "MEMBER",
   "path": "src/wallet/feebumper.cpp",
   "commit": "3fdc45d1fa2a6f32f251aa6f639a52bbfd5245b0",
   "in_reply_to": 4320941030,
   "text": "Taken, thanks",
   "id": "rc:4379746946",
   "url": "https://github.com/bitcoin/bitcoin/pull/36539#discussion_r4379746946",
   "hash": "fcfd14819af49631",
   "edited": "2026-10-26T16:27:20Z"
  },
  {
   "t": "2026-10-27T12:24:44Z",
   "kind": "comment",
   "who": "Sjors",
   "assoc": "MEMBER",
   "text": "ACK 3fdc45d1fa2a6f32f251aa6f639a52bbfd5245b0\n\nSadly we missed the 32.1 milestone, time flies.",
   "id": "c:6441810241",
   "url": "https://github.com/bitcoin/bitcoin/pull/36539#issuecomment-6441810241",
   "hash": "0004661936563196",
   "edited": "2026-10-27T12:25:07Z"
  },
  {
   "t": "2026-10-27T13:57:44Z",
   "kind": "comment",
   "who": "hebasto",
   "assoc": "MEMBER",
   "text": "I've re-run previously cancelled CI jobs.",
   "id": "c:6443797831",
   "url": "https://github.com/bitcoin/bitcoin/pull/36539#issuecomment-6443797831",
   "hash": "3a6955a2721ad02d",
   "edited": null
  },
  {
   "t": "2026-10-27T19:59:51Z",
   "kind": "review",
   "who": "w0xlt",
   "assoc": "CONTRIBUTOR",
   "state": "COMMENTED",
   "commit": "3fdc45d1fa2a6f32f251aa6f639a52bbfd5245b0",
   "text": "crACK 3fdc45d1fa2a6f32f251aa6f639a52bbfd5245b0",
   "id": "r:5673480077",
   "url": "https://github.com/bitcoin/bitcoin/pull/36539#pullrequestreview-5673480077",
   "hash": "1394590b0a4ea217",
   "edited": null
  }
 ],
 "labels_log": [
  {
   "t": "2026-10-15T08:18:16Z",
   "action": "labeled",
   "label": "GUI",
   "who": "DrahtBot"
  },
  {
   "t": "2026-10-21T11:06:30Z",
   "action": "labeled",
   "label": "Needs Backport (32.x)",
   "who": "fanquake"
  },
  {
   "t": "2026-10-26T16:27:32Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-10-27T14:57:31Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  }
 ],
 "state_log": [
  {
   "t": "2026-10-15T08:18:30Z",
   "kind": "milestoned",
   "who": "fanquake"
  },
  {
   "t": "2026-10-18T22:58:35Z",
   "kind": "renamed",
   "who": "davidgumberg",
   "from": "gui: Make PSBT version toggleable: v0 by default",
   "to": "gui: Use PSBT v0"
  },
  {
   "t": "2026-10-21T11:06:23Z",
   "kind": "demilestoned",
   "who": "fanquake"
  },
  {
   "t": "2026-10-21T11:06:23Z",
   "kind": "milestoned",
   "who": "fanquake"
  },
  {
   "t": "2026-10-26T10:50:02Z",
   "kind": "demilestoned",
   "who": "fanquake"
  },
  {
   "t": "2026-10-26T10:50:02Z",
   "kind": "milestoned",
   "who": "fanquake"
  }
 ],
 "text_chars": 7534,
 "text_tokens_estimate": 1883,
 "changed_paths": [
  "doc/release-notes-hwi-minver.md",
  "src/psbt.h",
  "src/qt/sendcoinsdialog.cpp",
  "src/qt/test/wallettests.cpp",
  "src/qt/walletmodel.cpp",
  "src/test/fuzz/psbt.cpp",
  "src/test/psbt_tests.cpp",
  "src/wallet/feebumper.cpp"
 ],
 "files": [
  {
   "path": "doc/release-notes-hwi-minver.md",
   "add": 10,
   "del": 0
  },
  {
   "path": "src/psbt.h",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/qt/sendcoinsdialog.cpp",
   "add": 4,
   "del": 2
  },
  {
   "path": "src/qt/test/wallettests.cpp",
   "add": 1,
   "del": 0
  },
  {
   "path": "src/qt/walletmodel.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/fuzz/psbt.cpp",
   "add": 1,
   "del": 1
  },
  {
   "path": "src/test/psbt_tests.cpp",
   "add": 3,
   "del": 3
  },
  {
   "path": "src/wallet/feebumper.cpp",
   "add": 3,
   "del": 2
  }
 ],
 "test_lines": 9,
 "git": {
  "head": "3fdc45d1fa2a6f32f251aa6f639a52bbfd5245b0",
  "head_matches_backup": true,
  "base": "89a3a13c44e85c6e32ac54444fdf5e07886842e8",
  "patch_id": "fa5e3d29fd93a5a8",
  "commits": [
   {
    "sha": "23dcb03a2c",
    "subject": "gui: wallet: Use v0 PSBT",
    "files": 4,
    "add": 16,
    "del": 3
   },
   {
    "sha": "3fdc45d1fa",
    "subject": "refactor: psbt: Don't set a default version for PSBT constructor",
    "files": 4,
    "add": 8,
    "del": 7
   }
  ],
  "patch_truncated": false
 },
 "patch_id": "fa5e3d29fd93a5a8",
 "input_hash": "3ec085688a852087",
 "extracted_at": "2026-11-02T01:09:49+00:00"
}