Skip to content

feat(key-wallet): fund transactions from several account types - #925

Merged
QuantumExplorer merged 2 commits into
devfrom
feat/multi-account-tx-funding
Aug 7, 2026
Merged

feat(key-wallet): fund transactions from several account types#925
QuantumExplorer merged 2 commits into
devfrom
feat/multi-account-tx-funding

Conversation

@ZocoLini

@ZocoLini ZocoLini commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator
  • Multi-account funding: build_and_sign_transaction takes sources: &[AccountTypePreference] and pools those accounts' UTXOs. Empty list = every account type present at the index.
  • set_fundingadd_funding, additive: called once per funding account, first one gives the change address. Input derivation paths are collected across accounts for signing.
  • One reservation token per build, not per reserve call: each account reserves only the inputs it contributed, in its own set, all stamped with the same token. reserve now takes the owner, and the counter behind it is process-wide (per-set counters would mint colliding tokens across accounts, reopening the feat(key-wallet): owner-tagged reservations to close the broadcast-release TOCTOU (platform#4185) #916 race).

Summary by CodeRabbit

  • New Features

    • Transactions can now combine funding from multiple supported account types.
    • Added unsigned transaction building and multi-account signing support.
    • Default account selection now supports BIP44 and BIP32 accounts.
    • Explicit account preferences are supported when selecting funding sources.
  • Bug Fixes

    • Improved reservation tracking and cleanup when transactions use multiple accounts or signing fails.
    • Added clearer handling for unavailable funding accounts and invalid networks.

@github-actions github-actions Bot added the merge-conflict The PR conflicts with the target branch. label Aug 5, 2026
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

This PR has merge conflicts with the base branch. Please rebase or merge the base branch into your branch to resolve them.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 4a564cf1-5f1f-41b1-a39e-e1a2a878e790

📥 Commits

Reviewing files that changed from the base of the PR and between 97c80a5 and f683b1b.

📒 Files selected for processing (1)
  • key-wallet/src/wallet/managed_wallet_info/transaction_builder.rs

📝 Walkthrough

Walkthrough

Transaction building now supports multiple account preferences, pooled UTXO funding, per-account reservations, shared signing, and unsigned transaction construction. Reservation tokens use process-wide generation and explicit ownership. Call sites and tests use the updated APIs.

Changes

Multi-account transaction construction

Layer / File(s) Summary
Multi-account transaction API
key-wallet/src/wallet/managed_wallet_info/transaction_building.rs, key-wallet-manager/src/lib.rs
Transaction-building methods accept account preference slices, use default BIP44/BIP32 ordering when sources are empty, pool funding across available accounts, and track derivation paths.
Per-account funding and cleanup
key-wallet/src/wallet/managed_wallet_info/transaction_builder.rs, key-wallet/src/wallet/managed_wallet_info/asset_lock_builder.rs, key-wallet/src/managed_account/reservation.rs, key-wallet/src/tests/spent_outpoints_tests.rs
add_funding records funding by account, reserves selected inputs with one owner token, and releases reservations from all contributing accounts after signing failure. Reservation tokens use process-wide generation.
Integration and validation
key-wallet-ffi/src/transaction.rs, dash-spv/tests/dashd_sync/tests_transaction.rs
FFI and test call sites pass preference slices and use add_funding.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Wallet
  participant TransactionBuilding
  participant TransactionBuilder
  participant ReservationSet
  participant TransactionSigner
  Wallet->>TransactionBuilding: request transaction with account sources
  TransactionBuilding->>TransactionBuilder: add_funding for selected accounts
  TransactionBuilder->>ReservationSet: reserve selected outpoints
  TransactionBuilding->>TransactionSigner: sign inputs using derivation paths
  TransactionSigner-->>Wallet: signed transaction
  TransactionBuilding->>ReservationSet: release reservations if signing fails
Loading

Possibly related PRs

Suggested labels: ready-for-review

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: funding transactions from multiple account types.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/multi-account-tx-funding

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@key-wallet/src/wallet/managed_wallet_info/transaction_building.rs`:
- Around line 137-181: Prevent duplicate funding accounts from adding the same
outpoints twice: in
key-wallet/src/wallet/managed_wallet_info/transaction_building.rs lines 137-181,
reject or de-duplicate repeated entries in sources before the funding loop; in
key-wallet/src/wallet/managed_wallet_info/transaction_builder.rs lines 147-164,
enforce the one-call-per-funding-account rule by skipping accounts whose
outpoints are already present in self.funding. Use the existing funding and
add_funding logic without relying solely on documentation.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f9d6dbe2-206a-4460-9cca-1a5dd555e583

📥 Commits

Reviewing files that changed from the base of the PR and between 8f78baa and 0eca14a.

📒 Files selected for processing (6)
  • dash-spv/tests/dashd_sync/tests_transaction.rs
  • key-wallet-ffi/src/transaction.rs
  • key-wallet-manager/src/lib.rs
  • key-wallet/src/wallet/managed_wallet_info/asset_lock_builder.rs
  • key-wallet/src/wallet/managed_wallet_info/transaction_builder.rs
  • key-wallet/src/wallet/managed_wallet_info/transaction_building.rs

Comment thread key-wallet/src/wallet/managed_wallet_info/transaction_building.rs
@ZocoLini
ZocoLini force-pushed the feat/multi-account-tx-funding branch from 0eca14a to 546ac4c Compare August 6, 2026 07:16
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@github-actions github-actions Bot removed the merge-conflict The PR conflicts with the target branch. label Aug 6, 2026
@ZocoLini
ZocoLini marked this pull request as draft August 6, 2026 07:17

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
key-wallet/src/wallet/managed_wallet_info/asset_lock_builder.rs (1)

364-366: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Update the reservation_token field doc to match single_token().

The field doc at Line 114 states the token is None "if the funding account carried no reservation set." single_token() now returns None under two different conditions: the build reserved nothing, or the build spans several funding accounts. An asset lock always uses one funding account, so only the first condition applies here. Correct the wording so callers do not infer the old meaning.

📝 Proposed doc fix (applies to the unchanged field doc above)
     /// Owner token for the reservation this build took on the funding inputs,
-    /// or `None` if the funding account carried no reservation set.
+    /// or `None` if the build reserved no inputs.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@key-wallet/src/wallet/managed_wallet_info/asset_lock_builder.rs` around lines
364 - 366, Update the reservation_token field documentation near the managed
wallet asset-lock builder to describe None as meaning the build reserved
nothing, matching reservations.single_token(); do not document the
multiple-funding-account case because asset locks always use one funding
account.
key-wallet/src/wallet/managed_wallet_info/transaction_builder.rs (2)

1353-1354: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Rename the test to match the renamed API.

set_funding no longer exists. The test name set_funding_skips_reserved_utxos now points at a removed method, which makes the behavior harder to find after the rename.

♻️ Proposed rename
     #[test]
-    fn set_funding_skips_reserved_utxos() {
+    fn add_funding_skips_reserved_utxos() {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@key-wallet/src/wallet/managed_wallet_info/transaction_builder.rs` around
lines 1353 - 1354, Rename the test function set_funding_skips_reserved_utxos to
reference the current funding API name, while preserving its existing
reserved-UTXO behavior and test implementation.

1456-1467: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Bind the transaction without the underscore prefix.

The test binds _tx and then uses it at Line 1466 in funds.release_reservation_if_owner(&_tx, token). An underscore prefix signals an unused binding, so the name contradicts the use.

♻️ Proposed rename
-        let (_tx, _fee, reservations) = TransactionBuilder::new()
+        let (tx, _fee, reservations) = TransactionBuilder::new()
-        funds.release_reservation_if_owner(&_tx, token);
+        funds.release_reservation_if_owner(&tx, token);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@key-wallet/src/wallet/managed_wallet_info/transaction_builder.rs` around
lines 1456 - 1467, Rename the transaction binding in the test from _tx to tx,
and update the funds.release_reservation_if_owner call to pass tx while leaving
the reservation assertions unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@key-wallet/src/wallet/managed_wallet_info/asset_lock_builder.rs`:
- Around line 321-325: Update the reserved-builder documentation associated with
build_unsigned_reserved and related funding APIs: replace all stale set_funding
references with the current add_funding terminology, and document its third
return value as BuildReservations rather than Option<ReservationToken>. Keep the
implementation around build_signed_reserved unchanged.

In `@key-wallet/src/wallet/managed_wallet_info/transaction_builder.rs`:
- Around line 595-613: Update the opening documentation for
build_unsigned_reserved to describe its BuildReservations return value rather
than the obsolete ReservationToken/None behavior; state that empty reservations
represent no attached reservation set and that multiple funding-account entries
may be returned, while preserving the newer ownership and release guidance.

---

Nitpick comments:
In `@key-wallet/src/wallet/managed_wallet_info/asset_lock_builder.rs`:
- Around line 364-366: Update the reservation_token field documentation near the
managed wallet asset-lock builder to describe None as meaning the build reserved
nothing, matching reservations.single_token(); do not document the
multiple-funding-account case because asset locks always use one funding
account.

In `@key-wallet/src/wallet/managed_wallet_info/transaction_builder.rs`:
- Around line 1353-1354: Rename the test function
set_funding_skips_reserved_utxos to reference the current funding API name,
while preserving its existing reserved-UTXO behavior and test implementation.
- Around line 1456-1467: Rename the transaction binding in the test from _tx to
tx, and update the funds.release_reservation_if_owner call to pass tx while
leaving the reservation assertions unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 94cf12e5-7245-4308-a7bd-8864be84bc00

📥 Commits

Reviewing files that changed from the base of the PR and between 712bab1 and 546ac4c.

📒 Files selected for processing (7)
  • dash-spv/tests/dashd_sync/tests_transaction.rs
  • key-wallet-ffi/src/transaction.rs
  • key-wallet-manager/src/lib.rs
  • key-wallet/src/lib.rs
  • key-wallet/src/wallet/managed_wallet_info/asset_lock_builder.rs
  • key-wallet/src/wallet/managed_wallet_info/transaction_builder.rs
  • key-wallet/src/wallet/managed_wallet_info/transaction_building.rs
🚧 Files skipped from review as they are similar to previous changes (4)
  • key-wallet-manager/src/lib.rs
  • key-wallet-ffi/src/transaction.rs
  • dash-spv/tests/dashd_sync/tests_transaction.rs
  • key-wallet/src/wallet/managed_wallet_info/transaction_building.rs

Comment thread key-wallet/src/wallet/managed_wallet_info/asset_lock_builder.rs Outdated
Comment thread key-wallet/src/wallet/managed_wallet_info/transaction_builder.rs Outdated
@codecov

codecov Bot commented Aug 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.06383% with 21 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.19%. Comparing base (8f78baa) to head (f683b1b).
⚠️ Report is 7 commits behind head on dev.

Files with missing lines Patch % Lines
...wallet/managed_wallet_info/transaction_building.rs 88.09% 20 Missing ⚠️
key-wallet-ffi/src/transaction.rs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##              dev     #925      +/-   ##
==========================================
+ Coverage   74.75%   75.19%   +0.44%     
==========================================
  Files         328      328              
  Lines       76700    77767    +1067     
==========================================
+ Hits        57337    58477    +1140     
+ Misses      19363    19290      -73     
Flag Coverage Δ
core 77.29% <ø> (ø)
ffi 49.84% <0.00%> (+0.52%) ⬆️
rpc 20.00% <ø> (ø)
spv 91.24% <ø> (+0.18%) ⬆️
wallet 76.58% <91.45%> (+0.83%) ⬆️
Files with missing lines Coverage Δ
key-wallet-manager/src/lib.rs 76.07% <100.00%> (+1.25%) ⬆️
key-wallet/src/managed_account/reservation.rs 100.00% <100.00%> (ø)
...c/wallet/managed_wallet_info/asset_lock_builder.rs 89.61% <100.00%> (ø)
.../wallet/managed_wallet_info/transaction_builder.rs 88.96% <100.00%> (+1.62%) ⬆️
key-wallet-ffi/src/transaction.rs 0.00% <0.00%> (ø)
...wallet/managed_wallet_info/transaction_building.rs 93.81% <88.09%> (+5.94%) ⬆️

... and 39 files with indirect coverage changes

@ZocoLini
ZocoLini force-pushed the feat/multi-account-tx-funding branch 3 times, most recently from 36b86c0 to 032893d Compare August 6, 2026 09:59
@ZocoLini
ZocoLini marked this pull request as ready for review August 7, 2026 08:03
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
key-wallet/src/wallet/managed_wallet_info/transaction_building.rs (1)

157-201: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Nothing de-duplicates funding accounts, so one account's UTXOs can enter the candidate input set twice. add_funding appends unreserved UTXOs to self.inputs on every call, and reservation happens later in assemble_unsigned. A repeated funding account therefore appends the same outpoints again, and coin selection can select one outpoint twice, producing a transaction with duplicate inputs.

  • key-wallet/src/wallet/managed_wallet_info/transaction_building.rs#L157-L201: de-duplicate or reject repeated entries in preferences before the funding loop, so a caller-supplied duplicate cannot reach add_funding twice.
  • key-wallet/src/wallet/managed_wallet_info/transaction_builder.rs#L119-L136: enforce the documented "call it once per funding account" rule in code, for example by skipping an account whose outpoints already appear in self.funding.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@key-wallet/src/wallet/managed_wallet_info/transaction_building.rs` around
lines 157 - 201, Prevent duplicate funding accounts before they reach
add_funding: in
key-wallet/src/wallet/managed_wallet_info/transaction_building.rs:157-201,
de-duplicate or reject repeated entries in preferences; in
key-wallet/src/wallet/managed_wallet_info/transaction_builder.rs:119-136,
enforce the once-per-funding-account rule by skipping accounts whose outpoints
already exist in self.funding.
🧹 Nitpick comments (1)
key-wallet/src/wallet/managed_wallet_info/transaction_builder.rs (1)

450-466: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Consider returning the per-account reservation handles.

The build stamps one token across several sets, but the caller receives only the token. To release an abandoned multi-account build, the caller must re-resolve every funding account itself. Returning the contributing ReservationSet handles alongside the token would make cleanup self-contained. This is optional; the current API works if callers know their own sources list.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@key-wallet/src/wallet/managed_wallet_info/transaction_builder.rs` around
lines 450 - 466, Consider updating the reservation setup around
ReservationToken::next and the reservation_token return value to retain the
contributing ReservationSet handles alongside the shared owner token. Return
enough information for callers to release abandoned multi-account reservations
without re-resolving the funding accounts, while preserving the existing
behavior for empty funding and callers that already provide their own sources.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@key-wallet/src/wallet/managed_wallet_info/transaction_builder.rs`:
- Around line 504-505: Update the documentation near assemble_unsigned and
ManagedCoreFundsAccount::release_reservation_if_owner to instruct callers to
release the reservation token on every funding account, not only the first.
State that build_unsigned_reserved does not expose which accounts contributed,
so callers must track the contributing accounts independently.

---

Duplicate comments:
In `@key-wallet/src/wallet/managed_wallet_info/transaction_building.rs`:
- Around line 157-201: Prevent duplicate funding accounts before they reach
add_funding: in
key-wallet/src/wallet/managed_wallet_info/transaction_building.rs:157-201,
de-duplicate or reject repeated entries in preferences; in
key-wallet/src/wallet/managed_wallet_info/transaction_builder.rs:119-136,
enforce the once-per-funding-account rule by skipping accounts whose outpoints
already exist in self.funding.

---

Nitpick comments:
In `@key-wallet/src/wallet/managed_wallet_info/transaction_builder.rs`:
- Around line 450-466: Consider updating the reservation setup around
ReservationToken::next and the reservation_token return value to retain the
contributing ReservationSet handles alongside the shared owner token. Return
enough information for callers to release abandoned multi-account reservations
without re-resolving the funding accounts, while preserving the existing
behavior for empty funding and callers that already provide their own sources.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: a7ea0178-f23f-47e6-83df-e87e15b43026

📥 Commits

Reviewing files that changed from the base of the PR and between c6deac5 and 97c80a5.

📒 Files selected for processing (8)
  • dash-spv/tests/dashd_sync/tests_transaction.rs
  • key-wallet-ffi/src/transaction.rs
  • key-wallet-manager/src/lib.rs
  • key-wallet/src/managed_account/reservation.rs
  • key-wallet/src/tests/spent_outpoints_tests.rs
  • key-wallet/src/wallet/managed_wallet_info/asset_lock_builder.rs
  • key-wallet/src/wallet/managed_wallet_info/transaction_builder.rs
  • key-wallet/src/wallet/managed_wallet_info/transaction_building.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • dash-spv/tests/dashd_sync/tests_transaction.rs
  • key-wallet-manager/src/lib.rs
  • key-wallet-ffi/src/transaction.rs

Comment thread key-wallet/src/wallet/managed_wallet_info/transaction_builder.rs Outdated
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@QuantumExplorer
QuantumExplorer merged commit 09904a6 into dev Aug 7, 2026
33 checks passed
@QuantumExplorer
QuantumExplorer deleted the feat/multi-account-tx-funding branch August 7, 2026 08:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants