viem 2.8.18 → 2.9.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 (226) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/_cjs/chains/definitions/optimismSepolia.js +5 -0
  3. package/_cjs/chains/definitions/optimismSepolia.js.map +1 -1
  4. package/_cjs/chains/opStack/abis.js +1070 -1
  5. package/_cjs/chains/opStack/abis.js.map +1 -1
  6. package/_cjs/chains/opStack/actions/buildProveWithdrawal.js +3 -3
  7. package/_cjs/chains/opStack/actions/buildProveWithdrawal.js.map +1 -1
  8. package/_cjs/chains/opStack/actions/getGame.js +20 -0
  9. package/_cjs/chains/opStack/actions/getGame.js.map +1 -0
  10. package/_cjs/chains/opStack/actions/getGames.js +56 -0
  11. package/_cjs/chains/opStack/actions/getGames.js.map +1 -0
  12. package/_cjs/chains/opStack/actions/getL2Output.js +12 -0
  13. package/_cjs/chains/opStack/actions/getL2Output.js.map +1 -1
  14. package/_cjs/chains/opStack/actions/getPortalVersion.js +25 -0
  15. package/_cjs/chains/opStack/actions/getPortalVersion.js.map +1 -0
  16. package/_cjs/chains/opStack/actions/getTimeToFinalize.js +52 -26
  17. package/_cjs/chains/opStack/actions/getTimeToFinalize.js.map +1 -1
  18. package/_cjs/chains/opStack/actions/getTimeToNextGame.js +45 -0
  19. package/_cjs/chains/opStack/actions/getTimeToNextGame.js.map +1 -0
  20. package/_cjs/chains/opStack/actions/getTimeToProve.js +9 -1
  21. package/_cjs/chains/opStack/actions/getTimeToProve.js.map +1 -1
  22. package/_cjs/chains/opStack/actions/getWithdrawalStatus.js +79 -28
  23. package/_cjs/chains/opStack/actions/getWithdrawalStatus.js.map +1 -1
  24. package/_cjs/chains/opStack/actions/proveWithdrawal.js +1 -1
  25. package/_cjs/chains/opStack/actions/proveWithdrawal.js.map +1 -1
  26. package/_cjs/chains/opStack/actions/waitForNextGame.js +35 -0
  27. package/_cjs/chains/opStack/actions/waitForNextGame.js.map +1 -0
  28. package/_cjs/chains/opStack/actions/waitForNextL2Output.js.map +1 -1
  29. package/_cjs/chains/opStack/actions/waitToProve.js +34 -3
  30. package/_cjs/chains/opStack/actions/waitToProve.js.map +1 -1
  31. package/_cjs/chains/opStack/decorators/publicL1.js +10 -0
  32. package/_cjs/chains/opStack/decorators/publicL1.js.map +1 -1
  33. package/_cjs/chains/opStack/errors/withdrawal.js +13 -1
  34. package/_cjs/chains/opStack/errors/withdrawal.js.map +1 -1
  35. package/_cjs/chains/opStack/index.js +11 -1
  36. package/_cjs/chains/opStack/index.js.map +1 -1
  37. package/_cjs/chains/zksync/actions/deployContract.js +26 -0
  38. package/_cjs/chains/zksync/actions/deployContract.js.map +1 -0
  39. package/_cjs/chains/zksync/constants/abis.js +427 -0
  40. package/_cjs/chains/zksync/constants/abis.js.map +1 -0
  41. package/_cjs/chains/zksync/constants/address.js +5 -0
  42. package/_cjs/chains/zksync/constants/address.js.map +1 -0
  43. package/_cjs/chains/zksync/constants/contract.js +6 -0
  44. package/_cjs/chains/zksync/constants/contract.js.map +1 -0
  45. package/_cjs/chains/zksync/constants/number.js +6 -0
  46. package/_cjs/chains/zksync/constants/number.js.map +1 -0
  47. package/_cjs/chains/zksync/decorators/eip712.js +2 -0
  48. package/_cjs/chains/zksync/decorators/eip712.js.map +1 -1
  49. package/_cjs/chains/zksync/errors/bytecode.js +41 -0
  50. package/_cjs/chains/zksync/errors/bytecode.js.map +1 -0
  51. package/_cjs/chains/zksync/formatters.js +5 -1
  52. package/_cjs/chains/zksync/formatters.js.map +1 -1
  53. package/_cjs/chains/zksync/index.js +3 -1
  54. package/_cjs/chains/zksync/index.js.map +1 -1
  55. package/_cjs/chains/zksync/types/contract.js +3 -0
  56. package/_cjs/chains/zksync/types/contract.js.map +1 -0
  57. package/_cjs/chains/zksync/utils/abi/encodeDeployData.js +68 -0
  58. package/_cjs/chains/zksync/utils/abi/encodeDeployData.js.map +1 -0
  59. package/_cjs/chains/zksync/utils/getEip712Domain.js +4 -2
  60. package/_cjs/chains/zksync/utils/getEip712Domain.js.map +1 -1
  61. package/_cjs/chains/zksync/utils/hashBytecode.js +36 -0
  62. package/_cjs/chains/zksync/utils/hashBytecode.js.map +1 -0
  63. package/_cjs/errors/version.js +1 -1
  64. package/_cjs/errors/version.js.map +1 -1
  65. package/_esm/chains/definitions/optimismSepolia.js +5 -0
  66. package/_esm/chains/definitions/optimismSepolia.js.map +1 -1
  67. package/_esm/chains/opStack/abis.js +1069 -0
  68. package/_esm/chains/opStack/abis.js.map +1 -1
  69. package/_esm/chains/opStack/actions/buildProveWithdrawal.js +4 -3
  70. package/_esm/chains/opStack/actions/buildProveWithdrawal.js.map +1 -1
  71. package/_esm/chains/opStack/actions/getGame.js +40 -0
  72. package/_esm/chains/opStack/actions/getGame.js.map +1 -0
  73. package/_esm/chains/opStack/actions/getGames.js +75 -0
  74. package/_esm/chains/opStack/actions/getGames.js.map +1 -0
  75. package/_esm/chains/opStack/actions/getL2Output.js +12 -0
  76. package/_esm/chains/opStack/actions/getL2Output.js.map +1 -1
  77. package/_esm/chains/opStack/actions/getPortalVersion.js +48 -0
  78. package/_esm/chains/opStack/actions/getPortalVersion.js.map +1 -0
  79. package/_esm/chains/opStack/actions/getTimeToFinalize.js +54 -27
  80. package/_esm/chains/opStack/actions/getTimeToFinalize.js.map +1 -1
  81. package/_esm/chains/opStack/actions/getTimeToNextGame.js +71 -0
  82. package/_esm/chains/opStack/actions/getTimeToNextGame.js.map +1 -0
  83. package/_esm/chains/opStack/actions/getTimeToProve.js +10 -1
  84. package/_esm/chains/opStack/actions/getTimeToProve.js.map +1 -1
  85. package/_esm/chains/opStack/actions/getWithdrawalStatus.js +84 -32
  86. package/_esm/chains/opStack/actions/getWithdrawalStatus.js.map +1 -1
  87. package/_esm/chains/opStack/actions/proveWithdrawal.js +1 -1
  88. package/_esm/chains/opStack/actions/proveWithdrawal.js.map +1 -1
  89. package/_esm/chains/opStack/actions/waitForNextGame.js +61 -0
  90. package/_esm/chains/opStack/actions/waitForNextGame.js.map +1 -0
  91. package/_esm/chains/opStack/actions/waitForNextL2Output.js.map +1 -1
  92. package/_esm/chains/opStack/actions/waitToProve.js +35 -3
  93. package/_esm/chains/opStack/actions/waitToProve.js.map +1 -1
  94. package/_esm/chains/opStack/decorators/publicL1.js +10 -0
  95. package/_esm/chains/opStack/decorators/publicL1.js.map +1 -1
  96. package/_esm/chains/opStack/errors/withdrawal.js +11 -0
  97. package/_esm/chains/opStack/errors/withdrawal.js.map +1 -1
  98. package/_esm/chains/opStack/index.js +5 -0
  99. package/_esm/chains/opStack/index.js.map +1 -1
  100. package/_esm/chains/zksync/actions/deployContract.js +52 -0
  101. package/_esm/chains/zksync/actions/deployContract.js.map +1 -0
  102. package/_esm/chains/zksync/constants/abis.js +425 -0
  103. package/_esm/chains/zksync/constants/abis.js.map +1 -0
  104. package/_esm/chains/zksync/constants/address.js +2 -0
  105. package/_esm/chains/zksync/constants/address.js.map +1 -0
  106. package/_esm/chains/zksync/constants/contract.js +3 -0
  107. package/_esm/chains/zksync/constants/contract.js.map +1 -0
  108. package/_esm/chains/zksync/constants/number.js +3 -0
  109. package/_esm/chains/zksync/constants/number.js.map +1 -0
  110. package/_esm/chains/zksync/decorators/eip712.js +2 -0
  111. package/_esm/chains/zksync/decorators/eip712.js.map +1 -1
  112. package/_esm/chains/zksync/errors/bytecode.js +35 -0
  113. package/_esm/chains/zksync/errors/bytecode.js.map +1 -0
  114. package/_esm/chains/zksync/formatters.js +5 -1
  115. package/_esm/chains/zksync/formatters.js.map +1 -1
  116. package/_esm/chains/zksync/index.js +1 -0
  117. package/_esm/chains/zksync/index.js.map +1 -1
  118. package/_esm/chains/zksync/types/contract.js +2 -0
  119. package/_esm/chains/zksync/types/contract.js.map +1 -0
  120. package/_esm/chains/zksync/utils/abi/encodeDeployData.js +65 -0
  121. package/_esm/chains/zksync/utils/abi/encodeDeployData.js.map +1 -0
  122. package/_esm/chains/zksync/utils/getEip712Domain.js +4 -2
  123. package/_esm/chains/zksync/utils/getEip712Domain.js.map +1 -1
  124. package/_esm/chains/zksync/utils/hashBytecode.js +36 -0
  125. package/_esm/chains/zksync/utils/hashBytecode.js.map +1 -0
  126. package/_esm/errors/version.js +1 -1
  127. package/_esm/errors/version.js.map +1 -1
  128. package/_types/chains/definitions/optimismSepolia.d.ts +5 -0
  129. package/_types/chains/definitions/optimismSepolia.d.ts.map +1 -1
  130. package/_types/chains/opStack/abis.d.ts +824 -0
  131. package/_types/chains/opStack/abis.d.ts.map +1 -1
  132. package/_types/chains/opStack/actions/buildProveWithdrawal.d.ts +6 -2
  133. package/_types/chains/opStack/actions/buildProveWithdrawal.d.ts.map +1 -1
  134. package/_types/chains/opStack/actions/getGame.d.ts +57 -0
  135. package/_types/chains/opStack/actions/getGame.d.ts.map +1 -0
  136. package/_types/chains/opStack/actions/getGames.d.ts +48 -0
  137. package/_types/chains/opStack/actions/getGames.d.ts.map +1 -0
  138. package/_types/chains/opStack/actions/getL2Output.d.ts +8 -1
  139. package/_types/chains/opStack/actions/getL2Output.d.ts.map +1 -1
  140. package/_types/chains/opStack/actions/getPortalVersion.d.ts +46 -0
  141. package/_types/chains/opStack/actions/getPortalVersion.d.ts.map +1 -0
  142. package/_types/chains/opStack/actions/getTimeToFinalize.d.ts.map +1 -1
  143. package/_types/chains/opStack/actions/getTimeToNextGame.d.ts +61 -0
  144. package/_types/chains/opStack/actions/getTimeToNextGame.d.ts.map +1 -0
  145. package/_types/chains/opStack/actions/getTimeToProve.d.ts +6 -3
  146. package/_types/chains/opStack/actions/getTimeToProve.d.ts.map +1 -1
  147. package/_types/chains/opStack/actions/getWithdrawalStatus.d.ts +7 -1
  148. package/_types/chains/opStack/actions/getWithdrawalStatus.d.ts.map +1 -1
  149. package/_types/chains/opStack/actions/proveWithdrawal.d.ts +1 -1
  150. package/_types/chains/opStack/actions/proveWithdrawal.d.ts.map +1 -1
  151. package/_types/chains/opStack/actions/waitForNextGame.d.ts +60 -0
  152. package/_types/chains/opStack/actions/waitForNextGame.d.ts.map +1 -0
  153. package/_types/chains/opStack/actions/waitForNextL2Output.d.ts.map +1 -1
  154. package/_types/chains/opStack/actions/waitToProve.d.ts +10 -2
  155. package/_types/chains/opStack/actions/waitToProve.d.ts.map +1 -1
  156. package/_types/chains/opStack/decorators/publicL1.d.ts +129 -0
  157. package/_types/chains/opStack/decorators/publicL1.d.ts.map +1 -1
  158. package/_types/chains/opStack/errors/withdrawal.d.ts +7 -0
  159. package/_types/chains/opStack/errors/withdrawal.d.ts.map +1 -1
  160. package/_types/chains/opStack/index.d.ts +5 -0
  161. package/_types/chains/opStack/index.d.ts.map +1 -1
  162. package/_types/chains/opStack/types/chain.d.ts +1 -1
  163. package/_types/chains/opStack/types/chain.d.ts.map +1 -1
  164. package/_types/chains/opStack/types/withdrawal.d.ts +7 -0
  165. package/_types/chains/opStack/types/withdrawal.d.ts.map +1 -1
  166. package/_types/chains/zksync/actions/deployContract.d.ts +49 -0
  167. package/_types/chains/zksync/actions/deployContract.d.ts.map +1 -0
  168. package/_types/chains/zksync/constants/abis.d.ts +70 -0
  169. package/_types/chains/zksync/constants/abis.d.ts.map +1 -0
  170. package/_types/chains/zksync/constants/address.d.ts +2 -0
  171. package/_types/chains/zksync/constants/address.d.ts.map +1 -0
  172. package/_types/chains/zksync/constants/contract.d.ts +3 -0
  173. package/_types/chains/zksync/constants/contract.d.ts.map +1 -0
  174. package/_types/chains/zksync/constants/number.d.ts +2 -0
  175. package/_types/chains/zksync/constants/number.d.ts.map +1 -0
  176. package/_types/chains/zksync/decorators/eip712.d.ts +32 -0
  177. package/_types/chains/zksync/decorators/eip712.d.ts.map +1 -1
  178. package/_types/chains/zksync/errors/bytecode.d.ts +30 -0
  179. package/_types/chains/zksync/errors/bytecode.d.ts.map +1 -0
  180. package/_types/chains/zksync/formatters.d.ts.map +1 -1
  181. package/_types/chains/zksync/index.d.ts +1 -0
  182. package/_types/chains/zksync/index.d.ts.map +1 -1
  183. package/_types/chains/zksync/types/contract.d.ts +2 -0
  184. package/_types/chains/zksync/types/contract.d.ts.map +1 -0
  185. package/_types/chains/zksync/utils/abi/encodeDeployData.d.ts +13 -0
  186. package/_types/chains/zksync/utils/abi/encodeDeployData.d.ts.map +1 -0
  187. package/_types/chains/zksync/utils/getEip712Domain.d.ts.map +1 -1
  188. package/_types/chains/zksync/utils/hashBytecode.d.ts +3 -0
  189. package/_types/chains/zksync/utils/hashBytecode.d.ts.map +1 -0
  190. package/_types/errors/version.d.ts +1 -1
  191. package/_types/errors/version.d.ts.map +1 -1
  192. package/chains/definitions/optimismSepolia.ts +5 -0
  193. package/chains/opStack/abis.ts +1071 -0
  194. package/chains/opStack/actions/buildProveWithdrawal.ts +7 -6
  195. package/chains/opStack/actions/getGame.ts +99 -0
  196. package/chains/opStack/actions/getGames.ts +133 -0
  197. package/chains/opStack/actions/getL2Output.ts +44 -3
  198. package/chains/opStack/actions/getPortalVersion.ts +87 -0
  199. package/chains/opStack/actions/getTimeToFinalize.ts +64 -27
  200. package/chains/opStack/actions/getTimeToNextGame.ts +143 -0
  201. package/chains/opStack/actions/getTimeToProve.ts +43 -5
  202. package/chains/opStack/actions/getWithdrawalStatus.ts +130 -38
  203. package/chains/opStack/actions/proveWithdrawal.ts +3 -1
  204. package/chains/opStack/actions/waitForNextGame.ts +122 -0
  205. package/chains/opStack/actions/waitForNextL2Output.ts +5 -1
  206. package/chains/opStack/actions/waitToProve.ts +65 -7
  207. package/chains/opStack/decorators/publicL1.ts +164 -0
  208. package/chains/opStack/errors/withdrawal.ts +10 -0
  209. package/chains/opStack/index.ts +30 -0
  210. package/chains/opStack/types/chain.ts +4 -1
  211. package/chains/opStack/types/withdrawal.ts +8 -0
  212. package/chains/zksync/actions/deployContract.ts +100 -0
  213. package/chains/zksync/constants/abis.ts +424 -0
  214. package/chains/zksync/constants/address.ts +2 -0
  215. package/chains/zksync/constants/contract.ts +2 -0
  216. package/chains/zksync/constants/number.ts +3 -0
  217. package/chains/zksync/decorators/eip712.ts +47 -0
  218. package/chains/zksync/errors/bytecode.ts +46 -0
  219. package/chains/zksync/formatters.ts +7 -1
  220. package/chains/zksync/index.ts +6 -0
  221. package/chains/zksync/types/contract.ts +6 -0
  222. package/chains/zksync/utils/abi/encodeDeployData.ts +120 -0
  223. package/chains/zksync/utils/getEip712Domain.ts +4 -2
  224. package/chains/zksync/utils/hashBytecode.ts +48 -0
  225. package/errors/version.ts +1 -1
  226. package/package.json +1 -1
@@ -0,0 +1,143 @@
1
+ import type { Client } from '../../../clients/createClient.js'
2
+ import type { Transport } from '../../../clients/transports/createTransport.js'
3
+ import type { ErrorType } from '../../../errors/utils.js'
4
+ import type { Account } from '../../../types/account.js'
5
+ import type {
6
+ Chain,
7
+ DeriveChain,
8
+ GetChainParameter,
9
+ } from '../../../types/chain.js'
10
+ import type { GetContractAddressParameter } from '../types/contract.js'
11
+ import { type GetGamesErrorType, getGames } from './getGames.js'
12
+
13
+ export type GetTimeToNextGameParameters<
14
+ chain extends Chain | undefined = Chain | undefined,
15
+ chainOverride extends Chain | undefined = Chain | undefined,
16
+ _derivedChain extends Chain | undefined = DeriveChain<chain, chainOverride>,
17
+ > = GetChainParameter<chain, chainOverride> &
18
+ GetContractAddressParameter<
19
+ _derivedChain,
20
+ 'portal' | 'disputeGameFactory'
21
+ > & {
22
+ /**
23
+ * The buffer to account for discrepencies between non-deterministic time intervals.
24
+ * @default 1.1
25
+ */
26
+ intervalBuffer?: number | undefined
27
+ /**
28
+ * The minimum L2 block number of the next game.
29
+ */
30
+ l2BlockNumber: bigint
31
+ }
32
+ export type GetTimeToNextGameReturnType = {
33
+ /** The estimated interval (in seconds) between L2 dispute games. */
34
+ interval: number
35
+ /**
36
+ * Estimated seconds until the next L2 dispute game.
37
+ * `0` if the next L2 dispute game has already been submitted.
38
+ */
39
+ seconds: number
40
+ /**
41
+ * Estimated timestamp of the next L2 dispute game.
42
+ * `undefined` if the next L2 dispute game has already been submitted.
43
+ */
44
+ timestamp?: number | undefined
45
+ }
46
+ export type GetTimeToNextGameErrorType = GetGamesErrorType | ErrorType
47
+
48
+ /**
49
+ * Returns the time until the next L2 dispute game (after the provided block number) is submitted.
50
+ * Used for the [Withdrawal](/op-stack/guides/withdrawals) flow.
51
+ *
52
+ * - Docs: https://viem.sh/op-stack/actions/getTimeToNextGame
53
+ *
54
+ * @param client - Client to use
55
+ * @param parameters - {@link GetTimeToNextGameParameters}
56
+ * @returns The L2 transaction hash. {@link GetTimeToNextGameReturnType}
57
+ *
58
+ * @example
59
+ * import { createPublicClient, http } from 'viem'
60
+ * import { getBlockNumber } from 'viem/actions'
61
+ * import { mainnet, optimism } from 'viem/chains'
62
+ * import { getTimeToNextGame } from 'viem/op-stack'
63
+ *
64
+ * const publicClientL1 = createPublicClient({
65
+ * chain: mainnet,
66
+ * transport: http(),
67
+ * })
68
+ *
69
+ * const { seconds } = await getTimeToNextGame(publicClientL1, {
70
+ * l2BlockNumber: 113405763n,
71
+ * targetChain: optimism
72
+ * })
73
+ */
74
+ export async function getTimeToNextGame<
75
+ chain extends Chain | undefined,
76
+ account extends Account | undefined,
77
+ chainOverride extends Chain | undefined = undefined,
78
+ >(
79
+ client: Client<Transport, chain, account>,
80
+ parameters: GetTimeToNextGameParameters<chain, chainOverride>,
81
+ ): Promise<GetTimeToNextGameReturnType> {
82
+ const { intervalBuffer = 1.1, l2BlockNumber } = parameters
83
+
84
+ const games = await getGames(client, {
85
+ ...parameters,
86
+ l2BlockNumber: undefined,
87
+ limit: 10,
88
+ })
89
+
90
+ const deltas = games
91
+ .map(({ l2BlockNumber, timestamp }, index) => {
92
+ return index === games.length - 1
93
+ ? null
94
+ : [
95
+ games[index + 1].timestamp - timestamp,
96
+ games[index + 1].l2BlockNumber - l2BlockNumber,
97
+ ]
98
+ })
99
+ .filter(Boolean)
100
+ const interval = Math.ceil(
101
+ (deltas as [bigint, bigint][]).reduce(
102
+ (a, [b]) => Number(a) - Number(b),
103
+ 0,
104
+ ) / deltas.length,
105
+ )
106
+ const blockInterval = Math.ceil(
107
+ (deltas as [bigint, bigint][]).reduce(
108
+ (a, [_, b]) => Number(a) - Number(b),
109
+ 0,
110
+ ) / deltas.length,
111
+ )
112
+
113
+ const latestGame = games[0]
114
+ const latestGameTimestamp = Number(latestGame.timestamp) * 1000
115
+
116
+ const intervalWithBuffer = Math.ceil(interval * intervalBuffer)
117
+
118
+ const now = Date.now()
119
+
120
+ const seconds = (() => {
121
+ // If the current timestamp is lesser than the latest dispute game timestamp,
122
+ // then we assume that the dispute game has already been submitted.
123
+ if (now < latestGameTimestamp) return 0
124
+
125
+ // If the latest dispute game block is newer than the provided dispute game block number,
126
+ // then we assume that the dispute game has already been submitted.
127
+ if (latestGame.l2BlockNumber > l2BlockNumber) return 0
128
+
129
+ const elapsedBlocks = Number(l2BlockNumber - latestGame.l2BlockNumber)
130
+
131
+ const elapsed = Math.ceil((now - latestGameTimestamp) / 1000)
132
+ const secondsToNextOutput =
133
+ intervalWithBuffer - (elapsed % intervalWithBuffer)
134
+ return elapsedBlocks < blockInterval
135
+ ? secondsToNextOutput
136
+ : Math.floor(elapsedBlocks / Number(blockInterval)) * intervalWithBuffer +
137
+ secondsToNextOutput
138
+ })()
139
+
140
+ const timestamp = seconds > 0 ? now + seconds * 1000 : undefined
141
+
142
+ return { interval, seconds, timestamp }
143
+ }
@@ -8,7 +8,19 @@ import type {
8
8
  GetChainParameter,
9
9
  } from '../../../types/chain.js'
10
10
  import type { TransactionReceipt } from '../../../types/transaction.js'
11
+ import type { OneOf } from '../../../types/utils.js'
11
12
  import type { GetContractAddressParameter } from '../types/contract.js'
13
+ import {
14
+ type GetPortalVersionErrorType,
15
+ type GetPortalVersionParameters,
16
+ getPortalVersion,
17
+ } from './getPortalVersion.js'
18
+ import {
19
+ type GetTimeToNextGameErrorType,
20
+ type GetTimeToNextGameParameters,
21
+ type GetTimeToNextGameReturnType,
22
+ getTimeToNextGame,
23
+ } from './getTimeToNextGame.js'
12
24
  import {
13
25
  type GetTimeToNextL2OutputErrorType,
14
26
  type GetTimeToNextL2OutputParameters,
@@ -21,7 +33,13 @@ export type GetTimeToProveParameters<
21
33
  chainOverride extends Chain | undefined = Chain | undefined,
22
34
  _derivedChain extends Chain | undefined = DeriveChain<chain, chainOverride>,
23
35
  > = GetChainParameter<chain, chainOverride> &
24
- GetContractAddressParameter<_derivedChain, 'l2OutputOracle'> & {
36
+ OneOf<
37
+ | GetContractAddressParameter<_derivedChain, 'l2OutputOracle'>
38
+ | GetContractAddressParameter<
39
+ _derivedChain,
40
+ 'disputeGameFactory' | 'portal'
41
+ >
42
+ > & {
25
43
  /**
26
44
  * The buffer to account for discrepencies between non-deterministic time intervals.
27
45
  * @default 1.1
@@ -31,8 +49,16 @@ export type GetTimeToProveParameters<
31
49
  | undefined
32
50
  receipt: TransactionReceipt
33
51
  }
34
- export type GetTimeToProveReturnType = GetTimeToNextL2OutputReturnType
35
- export type GetTimeToProveErrorType = GetTimeToNextL2OutputErrorType | ErrorType
52
+
53
+ export type GetTimeToProveReturnType =
54
+ | GetTimeToNextGameReturnType
55
+ | GetTimeToNextL2OutputReturnType
56
+
57
+ export type GetTimeToProveErrorType =
58
+ | GetPortalVersionErrorType
59
+ | GetTimeToNextGameErrorType
60
+ | GetTimeToNextL2OutputErrorType
61
+ | ErrorType
36
62
 
37
63
  /**
38
64
  * Returns the time until the withdrawal transaction is ready to prove. Used for the [Withdrawal](/op-stack/guides/withdrawals) flow.
@@ -74,8 +100,20 @@ export async function getTimeToProve<
74
100
  ): Promise<GetTimeToProveReturnType> {
75
101
  const { receipt } = parameters
76
102
 
77
- return getTimeToNextL2Output(client, {
103
+ const portalVersion = await getPortalVersion(
104
+ client,
105
+ parameters as GetPortalVersionParameters,
106
+ )
107
+
108
+ // Legacy
109
+ if (portalVersion.major < 3)
110
+ return getTimeToNextL2Output(client, {
111
+ ...parameters,
112
+ l2BlockNumber: receipt.blockNumber,
113
+ } as GetTimeToNextL2OutputParameters)
114
+
115
+ return getTimeToNextGame(client, {
78
116
  ...parameters,
79
117
  l2BlockNumber: receipt.blockNumber,
80
- })
118
+ } as GetTimeToNextGameParameters)
81
119
  }
@@ -13,16 +13,32 @@ import type {
13
13
  GetChainParameter,
14
14
  } from '../../../types/chain.js'
15
15
  import type { TransactionReceipt } from '../../../types/transaction.js'
16
- import { portalAbi } from '../abis.js'
16
+ import type { OneOf } from '../../../types/utils.js'
17
+ import { portal2Abi, portalAbi } from '../abis.js'
17
18
  import { ReceiptContainsNoWithdrawalsError } from '../errors/withdrawal.js'
19
+ import type { TargetChain } from '../types/chain.js'
18
20
  import type { GetContractAddressParameter } from '../types/contract.js'
19
21
  import {
20
22
  type GetWithdrawalsErrorType,
21
23
  getWithdrawals,
22
24
  } from '../utils/getWithdrawals.js'
23
- import { type GetL2OutputErrorType, getL2Output } from './getL2Output.js'
25
+ import {
26
+ type GetGameErrorType,
27
+ type GetGameParameters,
28
+ getGame,
29
+ } from './getGame.js'
30
+ import {
31
+ type GetL2OutputErrorType,
32
+ type GetL2OutputParameters,
33
+ getL2Output,
34
+ } from './getL2Output.js'
35
+ import {
36
+ type GetPortalVersionParameters,
37
+ getPortalVersion,
38
+ } from './getPortalVersion.js'
24
39
  import {
25
40
  type GetTimeToFinalizeErrorType,
41
+ type GetTimeToFinalizeParameters,
26
42
  getTimeToFinalize,
27
43
  } from './getTimeToFinalize.js'
28
44
 
@@ -31,7 +47,18 @@ export type GetWithdrawalStatusParameters<
31
47
  chainOverride extends Chain | undefined = Chain | undefined,
32
48
  _derivedChain extends Chain | undefined = DeriveChain<chain, chainOverride>,
33
49
  > = GetChainParameter<chain, chainOverride> &
34
- GetContractAddressParameter<_derivedChain, 'l2OutputOracle' | 'portal'> & {
50
+ OneOf<
51
+ | GetContractAddressParameter<_derivedChain, 'l2OutputOracle' | 'portal'>
52
+ | GetContractAddressParameter<
53
+ _derivedChain,
54
+ 'disputeGameFactory' | 'portal'
55
+ >
56
+ > & {
57
+ /**
58
+ * Limit of games to extract to check withdrawal status.
59
+ * @default 100
60
+ */
61
+ gameLimit?: number
35
62
  receipt: TransactionReceipt
36
63
  }
37
64
  export type GetWithdrawalStatusReturnType =
@@ -85,12 +112,19 @@ export async function getWithdrawalStatus<
85
112
  client: Client<Transport, chain, account>,
86
113
  parameters: GetWithdrawalStatusParameters<chain, chainOverride>,
87
114
  ): Promise<GetWithdrawalStatusReturnType> {
88
- const { chain = client.chain, receipt, targetChain } = parameters
115
+ const {
116
+ chain = client.chain,
117
+ gameLimit = 100,
118
+ receipt,
119
+ targetChain: targetChain_,
120
+ } = parameters
121
+
122
+ const targetChain = targetChain_ as unknown as TargetChain
89
123
 
90
124
  const portalAddress = (() => {
91
125
  if (parameters.portalAddress) return parameters.portalAddress
92
- if (chain) return targetChain!.contracts.portal[chain.id].address
93
- return Object.values(targetChain!.contracts.portal)[0].address
126
+ if (chain) return targetChain.contracts.portal[chain.id].address
127
+ return Object.values(targetChain.contracts.portal)[0].address
94
128
  })()
95
129
 
96
130
  const [withdrawal] = getWithdrawals(receipt)
@@ -100,53 +134,111 @@ export async function getWithdrawalStatus<
100
134
  hash: receipt.transactionHash,
101
135
  })
102
136
 
103
- const [outputResult, proveResult, finalizedResult, timeToFinalizeResult] =
137
+ const portalVersion = await getPortalVersion(
138
+ client,
139
+ parameters as GetPortalVersionParameters,
140
+ )
141
+
142
+ // Legacy (Portal < v3)
143
+ if (portalVersion.major < 3) {
144
+ const [outputResult, proveResult, finalizedResult, timeToFinalizeResult] =
145
+ await Promise.allSettled([
146
+ getL2Output(client, {
147
+ ...parameters,
148
+ l2BlockNumber: receipt.blockNumber,
149
+ } as GetL2OutputParameters),
150
+ readContract(client, {
151
+ abi: portalAbi,
152
+ address: portalAddress,
153
+ functionName: 'provenWithdrawals',
154
+ args: [withdrawal.withdrawalHash],
155
+ }),
156
+ readContract(client, {
157
+ abi: portalAbi,
158
+ address: portalAddress,
159
+ functionName: 'finalizedWithdrawals',
160
+ args: [withdrawal.withdrawalHash],
161
+ }),
162
+ getTimeToFinalize(client, {
163
+ ...parameters,
164
+ withdrawalHash: withdrawal.withdrawalHash,
165
+ } as GetTimeToFinalizeParameters),
166
+ ])
167
+
168
+ // If the L2 Output is not processed yet (ie. the actions throws), this means
169
+ // that the withdrawal is not ready to prove.
170
+ if (outputResult.status === 'rejected') {
171
+ const error = outputResult.reason as GetL2OutputErrorType
172
+ if (
173
+ error.cause instanceof ContractFunctionRevertedError &&
174
+ error.cause.data?.args?.[0] ===
175
+ 'L2OutputOracle: cannot get output for a block that has not been proposed'
176
+ )
177
+ return 'waiting-to-prove'
178
+ throw error
179
+ }
180
+ if (proveResult.status === 'rejected') throw proveResult.reason
181
+ if (finalizedResult.status === 'rejected') throw finalizedResult.reason
182
+ if (timeToFinalizeResult.status === 'rejected')
183
+ throw timeToFinalizeResult.reason
184
+
185
+ const [_, proveTimestamp] = proveResult.value
186
+ if (!proveTimestamp) return 'ready-to-prove'
187
+
188
+ const finalized = finalizedResult.value
189
+ if (finalized) return 'finalized'
190
+
191
+ const { seconds } = timeToFinalizeResult.value
192
+ return seconds > 0 ? 'waiting-to-finalize' : 'ready-to-finalize'
193
+ }
194
+
195
+ const [disputeGameResult, checkWithdrawalResult, finalizedResult] =
104
196
  await Promise.allSettled([
105
- getL2Output(client, {
197
+ getGame(client, {
106
198
  ...parameters,
107
199
  l2BlockNumber: receipt.blockNumber,
108
- }),
200
+ limit: gameLimit,
201
+ } as GetGameParameters),
109
202
  readContract(client, {
110
- abi: portalAbi,
203
+ abi: portal2Abi,
111
204
  address: portalAddress,
112
- functionName: 'provenWithdrawals',
205
+ functionName: 'checkWithdrawal',
113
206
  args: [withdrawal.withdrawalHash],
114
207
  }),
115
208
  readContract(client, {
116
- abi: portalAbi,
209
+ abi: portal2Abi,
117
210
  address: portalAddress,
118
211
  functionName: 'finalizedWithdrawals',
119
212
  args: [withdrawal.withdrawalHash],
120
213
  }),
121
- getTimeToFinalize(client, {
122
- ...parameters,
123
- withdrawalHash: withdrawal.withdrawalHash,
124
- }),
125
214
  ])
126
215
 
127
- // If the L2 Output is not processed yet (ie. the actions throws), this means
128
- // that the withdrawal is not ready to prove.
129
- if (outputResult.status === 'rejected') {
130
- const error = outputResult.reason as GetL2OutputErrorType
131
- if (
132
- error.cause instanceof ContractFunctionRevertedError &&
133
- error.cause.data?.args?.[0] ===
134
- 'L2OutputOracle: cannot get output for a block that has not been proposed'
135
- )
136
- return 'waiting-to-prove'
137
- throw error
216
+ if (finalizedResult.status === 'fulfilled' && finalizedResult.value)
217
+ return 'finalized'
218
+
219
+ if (disputeGameResult.status === 'rejected') {
220
+ const error = disputeGameResult.reason as GetGameErrorType
221
+ if (error.name === 'GameNotFoundError') return 'waiting-to-prove'
222
+ throw disputeGameResult.reason
223
+ }
224
+ if (checkWithdrawalResult.status === 'rejected') {
225
+ const error = checkWithdrawalResult.reason as ReadContractErrorType
226
+ if (error.cause instanceof ContractFunctionRevertedError) {
227
+ const errorMessage = error.cause.data?.args?.[0]
228
+ if (errorMessage === 'OptimismPortal: withdrawal has not been proven yet')
229
+ return 'ready-to-prove'
230
+ if (
231
+ errorMessage ===
232
+ 'OptimismPortal: proven withdrawal has not matured yet' ||
233
+ errorMessage ===
234
+ 'OptimismPortal: output proposal has not been finalized yet' ||
235
+ errorMessage === 'OptimismPortal: output proposal in air-gap'
236
+ )
237
+ return 'waiting-to-finalize'
238
+ }
239
+ throw checkWithdrawalResult.reason
138
240
  }
139
- if (proveResult.status === 'rejected') throw proveResult.reason
140
241
  if (finalizedResult.status === 'rejected') throw finalizedResult.reason
141
- if (timeToFinalizeResult.status === 'rejected')
142
- throw timeToFinalizeResult.reason
143
-
144
- const [_, proveTimestamp] = proveResult.value
145
- if (!proveTimestamp) return 'ready-to-prove'
146
-
147
- const finalized = finalizedResult.value
148
- if (finalized) return 'finalized'
149
242
 
150
- const { seconds } = timeToFinalizeResult.value
151
- return seconds > 0 ? 'waiting-to-finalize' : 'ready-to-finalize'
243
+ return 'ready-to-finalize'
152
244
  }
@@ -33,9 +33,11 @@ export type ProveWithdrawalParameters<
33
33
  UnionOmit<
34
34
  FormattedTransactionRequest<_derivedChain>,
35
35
  | 'accessList'
36
+ | 'blobs'
36
37
  | 'data'
37
38
  | 'from'
38
39
  | 'gas'
40
+ | 'maxFeePerBlobGas'
39
41
  | 'gasPrice'
40
42
  | 'to'
41
43
  | 'type'
@@ -130,7 +132,7 @@ export async function proveWithdrawal<
130
132
  })()
131
133
 
132
134
  const gas_ =
133
- typeof gas !== 'number' && gas !== null
135
+ typeof gas !== 'bigint' && gas !== null
134
136
  ? await estimateProveWithdrawalGas(
135
137
  client,
136
138
  parameters as EstimateProveWithdrawalGasParameters,
@@ -0,0 +1,122 @@
1
+ import type { Client } from '../../../clients/createClient.js'
2
+ import type { Transport } from '../../../clients/transports/createTransport.js'
3
+ import type { ErrorType } from '../../../errors/utils.js'
4
+ import type { Account } from '../../../types/account.js'
5
+ import type {
6
+ Chain,
7
+ DeriveChain,
8
+ GetChainParameter,
9
+ } from '../../../types/chain.js'
10
+ import { poll } from '../../../utils/poll.js'
11
+ import { GameNotFoundError } from '../errors/withdrawal.js'
12
+ import type { GetContractAddressParameter } from '../types/contract.js'
13
+ import {
14
+ type GetGameErrorType,
15
+ type GetGameReturnType,
16
+ getGame,
17
+ } from './getGame.js'
18
+ import {
19
+ type GetTimeToNextGameErrorType,
20
+ type GetTimeToNextGameParameters,
21
+ getTimeToNextGame,
22
+ } from './getTimeToNextGame.js'
23
+
24
+ export type WaitForNextGameParameters<
25
+ chain extends Chain | undefined = Chain | undefined,
26
+ chainOverride extends Chain | undefined = Chain | undefined,
27
+ _derivedChain extends Chain | undefined = DeriveChain<chain, chainOverride>,
28
+ > = GetChainParameter<chain, chainOverride> &
29
+ GetContractAddressParameter<
30
+ _derivedChain,
31
+ 'portal' | 'disputeGameFactory'
32
+ > & {
33
+ /**
34
+ * Limit of games to extract.
35
+ * @default 100
36
+ */
37
+ limit?: number | undefined
38
+ /**
39
+ * The buffer to account for discrepencies between non-deterministic time intervals.
40
+ * @default 1.1
41
+ */
42
+ intervalBuffer?: GetTimeToNextGameParameters['intervalBuffer'] | undefined
43
+ l2BlockNumber: bigint
44
+ /**
45
+ * Polling frequency (in ms). Defaults to Client's pollingInterval config.
46
+ * @default client.pollingInterval
47
+ */
48
+ pollingInterval?: number | undefined
49
+ }
50
+ export type WaitForNextGameReturnType = GetGameReturnType
51
+ export type WaitForNextGameErrorType =
52
+ | GetGameErrorType
53
+ | GetTimeToNextGameErrorType
54
+ | ErrorType
55
+
56
+ /**
57
+ * Waits for the next dispute game (after the provided block number) to be submitted.
58
+ *
59
+ * - Docs: https://viem.sh/op-stack/actions/waitForNextGame
60
+ *
61
+ * @param client - Client to use
62
+ * @param parameters - {@link WaitForNextGameParameters}
63
+ * @returns The L2 transaction hash. {@link WaitForNextGameReturnType}
64
+ *
65
+ * @example
66
+ * import { createPublicClient, http } from 'viem'
67
+ * import { getBlockNumber } from 'viem/actions'
68
+ * import { mainnet, optimism } from 'viem/chains'
69
+ * import { waitForNextGame } from 'viem/op-stack'
70
+ *
71
+ * const publicClientL1 = createPublicClient({
72
+ * chain: mainnet,
73
+ * transport: http(),
74
+ * })
75
+ * const publicClientL2 = createPublicClient({
76
+ * chain: optimism,
77
+ * transport: http(),
78
+ * })
79
+ *
80
+ * const l2BlockNumber = await getBlockNumber(publicClientL2)
81
+ * await waitForNextGame(publicClientL1, {
82
+ * l2BlockNumber,
83
+ * targetChain: optimism
84
+ * })
85
+ */
86
+ export async function waitForNextGame<
87
+ chain extends Chain | undefined,
88
+ account extends Account | undefined,
89
+ chainOverride extends Chain | undefined = undefined,
90
+ >(
91
+ client: Client<Transport, chain, account>,
92
+ parameters: WaitForNextGameParameters<chain, chainOverride>,
93
+ ): Promise<WaitForNextGameReturnType> {
94
+ const { pollingInterval = client.pollingInterval } = parameters
95
+
96
+ const { seconds } = await getTimeToNextGame(client, parameters)
97
+
98
+ return new Promise((resolve, reject) => {
99
+ poll(
100
+ async ({ unpoll }) => {
101
+ try {
102
+ const game = await getGame(client, {
103
+ ...parameters,
104
+ strategy: 'random',
105
+ })
106
+ unpoll()
107
+ resolve(game)
108
+ } catch (e) {
109
+ const error = e as GetGameErrorType
110
+ if (!(error instanceof GameNotFoundError)) {
111
+ unpoll()
112
+ reject(e)
113
+ }
114
+ }
115
+ },
116
+ {
117
+ interval: pollingInterval,
118
+ initialWaitTime: async () => seconds * 1000,
119
+ },
120
+ )
121
+ })
122
+ }
@@ -12,6 +12,7 @@ import { poll } from '../../../utils/poll.js'
12
12
  import type { GetContractAddressParameter } from '../types/contract.js'
13
13
  import {
14
14
  type GetL2OutputErrorType,
15
+ type GetL2OutputParameters,
15
16
  type GetL2OutputReturnType,
16
17
  getL2Output,
17
18
  } from './getL2Output.js'
@@ -93,7 +94,10 @@ export async function waitForNextL2Output<
93
94
  poll(
94
95
  async ({ unpoll }) => {
95
96
  try {
96
- const output = await getL2Output(client, parameters)
97
+ const output = await getL2Output(
98
+ client,
99
+ parameters as GetL2OutputParameters,
100
+ )
97
101
  unpoll()
98
102
  resolve(output)
99
103
  } catch (e) {