From 128484d124184804fc86c1fcfd81aa2e5805aa06 Mon Sep 17 00:00:00 2001 From: jxom <7336481+jxom@users.noreply.github.com> Date: Tue, 29 Sep 2026 12:00:53 +1000 Subject: [PATCH] feat: support keyed nonce rpc queries --- .changeset/keyed-nonce-rpc.md | 12 +++++++++++ src/core/_test/RpcSchema.test-d.ts | 32 ++++++++++++++++++++++++++++- src/core/internal/rpcSchemas/eth.ts | 11 +++++++++- 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 .changeset/keyed-nonce-rpc.md diff --git a/.changeset/keyed-nonce-rpc.md b/.changeset/keyed-nonce-rpc.md new file mode 100644 index 000000000..ca96d6cfa --- /dev/null +++ b/.changeset/keyed-nonce-rpc.md @@ -0,0 +1,12 @@ +--- +"ox": patch +--- + +Added optional `nonceKeys` to `eth_getTransactionCount` requests. + +```ts +const nonce = await provider.request({ + method: 'eth_getTransactionCount', + params: [address, 'pending', ['0x1', '0x2']], +}) +``` diff --git a/src/core/_test/RpcSchema.test-d.ts b/src/core/_test/RpcSchema.test-d.ts index 29b1694ac..f0e3ebbe5 100644 --- a/src/core/_test/RpcSchema.test-d.ts +++ b/src/core/_test/RpcSchema.test-d.ts @@ -1,5 +1,5 @@ import type { RpcSchema } from 'ox' -import { expectTypeOf, test } from 'vitest' +import { describe, expectTypeOf, test } from 'vitest' test('ToViem: converts ox schema to viem schema', () => { type OxSchema = @@ -161,3 +161,33 @@ test('frame simulation results expose payer and frame results', () => { expectTypeOf().toEqualTypeOf<`0x${string}`>() expectTypeOf().toEqualTypeOf<`0x${string}`>() }) + +describe('Eth', () => { + test('eth_getTransactionCount', () => { + type Request = RpcSchema.ExtractRequest< + RpcSchema.Eth, + 'eth_getTransactionCount' + > + type Params = Request['params'] + + expectTypeOf<['0x1234', 'latest']>().toMatchTypeOf() + expectTypeOf< + ['0x1234', 'pending', readonly ['0x0']] + >().toMatchTypeOf() + expectTypeOf< + ['0x1234', '0x10', readonly ['0x1', '0x2']] + >().toMatchTypeOf() + expectTypeOf<['0x1234', 'latest', undefined]>().toMatchTypeOf() + expectTypeOf<['0x1234', 'latest', '0x1']>().not.toMatchTypeOf() + expectTypeOf< + ['0x1234', 'latest', readonly [1n]] + >().not.toMatchTypeOf() + expectTypeOf<['0x1234', readonly ['0x1']]>().not.toMatchTypeOf() + expectTypeOf< + ['0x1234', 'latest', readonly ['0x1'], '0x2'] + >().not.toMatchTypeOf() + expectTypeOf< + RpcSchema.ExtractReturnType + >().toEqualTypeOf<`0x${string}`>() + }) +}) diff --git a/src/core/internal/rpcSchemas/eth.ts b/src/core/internal/rpcSchemas/eth.ts index 66b6eff1d..e9958dde8 100644 --- a/src/core/internal/rpcSchemas/eth.ts +++ b/src/core/internal/rpcSchemas/eth.ts @@ -557,7 +557,15 @@ export type Eth = RpcSchema.From< ReturnType: Transaction.Rpc | null } /** - * Returns the number of transactions sent from an address + * Returns the account nonce or the shared EIP-8250 sequence at the selected block. + * + * Omitted `nonceKeys` or `['0x0']` queries the account nonce. Nonzero keys query + * their shared sequence, with unused keys returning zero. `pending` uses pending state. + * Keys must be 1–16 canonical uint256 quantities in strictly increasing order; + * zero cannot be combined with other keys. + * + * Invalid keys return RPC error `-32602`. Differing sequences or EIP-8250 being + * inactive at the selected block for nonzero keys return `-32000`. * * @example * ``` @@ -575,6 +583,7 @@ export type Eth = RpcSchema.From< | Block.Tag | Block.Hash | Block.Identifier, + nonceKeys?: readonly Hex.Hex[] | undefined, ] } ReturnType: Hex.Hex