fix(wallet): gate sends on what the funding pool can actually spend - #1107
Draft
romchornyi wants to merge 1 commit into
Draft
fix(wallet): gate sends on what the funding pool can actually spend#1107romchornyi wants to merge 1 commit into
romchornyi wants to merge 1 commit into
Conversation
The amount screen compared against `balance.spendable`, which is the whole wallet's confirmed balance — every funding account, CoinJoin included. A send draws on `SEND_FUNDING_SOURCES`: BIP44@0, BIP32@0 and the DashPay receiving accounts, with CoinJoin deliberately out. So the screen accepted amounts the builder then refused, and the user learned it only after committing. Support ticket 32081: 94 DASH on screen, 0.0054 actually spendable, the rest mixed. Entering 1 DASH gave "insufficient unreserved core funds … available Some(538503), required Some(100000000)" — 538503 duffs being exactly the transparent balance. Both the gate and Max now read `pooledSpendableDuffs`, which the SDK computes with the same account resolution the builder uses (dashpay/platform#4582) rather than the app mirroring the pooling rule. The mirror is what drifted: the comment in SwiftDashSDKTransactionSender still claims `.allSpendable` pools "the same set the home balance already totals", and it never did. Max is included deliberately. Leaving it on the wallet-wide figure would keep a button that fills in an amount guaranteed to fail.
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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.
Issue being fixed or feature implemented
SendAmountModel.canShowInsufficientFundscompared againstbalance.spendable— the whole wallet'sconfirmed balance, every funding account, CoinJoin included. A send draws on
SEND_FUNDING_SOURCES:BIP44@0, BIP32@0 and the DashPay receiving accounts, with CoinJoin deliberately excluded (spending
mixed outputs alongside transparent ones undoes the mixing).
So the screen accepted amounts the builder then refused, and the user found out only after committing:
Support ticket 32081: 94 DASH on screen, 0.0054 actually spendable, the rest mixed.
538503duffsis exactly the transparent balance, unchanged across three days of the user trying.
What was done?
The gate and Max now read
pooledSpendableDuffs, refreshed from the SDK on every balance event. TheSDK computes it with the same account resolution the builder uses (dashpay/platform#4582), so the app
does not mirror the pooling rule.
The mirror is what drifted here: the comment in
SwiftDashSDKTransactionSenderstill claims.allSpendablepools "the same set the home balance already totals" — it never did, and that beliefis why this shipped.
Max is included deliberately. Leaving it on the wallet-wide figure keeps a button that fills in an
amount guaranteed to fail.
Reservations are still not subtracted; the SDK cannot read them yet, and that part is transient.
How Has This Been Tested?
Builds and runs against the SDK carrying the new call. Not yet verified against a live CoinJoin-heavy
wallet — the testnet wallet built for this work has since been swept, so the state must be rebuilt to
watch the ceiling change. The arithmetic is covered on the SDK side.
Breaking Changes
None in API terms, but user-visible: anyone holding CoinJoin funds will see a lower ceiling and a
smaller Max than today. That is the point — those funds were never spendable by a plain send — but it
is why the merge order below matters.
Merge order
This must not land before the sweep fix. On its own it lowers what the user is offered without
giving them a way to unlock the difference, which is strictly worse than today.
Checklist:
For repository code-owners and collaborators only