viem 0.3.12 → 0.3.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/actions/public/call.js +12 -1
- package/dist/cjs/actions/public/call.js.map +1 -1
- package/dist/cjs/actions/public/simulateContract.js +2 -2
- package/dist/cjs/actions/public/simulateContract.js.map +1 -1
- package/dist/cjs/actions/test/dropTransaction.js +1 -1
- package/dist/cjs/actions/test/dropTransaction.js.map +1 -1
- package/dist/cjs/actions/test/impersonateAccount.js +1 -1
- package/dist/cjs/actions/test/impersonateAccount.js.map +1 -1
- package/dist/cjs/actions/test/mine.js +1 -1
- package/dist/cjs/actions/test/mine.js.map +1 -1
- package/dist/cjs/actions/test/removeBlockTimestampInterval.js +1 -1
- package/dist/cjs/actions/test/removeBlockTimestampInterval.js.map +1 -1
- package/dist/cjs/actions/test/reset.js +1 -1
- package/dist/cjs/actions/test/reset.js.map +1 -1
- package/dist/cjs/actions/test/revert.js +1 -1
- package/dist/cjs/actions/test/revert.js.map +1 -1
- package/dist/cjs/actions/test/setAutomine.js +1 -1
- package/dist/cjs/actions/test/setAutomine.js.map +1 -1
- package/dist/cjs/actions/test/setBalance.js +1 -1
- package/dist/cjs/actions/test/setBalance.js.map +1 -1
- package/dist/cjs/actions/test/setBlockGasLimit.js +1 -1
- package/dist/cjs/actions/test/setBlockGasLimit.js.map +1 -1
- package/dist/cjs/actions/test/setBlockTimestampInterval.js +1 -1
- package/dist/cjs/actions/test/setBlockTimestampInterval.js.map +1 -1
- package/dist/cjs/actions/test/setCode.js +1 -1
- package/dist/cjs/actions/test/setCode.js.map +1 -1
- package/dist/cjs/actions/test/setCoinbase.js +1 -1
- package/dist/cjs/actions/test/setCoinbase.js.map +1 -1
- package/dist/cjs/actions/test/setIntervalMining.js +1 -1
- package/dist/cjs/actions/test/setIntervalMining.js.map +1 -1
- package/dist/cjs/actions/test/setLoggingEnabled.js +1 -1
- package/dist/cjs/actions/test/setLoggingEnabled.js.map +1 -1
- package/dist/cjs/actions/test/setMinGasPrice.js +1 -1
- package/dist/cjs/actions/test/setMinGasPrice.js.map +1 -1
- package/dist/cjs/actions/test/setNextBlockBaseFeePerGas.js +1 -1
- package/dist/cjs/actions/test/setNextBlockBaseFeePerGas.js.map +1 -1
- package/dist/cjs/actions/test/setNextBlockTimestamp.js +1 -1
- package/dist/cjs/actions/test/setNextBlockTimestamp.js.map +1 -1
- package/dist/cjs/actions/test/setNonce.js +1 -1
- package/dist/cjs/actions/test/setNonce.js.map +1 -1
- package/dist/cjs/actions/test/setRpcUrl.js +1 -1
- package/dist/cjs/actions/test/setRpcUrl.js.map +1 -1
- package/dist/cjs/actions/test/setStorageAt.js +1 -1
- package/dist/cjs/actions/test/setStorageAt.js.map +1 -1
- package/dist/cjs/actions/test/stopImpersonatingAccount.js +1 -1
- package/dist/cjs/actions/test/stopImpersonatingAccount.js.map +1 -1
- package/dist/cjs/actions/wallet/writeContract.js +2 -2
- package/dist/cjs/actions/wallet/writeContract.js.map +1 -1
- package/dist/cjs/chains.js +2 -4
- package/dist/cjs/chains.js.map +1 -1
- package/dist/cjs/constants/address.js +5 -0
- package/dist/cjs/constants/address.js.map +1 -0
- package/dist/cjs/constants/index.js +3 -1
- package/dist/cjs/constants/index.js.map +1 -1
- package/dist/cjs/errors/base.js +17 -0
- package/dist/cjs/errors/base.js.map +1 -1
- package/dist/cjs/errors/ccip.js +68 -0
- package/dist/cjs/errors/ccip.js.map +1 -0
- package/dist/cjs/errors/index.js +7 -3
- package/dist/cjs/errors/index.js.map +1 -1
- package/dist/cjs/errors/request.js +1 -1
- package/dist/cjs/errors/request.js.map +1 -1
- package/dist/cjs/errors/version.js +1 -1
- package/dist/cjs/index.js +10 -4
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/utils/ccip.js +97 -0
- package/dist/cjs/utils/ccip.js.map +1 -0
- package/dist/cjs/utils/errors/getContractError.js +1 -5
- package/dist/cjs/utils/errors/getContractError.js.map +1 -1
- package/dist/cjs/utils/errors/getNodeError.js +1 -1
- package/dist/cjs/utils/errors/getNodeError.js.map +1 -1
- package/dist/cjs/utils/index.js +8 -3
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/esm/actions/public/call.js +12 -2
- package/dist/esm/actions/public/call.js.map +1 -1
- package/dist/esm/actions/public/simulateContract.js +2 -2
- package/dist/esm/actions/public/simulateContract.js.map +1 -1
- package/dist/esm/actions/test/dropTransaction.js +1 -1
- package/dist/esm/actions/test/dropTransaction.js.map +1 -1
- package/dist/esm/actions/test/impersonateAccount.js +1 -1
- package/dist/esm/actions/test/impersonateAccount.js.map +1 -1
- package/dist/esm/actions/test/mine.js +1 -1
- package/dist/esm/actions/test/mine.js.map +1 -1
- package/dist/esm/actions/test/removeBlockTimestampInterval.js +1 -1
- package/dist/esm/actions/test/removeBlockTimestampInterval.js.map +1 -1
- package/dist/esm/actions/test/reset.js +1 -1
- package/dist/esm/actions/test/reset.js.map +1 -1
- package/dist/esm/actions/test/revert.js +1 -1
- package/dist/esm/actions/test/revert.js.map +1 -1
- package/dist/esm/actions/test/setAutomine.js +1 -1
- package/dist/esm/actions/test/setAutomine.js.map +1 -1
- package/dist/esm/actions/test/setBalance.js +1 -1
- package/dist/esm/actions/test/setBalance.js.map +1 -1
- package/dist/esm/actions/test/setBlockGasLimit.js +1 -1
- package/dist/esm/actions/test/setBlockGasLimit.js.map +1 -1
- package/dist/esm/actions/test/setBlockTimestampInterval.js +1 -1
- package/dist/esm/actions/test/setBlockTimestampInterval.js.map +1 -1
- package/dist/esm/actions/test/setCode.js +1 -1
- package/dist/esm/actions/test/setCode.js.map +1 -1
- package/dist/esm/actions/test/setCoinbase.js +1 -1
- package/dist/esm/actions/test/setCoinbase.js.map +1 -1
- package/dist/esm/actions/test/setIntervalMining.js +1 -1
- package/dist/esm/actions/test/setIntervalMining.js.map +1 -1
- package/dist/esm/actions/test/setLoggingEnabled.js +1 -1
- package/dist/esm/actions/test/setLoggingEnabled.js.map +1 -1
- package/dist/esm/actions/test/setMinGasPrice.js +1 -1
- package/dist/esm/actions/test/setMinGasPrice.js.map +1 -1
- package/dist/esm/actions/test/setNextBlockBaseFeePerGas.js +1 -1
- package/dist/esm/actions/test/setNextBlockBaseFeePerGas.js.map +1 -1
- package/dist/esm/actions/test/setNextBlockTimestamp.js +1 -1
- package/dist/esm/actions/test/setNextBlockTimestamp.js.map +1 -1
- package/dist/esm/actions/test/setNonce.js +1 -1
- package/dist/esm/actions/test/setNonce.js.map +1 -1
- package/dist/esm/actions/test/setRpcUrl.js +1 -1
- package/dist/esm/actions/test/setRpcUrl.js.map +1 -1
- package/dist/esm/actions/test/setStorageAt.js +1 -1
- package/dist/esm/actions/test/setStorageAt.js.map +1 -1
- package/dist/esm/actions/test/stopImpersonatingAccount.js +1 -1
- package/dist/esm/actions/test/stopImpersonatingAccount.js.map +1 -1
- package/dist/esm/actions/wallet/writeContract.js +2 -2
- package/dist/esm/actions/wallet/writeContract.js.map +1 -1
- package/dist/esm/chains.js +0 -1
- package/dist/esm/chains.js.map +1 -1
- package/dist/esm/constants/address.js +2 -0
- package/dist/esm/constants/address.js.map +1 -0
- package/dist/esm/constants/index.js +1 -0
- package/dist/esm/constants/index.js.map +1 -1
- package/dist/esm/errors/base.js +17 -0
- package/dist/esm/errors/base.js.map +1 -1
- package/dist/esm/errors/ccip.js +62 -0
- package/dist/esm/errors/ccip.js.map +1 -0
- package/dist/esm/errors/index.js +1 -0
- package/dist/esm/errors/index.js.map +1 -1
- package/dist/esm/errors/request.js +1 -1
- package/dist/esm/errors/request.js.map +1 -1
- package/dist/esm/errors/version.js +1 -1
- package/dist/esm/index.js +2 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/utils/ccip.js +92 -0
- package/dist/esm/utils/ccip.js.map +1 -0
- package/dist/esm/utils/errors/getContractError.js +3 -7
- package/dist/esm/utils/errors/getContractError.js.map +1 -1
- package/dist/esm/utils/errors/getNodeError.js +1 -1
- package/dist/esm/utils/errors/getNodeError.js.map +1 -1
- package/dist/esm/utils/index.js +1 -0
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/types/actions/public/call.d.ts +1 -0
- package/dist/types/actions/public/call.d.ts.map +1 -1
- package/dist/types/actions/public/simulateContract.d.ts +4 -2
- package/dist/types/actions/public/simulateContract.d.ts.map +1 -1
- package/dist/types/actions/wallet/writeContract.d.ts +6 -3
- package/dist/types/actions/wallet/writeContract.d.ts.map +1 -1
- package/dist/types/chains.d.ts +0 -1
- package/dist/types/chains.d.ts.map +1 -1
- package/dist/types/constants/address.d.ts +2 -0
- package/dist/types/constants/address.d.ts.map +1 -0
- package/dist/types/constants/index.d.ts +1 -0
- package/dist/types/constants/index.d.ts.map +1 -1
- package/dist/types/errors/base.d.ts +2 -0
- package/dist/types/errors/base.d.ts.map +1 -1
- package/dist/types/errors/ccip.d.ts +29 -0
- package/dist/types/errors/ccip.d.ts.map +1 -0
- package/dist/types/errors/index.d.ts +1 -0
- package/dist/types/errors/index.d.ts.map +1 -1
- package/dist/types/errors/request.d.ts +2 -2
- package/dist/types/errors/request.d.ts.map +1 -1
- package/dist/types/errors/version.d.ts +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/utils/ccip.d.ts +35 -0
- package/dist/types/utils/ccip.d.ts.map +1 -0
- package/dist/types/utils/errors/getContractError.d.ts.map +1 -1
- package/dist/types/utils/formatters/transaction.d.ts +1 -1
- package/dist/types/utils/index.d.ts +1 -0
- package/dist/types/utils/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/actions/public/call.ts +12 -1
- package/src/actions/public/simulateContract.ts +5 -1
- package/src/actions/test/dropTransaction.ts +1 -1
- package/src/actions/test/impersonateAccount.ts +1 -1
- package/src/actions/test/mine.ts +1 -1
- package/src/actions/test/removeBlockTimestampInterval.ts +1 -1
- package/src/actions/test/reset.ts +1 -1
- package/src/actions/test/revert.ts +1 -1
- package/src/actions/test/setAutomine.ts +1 -1
- package/src/actions/test/setBalance.ts +1 -1
- package/src/actions/test/setBlockGasLimit.ts +1 -1
- package/src/actions/test/setBlockTimestampInterval.ts +1 -1
- package/src/actions/test/setCode.ts +1 -1
- package/src/actions/test/setCoinbase.ts +1 -1
- package/src/actions/test/setIntervalMining.ts +1 -1
- package/src/actions/test/setLoggingEnabled.ts +1 -1
- package/src/actions/test/setMinGasPrice.ts +1 -1
- package/src/actions/test/setNextBlockBaseFeePerGas.ts +1 -1
- package/src/actions/test/setNextBlockTimestamp.ts +1 -1
- package/src/actions/test/setNonce.ts +1 -1
- package/src/actions/test/setRpcUrl.ts +1 -1
- package/src/actions/test/setStorageAt.ts +1 -1
- package/src/actions/test/stopImpersonatingAccount.ts +1 -1
- package/src/actions/wallet/writeContract.ts +7 -2
- package/src/chains.ts +0 -1
- package/src/constants/address.ts +1 -0
- package/src/constants/index.ts +2 -0
- package/src/errors/base.ts +10 -0
- package/src/errors/ccip.ts +74 -0
- package/src/errors/index.ts +6 -0
- package/src/errors/request.ts +3 -3
- package/src/errors/version.ts +1 -1
- package/src/index.ts +5 -0
- package/src/utils/ccip.ts +136 -0
- package/src/utils/errors/getContractError.ts +1 -7
- package/src/utils/errors/getNodeError.ts +1 -1
- package/src/utils/index.ts +7 -0
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import type { PublicClient, Transport } from '../../clients/index.js'
|
2
2
|
import { aggregate3Signature, multicall3Abi } from '../../constants/index.js'
|
3
|
-
import type { BaseError } from '../../errors/index.js'
|
4
3
|
import {
|
4
|
+
BaseError,
|
5
5
|
ChainDoesNotSupportContract,
|
6
6
|
ClientChainNotConfiguredError,
|
7
7
|
RawContractError,
|
@@ -30,6 +30,7 @@ import {
|
|
30
30
|
getCallError,
|
31
31
|
getChainContractAddress,
|
32
32
|
numberToHex,
|
33
|
+
offchainLookupSignature,
|
33
34
|
parseAccount,
|
34
35
|
} from '../../utils/index.js'
|
35
36
|
import { createBatchScheduler } from '../../utils/promise/createBatchScheduler.js'
|
@@ -159,6 +160,11 @@ export async function call<TChain extends Chain | undefined>(
|
|
159
160
|
if (response === '0x') return { data: undefined }
|
160
161
|
return { data: response }
|
161
162
|
} catch (err) {
|
163
|
+
const data = getRevertErrorData(err)
|
164
|
+
if (data?.slice(0, 10) === offchainLookupSignature && to) {
|
165
|
+
const { offchainLookup } = await import('../../utils/ccip.js')
|
166
|
+
return { data: await offchainLookup(client, { data, to }) }
|
167
|
+
}
|
162
168
|
throw getCallError(err as BaseError, {
|
163
169
|
...args,
|
164
170
|
account,
|
@@ -272,3 +278,8 @@ async function scheduleMulticall<TChain extends Chain | undefined>(
|
|
272
278
|
if (returnData === '0x') return { data: undefined }
|
273
279
|
return { data: returnData }
|
274
280
|
}
|
281
|
+
|
282
|
+
export function getRevertErrorData(err: unknown) {
|
283
|
+
if (!(err instanceof BaseError)) return undefined
|
284
|
+
return (err.walk() as { data?: Hex })?.data
|
285
|
+
}
|
@@ -7,6 +7,7 @@ import type {
|
|
7
7
|
ContractFunctionConfig,
|
8
8
|
ContractFunctionResult,
|
9
9
|
GetValue,
|
10
|
+
Hex,
|
10
11
|
} from '../../types/index.js'
|
11
12
|
import {
|
12
13
|
decodeFunctionResult,
|
@@ -29,6 +30,8 @@ export type SimulateContractParameters<
|
|
29
30
|
TChainOverride extends Chain | undefined = undefined,
|
30
31
|
> = {
|
31
32
|
chain?: TChainOverride
|
33
|
+
/** Data to append to the end of the calldata. Useful for adding a ["domain" tag](https://opensea.notion.site/opensea/Seaport-Order-Attributions-ec2d69bf455041a5baa490941aad307f). */
|
34
|
+
dataSuffix?: Hex
|
32
35
|
} & ContractFunctionConfig<TAbi, TFunctionName, 'payable' | 'nonpayable'> &
|
33
36
|
Omit<
|
34
37
|
CallParameters<TChainOverride extends Chain ? TChainOverride : TChain>,
|
@@ -99,6 +102,7 @@ export async function simulateContract<
|
|
99
102
|
abi,
|
100
103
|
address,
|
101
104
|
args,
|
105
|
+
dataSuffix,
|
102
106
|
functionName,
|
103
107
|
...callRequest
|
104
108
|
}: SimulateContractParameters<TAbi, TFunctionName, TChain, TChainOverride>,
|
@@ -116,7 +120,7 @@ export async function simulateContract<
|
|
116
120
|
try {
|
117
121
|
const { data } = await call(client, {
|
118
122
|
batch: false,
|
119
|
-
data: calldata,
|
123
|
+
data: `${calldata}${dataSuffix ? dataSuffix.replace('0x', '') : ''}`,
|
120
124
|
to: address,
|
121
125
|
...callRequest,
|
122
126
|
} as unknown as CallParameters<TChain>)
|
@@ -36,7 +36,7 @@ export async function dropTransaction<TChain extends Chain | undefined>(
|
|
36
36
|
client: TestClient<TestClientMode, Transport, TChain>,
|
37
37
|
{ hash }: DropTransactionParameters,
|
38
38
|
) {
|
39
|
-
|
39
|
+
await client.request({
|
40
40
|
method: `${client.mode}_dropTransaction`,
|
41
41
|
params: [hash],
|
42
42
|
})
|
@@ -36,7 +36,7 @@ export async function impersonateAccount<TChain extends Chain | undefined>(
|
|
36
36
|
client: TestClient<TestClientMode, Transport, TChain>,
|
37
37
|
{ address }: ImpersonateAccountParameters,
|
38
38
|
) {
|
39
|
-
|
39
|
+
await client.request({
|
40
40
|
method: `${client.mode}_impersonateAccount`,
|
41
41
|
params: [address],
|
42
42
|
})
|
package/src/actions/test/mine.ts
CHANGED
@@ -37,7 +37,7 @@ export async function mine<TChain extends Chain | undefined>(
|
|
37
37
|
client: TestClient<TestClientMode, Transport, TChain>,
|
38
38
|
{ blocks, interval }: MineParameters,
|
39
39
|
) {
|
40
|
-
|
40
|
+
await client.request({
|
41
41
|
method: `${client.mode}_mine`,
|
42
42
|
params: [numberToHex(blocks), numberToHex(interval || 0)],
|
43
43
|
})
|
@@ -27,7 +27,7 @@ import type {
|
|
27
27
|
export async function removeBlockTimestampInterval<
|
28
28
|
TChain extends Chain | undefined,
|
29
29
|
>(client: TestClient<TestClientMode, Transport, TChain>) {
|
30
|
-
|
30
|
+
await client.request({
|
31
31
|
method: `${client.mode}_removeBlockTimestampInterval`,
|
32
32
|
})
|
33
33
|
}
|
@@ -36,7 +36,7 @@ export async function reset<TChain extends Chain | undefined>(
|
|
36
36
|
client: TestClient<TestClientMode, Transport, TChain>,
|
37
37
|
{ blockNumber, jsonRpcUrl }: ResetParameters = {},
|
38
38
|
) {
|
39
|
-
|
39
|
+
await client.request({
|
40
40
|
method: `${client.mode}_reset`,
|
41
41
|
params: [{ forking: { blockNumber: Number(blockNumber), jsonRpcUrl } }],
|
42
42
|
})
|
@@ -34,7 +34,7 @@ export async function revert<TChain extends Chain | undefined>(
|
|
34
34
|
client: TestClient<TestClientMode, Transport, TChain>,
|
35
35
|
{ id }: RevertParameters,
|
36
36
|
) {
|
37
|
-
|
37
|
+
await client.request({
|
38
38
|
method: 'evm_revert',
|
39
39
|
params: [id],
|
40
40
|
})
|
@@ -28,7 +28,7 @@ export async function setAutomine<TChain extends Chain | undefined>(
|
|
28
28
|
client: TestClient<TestClientMode, Transport, TChain>,
|
29
29
|
enabled: boolean,
|
30
30
|
) {
|
31
|
-
|
31
|
+
await client.request({
|
32
32
|
method: 'evm_setAutomine',
|
33
33
|
params: [enabled],
|
34
34
|
})
|
@@ -40,7 +40,7 @@ export async function setBalance<TChain extends Chain | undefined>(
|
|
40
40
|
client: TestClient<TestClientMode, Transport, TChain>,
|
41
41
|
{ address, value }: SetBalanceParameters,
|
42
42
|
) {
|
43
|
-
|
43
|
+
await client.request({
|
44
44
|
method: `${client.mode}_setBalance`,
|
45
45
|
params: [address, numberToHex(value)],
|
46
46
|
})
|
@@ -35,7 +35,7 @@ export async function setBlockGasLimit<TChain extends Chain | undefined>(
|
|
35
35
|
client: TestClient<TestClientMode, Transport, TChain>,
|
36
36
|
{ gasLimit }: SetBlockGasLimitParameters,
|
37
37
|
) {
|
38
|
-
|
38
|
+
await client.request({
|
39
39
|
method: 'evm_setBlockGasLimit',
|
40
40
|
params: [numberToHex(gasLimit)],
|
41
41
|
})
|
@@ -36,7 +36,7 @@ export async function setBlockTimestampInterval<
|
|
36
36
|
client: TestClient<TestClientMode, Transport, TChain>,
|
37
37
|
{ interval }: SetBlockTimestampIntervalParameters,
|
38
38
|
) {
|
39
|
-
|
39
|
+
await client.request({
|
40
40
|
method: `${client.mode}_setBlockTimestampInterval`,
|
41
41
|
params: [interval],
|
42
42
|
})
|
@@ -39,7 +39,7 @@ export async function setCode<TChain extends Chain | undefined>(
|
|
39
39
|
client: TestClient<TestClientMode, Transport, TChain>,
|
40
40
|
{ address, bytecode }: SetCodeParameters,
|
41
41
|
) {
|
42
|
-
|
42
|
+
await client.request({
|
43
43
|
method: `${client.mode}_setCode`,
|
44
44
|
params: [address, bytecode],
|
45
45
|
})
|
@@ -36,7 +36,7 @@ export async function setCoinbase<TChain extends Chain | undefined>(
|
|
36
36
|
client: TestClient<TestClientMode, Transport, TChain>,
|
37
37
|
{ address }: SetCoinbaseParameters,
|
38
38
|
) {
|
39
|
-
|
39
|
+
await client.request({
|
40
40
|
method: `${client.mode}_setCoinbase`,
|
41
41
|
params: [address],
|
42
42
|
})
|
@@ -34,7 +34,7 @@ export async function setIntervalMining<TChain extends Chain | undefined>(
|
|
34
34
|
client: TestClient<TestClientMode, Transport, TChain>,
|
35
35
|
{ interval }: SetIntervalMiningParameters,
|
36
36
|
) {
|
37
|
-
|
37
|
+
await client.request({
|
38
38
|
method: 'evm_setIntervalMining',
|
39
39
|
params: [interval],
|
40
40
|
})
|
@@ -28,7 +28,7 @@ export async function setLoggingEnabled<TChain extends Chain | undefined>(
|
|
28
28
|
client: TestClient<TestClientMode, Transport, TChain>,
|
29
29
|
enabled: boolean,
|
30
30
|
) {
|
31
|
-
|
31
|
+
await client.request({
|
32
32
|
method: `${client.mode}_setLoggingEnabled`,
|
33
33
|
params: [enabled],
|
34
34
|
})
|
@@ -39,7 +39,7 @@ export async function setMinGasPrice<TChain extends Chain | undefined>(
|
|
39
39
|
client: TestClient<TestClientMode, Transport, TChain>,
|
40
40
|
{ gasPrice }: SetMinGasPriceParameters,
|
41
41
|
) {
|
42
|
-
|
42
|
+
await client.request({
|
43
43
|
method: `${client.mode}_setMinGasPrice`,
|
44
44
|
params: [numberToHex(gasPrice)],
|
45
45
|
})
|
@@ -39,7 +39,7 @@ export async function setNextBlockBaseFeePerGas<
|
|
39
39
|
client: TestClient<TestClientMode, Transport, TChain>,
|
40
40
|
{ baseFeePerGas }: SetNextBlockBaseFeePerGasParameters,
|
41
41
|
) {
|
42
|
-
|
42
|
+
await client.request({
|
43
43
|
method: `${client.mode}_setNextBlockBaseFeePerGas`,
|
44
44
|
params: [numberToHex(baseFeePerGas)],
|
45
45
|
})
|
@@ -35,7 +35,7 @@ export async function setNextBlockTimestamp<TChain extends Chain | undefined>(
|
|
35
35
|
client: TestClient<TestClientMode, Transport, TChain>,
|
36
36
|
{ timestamp }: SetNextBlockTimestampParameters,
|
37
37
|
) {
|
38
|
-
|
38
|
+
await client.request({
|
39
39
|
method: 'evm_setNextBlockTimestamp',
|
40
40
|
params: [numberToHex(timestamp)],
|
41
41
|
})
|
@@ -40,7 +40,7 @@ export async function setNonce<TChain extends Chain | undefined>(
|
|
40
40
|
client: TestClient<TestClientMode, Transport, TChain>,
|
41
41
|
{ address, nonce }: SetNonceParameters,
|
42
42
|
) {
|
43
|
-
|
43
|
+
await client.request({
|
44
44
|
method: `${client.mode}_setNonce`,
|
45
45
|
params: [address, numberToHex(nonce)],
|
46
46
|
})
|
@@ -29,7 +29,7 @@ export async function setRpcUrl<TChain extends Chain | undefined>(
|
|
29
29
|
client: TestClient<TestClientMode, Transport, TChain>,
|
30
30
|
jsonRpcUrl: string,
|
31
31
|
) {
|
32
|
-
|
32
|
+
await client.request({
|
33
33
|
method: `${client.mode}_setRpcUrl`,
|
34
34
|
params: [jsonRpcUrl],
|
35
35
|
})
|
@@ -43,7 +43,7 @@ export async function setStorageAt<TChain extends Chain | undefined>(
|
|
43
43
|
client: TestClient<TestClientMode, Transport, TChain>,
|
44
44
|
{ address, index, value }: SetStorageAtParameters,
|
45
45
|
) {
|
46
|
-
|
46
|
+
await client.request({
|
47
47
|
method: `${client.mode}_setStorageAt`,
|
48
48
|
params: [
|
49
49
|
address,
|
@@ -38,7 +38,7 @@ export async function stopImpersonatingAccount<
|
|
38
38
|
client: TestClient<TestClientMode, Transport, TChain>,
|
39
39
|
{ address }: StopImpersonatingAccountParameters,
|
40
40
|
) {
|
41
|
-
|
41
|
+
await client.request({
|
42
42
|
method: `${client.mode}_stopImpersonatingAccount`,
|
43
43
|
params: [address],
|
44
44
|
})
|
@@ -7,6 +7,7 @@ import type {
|
|
7
7
|
ContractFunctionConfig,
|
8
8
|
GetChain,
|
9
9
|
GetValue,
|
10
|
+
Hex,
|
10
11
|
} from '../../types/index.js'
|
11
12
|
import { encodeFunctionData } from '../../utils/index.js'
|
12
13
|
import type { EncodeFunctionDataParameters } from '../../utils/index.js'
|
@@ -28,7 +29,10 @@ export type WriteContractParameters<
|
|
28
29
|
'chain' | 'to' | 'data' | 'value'
|
29
30
|
> &
|
30
31
|
GetChain<TChain, TChainOverride> &
|
31
|
-
GetValue<TAbi, TFunctionName, SendTransactionParameters<TChain>['value']>
|
32
|
+
GetValue<TAbi, TFunctionName, SendTransactionParameters<TChain>['value']> & {
|
33
|
+
/** Data to append to the end of the calldata. Useful for adding a ["domain" tag](https://opensea.notion.site/opensea/Seaport-Order-Attributions-ec2d69bf455041a5baa490941aad307f). */
|
34
|
+
dataSuffix?: Hex
|
35
|
+
}
|
32
36
|
|
33
37
|
export type WriteContractReturnType = SendTransactionReturnType
|
34
38
|
|
@@ -94,6 +98,7 @@ export async function writeContract<
|
|
94
98
|
abi,
|
95
99
|
address,
|
96
100
|
args,
|
101
|
+
dataSuffix,
|
97
102
|
functionName,
|
98
103
|
...request
|
99
104
|
}: WriteContractParameters<
|
@@ -110,7 +115,7 @@ export async function writeContract<
|
|
110
115
|
functionName,
|
111
116
|
} as unknown as EncodeFunctionDataParameters<TAbi, TFunctionName>)
|
112
117
|
const hash = await sendTransaction(client, {
|
113
|
-
data,
|
118
|
+
data: `${data}${dataSuffix ? dataSuffix.replace('0x', '') : ''}`,
|
114
119
|
to: address,
|
115
120
|
...request,
|
116
121
|
} as unknown as SendTransactionParameters<TChain, TAccount, TChainOverride>)
|
package/src/chains.ts
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
export const zeroAddress = '0x0000000000000000000000000000000000000000' as const
|
package/src/constants/index.ts
CHANGED
package/src/errors/base.ts
CHANGED
@@ -59,4 +59,14 @@ export class BaseError extends Error {
|
|
59
59
|
this.metaMessages = args.metaMessages
|
60
60
|
this.shortMessage = shortMessage
|
61
61
|
}
|
62
|
+
|
63
|
+
walk(fn?: (err: unknown) => boolean) {
|
64
|
+
return this.#walk(this, fn)
|
65
|
+
}
|
66
|
+
|
67
|
+
#walk(err: unknown, fn?: (err: unknown) => boolean): unknown {
|
68
|
+
if (fn?.(err)) return err
|
69
|
+
if ((err as Error).cause) return this.#walk((err as Error).cause, fn)
|
70
|
+
return err
|
71
|
+
}
|
62
72
|
}
|
@@ -0,0 +1,74 @@
|
|
1
|
+
import type { Address } from 'abitype'
|
2
|
+
import { BaseError } from './base.js'
|
3
|
+
import type { Hex } from '../types/index.js'
|
4
|
+
import { getUrl } from './utils.js'
|
5
|
+
|
6
|
+
export class OffchainLookupError extends BaseError {
|
7
|
+
override name = 'OffchainLookupError'
|
8
|
+
constructor({
|
9
|
+
callbackSelector,
|
10
|
+
cause,
|
11
|
+
data,
|
12
|
+
extraData,
|
13
|
+
sender,
|
14
|
+
urls,
|
15
|
+
}: {
|
16
|
+
callbackSelector: Hex
|
17
|
+
cause: BaseError
|
18
|
+
data: Hex
|
19
|
+
extraData: Hex
|
20
|
+
sender: Address
|
21
|
+
urls: readonly string[]
|
22
|
+
}) {
|
23
|
+
super(
|
24
|
+
cause.shortMessage ||
|
25
|
+
'An error occurred while fetching for an offchain result.',
|
26
|
+
{
|
27
|
+
cause,
|
28
|
+
metaMessages: [
|
29
|
+
...(cause.metaMessages || []),
|
30
|
+
cause.metaMessages?.length ? '' : [],
|
31
|
+
'Offchain Gateway Call:',
|
32
|
+
urls && [
|
33
|
+
' Gateway URL(s):',
|
34
|
+
...urls.map((url) => ` ${getUrl(url)}`),
|
35
|
+
],
|
36
|
+
` Sender: ${sender}`,
|
37
|
+
` Data: ${data}`,
|
38
|
+
` Callback selector: ${callbackSelector}`,
|
39
|
+
` Extra data: ${extraData}`,
|
40
|
+
].flat(),
|
41
|
+
},
|
42
|
+
)
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
export class OffchainLookupResponseMalformedError extends BaseError {
|
47
|
+
override name = 'OffchainLookupResponseMalformedError'
|
48
|
+
constructor({ result, url }: { result: any; url: string }) {
|
49
|
+
super(
|
50
|
+
'Offchain gateway response is malformed. Response data must be a hex value.',
|
51
|
+
{
|
52
|
+
metaMessages: [
|
53
|
+
`Gateway URL: ${getUrl(url)}`,
|
54
|
+
`Response: ${JSON.stringify(result)}`,
|
55
|
+
],
|
56
|
+
},
|
57
|
+
)
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
export class OffchainLookupSenderMismatchError extends BaseError {
|
62
|
+
override name = 'OffchainLookupSenderMismatchError'
|
63
|
+
constructor({ sender, to }: { sender: Address; to: Address }) {
|
64
|
+
super(
|
65
|
+
'Reverted sender address does not match target contract address (`to`).',
|
66
|
+
{
|
67
|
+
metaMessages: [
|
68
|
+
`Contract address: ${to}`,
|
69
|
+
`OffchainLookup sender address: ${sender}`,
|
70
|
+
],
|
71
|
+
},
|
72
|
+
)
|
73
|
+
}
|
74
|
+
}
|
package/src/errors/index.ts
CHANGED
@@ -41,6 +41,12 @@ export {
|
|
41
41
|
InvalidChainIdError,
|
42
42
|
} from './chain.js'
|
43
43
|
|
44
|
+
export {
|
45
|
+
OffchainLookupError,
|
46
|
+
OffchainLookupResponseMalformedError,
|
47
|
+
OffchainLookupSenderMismatchError,
|
48
|
+
} from './ccip.js'
|
49
|
+
|
44
50
|
export {
|
45
51
|
CallExecutionError,
|
46
52
|
ContractFunctionExecutionError,
|
package/src/errors/request.ts
CHANGED
@@ -5,7 +5,7 @@ import { getUrl } from './utils.js'
|
|
5
5
|
export class HttpRequestError extends BaseError {
|
6
6
|
override name = 'HttpRequestError'
|
7
7
|
|
8
|
-
body
|
8
|
+
body?: { [key: string]: unknown }
|
9
9
|
headers?: Headers
|
10
10
|
status?: number
|
11
11
|
url: string
|
@@ -17,7 +17,7 @@ export class HttpRequestError extends BaseError {
|
|
17
17
|
status,
|
18
18
|
url,
|
19
19
|
}: {
|
20
|
-
body
|
20
|
+
body?: { [key: string]: unknown }
|
21
21
|
details?: string
|
22
22
|
headers?: Headers
|
23
23
|
status?: number
|
@@ -28,7 +28,7 @@ export class HttpRequestError extends BaseError {
|
|
28
28
|
metaMessages: [
|
29
29
|
status && `Status: ${status}`,
|
30
30
|
`URL: ${getUrl(url)}`,
|
31
|
-
`Request body: ${stringify(body)}`,
|
31
|
+
body && `Request body: ${stringify(body)}`,
|
32
32
|
].filter(Boolean) as string[],
|
33
33
|
})
|
34
34
|
this.body = body
|
package/src/errors/version.ts
CHANGED
@@ -1 +1 @@
|
|
1
|
-
export const version = '0.3.
|
1
|
+
export const version = '0.3.14'
|
package/src/index.ts
CHANGED
@@ -159,6 +159,7 @@ export {
|
|
159
159
|
etherUnits,
|
160
160
|
gweiUnits,
|
161
161
|
weiUnits,
|
162
|
+
zeroAddress,
|
162
163
|
} from './constants/index.js'
|
163
164
|
|
164
165
|
export {
|
@@ -398,6 +399,7 @@ export {
|
|
398
399
|
bytesToHex,
|
399
400
|
bytesToNumber,
|
400
401
|
bytesToString,
|
402
|
+
ccipFetch,
|
401
403
|
concat,
|
402
404
|
concatBytes,
|
403
405
|
concatHex,
|
@@ -452,6 +454,9 @@ export {
|
|
452
454
|
keccak256,
|
453
455
|
numberToBytes,
|
454
456
|
numberToHex,
|
457
|
+
offchainLookup,
|
458
|
+
offchainLookupAbiItem,
|
459
|
+
offchainLookupSignature,
|
455
460
|
pad,
|
456
461
|
padBytes,
|
457
462
|
padHex,
|
@@ -0,0 +1,136 @@
|
|
1
|
+
import { parseAbiItem, parseAbiParameters, type Address } from 'abitype'
|
2
|
+
import type { PublicClient, Transport } from '../clients/index.js'
|
3
|
+
import {
|
4
|
+
BaseError,
|
5
|
+
HttpRequestError,
|
6
|
+
OffchainLookupError,
|
7
|
+
OffchainLookupResponseMalformedError,
|
8
|
+
OffchainLookupSenderMismatchError,
|
9
|
+
} from '../errors/index.js'
|
10
|
+
import { call, type CallParameters } from '../public.js'
|
11
|
+
import type { Chain, GetErrorArgs, Hex } from '../types/index.js'
|
12
|
+
import { decodeErrorResult, encodeAbiParameters } from './abi/index.js'
|
13
|
+
import { isAddressEqual } from './address/index.js'
|
14
|
+
import { concat, isHex } from './data/index.js'
|
15
|
+
import { stringify } from './stringify.js'
|
16
|
+
|
17
|
+
export const offchainLookupSignature = '0x556f1830'
|
18
|
+
export const offchainLookupAbiItem = parseAbiItem(
|
19
|
+
'error OffchainLookup(address sender, string[] urls, bytes callData, bytes4 callbackFunction, bytes extraData)',
|
20
|
+
)
|
21
|
+
|
22
|
+
export async function offchainLookup<TChain extends Chain | undefined>(
|
23
|
+
client: PublicClient<Transport, TChain>,
|
24
|
+
{
|
25
|
+
blockNumber,
|
26
|
+
blockTag,
|
27
|
+
data,
|
28
|
+
to,
|
29
|
+
}: Pick<CallParameters, 'blockNumber' | 'blockTag'> & {
|
30
|
+
data: Hex
|
31
|
+
to: Address
|
32
|
+
},
|
33
|
+
): Promise<Hex> {
|
34
|
+
const { args } = decodeErrorResult({
|
35
|
+
data,
|
36
|
+
abi: [offchainLookupAbiItem],
|
37
|
+
}) as unknown as GetErrorArgs<
|
38
|
+
[typeof offchainLookupAbiItem],
|
39
|
+
'OffchainLookup'
|
40
|
+
>
|
41
|
+
const [sender, urls, callData, callbackSelector, extraData] = args
|
42
|
+
|
43
|
+
try {
|
44
|
+
if (!isAddressEqual(to, sender))
|
45
|
+
throw new OffchainLookupSenderMismatchError({ sender, to })
|
46
|
+
|
47
|
+
const result = await ccipFetch({ data: callData, sender, urls })
|
48
|
+
|
49
|
+
const { data: data_ } = await call(client, {
|
50
|
+
blockNumber,
|
51
|
+
blockTag,
|
52
|
+
data: concat([
|
53
|
+
callbackSelector,
|
54
|
+
encodeAbiParameters(parseAbiParameters('bytes,bytes'), [
|
55
|
+
result,
|
56
|
+
extraData,
|
57
|
+
]),
|
58
|
+
]),
|
59
|
+
to,
|
60
|
+
} as CallParameters)
|
61
|
+
|
62
|
+
return data_!
|
63
|
+
} catch (err) {
|
64
|
+
throw new OffchainLookupError({
|
65
|
+
callbackSelector,
|
66
|
+
cause: err as BaseError,
|
67
|
+
data,
|
68
|
+
extraData,
|
69
|
+
sender,
|
70
|
+
urls,
|
71
|
+
})
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
export async function ccipFetch({
|
76
|
+
data,
|
77
|
+
sender,
|
78
|
+
urls,
|
79
|
+
}: { data: Hex; sender: Address; urls: readonly string[] }) {
|
80
|
+
let error = new Error('An unknown error occurred.')
|
81
|
+
|
82
|
+
for (let i = 0; i < urls.length; i++) {
|
83
|
+
const url = urls[i]
|
84
|
+
const method =
|
85
|
+
url.includes('{sender}') || url.includes('{data}') ? 'GET' : 'POST'
|
86
|
+
const body = method === 'POST' ? { data, sender } : undefined
|
87
|
+
|
88
|
+
try {
|
89
|
+
const response = await fetch(
|
90
|
+
url.replace('{sender}', sender).replace('{data}', data),
|
91
|
+
{
|
92
|
+
body: JSON.stringify(body),
|
93
|
+
method,
|
94
|
+
},
|
95
|
+
)
|
96
|
+
|
97
|
+
let result
|
98
|
+
if (
|
99
|
+
response.headers.get('Content-Type')?.startsWith('application/json')
|
100
|
+
) {
|
101
|
+
result = (await response.json()).data
|
102
|
+
} else {
|
103
|
+
result = (await response.text()) as any
|
104
|
+
}
|
105
|
+
|
106
|
+
if (!response.ok) {
|
107
|
+
error = new HttpRequestError({
|
108
|
+
body,
|
109
|
+
details: stringify(result.error) || response.statusText,
|
110
|
+
headers: response.headers,
|
111
|
+
status: response.status,
|
112
|
+
url,
|
113
|
+
})
|
114
|
+
continue
|
115
|
+
}
|
116
|
+
|
117
|
+
if (!isHex(result)) {
|
118
|
+
error = new OffchainLookupResponseMalformedError({
|
119
|
+
result,
|
120
|
+
url,
|
121
|
+
})
|
122
|
+
continue
|
123
|
+
}
|
124
|
+
|
125
|
+
return result
|
126
|
+
} catch (err) {
|
127
|
+
error = new HttpRequestError({
|
128
|
+
body,
|
129
|
+
details: (err as Error).message,
|
130
|
+
url,
|
131
|
+
})
|
132
|
+
}
|
133
|
+
}
|
134
|
+
|
135
|
+
throw error
|
136
|
+
}
|