viem 0.3.13 → 0.3.15

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.
Files changed (113) hide show
  1. package/dist/cjs/actions/public/call.js +12 -1
  2. package/dist/cjs/actions/public/call.js.map +1 -1
  3. package/dist/cjs/actions/public/multicall.js +1 -1
  4. package/dist/cjs/actions/public/multicall.js.map +1 -1
  5. package/dist/cjs/actions/public/simulateContract.js +2 -2
  6. package/dist/cjs/actions/public/simulateContract.js.map +1 -1
  7. package/dist/cjs/actions/wallet/writeContract.js +2 -2
  8. package/dist/cjs/actions/wallet/writeContract.js.map +1 -1
  9. package/dist/cjs/chains.js +2 -4
  10. package/dist/cjs/chains.js.map +1 -1
  11. package/dist/cjs/constants/address.js +5 -0
  12. package/dist/cjs/constants/address.js.map +1 -0
  13. package/dist/cjs/constants/index.js +3 -1
  14. package/dist/cjs/constants/index.js.map +1 -1
  15. package/dist/cjs/errors/base.js +17 -0
  16. package/dist/cjs/errors/base.js.map +1 -1
  17. package/dist/cjs/errors/ccip.js +68 -0
  18. package/dist/cjs/errors/ccip.js.map +1 -0
  19. package/dist/cjs/errors/index.js +7 -3
  20. package/dist/cjs/errors/index.js.map +1 -1
  21. package/dist/cjs/errors/request.js +1 -1
  22. package/dist/cjs/errors/request.js.map +1 -1
  23. package/dist/cjs/errors/version.js +1 -1
  24. package/dist/cjs/index.js +10 -4
  25. package/dist/cjs/index.js.map +1 -1
  26. package/dist/cjs/utils/ccip.js +118 -0
  27. package/dist/cjs/utils/ccip.js.map +1 -0
  28. package/dist/cjs/utils/errors/getContractError.js +1 -5
  29. package/dist/cjs/utils/errors/getContractError.js.map +1 -1
  30. package/dist/cjs/utils/errors/getNodeError.js +1 -1
  31. package/dist/cjs/utils/errors/getNodeError.js.map +1 -1
  32. package/dist/cjs/utils/index.js +8 -3
  33. package/dist/cjs/utils/index.js.map +1 -1
  34. package/dist/esm/actions/public/call.js +11 -1
  35. package/dist/esm/actions/public/call.js.map +1 -1
  36. package/dist/esm/actions/public/multicall.js +1 -1
  37. package/dist/esm/actions/public/multicall.js.map +1 -1
  38. package/dist/esm/actions/public/simulateContract.js +2 -2
  39. package/dist/esm/actions/public/simulateContract.js.map +1 -1
  40. package/dist/esm/actions/wallet/writeContract.js +2 -2
  41. package/dist/esm/actions/wallet/writeContract.js.map +1 -1
  42. package/dist/esm/chains.js +0 -1
  43. package/dist/esm/chains.js.map +1 -1
  44. package/dist/esm/constants/address.js +2 -0
  45. package/dist/esm/constants/address.js.map +1 -0
  46. package/dist/esm/constants/index.js +1 -0
  47. package/dist/esm/constants/index.js.map +1 -1
  48. package/dist/esm/errors/base.js +17 -0
  49. package/dist/esm/errors/base.js.map +1 -1
  50. package/dist/esm/errors/ccip.js +62 -0
  51. package/dist/esm/errors/ccip.js.map +1 -0
  52. package/dist/esm/errors/index.js +1 -0
  53. package/dist/esm/errors/index.js.map +1 -1
  54. package/dist/esm/errors/request.js +1 -1
  55. package/dist/esm/errors/request.js.map +1 -1
  56. package/dist/esm/errors/version.js +1 -1
  57. package/dist/esm/index.js +2 -2
  58. package/dist/esm/index.js.map +1 -1
  59. package/dist/esm/utils/ccip.js +113 -0
  60. package/dist/esm/utils/ccip.js.map +1 -0
  61. package/dist/esm/utils/errors/getContractError.js +3 -7
  62. package/dist/esm/utils/errors/getContractError.js.map +1 -1
  63. package/dist/esm/utils/errors/getNodeError.js +1 -1
  64. package/dist/esm/utils/errors/getNodeError.js.map +1 -1
  65. package/dist/esm/utils/index.js +1 -0
  66. package/dist/esm/utils/index.js.map +1 -1
  67. package/dist/types/actions/public/call.d.ts +1 -0
  68. package/dist/types/actions/public/call.d.ts.map +1 -1
  69. package/dist/types/actions/public/simulateContract.d.ts +4 -2
  70. package/dist/types/actions/public/simulateContract.d.ts.map +1 -1
  71. package/dist/types/actions/wallet/writeContract.d.ts +6 -3
  72. package/dist/types/actions/wallet/writeContract.d.ts.map +1 -1
  73. package/dist/types/chains.d.ts +0 -1
  74. package/dist/types/chains.d.ts.map +1 -1
  75. package/dist/types/constants/address.d.ts +2 -0
  76. package/dist/types/constants/address.d.ts.map +1 -0
  77. package/dist/types/constants/index.d.ts +1 -0
  78. package/dist/types/constants/index.d.ts.map +1 -1
  79. package/dist/types/errors/base.d.ts +2 -0
  80. package/dist/types/errors/base.d.ts.map +1 -1
  81. package/dist/types/errors/ccip.d.ts +29 -0
  82. package/dist/types/errors/ccip.d.ts.map +1 -0
  83. package/dist/types/errors/index.d.ts +1 -0
  84. package/dist/types/errors/index.d.ts.map +1 -1
  85. package/dist/types/errors/request.d.ts +2 -2
  86. package/dist/types/errors/request.d.ts.map +1 -1
  87. package/dist/types/errors/version.d.ts +1 -1
  88. package/dist/types/index.d.ts +2 -2
  89. package/dist/types/index.d.ts.map +1 -1
  90. package/dist/types/utils/ccip.d.ts +35 -0
  91. package/dist/types/utils/ccip.d.ts.map +1 -0
  92. package/dist/types/utils/errors/getContractError.d.ts.map +1 -1
  93. package/dist/types/utils/formatters/transaction.d.ts +1 -1
  94. package/dist/types/utils/index.d.ts +1 -0
  95. package/dist/types/utils/index.d.ts.map +1 -1
  96. package/package.json +1 -1
  97. package/src/actions/public/call.ts +13 -1
  98. package/src/actions/public/multicall.ts +1 -1
  99. package/src/actions/public/simulateContract.ts +5 -1
  100. package/src/actions/wallet/writeContract.ts +7 -2
  101. package/src/chains.ts +0 -1
  102. package/src/constants/address.ts +1 -0
  103. package/src/constants/index.ts +2 -0
  104. package/src/errors/base.ts +10 -0
  105. package/src/errors/ccip.ts +74 -0
  106. package/src/errors/index.ts +6 -0
  107. package/src/errors/request.ts +3 -3
  108. package/src/errors/version.ts +1 -1
  109. package/src/index.ts +5 -0
  110. package/src/utils/ccip.ts +160 -0
  111. package/src/utils/errors/getContractError.ts +1 -7
  112. package/src/utils/errors/getNodeError.ts +1 -1
  113. package/src/utils/index.ts +7 -0
@@ -4,6 +4,7 @@ export { parseAccount, publicKeyToAddress } from './accounts.js';
4
4
  export type { GetContractAddressOptions, GetCreate2AddressOptions, GetCreateAddressOptions, } from './address/index.js';
5
5
  export { getAddress, getContractAddress, getCreateAddress, getCreate2Address, isAddress, isAddressEqual, } from './address/index.js';
6
6
  export { buildRequest } from './buildRequest.js';
7
+ export { ccipFetch, offchainLookup, offchainLookupAbiItem, offchainLookupSignature, } from './ccip.js';
7
8
  export { defineChain, getChainContractAddress } from './chain.js';
8
9
  export { extractFunctionName, extractFunctionParams, extractFunctionType, extractFunctionParts, } from './contract/index.js';
9
10
  export { concat, concatBytes, concatHex, isBytes, isHex, pad, padBytes, padHex, size, slice, sliceBytes, sliceHex, trim, } from './data/index.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "isomorphic-ws": "5.0.0",
13
13
  "ws": "8.12.0"
14
14
  },
15
- "version": "0.3.13",
15
+ "version": "0.3.15",
16
16
  "files": [
17
17
  "dist",
18
18
  "!dist/**/*.tsbuildinfo",
@@ -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,
@@ -159,6 +159,13 @@ export async function call<TChain extends Chain | undefined>(
159
159
  if (response === '0x') return { data: undefined }
160
160
  return { data: response }
161
161
  } catch (err) {
162
+ const data = getRevertErrorData(err)
163
+ const { offchainLookup, offchainLookupSignature } = await import(
164
+ '../../utils/ccip.js'
165
+ )
166
+ if (data?.slice(0, 10) === offchainLookupSignature && to) {
167
+ return { data: await offchainLookup(client, { data, to }) }
168
+ }
162
169
  throw getCallError(err as BaseError, {
163
170
  ...args,
164
171
  account,
@@ -272,3 +279,8 @@ async function scheduleMulticall<TChain extends Chain | undefined>(
272
279
  if (returnData === '0x') return { data: undefined }
273
280
  return { data: returnData }
274
281
  }
282
+
283
+ export function getRevertErrorData(err: unknown) {
284
+ if (!(err instanceof BaseError)) return undefined
285
+ return (err.walk() as { data?: Hex })?.data
286
+ }
@@ -185,7 +185,7 @@ export async function multicall<
185
185
  ),
186
186
  )
187
187
 
188
- return results.flat().flatMap(({ returnData, success }, i) => {
188
+ return results.flat().map(({ returnData, success }, i) => {
189
189
  const calls = chunkedCalls.flat()
190
190
  const { callData } = calls[i]
191
191
  const { abi, address, functionName, args } = contracts[i]
@@ -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>)
@@ -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
@@ -10,7 +10,6 @@ import {
10
10
  } from './utils/index.js'
11
11
 
12
12
  export type { Chain } from './types/index.js'
13
- export { defineChain } from './utils/index.js'
14
13
 
15
14
  const celoFormatters = {
16
15
  block: defineBlock({
@@ -0,0 +1 @@
1
+ export const zeroAddress = '0x0000000000000000000000000000000000000000' as const
@@ -1,3 +1,5 @@
1
+ export { zeroAddress } from './address.js'
2
+
1
3
  export { multicall3Abi } from './abis.js'
2
4
 
3
5
  export { aggregate3Signature } from './contract.js'
@@ -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
+ }
@@ -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,
@@ -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: { [key: string]: unknown }
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: { [key: string]: unknown }
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
@@ -1 +1 @@
1
- export const version = '0.3.13'
1
+ export const version = '0.3.15'
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,160 @@
1
+ import type { Abi, 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 type { CallParameters } from '../actions/public/index.js'
11
+ import { call } from '../actions/public/call.js'
12
+ import type { Chain, GetErrorArgs, Hex } from '../types/index.js'
13
+ import { decodeErrorResult, encodeAbiParameters } from './abi/index.js'
14
+ import { isAddressEqual } from './address/index.js'
15
+ import { concat, isHex } from './data/index.js'
16
+ import { stringify } from './stringify.js'
17
+
18
+ export const offchainLookupSignature = '0x556f1830'
19
+ export const offchainLookupAbiItem = {
20
+ name: 'OffchainLookup',
21
+ type: 'error',
22
+ inputs: [
23
+ {
24
+ name: 'sender',
25
+ type: 'address',
26
+ },
27
+ {
28
+ name: 'urls',
29
+ type: 'string[]',
30
+ },
31
+ {
32
+ name: 'callData',
33
+ type: 'bytes',
34
+ },
35
+ {
36
+ name: 'callbackFunction',
37
+ type: 'bytes4',
38
+ },
39
+ {
40
+ name: 'extraData',
41
+ type: 'bytes',
42
+ },
43
+ ],
44
+ } as const satisfies Abi[number]
45
+
46
+ export async function offchainLookup<TChain extends Chain | undefined>(
47
+ client: PublicClient<Transport, TChain>,
48
+ {
49
+ blockNumber,
50
+ blockTag,
51
+ data,
52
+ to,
53
+ }: Pick<CallParameters, 'blockNumber' | 'blockTag'> & {
54
+ data: Hex
55
+ to: Address
56
+ },
57
+ ): Promise<Hex> {
58
+ const { args } = decodeErrorResult({
59
+ data,
60
+ abi: [offchainLookupAbiItem],
61
+ }) as unknown as GetErrorArgs<
62
+ [typeof offchainLookupAbiItem],
63
+ 'OffchainLookup'
64
+ >
65
+ const [sender, urls, callData, callbackSelector, extraData] = args
66
+
67
+ try {
68
+ if (!isAddressEqual(to, sender))
69
+ throw new OffchainLookupSenderMismatchError({ sender, to })
70
+
71
+ const result = await ccipFetch({ data: callData, sender, urls })
72
+
73
+ const { data: data_ } = await call(client, {
74
+ blockNumber,
75
+ blockTag,
76
+ data: concat([
77
+ callbackSelector,
78
+ encodeAbiParameters(
79
+ [{ type: 'bytes' }, { type: 'bytes' }],
80
+ [result, extraData],
81
+ ),
82
+ ]),
83
+ to,
84
+ } as CallParameters)
85
+
86
+ return data_!
87
+ } catch (err) {
88
+ throw new OffchainLookupError({
89
+ callbackSelector,
90
+ cause: err as BaseError,
91
+ data,
92
+ extraData,
93
+ sender,
94
+ urls,
95
+ })
96
+ }
97
+ }
98
+
99
+ export async function ccipFetch({
100
+ data,
101
+ sender,
102
+ urls,
103
+ }: { data: Hex; sender: Address; urls: readonly string[] }) {
104
+ let error = new Error('An unknown error occurred.')
105
+
106
+ for (let i = 0; i < urls.length; i++) {
107
+ const url = urls[i]
108
+ const method =
109
+ url.includes('{sender}') || url.includes('{data}') ? 'GET' : 'POST'
110
+ const body = method === 'POST' ? { data, sender } : undefined
111
+
112
+ try {
113
+ const response = await fetch(
114
+ url.replace('{sender}', sender).replace('{data}', data),
115
+ {
116
+ body: JSON.stringify(body),
117
+ method,
118
+ },
119
+ )
120
+
121
+ let result
122
+ if (
123
+ response.headers.get('Content-Type')?.startsWith('application/json')
124
+ ) {
125
+ result = (await response.json()).data
126
+ } else {
127
+ result = (await response.text()) as any
128
+ }
129
+
130
+ if (!response.ok) {
131
+ error = new HttpRequestError({
132
+ body,
133
+ details: stringify(result.error) || response.statusText,
134
+ headers: response.headers,
135
+ status: response.status,
136
+ url,
137
+ })
138
+ continue
139
+ }
140
+
141
+ if (!isHex(result)) {
142
+ error = new OffchainLookupResponseMalformedError({
143
+ result,
144
+ url,
145
+ })
146
+ continue
147
+ }
148
+
149
+ return result
150
+ } catch (err) {
151
+ error = new HttpRequestError({
152
+ body,
153
+ details: (err as Error).message,
154
+ url,
155
+ })
156
+ }
157
+ }
158
+
159
+ throw error
160
+ }
@@ -3,11 +3,9 @@ import type { BaseError } from '../../errors/index.js'
3
3
  import {
4
4
  AbiDecodingZeroDataError,
5
5
  ContractFunctionExecutionError,
6
- EstimateGasExecutionError,
7
6
  RawContractError,
8
7
  } from '../../errors/index.js'
9
8
  import {
10
- CallExecutionError,
11
9
  ContractFunctionRevertedError,
12
10
  ContractFunctionZeroDataError,
13
11
  } from '../../errors/contract.js'
@@ -36,11 +34,7 @@ export function getContractError(
36
34
  const { code, data, message, shortMessage } = (
37
35
  err instanceof RawContractError
38
36
  ? err
39
- : !(err.cause && 'data' in (err.cause as BaseError)) &&
40
- (err instanceof CallExecutionError ||
41
- err instanceof EstimateGasExecutionError)
42
- ? ((err.cause as BaseError)?.cause as BaseError)?.cause || {}
43
- : err.cause || {}
37
+ : err.walk((err) => 'data' in (err as Error))
44
38
  ) as RawContractError
45
39
 
46
40
  let cause = err
@@ -67,7 +67,7 @@ export function getNodeError(
67
67
  )
68
68
  return new ExecutionRevertedError({
69
69
  cause: err,
70
- message: (err.cause as BaseError).details,
70
+ message: (err.cause as BaseError).details || err.details,
71
71
  })
72
72
  return new UnknownNodeError({
73
73
  cause: (err.cause as BaseError).cause as BaseError,
@@ -60,6 +60,13 @@ export {
60
60
 
61
61
  export { buildRequest } from './buildRequest.js'
62
62
 
63
+ export {
64
+ ccipFetch,
65
+ offchainLookup,
66
+ offchainLookupAbiItem,
67
+ offchainLookupSignature,
68
+ } from './ccip.js'
69
+
63
70
  export { defineChain, getChainContractAddress } from './chain.js'
64
71
 
65
72
  export {