Skip to content

fix: port recent viem fixes to AbiItem, AbiEvent, Signature, TypedData, Hex, and RpcTransport - #526

Merged
jxom merged 8 commits into
mainfrom
jxom/happy-pascal-cptf94
Oct 25, 2026
Merged

jxom merged 8 commits into
mainfrom
jxom/happy-pascal-cptf94

Conversation

@jxom

@jxom jxom commented Oct 24, 2026 •

Copy link
Copy Markdown
Member

Ports the viem fixes whose logic also lives in Ox, in sync with viem main at 2867b2a and with the 0.x backport in #527. One commit per fix, each with a changeset and regression tests that fail without it.

viem Ox change
wevm/viem#5240 TypedData.extractEip712DomainTypes keeps an empty version (''), so encode/getSignPayload/hashDomain match viem (0xa437e12e…).
wevm/viem#5283 Hex.assert / Hex.validate accept even: true, which rejects odd-length hex (Hex.InvalidLengthError).
wevm/viem#5279 Signature.toHex / toBytes left-pad r and s shorter than 32 bytes. Before, a 31-byte s serialized to 64 bytes and fromHex misread it.
wevm/viem#5281 AbiItem.fromAbi: matches arrays with a 0 in the element size (uint160[]) and checks [M] lengths. Tuple object args are read by component name, and params after a tuple are still checked. address[] vs bytes20[]/string[]/bytes[] overloads, including empty arrays, now throw AmbiguityError.
wevm/viem#5280 AbiEvent.assertArgs / extractLogs args filters match non-indexed string/bytes by value (not hash), indexed args decoded from data in non-strict mode, and bytes/bytesN in either hex case.
wevm/viem#5200 RpcTransport.fromHttp applies timeout to reading the response body, not only to fetch resolving. On runtimes without AbortSignal.any (Node < 18.17, Safari < 17.4), a fetchOptions.signal is now used alone instead of throwing.
AbiItem.fromAbi(Abi.from(['function foo(bool x)', 'function foo(uint160[] x)']), 'foo', { args: [[1n, 2n]] })
// before: foo(bool) (array arg never matched)   after: foo(uint160[])

Overlaps: #523 (AbiItem) and #446 (Signature.toHex padding). This PR includes both fixes.

Not ported, since Ox already has them or has no matching code: indexed string UTF-8 hashing (wevm/viem#5238, already correct here), normalizeSignature (wevm/viem#5201, already #516), http batch errors (wevm/viem#5282, RpcTransport has no batching), and request retries (wevm/viem#5286, wevm/viem#5288, Ox has no retry layer). Viem-only actions, chains, and Tempo client code are also out.

Differences from #527 follow from the branches: 0.x has no extractLogs and already pads Signature r/s, while main already has #516 and the docgen Variable link fix.

Validation: pnpm check:types and pnpm check pass. The changed suites pass with SKIP_GLOBAL_SETUP=1 pnpm test --project core, except existing tests that need a local Anvil node, which wasn't available. Every new test was confirmed to fail on unpatched sources.

🤖 Generated with Claude Code

https://claude.ai/code/session_0133zgX2g8oLCoH4KuY8tM9b

@vercel

vercel Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
ox Error Error Oct 25, 2026 11:44pm UTC

Request Review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-25T23:46:54.995075Z 88b61a2 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@pkg-pr-new

pkg-pr-new Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/ox@526

commit: 88b61a2

@Revinand

Copy link
Copy Markdown

The AbiItem commit here matches the first two commits of wevm/viem#5281 but not the last one (6b613f0), which reads tuple object args by component name and treats an empty array as ambiguous for address[] vs string[] / bytes[]. On this branch:

  • foo((address a, string b)) / foo((string a, string b)) with { b: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', a: 'hello' } throws AbiItem.AmbiguityError, where viem resolves it to foo((string,string))
  • foo(address[]) / foo(string[]) with [] resolves to foo(string[]) instead of throwing

#523 has both changes in d95257b, with viem's tests. Happy to close it if you'd rather add them here.

…m.fromAbi` overloads

Syncs with the merged wevm/viem#5281: tuple object args are read by component
name, and an empty array is ambiguous for `address[]` vs `string[]`/`bytes[]`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133zgX2g8oLCoH4KuY8tM9b

jxom commented Oct 24, 2026

Copy link
Copy Markdown
Member Author

Thanks, confirmed against the merged wevm/viem#5281. f75afaa adds both changes here: tuple object args are now read by component name (as AbiParameters.encode reads them), and an empty array is ambiguous for address[] vs string[]/bytes[]. It also adds viem's three new test cases, and each one fails without the change. The 0.x backport (#527) has the same fix in 77648f7. This covers everything in #523, so that PR can be closed once this lands.


Generated by Claude Code

…Transport.fromHttp`

Matches the 0.x backport (#527): runtimes without `AbortSignal.any`
(Node < 18.17, older browsers) use the caller signal alone instead of
throwing. Also aligns the `AbiEvent.assertArgs` test and the
`getComponentValue` comment with 0.x.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133zgX2g8oLCoH4KuY8tM9b
jxom pushed a commit that referenced this pull request Oct 25, 2026
Matches the main-branch test in #526.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133zgX2g8oLCoH4KuY8tM9b
@jxom
jxom merged commit 71decbb into main Oct 25, 2026
15 of 16 checks passed
@jxom
jxom deleted the jxom/happy-pascal-cptf94 branch October 25, 2026 23:43
jxom added a commit that referenced this pull request Oct 25, 2026
…`, `Hex`, and `RpcTransport` (#527)

* fix: keep empty `version` in `TypedData.extractEip712DomainTypes`

Ports wevm/viem#5240.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133zgX2g8oLCoH4KuY8tM9b

* feat: add `even` option to `Hex.assert` and `Hex.validate`

Ports wevm/viem#5283.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133zgX2g8oLCoH4KuY8tM9b

* fix: array overload resolution in `AbiItem.fromAbi`

Ports wevm/viem#5281.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133zgX2g8oLCoH4KuY8tM9b

* fix: `AbiEvent.assertArgs` `string` and `bytes` matching

Ports wevm/viem#5238 and wevm/viem#5280.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133zgX2g8oLCoH4KuY8tM9b

* fix: apply `RpcTransport.fromHttp` timeout to the response body and with a caller signal

Ports wevm/viem#5200.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133zgX2g8oLCoH4KuY8tM9b

* fix: keep first parameter after `( ` in normalizeSignature (#516)

(cherry picked from commit 36dce4a)

* test: format `Hex` and `RpcTransport` tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133zgX2g8oLCoH4KuY8tM9b

* fix: read tuple object args by name and match empty arrays in `AbiItem.fromAbi` overloads

Syncs with the merged wevm/viem#5281: tuple object args are read by component
name, and an empty array is ambiguous for `address[]` vs `string[]`/`bytes[]`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133zgX2g8oLCoH4KuY8tM9b

* fix: use a line comment for `getComponentValue` to satisfy `check:tsdoc`

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133zgX2g8oLCoH4KuY8tM9b

* fix(docgen): link to variables in API docs

Ports the `Variable` case of `getLinkForApiItem` from `main` (#414). Without
it, the `{@link ox#AccountConfig.maxSignatures}` reference added in #509
fails `docs:gen` and every `0.x` docs deployment.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133zgX2g8oLCoH4KuY8tM9b

* fix: keep the caller signal when `AbortSignal.any` is missing in `RpcTransport.fromHttp`

`AbortSignal.any` is missing on Node < 18.17 and older browsers, which the
0.x line supports. There, the transport now uses the caller signal alone,
as it did before, instead of throwing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133zgX2g8oLCoH4KuY8tM9b

* test: restore `AbortSignal.any` by property descriptor

Matches the main-branch test in #526.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133zgX2g8oLCoH4KuY8tM9b

---------

Co-authored-by: Claude <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 88b61a22f3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/core/RpcTransport.ts
Comment on lines +114 to +116
// Runtimes without `AbortSignal.any` (e.g. Node < 18.17) keep
// only the caller's signal.
if (typeof AbortSignal.any !== 'function') return signals[0]!

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve the timeout signal in the fallback

When AbortSignal.any is unavailable and the caller supplies fetchOptions.signal, this fallback selects only the caller's signal and drops the timeout signal. Because withTimeout is invoked with signal: true, its timer merely aborts its internal controller rather than directly rejecting; a stalled fetch or response.text() therefore ignores the configured timeout and can hang until it eventually completes. The fallback needs to propagate both abort sources or otherwise ensure the timeout rejects independently.

Useful? React with 👍 / 👎.

Comment on lines +596 to +598
isArgOfType(
getComponentValue(arg, component, index),
component as AbiParameters.Parameter,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Prefer the tuple overload that consumes all supplied fields

For tuple overloads where one tuple is a prefix of another, reading object values by component name makes both candidates match even when the argument supplies the longer tuple's extra fields. Since fromAbi retains the last match, reversing the test's ABI order—such as foo((uint256[] a,uint256 b)) followed by foo((uint256[] a)) with { b: 2n, a: [1n] }—selects the shorter overload and subsequent encoding ignores b, producing the wrong selector and calldata. Tuple matching needs to reject or deprioritize candidates that leave supplied tuple fields unused.

Useful? React with 👍 / 👎.

This branch had an error being deployed

1 failed deployment
Preview — 88b61a22 Deployed Oct 25, 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.

3 participants