viem 2.56.9 → 2.57.0

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 (260) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/_cjs/actions/public/waitForTransactionReceipt.js +12 -1
  3. package/_cjs/actions/public/waitForTransactionReceipt.js.map +1 -1
  4. package/_cjs/chains/definitions/blockdag.js +23 -0
  5. package/_cjs/chains/definitions/blockdag.js.map +1 -0
  6. package/_cjs/chains/definitions/candyChain.js +29 -0
  7. package/_cjs/chains/definitions/candyChain.js.map +1 -0
  8. package/_cjs/chains/definitions/creditCoin3Devnet.js +6 -0
  9. package/_cjs/chains/definitions/creditCoin3Devnet.js.map +1 -1
  10. package/_cjs/chains/definitions/creditCoin3Mainnet.js +6 -0
  11. package/_cjs/chains/definitions/creditCoin3Mainnet.js.map +1 -1
  12. package/_cjs/chains/definitions/creditCoin3Testnet.js +6 -0
  13. package/_cjs/chains/definitions/creditCoin3Testnet.js.map +1 -1
  14. package/_cjs/chains/definitions/kortana.js +23 -0
  15. package/_cjs/chains/definitions/kortana.js.map +1 -0
  16. package/_cjs/chains/index.js +20 -14
  17. package/_cjs/chains/index.js.map +1 -1
  18. package/_cjs/clients/createClientResolver.js +45 -0
  19. package/_cjs/clients/createClientResolver.js.map +1 -0
  20. package/_cjs/errors/version.js +1 -1
  21. package/_cjs/index.js +13 -9
  22. package/_cjs/index.js.map +1 -1
  23. package/_cjs/op-stack/actions/getGame.js +1 -1
  24. package/_cjs/op-stack/actions/getGame.js.map +1 -1
  25. package/_cjs/op-stack/actions/getGames.js +1 -1
  26. package/_cjs/op-stack/actions/getGames.js.map +1 -1
  27. package/_cjs/op-stack/actions/getTimeToNextGame.js +1 -1
  28. package/_cjs/op-stack/actions/getTimeToNextGame.js.map +1 -1
  29. package/_cjs/op-stack/actions/getTimeToNextL2Output.js +1 -1
  30. package/_cjs/op-stack/actions/getTimeToNextL2Output.js.map +1 -1
  31. package/_cjs/tempo/Client.js +2 -10
  32. package/_cjs/tempo/Client.js.map +1 -1
  33. package/_cjs/tempo/ExecutionError.js +290 -0
  34. package/_cjs/tempo/ExecutionError.js.map +1 -0
  35. package/_cjs/tempo/Relay.js +88 -0
  36. package/_cjs/tempo/Relay.js.map +1 -0
  37. package/_cjs/tempo/Transaction.js.map +1 -1
  38. package/_cjs/tempo/Transport.js +21 -12
  39. package/_cjs/tempo/Transport.js.map +1 -1
  40. package/_cjs/tempo/chainConfig.js +3 -0
  41. package/_cjs/tempo/chainConfig.js.map +1 -1
  42. package/_cjs/tempo/index.js +3 -3
  43. package/_cjs/tempo/index.js.map +1 -1
  44. package/_cjs/tempo/internal/relay/cache.js +74 -0
  45. package/_cjs/tempo/internal/relay/cache.js.map +1 -0
  46. package/_cjs/tempo/internal/relay/deadline.js +35 -0
  47. package/_cjs/tempo/internal/relay/deadline.js.map +1 -0
  48. package/_cjs/tempo/internal/relay/error.js +102 -0
  49. package/_cjs/tempo/internal/relay/error.js.map +1 -0
  50. package/_cjs/tempo/internal/relay/feePayer.js +426 -0
  51. package/_cjs/tempo/internal/relay/feePayer.js.map +1 -0
  52. package/_cjs/tempo/internal/relay/feeToken.js +143 -0
  53. package/_cjs/tempo/internal/relay/feeToken.js.map +1 -0
  54. package/_cjs/tempo/{Multisig.js → internal/relay/multisig.js} +132 -122
  55. package/_cjs/tempo/internal/relay/multisig.js.map +1 -0
  56. package/_cjs/tempo/internal/relay/plugin.js +13 -0
  57. package/_cjs/tempo/internal/relay/plugin.js.map +1 -0
  58. package/_cjs/tempo/internal/relay/preflight.js +58 -0
  59. package/_cjs/tempo/internal/relay/preflight.js.map +1 -0
  60. package/_cjs/tempo/internal/relay/request.js +319 -0
  61. package/_cjs/tempo/internal/relay/request.js.map +1 -0
  62. package/_cjs/tempo/internal/relay/simulate.js +267 -0
  63. package/_cjs/tempo/internal/relay/simulate.js.map +1 -0
  64. package/_cjs/tempo/internal/relay/utils.js +174 -0
  65. package/_cjs/tempo/internal/relay/utils.js.map +1 -0
  66. package/_cjs/tempo/internal/relay/virtualAddress.js +78 -0
  67. package/_cjs/tempo/internal/relay/virtualAddress.js.map +1 -0
  68. package/_cjs/tempo/internal/relay.js +139 -0
  69. package/_cjs/tempo/internal/relay.js.map +1 -0
  70. package/_cjs/tempo/multisig/Config.js +0 -2
  71. package/_cjs/tempo/multisig/Config.js.map +1 -1
  72. package/_cjs/tempo/multisig/Operation.js +1 -2
  73. package/_cjs/tempo/multisig/Operation.js.map +1 -1
  74. package/_cjs/utils/siwe/parseSiweMessage.js +3 -3
  75. package/_cjs/utils/siwe/parseSiweMessage.js.map +1 -1
  76. package/_esm/actions/public/waitForTransactionReceipt.js +15 -1
  77. package/_esm/actions/public/waitForTransactionReceipt.js.map +1 -1
  78. package/_esm/chains/definitions/blockdag.js +20 -0
  79. package/_esm/chains/definitions/blockdag.js.map +1 -0
  80. package/_esm/chains/definitions/candyChain.js +26 -0
  81. package/_esm/chains/definitions/candyChain.js.map +1 -0
  82. package/_esm/chains/definitions/creditCoin3Devnet.js +6 -0
  83. package/_esm/chains/definitions/creditCoin3Devnet.js.map +1 -1
  84. package/_esm/chains/definitions/creditCoin3Mainnet.js +6 -0
  85. package/_esm/chains/definitions/creditCoin3Mainnet.js.map +1 -1
  86. package/_esm/chains/definitions/creditCoin3Testnet.js +6 -0
  87. package/_esm/chains/definitions/creditCoin3Testnet.js.map +1 -1
  88. package/_esm/chains/definitions/kortana.js +20 -0
  89. package/_esm/chains/definitions/kortana.js.map +1 -0
  90. package/_esm/chains/index.js +3 -0
  91. package/_esm/chains/index.js.map +1 -1
  92. package/_esm/clients/createClientResolver.js +64 -0
  93. package/_esm/clients/createClientResolver.js.map +1 -0
  94. package/_esm/errors/version.js +1 -1
  95. package/_esm/index.js +2 -0
  96. package/_esm/index.js.map +1 -1
  97. package/_esm/op-stack/actions/getGame.js +1 -1
  98. package/_esm/op-stack/actions/getGame.js.map +1 -1
  99. package/_esm/op-stack/actions/getGames.js +1 -1
  100. package/_esm/op-stack/actions/getGames.js.map +1 -1
  101. package/_esm/op-stack/actions/getTimeToNextGame.js +2 -2
  102. package/_esm/op-stack/actions/getTimeToNextGame.js.map +1 -1
  103. package/_esm/op-stack/actions/getTimeToNextL2Output.js +2 -2
  104. package/_esm/op-stack/actions/getTimeToNextL2Output.js.map +1 -1
  105. package/_esm/tempo/Client.js +8 -14
  106. package/_esm/tempo/Client.js.map +1 -1
  107. package/_esm/tempo/ExecutionError.js +306 -0
  108. package/_esm/tempo/ExecutionError.js.map +1 -0
  109. package/_esm/tempo/Relay.js +170 -0
  110. package/_esm/tempo/Relay.js.map +1 -0
  111. package/_esm/tempo/Transaction.js.map +1 -1
  112. package/_esm/tempo/Transport.js +21 -46
  113. package/_esm/tempo/Transport.js.map +1 -1
  114. package/_esm/tempo/chainConfig.js +4 -0
  115. package/_esm/tempo/chainConfig.js.map +1 -1
  116. package/_esm/tempo/index.js +8 -3
  117. package/_esm/tempo/index.js.map +1 -1
  118. package/_esm/tempo/internal/relay/cache.js +72 -0
  119. package/_esm/tempo/internal/relay/cache.js.map +1 -0
  120. package/_esm/tempo/internal/relay/deadline.js +34 -0
  121. package/_esm/tempo/internal/relay/deadline.js.map +1 -0
  122. package/_esm/tempo/internal/relay/error.js +101 -0
  123. package/_esm/tempo/internal/relay/error.js.map +1 -0
  124. package/_esm/tempo/internal/relay/feePayer.js +442 -0
  125. package/_esm/tempo/internal/relay/feePayer.js.map +1 -0
  126. package/_esm/tempo/internal/relay/feeToken.js +143 -0
  127. package/_esm/tempo/internal/relay/feeToken.js.map +1 -0
  128. package/_esm/tempo/{Multisig.js → internal/relay/multisig.js} +133 -129
  129. package/_esm/tempo/internal/relay/multisig.js.map +1 -0
  130. package/_esm/tempo/internal/relay/plugin.js +10 -0
  131. package/_esm/tempo/internal/relay/plugin.js.map +1 -0
  132. package/_esm/tempo/internal/relay/preflight.js +57 -0
  133. package/_esm/tempo/internal/relay/preflight.js.map +1 -0
  134. package/_esm/tempo/internal/relay/request.js +321 -0
  135. package/_esm/tempo/internal/relay/request.js.map +1 -0
  136. package/_esm/tempo/internal/relay/simulate.js +277 -0
  137. package/_esm/tempo/internal/relay/simulate.js.map +1 -0
  138. package/_esm/tempo/internal/relay/utils.js +174 -0
  139. package/_esm/tempo/internal/relay/utils.js.map +1 -0
  140. package/_esm/tempo/internal/relay/virtualAddress.js +73 -0
  141. package/_esm/tempo/internal/relay/virtualAddress.js.map +1 -0
  142. package/_esm/tempo/internal/relay.js +138 -0
  143. package/_esm/tempo/internal/relay.js.map +1 -0
  144. package/_esm/tempo/multisig/Config.js +2 -1
  145. package/_esm/tempo/multisig/Config.js.map +1 -1
  146. package/_esm/tempo/multisig/Operation.js +1 -1
  147. package/_esm/tempo/multisig/Operation.js.map +1 -1
  148. package/_esm/utils/siwe/parseSiweMessage.js +3 -3
  149. package/_esm/utils/siwe/parseSiweMessage.js.map +1 -1
  150. package/_types/actions/public/waitForTransactionReceipt.d.ts.map +1 -1
  151. package/_types/chains/definitions/blockdag.d.ts +51 -0
  152. package/_types/chains/definitions/blockdag.d.ts.map +1 -0
  153. package/_types/chains/definitions/candyChain.d.ts +48 -0
  154. package/_types/chains/definitions/candyChain.d.ts.map +1 -0
  155. package/_types/chains/definitions/creditCoin3Devnet.d.ts +6 -9
  156. package/_types/chains/definitions/creditCoin3Devnet.d.ts.map +1 -1
  157. package/_types/chains/definitions/creditCoin3Mainnet.d.ts +6 -9
  158. package/_types/chains/definitions/creditCoin3Mainnet.d.ts.map +1 -1
  159. package/_types/chains/definitions/creditCoin3Testnet.d.ts +6 -9
  160. package/_types/chains/definitions/creditCoin3Testnet.d.ts.map +1 -1
  161. package/_types/chains/definitions/kortana.d.ts +51 -0
  162. package/_types/chains/definitions/kortana.d.ts.map +1 -0
  163. package/_types/chains/index.d.ts +3 -0
  164. package/_types/chains/index.d.ts.map +1 -1
  165. package/_types/clients/createClientResolver.d.ts +76 -0
  166. package/_types/clients/createClientResolver.d.ts.map +1 -0
  167. package/_types/errors/version.d.ts +1 -1
  168. package/_types/index.d.ts +2 -0
  169. package/_types/index.d.ts.map +1 -1
  170. package/_types/op-stack/actions/getGame.d.ts.map +1 -1
  171. package/_types/tempo/Capabilities.d.ts +7 -28
  172. package/_types/tempo/Capabilities.d.ts.map +1 -1
  173. package/_types/tempo/Client.d.ts +6 -15
  174. package/_types/tempo/Client.d.ts.map +1 -1
  175. package/_types/tempo/ExecutionError.d.ts +79 -0
  176. package/_types/tempo/ExecutionError.d.ts.map +1 -0
  177. package/_types/tempo/Relay.d.ts +302 -0
  178. package/_types/tempo/Relay.d.ts.map +1 -0
  179. package/_types/tempo/Transaction.d.ts +2 -1
  180. package/_types/tempo/Transaction.d.ts.map +1 -1
  181. package/_types/tempo/Transport.d.ts +15 -29
  182. package/_types/tempo/Transport.d.ts.map +1 -1
  183. package/_types/tempo/chainConfig.d.ts.map +1 -1
  184. package/_types/tempo/index.d.ts +8 -3
  185. package/_types/tempo/index.d.ts.map +1 -1
  186. package/_types/tempo/internal/relay/cache.d.ts +9 -0
  187. package/_types/tempo/internal/relay/cache.d.ts.map +1 -0
  188. package/_types/tempo/internal/relay/deadline.d.ts +4 -0
  189. package/_types/tempo/internal/relay/deadline.d.ts.map +1 -0
  190. package/_types/tempo/internal/relay/error.d.ts +47 -0
  191. package/_types/tempo/internal/relay/error.d.ts.map +1 -0
  192. package/_types/tempo/internal/relay/feePayer.d.ts +70 -0
  193. package/_types/tempo/internal/relay/feePayer.d.ts.map +1 -0
  194. package/_types/tempo/internal/relay/feeToken.d.ts +38 -0
  195. package/_types/tempo/internal/relay/feeToken.d.ts.map +1 -0
  196. package/_types/tempo/internal/relay/multisig.d.ts +4 -0
  197. package/_types/tempo/internal/relay/multisig.d.ts.map +1 -0
  198. package/_types/tempo/internal/relay/plugin.d.ts +5 -0
  199. package/_types/tempo/internal/relay/plugin.d.ts.map +1 -0
  200. package/_types/tempo/internal/relay/preflight.d.ts +17 -0
  201. package/_types/tempo/internal/relay/preflight.d.ts.map +1 -0
  202. package/_types/tempo/internal/relay/request.d.ts +16 -0
  203. package/_types/tempo/internal/relay/request.d.ts.map +1 -0
  204. package/_types/tempo/internal/relay/simulate.d.ts +59 -0
  205. package/_types/tempo/internal/relay/simulate.d.ts.map +1 -0
  206. package/_types/tempo/internal/relay/utils.d.ts +294 -0
  207. package/_types/tempo/internal/relay/utils.d.ts.map +1 -0
  208. package/_types/tempo/internal/relay/virtualAddress.d.ts +9 -0
  209. package/_types/tempo/internal/relay/virtualAddress.d.ts.map +1 -0
  210. package/_types/tempo/internal/relay.d.ts +4 -0
  211. package/_types/tempo/internal/relay.d.ts.map +1 -0
  212. package/_types/tempo/multisig/Config.d.ts +0 -13
  213. package/_types/tempo/multisig/Config.d.ts.map +1 -1
  214. package/_types/tempo/multisig/Operation.d.ts +0 -5
  215. package/_types/tempo/multisig/Operation.d.ts.map +1 -1
  216. package/_types/utils/siwe/parseSiweMessage.d.ts.map +1 -1
  217. package/actions/public/waitForTransactionReceipt.ts +16 -2
  218. package/chains/definitions/blockdag.ts +20 -0
  219. package/chains/definitions/candyChain.ts +26 -0
  220. package/chains/definitions/creditCoin3Devnet.ts +6 -0
  221. package/chains/definitions/creditCoin3Mainnet.ts +6 -0
  222. package/chains/definitions/creditCoin3Testnet.ts +6 -0
  223. package/chains/definitions/kortana.ts +20 -0
  224. package/chains/index.ts +3 -0
  225. package/clients/createClientResolver.ts +191 -0
  226. package/errors/version.ts +1 -1
  227. package/index.ts +6 -0
  228. package/op-stack/actions/getGame.ts +3 -1
  229. package/op-stack/actions/getGames.ts +1 -1
  230. package/op-stack/actions/getTimeToNextGame.ts +2 -2
  231. package/op-stack/actions/getTimeToNextL2Output.ts +2 -2
  232. package/package.json +1 -1
  233. package/tempo/Capabilities.ts +7 -29
  234. package/tempo/Client.ts +8 -38
  235. package/tempo/ExecutionError.ts +418 -0
  236. package/tempo/Relay.ts +428 -0
  237. package/tempo/Transaction.ts +2 -1
  238. package/tempo/Transport.ts +69 -60
  239. package/tempo/chainConfig.ts +4 -0
  240. package/tempo/index.ts +7 -3
  241. package/tempo/internal/relay/cache.ts +82 -0
  242. package/tempo/internal/relay/deadline.ts +45 -0
  243. package/tempo/internal/relay/error.ts +128 -0
  244. package/tempo/internal/relay/feePayer.ts +692 -0
  245. package/tempo/internal/relay/feeToken.ts +190 -0
  246. package/tempo/{Multisig.ts → internal/relay/multisig.ts} +162 -193
  247. package/tempo/internal/relay/plugin.ts +13 -0
  248. package/tempo/internal/relay/preflight.ts +81 -0
  249. package/tempo/internal/relay/request.ts +391 -0
  250. package/tempo/internal/relay/simulate.ts +367 -0
  251. package/tempo/internal/relay/utils.ts +202 -0
  252. package/tempo/internal/relay/virtualAddress.ts +95 -0
  253. package/tempo/internal/relay.ts +158 -0
  254. package/tempo/multisig/Config.ts +3 -2
  255. package/tempo/multisig/Operation.ts +1 -1
  256. package/utils/siwe/parseSiweMessage.ts +21 -13
  257. package/_cjs/tempo/Multisig.js.map +0 -1
  258. package/_esm/tempo/Multisig.js.map +0 -1
  259. package/_types/tempo/Multisig.d.ts +0 -37
  260. package/_types/tempo/Multisig.d.ts.map +0 -1
@@ -0,0 +1,82 @@
1
+ import { withTimeout } from '../../../utils/promise/withTimeout.js'
2
+ import type * as Store_ from '../../Store.js'
3
+
4
+ export type Store = Store_.Store
5
+
6
+ // Scope in-flight work to one request so Workers never share request-owned I/O.
7
+ const flights = new WeakMap<Store, Map<string, Promise<unknown>>>()
8
+ const prefix = 'viem:relay:cache:'
9
+
10
+ export function scoped(store: Store | undefined): Store | undefined {
11
+ if (!store) return undefined
12
+ return {
13
+ getItem: (key) => store.getItem(key),
14
+ setItem: (key, value) => store.setItem(key, value),
15
+ removeItem: (key) => store.removeItem(key),
16
+ }
17
+ }
18
+
19
+ export async function memoize<value>(
20
+ fetch: () => Promise<value>,
21
+ options: { key: string; store: Store; ttl: number },
22
+ ): Promise<value> {
23
+ const { store, ttl } = options
24
+ const key = `${prefix}${options.key}`
25
+ let active = true
26
+ const timeoutError = new Error('Relay cache operation timed out.')
27
+ return withTimeout(
28
+ async () => {
29
+ const raw = await store.getItem(key)
30
+ if (!active) throw timeoutError
31
+ if (raw) {
32
+ try {
33
+ const entry = JSON.parse(raw, (_key, item) => {
34
+ if (typeof item !== 'string' || !item.startsWith(prefix))
35
+ return item
36
+ if (item.startsWith(`${prefix}string:`))
37
+ return item.slice(`${prefix}string:`.length)
38
+ if (item.startsWith(`${prefix}bigint:`))
39
+ return BigInt(item.slice(`${prefix}bigint:`.length))
40
+ throw new TypeError('Invalid relay cache value.')
41
+ }) as { value: value; expiresAt: number }
42
+ if (entry.expiresAt > Date.now()) return entry.value
43
+ } catch {
44
+ // Refresh malformed or older entries.
45
+ }
46
+ }
47
+ let pending = flights.get(store)
48
+ if (!pending) {
49
+ pending = new Map()
50
+ flights.set(store, pending)
51
+ }
52
+ const existing = pending.get(key)
53
+ if (existing) return existing as Promise<value>
54
+ const result = (async () => {
55
+ const value = await fetch()
56
+ if (!active) throw timeoutError
57
+ if (value !== undefined)
58
+ await store.setItem(
59
+ key,
60
+ JSON.stringify(
61
+ { value, expiresAt: Date.now() + ttl },
62
+ (_key, item) => {
63
+ if (typeof item === 'bigint') return `${prefix}bigint:${item}`
64
+ if (typeof item === 'string' && item.startsWith(prefix))
65
+ return `${prefix}string:${item}`
66
+ return item
67
+ },
68
+ ),
69
+ )
70
+ return value
71
+ })().finally(() => pending.delete(key))
72
+ pending.set(key, result)
73
+ return result
74
+ },
75
+ {
76
+ timeout: 30_000,
77
+ errorInstance: timeoutError,
78
+ },
79
+ ).finally(() => {
80
+ active = false
81
+ })
82
+ }
@@ -0,0 +1,45 @@
1
+ import { RpcResponse } from 'ox'
2
+ import type * as Relay from '../../Relay.js'
3
+
4
+ /** Bounds the complete fill, including callbacks that do not observe abort signals. */
5
+ export async function run(
6
+ handler: Relay.handleRequest.Handler,
7
+ request: Relay.handleRequest.Request,
8
+ options: Relay.handleRequest.RequestOptions,
9
+ config: Relay.handleRequest.Options,
10
+ ) {
11
+ const controller = new AbortController()
12
+ const abort = () => controller.abort(options.signal?.reason)
13
+ options.signal?.addEventListener('abort', abort, { once: true })
14
+ if (options.signal?.aborted) abort()
15
+ const timeout = setTimeout(
16
+ () =>
17
+ controller.abort(
18
+ new RpcResponse.LimitExceededError({
19
+ message: 'Relay fill exceeded its deadline.',
20
+ }),
21
+ ),
22
+ config.timeout ?? 10_000,
23
+ )
24
+ const signal = controller.signal
25
+
26
+ let rejectAbort!: (reason: unknown) => void
27
+ const aborted = new Promise<never>((_, reject) => {
28
+ rejectAbort = reject
29
+ })
30
+ const onAbort = () => rejectAbort(signal.reason)
31
+ signal.addEventListener('abort', onAbort, { once: true })
32
+ try {
33
+ signal.throwIfAborted()
34
+ return await Promise.race([
35
+ handler(request, { ...options, signal }),
36
+ aborted,
37
+ ])
38
+ } finally {
39
+ clearTimeout(timeout)
40
+ options.signal?.removeEventListener('abort', abort)
41
+ signal.removeEventListener('abort', onAbort)
42
+ // Prevent timed-out hooks from dispatching additional I/O after the response completes.
43
+ controller.abort()
44
+ }
45
+ }
@@ -0,0 +1,128 @@
1
+ import type { Address } from 'abitype'
2
+ import { Hex } from 'ox'
3
+ import type { Client } from '../../../clients/createClient.js'
4
+ import { zeroAddress } from '../../../constants/address.js'
5
+ import { formatUnits } from '../../../utils/unit/formatUnits.js'
6
+ import * as ExecutionError from '../../ExecutionError.js'
7
+ import type * as Store from './cache.js'
8
+ import { resolveTokenMetadata } from './feeToken.js'
9
+ import { simulateAndParseDiffs } from './simulate.js'
10
+ import * as Utils from './utils.js'
11
+ import { extractCalls, resolveVirtualAddresses } from './virtualAddress.js'
12
+
13
+ /** Distinguishes execution reverts from transport and plugin failures. */
14
+ export function isExecutionError(error: unknown): error is Error {
15
+ if (!(error instanceof Error)) return false
16
+
17
+ const seen = new Set<unknown>()
18
+ const pending: unknown[] = [error]
19
+ while (pending.length) {
20
+ const current = pending.pop()
21
+ if (!current || typeof current !== 'object' || seen.has(current)) continue
22
+ seen.add(current)
23
+
24
+ const candidate = current as Record<string, unknown>
25
+ if (
26
+ candidate.code === 3 ||
27
+ candidate.name === 'UpstreamRevertError' ||
28
+ candidate.name === 'ExecutionRevertedError' ||
29
+ candidate.name === 'ContractFunctionRevertedError' ||
30
+ [candidate.message, candidate.details].some(
31
+ (message) =>
32
+ typeof message === 'string' && /^execution reverted\b/i.test(message),
33
+ )
34
+ )
35
+ return true
36
+
37
+ pending.push(candidate.cause, candidate.error)
38
+ }
39
+ return false
40
+ }
41
+
42
+ export async function formatError(
43
+ error: Error,
44
+ parameters: Record<string, unknown>,
45
+ client: Client,
46
+ simulateStore?: Store.Store,
47
+ ) {
48
+ const revert = ExecutionError.from(error)
49
+
50
+ const stub = {
51
+ from: parameters.from,
52
+ to: parameters.to ?? null,
53
+ gas: '0x0',
54
+ nonce: '0x0',
55
+ value: '0x0',
56
+ maxFeePerGas: '0x0',
57
+ maxPriorityFeePerGas: '0x0',
58
+ }
59
+
60
+ if (revert.errorName === 'InsufficientBalance' && revert.args?.length === 3) {
61
+ const [available, required, token] = revert.args
62
+
63
+ const normalized = Utils.normalizeFillTransactionRequest(parameters)
64
+
65
+ // Simulate from zero address for optimistic balance diffs.
66
+ const optimisticCalls = normalized ? extractCalls(normalized) : undefined
67
+ const [{ balanceDiffs, tokenMetadata }, virtualAddresses] = optimisticCalls
68
+ ? await Promise.all([
69
+ simulateAndParseDiffs(client, {
70
+ account: zeroAddress,
71
+ calls: optimisticCalls,
72
+ store: simulateStore,
73
+ }),
74
+ resolveVirtualAddresses(client, { calls: optimisticCalls }).catch(
75
+ () => undefined,
76
+ ),
77
+ ])
78
+ : [{ balanceDiffs: undefined, tokenMetadata: undefined }, undefined]
79
+
80
+ // Re-key balance diffs from zero address to the real sender.
81
+ const senderDiffs =
82
+ parameters.from && balanceDiffs
83
+ ? { [parameters.from as Address]: balanceDiffs[zeroAddress] ?? [] }
84
+ : balanceDiffs
85
+
86
+ const metadata = await resolveTokenMetadata(client, {
87
+ token,
88
+ tokenMetadata,
89
+ store: simulateStore,
90
+ }).catch(() => undefined)
91
+ const deficit = required - available
92
+
93
+ return {
94
+ tx: stub,
95
+ capabilities: {
96
+ balanceDiffs: senderDiffs,
97
+ error: ExecutionError.serialize(revert),
98
+ insufficientFunds: metadata
99
+ ? {
100
+ amount: Hex.fromNumber(deficit) as `0x${string}`,
101
+ decimals: metadata.decimals,
102
+ formatted: formatUnits(deficit, metadata.decimals),
103
+ token,
104
+ symbol: metadata.symbol,
105
+ }
106
+ : undefined,
107
+ sponsored: false,
108
+ ...(virtualAddresses ? { virtualAddresses } : {}),
109
+ },
110
+ }
111
+ }
112
+
113
+ const normalized = Utils.normalizeFillTransactionRequest(parameters)
114
+ const virtualAddresses = normalized
115
+ ? await resolveVirtualAddresses(client, {
116
+ calls: extractCalls(normalized),
117
+ }).catch(() => undefined)
118
+ : undefined
119
+
120
+ return {
121
+ tx: stub,
122
+ capabilities: {
123
+ error: ExecutionError.serialize(revert),
124
+ sponsored: false,
125
+ ...(virtualAddresses ? { virtualAddresses } : {}),
126
+ },
127
+ }
128
+ }