Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/big-humans-learn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"viem": patch
---

Added support for `blockOverrides` on `call`.
12 changes: 10 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions src/actions/public/call.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from '~contracts/generated.js'
import {
baycContractConfig,
multicall3ContractConfig,
usdcContractConfig,
wagmiContractConfig,
} from '~test/src/abis.js'
Expand Down Expand Up @@ -51,6 +52,7 @@ const wagmiContractAddress = '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2'
const name4bytes = '0x06fdde03'
const mint4bytes = '0x1249c58b'
const mintWithParams4bytes = '0xa0712d68'
const getCurrentBlockTimestamp4bytes = '0x0f28c97d'
const fourTwenty =
'00000000000000000000000000000000000000000000000000000000000001a4'
const sixHundred =
Expand Down Expand Up @@ -200,6 +202,16 @@ test('args: override', async () => {
)
})

test.skip('args: blockOverrides', async () => {
// TODO: don't skip once block overrides are supported in Anvil.
const { data } = await call(client, {
data: getCurrentBlockTimestamp4bytes,
code: multicall3ContractConfig.bytecode,
blockOverrides: { time: 420n },
})
expect(data).toMatchInlineSnapshot(fourTwenty)
})

test.skip('args: blobs', async () => {
// TODO: migrate to `client` once 4844 is supported in Anvil.
const blobs = toBlobs({ data: stringToHex(blobData) })
Expand Down
34 changes: 26 additions & 8 deletions src/actions/public/call.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type Address, parseAbi } from 'abitype'
import * as BlockOverrides from 'ox/BlockOverrides'
Copy link
Member

Choose a reason for hiding this comment

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

nice :D


import type { Account } from '../../accounts/types.js'
import {
Expand Down Expand Up @@ -83,6 +84,8 @@ export type CallParameters<
account?: Account | Address | undefined
/** Whether or not to enable multicall batching on this call. */
batch?: boolean | undefined
/** Block overrides for the call. */
blockOverrides?: BlockOverrides.BlockOverrides | undefined
/** Bytecode to perform the call on. */
code?: Hex | undefined
/** Contract deployment factory address (ie. Create2 factory, Smart Account factory, etc). */
Expand Down Expand Up @@ -159,6 +162,7 @@ export async function call<chain extends Chain | undefined>(
blockTag = 'latest',
accessList,
blobs,
blockOverrides,
code,
data: data_,
factory,
Expand Down Expand Up @@ -211,6 +215,9 @@ export async function call<chain extends Chain | undefined>(
const blockNumberHex = blockNumber ? numberToHex(blockNumber) : undefined
const block = blockNumberHex || blockTag

const rpcBlockOverrides = blockOverrides
? BlockOverrides.toRpc(blockOverrides)
: undefined
const rpcStateOverride = serializeStateOverride(stateOverride)

const chainFormat = client.chain?.formatters?.transactionRequest?.format
Expand All @@ -233,7 +240,12 @@ export async function call<chain extends Chain | undefined>(
value,
} as TransactionRequest) as TransactionRequest

if (batch && shouldPerformMulticall({ request }) && !rpcStateOverride) {
if (
batch &&
shouldPerformMulticall({ request }) &&
!rpcStateOverride &&
!rpcBlockOverrides
) {
try {
return await scheduleMulticall(client, {
...request,
Expand All @@ -249,15 +261,21 @@ export async function call<chain extends Chain | undefined>(
}
}

const params = (() => {
const base = [
request as ExactPartial<RpcTransactionRequest>,
block,
] as const
if (rpcStateOverride && rpcBlockOverrides)
return [...base, rpcStateOverride, rpcBlockOverrides] as const
if (rpcStateOverride) return [...base, rpcStateOverride] as const
if (rpcBlockOverrides) return [...base, {}, rpcBlockOverrides] as const
return base
})()

const response = await client.request({
method: 'eth_call',
params: rpcStateOverride
? [
request as ExactPartial<RpcTransactionRequest>,
block,
rpcStateOverride,
]
: [request as ExactPartial<RpcTransactionRequest>, block],
params,
})
if (response === '0x') return { data: undefined }
return { data: response }
Expand Down
12 changes: 9 additions & 3 deletions src/types/eip1193.ts
Original file line number Diff line number Diff line change
Expand Up @@ -643,15 +643,21 @@ export type PublicRpcSchema = [
{
Method: 'eth_call'
Parameters:
| [transaction: ExactPartial<TransactionRequest>]
| [
| readonly [transaction: ExactPartial<TransactionRequest>]
| readonly [
transaction: ExactPartial<TransactionRequest>,
block: BlockNumber | BlockTag | BlockIdentifier,
]
| [
| readonly [
transaction: ExactPartial<TransactionRequest>,
block: BlockNumber | BlockTag | BlockIdentifier,
stateOverrideSet: RpcStateOverride,
]
| readonly [
transaction: ExactPartial<TransactionRequest>,
block: BlockNumber | BlockTag | BlockIdentifier,
stateOverrideSet: RpcStateOverride,
blockOverrides: BlockOverrides.Rpc,
]
ReturnType: Hex
},
Expand Down
9 changes: 8 additions & 1 deletion test/src/abis.ts

Large diffs are not rendered by default.