@aztec/ethereum 0.0.1-commit.b655e406 → 0.0.1-commit.c0b82b2

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/dest/account.d.ts +1 -1
  2. package/dest/chain.d.ts +1 -1
  3. package/dest/client.d.ts +1 -1
  4. package/dest/client.js +6 -2
  5. package/dest/config.d.ts +22 -68
  6. package/dest/config.d.ts.map +1 -1
  7. package/dest/config.js +61 -380
  8. package/dest/constants.d.ts +1 -1
  9. package/dest/contracts/empire_base.d.ts +9 -5
  10. package/dest/contracts/empire_base.d.ts.map +1 -1
  11. package/dest/contracts/empire_base.js +1 -1
  12. package/dest/contracts/empire_slashing_proposer.d.ts +8 -4
  13. package/dest/contracts/empire_slashing_proposer.d.ts.map +1 -1
  14. package/dest/contracts/empire_slashing_proposer.js +39 -17
  15. package/dest/contracts/errors.d.ts +1 -1
  16. package/dest/contracts/errors.d.ts.map +1 -1
  17. package/dest/contracts/fee_asset_handler.d.ts +6 -5
  18. package/dest/contracts/fee_asset_handler.d.ts.map +1 -1
  19. package/dest/contracts/fee_asset_handler.js +11 -9
  20. package/dest/contracts/fee_asset_price_oracle.d.ts +101 -0
  21. package/dest/contracts/fee_asset_price_oracle.d.ts.map +1 -0
  22. package/dest/contracts/fee_asset_price_oracle.js +651 -0
  23. package/dest/contracts/fee_juice.d.ts +1 -1
  24. package/dest/contracts/fee_juice.d.ts.map +1 -1
  25. package/dest/contracts/governance.d.ts +18 -16
  26. package/dest/contracts/governance.d.ts.map +1 -1
  27. package/dest/contracts/governance.js +14 -4
  28. package/dest/contracts/governance_proposer.d.ts +8 -4
  29. package/dest/contracts/governance_proposer.d.ts.map +1 -1
  30. package/dest/contracts/governance_proposer.js +412 -11
  31. package/dest/contracts/gse.d.ts +1 -1
  32. package/dest/contracts/gse.d.ts.map +1 -1
  33. package/dest/contracts/inbox.d.ts +24 -3
  34. package/dest/contracts/inbox.d.ts.map +1 -1
  35. package/dest/contracts/inbox.js +36 -1
  36. package/dest/contracts/index.d.ts +4 -1
  37. package/dest/contracts/index.d.ts.map +1 -1
  38. package/dest/contracts/index.js +3 -0
  39. package/dest/contracts/log.d.ts +13 -0
  40. package/dest/contracts/log.d.ts.map +1 -0
  41. package/dest/contracts/log.js +1 -0
  42. package/dest/contracts/multicall.d.ts +2 -2
  43. package/dest/contracts/multicall.d.ts.map +1 -1
  44. package/dest/contracts/multicall.js +2 -1
  45. package/dest/contracts/outbox.d.ts +41 -0
  46. package/dest/contracts/outbox.d.ts.map +1 -0
  47. package/dest/contracts/outbox.js +86 -0
  48. package/dest/contracts/registry.d.ts +1 -1
  49. package/dest/contracts/registry.d.ts.map +1 -1
  50. package/dest/contracts/rollup.d.ts +195 -123
  51. package/dest/contracts/rollup.d.ts.map +1 -1
  52. package/dest/contracts/rollup.js +765 -187
  53. package/dest/contracts/slasher_contract.d.ts +1 -1
  54. package/dest/contracts/slasher_contract.d.ts.map +1 -1
  55. package/dest/contracts/tally_slashing_proposer.d.ts +9 -7
  56. package/dest/contracts/tally_slashing_proposer.d.ts.map +1 -1
  57. package/dest/contracts/tally_slashing_proposer.js +11 -4
  58. package/dest/contracts/utils.d.ts +1 -1
  59. package/dest/deploy_aztec_l1_contracts.d.ts +259 -0
  60. package/dest/deploy_aztec_l1_contracts.d.ts.map +1 -0
  61. package/dest/deploy_aztec_l1_contracts.js +413 -0
  62. package/dest/deploy_l1_contract.d.ts +68 -0
  63. package/dest/deploy_l1_contract.d.ts.map +1 -0
  64. package/dest/deploy_l1_contract.js +312 -0
  65. package/dest/eth-signer/eth-signer.d.ts +1 -1
  66. package/dest/eth-signer/index.d.ts +1 -1
  67. package/dest/forwarder_proxy.d.ts +32 -0
  68. package/dest/forwarder_proxy.d.ts.map +1 -0
  69. package/dest/forwarder_proxy.js +93 -0
  70. package/dest/generated/l1-contracts-defaults.d.ts +30 -0
  71. package/dest/generated/l1-contracts-defaults.d.ts.map +1 -0
  72. package/dest/generated/l1-contracts-defaults.js +30 -0
  73. package/dest/l1_artifacts.d.ts +7608 -2048
  74. package/dest/l1_artifacts.d.ts.map +1 -1
  75. package/dest/l1_contract_addresses.d.ts +3 -3
  76. package/dest/l1_contract_addresses.d.ts.map +1 -1
  77. package/dest/l1_contract_addresses.js +3 -3
  78. package/dest/l1_reader.d.ts +3 -1
  79. package/dest/l1_reader.d.ts.map +1 -1
  80. package/dest/l1_reader.js +6 -0
  81. package/dest/l1_tx_utils/config.d.ts +11 -5
  82. package/dest/l1_tx_utils/config.d.ts.map +1 -1
  83. package/dest/l1_tx_utils/config.js +43 -7
  84. package/dest/l1_tx_utils/constants.d.ts +8 -2
  85. package/dest/l1_tx_utils/constants.d.ts.map +1 -1
  86. package/dest/l1_tx_utils/constants.js +27 -2
  87. package/dest/l1_tx_utils/factory.d.ts +18 -10
  88. package/dest/l1_tx_utils/factory.d.ts.map +1 -1
  89. package/dest/l1_tx_utils/factory.js +17 -7
  90. package/dest/l1_tx_utils/fee-strategies/index.d.ts +10 -0
  91. package/dest/l1_tx_utils/fee-strategies/index.d.ts.map +1 -0
  92. package/dest/l1_tx_utils/fee-strategies/index.js +12 -0
  93. package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts +8 -0
  94. package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts.map +1 -0
  95. package/dest/l1_tx_utils/fee-strategies/p75_competitive.js +129 -0
  96. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts +23 -0
  97. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts.map +1 -0
  98. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.js +191 -0
  99. package/dest/l1_tx_utils/fee-strategies/types.d.ts +51 -0
  100. package/dest/l1_tx_utils/fee-strategies/types.d.ts.map +1 -0
  101. package/dest/l1_tx_utils/fee-strategies/types.js +3 -0
  102. package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts +41 -0
  103. package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts.map +1 -0
  104. package/dest/l1_tx_utils/forwarder_l1_tx_utils.js +42 -0
  105. package/dest/l1_tx_utils/index-blobs.d.ts +3 -0
  106. package/dest/l1_tx_utils/index-blobs.d.ts.map +1 -0
  107. package/dest/l1_tx_utils/index-blobs.js +2 -0
  108. package/dest/l1_tx_utils/index.d.ts +4 -1
  109. package/dest/l1_tx_utils/index.d.ts.map +1 -1
  110. package/dest/l1_tx_utils/index.js +3 -0
  111. package/dest/l1_tx_utils/interfaces.d.ts +2 -2
  112. package/dest/l1_tx_utils/interfaces.d.ts.map +1 -1
  113. package/dest/l1_tx_utils/l1_fee_analyzer.d.ts +233 -0
  114. package/dest/l1_tx_utils/l1_fee_analyzer.d.ts.map +1 -0
  115. package/dest/l1_tx_utils/l1_fee_analyzer.js +506 -0
  116. package/dest/l1_tx_utils/l1_tx_utils.d.ts +16 -8
  117. package/dest/l1_tx_utils/l1_tx_utils.d.ts.map +1 -1
  118. package/dest/l1_tx_utils/l1_tx_utils.js +64 -46
  119. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts +19 -30
  120. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts.map +1 -1
  121. package/dest/l1_tx_utils/readonly_l1_tx_utils.js +55 -163
  122. package/dest/l1_tx_utils/signer.d.ts +1 -1
  123. package/dest/l1_tx_utils/tx_delayer.d.ts +56 -0
  124. package/dest/l1_tx_utils/tx_delayer.d.ts.map +1 -0
  125. package/dest/{test → l1_tx_utils}/tx_delayer.js +65 -36
  126. package/dest/l1_tx_utils/types.d.ts +1 -1
  127. package/dest/l1_tx_utils/types.d.ts.map +1 -1
  128. package/dest/l1_tx_utils/utils.d.ts +1 -1
  129. package/dest/l1_types.d.ts +1 -1
  130. package/dest/publisher_manager.d.ts +3 -2
  131. package/dest/publisher_manager.d.ts.map +1 -1
  132. package/dest/publisher_manager.js +2 -2
  133. package/dest/queries.d.ts +2 -2
  134. package/dest/queries.d.ts.map +1 -1
  135. package/dest/queries.js +16 -6
  136. package/dest/test/chain_monitor.d.ts +27 -24
  137. package/dest/test/chain_monitor.d.ts.map +1 -1
  138. package/dest/test/chain_monitor.js +33 -36
  139. package/dest/test/eth_cheat_codes.d.ts +11 -3
  140. package/dest/test/eth_cheat_codes.d.ts.map +1 -1
  141. package/dest/test/eth_cheat_codes.js +11 -3
  142. package/dest/test/eth_cheat_codes_with_state.d.ts +1 -1
  143. package/dest/test/eth_cheat_codes_with_state.d.ts.map +1 -1
  144. package/dest/test/index.d.ts +1 -3
  145. package/dest/test/index.d.ts.map +1 -1
  146. package/dest/test/index.js +0 -2
  147. package/dest/test/rollup_cheat_codes.d.ts +17 -13
  148. package/dest/test/rollup_cheat_codes.d.ts.map +1 -1
  149. package/dest/test/rollup_cheat_codes.js +62 -38
  150. package/dest/test/start_anvil.d.ts +11 -2
  151. package/dest/test/start_anvil.d.ts.map +1 -1
  152. package/dest/test/start_anvil.js +128 -28
  153. package/dest/test/upgrade_utils.d.ts +1 -1
  154. package/dest/test/upgrade_utils.js +2 -2
  155. package/dest/types.d.ts +57 -2
  156. package/dest/types.d.ts.map +1 -1
  157. package/dest/utils.d.ts +16 -3
  158. package/dest/utils.d.ts.map +1 -1
  159. package/dest/utils.js +64 -0
  160. package/dest/zkPassportVerifierAddress.d.ts +1 -1
  161. package/package.json +34 -16
  162. package/src/client.ts +2 -2
  163. package/src/config.ts +74 -460
  164. package/src/contracts/README.md +157 -0
  165. package/src/contracts/empire_base.ts +8 -5
  166. package/src/contracts/empire_slashing_proposer.ts +38 -32
  167. package/src/contracts/fee_asset_handler.ts +10 -7
  168. package/src/contracts/fee_asset_price_oracle.ts +280 -0
  169. package/src/contracts/governance.ts +13 -4
  170. package/src/contracts/governance_proposer.ts +26 -6
  171. package/src/contracts/inbox.ts +55 -3
  172. package/src/contracts/index.ts +3 -0
  173. package/src/contracts/log.ts +13 -0
  174. package/src/contracts/multicall.ts +5 -2
  175. package/src/contracts/outbox.ts +98 -0
  176. package/src/contracts/rollup.ts +446 -167
  177. package/src/contracts/tally_slashing_proposer.ts +15 -8
  178. package/src/deploy_aztec_l1_contracts.ts +650 -0
  179. package/src/deploy_l1_contract.ts +362 -0
  180. package/src/forwarder_proxy.ts +108 -0
  181. package/src/generated/l1-contracts-defaults.ts +32 -0
  182. package/src/l1_contract_addresses.ts +22 -20
  183. package/src/l1_reader.ts +8 -0
  184. package/src/l1_tx_utils/config.ts +52 -11
  185. package/src/l1_tx_utils/constants.ts +13 -2
  186. package/src/l1_tx_utils/factory.ts +31 -31
  187. package/src/l1_tx_utils/fee-strategies/index.ts +22 -0
  188. package/src/l1_tx_utils/fee-strategies/p75_competitive.ts +163 -0
  189. package/src/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.ts +245 -0
  190. package/src/l1_tx_utils/fee-strategies/types.ts +56 -0
  191. package/src/l1_tx_utils/forwarder_l1_tx_utils.ts +108 -0
  192. package/src/l1_tx_utils/index-blobs.ts +2 -0
  193. package/src/l1_tx_utils/index.ts +3 -0
  194. package/src/l1_tx_utils/interfaces.ts +1 -1
  195. package/src/l1_tx_utils/l1_fee_analyzer.ts +803 -0
  196. package/src/l1_tx_utils/l1_tx_utils.ts +71 -36
  197. package/src/l1_tx_utils/readonly_l1_tx_utils.ts +69 -209
  198. package/src/{test → l1_tx_utils}/tx_delayer.ts +82 -52
  199. package/src/publisher_manager.ts +4 -2
  200. package/src/queries.ts +17 -6
  201. package/src/test/chain_monitor.ts +51 -49
  202. package/src/test/eth_cheat_codes.ts +9 -3
  203. package/src/test/index.ts +0 -2
  204. package/src/test/rollup_cheat_codes.ts +63 -43
  205. package/src/test/start_anvil.ts +148 -27
  206. package/src/test/upgrade_utils.ts +2 -2
  207. package/src/types.ts +62 -0
  208. package/src/utils.ts +83 -1
  209. package/dest/deploy_l1_contracts.d.ts +0 -226
  210. package/dest/deploy_l1_contracts.d.ts.map +0 -1
  211. package/dest/deploy_l1_contracts.js +0 -1473
  212. package/dest/index.d.ts +0 -18
  213. package/dest/index.d.ts.map +0 -1
  214. package/dest/index.js +0 -17
  215. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts +0 -26
  216. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts.map +0 -1
  217. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.js +0 -26
  218. package/dest/test/delayed_tx_utils.d.ts +0 -13
  219. package/dest/test/delayed_tx_utils.d.ts.map +0 -1
  220. package/dest/test/delayed_tx_utils.js +0 -28
  221. package/dest/test/tx_delayer.d.ts +0 -36
  222. package/dest/test/tx_delayer.d.ts.map +0 -1
  223. package/src/deploy_l1_contracts.ts +0 -1849
  224. package/src/index.ts +0 -17
  225. package/src/l1_tx_utils/l1_tx_utils_with_blobs.ts +0 -77
  226. package/src/test/delayed_tx_utils.ts +0 -52
@@ -1,6 +1,11 @@
1
+ import { CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
2
+ import { Buffer32 } from '@aztec/foundation/buffer';
3
+ import { Fr } from '@aztec/foundation/curves/bn254';
1
4
  import { memoize } from '@aztec/foundation/decorators';
2
5
  import { EthAddress } from '@aztec/foundation/eth-address';
3
6
  import type { ViemSignature } from '@aztec/foundation/eth-signature';
7
+ import { makeBackoff, retry } from '@aztec/foundation/retry';
8
+ import { EscapeHatchAbi } from '@aztec/l1-artifacts/EscapeHatchAbi';
4
9
  import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
5
10
  import { RollupStorage } from '@aztec/l1-artifacts/RollupStorage';
6
11
 
@@ -18,7 +23,7 @@ import {
18
23
  } from 'viem';
19
24
 
20
25
  import { getPublicClient } from '../client.js';
21
- import type { DeployL1ContractsReturnType } from '../deploy_l1_contracts.js';
26
+ import type { DeployAztecL1ContractsReturnType } from '../deploy_aztec_l1_contracts.js';
22
27
  import type { L1ContractAddresses } from '../l1_contract_addresses.js';
23
28
  import type { L1ReaderConfig } from '../l1_reader.js';
24
29
  import type { L1TxRequest, L1TxUtils } from '../l1_tx_utils/index.js';
@@ -26,6 +31,7 @@ import type { ViemClient } from '../types.js';
26
31
  import { formatViemError } from '../utils.js';
27
32
  import { EmpireSlashingProposerContract } from './empire_slashing_proposer.js';
28
33
  import { GSEContract } from './gse.js';
34
+ import type { L1EventLog } from './log.js';
29
35
  import { SlasherContract } from './slasher_contract.js';
30
36
  import { TallySlashingProposerContract } from './tally_slashing_proposer.js';
31
37
  import { checkBlockTag } from './utils.js';
@@ -56,12 +62,16 @@ export type L1RollupContractAddresses = Pick<
56
62
  export type EpochProofPublicInputArgs = {
57
63
  previousArchive: `0x${string}`;
58
64
  endArchive: `0x${string}`;
65
+ outHash: `0x${string}`;
59
66
  proverId: `0x${string}`;
60
67
  };
61
68
 
62
69
  export type ViemHeader = {
63
70
  lastArchiveRoot: `0x${string}`;
64
- contentCommitment: ViemContentCommitment;
71
+ blockHeadersHash: `0x${string}`;
72
+ blobsHash: `0x${string}`;
73
+ inHash: `0x${string}`;
74
+ outHash: `0x${string}`;
65
75
  slotNumber: bigint;
66
76
  timestamp: bigint;
67
77
  coinbase: `0x${string}`;
@@ -70,43 +80,136 @@ export type ViemHeader = {
70
80
  totalManaUsed: bigint;
71
81
  };
72
82
 
73
- export type ViemContentCommitment = {
74
- blobsHash: `0x${string}`;
75
- inHash: `0x${string}`;
76
- outHash: `0x${string}`;
77
- };
78
-
79
83
  export type ViemGasFees = {
80
84
  feePerDaGas: bigint;
81
85
  feePerL2Gas: bigint;
82
86
  };
83
87
 
84
- export type ViemStateReference = {
85
- l1ToL2MessageTree: ViemAppendOnlyTreeSnapshot;
86
- partialStateReference: ViemPartialStateReference;
88
+ export enum SlashingProposerType {
89
+ None = 0,
90
+ Tally = 1,
91
+ Empire = 2,
92
+ }
93
+
94
+ /**
95
+ * Status of a validator/attester in the staking system.
96
+ * Matches the Status enum in StakingLib.sol
97
+ */
98
+ export enum AttesterStatus {
99
+ NONE = 0,
100
+ VALIDATING = 1,
101
+ ZOMBIE = 2,
102
+ EXITING = 3,
103
+ }
104
+
105
+ /**
106
+ * Fee header data for a checkpoint
107
+ */
108
+ export type FeeHeader = {
109
+ excessMana: bigint;
110
+ manaUsed: bigint;
111
+ ethPerFeeAsset: bigint;
112
+ congestionCost: bigint;
113
+ proverCost: bigint;
87
114
  };
88
115
 
89
- export type ViemPartialStateReference = {
90
- noteHashTree: ViemAppendOnlyTreeSnapshot;
91
- nullifierTree: ViemAppendOnlyTreeSnapshot;
92
- publicDataTree: ViemAppendOnlyTreeSnapshot;
116
+ /**
117
+ * Checkpoint log data returned from the rollup contract
118
+ */
119
+ export type CheckpointLog = {
120
+ archive: Fr;
121
+ headerHash: Buffer32;
122
+ blobCommitmentsHash: Buffer32;
123
+ attestationsHash: Buffer32;
124
+ payloadDigest: Buffer32;
125
+ slotNumber: SlotNumber;
126
+ feeHeader: FeeHeader;
93
127
  };
94
128
 
95
- export type ViemAppendOnlyTreeSnapshot = {
96
- root: `0x${string}`;
97
- nextAvailableLeafIndex: number;
129
+ /**
130
+ * L1 fee data (base fee and blob fee)
131
+ */
132
+ export type L1FeeData = {
133
+ baseFee: bigint;
134
+ blobFee: bigint;
98
135
  };
99
136
 
100
- export enum SlashingProposerType {
101
- None = 0,
102
- Tally = 1,
103
- Empire = 2,
104
- }
137
+ /**
138
+ * Reward configuration for the rollup
139
+ */
140
+ export type RewardConfig = {
141
+ rewardDistributor: EthAddress;
142
+ sequencerBps: bigint;
143
+ booster: EthAddress;
144
+ checkpointReward: bigint;
145
+ };
146
+
147
+ /**
148
+ * Exit information for a validator
149
+ */
150
+ export type Exit = {
151
+ withdrawalId: bigint;
152
+ amount: bigint;
153
+ exitableAt: bigint;
154
+ recipientOrWithdrawer: EthAddress;
155
+ isRecipient: boolean;
156
+ exists: boolean;
157
+ };
158
+
159
+ /**
160
+ * Attester configuration including public key and withdrawer
161
+ */
162
+ export type AttesterConfig = {
163
+ publicKey: {
164
+ x: bigint;
165
+ y: bigint;
166
+ };
167
+ withdrawer: EthAddress;
168
+ };
169
+
170
+ /**
171
+ * Complete view of an attester's state
172
+ */
173
+ export type AttesterView = {
174
+ status: AttesterStatus;
175
+ effectiveBalance: bigint;
176
+ exit: Exit;
177
+ config: AttesterConfig;
178
+ };
179
+
180
+ /**
181
+ * Return for a status call
182
+ */
183
+ export type RollupStatusResponse = {
184
+ provenCheckpointNumber: CheckpointNumber;
185
+ provenArchive: Fr;
186
+ pendingCheckpointNumber: CheckpointNumber;
187
+ pendingArchive: Fr;
188
+ archiveOfMyCheckpoint: Fr;
189
+ };
190
+
191
+ /** Arguments for the CheckpointProposed event. */
192
+ export type CheckpointProposedArgs = {
193
+ checkpointNumber: CheckpointNumber;
194
+ archive: Fr;
195
+ versionedBlobHashes: Buffer[];
196
+ /** Hash of attestations emitted in the CheckpointProposed event. */
197
+ attestationsHash: Buffer32;
198
+ /** Digest of the payload emitted in the CheckpointProposed event. */
199
+ payloadDigest: Buffer32;
200
+ };
201
+
202
+ /** Log type for CheckpointProposed events. */
203
+ export type CheckpointProposedLog = L1EventLog<CheckpointProposedArgs>;
105
204
 
106
205
  export class RollupContract {
107
206
  private readonly rollup: GetContractReturnType<typeof RollupAbi, ViemClient>;
108
207
 
109
208
  private static cachedStfStorageSlot: Hex | undefined;
209
+ private cachedEscapeHatch?: {
210
+ address: EthAddress;
211
+ contract: GetContractReturnType<typeof EscapeHatchAbi, ViemClient>;
212
+ };
110
213
 
111
214
  static get checkBlobStorageSlot(): bigint {
112
215
  const asString = RollupStorage.find(storage => storage.label === 'checkBlob')?.slot;
@@ -120,7 +223,7 @@ export class RollupContract {
120
223
  return (RollupContract.cachedStfStorageSlot ??= keccak256(Buffer.from('aztec.stf.storage', 'utf-8')));
121
224
  }
122
225
 
123
- static getFromL1ContractsValues(deployL1ContractsValues: DeployL1ContractsReturnType) {
226
+ static getFromL1ContractsValues(deployL1ContractsValues: DeployAztecL1ContractsReturnType) {
124
227
  const {
125
228
  l1Client,
126
229
  l1ContractAddresses: { rollupAddress },
@@ -144,8 +247,8 @@ export class RollupContract {
144
247
  this.rollup = getContract({ address, abi: RollupAbi, client });
145
248
  }
146
249
 
147
- getGSE() {
148
- return this.rollup.read.getGSE();
250
+ async getGSE(): Promise<EthAddress> {
251
+ return EthAddress.fromString(await this.rollup.read.getGSE());
149
252
  }
150
253
 
151
254
  public get address() {
@@ -187,88 +290,93 @@ export class RollupContract {
187
290
  }
188
291
 
189
292
  @memoize
190
- getL1StartBlock() {
293
+ getL1StartBlock(): Promise<bigint> {
191
294
  return this.rollup.read.L1_BLOCK_AT_GENESIS();
192
295
  }
193
296
 
194
297
  @memoize
195
- getL1GenesisTime() {
298
+ getL1GenesisTime(): Promise<bigint> {
196
299
  return this.rollup.read.getGenesisTime();
197
300
  }
198
301
 
199
302
  @memoize
200
- getProofSubmissionEpochs() {
201
- return this.rollup.read.getProofSubmissionEpochs();
303
+ async getProofSubmissionEpochs(): Promise<number> {
304
+ return Number(await this.rollup.read.getProofSubmissionEpochs());
202
305
  }
203
306
 
204
307
  @memoize
205
- getEpochDuration() {
206
- return this.rollup.read.getEpochDuration();
308
+ async getEpochDuration(): Promise<number> {
309
+ return Number(await this.rollup.read.getEpochDuration());
207
310
  }
208
311
 
209
312
  @memoize
210
- getSlotDuration() {
211
- return this.rollup.read.getSlotDuration();
313
+ async getSlotDuration(): Promise<number> {
314
+ return Number(await this.rollup.read.getSlotDuration());
212
315
  }
213
316
 
214
317
  @memoize
215
- getTargetCommitteeSize() {
216
- return this.rollup.read.getTargetCommitteeSize();
318
+ async getTargetCommitteeSize(): Promise<number> {
319
+ return Number(await this.rollup.read.getTargetCommitteeSize());
217
320
  }
218
321
 
219
322
  @memoize
220
- getEjectionThreshold() {
323
+ getEjectionThreshold(): Promise<bigint> {
221
324
  return this.rollup.read.getEjectionThreshold();
222
325
  }
223
326
 
224
327
  @memoize
225
- getLocalEjectionThreshold() {
328
+ getLocalEjectionThreshold(): Promise<bigint> {
226
329
  return this.rollup.read.getLocalEjectionThreshold();
227
330
  }
228
331
 
229
332
  @memoize
230
- getLagInEpochs() {
231
- return this.rollup.read.getLagInEpochs();
333
+ async getLagInEpochsForValidatorSet(): Promise<number> {
334
+ return Number(await this.rollup.read.getLagInEpochsForValidatorSet());
232
335
  }
233
336
 
234
337
  @memoize
235
- getActivationThreshold() {
338
+ async getLagInEpochsForRandao(): Promise<number> {
339
+ return Number(await this.rollup.read.getLagInEpochsForRandao());
340
+ }
341
+
342
+ @memoize
343
+ getActivationThreshold(): Promise<bigint> {
236
344
  return this.rollup.read.getActivationThreshold();
237
345
  }
238
346
 
239
347
  @memoize
240
- getExitDelay() {
241
- return this.rollup.read.getExitDelay();
348
+ async getExitDelay(): Promise<number> {
349
+ return Number(await this.rollup.read.getExitDelay());
242
350
  }
243
351
 
244
352
  @memoize
245
- getManaTarget() {
353
+ getManaTarget(): Promise<bigint> {
246
354
  return this.rollup.read.getManaTarget();
247
355
  }
248
356
 
249
357
  @memoize
250
- getProvingCostPerMana() {
358
+ getProvingCostPerMana(): Promise<bigint> {
251
359
  return this.rollup.read.getProvingCostPerManaInEth();
252
360
  }
253
361
 
254
362
  @memoize
255
- getProvingCostPerManaInFeeAsset() {
363
+ getProvingCostPerManaInFeeAsset(): Promise<bigint> {
256
364
  return this.rollup.read.getProvingCostPerManaInFeeAsset();
257
365
  }
258
366
 
259
367
  @memoize
260
- getManaLimit() {
368
+ getManaLimit(): Promise<bigint> {
261
369
  return this.rollup.read.getManaLimit();
262
370
  }
263
371
 
264
372
  @memoize
265
- getVersion() {
373
+ getVersion(): Promise<bigint> {
266
374
  return this.rollup.read.getVersion();
267
375
  }
268
376
 
269
377
  @memoize
270
- async getGenesisArchiveTreeRoot(): Promise<`0x${string}`> {
271
- return await this.rollup.read.archiveAt([0n]);
378
+ async getGenesisArchiveTreeRoot(): Promise<Fr> {
379
+ return Fr.fromString(await this.rollup.read.archiveAt([0n]));
272
380
  }
273
381
 
274
382
  /**
@@ -283,44 +391,100 @@ export class RollupContract {
283
391
  slotDuration: number;
284
392
  epochDuration: number;
285
393
  proofSubmissionEpochs: number;
394
+ targetCommitteeSize: number;
286
395
  }> {
287
- const [l1StartBlock, l1GenesisTime, slotDuration, epochDuration, proofSubmissionEpochs] = await Promise.all([
288
- this.getL1StartBlock(),
289
- this.getL1GenesisTime(),
290
- this.getSlotDuration(),
291
- this.getEpochDuration(),
292
- this.getProofSubmissionEpochs(),
293
- ]);
396
+ const [l1StartBlock, l1GenesisTime, slotDuration, epochDuration, proofSubmissionEpochs, targetCommitteeSize] =
397
+ await Promise.all([
398
+ this.getL1StartBlock(),
399
+ this.getL1GenesisTime(),
400
+ this.getSlotDuration(),
401
+ this.getEpochDuration(),
402
+ this.getProofSubmissionEpochs(),
403
+ this.getTargetCommitteeSize(),
404
+ ]);
294
405
  return {
295
406
  l1StartBlock,
296
407
  l1GenesisTime,
297
- slotDuration: Number(slotDuration),
408
+ slotDuration,
298
409
  epochDuration: Number(epochDuration),
299
410
  proofSubmissionEpochs: Number(proofSubmissionEpochs),
411
+ targetCommitteeSize,
300
412
  };
301
413
  }
302
414
 
303
- getSlasherAddress() {
304
- return this.rollup.read.getSlasher();
415
+ async getSlasherAddress(): Promise<EthAddress> {
416
+ return EthAddress.fromString(await this.rollup.read.getSlasher());
417
+ }
418
+
419
+ /**
420
+ * Returns the configured escape hatch contract address, or zero if disabled.
421
+ */
422
+ async getEscapeHatchAddress(): Promise<EthAddress> {
423
+ return EthAddress.fromString(await this.rollup.read.getEscapeHatch());
424
+ }
425
+
426
+ private async getEscapeHatchContract(): Promise<
427
+ GetContractReturnType<typeof EscapeHatchAbi, ViemClient> | undefined
428
+ > {
429
+ const escapeHatchAddress = await this.getEscapeHatchAddress();
430
+ if (escapeHatchAddress.isZero()) {
431
+ return undefined;
432
+ }
433
+
434
+ // Cache the viem contract wrapper since it will be used frequently.
435
+ if (!this.cachedEscapeHatch || !this.cachedEscapeHatch.address.equals(escapeHatchAddress)) {
436
+ this.cachedEscapeHatch = {
437
+ address: escapeHatchAddress,
438
+ contract: getContract({
439
+ address: escapeHatchAddress.toString(),
440
+ abi: EscapeHatchAbi,
441
+ client: this.client,
442
+ }),
443
+ };
444
+ }
445
+
446
+ return this.cachedEscapeHatch.contract;
447
+ }
448
+
449
+ /**
450
+ * Returns whether the escape hatch is open for the given epoch.
451
+ * If escape hatch is not configured, returns false.
452
+ *
453
+ * This function is intentionally defensive: any failure to query the escape hatch
454
+ * (RPC issues, transient errors, etc.) is treated as "closed" to avoid callers
455
+ * needing to sprinkle try/catch everywhere.
456
+ */
457
+ async isEscapeHatchOpen(epoch: EpochNumber): Promise<boolean> {
458
+ try {
459
+ const escapeHatch = await this.getEscapeHatchContract();
460
+ if (!escapeHatch) {
461
+ return false;
462
+ }
463
+
464
+ const [isOpen] = await escapeHatch.read.isHatchOpen([BigInt(epoch)]);
465
+ return isOpen;
466
+ } catch {
467
+ return false;
468
+ }
305
469
  }
306
470
 
307
471
  /**
308
472
  * Returns a SlasherContract instance for interacting with the slasher contract.
309
473
  */
310
474
  async getSlasherContract(): Promise<SlasherContract | undefined> {
311
- const slasherAddress = EthAddress.fromString(await this.getSlasherAddress());
475
+ const slasherAddress = await this.getSlasherAddress();
312
476
  if (slasherAddress.isZero()) {
313
477
  return undefined;
314
478
  }
315
479
  return new SlasherContract(this.client, slasherAddress);
316
480
  }
317
481
 
318
- getOwner() {
319
- return this.rollup.read.owner();
482
+ async getOwner(): Promise<EthAddress> {
483
+ return EthAddress.fromString(await this.rollup.read.owner());
320
484
  }
321
485
 
322
- getActiveAttesterCount() {
323
- return this.rollup.read.getActiveAttesterCount();
486
+ async getActiveAttesterCount(): Promise<number> {
487
+ return Number(await this.rollup.read.getActiveAttesterCount());
324
488
  }
325
489
 
326
490
  public async getSlashingProposerAddress() {
@@ -331,31 +495,35 @@ export class RollupContract {
331
495
  return await slasher.getProposer();
332
496
  }
333
497
 
334
- getBlockReward() {
335
- return this.rollup.read.getBlockReward();
498
+ getCheckpointReward(): Promise<bigint> {
499
+ return this.rollup.read.getCheckpointReward();
336
500
  }
337
501
 
338
- getBlockNumber() {
339
- return this.rollup.read.getPendingBlockNumber();
502
+ async getCheckpointNumber(): Promise<CheckpointNumber> {
503
+ return CheckpointNumber.fromBigInt(await this.rollup.read.getPendingCheckpointNumber());
340
504
  }
341
505
 
342
- getProvenBlockNumber() {
343
- return this.rollup.read.getProvenBlockNumber();
506
+ async getProvenCheckpointNumber(): Promise<CheckpointNumber> {
507
+ return CheckpointNumber.fromBigInt(await this.rollup.read.getProvenCheckpointNumber());
344
508
  }
345
509
 
346
- getSlotNumber() {
347
- return this.rollup.read.getCurrentSlot();
510
+ async getSlotNumber(): Promise<SlotNumber> {
511
+ return SlotNumber.fromBigInt(await this.rollup.read.getCurrentSlot());
348
512
  }
349
513
 
350
- getL1FeesAt(timestamp: bigint) {
351
- return this.rollup.read.getL1FeesAt([timestamp]);
514
+ async getL1FeesAt(timestamp: bigint): Promise<L1FeeData> {
515
+ const result = await this.rollup.read.getL1FeesAt([timestamp]);
516
+ return {
517
+ baseFee: result.baseFee,
518
+ blobFee: result.blobFee,
519
+ };
352
520
  }
353
521
 
354
- getFeeAssetPerEth() {
355
- return this.rollup.read.getFeeAssetPerEth();
522
+ getEthPerFeeAsset(): Promise<bigint> {
523
+ return this.rollup.read.getEthPerFeeAsset();
356
524
  }
357
525
 
358
- async getCommitteeAt(timestamp: bigint): Promise<readonly `0x${string}`[] | undefined> {
526
+ async getCommitteeAt(timestamp: bigint): Promise<EthAddress[] | undefined> {
359
527
  const { result } = await this.client
360
528
  .simulateContract({
361
529
  address: this.address,
@@ -370,22 +538,22 @@ export class RollupContract {
370
538
  throw e;
371
539
  });
372
540
 
373
- return result;
541
+ return result ? result.map(addr => EthAddress.fromString(addr)) : undefined;
374
542
  }
375
543
 
376
- getSampleSeedAt(timestamp: bigint) {
377
- return this.rollup.read.getSampleSeedAt([timestamp]);
544
+ async getSampleSeedAt(timestamp: bigint): Promise<Buffer32> {
545
+ return Buffer32.fromBigInt(await this.rollup.read.getSampleSeedAt([timestamp]));
378
546
  }
379
547
 
380
- getCurrentSampleSeed() {
381
- return this.rollup.read.getCurrentSampleSeed();
548
+ async getCurrentSampleSeed(): Promise<Buffer32> {
549
+ return Buffer32.fromBigInt(await this.rollup.read.getCurrentSampleSeed());
382
550
  }
383
551
 
384
- getCurrentEpoch() {
385
- return this.rollup.read.getCurrentEpoch();
552
+ async getCurrentEpoch(): Promise<EpochNumber> {
553
+ return EpochNumber.fromBigInt(await this.rollup.read.getCurrentEpoch());
386
554
  }
387
555
 
388
- async getCurrentEpochCommittee(): Promise<readonly `0x${string}`[] | undefined> {
556
+ async getCurrentEpochCommittee(): Promise<EthAddress[] | undefined> {
389
557
  const { result } = await this.client
390
558
  .simulateContract({
391
559
  address: this.address,
@@ -400,10 +568,10 @@ export class RollupContract {
400
568
  throw e;
401
569
  });
402
570
 
403
- return result;
571
+ return result ? result.map(addr => EthAddress.fromString(addr)) : undefined;
404
572
  }
405
573
 
406
- async getCurrentProposer() {
574
+ async getCurrentProposer(): Promise<EthAddress> {
407
575
  const { result } = await this.client.simulateContract({
408
576
  address: this.address,
409
577
  abi: RollupAbi,
@@ -411,10 +579,10 @@ export class RollupContract {
411
579
  args: [],
412
580
  });
413
581
 
414
- return result;
582
+ return EthAddress.fromString(result);
415
583
  }
416
584
 
417
- async getProposerAt(timestamp: bigint) {
585
+ async getProposerAt(timestamp: bigint): Promise<EthAddress> {
418
586
  const { result } = await this.client.simulateContract({
419
587
  address: this.address,
420
588
  abi: RollupAbi,
@@ -422,39 +590,73 @@ export class RollupContract {
422
590
  args: [timestamp],
423
591
  });
424
592
 
425
- return result;
593
+ return EthAddress.fromString(result);
426
594
  }
427
595
 
428
- getBlock(blockNumber: bigint | number) {
429
- return this.rollup.read.getBlock([BigInt(blockNumber)]);
596
+ async getCheckpoint(checkpointNumber: CheckpointNumber): Promise<CheckpointLog> {
597
+ const result = await this.rollup.read.getCheckpoint([BigInt(checkpointNumber)]);
598
+ return {
599
+ archive: Fr.fromString(result.archive),
600
+ headerHash: Buffer32.fromString(result.headerHash),
601
+ blobCommitmentsHash: Buffer32.fromString(result.blobCommitmentsHash),
602
+ attestationsHash: Buffer32.fromString(result.attestationsHash),
603
+ payloadDigest: Buffer32.fromString(result.payloadDigest),
604
+ slotNumber: SlotNumber.fromBigInt(result.slotNumber),
605
+ feeHeader: {
606
+ excessMana: result.feeHeader.excessMana,
607
+ manaUsed: result.feeHeader.manaUsed,
608
+ ethPerFeeAsset: result.feeHeader.ethPerFeeAsset,
609
+ congestionCost: result.feeHeader.congestionCost,
610
+ proverCost: result.feeHeader.proverCost,
611
+ },
612
+ };
430
613
  }
431
614
 
432
- getTips() {
433
- return this.rollup.read.getTips();
615
+ /** Returns the pending checkpoint from the rollup contract */
616
+ getPendingCheckpoint() {
617
+ // We retry because of race conditions during prunes: we may get a pending checkpoint number which is immediately
618
+ // reorged out due to a prune happening, causing the subsequent getCheckpoint call to fail. So we try again in that case.
619
+ return retry(
620
+ async () => {
621
+ const pendingCheckpointNumber = await this.getCheckpointNumber();
622
+ const pendingCheckpoint = await this.getCheckpoint(pendingCheckpointNumber);
623
+ return pendingCheckpoint;
624
+ },
625
+ 'getting pending checkpoint',
626
+ makeBackoff([0.5, 0.5, 0.5]),
627
+ );
628
+ }
629
+
630
+ async getTips(): Promise<{ pending: CheckpointNumber; proven: CheckpointNumber }> {
631
+ const { pending, proven } = await this.rollup.read.getTips();
632
+ return {
633
+ pending: CheckpointNumber.fromBigInt(pending),
634
+ proven: CheckpointNumber.fromBigInt(proven),
635
+ };
434
636
  }
435
637
 
436
- getTimestampForSlot(slot: bigint) {
437
- return this.rollup.read.getTimestampForSlot([slot]);
638
+ getTimestampForSlot(slot: SlotNumber): Promise<bigint> {
639
+ return this.rollup.read.getTimestampForSlot([BigInt(slot)]);
438
640
  }
439
641
 
440
- getEntryQueueLength() {
441
- return this.rollup.read.getEntryQueueLength();
642
+ async getEntryQueueLength(): Promise<number> {
643
+ return Number(await this.rollup.read.getEntryQueueLength());
442
644
  }
443
645
 
444
- getAvailableValidatorFlushes() {
445
- return this.rollup.read.getAvailableValidatorFlushes();
646
+ async getAvailableValidatorFlushes(): Promise<number> {
647
+ return Number(await this.rollup.read.getAvailableValidatorFlushes());
446
648
  }
447
649
 
448
- getNextFlushableEpoch() {
449
- return this.rollup.read.getNextFlushableEpoch();
650
+ async getNextFlushableEpoch(): Promise<EpochNumber> {
651
+ return EpochNumber.fromBigInt(await this.rollup.read.getNextFlushableEpoch());
450
652
  }
451
653
 
452
- getCurrentEpochNumber(): Promise<bigint> {
453
- return this.rollup.read.getCurrentEpoch();
654
+ async getCurrentEpochNumber(): Promise<EpochNumber> {
655
+ return EpochNumber.fromBigInt(await this.rollup.read.getCurrentEpoch());
454
656
  }
455
657
 
456
- getEpochNumberForBlock(blockNumber: bigint) {
457
- return this.rollup.read.getEpochForBlock([BigInt(blockNumber)]);
658
+ async getEpochNumberForCheckpoint(checkpointNumber: CheckpointNumber): Promise<EpochNumber> {
659
+ return EpochNumber.fromBigInt(await this.rollup.read.getEpochForCheckpoint([BigInt(checkpointNumber)]));
458
660
  }
459
661
 
460
662
  async getRollupAddresses(): Promise<L1RollupContractAddresses> {
@@ -494,14 +696,15 @@ export class RollupContract {
494
696
  return EthAddress.fromString(await this.rollup.read.getFeeAssetPortal());
495
697
  }
496
698
 
497
- public async getEpochNumberForSlotNumber(slotNumber: bigint): Promise<bigint> {
498
- return await this.rollup.read.getEpochAtSlot([slotNumber]);
699
+ public async getEpochNumberForSlotNumber(slotNumber: SlotNumber): Promise<EpochNumber> {
700
+ return EpochNumber.fromBigInt(await this.rollup.read.getEpochAtSlot([BigInt(slotNumber)]));
499
701
  }
500
702
 
501
- getEpochProofPublicInputs(
703
+ async getEpochProofPublicInputs(
502
704
  args: readonly [bigint, bigint, EpochProofPublicInputArgs, readonly `0x${string}`[], `0x${string}`],
503
- ) {
504
- return this.rollup.read.getEpochProofPublicInputs(args);
705
+ ): Promise<Fr[]> {
706
+ const result = await this.rollup.read.getEpochProofPublicInputs(args);
707
+ return result.map(Fr.fromString);
505
708
  }
506
709
 
507
710
  public async validateHeader(
@@ -538,53 +741,57 @@ export class RollupContract {
538
741
  * @dev Throws if unable to propose
539
742
  *
540
743
  * @param archive - The archive that we expect to be current state
541
- * @return [slot, blockNumber] - If you can propose, the L2 slot number and L2 block number of the next Ethereum block,
744
+ * @return [slot, checkpointNumber, timeOfNextL1Slot] - If you can propose, the L2 slot number, checkpoint number and
745
+ * timestamp of the next L1 block
542
746
  * @throws otherwise
543
747
  */
544
748
  public async canProposeAtNextEthBlock(
545
749
  archive: Buffer,
546
750
  account: `0x${string}` | Account,
547
- slotDuration: bigint | number,
548
- opts: { forcePendingBlockNumber?: number } = {},
549
- ): Promise<{ slot: bigint; blockNumber: bigint; timeOfNextL1Slot: bigint }> {
550
- if (typeof slotDuration === 'number') {
551
- slotDuration = BigInt(slotDuration);
552
- }
751
+ slotDuration: number,
752
+ opts: { forcePendingCheckpointNumber?: CheckpointNumber } = {},
753
+ ): Promise<{ slot: SlotNumber; checkpointNumber: CheckpointNumber; timeOfNextL1Slot: bigint }> {
553
754
  const latestBlock = await this.client.getBlock();
554
- const timeOfNextL1Slot = latestBlock.timestamp + slotDuration;
755
+ const timeOfNextL1Slot = latestBlock.timestamp + BigInt(slotDuration);
555
756
  const who = typeof account === 'string' ? account : account.address;
556
757
 
557
758
  try {
558
759
  const {
559
- result: [slot, blockNumber],
760
+ result: [slot, checkpointNumber],
560
761
  } = await this.client.simulateContract({
561
762
  address: this.address,
562
763
  abi: RollupAbi,
563
764
  functionName: 'canProposeAtTime',
564
765
  args: [timeOfNextL1Slot, `0x${archive.toString('hex')}`, who],
565
766
  account,
566
- stateOverride: await this.makePendingBlockNumberOverride(opts.forcePendingBlockNumber),
767
+ stateOverride: await this.makePendingCheckpointNumberOverride(opts.forcePendingCheckpointNumber),
567
768
  });
568
769
 
569
- return { slot, blockNumber, timeOfNextL1Slot };
770
+ return {
771
+ slot: SlotNumber.fromBigInt(slot),
772
+ checkpointNumber: CheckpointNumber.fromBigInt(checkpointNumber),
773
+ timeOfNextL1Slot,
774
+ };
570
775
  } catch (err: unknown) {
571
776
  throw formatViemError(err);
572
777
  }
573
778
  }
574
779
 
575
780
  /**
576
- * Returns a state override that sets the pending block number to the specified value. Useful for simulations.
577
- * Requires querying the current state of the contract to get the current proven block number, as they are both
781
+ * Returns a state override that sets the pending checkpoint number to the specified value. Useful for simulations.
782
+ * Requires querying the current state of the contract to get the current proven checkpoint number, as they are both
578
783
  * stored in the same slot. If the argument is undefined, it returns an empty override.
579
784
  */
580
- public async makePendingBlockNumberOverride(forcePendingBlockNumber: number | undefined): Promise<StateOverride> {
581
- if (forcePendingBlockNumber === undefined) {
785
+ public async makePendingCheckpointNumberOverride(
786
+ forcePendingCheckpointNumber: CheckpointNumber | undefined,
787
+ ): Promise<StateOverride> {
788
+ if (forcePendingCheckpointNumber === undefined) {
582
789
  return [];
583
790
  }
584
791
  const slot = RollupContract.stfStorageSlot;
585
792
  const currentValue = await this.client.getStorageAt({ address: this.address, slot });
586
- const currentProvenBlockNumber = currentValue ? hexToBigInt(currentValue) & ((1n << 128n) - 1n) : 0n;
587
- const newValue = (BigInt(forcePendingBlockNumber) << 128n) | currentProvenBlockNumber;
793
+ const currentProvenCheckpointNumber = currentValue ? hexToBigInt(currentValue) & ((1n << 128n) - 1n) : 0n;
794
+ const newValue = (BigInt(forcePendingCheckpointNumber) << 128n) | currentProvenCheckpointNumber;
588
795
  return [
589
796
  {
590
797
  address: this.address,
@@ -595,18 +802,19 @@ export class RollupContract {
595
802
 
596
803
  /** Creates a request to Rollup#invalidateBadAttestation to be simulated or sent */
597
804
  public buildInvalidateBadAttestationRequest(
598
- blockNumber: number,
805
+ checkpointNumber: CheckpointNumber,
599
806
  attestationsAndSigners: ViemCommitteeAttestations,
600
807
  committee: EthAddress[],
601
808
  invalidIndex: number,
602
809
  ): L1TxRequest {
603
810
  return {
604
811
  to: this.address,
812
+ abi: RollupAbi,
605
813
  data: encodeFunctionData({
606
814
  abi: RollupAbi,
607
815
  functionName: 'invalidateBadAttestation',
608
816
  args: [
609
- BigInt(blockNumber),
817
+ BigInt(checkpointNumber),
610
818
  attestationsAndSigners,
611
819
  committee.map(addr => addr.toString()),
612
820
  BigInt(invalidIndex),
@@ -617,112 +825,147 @@ export class RollupContract {
617
825
 
618
826
  /** Creates a request to Rollup#invalidateInsufficientAttestations to be simulated or sent */
619
827
  public buildInvalidateInsufficientAttestationsRequest(
620
- blockNumber: number,
828
+ checkpointNumber: CheckpointNumber,
621
829
  attestationsAndSigners: ViemCommitteeAttestations,
622
830
  committee: EthAddress[],
623
831
  ): L1TxRequest {
624
832
  return {
625
833
  to: this.address,
834
+ abi: RollupAbi,
626
835
  data: encodeFunctionData({
627
836
  abi: RollupAbi,
628
837
  functionName: 'invalidateInsufficientAttestations',
629
- args: [BigInt(blockNumber), attestationsAndSigners, committee.map(addr => addr.toString())],
838
+ args: [BigInt(checkpointNumber), attestationsAndSigners, committee.map(addr => addr.toString())],
630
839
  }),
631
840
  };
632
841
  }
633
842
 
634
843
  /** Calls getHasSubmitted directly. Returns whether the given prover has submitted a proof with the given length for the given epoch. */
635
- public getHasSubmittedProof(epochNumber: number, numberOfBlocksInEpoch: number, prover: Hex | EthAddress) {
844
+ public getHasSubmittedProof(epochNumber: EpochNumber, numberOfCheckpointsInEpoch: number, prover: Hex | EthAddress) {
636
845
  if (prover instanceof EthAddress) {
637
846
  prover = prover.toString();
638
847
  }
639
- return this.rollup.read.getHasSubmitted([BigInt(epochNumber), BigInt(numberOfBlocksInEpoch), prover]);
848
+ return this.rollup.read.getHasSubmitted([BigInt(epochNumber), BigInt(numberOfCheckpointsInEpoch), prover]);
640
849
  }
641
850
 
642
- getManaBaseFeeAt(timestamp: bigint, inFeeAsset: boolean) {
643
- return this.rollup.read.getManaBaseFeeAt([timestamp, inFeeAsset]);
851
+ getManaMinFeeAt(timestamp: bigint, inFeeAsset: boolean): Promise<bigint> {
852
+ return this.rollup.read.getManaMinFeeAt([timestamp, inFeeAsset]);
644
853
  }
645
854
 
646
- getSlotAt(timestamp: bigint) {
647
- return this.rollup.read.getSlotAt([timestamp]);
855
+ async getSlotAt(timestamp: bigint): Promise<SlotNumber> {
856
+ return SlotNumber.fromBigInt(await this.rollup.read.getSlotAt([timestamp]));
648
857
  }
649
858
 
650
- async status(blockNumber: bigint, options?: { blockNumber?: bigint }) {
859
+ async status(checkpointNumber: CheckpointNumber, options?: { blockNumber?: bigint }): Promise<RollupStatusResponse> {
651
860
  await checkBlockTag(options?.blockNumber, this.client);
652
- return this.rollup.read.status([blockNumber], options);
861
+ const result = await this.rollup.read.status([BigInt(checkpointNumber)], options);
862
+ return {
863
+ provenCheckpointNumber: CheckpointNumber.fromBigInt(result[0]),
864
+ provenArchive: Fr.fromString(result[1]),
865
+ pendingCheckpointNumber: CheckpointNumber.fromBigInt(result[2]),
866
+ pendingArchive: Fr.fromString(result[3]),
867
+ archiveOfMyCheckpoint: Fr.fromString(result[4]),
868
+ };
653
869
  }
654
870
 
655
- async canPruneAtTime(timestamp: bigint, options?: { blockNumber?: bigint }) {
871
+ async canPruneAtTime(timestamp: bigint, options?: { blockNumber?: bigint }): Promise<boolean> {
656
872
  await checkBlockTag(options?.blockNumber, this.client);
657
873
  return this.rollup.read.canPruneAtTime([timestamp], options);
658
874
  }
659
875
 
660
- archive() {
661
- return this.rollup.read.archive();
876
+ async archive(): Promise<Fr> {
877
+ return Fr.fromString(await this.rollup.read.archive());
662
878
  }
663
879
 
664
- archiveAt(blockNumber: bigint) {
665
- return this.rollup.read.archiveAt([blockNumber]);
880
+ async archiveAt(checkpointNumber: CheckpointNumber): Promise<Fr> {
881
+ return Fr.fromString(await this.rollup.read.archiveAt([BigInt(checkpointNumber)]));
666
882
  }
667
883
 
668
- getSequencerRewards(address: Hex | EthAddress) {
884
+ getSequencerRewards(address: Hex | EthAddress): Promise<bigint> {
669
885
  if (address instanceof EthAddress) {
670
886
  address = address.toString();
671
887
  }
672
888
  return this.rollup.read.getSequencerRewards([address]);
673
889
  }
674
890
 
675
- getSpecificProverRewardsForEpoch(epoch: bigint, prover: Hex | EthAddress) {
891
+ getSpecificProverRewardsForEpoch(epoch: bigint, prover: Hex | EthAddress): Promise<bigint> {
676
892
  if (prover instanceof EthAddress) {
677
893
  prover = prover.toString();
678
894
  }
679
895
  return this.rollup.read.getSpecificProverRewardsForEpoch([epoch, prover]);
680
896
  }
681
897
 
682
- async getAttesters() {
898
+ async getAttesters(): Promise<EthAddress[]> {
683
899
  const attesterSize = await this.getActiveAttesterCount();
684
900
  const gse = new GSEContract(this.client, await this.getGSE());
685
901
  const ts = (await this.client.getBlock()).timestamp;
686
902
 
687
- const indices = Array.from({ length: Number(attesterSize) }, (_, i) => BigInt(i));
903
+ const indices = Array.from({ length: attesterSize }, (_, i) => BigInt(i));
688
904
  const chunks = chunk(indices, 1000);
689
905
 
690
- return (await Promise.all(chunks.map(chunk => gse.getAttestersFromIndicesAtTime(this.address, ts, chunk)))).flat();
906
+ const results = await Promise.all(chunks.map(chunk => gse.getAttestersFromIndicesAtTime(this.address, ts, chunk)));
907
+ return results.flat().map(addr => EthAddress.fromString(addr));
691
908
  }
692
909
 
693
- getAttesterView(address: Hex | EthAddress) {
910
+ async getAttesterView(address: Hex | EthAddress): Promise<AttesterView> {
694
911
  if (address instanceof EthAddress) {
695
912
  address = address.toString();
696
913
  }
697
- return this.rollup.read.getAttesterView([address]);
914
+ const result = await this.rollup.read.getAttesterView([address]);
915
+ return {
916
+ status: result.status as AttesterStatus,
917
+ effectiveBalance: result.effectiveBalance,
918
+ exit: {
919
+ withdrawalId: result.exit.withdrawalId,
920
+ amount: result.exit.amount,
921
+ exitableAt: result.exit.exitableAt,
922
+ recipientOrWithdrawer: EthAddress.fromString(result.exit.recipientOrWithdrawer),
923
+ isRecipient: result.exit.isRecipient,
924
+ exists: result.exit.exists,
925
+ },
926
+ config: {
927
+ publicKey: {
928
+ x: result.config.publicKey.x,
929
+ y: result.config.publicKey.y,
930
+ },
931
+ withdrawer: EthAddress.fromString(result.config.withdrawer),
932
+ },
933
+ };
698
934
  }
699
935
 
700
- getStatus(address: Hex | EthAddress) {
936
+ async getStatus(address: Hex | EthAddress): Promise<AttesterStatus> {
701
937
  if (address instanceof EthAddress) {
702
938
  address = address.toString();
703
939
  }
704
- return this.rollup.read.getStatus([address]);
940
+ return (await this.rollup.read.getStatus([address])) as AttesterStatus;
705
941
  }
706
942
 
707
- getBlobCommitmentsHash(blockNumber: bigint) {
708
- return this.rollup.read.getBlobCommitmentsHash([blockNumber]);
943
+ async getBlobCommitmentsHash(checkpointNumber: CheckpointNumber): Promise<Buffer32> {
944
+ return Buffer32.fromString(await this.rollup.read.getBlobCommitmentsHash([BigInt(checkpointNumber)]));
709
945
  }
710
946
 
711
- getCurrentBlobCommitmentsHash() {
712
- return this.rollup.read.getCurrentBlobCommitmentsHash();
947
+ async getCurrentBlobCommitmentsHash(): Promise<Buffer32> {
948
+ return Buffer32.fromString(await this.rollup.read.getCurrentBlobCommitmentsHash());
713
949
  }
714
950
 
715
- getStakingAsset() {
716
- return this.rollup.read.getStakingAsset();
951
+ async getStakingAsset(): Promise<EthAddress> {
952
+ return EthAddress.fromString(await this.rollup.read.getStakingAsset());
717
953
  }
718
954
 
719
- getRewardConfig() {
720
- return this.rollup.read.getRewardConfig();
955
+ async getRewardConfig(): Promise<RewardConfig> {
956
+ const result = await this.rollup.read.getRewardConfig();
957
+ return {
958
+ rewardDistributor: EthAddress.fromString(result.rewardDistributor),
959
+ sequencerBps: BigInt(result.sequencerBps),
960
+ booster: EthAddress.fromString(result.booster),
961
+ checkpointReward: result.checkpointReward,
962
+ };
721
963
  }
722
964
 
723
965
  setupEpoch(l1TxUtils: L1TxUtils) {
724
966
  return l1TxUtils.sendAndMonitorTransaction({
725
967
  to: this.address,
968
+ abi: RollupAbi,
726
969
  data: encodeFunctionData({
727
970
  abi: RollupAbi,
728
971
  functionName: 'setupEpoch',
@@ -734,6 +977,7 @@ export class RollupContract {
734
977
  vote(l1TxUtils: L1TxUtils, proposalId: bigint) {
735
978
  return l1TxUtils.sendAndMonitorTransaction({
736
979
  to: this.address,
980
+ abi: RollupAbi,
737
981
  data: encodeFunctionData({
738
982
  abi: RollupAbi,
739
983
  functionName: 'vote',
@@ -760,15 +1004,17 @@ export class RollupContract {
760
1004
  );
761
1005
  }
762
1006
 
763
- public listenToBlockInvalidated(callback: (args: { blockNumber: bigint }) => unknown): WatchContractEventReturnType {
764
- return this.rollup.watchEvent.BlockInvalidated(
1007
+ public listenToCheckpointInvalidated(
1008
+ callback: (args: { checkpointNumber: CheckpointNumber }) => unknown,
1009
+ ): WatchContractEventReturnType {
1010
+ return this.rollup.watchEvent.CheckpointInvalidated(
765
1011
  {},
766
1012
  {
767
1013
  onLogs: logs => {
768
1014
  for (const log of logs) {
769
1015
  const args = log.args;
770
- if (args.blockNumber !== undefined) {
771
- callback({ blockNumber: args.blockNumber });
1016
+ if (args.checkpointNumber !== undefined) {
1017
+ callback({ checkpointNumber: CheckpointNumber.fromBigInt(args.checkpointNumber) });
772
1018
  }
773
1019
  }
774
1020
  },
@@ -800,4 +1046,37 @@ export class RollupContract {
800
1046
  },
801
1047
  );
802
1048
  }
1049
+
1050
+ /** Fetches CheckpointProposed events within the given block range. */
1051
+ async getCheckpointProposedEvents(fromBlock: bigint, toBlock: bigint): Promise<CheckpointProposedLog[]> {
1052
+ const logs = await this.rollup.getEvents.CheckpointProposed({}, { fromBlock, toBlock });
1053
+ return logs
1054
+ .filter(log => log.blockNumber! >= fromBlock && log.blockNumber! <= toBlock)
1055
+ .map(log => ({
1056
+ l1BlockNumber: log.blockNumber!,
1057
+ l1BlockHash: Buffer32.fromString(log.blockHash!),
1058
+ l1TransactionHash: log.transactionHash!,
1059
+ args: {
1060
+ checkpointNumber: CheckpointNumber.fromBigInt(log.args.checkpointNumber!),
1061
+ archive: Fr.fromString(log.args.archive!),
1062
+ versionedBlobHashes: log.args.versionedBlobHashes!.map(h => Buffer.from(h.slice(2), 'hex')),
1063
+ attestationsHash: (() => {
1064
+ if (!log.args.attestationsHash) {
1065
+ throw new Error(
1066
+ `CheckpointProposed event missing attestationsHash for checkpoint ${log.args.checkpointNumber}`,
1067
+ );
1068
+ }
1069
+ return Buffer32.fromString(log.args.attestationsHash);
1070
+ })(),
1071
+ payloadDigest: (() => {
1072
+ if (!log.args.payloadDigest) {
1073
+ throw new Error(
1074
+ `CheckpointProposed event missing payloadDigest for checkpoint ${log.args.checkpointNumber}`,
1075
+ );
1076
+ }
1077
+ return Buffer32.fromString(log.args.payloadDigest);
1078
+ })(),
1079
+ },
1080
+ }));
1081
+ }
803
1082
  }