Skip to content

fix(widget): show receiving-chain receipt row for non-EVM-hash bridges#751

Open
chybisov wants to merge 1 commit into
mainfrom
fix/emb-396-bridge-completed-row-non-evm-hash
Open

fix(widget): show receiving-chain receipt row for non-EVM-hash bridges#751
chybisov wants to merge 1 commit into
mainfrom
fix/emb-396-bridge-completed-row-non-evm-hash

Conversation

@chybisov
Copy link
Copy Markdown
Member

@chybisov chybisov commented May 27, 2026

Which Linear task is linked to this PR?

EMB-396 — Widget UI missing "bridge completed" + dest tx link

Why was it implemented this way?

Bug: The "Bridge completed" receipt row was missing for bridges whose destination transaction hash is not a 0x-prefixed EVM hash. Reproduced with a USDC Arbitrum → Lighter route via Relay: the Across leg shows Bridge transaction confirmed + Bridge completed, but the Lighter leg only shows Bridge transaction confirmed.

Root cause: The SDK correctly adds a RECEIVING_CHAIN action (status: DONE, with both txHash and txLink). The widget then dropped the row in StepActionsList, whose filter requires a truthy href. useExplorer.getTransactionLink was returning undefined because Lighter is registered as an EVM chain (ChainId.LTR = 3586256) and its destination hash (609af30b…, 80 chars, no 0x) fails the strict isHex check that exists to guard against relayer task-IDs producing dead Etherscan links.

Fix:

  • Build the explorer link from the chain explorer + path override instead of bailing out. getTransactionLink now skips the EVM hash check when a chain-specific override is registered (an explicit signal the chain's explorer accepts a non-hex hash), and relaxes the remaining EVM check to non-strict. It falls back to the SDK-provided txLink only when no link can be built.
  • Add a Lighter override using its real explorer paths: txPath: 'logs', addressPath: 'accounts' (→ https://lighter.exchange/explorer/logs/<hash> and …/accounts/<addr>).
  • Collapse the duplicated txHash ? … : txLink ? … call sites in StepActionsList and StepAction into a single getTransactionLink({ txHash, txLink, chain }) call (props type relaxed to both-optional).

Alternatives considered: Falling back to the SDK's txLink alone is insufficient — the status API currently returns the wrong path (/tx/ instead of /logs/) for Lighter, so relying on it would produce a broken link. Building the URL from the registered override is the source of truth.

Visual showcase (Screenshots or Videos)

Before: Lighter receipt shows only "Bridge transaction confirmed" + "Sent to wallet".
After: "Bridge completed" row renders, linking to https://lighter.exchange/explorer/logs/<hash>.

No runtime screenshot attached — reproducing requires a live Lighter route; change verified via type-check, lint, unit tests, and source tracing.

Checklist before requesting a review

  • I have performed a self-review and testing of my code.
  • This pull request is focused and addresses a single problem.
  • If this PR modifies the Widget API or adds new features that require documentation, I have updated the documentation in the public-docs repository.

The "Bridge completed" receipt row was dropped for bridges whose
destination tx hash is not a 0x-prefixed EVM hash (e.g. Lighter via
Relay). getTransactionLink rejected such hashes on EVM chains and
returned undefined, so StepActionsList filtered the row out.

Build the link from the chain explorer + path override instead of
bailing out: skip the EVM hash check when a chain-specific override is
registered, and fall back to the SDK-provided txLink otherwise. Add a
Lighter (ChainId.LTR) override using its logs/accounts explorer paths.
@github-actions
Copy link
Copy Markdown

E2E Examples — failures

The following example(s) failed:

  • nft-checkout
  • vite-iframe-wagmi

See the workflow run for Playwright reports and logs.

@chybisov chybisov requested review from effie-ms and melianessa May 28, 2026 09:30
const validForEvm =
config.resolvedChain?.chainType !== ChainType.EVM ||
config.hasOverride ||
isHex(txHash, { strict: false })
Copy link
Copy Markdown
Contributor

@effie-ms effie-ms May 28, 2026

Choose a reason for hiding this comment

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

Trying to understand: if we have an override - the hash is valid if it is hex, even if it's not visible on chain (isHex(txHash, { strict: false })). And then shouldn't we use isHex(txHash, { strict: true }) for EVM with no overrides? To still validate its presence on chain?

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