Skip to content

feat: add bitcoin rbf speed-up flow and replacement checks#3850

Open
jstrnbrg wants to merge 11 commits intoBitBoxSwiss:masterfrom
jstrnbrg:rbf
Open

feat: add bitcoin rbf speed-up flow and replacement checks#3850
jstrnbrg wants to merge 11 commits intoBitBoxSwiss:masterfrom
jstrnbrg:rbf

Conversation

@jstrnbrg
Copy link
Copy Markdown
Collaborator

@jstrnbrg jstrnbrg commented Feb 8, 2026

  • add end-to-end RBF support from tx details to send flow
  • pass rbfTxID through proposal API and tx builder
  • enforce BIP-125 replacement rules:
    • new fee rate must be at least +1 sat/vB
    • new absolute fee must be higher than original
  • derive original tx fee/feerate from indexed local tx data in transactions instead of fetching from blockchain during proposal
  • add RBF-specific backend errors and frontend handling/messages
  • add speed-up button + RBF send UX (including mobile and fee target behavior)
  • keep send-all behavior in RBF mode
  • add comprehensive backend/frontend tests for RBF success and error paths

onShowDetail={setDetailID}
onSpeedUp={internalID => {
navigate(`/account/${code}/send`, {
state: {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

please don't use react-router state, we don't use it in the codebase and the less react-router we have the easier it is to migrate away from that library ... (which we should have done a long time ago)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

done, PTAL at the frontend when you have time

@jstrnbrg jstrnbrg force-pushed the rbf branch 2 times, most recently from 3e7fa7f to 863c3f4 Compare April 1, 2026 10:35
@jstrnbrg jstrnbrg self-assigned this Apr 2, 2026
@thisconnect
Copy link
Copy Markdown
Collaborator

merged upstream/master into rbf

Copy link
Copy Markdown
Collaborator

@thisconnect thisconnect left a comment

Choose a reason for hiding this comment

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

partly reviewed for myself to know what needs to be done

amount={fiatAmount}
baseCurrencyUnit={defaultCurrency}
className={style.rbfFiatAmount}
/>
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This component is only used on mobile. The FiatValue componet has been moved to components/amount see 092b015

The whole point of all the "amount" components is that we can pass an TAmountWithConversions object and rotate currencies, but the newly added FiatValue comp here only accepts a string. So rotating wont work.

Might as well just use a text element with some styling..

label: feeTarget as string,
value: feeTarget,
}]}
}}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

When I am trying to change the fee in rbf workflo for example from 1.1 sat/vbyte to 1.5 sat/vbyte, some kind of error quickly flashes, but then is replaced by 3 sats/vbyte. I haven't checked what is going on but it looks like it changes to preferredFeeTarget.

className={style.unit} />
</p>
);
};
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Remove.

This component was moved in commit 092b015

This newly added one seems to work different, commented also in send.tsx

@thisconnect thisconnect mentioned this pull request Apr 8, 2026
5 tasks
- add end-to-end RBF support from tx details to send flow
- pass rbfTxID through proposal API and tx builder
- enforce BIP-125 replacement rules:
  - new fee rate must be at least +1 sat/vB
  - new absolute fee must be higher than original
- derive original tx fee/feerate from indexed local tx data in transactions
  instead of fetching from blockchain during proposal
- add RBF-specific backend errors and frontend handling/messages
- add speed-up button + RBF send UX (including mobile and fee target behavior)
- keep send-all behavior in RBF mode
- add comprehensive backend/frontend tests for RBF success and error paths
- Show a speed-up note inside the transaction card in tx history
trigger note after 60 minutes on mainnet and immediately in testnet mode
- Use first-seen timestamp for pending outgoing btc txs to support speed-up trigger
- Add tests for speed-up eligibility logic
When a non-expert user (custom fees disabled) speeds up a transaction,
the backend now silently bumps the fee rate to original + 1 sat/vB if
the selected preset target is too low, instead of returning an error
that forced the frontend into a custom fee input the user shouldn't see.

For expert users (custom fees enabled), the existing behavior is
preserved: rbfFeeTooLow triggers the frontend to switch to custom fee
mode with the minimum required rate.
Hide the available balance section, the "hide amounts" button, and
render the receiver address and amount as plain text instead of
disabled input fields when speeding up a transaction.
- return a typed rbf broadcast conflict error from the btc backend
- recover already-confirmed replacements without matching raw node error text
- move the speed-up flow into a dedicated rbf send screen
- make FeeTargets controlled and keep TxDetailsDialog presentational
- polish the transaction details and mobile rbf layouts
As the app does not currently support batch transactions we need to ensure that no RBF option shows up for batch transactions made via a different wallet client app.
Fix a race condition where removing a replaced transaction could delete
input records already claimed by the replacement, making the replacement
appear non-replaceable. Guard DeleteInput to only act when the tx being
removed is still the recorded spender.

Filter fee target options below the RBF minimum (original + 1 sat/vB)
and show the required minimum in the custom fee error message.
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.

3 participants