Skip to content

feat(bridge): signal board, slide to confirm and a /bridge page - #121

Closed
Vasanthdev2004 wants to merge 2 commits into
feat/bridge-funding-chainsfrom
feat/bridge-redesign
Closed

Vasanthdev2004 wants to merge 2 commits into
feat/bridge-funding-chainsfrom
feat/bridge-redesign

Conversation

@Vasanthdev2004

Copy link
Copy Markdown
Collaborator

Stacked on #120 (funding networks), which is stacked on #119 and #118. Base is feat/bridge-funding-chains so this diff shows only the redesign.

What

A redesign of the bridge panel plus a full /bridge page. The transfer logic is untouched: useBridge, the validators and every wallet guard are the same files as before.

  • Signal board. A dot-matrix strip at the top of the panel spells the two networks (BASE, HOOD, ARC, ETH, ARB, OP) and runs lights along the route between them.
  • Dot numerals. The amount you send and the estimated output are set in a dot-matrix face.
  • Slide to confirm. For the deposit step only, a coin can be dragged across a rail to confirm. The normal button stays beside it.
  • /bridge page. The same panel as a page, with the networks, steps, costs and limits next to it.
  • Shareable links. /bridge?from=arbitrum&to=base&asset=USDC&toAsset=USDC preselects a route.

How it stays safe

  • The board cannot lie. What it shows is a pure function of the transfer state (lib/bridge/signal.ts). Lights travel "in transit" only for a tracked, pending transfer. It turns green only on a reported arrival, and amber for a refund or anything unknown or failed. It is decorative (aria-hidden); the panel's own status text says the same thing in words.
  • Sliding confirms nothing by movement. Only letting go, or pressing Enter, at the far end confirms (lib/bridge/slide.ts). Letting go anywhere else puts the coin back and requests nothing. The slide and the button call one shared function with the same guards. Approvals, quotes and refreshes are never slid.
  • One bridge controller. The /bridge page does not run a second copy of the bridge. It registers an empty element (components/bridge/bridge-slot.ts) and the header's existing controller renders the panel into it, so a transfer is quoted, sent and tracked once. While the page is open, the header button focuses the page's panel instead of opening the dialog.
  • Links only preselect. A link carries no amount and no address. It is applied once through the pickers' own guarded setters, which refuse during an approval or a transfer, and is ignored whole if any value is unknown, repeated or unsupported. to must be a launch chain.

Notes for review

  • New font: Doto (SIL Open Font Licence) through next/font/google, the same way Geist is loaded. It is declared in components/bridge/dot-font.ts with preload: false, so it ships with the lazily loaded panel and is not preloaded site-wide.
  • No new dependencies.
  • The board is a dark plate in both themes on purpose (an LED strip is not a light-mode surface); everything around it follows the site tokens.
  • Animation stops under prefers-reduced-motion.
  • /bridge is added to the sitemap and the footer.

Checks

  • tsc clean, eslint 0 errors (the 5 existing warnings)
  • New tests: board states and light direction, dot spacing, drag and keyboard rules, link parsing, the single-controller shape
  • Full suite: no new failures (the only failures on Windows are the existing CRLF regex ones)
  • Browser, desktop and phone width, both themes, no wallet:
    • /bridge renders the panel through the header's controller; a link preselected Arbitrum to Base with USDC
    • the header dialog still opens on other pages and links to the full page
    • in the dev-only /ui-review-bridge fixture, a half drag reset with "Nothing was sent" and a full drag confirmed; the board switched to "In transit"

Not done: a production next build was not run on this machine, and no wallet signed anything.

Two bugs found and fixed while checking, both covered by tests:

  • a very fast drag could let go before the last move had rendered and reset; the handlers now read the live drag position
  • inside the dialog the board's height could toggle the dialog's scrollbar, which changed the board's width and height in a loop; dot spacing is now sticky across a scrollbar's worth of width

A redesign of the bridge panel that leaves the transfer logic alone:
useBridge, the validators and every wallet guard are unchanged.

- signal board: a dot-matrix strip spells the two networks and runs
  lights along the route. What it shows is a pure function of the
  transfer state (lib/bridge/signal.ts); packets move only for a tracked
  pending transfer. Decorative (aria-hidden), canvas, still under
  reduced motion, a dark plate in both themes
- dot numerals (Doto, OFL) for the amount and the estimated output,
  loaded with the lazy panel only
- slide to confirm: for the deposit step alone, a coin can be dragged
  across a rail. Only a release or Enter at the far end confirms
  (lib/bridge/slide.ts); the slide and the button share one guarded
  submit path and the button never goes away
- /bridge: the same panel as a page with the networks, steps, costs and
  limits beside it. The page registers a slot and the header's one
  controller renders into it, so no second bridge hook runs
- shareable links: /bridge?from=&to=&asset=&toAsset= preselects a route
  through the pickers' guarded setters; no amount, ignored whole if any
  value is off (lib/bridge/link.ts)
- sitemap and footer list /bridge; docs/bridge.md section; tests for the
  board states, drag rules, links, the single controller and the shapes
@coderabbitai

coderabbitai Bot commented Nov 10, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: 3ca4076c-337c-4bfc-afb3-cf1b50078af2

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

@Vasanthdev2004

Copy link
Copy Markdown
Collaborator Author

Closed in favour of #135, which holds the whole bridge update in one PR. The commits from this PR are in it unchanged.

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.

1 participant