feat(gateway): ABI-decode revert data into human-readable API errors - #842
Open
agentotto[bot] wants to merge 7 commits into
Open
feat(gateway): ABI-decode revert data into human-readable API errors#842agentotto[bot] wants to merge 7 commits into
agentotto[bot] wants to merge 7 commits into
Conversation
The gateway previously surfaced raw RPC errors (hex-encoded custom-error
selectors buried in JSON-RPC messages) directly to API callers. Add
structured ABI decoding of revert data so callers see stable, meaningful
error messages instead of opaque hex.
Changes
- New `contract_errors` module: decodes revert data against the V1 and
V2 WorldIDRegistry ABIs (via the `sol!`-generated `*Errors` enums'
`name_by_selector`), then maps the recognised variant to a
`GatewayErrorCode` and a human-readable message. V2 is tried first so
richer V2-only variants (e.g. `RecoveryAgentUpdateWindowExpired`)
win when a shared selector matches both ABIs.
- `GatewayErrorResponse`: adds `from_rpc_error` (for
`RpcError<TransportErrorKind>` from `provider.call`) and
`from_contract_error` (for `alloy::contract::Error` from
`sol!`-generated builders). Both attempt structured decoding first
and fall back to the existing string-matching `from_simulation_error`
path when revert data is absent or unknown.
- `simulate_calldata` (validation) and `is_valid_root` now use the
structured decoders, so simulation failures surface as e.g.
`{"code": "authenticator_already_exists", "message": "WorldID:
authenticator address is already in use by another account"}`
instead of `0x…` hex.
- Batcher: when `send_batch` fails, decode revert data before falling
back to the legacy string scan, so the recorded `Failed` state
carries a decoded message and correct `GatewayErrorCode`.
- `parse_contract_error` retained (and unit-tested) as the string-based
fallback for paths where structured errors aren't available.
Tests
- 9 unit tests in `contract_errors` covering V1-only, V2-only, and
shared selectors; short/unknown data; the `selector_hex` helper.
- 4 unit tests in `error` covering the fallback string-matching path
and the new `from_decoded_revert` constructor.
PROTO-4873
Co-authored-by: Otto <otto@toolsforhumanity.com>
Co-authored-by: Otto <otto@toolsforhumanity.com>
Contributor
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 6a4ff7c. Configure here.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
ABI-decode World ID registry reverts in the gateway so API callers receive stable error codes and human-readable messages instead of opaque selector hex.
Changes
sol!-generatedWorldIdRegistryV2Errorsvariants.GatewayErrorCodeandWorldID:-prefixed messages without string-based dispatch or selector scanning.bad_requestresponses with their original message.Validation
Linear: PROTO-4873
Note
Medium Risk
Changes how all on-chain failure paths surface to API clients and async batch status; behavior is improved but any mapping gap could misclassify reverts as generic bad_request.
Overview
Replaces string/selector hex scanning for World ID registry failures with ABI decoding of revert data via
WorldIdRegistryV2Errors, so clients get stableGatewayErrorCodevalues andWorldID:-prefixed messages instead of opaque RPC blobs.A new
contract_errorsmodule decodes revert bytes from alloy transport and contract errors, maps variants to codes and human text (including V2 recovery and broader registry errors), and leaves undecodable failures as generic bad requests with the original message.GatewayErrorResponsedropsfrom_simulation_error/parse_contract_errorin favor offrom_rpc_error,from_contract_error, andfrom_decoded_revert. Simulation (validation),is_valid_rootreads, and batch submit failures all use this path; the gatewayhexdependency is removed. Unit tests usetest-case; integration tests assertauthenticator_already_existson duplicate-authenticator flows.Reviewed by Cursor Bugbot for commit 731cf58. Bugbot is set up for automated code reviews on this repo. Configure here.