Improve Fee UX: Bidirectional Fee/Rate Input & Better Rebalance Button#447
Improve Fee UX: Bidirectional Fee/Rate Input & Better Rebalance Button#447Legend101Zz wants to merge 14 commits intocaravan-bitcoin:mainfrom
Conversation
🦋 Changeset detectedLatest commit: a62473c The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
@bucko13 let me know if we want to make the fees field editable in auto mode too , not a big change , just wanted to confirm once :) |
bucko13
left a comment
There was a problem hiding this comment.
a couple of console.logs to cleanup. will validate functionality as well.
|
@bucko13 sorry for the huge delay on this , finally I have fixed all the issues and also I decided not have the fees edit field on auto mode as it was getting far to complicated and logic was being fragile and inaccurate to calculate the fees before hand without knowing the inputs , can you check the UI , I am happy to iterate as we are taking time so any new fresh and better UX would be very nice
|
|
@bucko13 @tomunchained how do these look ?
|
|
Ugh, bummer. Still having e2e failures! https://github.com/caravan-bitcoin/caravan/actions/runs/23207942129/job/67448546087?pr=447 |
|
Ah, i think this is a legitimate e2e failure! |
| ) | ||
| rate = "0"; | ||
| setFeeRate(rate); | ||
| setFeeRate(rate === "" ? "0" : rate); // Reducer handles fee calculation and validation |
There was a problem hiding this comment.
Can also do:
Math.round(num * 100) / 100
bucko13
left a comment
There was a problem hiding this comment.
couple small questions/comments. Need to fix e2e as well. I'll test functionally next but the screenshots look good
| let feeRateString = action.value; | ||
|
|
||
| // Limit to 2 decimal places | ||
| if (feeRateString && feeRateString.includes(".")) { |
There was a problem hiding this comment.
Same
Math.round((num + Number.EPSILON) * 100) / 100
(or similar)
I yes I suspected that as I made changes to the transcation creation flow so would need to make changes to selectors in the Page model in. e2e , glad it's working fine :) |
|
This pull request has been inactive for 30 days and has been marked as stale. It will be closed in 7 days if no further activity occurs. To keep this PR open, add the "long-lived" label or comment on it. |
Address Buck's review feedback: only show the Rebalance button on the change output (or on recipients when no change output is set), and use Math.round((n + Number.EPSILON) * 100) / 100 for fee-rate rounding so floating-point artifacts don't leak into the input.
Buck noted ↑/↓ on the fee rate input bumping by 0.01 sat/vB has no practical value. Switch the step to 1 (manual decimal entry still works, reducer still rounds to 2 places). Also fix the row jumping when a change output is added: the rebalance column (xs=2) plus delete column (xs=1) was overflowing past 12, causing the row to wrap. Address column shrunk to xs=6 and both action slots are now always rendered (empty when inactive) so columns stay stable. Helper text under the Rebalance button is clipped with an ellipsis instead of wrapping to a second line.
Buck reported the fee rate field staying stale while editing the fee amount. updateFee was guarded by !feeError, so any non-fatal validation hiccup (intermediate typing, fee-too-high) suppressed the back-calc and left the rate showing the previous value. Drop the !feeError guard. As long as inputs are known and feeSats > 0, recompute the rate from the typed fee. Use the same EPSILON-based rounding as updateFeeRate so display values stay consistent.
The IconButton wrapping AddCircle was replaced by a labelled Button, so locating it via the auto-generated AddCircleIcon test id is brittle and only matches the "Increase" variant. Tag the button with data-testid="rebalance-button" and have the manual-coin-selection flow look it up directly.
…c runs bitcoinsToSatoshis returns a string, not a BigNumber. updateFee was storing that string in feeSats and then guarding the back-calculation with BigNumber.isBigNumber(feeSats), which always returned false. The fee field updated, but feeRate silently stayed at its previous value — the symptom Buck and the maintainer both saw in the form and Preview modal. Wrap the result in new BigNumber(...) so the guards behave like numbers and the back-calc actually fires. Add a regression test that mirrors the reported scenario (1 input of 6.25 BTC, two outputs, fee=0.001 BTC) and asserts the rate climbs well above the previous value of 1 sat/vB.
…nge-in-tx # Conflicts: # apps/coordinator/e2e/tests/03-transaction_flow.spec.ts
bf1b0f3 to
c2a983a
Compare



















Problem
Users reported two major UX issues when building transactions:
No way to specify exact fee amounts: Users could only set a fee rate and had to use trial-and-error, repeatedly adjusting the rate (4 → 5 → 4.5 → 4.6 sats/vB) until they achieved the desired total fee. This was frustrating when trying to pay exactly X satoshis in fees.
Unintuitive rebalance button: The output amount rebalance feature used a small gray +/- icon button that users found difficult to discover and unclear in its purpose.
Auto-spend mode limitations: In wallet auto-spend mode, the fee amount field was completely hidden, preventing any fee customization beyond the rate.
Changes Made
Testing
Manual Testing Checklist:
Fee Rate → Fee Amount sync
Fee Amount → Fee Rate sync
Rebalance button
Auto-spend mode
Edge cases
Test Transactions:
Related Issues
Fixes #443