Repository navigation
Dim the Stealth toggles when they cannot arm - #6279
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
j0ntz
left a comment
There was a problem hiding this comment.
Self-review before human review (medium).
Fixed before review (2)
src/components/scenes/SendScene2.tsx:2064: an armed toggle stayed on when the source asset was picked back as the recipient after its quote came back with no private route to itself. Fixed in "Dim the Stealth Send toggle when it cannot arm": the seed also disarms onpairCaps.stealth === false, and the recipient-network test covers it.src/components/scenes/SwapCreateScene.tsx:166: the blocked reason was computed before the Houdini list loaded. Fixed in "Dim the Stealth Swap toggle on a blocked pair": it waits forstealthAvailable(the row is hidden until then; nothing visible changes).
Rejected in curation (2)
src/components/scenes/SwapCreateScene.tsx:193: a blocked pair quotes through the regular providers while Stealth is saved on. Rejected: the task spec sets effective stealth to(override ?? saved) && list loaded && not blocked, and the toggle shows off with the reason. A regular quote matches what the toggle shows.src/components/scenes/SendScene2.tsx:2081:reseedStealthRefcan latch true. Rejected: a same-key re-pick returns before the flag is set, and a latched flag only runs the seed, which arms only on an eligible pair the visit or saved choice asks for and disarms only on a blocked same-asset pair, both the intended state.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9a0ecec667
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 9a0ecec. Configure here.
9a0ecec to
fd0fda8
Compare
peachbits
left a comment
There was a problem hiding this comment.
Checked at fd0fda8: tsc clean, full jest 1363/1363, no new eslint warnings. Removing the recipient-change trigger, the new disarm branch, the dimmed prop, or any Swap block check (either side, the bans, the stealth gate) each fails a test. Two gaps on the Send side are inline.
fd0fda8 to
98f23fb
Compare
|
Both Send gaps from the inline threads are fixed in c1e58d4. A banned source or destination now dims the Stealth Send toggle with its own reason, and the toggle re-arms once the block clears (recipient change, raising the amount above the private minimum). Two jest tests cover those paths. The Swap per-side ban check is in 728a7c7 with a picker test, and the docs follow in 98f23fb. On the iOS sim: RBTC to itself disarms, a RIF recipient at $5 stays off on the $25 minimum, and $30 arms it again. With a local LTC ban injected (reverted, not committed), Send dims with the LTC reason and the Swap from picker leaves LTC out while the to picker keeps it. |
peachbits
left a comment
There was a problem hiding this comment.
Re-checked at 98f23fb (same base as round 1). All four round-1 threads are addressed. Removing the cleared-reason trigger, the source-ban arm, or the "from" picker's source bans each fails the test added for it, and getStealthBlockedCurrencyCode reads as asked. tsc clean, full jest 1366/1366, no new eslint warnings.
For the rebase onto develop: two lines this PR adds read strings that EdgeApp/edge-react-gui#6278 removed, lstrings.stealth_send_info in the recipient-network test (:1314) and lstrings.stealth_swap_info in the SwapCreateScene test helper (:525). Both move to stealth_info_1s.
98f23fb to
51c1e54
Compare
|
Rebased onto develop at the EdgeApp/edge-react-gui#6278 merge (4ee991c). Both strings moved to |
51c1e54 to
b6c9610
Compare
A Stealth Send that cannot go private now shows the toggle dimmed and off with its reason under it, on a plain send as well as a swap-send. This reverses #6270, which left a plain send unexplained. A tap toasts the reason and saves nothing. The saved choice or the stealth link param arms again on the next wallet, token, or recipient asset that has a route, and an armed toggle turns off when the source asset is picked back as the recipient with no private route to itself. With Stealth on, the private minimum stays in the quote's error card.
A Stealth Swap pair with a side Houdini does not serve, or one the info server bans for Houdini on that side, now shows the toggle dimmed and off with a reason naming that side, the sending side first. A tap toasts the reason and saves nothing, and the saved choice or link override comes back once the user picks a pair Stealth can route. No route is probed before the quote.
b6c9610 to
916eec0
Compare
Correct the edge://send section of the deep link doc, which still said a token source always pays out the chain coin and that a token on an unserved chain arms until its first quote fails. Describe the dimmed toggle and its reasons in the Stealth design doc, with the tests that cover it.
916eec0 to
48f707c
Compare

Technical Design Document
stealth-send-swap.md
Description
Asana task
When a Stealth toggle cannot arm, it now shows dimmed and off with the reason under it, instead of hiding or arming until the first quote fails. The saved choice never changes because of this. It comes back on its own once the user picks an asset or pair Stealth can route.
Send scene:
stealth=truelink param arms again when the wallet, token, or recipient asset becomes eligible. It also arms again when the reason clears with no pick in between, such as an amount raised past the minimum. An armed toggle turns off (without saving) when the source asset is picked back as the recipient with no private route to itself.Swap scene:
stealth_asset_unsupported_1sand names the failing side, the sending side first.(override ?? saved) && list loaded && not blocked. When blocked, the toggle is dimmed and off with the reason, a tap toasts it, and nothing is saved. No route is probed before the quote.Tests: updates the EdgeApp/edge-react-gui#6253 and EdgeApp/edge-react-gui#6270 cases and adds dimmed-state UI tests for both scenes. Docs: corrects section 4.6 of
exchange-deep-links.mdand describes the dimmed toggle instealth-send-swap.md.Out of scope: narrowing the
edge://send?stealth=truewallet picker.On the iOS simulator, Stealth Send saved on with BTC, then a send from ARRR showed the toggle dimmed with "Stealth routing is not available for ARRR." A tap toasted it without arming, and BTC still showed the toggle armed afterward. The Swap frames used a local, uncommitted Houdini ban on Litecoin to reach the blocked state, because the swap picker hides unserved assets.
After review: an RBTC send to a RIF recipient at 5 USD showed the toggle off with the minimum reason, and raising the amount to 30 USD armed it again. With a local, uncommitted Houdini source ban on LTC, a send from LTC showed the toggle dimmed with "Stealth routing is not available for LTC.", the Stealth Swap from picker left LTC out, and the to picker kept it.
CHANGELOG
Does this branch warrant an entry to the CHANGELOG?
Dependencies
none
Requirements
If you have made any visual changes to the GUI. Make sure you have:
Note
Medium Risk
Changes Stealth Send/Swap eligibility, seeding, and toggle UX across send and swap flows, including deep-link arming behavior, though mostly presentation and guardrails without altering successful routing paths.
Overview
Stealth Send and Stealth Swap toggles now appear dimmed and off with an inline reason when routing cannot work, instead of looking enabled until a quote fails or leaving plain sends unexplained.
On Send, blocked cases (unsupported asset, no private same-asset route, below the private minimum, or a refused route) show the reason under the toggle; taps toast the same text without arming or changing the saved preference. Seeding re-runs on recipient-asset changes, turns Stealth off when picking the source asset back with no private route, and re-arms from saved/
stealth=truewhen the wallet, token, or pair becomes eligible. Once Stealth is on, minimum errors stay on the quote card only.On Swap, effective Stealth is gated by Houdini serve-list and per-side info-server bans via new
isStealthRoutable; blocked pairs usestealth_asset_unsupported_1s, dim the switch, and still allow a normal swap on Max/Next. Docs and CHANGELOG reflect the UX and deep-link behavior.Reviewed by Cursor Bugbot for commit 9a0ecec. Bugbot is set up for automated code reviews on this repo. Configure here.
Test evidence
fd0fda82026-10-21
🪓 Local uncommitted edit injected a Houdini source ban on litecoin into SwapCreateScene's disableAssetsByPlugin input
5. swap btc eth stealth saved on
6. 🪓 swap ltc banned source dimmed with reason
7. 🪓 swap ltc tap toasts reason
8. 🪓 swap btc saved choice returns
1. send btc stealth saved on
2. send arrr dimmed with reason
3. send arrr tap toasts reason
4. send btc saved choice kept
98f23fbfixup! Update Stealth docs for the dimmed toggle
2026-10-21
🪓 Local uncommitted edit to getStealthDisableAssets returned a Houdini ban on LTC as a source.
9. send rbtc rif held off under private minimum
10. send rbtc rif arms again at 30
11. 🪓 send ltc banned source dimmed with reason
12. 🪓 send ltc banned source tap toasts reason
13. 🪓 swap from picker leaves out banned ltc
14. 🪓 swap to picker keeps ltc