Skip to content

Fix swap flipping to error after websocket already confirmed success - #1121

Merged
ted-palmer merged 1 commit into
mainfrom
ted/fix-swap-flipping-to-error-after-success
Sep 2, 2026
Merged

Fix swap flipping to error after websocket already confirmed success#1121
ted-palmer merged 1 commit into
mainfrom
ted/fix-swap-flipping-to-error-after-success

Conversation

@ted-palmer

Copy link
Copy Markdown
Collaborator

No description provided.

@vercel

vercel Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
relay-sdk-demo Ready Ready Preview Sep 2, 2026 2:36pm UTC

Request Review

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Claude finished @ted-palmer's task in 32s —— View job


📝 Docs Drift Check — No docs impact

This PR does not touch surfaces that require a relayprotocol/relay-docs update.

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Claude finished @ted-palmer's task in 1m 58s —— View job


Code Review

Reviewed 6 files (+175/−4). Checked correctness, error handling, async/race behavior, and repo guidelines.

No high-confidence issues found.

The fix is well-designed and addresses the bug at three complementary layers, so a late RPC receipt error after backend-confirmed success can no longer flip the flow to error:

  1. executeSteps/index.ts — a successStatusPromise is added to the Promise.race, so a websocket success resolves step execution instead of leaving it blocked on the RPC receipt. The catch also swallows late errors when stepItem.status === 'complete' or lastKnownStatus === 'success', marking the item complete rather than failing it.
  2. transaction.ts — the receipt-lookup .catch returns early (no TransactionConfirmationError) once statusControl.lastKnownStatus === 'success', correctly treating a late receipt failure as a node/RPC issue rather than a failed transaction.
  3. TransactionModalRenderer.tsx — a UI guard prevents downgrading a Success state to Error.

Notes I verified while reviewing (all fine, no action needed):

  • Recursion scopesuccessStatusPromise/terminalStatusPromise are only assigned in the websocket-setup block, which runs on the call that processes the last step. The race guard falls back to await stepExecutionPromise on recursive calls where these are null. Consistent with the pre-existing terminalStatusPromise pattern.
  • No new unhandled rejection — when successStatusPromise wins the race, the dangling stepExecutionPromise still resolves because lastKnownStatus is set to 'success' before onTerminalSuccess fires (websocketHandlers.ts:34 runs before the success case at :57), so the transaction.ts catch swallows any subsequent receipt error rather than rejecting.
  • UI guard is defense-in-depth — the effect deps stay [steps, swapError] and read progressStep via closure, matching the existing pattern in the same effect. Since the SDK layers now prevent swapError from being set on the success path, the guard is a belt-and-suspenders safeguard rather than the primary fix.
  • Changeset — follows the repo convention and correctly patches both relay-sdk and relay-kit-ui.
  • Tests — the two added cases exercise both the "resolve on websocket success without receipt" path and the "receipt errors after success" path, including asserting no errored progress updates are emitted.

Nice, targeted fix with good test coverage.
• branch ted/fix-swap-flipping-to-error-after-success

@greptile-apps

greptile-apps Bot commented Sep 2, 2026

Copy link
Copy Markdown

Greptile Summary

This change keeps a completed swap successful when a delayed RPC receipt lookup fails after the backend has already confirmed success. Focused checks exercised both an indefinitely pending receipt and a receipt rejection after a WebSocket success update; both completed without returning an error or downgrading the step state. The complete SDK executeSteps test file also passed.

Confidence Score: 5/5

Safe to merge based on direct coverage of the WebSocket-success and delayed-receipt race that this change addresses.

The focused checks confirmed that backend success completes execution even when the RPC receipt remains pending or later rejects, and the surrounding SDK execution tests passed.

Files Needing Attention: No additional files need attention.

T-Rex T-Rex Logs

What T-Rex did

  • I ran a focused SDK test sequence that sends request.status.updated with status 'success' while the receipt promise remains unresolved or later rejects to exercise the receipt race.
  • I compared PR-commit results with the parent commit and observed that the PR passes the WebSocket success and late-receipt rejection scenarios, while the parent commit times out in the unresolved case and rejects in the late-receipt case.
  • I executed the full executeSteps test file on the PR commit and confirmed all 41 tests passed, indicating no regression in the surrounding execution behavior.
  • I reviewed the coordination logic and WebSocket state handling to confirm the fix resolves the receipt race, supported by the focused test source and full-suite results.

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (1): Last reviewed commit: "Fix swap flipping to error after websock..." | Re-trigger Greptile

@pedromcunha
pedromcunha self-requested a review September 2, 2026 17:06
@ted-palmer
ted-palmer merged commit 581e9d8 into main Sep 2, 2026
8 checks passed
@ted-palmer
ted-palmer deleted the ted/fix-swap-flipping-to-error-after-success branch September 2, 2026 17:28
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