Skip to content

feat(bridge): transfer history on /bridge - #125

Closed
Vasanthdev2004 wants to merge 2 commits into
feat/bridge-redesignfrom
feat/bridge-history
Closed

Vasanthdev2004 wants to merge 2 commits into
feat/bridge-redesignfrom
feat/bridge-history

Conversation

@Vasanthdev2004

Copy link
Copy Markdown
Collaborator

Phase 3 of the bridge update: transfer history. This PR is stacked on #121 and should be merged after it.

What it adds

  • Your transfers at the bottom of /bridge. It is a board for the connected wallet. Each row shows the time, the route (the Signal board's network codes), the amount sent, the amount received, the status in words, and links to Relay and both block explorers. The header panel's footer now links to /bridge#transfers.
  • History saved in this browser (lib/bridge/history-store.ts). This works today, with no key and no server.
    • The bridge controller saves a transfer once it has a source transaction hash or Relay has finished it. A cancelled wallet prompt never shows up.
    • A transfer that is discarded as never sent is removed again.
    • Each wallet keeps its 20 newest transfers.
    • It sits beside the recovery record and does not replace it. The recovery record and its anti-double-send rules are unchanged.
  • History from Relay: GET /api/bridge/history?address= reads GET /requests/v3?user=…. This shows transfers made from other devices too.
    • Relay needs RELAY_API_KEY for this. v3 requires an API key, and Relay retires the keyless v2 on 2026-11-24.
    • Without the key, the route answers { relay: "off" } and makes no call. The board then says it is showing what this browser saved.
    • The key is sent in the x-api-key header and never in the URL.
    • Answers are reused for 20 seconds per wallet. Calls to Relay share a budget of 120 a minute; Relay's limit with a key is 200. Each IP can make 30 requests a minute.

Rules (lib/bridge/history.ts)

  • A Relay request becomes a row only when this wallet sent it and both ends are networks and tokens this bridge supports. Tokens are matched by currency address, and the decimals must match. Anything else is left out.
  • A finished status is never replaced by an unfinished one, so a slow or late answer cannot roll a transfer back.
  • An amount Relay reports as delivered wins over a quoted amount. A quoted amount is labelled "Quoted".
  • A refund or failure shows no destination amount.
  • The browser checks every row the server sends again.

Checks

  • Type-check is clean and lint has 0 errors.
  • Full suite: 1454 tests, 1378 pass. The 28 failures are the same Windows line-ending failures as before; none are new.
  • New tests cover:
    • the parser, against Relay's published v3 schema;
    • the browser history, including a blocked or full storage;
    • the route's input checks and rate limit;
    • the key being off, the key sent in the header, caching, and the call budget.
  • Checked in the browser with new history scenes in /ui-review-bridge, on desktop and phone width, in light and dark. The real /bridge page without a wallet shows the empty state.

Not checked against live Relay data. The schema comes from Relay's OpenAPI document. An opt-in live test (RUN_BRIDGE_LIVE_TESTS=1 with RELAY_API_KEY) reads recent Robinhood requests through the same parser. It needs the key, so it has not run.

Before it shows Relay history

@kevincodex1: please set RELAY_API_KEY in production. It is the same key the quote path already sends when present. Then run the live test once.

A "Your transfers" departures board on /bridge for the connected wallet,
fed by two sources that share one set of rules (lib/bridge/history.ts):

- This browser: a small ledger beside the recovery record (never instead
  of it). The controller records a transfer once it has a source hash or
  a settled status and forgets it if discarded as never sent. Storage
  failures only show a notice; they never reach a transfer.
- Relay: GET /api/bridge/history reads /requests/v3 for the wallet with
  RELAY_API_KEY in the x-api-key header. Without the key it answers
  { relay: "off" } and calls nothing. Answers are cached for 20 seconds,
  upstream calls share a budget of 120 a minute, and each IP gets 30.

Rows only cover this bridge's networks and tokens, matched by currency
address and decimals. A settled status is never rolled back, a delivered
amount beats a quoted one, and the browser re-validates server rows.
Refunds and failures show no destination amount.

The header panel's footer now links to /bridge#transfers. The
/ui-review-bridge fixture gains history scenes.
@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: 1b324da2-fc41-4bd3-aea6-05a70a39e8ec

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