{
 "number": 35813,
 "repo": "bitcoin/bitcoin",
 "url": "https://github.com/bitcoin/bitcoin/pull/35813",
 "title": "wallet, rpc: Add listrawtransactions RPC",
 "author": "pablomartin4btc",
 "author_association": "MEMBER",
 "created_at": "2026-07-26T17:08:37Z",
 "updated_at": "2026-09-17T09:37:39Z",
 "age_days": 52,
 "draft": false,
 "labels": [
  "Wallet",
  "Needs rebase"
 ],
 "milestone": null,
 "base": "master",
 "head_sha": "0e539c51e096db9c6787f00957b20d418f46bb04",
 "head_ref": "wallet/listrawtransactions",
 "head_repo": "pablomartin4btc/bitcoin",
 "head_history": [
  {
   "t": "2026-07-26T17:18:08Z",
   "sha": "15551988530f8175c55d2dbe4d368eb926b6da09"
  },
  {
   "t": "2026-07-26T22:17:53Z",
   "sha": "f592d25fc776112264084e776a417750b7632749"
  },
  {
   "t": "2026-07-28T00:30:49Z",
   "sha": "aa5307dbb6982f3b7bc2448bcb268d63bf984c92"
  },
  {
   "t": "2026-07-28T00:39:13Z",
   "sha": "142e1ac0f72e7d7555186a56d5458d379130792c"
  },
  {
   "t": "2026-08-11T03:08:03Z",
   "sha": "4e82e779026b05f8231f778e8758311c76ab4912"
  },
  {
   "t": "2026-08-11T03:18:23Z",
   "sha": "c163774b0039315d79af5c534632ee0f1defc2d4"
  },
  {
   "t": "2026-08-11T03:26:17Z",
   "sha": "51705e4f278a07780b102df2f86066ecb410d5f5"
  },
  {
   "t": "2026-08-11T21:04:23Z",
   "sha": "7940906b3fdcbe8defdd78dcc153da4ec0bda1b6"
  },
  {
   "t": "2026-08-20T23:44:39Z",
   "sha": "f7f4bf67f7ffa66e05c142257fd281baf57b4ff2"
  },
  {
   "t": "2026-08-27T03:24:30Z",
   "sha": "1a03da3ade34455818c0da09bacf337edba8f921"
  },
  {
   "t": "2026-08-27T18:03:12Z",
   "sha": "c08e90f07a033827f75274e4252f9f392aeb7697"
  },
  {
   "t": "2026-08-28T14:05:04Z",
   "sha": "0e539c51e096db9c6787f00957b20d418f46bb04"
  }
 ],
 "additions": 334,
 "deletions": 27,
 "changed_files": 6,
 "commit_count": 5,
 "size_bucket": "M",
 "mergeable_state": "dirty",
 "bot": {
  "drahtbot": {
   "present": true,
   "reviews": {
    "ack": [
     {
      "login": "polespinasa",
      "url": "https://github.com/bitcoin/bitcoin/pull/35813#issuecomment-5453550124"
     },
     {
      "login": "Bicaru20",
      "url": "https://github.com/bitcoin/bitcoin/pull/35813#pullrequestreview-5233771961"
     }
    ],
    "stale_ack": [
     {
      "login": "achow101",
      "url": "https://github.com/bitcoin/bitcoin/pull/35813#issuecomment-5259386497"
     },
     {
      "login": "BrandonOdiwuor",
      "url": "https://github.com/bitcoin/bitcoin/pull/35813#pullrequestreview-4998263283"
     },
     {
      "login": "w0xlt",
      "url": "https://github.com/bitcoin/bitcoin/pull/35813#pullrequestreview-5037466796"
     }
    ]
   },
   "conflicts": [
    {
     "number": 35513,
     "title": "rpc: help metadata fixes",
     "author": "RuslanProgrammer"
    },
    {
     "number": 35511,
     "title": "RFC: consensus: Make `CAmount` a class",
     "author": "hodlinator"
    },
    {
     "number": 27865,
     "title": "wallet: Track no-longer-spendable TXOs separately",
     "author": "achow101"
    }
   ]
  }
 },
 "acks_parsed": {
  "w0xlt": {
   "kind": "ack",
   "hash": "1a03da3ade34455818c0da09bacf337edba8f921",
   "t": "2026-08-27T05:19:04Z",
   "stale": true
  },
  "Bicaru20": {
   "kind": "ack",
   "hash": "0e539c51e096db9c6787f00957b20d418f46bb04",
   "t": "2026-09-17T09:37:35Z",
   "stale": false
  },
  "achow101": {
   "kind": "ack",
   "hash": "7940906b3fdcbe8defdd78dcc153da4ec0bda1b6",
   "t": "2026-08-11T22:05:44Z",
   "stale": true
  },
  "BrandonOdiwuor": {
   "kind": "ack",
   "hash": "f7f4bf67f7ffa66e05c142257fd281baf57b4ff2",
   "t": "2026-08-21T23:52:48Z",
   "stale": true
  },
  "polespinasa": {
   "kind": "ack",
   "hash": "0e539c51e096db9c6787f00957b20d418f46bb04",
   "t": "2026-08-28T14:10:50Z",
   "stale": false
  }
 },
 "acks_tally": {
  "ack": 2,
  "stale_ack": 3,
  "concept_ack": 0,
  "approach_ack": 0,
  "nack": 0,
  "concept_nack": 0,
  "approach_nack": 0
 },
 "reviews": {
  "approved": 1,
  "changes_requested": 0,
  "distinct_reviewers": [
   "Bicaru20",
   "BrandonOdiwuor",
   "achow101",
   "polespinasa",
   "vicjuma",
   "w0xlt"
  ]
 },
 "signals": {
  "needs_rebase": true,
  "ci_failed": false,
  "mergeable_state": "dirty",
  "last_author_activity": "2026-08-28T14:08:16Z",
  "last_reviewer_activity": "2026-09-17T09:37:35Z",
  "last_reviewer": "Bicaru20",
  "author_silent_days": 20,
  "waiting_on_author_days": 0,
  "days_since_update": 0
 },
 "refs": {
  "mentioned": [
   34632,
   35009
  ],
  "depends_on": [],
  "fixes": [
   34632
  ],
  "linked_issues": [
   {
    "number": 34632,
    "type": "issue",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "`listtransactions` does not list tx that spends only change outputs to a change address"
   }
  ],
  "references": [
   {
    "number": 34632,
    "type": "issue",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "`listtransactions` does not list tx that spends only change outputs to a change address"
   },
   {
    "number": 35009,
    "type": "pull",
    "state": "closed",
    "merged": false,
    "merged_at": null,
    "title": "wallet, rpc: add include_change parameter to listtransactions"
   }
  ],
  "conflicts": [
   35513,
   35511,
   27865
  ]
 },
 "stack": {
  "shares_commits_with": [],
  "based_on": [],
  "base_for": []
 },
 "review_paths": [
  "doc/release-notes-35813.md",
  "src/wallet/rpc/transactions.cpp",
  "test/functional/wallet_listrawtransactions.py"
 ],
 "body": "Add a new `listrawtransactions` RPC that returns wallet transactions without logical interpretation. Unlike `listtransactions`, which only lists transactions with an economic category (sends to external addresses, receives from outside), this RPC returns every transaction the wallet knows about \u2014 including consolidations and self-transfers that would otherwise be invisible.\n\nEach transaction appears exactly once with its net wallet balance change (`amount`) and, when the wallet funded the transaction, the fee paid (`fee`). Pagination is supported via `count` and `skip` parameters, matching the interface of `listtransactions`.\n\nNext possible follow-ups:\n- A filter parameter (`\"all\"` / `\"received\"` / `\"sent\"` / `\"self\"`) once per-tx semantics are agreed on\n- Some fields inherited from `TransactionDescriptionString()` carry references to `category` (e.g. `replaced_by_txid`, `parent_descs`) which don't apply here \u2014 could be cleaned up in a separate pass\n\nCloses #34632.\n\nPrevious attempt: #35009 (by alfonsoromanz), closed in favour of a separate RPC as suggested by achow101.",
 "commits": [
  {
   "sha": "8c9d360058083b36e529e422ae526c1c637ce258",
   "date": "2026-08-27T03:14:57Z",
   "message": "wallet, rpc: extract PushTxAmountAndFee/PushTxDecoded helpers\n\ngettransaction's amount/fee and decoded-transaction logic is duplicated\ninline. Extract it into two static helpers, PushTxAmountAndFee and\nPushTxDecoded, and have gettransaction call them instead.\n\nThis is in preparation for the upcoming listrawtransactions RPC, which\nneeds the exact same amount/fee and decoded-transaction logic per\ntransaction entry and will reuse these helpers rather than duplicate\nthem again.\n\nCo-authored-by: polespinasa <polespinasa@users.noreply.github.com>"
  },
  {
   "sha": "978fac7a586395b770f609756ef591c758b76254",
   "date": "2026-08-27T17:15:47Z",
   "message": "wallet, rpc: allow omitting parent_descs from TransactionDescriptionString\n\nTransactionDescriptionString() unconditionally documents a parent_descs\nfield, which is only ever populated by ListTransactions()'s per-output\n\"received\" branch via PushParentDescriptors(). Add an\ninclude_parent_descs parameter (default true, preserving current\nbehavior for listtransactions/listsinceblock/gettransaction) so a\ncaller whose entries don't go through that code path can correctly\nomit it instead of documenting a field it can never produce.\n\nThis is in preparation for the upcoming listrawtransactions RPC, whose\nentries are built via WalletTxToJSON rather than ListTransactions and\nso can never populate parent_descs."
  },
  {
   "sha": "024f8eae0081acfdd718c67a52a4cc08aabec2d6",
   "date": "2026-08-28T13:59:54Z",
   "message": "wallet, rpc: Add listrawtransactions RPC\n\nAdd a new `listrawtransactions` RPC that returns up to `count` most\nrecent wallet transactions (newest-first, then reversed to oldest-first\nin the result), skipping the first `skip` entries.\n\nUnlike `listtransactions`, each wallet transaction appears exactly once\nwith its net balance change, with no category assignment and no change\nsuppression. This makes consolidation and self-transfer transactions\nthat are invisible in `listtransactions` visible here.\n\nParams: count (default 10), skip (default 0), verbose (default false).\nWhen verbose=true, a `decoded` field is included (equivalent to\ndecoderawtransaction)."
  },
  {
   "sha": "4cc29809dff3ef3085601a917111e8c9bb750c5c",
   "date": "2026-08-28T13:59:54Z",
   "message": "test: Add functional test for listrawtransactions\n\nCovers:\n- Each transaction appears exactly once (unlike listtransactions which\n  shows one entry per output)\n- Coinbase transactions appear with generated=true and no category field\n- Consolidation transactions (all inputs/outputs wallet-owned) are\n  visible, unlike in listtransactions\n- count and skip pagination\n- verbose=true includes hex always and a decoded field; verbose=false\n  omits decoded"
  },
  {
   "sha": "0e539c51e096db9c6787f00957b20d418f46bb04",
   "date": "2026-08-28T13:59:54Z",
   "message": "doc: Add release notes for listrawtransactions"
  }
 ],
 "timeline": [
  {
   "t": "2026-07-26T17:18:08Z",
   "kind": "force_push",
   "who": "pablomartin4btc",
   "commit": "15551988530f8175c55d2dbe4d368eb926b6da09"
  },
  {
   "t": "2026-07-26T22:17:53Z",
   "kind": "force_push",
   "who": "pablomartin4btc",
   "commit": "f592d25fc776112264084e776a417750b7632749"
  },
  {
   "t": "2026-07-26T23:38:28Z",
   "kind": "comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "text": "-<ins>_**Updates**_</ins>:\n- Added release notes."
  },
  {
   "t": "2026-07-27T09:21:37Z",
   "kind": "comment",
   "who": "w0xlt",
   "assoc": "CONTRIBUTOR",
   "text": "Concept ACK."
  },
  {
   "t": "2026-07-27T22:08:40Z",
   "kind": "review_comment",
   "who": "vicjuma",
   "assoc": "CONTRIBUTOR",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "142e1ac0f72e7d7555186a56d5458d379130792c",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\ntACK. I think coinbase tx category may apply here."
  },
  {
   "t": "2026-07-28T00:30:49Z",
   "kind": "force_push",
   "who": "pablomartin4btc",
   "commit": "aa5307dbb6982f3b7bc2448bcb268d63bf984c92"
  },
  {
   "t": "2026-07-28T00:34:52Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "142e1ac0f72e7d7555186a56d5458d379130792c",
   "in_reply_to": 3661251404,
   "text": "A coinbase tx will be [flagged](https://github.com/bitcoin/bitcoin/blob/7dea464d6b51a69bd99a0451be8aaf3a26313eb6/src/wallet/rpc/transactions.cpp#L26-L27) via the **\"generated\"** field, not \"category\". Added a test for this in the first commit."
  },
  {
   "t": "2026-07-28T00:39:13Z",
   "kind": "force_push",
   "who": "pablomartin4btc",
   "commit": "142e1ac0f72e7d7555186a56d5458d379130792c"
  },
  {
   "t": "2026-07-28T00:43:24Z",
   "kind": "comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "text": "-<ins>_**Updates**_</ins>:\n- Added a test for a coinbase tx."
  },
  {
   "t": "2026-08-05T11:06:52Z",
   "kind": "review_comment",
   "who": "Bicaru20",
   "assoc": "CONTRIBUTOR",
   "path": "test/functional/wallet_listrawtransactions.py",
   "commit": "142e1ac0f72e7d7555186a56d5458d379130792c",
   "in_reply_to": null,
   "text": "If this test is for `listrawtransaction` why do this check on `listtransaction`? Shouldn't this be made in the `listtransaction` test?"
  },
  {
   "t": "2026-08-05T11:14:55Z",
   "kind": "review_comment",
   "who": "Bicaru20",
   "assoc": "CONTRIBUTOR",
   "path": "test/functional/wallet_listrawtransactions.py",
   "commit": "142e1ac0f72e7d7555186a56d5458d379130792c",
   "in_reply_to": null,
   "text": "Again, I do not think it is necessary to demostrate the behaviour of `listtransaction` in this test as it has its own test to test its behaviour."
  },
  {
   "t": "2026-08-05T11:16:28Z",
   "kind": "review_comment",
   "who": "Bicaru20",
   "assoc": "CONTRIBUTOR",
   "path": "test/functional/wallet_listrawtransactions.py",
   "commit": "142e1ac0f72e7d7555186a56d5458d379130792c",
   "in_reply_to": null,
   "text": "Maybe it is better to use `assert_greater_than_or_equal`?\n```suggestion\n        assert_greater_than_or_equal(total, 3) # Need at least 3 txs for pagination test\n```"
  },
  {
   "t": "2026-08-06T08:57:54Z",
   "kind": "review_comment",
   "who": "Bicaru20",
   "assoc": "CONTRIBUTOR",
   "path": "test/functional/wallet_listrawtransactions.py",
   "commit": "142e1ac0f72e7d7555186a56d5458d379130792c",
   "in_reply_to": null,
   "text": "Maybe is better to use `assert_greater_than`\n```suggestion\n        assert_greater_than(entry[\"amount\"],0)\n```"
  },
  {
   "t": "2026-08-06T10:06:06Z",
   "kind": "review_comment",
   "who": "Bicaru20",
   "assoc": "CONTRIBUTOR",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "142e1ac0f72e7d7555186a56d5458d379130792c",
   "in_reply_to": null,
   "text": "In order to keep the logic the same as `ListTransactions`, maybe it would be better to modify the vector `ret` inside the function instead of returning the `entry` and then adding it to the vector. That way when we call it, it would be just `ListRawTransaction(*pwallet, *pwtx, ret);` and the function would take care of modifying `ret`. Added the suggestion of how I think it should be:\n\n```suggestion\ntemplate <class Vec>\nstatic void ListRawTransaction(const CWallet& wallet, const CWalletTx& wtx, Vec& ret)\n    EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)\n{\n    UniValue entry(UniValue::VOBJ);\n\n    CAmount nCredit = CachedTxGetCredit(wallet, wtx, /*avoid_reuse=*/false);\n    CAmount nDebit = CachedTxGetDebit(wallet, wtx, /*avoid_reuse=*/false);\n    CAmount nNet = nCredit - nDebit;\n    bool is_from_me = CachedTxIsFromMe(wallet, wtx);\n    CAmount nFee = (is_from_me ? wtx.tx->GetValueOut() - nDebit : 0);\n\n    entry.pushKV(\"amount\", ValueFromAmount(nNet - nFee));\n    if (is_from_me)\n        entry.pushKV(\"fee\", ValueFromAmount(nFee));\n\n    WalletTxToJSON(wallet, wtx, entry);\n    entry.pushKV(\"abandoned\", wtx.isAbandoned());\n    ret.push_back(entry);\n}\n```"
  },
  {
   "t": "2026-08-06T10:15:47Z",
   "kind": "review",
   "who": "Bicaru20",
   "assoc": "CONTRIBUTOR",
   "state": "COMMENTED",
   "commit": "142e1ac0f72e7d7555186a56d5458d379130792c",
   "text": "Concept ACK.\n Left some comments that I think will improve the code. Also, maybe it would be better for reviewers if you could split the first commit into two: One for the new rpc and the other for the test.\n\nWhile reviewing, I noticed a lot of the code of `listrawtransaction` is from `listtransaction`. I though that it would be better if we created a helper function so we don't have duplicated code.\n\nSomething like this:\n\n```diff\n\ndiff --git a/src/wallet/rpc/transactions.cpp b/src/wallet/rpc/transactions.cpp\nindex d20bec0ab4..5526165997 100644\n--- a/src/wallet/rpc/transactions.cpp\n+++ b/src/wallet/rpc/transactions.cpp\n@@ -409,6 +409,78 @@ static UniValue ListRawTransaction(const CWallet& wallet, const CWalletTx& wtx)\n     return entry;\n }\n\n+static UniValue ListTransactionHelper(const JSONRPCRequest& request, bool raw){\n+\n+    LogDebug(BCLog::RPC, \"\\nlistrawtransactions 123\\n\");\n+    const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);\n+    if (!pwallet) return UniValue::VNULL;\n+\n+    // Make sure the results are valid at least up to the most recent block\n+    // the user could have gotten from another RPC command prior to now\n+    pwallet->BlockUntilSyncedToCurrentChain();\n+    std::optional<std::string> filter_label;\n+    // Listtransaction has an extra element than listrawtrnasaction\n+    // Depending on which rpc we are dealing with we substract value\n+    // to the index to get the parameter we want.\n+    int index = 1;\n+    if (!raw){\n+        index = 0;\n+        if (!request.params[0].isNull() && request.params[0].get_str() != \"*\") {\n+            filter_label.emplace(LabelFromValue(request.params[0]));\n+            if (filter_label.value().empty()) {\n+                throw JSONRPCError(RPC_INVALID_PARAMETER, \"Label argument must be a valid label name or \\\"*\\\".\");\n+            }\n+        }\n+    }\n+\n+    int nCount = 10;\n+    if (!request.params[1-index].isNull())\n+        nCount = request.params[1-index].getInt<int>();\n+    int nFrom = 0;\n+    if (!request.params[2-index].isNull())\n+        nFrom = request.params[2-index].getInt<int>();\n+\n+    if (nCount < 0)\n+        throw JSONRPCError(RPC_INVALID_PARAMETER, \"Negative count\");\n+    if (nFrom < 0)\n+        throw JSONRPCError(RPC_INVALID_PARAMETER, \"Negative from\");\n+\n+    std::vector<UniValue> ret;\n+    {\n+        LOCK(pwallet->cs_wallet);\n+\n+        const CWallet::TxItems & txOrdered = pwallet->wtxOrdered;\n+\n+        // iterate backwards until we have nCount items to return:\n+        if (!raw){\n+            for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)\n+            {\n+                CWalletTx *const pwtx = (*it).second;\n+                ListTransactions(*pwallet, *pwtx, 0, true, ret, filter_label);\n+                if ((int)ret.size() >= (nCount+nFrom)) break;\n+            }\n+        } else {\n+            for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) {\n+                CWalletTx* const pwtx = (*it).second;\n+                ret.push_back(ListRawTransaction(*pwallet, *pwtx));\n+                if ((int)ret.size() >= (nCount + nFrom)) break;\n+            }\n+        }\n+    }\n+\n+    // ret is newest to oldest\n+\n+    if (nFrom > (int)ret.size())\n+        nFrom = ret.size();\n+    if ((nFrom + nCount) > (int)ret.size())\n+        nCount = ret.size() - nFrom;\n+\n+    auto txs_rev_it{std::make_move_iterator(ret.rend())};\n+    UniValue result{UniValue::VARR};\n+    result.push_backV(txs_rev_it - nFrom - nCount, txs_rev_it - nFrom); // Return oldest to newest\n+    return result;\n+}\n+\n static std::vector<RPCResult> TransactionDescriptionString()\n {\n     return{{RPCResult::Type::NUM, \"confirmations\", \"The number of confirmations for the transaction. Negative confirmations means the\\n\"\n@@ -496,58 +568,7 @@ RPCMethod listtransactions()\n                 },\n         [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue\n {\n-    const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);\n-    if (!pwallet) return UniValue::VNULL;\n-\n-    // Make sure the results are valid at least up to the most recent block\n-    // the user could have gotten from another RPC command prior to now\n-    pwallet->BlockUntilSyncedToCurrentChain();\n-\n-    std::optional<std::string> filter_label;\n-    if (!request.params[0].isNull() && request.params[0].get_str() != \"*\") {\n-        filter_label.emplace(LabelFromValue(request.params[0]));\n-        if (filter_label.value().empty()) {\n-            throw JSONRPCError(RPC_INVALID_PARAMETER, \"Label argument must be a valid label name or \\\"*\\\".\");\n-        }\n-    }\n-    int nCount = 10;\n-    if (!request.params[1].isNull())\n-        nCount = request.params[1].getInt<int>();\n-    int nFrom = 0;\n-    if (!request.params[2].isNull())\n-        nFrom = request.params[2].getInt<int>();\n-\n-    if (nCount < 0)\n-        throw JSONRPCError(RPC_INVALID_PARAMETER, \"Negative count\");\n-    if (nFrom < 0)\n-        throw JSONRPCError(RPC_INVALID_PARAMETER, \"Negative from\");\n-\n-    std::vector<UniValue> ret;\n-    {\n-        LOCK(pwallet->cs_wallet);\n-\n-        const CWallet::TxItems & txOrdered = pwallet->wtxOrdered;\n-\n-        // iterate backwards until we have nCount items to return:\n-        for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)\n-        {\n-            CWalletTx *const pwtx = (*it).second;\n-            ListTransactions(*pwallet, *pwtx, 0, true, ret, filter_label);\n-            if ((int)ret.size() >= (nCount+nFrom)) break;\n-        }\n-    }\n-\n-    // ret is newest to oldest\n-\n-    if (nFrom > (int)ret.size())\n-        nFrom = ret.size();\n-    if ((nFrom + nCount) > (int)ret.size())\n-        nCount = ret.size() - nFrom;\n-\n-    auto txs_rev_it{std::make_move_iterator(ret.rend())};\n-    UniValue result{UniValue::VARR};\n-    result.push_backV(txs_rev_it - nFrom - nCount, txs_rev_it - nFrom); // Return oldest to newest\n-    return result;\n+    return ListTransactionHelper(request, false);\n },\n     };\n }\n@@ -592,45 +613,8 @@ RPCMethod listrawtransactions()\n         },\n         [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue\n {\n-    const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);\n-    if (!pwallet) return UniValue::VNULL;\n-\n-    pwallet->BlockUntilSyncedToCurrentChain();\n-\n-    int nCount = 10;\n-    if (!request.params[0].isNull())\n-        nCount = request.params[0].getInt<int>();\n-    int nFrom = 0;\n-    if (!request.params[1].isNull())\n-        nFrom = request.params[1].getInt<int>();\n-\n-    if (nCount < 0)\n-        throw JSONRPCError(RPC_INVALID_PARAMETER, \"Negative count\");\n-    if (nFrom < 0)\n-        throw JSONRPCError(RPC_INVALID_PARAMETER, \"Negative from\");\n-\n-    std::vector<UniValue> ret;\n-    {\n-        LOCK(pwallet->cs_wallet);\n-\n-        const CWallet::TxItems& txOrdered = pwallet->wtxOrdered;\n-\n-        for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) {\n-            CWalletTx* const pwtx = (*it).second;\n-            ret.push_back(ListRawTransaction(*pwallet, *pwtx));\n-            if ((int)ret.size() >= (nCount + nFrom)) break;\n-        }\n-    }\n-\n-    if (nFrom > (int)ret.size())\n-        nFrom = ret.size();\n-    if ((nFrom + nCount) > (int)ret.size())\n-        nCount = ret.size() - nFrom;\n-\n-    auto txs_rev_it{std::make_move_iterator(ret.rend())};\n-    UniValue result{UniValue::VARR};\n-    result.push_backV(txs_rev_it - nFrom - nCount, txs_rev_it - nFrom);\n-    return result;\n+    return ListTransactionHelper(request, true);\n },\n     };\n }\n```\n\nI am not supper convinced about this, as this requiers to also change the rpc `listtransaction` and may difficult things in the future if some new parameters are introduced in one of the rpcs. Just wanted to comment the idea to see what others think."
  },
  {
   "t": "2026-08-10T20:53:08Z",
   "kind": "review_comment",
   "who": "achow101",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "ad67c8a67aa9a0c148c88cae2062d0c43ab2b448",
   "in_reply_to": null,
   "text": "In ad67c8a67aa9a0c148c88cae2062d0c43ab2b448 \"wallet, test: Add listrawtransactions RPC\"\n\nnit: New code should be snake_case.\n\n```suggestion\n    int count = 10;\n```"
  },
  {
   "t": "2026-08-10T20:55:32Z",
   "kind": "review_comment",
   "who": "achow101",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "ad67c8a67aa9a0c148c88cae2062d0c43ab2b448",
   "in_reply_to": null,
   "text": "In ad67c8a67aa9a0c148c88cae2062d0c43ab2b448 \"wallet, test: Add listrawtransactions RPC\"\n\nnit: Use `Arg` instead\n\n```suggestion\n    int count = request.params.Arg<int>(\"count\");\n```"
  },
  {
   "t": "2026-08-10T21:12:47Z",
   "kind": "review_comment",
   "who": "achow101",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "ad67c8a67aa9a0c148c88cae2062d0c43ab2b448",
   "in_reply_to": null,
   "text": "In ad67c8a67aa9a0c148c88cae2062d0c43ab2b448 \"wallet, test: Add listrawtransactions RPC\"\n\nInstead of this insane iterator arithmetic, I think it would be better if the loop above that filled out `ret` just skipped the `skip` transactions in the first place. Then this can become\n\n```suggestion\n    result.push_backV(ret.rbegin(), ret.rend());\n```"
  },
  {
   "t": "2026-08-10T21:15:43Z",
   "kind": "review",
   "who": "achow101",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "142e1ac0f72e7d7555186a56d5458d379130792c",
   "text": "This should take a `verbose` or `verbosity` parameter that would let the user optionally have the full transaction be decoded. The raw transaction hex should be in the default output as well.\n\nThe help text should not include any mention of fields that will not be output, such as `category`."
  },
  {
   "t": "2026-08-11T03:08:03Z",
   "kind": "force_push",
   "who": "pablomartin4btc",
   "commit": "4e82e779026b05f8231f778e8758311c76ab4912"
  },
  {
   "t": "2026-08-11T03:18:23Z",
   "kind": "force_push",
   "who": "pablomartin4btc",
   "commit": "c163774b0039315d79af5c534632ee0f1defc2d4"
  },
  {
   "t": "2026-08-11T03:26:17Z",
   "kind": "force_push",
   "who": "pablomartin4btc",
   "commit": "51705e4f278a07780b102df2f86066ecb410d5f5"
  },
  {
   "t": "2026-08-11T04:43:47Z",
   "kind": "comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nI have done that, thanks.\n\n[quoted text omitted]\nThanks for the suggestion and for thinking about DRY here. `listtransactions` and `listrawtransactions` have fundamentally different semantics. `listtransactions` does economic interpretation: category assignment, change suppression, multiple entries per tx. `listrawtransactions` deliberately avoids all of that. A shared helper would entangle two RPCs that are designed to diverge, making it harder to evolve either one independently in the future."
  },
  {
   "t": "2026-08-11T04:45:27Z",
   "kind": "comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nBoth done in 42b0de1da0dfe0b94bc8011c1ac57b3afca4d1b5, thanks."
  },
  {
   "t": "2026-08-11T04:46:28Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "ad67c8a67aa9a0c148c88cae2062d0c43ab2b448",
   "in_reply_to": 3753420417,
   "text": "Done in 061f0824f5cde46614427c0f2c3a1b9171d5fd8c, thanks!"
  },
  {
   "t": "2026-08-11T04:46:50Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "ad67c8a67aa9a0c148c88cae2062d0c43ab2b448",
   "in_reply_to": 3753304625,
   "text": "Done in 061f0824f5cde46614427c0f2c3a1b9171d5fd8c, thanks!"
  },
  {
   "t": "2026-08-11T04:49:38Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "ad67c8a67aa9a0c148c88cae2062d0c43ab2b448",
   "in_reply_to": 3753287085,
   "text": "Done in 061f0824f5cde46614427c0f2c3a1b9171d5fd8c, thanks!"
  },
  {
   "t": "2026-08-11T04:53:58Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "142e1ac0f72e7d7555186a56d5458d379130792c",
   "in_reply_to": 3727812567,
   "text": "Done in 42b0de1da0dfe0b94bc8011c1ac57b3afca4d1b5, thanks!"
  },
  {
   "t": "2026-08-11T04:54:26Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "test/functional/wallet_listrawtransactions.py",
   "commit": "142e1ac0f72e7d7555186a56d5458d379130792c",
   "in_reply_to": 3727352027,
   "text": "Done in 061f0824f5cde46614427c0f2c3a1b9171d5fd8c, thanks!"
  },
  {
   "t": "2026-08-11T04:55:22Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "test/functional/wallet_listrawtransactions.py",
   "commit": "142e1ac0f72e7d7555186a56d5458d379130792c",
   "in_reply_to": 3720095605,
   "text": "Done in 061f0824f5cde46614427c0f2c3a1b9171d5fd8c, thanks!"
  },
  {
   "t": "2026-08-11T04:57:42Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "test/functional/wallet_listrawtransactions.py",
   "commit": "142e1ac0f72e7d7555186a56d5458d379130792c",
   "in_reply_to": 3720042023,
   "text": "You're right, done in 061f0824f5cde46614427c0f2c3a1b9171d5fd8c, thanks! \u2014 removing the `listtransactions` assertions, that behaviour is already covered by its own test. Keeping the comments for context."
  },
  {
   "t": "2026-08-11T04:58:18Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "test/functional/wallet_listrawtransactions.py",
   "commit": "142e1ac0f72e7d7555186a56d5458d379130792c",
   "in_reply_to": 3720086960,
   "text": "Same as above, removed in 061f0824f5cde46614427c0f2c3a1b9171d5fd8c, thanks!"
  },
  {
   "t": "2026-08-11T05:12:58Z",
   "kind": "comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "text": "-<ins>_**Updates**_</ins>:\n- Addressed @Bicaru20's [feedback](https://github.com/bitcoin/bitcoin/pull/35813#pullrequestreview-4863711017):\n  - Split the first commit into two \u2014 now 3 commits: RPC implementation, functional test, and release notes;\n  - `ListRawTransaction` now pushes to `ret` directly via [template](https://github.com/bitcoin/bitcoin/pull/35813#discussion_r3727812567) `<class Vec>` (matching `ListTransactions` style), with a verbose param added for the decoded output;\n  - [Removed](https://github.com/bitcoin/bitcoin/pull/35813#discussion_r3720042023) `listtransactions` API calls from `test_one_entry_per_tx` and `test_consolidation_tx_visible`; kept explanatory comments documenting why the comparison matters conceptually;\n  - [Replaced](https://github.com/bitcoin/bitcoin/pull/35813#discussion_r3720095605) bare `assert` comparisons with `assert_greater_than` and `assert_greater_than_or_equal`;\n  - On the shared `ListTransactionHelper` suggestion: `listtransactions` and `listrawtransactions` have fundamentally different semantics \u2014 the former works per-output with category assignment, label filtering, and change suppression; the latter works per-transaction with no categorisation. A shared raw flag would couple two RPCs that are likely to diverge further (e.g. the new verbose param only applies to `listrawtransactions`). Keeping them independent is cleaner.\n- Addressed @achow101's [feedback](https://github.com/bitcoin/bitcoin/pull/35813#pullrequestreview-4900868755):\n  - Added verbose (`bool`, default `false`); `hex` is always included in the output; `decoded` is added when `verbose=true` (matches the `gettransaction` pattern);\n  - Removed `category` field references from `TransactionDescriptionString()` help strings \u2014 descriptions no longer reference the `category` field;\n  - [Variables](https://github.com/bitcoin/bitcoin/pull/35813#discussion_r3753287085) are now snake_case;\n  - [Using](https://github.com/bitcoin/bitcoin/pull/35813#discussion_r3753304625) `self.Arg<int>(\"count\")`, `self.Arg<int>(\"skip\")`, `self.Arg<bool>(\"verbose\")`;\n  - Pagination now [skips](https://github.com/bitcoin/bitcoin/pull/35813#discussion_r3753420417) in the loop directly; result assembled with `result.push_backV(ret.rbegin(), ret.rend())`."
  },
  {
   "t": "2026-08-11T19:20:55Z",
   "kind": "review_comment",
   "who": "achow101",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "42b0de1da0dfe0b94bc8011c1ac57b3afca4d1b5",
   "in_reply_to": null,
   "text": "In 42b0de1da0dfe0b94bc8011c1ac57b3afca4d1b5 \"wallet, rpc: Add listrawtransactions RPC\"\n\nnit: Whitespace"
  },
  {
   "t": "2026-08-11T19:21:24Z",
   "kind": "review_comment",
   "who": "achow101",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "42b0de1da0dfe0b94bc8011c1ac57b3afca4d1b5",
   "in_reply_to": null,
   "text": "In 42b0de1da0dfe0b94bc8011c1ac57b3afca4d1b5 \"wallet, rpc: Add listrawtransactions RPC\"\n\n```suggestion\n            if (skipped++ < skip) continue\n```"
  },
  {
   "t": "2026-08-11T19:21:50Z",
   "kind": "review_comment",
   "who": "achow101",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "42b0de1da0dfe0b94bc8011c1ac57b3afca4d1b5",
   "in_reply_to": null,
   "text": "In 42b0de1da0dfe0b94bc8011c1ac57b3afca4d1b5 \"wallet, rpc: Add listrawtransactions RPC\"\n\nnit: snake_case"
  },
  {
   "t": "2026-08-11T19:22:54Z",
   "kind": "review_comment",
   "who": "achow101",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "42b0de1da0dfe0b94bc8011c1ac57b3afca4d1b5",
   "in_reply_to": null,
   "text": "In 42b0de1da0dfe0b94bc8011c1ac57b3afca4d1b5 \"wallet, rpc: Add listrawtransactions RPC\"\n\nnit: Naming, in this function in general."
  },
  {
   "t": "2026-08-11T21:04:23Z",
   "kind": "force_push",
   "who": "pablomartin4btc",
   "commit": "7940906b3fdcbe8defdd78dcc153da4ec0bda1b6"
  },
  {
   "t": "2026-08-11T21:05:37Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "42b0de1da0dfe0b94bc8011c1ac57b3afca4d1b5",
   "in_reply_to": 3761022516,
   "text": "Done in 4791ec9727db6e169f4b130ad8ac50faf97c26dc, thanks!"
  },
  {
   "t": "2026-08-11T21:05:39Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "42b0de1da0dfe0b94bc8011c1ac57b3afca4d1b5",
   "in_reply_to": 3761019827,
   "text": "Done in 4791ec9727db6e169f4b130ad8ac50faf97c26dc, thanks!"
  },
  {
   "t": "2026-08-11T21:05:43Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "42b0de1da0dfe0b94bc8011c1ac57b3afca4d1b5",
   "in_reply_to": 3761016475,
   "text": "Done in 4791ec9727db6e169f4b130ad8ac50faf97c26dc, thanks!"
  },
  {
   "t": "2026-08-11T21:05:59Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "42b0de1da0dfe0b94bc8011c1ac57b3afca4d1b5",
   "in_reply_to": 3761029833,
   "text": "Done in 4791ec9727db6e169f4b130ad8ac50faf97c26dc, thanks!"
  },
  {
   "t": "2026-08-11T21:15:48Z",
   "kind": "comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "text": "-<ins>_**Updates**_</ins>:\n- Addressed @achow101's feedback: corrected [naming](https://github.com/bitcoin/bitcoin/pull/35813#discussion_r3761029833) convention for new code ([snake_case](https://github.com/bitcoin/bitcoin/pull/35813#discussion_r3761022516)) \u2014 missed from previous feedback (sorry!), [removed](https://github.com/bitcoin/bitcoin/pull/35813#discussion_r3761016475) extra alignment spaces and [suggestion](https://github.com/bitcoin/bitcoin/pull/35813#discussion_r3761019827) taken for `if (skipped < skip) { ++skipped; continue; }` \u2192 `if (skipped++ < skip) continue`."
  },
  {
   "t": "2026-08-11T22:05:44Z",
   "kind": "comment",
   "who": "achow101",
   "assoc": "MEMBER",
   "text": "ACK 7940906b3fdcbe8defdd78dcc153da4ec0bda1b6"
  },
  {
   "t": "2026-08-19T18:09:23Z",
   "kind": "comment",
   "who": "Bicaru20",
   "assoc": "CONTRIBUTOR",
   "text": "ACK 7940906b3f\n\nI really like the `verbose` parameter to ge the decoded transaction, I think it is very usefull.\n\n[quoted text omitted]\nAgreed, it make sense to leave it separately."
  },
  {
   "t": "2026-08-20T20:12:18Z",
   "kind": "review_comment",
   "who": "w0xlt",
   "assoc": "CONTRIBUTOR",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "7940906b3fdcbe8defdd78dcc153da4ec0bda1b6",
   "in_reply_to": null,
   "text": "Why is `count=0` allowed ?\nThis will always return no data.\n\nMaybe can the validation be changed ?\n```c++\nif (count <= 0)\n        throw JSONRPCError(RPC_INVALID_PARAMETER, \"Negative or zero count\");\n```\n\nBut even we want to support zero count for any reason, the code needs to be fixed since it will return the newest eligible wallet transaction:\n\n```diff\ndiff --git a/src/wallet/rpc/transactions.cpp b/src/wallet/rpc/transactions.cpp\nindex a754aa3942..d95e8b5bb2 100644\n--- a/src/wallet/rpc/transactions.cpp\n+++ b/src/wallet/rpc/transactions.cpp\n@@ -650,10 +650,10 @@ RPCMethod listrawtransactions()\n\n         int skipped = 0;\n         for (CWallet::TxItems::const_reverse_iterator it = tx_ordered.rbegin(); it != tx_ordered.rend(); ++it) {\n+            if ((int)ret.size() >= count) break;\n             if (skipped++ < skip) continue;\n             CWalletTx* const pwtx = (*it).second;\n             ListRawTransaction(*pwallet, *pwtx, ret, verbose);\n-            if ((int)ret.size() >= count) break;\n         }\n     }\n\ndiff --git a/test/functional/wallet_listrawtransactions.py b/test/functional/wallet_listrawtransactions.py\nindex 549d920f92..f2ced75141 100755\n--- a/test/functional/wallet_listrawtransactions.py\n+++ b/test/functional/wallet_listrawtransactions.py\n@@ -121,6 +121,9 @@ class ListRawTransactionsTest(BitcoinTestFramework):\n         total = len(all_txs)\n         assert_greater_than_or_equal(total, 3)  # Need at least 3 txs for pagination test\n\n+        # count=0 returns an empty page.\n+        assert_equal(node.listrawtransactions(0), [])\n+\n         # count=2 returns the 2 newest txs ordered oldest-first within the result.\n         page = node.listrawtransactions(2)\n         assert_equal(len(page), 2)\n```"
  },
  {
   "t": "2026-08-20T23:44:39Z",
   "kind": "force_push",
   "who": "pablomartin4btc",
   "commit": "f7f4bf67f7ffa66e05c142257fd281baf57b4ff2"
  },
  {
   "t": "2026-08-20T23:48:45Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "7940906b3fdcbe8defdd78dcc153da4ec0bda1b6",
   "in_reply_to": 3824997846,
   "text": "Thanks for catching this!\n\n[quoted text omitted]\nThe reasoning is that `listrawtransactions` is meant to mimic `listtransactions`' behaviour, and rejecting `count=0` here would create a divergence \u2014 `listtransactions` already accepts it silently and returns `[]`.\n\nI've taken your fix \u2014 as you spotted, `count=0` was incorrectly returning the newest record instead of an empty list."
  },
  {
   "t": "2026-08-20T23:54:22Z",
   "kind": "comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "text": "-<ins>_**Updates**_</ins>:\n- Addressed @w0xlt's [feedback](https://github.com/bitcoin/bitcoin/pull/35813#discussion_r3826209935): fixed `count=0` incorrectly returning the newest record; now correctly returns `[]`, matching `listtransactions`' behaviour."
  },
  {
   "t": "2026-08-21T23:52:48Z",
   "kind": "review",
   "who": "BrandonOdiwuor",
   "assoc": "CONTRIBUTOR",
   "state": "COMMENTED",
   "commit": "f7f4bf67f7ffa66e05c142257fd281baf57b4ff2",
   "text": "ACK f7f4bf67f7ffa66e05c142257fd281baf57b4ff2\n\nTested the new `listrawtransactions` RPC on regtest (Ubuntu 24.04.4 LTS)\n\nVerified:\n\n- Every wallet transaction appears exactly once, with no `category` field\n- Self-sends are shown as a single entry with `amount: 0` and the correct `fee`\n- Pagination via `count` / `skip` works as documented (including edge cases)\n\n**`listrawtransactions` vs `listtransactions`**\n\nbitcoin-cli -regtest listtransactions\n\n``` bash\n./build_dev_mode/bin/bitcoin-cli -regtest -rpcwallet=my_wallet listtransactions\n[\n  {\n    \"address\": \"bcrt1qygq445lj6r9qx9q0mss8w32u2c63fydlh52l8h\",\n    \"parent_descs\": [\n      \"wpkh([3abfaf54/84h/1h/0h]tpubDC4R87NimtK5PaN6WYxrayGo5LiZVfcjt3Jm58h4xuR24MyrJkiWWu3bDj4d9AKJmhRLEN1tTUm78Lo9CixG2gTPT6iN7GfjEVJtnSwv2PL/0/*)#vpvgr0z6\"\n    ],\n    \"category\": \"receive\",\n    \"amount\": 5.00000000,\n    \"label\": \"\",\n    \"vout\": 0,\n    \"abandoned\": false,\n    \"confirmations\": 1,\n    \"blockhash\": \"38d06e1c5bde99df396bd60c4b54287e994aaa0cbd0c50061a8d92401e48f096\",\n    \"blockheight\": 102,\n    \"blockindex\": 4,\n    \"blocktime\": 1787331199,\n    \"txid\": \"3021a78312359fb6557ff2337404e9983420825cd3e6900b5ec8201a68d5d4de\",\n    \"wtxid\": \"139dd42c8088e50f3916bb1b93c4a84ac9f852a727c3aa70f7a9b7d818609552\",\n    \"alternate_wtxids\": [\n    ],\n    \"walletconflicts\": [\n    ],\n    \"mempoolconflicts\": [\n    ],\n    \"time\": 1787331105,\n    \"timereceived\": 1787331105\n  },\n  {\n    \"address\": \"bcrt1qzc5v2u04ey742g8csxfqm95qaee7u92qrhkfxr\",\n    \"parent_descs\": [\n      \"wpkh([3abfaf54/84h/1h/0h]tpubDC4R87NimtK5PaN6WYxrayGo5LiZVfcjt3Jm58h4xuR24MyrJkiWWu3bDj4d9AKJmhRLEN1tTUm78Lo9CixG2gTPT6iN7GfjEVJtnSwv2PL/0/*)#vpvgr0z6\"\n    ],\n    \"category\": \"receive\",\n    \"amount\": 10.00000000,\n    \"label\": \"\",\n    \"vout\": 1,\n    \"abandoned\": false,\n    \"confirmations\": 1,\n    \"blockhash\": \"38d06e1c5bde99df396bd60c4b54287e994aaa0cbd0c50061a8d92401e48f096\",\n    \"blockheight\": 102,\n    \"blockindex\": 5,\n    \"blocktime\": 1787331199,\n    \"txid\": \"097ca684069f02817c36ea61bbd155782293802764d6505a991b0c9dd408fc74\",\n    \"wtxid\": \"39276f39bbe1e1e20d88e53cfe577e5a2c875faf965a30b3999327e9b32380e3\",\n    \"alternate_wtxids\": [\n    ],\n    \"walletconflicts\": [\n    ],\n    \"mempoolconflicts\": [\n    ],\n    \"time\": 1787331105,\n    \"timereceived\": 1787331105\n  },\n  {\n    \"address\": \"bcrt1q0vwvq26wqsff6fca92scc3355562l6l9ru0vwy\",\n    \"parent_descs\": [\n      \"wpkh([3abfaf54/84h/1h/0h]tpubDC4R87NimtK5PaN6WYxrayGo5LiZVfcjt3Jm58h4xuR24MyrJkiWWu3bDj4d9AKJmhRLEN1tTUm78Lo9CixG2gTPT6iN7GfjEVJtnSwv2PL/0/*)#vpvgr0z6\"\n    ],\n    \"category\": \"receive\",\n    \"amount\": 2.00000000,\n    \"label\": \"\",\n    \"vout\": 0,\n    \"abandoned\": false,\n    \"confirmations\": 0,\n    \"trusted\": true,\n    \"txid\": \"aa3acf06a2b474ed3675775f51de695b779ffcbe59c44056c97bf43c9249cc8d\",\n    \"wtxid\": \"65ea0b1a4e47a4f1e53c4c76f5e18fbe6b61fa32a654b1f016b76c20b3dc8cb3\",\n    \"alternate_wtxids\": [\n    ],\n    \"walletconflicts\": [\n    ],\n    \"mempoolconflicts\": [\n    ],\n    \"time\": 1787331293,\n    \"timereceived\": 1787331293\n  },\n  {\n    \"address\": \"bcrt1q0vwvq26wqsff6fca92scc3355562l6l9ru0vwy\",\n    \"category\": \"send\",\n    \"amount\": -2.00000000,\n    \"label\": \"\",\n    \"vout\": 0,\n    \"fee\": -0.00002820,\n    \"confirmations\": 0,\n    \"trusted\": true,\n    \"txid\": \"aa3acf06a2b474ed3675775f51de695b779ffcbe59c44056c97bf43c9249cc8d\",\n    \"wtxid\": \"65ea0b1a4e47a4f1e53c4c76f5e18fbe6b61fa32a654b1f016b76c20b3dc8cb3\",\n    \"alternate_wtxids\": [\n    ],\n    \"walletconflicts\": [\n    ],\n    \"mempoolconflicts\": [\n    ],\n    \"time\": 1787331293,\n    \"timereceived\": 1787331293,\n    \"abandoned\": false\n  }\n]\n```\n\nbitcoin-cli -regtest listrawtransactions\n\n``` bash\n./build_dev_mode/bin/bitcoin-cli -regtest -rpcwallet=my_wallet listrawtransactions\n[\n  {\n    \"amount\": 5.00000000,\n    \"confirmations\": 1,\n    \"blockhash\": \"38d06e1c5bde99df396bd60c4b54287e994aaa0cbd0c50061a8d92401e48f096\",\n    \"blockheight\": 102,\n    \"blockindex\": 4,\n    \"blocktime\": 1787331199,\n    \"txid\": \"3021a78312359fb6557ff2337404e9983420825cd3e6900b5ec8201a68d5d4de\",\n    \"wtxid\": \"139dd42c8088e50f3916bb1b93c4a84ac9f852a727c3aa70f7a9b7d818609552\",\n    \"alternate_wtxids\": [\n    ],\n    \"walletconflicts\": [\n    ],\n    \"mempoolconflicts\": [\n    ],\n    \"time\": 1787331105,\n    \"timereceived\": 1787331105,\n    \"abandoned\": false,\n    \"hex\": \"020000000001018ae67ec082ae5b4bfdd0a55eb30430835a4cd93077328bc69ad780d8e77b55c90100000000fdffffff020065cd1d0000000016001422015ad3f2d0ca03140fdc2077455c56351491bfac110295000000001600147aa249ffdc64983416f76a5c5d25f886639030f10247304402202998e2ab4d0ca0d1662a5765afac075971fc70a2b209ecbf9136268396f66b01022017427b04efdfb22ec0b06e306fa6537683043e2355686d30cfc423935f92c20c012102eb5f7f220b26583a40475a46682a589e3ae3274d4ad09debaabf61d08f8ca92500000000\"\n  },\n  {\n    \"amount\": 10.00000000,\n    \"confirmations\": 1,\n    \"blockhash\": \"38d06e1c5bde99df396bd60c4b54287e994aaa0cbd0c50061a8d92401e48f096\",\n    \"blockheight\": 102,\n    \"blockindex\": 5,\n    \"blocktime\": 1787331199,\n    \"txid\": \"097ca684069f02817c36ea61bbd155782293802764d6505a991b0c9dd408fc74\",\n    \"wtxid\": \"39276f39bbe1e1e20d88e53cfe577e5a2c875faf965a30b3999327e9b32380e3\",\n    \"alternate_wtxids\": [\n    ],\n    \"walletconflicts\": [\n    ],\n    \"mempoolconflicts\": [\n    ],\n    \"time\": 1787331105,\n    \"timereceived\": 1787331105,\n    \"abandoned\": false,\n    \"hex\": \"0200000000010275faff94cf8bdd5e593af300a9cc554a03b7c7c04ec8dd2337eb7982113eaf450000000000fdffffff631c2e7eeea13598244721c1767be13a4afe739dabde0a6ee767311b38ca3c820100000000fdffffff02209ccb1d0000000016001487afa811c32f2aabf8cdd6c96cf1c8daaae2d12e00ca9a3b000000001600141628c571f5c93d5520f881920d9680ee73ee154002473044022033c6120fc7a5a223a5c2c4482e28fdfad0a259f8d9a555a14189a041b1190942022067047e825bac1e2878dedd4b2729e9e7cfc0e8a17608519bd3725aa34948e8e001210241e7b7b792252c35d40d131fb1d3aecf3196095d6f1a4df696525c1ce14412f302473044022008622e5c03f0deb65388faefa4418aefdbaa64972d1cc67965d3d807e72eeefb022014e42955657f929142cd0a2ef0d3ceb4d34afddcea35e21f26c579a2c87fdeeb01210381f2fa33f5a95ff2cc944b89747a8578f72119f2311c6ea26b154d2c578f717e00000000\"\n  },\n  {\n    \"amount\": 0.00000000,\n    \"fee\": -0.00002820,\n    \"confirmations\": 0,\n    \"trusted\": true,\n    \"txid\": \"aa3acf06a2b474ed3675775f51de695b779ffcbe59c44056c97bf43c9249cc8d\",\n    \"wtxid\": \"65ea0b1a4e47a4f1e53c4c76f5e18fbe6b61fa32a654b1f016b76c20b3dc8cb3\",\n    \"alternate_wtxids\": [\n    ],\n    \"walletconflicts\": [\n    ],\n    \"mempoolconflicts\": [\n    ],\n    \"time\": 1787331293,\n    \"timereceived\": 1787331293,\n    \"abandoned\": false,\n    \"hex\": \"02000000000101ded4d5681a20c85e0b90e6d35c82203498e9047433f27f55b69f351283a721300000000000fdffffff0200c2eb0b000000001600147b1cc02b4e04129d271d2aa18c4634a534afebe5fc97e1110000000016001417e7b4daa467249ad1db13c1022d9079e5abb0e302473044022057c38c69acb5c1ff73f89842c6f5f46459069f2d26b29c4fc4defc6d8f47a277022041f8331d2c442ec6b7b431c15ea6d7621bfceae231821a59bbade8778f67b3460121036b245d774b4e83f854f8684cf839574358174d4d3a3232b59f4e794f2da4c06266000000\"\n  }\n]\n```\n\n**Self-send (single entry with `amount: 0`)**\n\n**Pagination**\n\nThe RPC behaves as described and makes internal transfers / consolidations visible."
  },
  {
   "t": "2026-08-25T23:36:22Z",
   "kind": "review",
   "who": "w0xlt",
   "assoc": "CONTRIBUTOR",
   "state": "COMMENTED",
   "commit": "f7f4bf67f7ffa66e05c142257fd281baf57b4ff2",
   "text": "ACK f7f4bf67f7ffa66e05c142257fd281baf57b4ff2"
  },
  {
   "t": "2026-08-26T15:43:50Z",
   "kind": "review_comment",
   "who": "polespinasa",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "0e539c51e096db9c6787f00957b20d418f46bb04",
   "in_reply_to": null,
   "text": "in 1fa34d1057843854f20ad35f7250ab2f8a7cb575 wallet, rpc: Add listrawtransactions RPC\n\nI would use `verbosity` to be consistent with other RPC calls with the same arg (see `getrawtransaction`).\nAlso, we normally have multiple levels of verbosity. I would suggest use a numeric type here with 0, 1 or 2, and give different type of information depending on that level. This again being consistent with what `getrawtransaction` does."
  },
  {
   "t": "2026-08-26T16:31:08Z",
   "kind": "review_comment",
   "who": "polespinasa",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "0e539c51e096db9c6787f00957b20d418f46bb04",
   "in_reply_to": null,
   "text": "in 1fa34d1057843854f20ad35f7250ab2f8a7cb575 wallet, rpc: Add listrawtransactions RPC\n\nWorth adding that it is a negative value. See `listtransactions` `fee` description:\n```json\n    \"fee\" : n,                       (numeric, optional) The amount of the fee in BTC. This is negative and only available for the\n                                     'send' category of transactions.\n\n```"
  },
  {
   "t": "2026-08-26T16:38:24Z",
   "kind": "review_comment",
   "who": "polespinasa",
   "assoc": "MEMBER",
   "path": "doc/release-notes-35813.md",
   "commit": "0e539c51e096db9c6787f00957b20d418f46bb04",
   "in_reply_to": null,
   "text": "in f7f4bf67f7ffa66e05c142257fd281baf57b4ff2 doc: Add release notes for listrawtransactions\n\nThe release note misdescribe amount and fee.\n\nFor `amount` should mention that it excludes the fee. And should mention that the fee is optional and only appears if the wallet funded the transaction."
  },
  {
   "t": "2026-08-26T16:40:17Z",
   "kind": "review_comment",
   "who": "polespinasa",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "1fa34d1057843854f20ad35f7250ab2f8a7cb575",
   "in_reply_to": null,
   "text": "in 1fa34d1057843854f20ad35f7250ab2f8a7cb575 wallet, rpc: Add listrawtransactions RPC\n\nShould mention \"excluding fee\"."
  },
  {
   "t": "2026-08-26T16:41:08Z",
   "kind": "review_comment",
   "who": "polespinasa",
   "assoc": "MEMBER",
   "path": "test/functional/wallet_listrawtransactions.py",
   "commit": "e6a746af1a00400595caa2e816b617ea619d0ba1",
   "in_reply_to": null,
   "text": "in e6a746af1a00400595caa2e816b617ea619d0ba1 test: Add functional test for listrawtransactions\n\nIIRC we use `Decimal` not `Float` for bitcoin amounts."
  },
  {
   "t": "2026-08-26T16:43:06Z",
   "kind": "review",
   "who": "polespinasa",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "f7f4bf67f7ffa66e05c142257fd281baf57b4ff2",
   "text": "concept ACK"
  },
  {
   "t": "2026-08-26T17:28:06Z",
   "kind": "comment",
   "who": "polespinasa",
   "assoc": "MEMBER",
   "text": "There is some code duplications between `listtransactions` and `listrawtransaction` some static helper function would probably make it more clean and readable.\n\ndiff\n\n```diff\n$ git diff\ndiff --git a/src/wallet/rpc/transactions.cpp b/src/wallet/rpc/transactions.cpp\nindex d95e8b5bb2..a84632ba87 100644\n--- a/src/wallet/rpc/transactions.cpp\n+++ b/src/wallet/rpc/transactions.cpp\n@@ -387,6 +387,47 @@ static void ListTransactions(const CWallet& wallet, const CWalletTx& wtx, int nM\n     }\n }\n\n+static void PushTxAmountAndFee(const CWallet& wallet, const CWalletTx& wtx, UniValue& entry)\n+    EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)\n+{\n+    CAmount credit = CachedTxGetCredit(wallet, wtx, /*avoid_reuse=*/false);\n+    CAmount debit = CachedTxGetDebit(wallet, wtx, /*avoid_reuse=*/false);\n+    CAmount net = credit - debit;\n+    bool is_from_me = CachedTxIsFromMe(wallet, wtx);\n+    CAmount fee = (is_from_me ? wtx.GetTx()->GetValueOut() - debit : 0);\n+\n+    entry.pushKV(\"amount\", ValueFromAmount(net - fee));\n+    if (is_from_me)\n+        entry.pushKV(\"fee\", ValueFromAmount(fee));\n+}\n+\n+static void PushTxDecoded(const CWallet& wallet, const CWalletTx& wtx, UniValue& entry)\n+    EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)\n+{\n+    UniValue decoded(UniValue::VOBJ);\n+    TxToUniv(*wtx.GetTx(),\n+            /*block_hash=*/uint256(),\n+            /*entry=*/decoded,\n+            /*include_hex=*/false,\n+            /*txundo=*/nullptr,\n+            /*verbosity=*/TxVerbosity::SHOW_DETAILS,\n+            /*is_change_func=*/[&wallet](const CTxOut& txout) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet) {\n+                                    AssertLockHeld(wallet.cs_wallet);\n+                                    return OutputIsChange(wallet, txout);\n+                                });\n+    entry.pushKV(\"decoded\", std::move(decoded));\n+}\n+\n /**\n  * Append a raw transaction entry for the given wallet transaction to ret.\n  *\n@@ -401,33 +442,14 @@ static void ListRawTransaction(const CWallet& wallet, const CWalletTx& wtx, Vec&\n {\n     UniValue entry(UniValue::VOBJ);\n\n-    CAmount credit = CachedTxGetCredit(wallet, wtx, /*avoid_reuse=*/false);\n-    CAmount debit = CachedTxGetDebit(wallet, wtx, /*avoid_reuse=*/false);\n-    CAmount net = credit - debit;\n-    bool is_from_me = CachedTxIsFromMe(wallet, wtx);\n-    CAmount fee = (is_from_me ? wtx.GetTx()->GetValueOut() - debit : 0);\n-\n-    entry.pushKV(\"amount\", ValueFromAmount(net - fee));\n-    if (is_from_me)\n-        entry.pushKV(\"fee\", ValueFromAmount(fee));\n+    PushTxAmountAndFee(wallet, wtx, entry);\n\n     WalletTxToJSON(wallet, wtx, entry);\n     entry.pushKV(\"abandoned\", wtx.isAbandoned());\n     entry.pushKV(\"hex\", EncodeHexTx(*wtx.GetTx()));\n\n     if (verbose) {\n-        UniValue decoded(UniValue::VOBJ);\n-        TxToUniv(*wtx.GetTx(),\n-                /*block_hash=*/uint256(),\n-                /*entry=*/decoded,\n-                /*include_hex=*/false,\n-                /*txundo=*/nullptr,\n-                /*verbosity=*/TxVerbosity::SHOW_DETAILS,\n-                /*is_change_func=*/[&wallet](const CTxOut& txout) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet) {\n-                                        AssertLockHeld(wallet.cs_wallet);\n-                                        return OutputIsChange(wallet, txout);\n-                                    });\n-        entry.pushKV(\"decoded\", std::move(decoded));\n+        PushTxDecoded(wallet, wtx, entry);\n     }\n\n     ret.push_back(std::move(entry));\n@@ -891,14 +913,7 @@ RPCMethod gettransaction()\n     }\n     const CWalletTx& wtx = it->second;\n\n-    CAmount nCredit = CachedTxGetCredit(*pwallet, wtx, /*avoid_reuse=*/false);\n-    CAmount nDebit = CachedTxGetDebit(*pwallet, wtx, /*avoid_reuse=*/false);\n-    CAmount nNet = nCredit - nDebit;\n-    CAmount nFee = (CachedTxIsFromMe(*pwallet, wtx) ? wtx.GetTx()->GetValueOut() - nDebit : 0);\n-\n-    entry.pushKV(\"amount\", ValueFromAmount(nNet - nFee));\n-    if (CachedTxIsFromMe(*pwallet, wtx))\n-        entry.pushKV(\"fee\", ValueFromAmount(nFee));\n+    PushTxAmountAndFee(*pwallet, wtx, entry);\n\n     WalletTxToJSON(*pwallet, wtx, entry);\n\n@@ -909,18 +924,7 @@ RPCMethod gettransaction()\n     entry.pushKV(\"hex\", EncodeHexTx(*wtx.GetTx()));\n\n     if (verbose) {\n-        UniValue decoded(UniValue::VOBJ);\n-        TxToUniv(*wtx.GetTx(),\n-                /*block_hash=*/uint256(),\n-                /*entry=*/decoded,\n-                /*include_hex=*/false,\n-                /*txundo=*/nullptr,\n-                /*verbosity=*/TxVerbosity::SHOW_DETAILS,\n-                /*is_change_func=*/[&pwallet](const CTxOut& txout) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) {\n-                                        AssertLockHeld(pwallet->cs_wallet);\n-                                        return OutputIsChange(*pwallet, txout);\n-                                    });\n-        entry.pushKV(\"decoded\", std::move(decoded));\n+        PushTxDecoded(*pwallet, wtx, entry);\n     }\n\n     AppendLastProcessedBlock(entry, *pwallet);\n\n```"
  },
  {
   "t": "2026-08-27T03:00:18Z",
   "kind": "comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nThanks for looking at that with detail... I'll make this refactoring...  small nit on the prose: this is dedup between `gettransaction` and `ListRawTransaction`, not `listtransactions` \u2014 the diff itself is exactly right though \u2014 mostly so nobody skimming the thread later comes away thinking `ListTransactions`'s own logic was in scope, since it genuinely does something different (per-output category splitting via `CachedTxGetAmounts`, not the net credit/debit approach the other two share).\n\nI'll land this as a prep commit before the rest, so `gettransaction` gets the helpers extracted first and `listrawtransactions` is introduced already using them (via `ListRawTransaction`), rather than duplicating the logic and cleaning it up after."
  },
  {
   "t": "2026-08-27T03:24:30Z",
   "kind": "force_push",
   "who": "pablomartin4btc",
   "commit": "1a03da3ade34455818c0da09bacf337edba8f921"
  },
  {
   "t": "2026-08-27T03:35:47Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "0e539c51e096db9c6787f00957b20d418f46bb04",
   "in_reply_to": 3864395452,
   "text": "I think `getrawtransaction`'s `verbosity`=2 exists mainly because `fee` and `prevout` there both need the same block-undo-data read \u2014 `verbosity`=1 never reads it, so bundling them at one tier avoids doing that read twice.\n\n`listrawtransactions` doesn't have that constraint: its `fee` already comes from the wallet's own accounting (`CachedTxGetCredit`/`CachedTxGetDebit`), no `prevout` lookup needed. A `prevout` tier here would only help with a niche case (seeing each input's source `address`/ `amount`), and unlike `getrawtransaction` (one tx per call), this RPC can decode up to `count` transactions per call, so that lookup cost multiplies.\n\nI'd keep `verbose` as a `bool`, matching `gettransaction` \u2014 `listrawtransactions` is already following the right sibling."
  },
  {
   "t": "2026-08-27T03:37:09Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "0e539c51e096db9c6787f00957b20d418f46bb04",
   "in_reply_to": 3864732146,
   "text": "Done in 304596b3083b100df34f53ae543be50c70135ca5, thanks!"
  },
  {
   "t": "2026-08-27T03:37:33Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "doc/release-notes-35813.md",
   "commit": "0e539c51e096db9c6787f00957b20d418f46bb04",
   "in_reply_to": 3864784032,
   "text": "Done in 1a03da3ade34455818c0da09bacf337edba8f921, thanks!"
  },
  {
   "t": "2026-08-27T03:38:01Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "1fa34d1057843854f20ad35f7250ab2f8a7cb575",
   "in_reply_to": 3864797889,
   "text": "Done in 304596b3083b100df34f53ae543be50c70135ca5, thanks!"
  },
  {
   "t": "2026-08-27T03:38:27Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "test/functional/wallet_listrawtransactions.py",
   "commit": "e6a746af1a00400595caa2e816b617ea619d0ba1",
   "in_reply_to": 3864803696,
   "text": "Done in 5617c172a47f4c969c9834d97020fcb5f40710e0, thanks!"
  },
  {
   "t": "2026-08-27T03:47:46Z",
   "kind": "comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "text": "-<ins>_**Updates**_</ins>:\n- Addressed @polespinasa's feedback [here](https://github.com/bitcoin/bitcoin/pull/35813#pullrequestreview-5032397115) and regarding a refactoring [here](https://github.com/bitcoin/bitcoin/pull/35813#issuecomment-5433801756):\n  - `fee` doc: now notes it's negative, matching `gettransaction`'s wording.\n  - `amount'`s help text and the release note now both mention it excludes the fee.\n  - Release note: also clarifies fee is only present (and negative) when the wallet funded the transaction.\n  - Test: dropped an unnecessary `float()` cast on `total - fee` \u2014 kept as `Decimal`, per convention.\n  - `verbose`/ `verbosity`: kept `verbose` as a `bool`, matching `gettransaction` rather than `getrawtransaction` \u2014 explained the reasoning in the [thread](https://github.com/bitcoin/bitcoin/pull/35813#discussion_r3868509901) (this RPC's `fee` doesn't depend on `prevout` data the way `getrawtransaction`'s does, so the usual reason for a numeric tier doesn't transfer here).\n  - Refactoring: extracted `PushTxAmountAndFee`/ `PushTxDecoded` static helpers shared between `gettransaction` and `ListRawTransactions`, landed as a prep commit ahead of the RPC commit."
  },
  {
   "t": "2026-08-27T05:19:04Z",
   "kind": "review",
   "who": "w0xlt",
   "assoc": "CONTRIBUTOR",
   "state": "COMMENTED",
   "commit": "1a03da3ade34455818c0da09bacf337edba8f921",
   "text": "reACK 1a03da3ade34455818c0da09bacf337edba8f921"
  },
  {
   "t": "2026-08-27T07:24:13Z",
   "kind": "review_comment",
   "who": "polespinasa",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "304596b3083b100df34f53ae543be50c70135ca5",
   "in_reply_to": null,
   "text": "in 304596b3083b100df34f53ae543be50c70135ca5 wallet, rpc: Add listrawtransactions RPC\n\nGiven how small this function is and given that it is only used inside `RPCMethod listrawtransactions()` it can probably be a lamda function inside it.\n\nsuggested diff\n\n```diff\n$ git diff\ndiff --git a/src/wallet/rpc/transactions.cpp b/src/wallet/rpc/transactions.cpp\nindex 0602ede8e2..cdde1774f0 100644\n--- a/src/wallet/rpc/transactions.cpp\n+++ b/src/wallet/rpc/transactions.cpp\n@@ -418,33 +418,6 @@ static void PushTxDecoded(const CWallet& wallet, const CWalletTx& wtx, UniValue&\n     entry.pushKV(\"decoded\", std::move(decoded));\n }\n\n-/**\n- * Append a raw transaction entry for the given wallet transaction to ret.\n- *\n- * @param  wallet         The wallet.\n- * @param  wtx            The wallet transaction.\n- * @param  ret            Output vector to append the entry to.\n- * @param  verbose        If true, include a decoded transaction object.\n- */\n-template <class Vec>\n-static void ListRawTransaction(const CWallet& wallet, const CWalletTx& wtx, Vec& ret, bool verbose)\n-    EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)\n-{\n-    UniValue entry(UniValue::VOBJ);\n-\n-    PushTxAmountAndFee(wallet, wtx, entry);\n-\n-    WalletTxToJSON(wallet, wtx, entry);\n-    entry.pushKV(\"abandoned\", wtx.isAbandoned());\n-    entry.pushKV(\"hex\", EncodeHexTx(*wtx.GetTx()));\n-\n-    if (verbose) {\n-        PushTxDecoded(wallet, wtx, entry);\n-    }\n-\n-    ret.push_back(std::move(entry));\n-}\n-\n static std::vector<RPCResult> TransactionDescriptionString()\n {\n     return{{RPCResult::Type::NUM, \"confirmations\", \"The number of confirmations for the transaction. Negative confirmations means the\\n\"\n@@ -660,12 +633,23 @@ RPCMethod listrawtransactions()\n\n         const CWallet::TxItems& tx_ordered = pwallet->wtxOrdered;\n\n+        auto list_raw_tx = [&](const CWalletTx& wtx) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) {\n+            UniValue entry(UniValue::VOBJ);\n+            PushTxAmountAndFee(*pwallet, wtx, entry);\n+            WalletTxToJSON(*pwallet, wtx, entry);\n+            entry.pushKV(\"abandoned\", wtx.isAbandoned());\n+            entry.pushKV(\"hex\", EncodeHexTx(*wtx.GetTx()));\n+            if (verbose) {\n+                PushTxDecoded(*pwallet, wtx, entry);\n+            }\n+            ret.push_back(std::move(entry));\n+        };\n+\n         int skipped = 0;\n         for (CWallet::TxItems::const_reverse_iterator it = tx_ordered.rbegin(); it != tx_ordered.rend(); ++it) {\n             if ((int)ret.size() >= count) break;\n             if (skipped++ < skip) continue;\n-            CWalletTx* const pwtx = (*it).second;\n-            ListRawTransaction(*pwallet, *pwtx, ret, verbose);\n+            list_raw_tx(*(*it).second);\n         }\n     }\n\n```"
  },
  {
   "t": "2026-08-27T07:30:33Z",
   "kind": "review_comment",
   "who": "polespinasa",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "304596b3083b100df34f53ae543be50c70135ca5",
   "in_reply_to": null,
   "text": "in 304596b wallet, rpc: Add listrawtransactions RPC\n\n`parent_descs` field is included in the documentation but it never can appear.\n`TransactionDescriptionString` adds `parent_descs` field, but as we are using `WalletTxToJSON()` (doesn't call `PushParentDescriptors()`) it never can have `parent_descs` field.\n\n```json\nknown.\n    \"parent_descs\" : [                (json array, optional) List of parent descriptors for the output script of this coin.\n      \"str\",                          (string) The descriptor string.\n      ...\n    ],\n\n```"
  },
  {
   "t": "2026-08-27T07:32:05Z",
   "kind": "review_comment",
   "who": "polespinasa",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "304596b3083b100df34f53ae543be50c70135ca5",
   "in_reply_to": null,
   "text": "in 304596b wallet, rpc: Add listrawtransactions RPC\n\nThis template is not necessary as the function is only called with `vector<UniValue>`.\nFixed also in this suggestion https://github.com/bitcoin/bitcoin/pull/35813/changes/304596b3083b100df34f53ae543be50c70135ca5#r3869588711"
  },
  {
   "t": "2026-08-27T18:03:12Z",
   "kind": "force_push",
   "who": "pablomartin4btc",
   "commit": "c08e90f07a033827f75274e4252f9f392aeb7697"
  },
  {
   "t": "2026-08-27T18:32:00Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "304596b3083b100df34f53ae543be50c70135ca5",
   "in_reply_to": 3869639206,
   "text": "Good catch! Originally matching `listtransactions` RPC `, but ListTransactions` is called from several places with different types: only `listtransactions` passes `std::vector<UniValue>` \u2014 `listsinceblock` (`transactions`/ `removed`) and `gettransaction` (`details`) all pass a plain `UniValue` (`UniValue::VARR`).\n\nDone in 2f302a90f2acd8c8a166dcca6e446ff810569970, thanks!"
  },
  {
   "t": "2026-08-27T18:36:45Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "304596b3083b100df34f53ae543be50c70135ca5",
   "in_reply_to": 3869629044,
   "text": "Done in 978fac7a586395b770f609756ef591c758b76254, as a prep commit since I had to touch `TransactionDescriptionString`, thanks!"
  },
  {
   "t": "2026-08-27T18:44:21Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "304596b3083b100df34f53ae543be50c70135ca5",
   "in_reply_to": 3869588711,
   "text": "Thanks for the suggestion \u2014 I'd like to keep it as a named function rather than inline it, for a few reasons:\n\n- Every other per-entry builder in this file (`ListTransactions`, `ListReceived`, and the `PushTxAmountAndFee`/`PushTxDecoded` helpers just extracted from `gettransaction`) is a free `static` function, not a lambda. `listrawtransactions` deliberately mirrors `listtransactions`'s shape (same iteration/pagination structure, just one entry per tx instead of one per category-split), so keeping `ListRawTransaction` named keeps that parallel intact.\n- The doc comment above it (`@param wallet`, `@param verbose`, etc.) reads naturally on a named function; it doesn't attach as cleanly to a lambda assignment.\n- Keeping the per-entry formatting logic out of the RPC handler's body keeps that lambda focused purely on iteration/pagination (skip/count/`wtxOrdered` traversal) \u2014 inlining would mix those two concerns back together.\n- `ListRawTransaction` could be a natural candidate to gain a second caller later; keeping it named avoids repeating that extraction.\n\nI did take the related [point](https://github.com/bitcoin/bitcoin/pull/35813#discussion_r3869639206) about the `Vec` template though \u2014 since it only has one caller today (unlike `ListTransactions`, which genuinely needs the template because `listsinceblock` passes a plain `UniValue` instead of a `std::vector<UniValue>`), I dropped it [in favour](https://github.com/bitcoin/bitcoin/pull/35813#discussion_r3874744857) of a concrete `std::vector<UniValue>&` parameter."
  },
  {
   "t": "2026-08-27T18:50:35Z",
   "kind": "comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "text": "<ins>Updates</ins>:\n- Addressed @polespinasa's latest feedback:\n  - Vec [template](https://github.com/bitcoin/bitcoin/pull/35813#discussion_r3869639206) on `ListRawTransaction`: dropped it \u2014 only ever instantiated with `std::vector<UniValue>`, unlike `ListTransactions` which genuinely needs it (`listsinceblock`/ `gettransaction` pass a plain `UniValue`). Done in 2f302a9.\n  - [`parent_descs`](https://github.com/bitcoin/bitcoin/pull/35813#discussion_r3869629044): confirmed a real doc bug \u2014 it was documented as a possible field on `listrawtransactions` but can never appear, since it's only populated by `ListTransactions`'s per-output \"received\" branch, which this RPC never goes through. Added an `include_parent_descs` param to `TransactionDescriptionString` (default true, preserving current behaviour elsewhere), landed as its own prep commit (978fac7a5) since it touches pre-existing shared code.\n  - Lambda [suggestion](https://github.com/bitcoin/bitcoin/pull/35813#discussion_r3869588711) for `ListRawTransaction`: kept it as a named free function instead \u2014 explained the reasoning in the [thread](https://github.com/bitcoin/bitcoin/pull/35813#discussion_r3874838490) (consistency with `ListTransactions`/ `PushTxAmountAndFee`/ `PushTxDecoded`, the doc comment attaching more naturally to a named function, and keeping the RPC lambda's body focused purely on pagination)."
  },
  {
   "t": "2026-08-28T09:50:51Z",
   "kind": "review_comment",
   "who": "polespinasa",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "2f302a90f2acd8c8a166dcca6e446ff810569970",
   "in_reply_to": null,
   "text": "in 2f302a90f2acd8c8a166dcca6e446ff810569970 wallet, rpc: Add listrawtransactions RPC\n\nnit: this could avoid an unnecessary copy by using `std::make_move_iterator`, similar to what `listtransactions` uses:\n```diff\n$ git diff\ndiff --git a/src/wallet/rpc/transactions.cpp b/src/wallet/rpc/transactions.cpp\nindex 3ffc51bc5a..21fed23bbc 100644\n--- a/src/wallet/rpc/transactions.cpp\n+++ b/src/wallet/rpc/transactions.cpp\n@@ -672,7 +672,7 @@ RPCMethod listrawtransactions()\n     }\n\n     UniValue result{UniValue::VARR};\n-    result.push_backV(ret.rbegin(), ret.rend());\n+    result.push_backV(std::make_move_iterator(ret.rbegin()), std::make_move_iterator(ret.rend()));\n     return result;\n },\n     };\n```"
  },
  {
   "t": "2026-08-28T09:52:02Z",
   "kind": "review",
   "who": "polespinasa",
   "assoc": "MEMBER",
   "state": "APPROVED",
   "commit": "c08e90f07a033827f75274e4252f9f392aeb7697",
   "text": "ACK c08e90f07a033827f75274e4252f9f392aeb7697\n\nThanks for addressing feedback, lgtm now :)\n\nJust left a small nit, feel free to ignore."
  },
  {
   "t": "2026-08-28T14:02:45Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "2f302a90f2acd8c8a166dcca6e446ff810569970",
   "in_reply_to": 3879645586,
   "text": "Thanks, I'll take it \u2014 I think it's worth fixing now, especially since `listtransactions` already uses the same mechanism."
  },
  {
   "t": "2026-08-28T14:05:04Z",
   "kind": "force_push",
   "who": "pablomartin4btc",
   "commit": "0e539c51e096db9c6787f00957b20d418f46bb04"
  },
  {
   "t": "2026-08-28T14:07:22Z",
   "kind": "review_comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "path": "src/wallet/rpc/transactions.cpp",
   "commit": "2f302a90f2acd8c8a166dcca6e446ff810569970",
   "in_reply_to": 3879645586,
   "text": "Done, thanks!"
  },
  {
   "t": "2026-08-28T14:08:16Z",
   "kind": "comment",
   "who": "pablomartin4btc",
   "assoc": "MEMBER",
   "text": "-<ins>_**Updates**_</ins>:\n- Addressed @polespinasa's [nit](https://github.com/bitcoin/bitcoin/pull/35813#discussion_r3879645586):\n  - `listrawtransactions`: use std::`make_move_iterator` when pushing the result vector, avoiding an unnecessary copy \u2014 matching the same pattern already used by `listtransactions`."
  },
  {
   "t": "2026-08-28T14:10:50Z",
   "kind": "comment",
   "who": "polespinasa",
   "assoc": "MEMBER",
   "text": "ACK 0e539c51e096db9c6787f00957b20d418f46bb04"
  },
  {
   "t": "2026-09-17T09:37:35Z",
   "kind": "review",
   "who": "Bicaru20",
   "assoc": "CONTRIBUTOR",
   "state": "COMMENTED",
   "commit": "0e539c51e096db9c6787f00957b20d418f46bb04",
   "text": "reACK 0e539c51e096db9c6787f00957b20d418f46bb04.\n\nI agree with the new changes since my last review and the approach taken."
  }
 ],
 "labels_log": [
  {
   "t": "2026-07-26T17:08:41Z",
   "action": "labeled",
   "label": "Wallet",
   "who": "DrahtBot"
  },
  {
   "t": "2026-07-26T17:11:59Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-07-26T23:20:28Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-07-28T00:39:52Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-07-28T01:39:40Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-11T03:18:49Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-08-11T04:46:02Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-09-09T20:55:38Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  }
 ],
 "state_log": [
  {
   "t": "2026-07-26T23:38:22Z",
   "kind": "renamed",
   "who": "pablomartin4btc",
   "from": "wallet: Add listrawtransactions RPC",
   "to": "wallet, rpc: Add listrawtransactions RPC"
  }
 ],
 "text_chars": 46977,
 "text_tokens_estimate": 11744,
 "changed_paths": [
  "doc/release-notes-35813.md",
  "src/rpc/client.cpp",
  "src/wallet/rpc/transactions.cpp",
  "src/wallet/rpc/wallet.cpp",
  "test/functional/test_runner.py",
  "test/functional/wallet_listrawtransactions.py"
 ],
 "files": [
  {
   "path": "doc/release-notes-35813.md",
   "add": 12,
   "del": 0
  },
  {
   "path": "src/rpc/client.cpp",
   "add": 3,
   "del": 0
  },
  {
   "path": "src/wallet/rpc/transactions.cpp",
   "add": 152,
   "del": 27
  },
  {
   "path": "src/wallet/rpc/wallet.cpp",
   "add": 2,
   "del": 0
  },
  {
   "path": "test/functional/test_runner.py",
   "add": 1,
   "del": 0
  },
  {
   "path": "test/functional/wallet_listrawtransactions.py",
   "add": 164,
   "del": 0
  }
 ],
 "test_lines": 165,
 "git": {
  "head": "0e539c51e096db9c6787f00957b20d418f46bb04",
  "head_matches_backup": true,
  "base": "1d386c250f222ad12b61a530af1ad673b3621ad5",
  "commits": [
   {
    "sha": "8c9d360058",
    "subject": "wallet, rpc: extract PushTxAmountAndFee/PushTxDecoded helpers",
    "files": 1,
    "add": 33,
    "del": 20
   },
   {
    "sha": "978fac7a58",
    "subject": "wallet, rpc: allow omitting parent_descs from TransactionDescriptionString",
    "files": 1,
    "add": 8,
    "del": 5
   },
   {
    "sha": "024f8eae00",
    "subject": "wallet, rpc: Add listrawtransactions RPC",
    "files": 3,
    "add": 116,
    "del": 2
   },
   {
    "sha": "4cc29809df",
    "subject": "test: Add functional test for listrawtransactions",
    "files": 2,
    "add": 165,
    "del": 0
   },
   {
    "sha": "0e539c51e0",
    "subject": "doc: Add release notes for listrawtransactions",
    "files": 1,
    "add": 12,
    "del": 0
   }
  ],
  "patch_truncated": false
 },
 "input_hash": "7dfcb7a83d6666fa",
 "extracted_at": "2026-09-17T16:15:31+00:00"
}