Failed RPC calls reach the site with no error code and without the node's revert data #533

Closed
opened 2026-10-14 05:05:22 +02:00 by clawbot · 1 comment
Collaborator

Where

proxyRpc() in src/background/index.js (lines 290-307) turns a node's JSON-RPC error into new Error(message), and the read-only proxy answers the page with { message } alone (line 1065). A transaction that cannot be prepared fails back with a message and no code too (src/shared/approvalTx.js, lines 191-200).

What happens

On next (8e52528), release build, Chrome, local chain with chain id 11155111, from a connected site:

  • eth_call to a reverting token transfer: the node answers code 3 with the revert data. The page gets "execution reverted: bal" with no code and no data.
  • eth_getBalance with a malformed address: "invalid string length", no code.
  • eth_sendTransaction whose gas estimate reverts: "The transaction could not be prepared: ...", no code.

A site cannot tell these failures apart, or from a rejection, and cannot decode a custom revert error.

What should happen

EIP-1193, Errors: a rejected request's error carries a numeric code, and may carry data. A node's error should reach the page with the node's code and data; an error the wallet raises itself should carry an EIP-1193 or EIP-1474 code, as its rejection and unsupported-method answers already do.

Severity: minor

Definition of done

  • Every rejected request reaches the page with a numeric code.
  • A node error reaches the page with the node's code and data unchanged.
  • Tests cover a reverting eth_call and a failed transaction preparation.

Model: opus-5-5

## Where `proxyRpc()` in `src/background/index.js` (lines 290-307) turns a node's JSON-RPC error into `new Error(message)`, and the read-only proxy answers the page with `{ message }` alone (line 1065). A transaction that cannot be prepared fails back with a message and no code too (`src/shared/approvalTx.js`, lines 191-200). ## What happens On `next` (8e52528), release build, Chrome, local chain with chain id 11155111, from a connected site: - `eth_call` to a reverting token `transfer`: the node answers code 3 with the revert data. The page gets "execution reverted: bal" with no `code` and no `data`. - `eth_getBalance` with a malformed address: "invalid string length", no `code`. - `eth_sendTransaction` whose gas estimate reverts: "The transaction could not be prepared: ...", no `code`. A site cannot tell these failures apart, or from a rejection, and cannot decode a custom revert error. ## What should happen EIP-1193, Errors: a rejected request's error carries a numeric `code`, and may carry `data`. A node's error should reach the page with the node's `code` and `data`; an error the wallet raises itself should carry an EIP-1193 or EIP-1474 code, as its rejection and unsupported-method answers already do. Severity: minor ## Definition of done - [ ] Every rejected request reaches the page with a numeric `code`. - [ ] A node error reaches the page with the node's `code` and `data` unchanged. - [ ] Tests cover a reverting `eth_call` and a failed transaction preparation. Model: opus-5-5
clawbot self-assigned this 2026-10-14 05:05:22 +02:00
Author
Collaborator

Plan: the page side already passes a code and data through (src/content/inpage.js builds its error from both when a code is present), so the fix is in the background. proxyRpc() in src/background/index.js keeps the node's JSON-RPC code and data on the error it throws, and every place the background answers a page with { error: { message } } alone gets a numeric code: the node's own code and data unchanged when the failure came from the node, otherwise EIP-1474 -32603 (internal error) for a failure inside the wallet, or -32602 (invalid params) for a request the wallet refuses as malformed, such as a missing address. "No accounts available" answers EIP-1193 4100. A transaction that cannot be prepared (prepareApprovalTx() in src/shared/approvalTx.js) keeps its sentence and carries the node's code and data when the cause was a node error, such as a reverting gas estimate, otherwise -32603. No new module; if a small helper is needed to build the error answer it lives in src/background/index.js next to the existing error answers. Tests, in a new tests/rpcErrorCodes.test.js: a reverting eth_call reaches the page with code 3 and the revert data; a malformed eth_getBalance keeps the node's code; an eth_sendTransaction whose gas estimate reverts gets the node's code and data; no rejected request reaches the page without a numeric code.

Model: opus-5-5

Plan: the page side already passes a `code` and `data` through (`src/content/inpage.js` builds its error from both when a code is present), so the fix is in the background. `proxyRpc()` in `src/background/index.js` keeps the node's JSON-RPC `code` and `data` on the error it throws, and every place the background answers a page with `{ error: { message } }` alone gets a numeric code: the node's own `code` and `data` unchanged when the failure came from the node, otherwise EIP-1474 `-32603` (internal error) for a failure inside the wallet, or `-32602` (invalid params) for a request the wallet refuses as malformed, such as a missing address. "No accounts available" answers EIP-1193 `4100`. A transaction that cannot be prepared (`prepareApprovalTx()` in `src/shared/approvalTx.js`) keeps its sentence and carries the node's `code` and `data` when the cause was a node error, such as a reverting gas estimate, otherwise `-32603`. No new module; if a small helper is needed to build the error answer it lives in `src/background/index.js` next to the existing error answers. Tests, in a new `tests/rpcErrorCodes.test.js`: a reverting `eth_call` reaches the page with code `3` and the revert data; a malformed `eth_getBalance` keeps the node's code; an `eth_sendTransaction` whose gas estimate reverts gets the node's code and data; no rejected request reaches the page without a numeric code. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/AutistMask#533