Skip to content

Dim the Stealth toggles when they cannot arm - #6279

Merged
j0ntz merged 3 commits into
developfrom
jon/stealth-toggle-blocked-state
Oct 22, 2026
Merged

j0ntz merged 3 commits into
developfrom
jon/stealth-toggle-blocked-state

Conversation

@j0ntz

@j0ntz j0ntz commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

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:

  • Reasons: an asset Houdini does not serve, an asset the info server bans for Houdini on that side (sending or receiving, as on the Exchange scene), no private route to itself, below the 25 USD private minimum, or a refused route.
  • The reason shows on plain sends too. This reverses EdgeApp/edge-react-gui#6270, which left a plain send's toggle unexplained.
  • A tap toasts the reason, does not arm, and saves nothing.
  • The saved choice or the stealth=true link 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.
  • With Stealth on and the amount below the minimum, the message stays in the quote error card. The line under the toggle shows only while the toggle is off.

Swap scene:

  • A pair is blocked when either side is unserved or banned for Houdini by the info server. The reason uses stealth_asset_unsupported_1s and names the failing side, the sending side first.
  • With Stealth on, each picker leaves out the assets the info server bans for Houdini on that side: the from picker drops source bans, the to picker drops destination bans.
  • Effective stealth is (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.md and describes the dimmed toggle in stealth-send-swap.md.

Out of scope: narrowing the edge://send?stealth=true wallet 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?

  • Yes
  • No

Dependencies

none

Requirements

If you have made any visual changes to the GUI. Make sure you have:

  • Tested on iOS device
  • Tested on Android device
  • Tested on small-screen device (iPod Touch)
  • Tested on large-screen device (tablet)

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=true when 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 use stealth_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

fd0fda8
2026-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
98f23fb
fixup! 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

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-21T08:31:04.063195Z 9a0ecec PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@j0ntz j0ntz left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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 on pairCaps.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 for stealthAvailable (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: reseedStealthRef can 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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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".

Comment thread src/components/scenes/SendScene2.tsx Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ 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.

Comment thread src/components/scenes/SendScene2.tsx Outdated
@j0ntz
j0ntz force-pushed the jon/stealth-toggle-blocked-state branch from 9a0ecec to fd0fda8 Compare October 21, 2026 08:39

@peachbits peachbits left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Comment thread src/components/scenes/SendScene2.tsx Outdated
Comment thread src/components/scenes/SendScene2.tsx
Comment thread src/components/scenes/SwapCreateScene.tsx Outdated
Comment thread src/components/scenes/SwapCreateScene.tsx Outdated
@j0ntz
j0ntz force-pushed the jon/stealth-toggle-blocked-state branch from fd0fda8 to 98f23fb Compare October 21, 2026 21:35
@j0ntz

j0ntz commented Oct 21, 2026

Copy link
Copy Markdown
Contributor Author

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 peachbits left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Comment thread src/components/scenes/SendScene2.tsx
@j0ntz
j0ntz force-pushed the jon/stealth-toggle-blocked-state branch from 98f23fb to 51c1e54 Compare October 22, 2026 00:22
@j0ntz

j0ntz commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor Author

Rebased onto develop at the EdgeApp/edge-react-gui#6278 merge (4ee991c). Both strings moved to stealth_info_1s: the recipient-network test now expects the formatted provider line, and the SwapCreateScene helper uses the stealthInfo() helper develop already has. The CHANGELOG conflict kept both Unreleased lines. On the sim against the rebased build, ARRR still shows the toggle dimmed with its reason, and the RIF send re-arms at $30 with the new copy.

@j0ntz
j0ntz force-pushed the jon/stealth-toggle-blocked-state branch from 51c1e54 to b6c9610 Compare October 22, 2026 00:53
@j0ntz
j0ntz enabled auto-merge October 22, 2026 00:53
@j0ntz
j0ntz disabled auto-merge October 22, 2026 01:05
j0ntz added 2 commits October 21, 2026 18:05
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.
@j0ntz
j0ntz force-pushed the jon/stealth-toggle-blocked-state branch from b6c9610 to 916eec0 Compare October 22, 2026 01:07
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.
@j0ntz
j0ntz force-pushed the jon/stealth-toggle-blocked-state branch from 916eec0 to 48f707c Compare October 22, 2026 01:12
@j0ntz
j0ntz enabled auto-merge October 22, 2026 01:13
@j0ntz
j0ntz disabled auto-merge October 22, 2026 01:20
@j0ntz
j0ntz merged commit 97a8534 into develop Oct 22, 2026
6 checks passed
@j0ntz
j0ntz deleted the jon/stealth-toggle-blocked-state branch October 22, 2026 01:26
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.

2 participants