Skip to content

fix(core): stop reporting landed user operations as failed - #357

Merged
Ghadi8 merged 12 commits into
mainfrom
mariano/fix-keyless
Sep 24, 2026
Merged

Ghadi8 merged 12 commits into
mainfrom
mariano/fix-keyless

Conversation

@mariano-aguero

@mariano-aguero mariano-aguero commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

What

Operations that landed are no longer reported as failed or reverted, and a failed token quote now says what the proxy answered.

Why

viem hands a receipt's transaction status over as 'success' or 'reverted', and pollForReceipt compared it with '0x1', so every successful operation was stored as reverted. The operation's own result is receipt.success, which is what decides now, also in transformReceiptsToEIP5792, where a reverted operation in a mined transaction read as successful. Receipts without success, like ones persisted by earlier versions, are still read by their transaction status.

Some bundlers also fail eth_getUserOperationReceipt for operations they did bundle. Etherspot answers "Missing/invalid userOpHash" for EntryPoint v0.8, which marked successful calls as failed and made a permission grant that had landed report an error. waitForOperationReceipt reads the EntryPoint's UserOperationEvent when the bundler fails, for both wallet_sendCalls and sendTransaction, and leaves an operation that is not on chain yet pending instead of failed. On young chains the event search starts at genesis.

fetchTokenQuotes now checks response.ok, so a proxy error shows its status instead of "no quotes array".

App-specific mode stays gated by an api-key. An earlier version of this PR made it optional; that change and the UI changes that depended on it are reverted here.

Closes N/A

How to test

bun install
bunx nx run-many -t typecheck lint test --projects=@jaw.id/core
bunx nx build @jaw.id/core

The tests worth reading are rpc/wallet_sendCalls.receipt.test.ts and the receipt block in account/smartAccount.test.ts: a successful receipt ends up completed, and an operation the bundler has no receipt for is read from the chain, completed, reverted or left pending.

By hand, these fixes ran in an app-specific dApp on localhost against staging, on a build that still included the keyless change. A batched USDC transfer, a swap and a permission grant all settled on Base Sepolia and were reported as completed. That run has not been repeated on the current head.

Checklist

  • The title is a conventional commit and reads as the subject it becomes on squash. nx release takes the version bump from its type
  • bunx prettier --check . and bunx nx affected -t lint test typecheck build api-check pass, which is what CI runs
  • @jaw.id/core's public API is unchanged, or bunx nx api-update @jaw.id/core ran and the report diff is part of this PR
  • Docs updated, if this changes behaviour somebody integrates against

Nothing here changes behaviour an integrator configures against.

@vercel

vercel Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
demo Ready Ready Preview Sep 24, 2026 11:25am UTC
jaw-docs Ready Ready Preview Sep 24, 2026 11:25am UTC
keys-jaw-id Ready Ready Preview Sep 24, 2026 11:25am UTC
playground Ready Ready Preview Sep 24, 2026 11:25am UTC

Request Review

@justalab-agents justalab-agents 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.

Findings outside the diff

These sit on lines this PR did not change, but this PR is what makes them wrong. They cannot be posted as inline comments.

Reviewer callouts (1)

Non-blocking observations. Nothing here needs to change before merge.

  • .github:1 — "The ubuntu-latest label will migrate to Ubuntu 26 beginning October 19, 2026. For more information, see actions/runner-images#14748"

@mariano-aguero

Copy link
Copy Markdown
Contributor Author

Conflict with #315: it adds a check in grantPermissions that throws when there is no api key, which blocks the keyless grant this PR enables. The check needs to be dropped from #315 before merge, and the keyless grant retested once both are on main. Following up tomorrow.

@mariano-aguero mariano-aguero changed the title feat(core): serve app-specific mode without an api-key fix(core): stop reporting landed user operations as failed Sep 24, 2026
@mariano-aguero

Copy link
Copy Markdown
Contributor Author

Resolved here: with app-specific mode kept behind an api-key, this PR no longer enables a keyless grant, so the check #315 adds in grantPermissions does not block anything this PR changes. The keyless app-specific change is reverted in e9010eb.

@Ghadi8
Ghadi8 merged commit 1c1e204 into main Sep 24, 2026
7 checks passed
@Ghadi8
Ghadi8 deleted the mariano/fix-keyless branch September 24, 2026 12:45

This branch was successfully deployed

4 active deployments
Preview – demo — e9010eb9 Deployed Sep 24, 2026 by vercel[bot]
Preview – jaw-docs — e9010eb9 Deployed Sep 24, 2026 by vercel[bot]
Preview – keys-jaw-id — e9010eb9 Deployed Sep 24, 2026 by vercel[bot]
Preview – playground — e9010eb9 Deployed Sep 24, 2026 by vercel[bot]
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