{
 "number": 36387,
 "repo": "bitcoin/bitcoin",
 "url": "https://github.com/bitcoin/bitcoin/pull/36387",
 "title": "wallet: rpc: Deprecate `encryptwallet` RPC for encrypting existing wallets.",
 "author": "davidgumberg",
 "author_association": "MEMBER",
 "created_at": "2026-09-30T02:11:05Z",
 "updated_at": "2026-10-27T13:43:14Z",
 "description_hash": "c8b55225492b263d",
 "age_days": 32,
 "draft": false,
 "labels": [
  "Wallet"
 ],
 "milestone": null,
 "base": "master",
 "head_sha": "2cc0946985e3e90e6da5ee2088e240568baa0676",
 "head_ref": "2026-09-29-deprecate-encryptwallet",
 "head_repo": "davidgumberg/bitcoin",
 "head_history": [],
 "additions": 150,
 "deletions": 73,
 "changed_files": 18,
 "commit_count": 8,
 "size_bucket": "M",
 "mergeable_state": "clean",
 "bot": {
  "drahtbot": {
   "present": true,
   "reviews": {
    "concept_ack": [
     {
      "login": "pseudoramdom",
      "url": "https://github.com/bitcoin/bitcoin/pull/36387#issuecomment-5904400903"
     },
     {
      "login": "w0xlt",
      "url": "https://github.com/bitcoin/bitcoin/pull/36387#issuecomment-5916410692"
     },
     {
      "login": "pablomartin4btc",
      "url": "https://github.com/bitcoin/bitcoin/pull/36387#pullrequestreview-5592655476"
     }
    ]
   },
   "conflicts": []
  }
 },
 "acks_parsed": {
  "pseudoramdom": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2026-09-30T05:00:22Z",
   "stale": false
  },
  "w0xlt": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2026-09-30T17:33:59Z",
   "stale": false
  },
  "pablomartin4btc": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2026-10-21T01:15:04Z",
   "stale": false
  }
 },
 "acks_tally": {
  "ack": 0,
  "stale_ack": 0,
  "concept_ack": 3,
  "approach_ack": 0,
  "nack": 0,
  "concept_nack": 0,
  "approach_nack": 0
 },
 "reviews": {
  "approved": 0,
  "changes_requested": 0,
  "distinct_reviewers": [
   "pablomartin4btc",
   "pseudoramdom",
   "w0xlt"
  ]
 },
 "signals": {
  "needs_rebase": false,
  "ci_failed": false,
  "mergeable_state": "clean",
  "last_author_activity": "2026-09-30T01:52:29Z",
  "last_reviewer_activity": "2026-10-21T01:15:04Z",
  "last_reviewer": "pablomartin4btc",
  "author_silent_days": 32,
  "waiting_on_author_days": 11,
  "days_since_update": 5
 },
 "refs": {
  "mentioned": [
   32452,
   36027
  ],
  "depends_on": [],
  "fixes": [],
  "linked_issues": [],
  "references": [
   {
    "number": 36027,
    "type": "issue",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "[rfc] Remove encrypting wallets that already exist"
   },
   {
    "number": 32452,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2025-05-17",
    "title": "test: Remove legacy wallet RPC overloads"
   }
  ],
  "conflicts": []
 },
 "stack": {
  "shares_commits_with": [],
  "based_on": [],
  "base_for": []
 },
 "review_paths": [
  "doc/release-notes-deprecateencryptwallet.md",
  "test/functional/rpc_deprecated.py",
  "test/functional/test_framework/test_framework.py",
  "test/functional/wallet_bumpfee.py",
  "test/functional/wallet_encryption.py",
  "test/functional/wallet_gethdkeys.py",
  "test/functional/wallet_listdescriptors.py"
 ],
 "body": "For more context, see: #36027\n\nEncrypting existing wallets that are unencrypted is fraught with footguns and complexity both for users and for developers.\n\nFor example:\n\n- No efforts are made to ensure that remnants of unencrypted key material are not left on the user's disk, as attempting to ensure this would be difficult and dangerous, and for some SSD's infeasible.\n\n- Encrypting a wallet that has manually imported descriptors will cause the wallet to change the spending conditions out from under the user. (https://github.com/bitcoin/bitcoin/issues/26607)\n\n- Because new keys are made after encryption, restoring from a backup made before encryption may result in loss of funds.\n\n_LLM Disclosure: Used gemma4-26B and qwen3.8-next-flash as research and drafting tools, but all code and text present here were written by me._",
 "commits": [
  {
   "sha": "645ea8b9b25bc24059134a2b27c550caa0c0590c",
   "date": "2026-09-30T01:20:57Z",
   "message": "refactor: test: Avoid encryptwallet in interface_bitcoin_cli.py\n\nThis RPC will be deprecated in a future commit, so tests should avoid\nrelying on it. This commit also adds scaffolding to init_wallet that\nwill be used when refactoring other tests."
  },
  {
   "sha": "2587fe96a8c54a97d2dd9c9d9fcc7d3ceda441b4",
   "date": "2026-09-30T01:23:13Z",
   "message": "refactor: test: rpc_psbt.py extract encrypted wallet signing\n\nThis improves legibility of the test and avoids the use of\n`encryptwallet` which will be deprecated."
  },
  {
   "sha": "f5f099eb586f7853031dae91760b19e4c9af3ffd",
   "date": "2026-09-30T01:35:21Z",
   "message": "refactor: test: wallet_bumpfee.py isolate encrypted wallet tests"
  },
  {
   "sha": "0af48177dd43efaff49e786ff69cab663a07849d",
   "date": "2026-09-30T01:35:21Z",
   "message": "refactor: test: wallet_fundrawtransaction.py avoid encryptwallet\n\nA later commit will deprecate this RPC."
  },
  {
   "sha": "2c247497ff438b6c697088b2161794fb15f0c636",
   "date": "2026-09-30T01:35:21Z",
   "message": "refactor: test: wallet_listdescriptors.py extract encrypted wallet test"
  },
  {
   "sha": "d6aebe0ebc5eed1bb723eed4dad09a03164a0c79",
   "date": "2026-09-30T01:35:21Z",
   "message": "test: refactor: wallet_multiwallet.py use a new encrypted wallet"
  },
  {
   "sha": "df3ac8100e0a7759401b05f8a5cffde35f2f16d5",
   "date": "2026-09-30T01:35:21Z",
   "message": "refactor: test: signrawtransaction isolate encrypted wallet test\n\nThis is useful since a future commit will deprecate `encryptwallet`."
  },
  {
   "sha": "2cc0946985e3e90e6da5ee2088e240568baa0676",
   "date": "2026-09-30T01:52:29Z",
   "message": "wallet: rpc: Deprecate `encryptwallet`\n\nEncrypting wallets from creation will still be supported, but there are\nfootguns both for users and for developers in supporting wallets that\nare created unencrypted and then later become encrypted.\n\nThe functional tests where the `deprecatedrpc` argument is added are\nones where functionality or behavior of `encryptwallet` is being tested,\nthey should be kept until the RPC command is removed."
  }
 ],
 "timeline": [
  {
   "t": "2026-09-30T05:00:22Z",
   "kind": "comment",
   "who": "pseudoramdom",
   "assoc": "MEMBER",
   "text": "Concept ACK, will review when I get a chance.",
   "id": "c:5904400903",
   "url": "https://github.com/bitcoin/bitcoin/pull/36387#issuecomment-5904400903",
   "hash": "518241d2a8cfbebc",
   "edited": null
  },
  {
   "t": "2026-09-30T17:33:59Z",
   "kind": "comment",
   "who": "w0xlt",
   "assoc": "CONTRIBUTOR",
   "text": "Concept ACK",
   "id": "c:5916410692",
   "url": "https://github.com/bitcoin/bitcoin/pull/36387#issuecomment-5916410692",
   "hash": "e8334cc43879b73c",
   "edited": null
  },
  {
   "t": "2026-10-20T22:36:57Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "doc/release-notes-deprecateencryptwallet.md",
   "commit": "2cc0946985e3e90e6da5ee2088e240568baa0676",
   "in_reply_to": null,
   "text": "nit: filename [convention](https://github.com/bitcoin/bitcoin/blob/master/doc/developer-notes.md#release-notes) is `release-notes-36387.md`.",
   "id": "rc:4331071666",
   "url": "https://github.com/bitcoin/bitcoin/pull/36387#discussion_r4331071666",
   "hash": "e3f3d44c0328f45c",
   "edited": "2026-10-21T01:15:04Z"
  },
  {
   "t": "2026-10-20T23:44:51Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "test/functional/test_framework/test_framework.py",
   "commit": "2cc0946985e3e90e6da5ee2088e240568baa0676",
   "in_reply_to": null,
   "text": "nit: the two branches only differ in the passphrase and the unlock around the import, so they could perhaps be collapsed. Also `w` is assigned but then `get_wallet_rpc` is called again for `wallet_importprivkey`, so `w` could be reused there.\n\nSince this drops the `if wallet_name is not None:` check, the `wallet_names` [comment](https://github.com/bitcoin/bitcoin/blob/4303f3b7f0775cdbbe77faddf142e1e44fa590ca/test/functional/test_framework/test_framework.py#L121-L122) could also drop \"If wallet names are None, wallet creation is skipped.\". That case has been broken since #32452 (fcc457573f) anyway (`get_wallet_rpc(None)` would rase in `urllib.parse.quote`).\n\n```suggestion\n            passphrase_args = {\"passphrase\": self.default_wallet_pass} if encrypted else {}\n            n.createwallet(wallet_name=wallet_name, load_on_startup=True, **passphrase_args)\n            w = n.get_wallet_rpc(wallet_name)\n            with WalletUnlock(w, self.default_wallet_pass) if encrypted else contextlib.nullcontext():\n                wallet_importprivkey(w, n.get_deterministic_priv_key().key, 0, label=\"coinbase\")\n```\n\n(needs import contextlib; tested on top of 2cc0946985 with the full extended functional suite.)",
   "id": "rc:4331521138",
   "url": "https://github.com/bitcoin/bitcoin/pull/36387#discussion_r4331521138",
   "hash": "5570bda6e28a1b7c",
   "edited": "2026-10-21T01:15:05Z"
  },
  {
   "t": "2026-10-20T23:49:08Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "test/functional/test_framework/test_framework.py",
   "commit": "2cc0946985e3e90e6da5ee2088e240568baa0676",
   "in_reply_to": null,
   "text": "nit: extra blank line here.",
   "id": "rc:4331546128",
   "url": "https://github.com/bitcoin/bitcoin/pull/36387#discussion_r4331546128",
   "hash": "75ebbca4efbd9cd9",
   "edited": "2026-10-21T01:15:05Z"
  },
  {
   "t": "2026-10-20T23:49:18Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "test/functional/wallet_gethdkeys.py",
   "commit": "2cc0946985e3e90e6da5ee2088e240568baa0676",
   "in_reply_to": null,
   "text": "nit: extra blank line here.",
   "id": "rc:4331547143",
   "url": "https://github.com/bitcoin/bitcoin/pull/36387#discussion_r4331547143",
   "hash": "75ebbca4efbd9cd9",
   "edited": "2026-10-21T01:15:05Z"
  },
  {
   "t": "2026-10-20T23:49:51Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "test/functional/wallet_encryption.py",
   "commit": "2cc0946985e3e90e6da5ee2088e240568baa0676",
   "in_reply_to": null,
   "text": "nit: extra blank line here.",
   "id": "rc:4331550359",
   "url": "https://github.com/bitcoin/bitcoin/pull/36387#discussion_r4331550359",
   "hash": "75ebbca4efbd9cd9",
   "edited": "2026-10-21T01:15:05Z"
  },
  {
   "t": "2026-10-20T23:51:44Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "test/functional/wallet_listdescriptors.py",
   "commit": "2cc0946985e3e90e6da5ee2088e240568baa0676",
   "in_reply_to": null,
   "text": "nit: extra blank line here.",
   "id": "rc:4331561699",
   "url": "https://github.com/bitcoin/bitcoin/pull/36387#discussion_r4331561699",
   "hash": "75ebbca4efbd9cd9",
   "edited": "2026-10-21T01:15:05Z"
  },
  {
   "t": "2026-10-21T00:06:27Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "test/functional/wallet_listdescriptors.py",
   "commit": "2cc0946985e3e90e6da5ee2088e240568baa0676",
   "in_reply_to": null,
   "text": "nit: import block indented 8 spaces (and missing trailing comma after `generate_keypair`).\n```suggestion\n    WalletUnlock,\n    generate_keypair,\n```",
   "id": "rc:4331646722",
   "url": "https://github.com/bitcoin/bitcoin/pull/36387#discussion_r4331646722",
   "hash": "efee1b4c56083578",
   "edited": "2026-10-21T01:15:05Z"
  },
  {
   "t": "2026-10-21T00:59:03Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "test/functional/wallet_listdescriptors.py",
   "commit": "2cc0946985e3e90e6da5ee2088e240568baa0676",
   "in_reply_to": null,
   "text": "nit: the previous version of the test compared the private output against `expected_private` and now the wallet is left unlocked until its unload.\n\n```suggestion\n         self.log.info(\"- With private=true, works when unlocked and matches the public descriptors.\")\n         with WalletUnlock(encrypted_wallet, self.default_wallet_pass):\n             private_output = encrypted_wallet.listdescriptors(True)\n         public_descs = [d[\"desc\"] for d in encrypted_locked_output[\"descriptors\"]]\n         private_descs = [d[\"desc\"] for d in private_output[\"descriptors\"]]\n         assert all(\"tprv\" in d for d in private_descs)\n         assert_equal([self.nodes[0].deriveaddresses(d, [0, 2]) for d in private_descs],\n                      [self.nodes[0].deriveaddresses(d, [0, 2]) for d in public_descs])\n```",
   "id": "rc:4331943126",
   "url": "https://github.com/bitcoin/bitcoin/pull/36387#discussion_r4331943126",
   "hash": "8d1bc95bcfac5a8f",
   "edited": "2026-10-21T01:15:05Z"
  },
  {
   "t": "2026-10-21T01:03:04Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "test/functional/wallet_bumpfee.py",
   "commit": "2cc0946985e3e90e6da5ee2088e240568baa0676",
   "in_reply_to": null,
   "text": "nit:\n```suggestion\n    assert_equal(bumpfee_res[\"errors\"], [])\n```",
   "id": "rc:4331966084",
   "url": "https://github.com/bitcoin/bitcoin/pull/36387#discussion_r4331966084",
   "hash": "65dc85715f9820db",
   "edited": "2026-10-21T01:15:05Z"
  },
  {
   "t": "2026-10-21T01:05:29Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "test/functional/rpc_deprecated.py",
   "commit": "2cc0946985e3e90e6da5ee2088e240568baa0676",
   "in_reply_to": null,
   "text": "nit (for consistency with the `removeprunedfunds` check above)...\n```suggestion\n            self.log.info(\"Test encryptwallet deprecation\")\n            assert_raises_rpc_error(\n```",
   "id": "rc:4331978382",
   "url": "https://github.com/bitcoin/bitcoin/pull/36387#discussion_r4331978382",
   "hash": "6834e8556e427802",
   "edited": "2026-10-21T01:15:05Z"
  },
  {
   "t": "2026-10-21T01:15:04Z",
   "kind": "review",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "2cc0946985e3e90e6da5ee2088e240568baa0676",
   "text": "Concept ACK\n\nI think `encryptwallet` RPC was created before the `createwalllet` gained the `passphrase`, and for what it worth creating today a new encrypted wallet and sendall-ing to it is equivalent and cleaner.\n\nThe GUI \"Encrypt Wallet\u2026\" action (`WalletView::encryptWallet` \u2192 `interfaces::Wallet::encryptWallet`) is unaffected and is probably where most users hit this. It might be worth mentioning in the description and release notes so the GUI and RPC deprecations ship in the same release (?).\n\nLeft some nits.",
   "id": "r:5592655476",
   "url": "https://github.com/bitcoin/bitcoin/pull/36387#pullrequestreview-5592655476",
   "hash": "e717a40bd7b4e317",
   "edited": null
  }
 ],
 "labels_log": [
  {
   "t": "2026-09-30T02:11:09Z",
   "action": "labeled",
   "label": "Wallet",
   "who": "DrahtBot"
  }
 ],
 "state_log": [],
 "text_chars": 5436,
 "text_tokens_estimate": 1359,
 "changed_paths": [
  "doc/release-notes-deprecateencryptwallet.md",
  "src/wallet/rpc/encrypt.cpp",
  "test/functional/interface_bitcoin_cli.py",
  "test/functional/rpc_deprecated.py",
  "test/functional/rpc_psbt.py",
  "test/functional/test_framework/test_framework.py",
  "test/functional/wallet_blank.py",
  "test/functional/wallet_bumpfee.py",
  "test/functional/wallet_createwallet.py",
  "test/functional/wallet_derivehdkey.py",
  "test/functional/wallet_descriptor.py",
  "test/functional/wallet_encryption.py",
  "test/functional/wallet_fundrawtransaction.py",
  "test/functional/wallet_gethdkeys.py",
  "test/functional/wallet_keypool.py",
  "test/functional/wallet_listdescriptors.py",
  "test/functional/wallet_multiwallet.py",
  "test/functional/wallet_signrawtransactionwithwallet.py"
 ],
 "files": [
  {
   "path": "doc/release-notes-deprecateencryptwallet.md",
   "add": 11,
   "del": 0
  },
  {
   "path": "src/wallet/rpc/encrypt.cpp",
   "add": 5,
   "del": 0
  },
  {
   "path": "test/functional/interface_bitcoin_cli.py",
   "add": 7,
   "del": 8
  },
  {
   "path": "test/functional/rpc_deprecated.py",
   "add": 6,
   "del": 0
  },
  {
   "path": "test/functional/rpc_psbt.py",
   "add": 31,
   "del": 9
  },
  {
   "path": "test/functional/test_framework/test_framework.py",
   "add": 14,
   "del": 5
  },
  {
   "path": "test/functional/wallet_blank.py",
   "add": 2,
   "del": 0
  },
  {
   "path": "test/functional/wallet_bumpfee.py",
   "add": 22,
   "del": 19
  },
  {
   "path": "test/functional/wallet_createwallet.py",
   "add": 1,
   "del": 0
  },
  {
   "path": "test/functional/wallet_derivehdkey.py",
   "add": 1,
   "del": 0
  },
  {
   "path": "test/functional/wallet_descriptor.py",
   "add": 1,
   "del": 1
  },
  {
   "path": "test/functional/wallet_encryption.py",
   "add": 2,
   "del": 0
  },
  {
   "path": "test/functional/wallet_fundrawtransaction.py",
   "add": 4,
   "del": 7
  },
  {
   "path": "test/functional/wallet_gethdkeys.py",
   "add": 2,
   "del": 0
  },
  {
   "path": "test/functional/wallet_keypool.py",
   "add": 1,
   "del": 0
  },
  {
   "path": "test/functional/wallet_listdescriptors.py",
   "add": 22,
   "del": 9
  },
  {
   "path": "test/functional/wallet_multiwallet.py",
   "add": 12,
   "del": 8
  },
  {
   "path": "test/functional/wallet_signrawtransactionwithwallet.py",
   "add": 6,
   "del": 7
  }
 ],
 "test_lines": 207,
 "git": {
  "head": "2cc0946985e3e90e6da5ee2088e240568baa0676",
  "head_matches_backup": true,
  "base": "ba8fdb9717791d9d71dba62f053a13e743247465",
  "patch_id": "1bb17d95f1a0fcc0",
  "commits": [
   {
    "sha": "645ea8b9b2",
    "subject": "refactor: test: Avoid encryptwallet in interface_bitcoin_cli.py",
    "files": 2,
    "add": 21,
    "del": 13
   },
   {
    "sha": "2587fe96a8",
    "subject": "refactor: test: rpc_psbt.py extract encrypted wallet signing",
    "files": 1,
    "add": 31,
    "del": 9
   },
   {
    "sha": "f5f099eb58",
    "subject": "refactor: test: wallet_bumpfee.py isolate encrypted wallet tests",
    "files": 1,
    "add": 22,
    "del": 19
   },
   {
    "sha": "0af48177dd",
    "subject": "refactor: test: wallet_fundrawtransaction.py avoid encryptwallet",
    "files": 1,
    "add": 4,
    "del": 7
   },
   {
    "sha": "2c247497ff",
    "subject": "refactor: test: wallet_listdescriptors.py extract encrypted wallet test",
    "files": 1,
    "add": 22,
    "del": 9
   },
   {
    "sha": "d6aebe0ebc",
    "subject": "test: refactor: wallet_multiwallet.py use a new encrypted wallet",
    "files": 1,
    "add": 12,
    "del": 8
   },
   {
    "sha": "df3ac8100e",
    "subject": "refactor: test: signrawtransaction isolate encrypted wallet test",
    "files": 1,
    "add": 6,
    "del": 7
   },
   {
    "sha": "2cc0946985",
    "subject": "wallet: rpc: Deprecate `encryptwallet`",
    "files": 10,
    "add": 32,
    "del": 1
   }
  ],
  "patch_truncated": false
 },
 "patch_id": "1bb17d95f1a0fcc0",
 "input_hash": "66543cd30a6b6c3f",
 "extracted_at": "2026-11-02T01:09:49+00:00"
}