refactor(send): migrate Core sends from split setFunding/buildSigned to finalizeAtomic - #920
Merged
QuantumExplorer merged 1 commit intoAug 6, 2026
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
…to finalizeAtomic The SDK's v1 split build path (setFunding → buildSigned → CoreTransaction → broadcastTransaction) is being removed upstream: funding selection and signing raced across the C ABI, so two concurrent same-account builds could select the same UTXO. finalizeAtomic commits selection + reservation in one native operation and returns a single-shot FinalizedCoreTransaction. - buildAndSign now finalizes atomically and returns the FinalizedCoreTransaction; tx bytes come from serializedData() (needed by the BIP70 Payment POST and the txHash computation). - Deferred confirm-then-broadcast semantics are preserved: the handle holds the input reservation until broadcast, and discarding it (user backs out, POST retry rebuilds) abandons the build and releases the inputs Rust-side. - Broadcast goes through broadcastTransactionWithOutcome; rejected/unknown outcomes map to new SendError.broadcastRejected/broadcastUnconfirmed. The handle is single-shot: a failed broadcast is re-prepared, not re-fired. - CoinJoin sweep and CrowdNode selected-input sends finalize atomically and serialize before broadcasting (broadcast consumes the handle). Requires the sibling platform checkout at v4.2-dev >= #4286 (serializedData). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
QuantumExplorer
force-pushed
the
feat/migrate-v2-atomic-send
branch
from
August 6, 2026 19:13
51f9b33 to
d0c5370
Compare
QuantumExplorer
added a commit
that referenced
this pull request
Aug 6, 2026
…he merge All four fixes are to upstream code that no longer compiled at swift-sdk-integration HEAD (the maya-swift-sdk merge, PR #916, landed after the finalizeAtomic refactor, PR #920, without rebasing over it): - CrowdNode error observers (OnlineAccountEmailController, CrowdNodePortalViewController): drop the `if let` on a value the preceding `compactMap { $0 }` already unwrapped — a non-optional binding is a compile error. - MAYA swap deposit (SwiftDashSDKTransactionSender.buildAndSignSwapDeposit): migrate from the removed split setFunding/buildSigned surface to finalizeAtomic, returning FinalizedCoreTransaction like every other send path; assertSwapDepositShape takes the serialized bytes + fee since the finalized handle exposes no raw `.data`. - WalletSendService.buildPreparedSwapDeposit: serialize via `serializedData()` (the PreparedStandardSend initializer now holds a FinalizedCoreTransaction). Candidate for cherry-pick to swift-sdk-integration — the base branch does not build without these. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
QuantumExplorer
added a commit
that referenced
this pull request
Aug 7, 2026
…-funds prompt (#858) * feat(coinjoin): offer BIP44 or Shielded destination in post-sync move-funds prompt The first-sync "Move your mixed coins" popup previously always swept the leftover CoinJoin balance into the BIP44 spendable balance. When the balance is large enough to be worth shielding (>= 2x the shield pool fee + asset-lock base cost + L1 send-fee reserve, and the shielded sub-wallet is bound), a destination-choice sheet now offers: - Dash Wallet balance: the existing one-hop sweep. - Shielded balance: sweep CoinJoin -> own BIP44 receive address, wait for the swept outputs to become spendable, then asset-lock the net amount into the shielded pool (Type 18), with a step checklist. The user authenticates once: the sweep leg runs the spend gate and the asset lock skips its own via a new explicit alreadyAuthorized parameter on ShieldedTransferCoordinator.performAssetLock. Failure posture: the sweep-leg result is kept on the ViewModel, so "Try again" never re-sweeps an emptied CoinJoin account - it resumes from the UTXO wait, or resumes a committed asset lock on its exact outpoint (mirroring the transfer confirm sheet); a stuck lock that survives the session is picked up by the home tx list's ShieldedRecoverySheet. Every failure mode leaves the funds spendable in the BIP44 balance. Small balances keep the BIP44-only dialog, and the availability check fails closed to it. Plumbing: sweepCoinJoin(to:) now also returns the net swept duffs; the CrowdNode UTXO-wait helper is promoted for reuse (waitForFunds); ShieldedTransferStepList gains a positional (labels/currentIndex) init for stages the coordinator phases can't express; the wallet source's onMain trampoline is promoted for the availability check's host reads. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(coinjoin): shield mixed coins via a direct CoinJoin-drain asset lock Replaces the two-hop shielded destination (sweep CoinJoin -> BIP44, wait, asset-lock) with a single CoinJoin-funded drain asset lock: every mixed-coin UTXO funds the Type 18 lock directly (lock value = sum(inputs) - L1 fee, computed SDK-side) and the shielded pool receives lock_value - pool_fee. The mixed coins never hop through a transparent BIP44 address, and the flow is one transaction with one PIN prompt. - ShieldedTransferCoordinator.performAssetLock gains an AssetLockFundingSource (.bip44(amountDuffs:) | .coinJoinDrain) routed to the new SDK wrapper shieldedFundFromCoinJoinDrain; the historical amountDuffs entry point delegates unchanged. The alreadyAuthorized seam is removed - the coordinator's own gate is the flow's single prompt again. Resume-by-outpoint covers drain locks identically. - CoinJoinMoveFundsSheet: the shielded path is one coordinator run with the same step checklist as the internal transfer; auth-cancel returns to the destination choice; the CoinJoin balance is re-tallied on completion so the popup/Settings surfaces self-clear. - The dead two-hop plumbing is removed (sweepCoinJoinForShielding, waitForSweptCoinJoinFunds, the sweep net-amount return, waitForFunds, and their error strings). Consumes SwiftDashSDK's shieldedFundFromCoinJoinDrain (platform feat/coinjoin-asset-lock-funding, on rust-dashcore key-wallet drain support) - rebuild DashSDKFFI.xcframework after pulling platform. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(build): repair swift-sdk-integration compile breaks surfaced by the merge All four fixes are to upstream code that no longer compiled at swift-sdk-integration HEAD (the maya-swift-sdk merge, PR #916, landed after the finalizeAtomic refactor, PR #920, without rebasing over it): - CrowdNode error observers (OnlineAccountEmailController, CrowdNodePortalViewController): drop the `if let` on a value the preceding `compactMap { $0 }` already unwrapped — a non-optional binding is a compile error. - MAYA swap deposit (SwiftDashSDKTransactionSender.buildAndSignSwapDeposit): migrate from the removed split setFunding/buildSigned surface to finalizeAtomic, returning FinalizedCoreTransaction like every other send path; assertSwapDepositShape takes the serialized bytes + fee since the finalized handle exposes no raw `.data`. - WalletSendService.buildPreparedSwapDeposit: serialize via `serializedData()` (the PreparedStandardSend initializer now holds a FinalizedCoreTransaction). Candidate for cherry-pick to swift-sdk-integration — the base branch does not build without these. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What was done?
The platform SDK's v1 split Core-send path (
setFunding→buildSigned→CoreTransaction→broadcastTransaction) is being removed upstream (dashpay/platform#4323): funding selection and signing race across the C ABI, so two concurrent same-account builds can select the same UTXO. This migrates every call site to the atomic v2 surface before that removal reaches the platform pin.buildAndSignfinalizes atomically (finalizeAtomic) and returns the single-shotFinalizedCoreTransaction; tx bytes come fromserializedData()(feeds the BIP70 Payment POST and the txHash computation).broadcastTransactionWithOutcome; rejected/unknown outcomes map to newSendError.broadcastRejected/.broadcastUnconfirmed. The handle is consumed on every attempt, so a failed broadcast is re-prepared rather than re-fired (comments updated where the old path promised identical-bytes rebroadcast).Requires the sibling
../platformcheckout at v4.2-dev ≥ #4286 (serializedData()); should merge before the pin advances past dashpay/platform#4323.How Has This Been Tested?
xcodebuild -workspace DashWallet.xcworkspace -scheme dashpayagainst the iPhone 16 simulator: BUILD SUCCEEDED, zero warnings introduced in the touched files, with../platformat v4.2-dev tip6dc1b4660eand a freshly builtDashSDKFFI.xcframework(ios + sim slices). Send-path behavior (standard, BIP70, sweep, selected-input) needs a testnet QA pass, which I'd fold into the next scheduled send-flow QA round.🤖 Generated with Claude Code