@aztec/ethereum 3.0.0-canary.a9708bd → 3.0.0-devnet.20251212

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 (195) hide show
  1. package/dest/account.d.ts +1 -1
  2. package/dest/chain.d.ts +1 -1
  3. package/dest/client.d.ts +2 -2
  4. package/dest/client.d.ts.map +1 -1
  5. package/dest/config.d.ts +16 -8
  6. package/dest/config.d.ts.map +1 -1
  7. package/dest/config.js +160 -62
  8. package/dest/constants.d.ts +1 -1
  9. package/dest/contracts/empire_base.d.ts +7 -6
  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 +7 -6
  13. package/dest/contracts/empire_slashing_proposer.d.ts.map +1 -1
  14. package/dest/contracts/empire_slashing_proposer.js +9 -3
  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 +4 -4
  18. package/dest/contracts/fee_asset_handler.d.ts.map +1 -1
  19. package/dest/contracts/fee_juice.d.ts +1 -1
  20. package/dest/contracts/fee_juice.d.ts.map +1 -1
  21. package/dest/contracts/governance.d.ts +16 -16
  22. package/dest/contracts/governance.d.ts.map +1 -1
  23. package/dest/contracts/governance.js +7 -3
  24. package/dest/contracts/governance_proposer.d.ts +6 -6
  25. package/dest/contracts/governance_proposer.d.ts.map +1 -1
  26. package/dest/contracts/governance_proposer.js +9 -4
  27. package/dest/contracts/gse.d.ts +1 -1
  28. package/dest/contracts/gse.d.ts.map +1 -1
  29. package/dest/contracts/inbox.d.ts +1 -1
  30. package/dest/contracts/inbox.d.ts.map +1 -1
  31. package/dest/contracts/index.d.ts +1 -1
  32. package/dest/contracts/multicall.d.ts +5 -7
  33. package/dest/contracts/multicall.d.ts.map +1 -1
  34. package/dest/contracts/multicall.js +6 -4
  35. package/dest/contracts/registry.d.ts +1 -1
  36. package/dest/contracts/registry.d.ts.map +1 -1
  37. package/dest/contracts/rollup.d.ts +83 -72
  38. package/dest/contracts/rollup.d.ts.map +1 -1
  39. package/dest/contracts/rollup.js +144 -139
  40. package/dest/contracts/slasher_contract.d.ts +11 -1
  41. package/dest/contracts/slasher_contract.d.ts.map +1 -1
  42. package/dest/contracts/slasher_contract.js +18 -0
  43. package/dest/contracts/tally_slashing_proposer.d.ts +30 -9
  44. package/dest/contracts/tally_slashing_proposer.d.ts.map +1 -1
  45. package/dest/contracts/tally_slashing_proposer.js +58 -8
  46. package/dest/contracts/utils.d.ts +1 -1
  47. package/dest/deploy_l1_contracts.d.ts +477 -15
  48. package/dest/deploy_l1_contracts.d.ts.map +1 -1
  49. package/dest/deploy_l1_contracts.js +610 -386
  50. package/dest/eth-signer/eth-signer.d.ts +1 -1
  51. package/dest/eth-signer/index.d.ts +1 -1
  52. package/dest/forwarder_proxy.d.ts +32 -0
  53. package/dest/forwarder_proxy.d.ts.map +1 -0
  54. package/dest/forwarder_proxy.js +93 -0
  55. package/dest/l1_artifacts.d.ts +14258 -6015
  56. package/dest/l1_artifacts.d.ts.map +1 -1
  57. package/dest/l1_artifacts.js +10 -5
  58. package/dest/l1_contract_addresses.d.ts +8 -4
  59. package/dest/l1_contract_addresses.d.ts.map +1 -1
  60. package/dest/l1_contract_addresses.js +16 -26
  61. package/dest/l1_reader.d.ts +4 -2
  62. package/dest/l1_reader.d.ts.map +1 -1
  63. package/dest/l1_reader.js +14 -8
  64. package/dest/l1_tx_utils/config.d.ts +59 -0
  65. package/dest/l1_tx_utils/config.d.ts.map +1 -0
  66. package/dest/l1_tx_utils/config.js +96 -0
  67. package/dest/l1_tx_utils/constants.d.ts +6 -0
  68. package/dest/l1_tx_utils/constants.d.ts.map +1 -0
  69. package/dest/l1_tx_utils/constants.js +14 -0
  70. package/dest/l1_tx_utils/factory.d.ts +24 -0
  71. package/dest/l1_tx_utils/factory.d.ts.map +1 -0
  72. package/dest/l1_tx_utils/factory.js +12 -0
  73. package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts +41 -0
  74. package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts.map +1 -0
  75. package/dest/l1_tx_utils/forwarder_l1_tx_utils.js +48 -0
  76. package/dest/l1_tx_utils/index-blobs.d.ts +3 -0
  77. package/dest/l1_tx_utils/index-blobs.d.ts.map +1 -0
  78. package/dest/l1_tx_utils/index-blobs.js +2 -0
  79. package/dest/l1_tx_utils/index.d.ts +10 -0
  80. package/dest/l1_tx_utils/index.d.ts.map +1 -0
  81. package/dest/l1_tx_utils/index.js +10 -0
  82. package/dest/l1_tx_utils/interfaces.d.ts +76 -0
  83. package/dest/l1_tx_utils/interfaces.d.ts.map +1 -0
  84. package/dest/l1_tx_utils/interfaces.js +4 -0
  85. package/dest/l1_tx_utils/l1_tx_utils.d.ts +94 -0
  86. package/dest/l1_tx_utils/l1_tx_utils.d.ts.map +1 -0
  87. package/dest/l1_tx_utils/l1_tx_utils.js +623 -0
  88. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts +26 -0
  89. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts.map +1 -0
  90. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.js +26 -0
  91. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts +94 -0
  92. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts.map +1 -0
  93. package/dest/l1_tx_utils/readonly_l1_tx_utils.js +431 -0
  94. package/dest/l1_tx_utils/signer.d.ts +4 -0
  95. package/dest/l1_tx_utils/signer.d.ts.map +1 -0
  96. package/dest/l1_tx_utils/signer.js +16 -0
  97. package/dest/l1_tx_utils/types.d.ts +67 -0
  98. package/dest/l1_tx_utils/types.d.ts.map +1 -0
  99. package/dest/l1_tx_utils/types.js +26 -0
  100. package/dest/l1_tx_utils/utils.d.ts +4 -0
  101. package/dest/l1_tx_utils/utils.d.ts.map +1 -0
  102. package/dest/l1_tx_utils/utils.js +14 -0
  103. package/dest/l1_types.d.ts +1 -1
  104. package/dest/publisher_manager.d.ts +8 -3
  105. package/dest/publisher_manager.d.ts.map +1 -1
  106. package/dest/publisher_manager.js +36 -8
  107. package/dest/queries.d.ts +1 -1
  108. package/dest/queries.d.ts.map +1 -1
  109. package/dest/queries.js +13 -12
  110. package/dest/test/chain_monitor.d.ts +33 -19
  111. package/dest/test/chain_monitor.d.ts.map +1 -1
  112. package/dest/test/chain_monitor.js +100 -33
  113. package/dest/test/delayed_tx_utils.d.ts +3 -3
  114. package/dest/test/delayed_tx_utils.d.ts.map +1 -1
  115. package/dest/test/delayed_tx_utils.js +2 -2
  116. package/dest/test/eth_cheat_codes.d.ts +36 -14
  117. package/dest/test/eth_cheat_codes.d.ts.map +1 -1
  118. package/dest/test/eth_cheat_codes.js +124 -31
  119. package/dest/test/eth_cheat_codes_with_state.d.ts +1 -1
  120. package/dest/test/eth_cheat_codes_with_state.d.ts.map +1 -1
  121. package/dest/test/index.d.ts +1 -1
  122. package/dest/test/rollup_cheat_codes.d.ts +23 -20
  123. package/dest/test/rollup_cheat_codes.d.ts.map +1 -1
  124. package/dest/test/rollup_cheat_codes.js +79 -42
  125. package/dest/test/start_anvil.d.ts +2 -1
  126. package/dest/test/start_anvil.d.ts.map +1 -1
  127. package/dest/test/start_anvil.js +2 -1
  128. package/dest/test/tx_delayer.d.ts +1 -1
  129. package/dest/test/tx_delayer.d.ts.map +1 -1
  130. package/dest/test/tx_delayer.js +3 -2
  131. package/dest/test/upgrade_utils.d.ts +1 -1
  132. package/dest/test/upgrade_utils.d.ts.map +1 -1
  133. package/dest/test/upgrade_utils.js +3 -2
  134. package/dest/types.d.ts +57 -2
  135. package/dest/types.d.ts.map +1 -1
  136. package/dest/utils.d.ts +2 -2
  137. package/dest/utils.d.ts.map +1 -1
  138. package/dest/utils.js +10 -161
  139. package/dest/zkPassportVerifierAddress.d.ts +1 -1
  140. package/dest/zkPassportVerifierAddress.js +1 -1
  141. package/package.json +27 -13
  142. package/src/client.ts +1 -1
  143. package/src/config.ts +177 -65
  144. package/src/contracts/empire_base.ts +7 -6
  145. package/src/contracts/empire_slashing_proposer.ts +18 -8
  146. package/src/contracts/fee_asset_handler.ts +1 -1
  147. package/src/contracts/governance.ts +3 -3
  148. package/src/contracts/governance_proposer.ts +14 -9
  149. package/src/contracts/multicall.ts +12 -10
  150. package/src/contracts/rollup.ts +170 -171
  151. package/src/contracts/slasher_contract.ts +22 -0
  152. package/src/contracts/tally_slashing_proposer.ts +63 -12
  153. package/src/deploy_l1_contracts.ts +610 -337
  154. package/src/forwarder_proxy.ts +108 -0
  155. package/src/l1_artifacts.ts +14 -6
  156. package/src/l1_contract_addresses.ts +17 -26
  157. package/src/l1_reader.ts +17 -9
  158. package/src/l1_tx_utils/README.md +177 -0
  159. package/src/l1_tx_utils/config.ts +161 -0
  160. package/src/l1_tx_utils/constants.ts +18 -0
  161. package/src/l1_tx_utils/factory.ts +64 -0
  162. package/src/l1_tx_utils/forwarder_l1_tx_utils.ts +119 -0
  163. package/src/l1_tx_utils/index-blobs.ts +2 -0
  164. package/src/l1_tx_utils/index.ts +12 -0
  165. package/src/l1_tx_utils/interfaces.ts +86 -0
  166. package/src/l1_tx_utils/l1_tx_utils.ts +738 -0
  167. package/src/l1_tx_utils/l1_tx_utils_with_blobs.ts +77 -0
  168. package/src/l1_tx_utils/readonly_l1_tx_utils.ts +557 -0
  169. package/src/l1_tx_utils/signer.ts +28 -0
  170. package/src/l1_tx_utils/types.ts +85 -0
  171. package/src/l1_tx_utils/utils.ts +16 -0
  172. package/src/publisher_manager.ts +51 -9
  173. package/src/queries.ts +16 -8
  174. package/src/test/chain_monitor.ts +118 -36
  175. package/src/test/delayed_tx_utils.ts +2 -2
  176. package/src/test/eth_cheat_codes.ts +149 -30
  177. package/src/test/rollup_cheat_codes.ts +94 -52
  178. package/src/test/start_anvil.ts +2 -0
  179. package/src/test/tx_delayer.ts +4 -2
  180. package/src/test/upgrade_utils.ts +3 -2
  181. package/src/types.ts +62 -0
  182. package/src/utils.ts +12 -184
  183. package/src/zkPassportVerifierAddress.ts +1 -1
  184. package/dest/index.d.ts +0 -18
  185. package/dest/index.d.ts.map +0 -1
  186. package/dest/index.js +0 -17
  187. package/dest/l1_tx_utils.d.ts +0 -250
  188. package/dest/l1_tx_utils.d.ts.map +0 -1
  189. package/dest/l1_tx_utils.js +0 -826
  190. package/dest/l1_tx_utils_with_blobs.d.ts +0 -19
  191. package/dest/l1_tx_utils_with_blobs.d.ts.map +0 -1
  192. package/dest/l1_tx_utils_with_blobs.js +0 -85
  193. package/src/index.ts +0 -17
  194. package/src/l1_tx_utils.ts +0 -1105
  195. package/src/l1_tx_utils_with_blobs.ts +0 -144
@@ -1,9 +1,9 @@
1
+ import { CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
1
2
  import { memoize } from '@aztec/foundation/decorators';
2
3
  import { EthAddress } from '@aztec/foundation/eth-address';
3
4
  import type { ViemSignature } from '@aztec/foundation/eth-signature';
4
5
  import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
5
6
  import { RollupStorage } from '@aztec/l1-artifacts/RollupStorage';
6
- import { SlasherAbi } from '@aztec/l1-artifacts/SlasherAbi';
7
7
 
8
8
  import chunk from 'lodash.chunk';
9
9
  import {
@@ -11,8 +11,8 @@ import {
11
11
  type GetContractReturnType,
12
12
  type Hex,
13
13
  type StateOverride,
14
+ type WatchContractEventReturnType,
14
15
  encodeFunctionData,
15
- getAddress,
16
16
  getContract,
17
17
  hexToBigInt,
18
18
  keccak256,
@@ -22,7 +22,7 @@ import { getPublicClient } from '../client.js';
22
22
  import type { DeployL1ContractsReturnType } from '../deploy_l1_contracts.js';
23
23
  import type { L1ContractAddresses } from '../l1_contract_addresses.js';
24
24
  import type { L1ReaderConfig } from '../l1_reader.js';
25
- import type { L1TxRequest, L1TxUtils } from '../l1_tx_utils.js';
25
+ import type { L1TxRequest, L1TxUtils } from '../l1_tx_utils/index.js';
26
26
  import type { ViemClient } from '../types.js';
27
27
  import { formatViemError } from '../utils.js';
28
28
  import { EmpireSlashingProposerContract } from './empire_slashing_proposer.js';
@@ -62,6 +62,7 @@ export type EpochProofPublicInputArgs = {
62
62
 
63
63
  export type ViemHeader = {
64
64
  lastArchiveRoot: `0x${string}`;
65
+ blockHeadersHash: `0x${string}`;
65
66
  contentCommitment: ViemContentCommitment;
66
67
  slotNumber: bigint;
67
68
  timestamp: bigint;
@@ -82,22 +83,6 @@ export type ViemGasFees = {
82
83
  feePerL2Gas: bigint;
83
84
  };
84
85
 
85
- export type ViemStateReference = {
86
- l1ToL2MessageTree: ViemAppendOnlyTreeSnapshot;
87
- partialStateReference: ViemPartialStateReference;
88
- };
89
-
90
- export type ViemPartialStateReference = {
91
- noteHashTree: ViemAppendOnlyTreeSnapshot;
92
- nullifierTree: ViemAppendOnlyTreeSnapshot;
93
- publicDataTree: ViemAppendOnlyTreeSnapshot;
94
- };
95
-
96
- export type ViemAppendOnlyTreeSnapshot = {
97
- root: `0x${string}`;
98
- nextAvailableLeafIndex: number;
99
- };
100
-
101
86
  export enum SlashingProposerType {
102
87
  None = 0,
103
88
  Tally = 1,
@@ -160,13 +145,12 @@ export class RollupContract {
160
145
  public async getSlashingProposer(): Promise<
161
146
  EmpireSlashingProposerContract | TallySlashingProposerContract | undefined
162
147
  > {
163
- const slasherAddress = await this.rollup.read.getSlasher();
164
- if (EthAddress.fromString(slasherAddress).isZero()) {
148
+ const slasher = await this.getSlasherContract();
149
+ if (!slasher) {
165
150
  return undefined;
166
151
  }
167
152
 
168
- const slasher = getContract({ address: slasherAddress, abi: SlasherAbi, client: this.client });
169
- const proposerAddress = await slasher.read.PROPOSER();
153
+ const proposerAddress = await slasher.getProposer();
170
154
  const proposerAbi = [
171
155
  {
172
156
  type: 'function',
@@ -177,7 +161,7 @@ export class RollupContract {
177
161
  },
178
162
  ] as const;
179
163
 
180
- const proposer = getContract({ address: proposerAddress, abi: proposerAbi, client: this.client });
164
+ const proposer = getContract({ address: proposerAddress.toString(), abi: proposerAbi, client: this.client });
181
165
  const proposerType = await proposer.read.SLASHING_PROPOSER_TYPE();
182
166
  if (proposerType === SlashingProposerType.Tally.valueOf()) {
183
167
  return new TallySlashingProposerContract(this.client, proposerAddress);
@@ -209,8 +193,8 @@ export class RollupContract {
209
193
  }
210
194
 
211
195
  @memoize
212
- getSlotDuration() {
213
- return this.rollup.read.getSlotDuration();
196
+ async getSlotDuration(): Promise<number> {
197
+ return Number(await this.rollup.read.getSlotDuration());
214
198
  }
215
199
 
216
200
  @memoize
@@ -223,6 +207,21 @@ export class RollupContract {
223
207
  return this.rollup.read.getEjectionThreshold();
224
208
  }
225
209
 
210
+ @memoize
211
+ getLocalEjectionThreshold() {
212
+ return this.rollup.read.getLocalEjectionThreshold();
213
+ }
214
+
215
+ @memoize
216
+ getLagInEpochsForValidatorSet() {
217
+ return this.rollup.read.getLagInEpochsForValidatorSet();
218
+ }
219
+
220
+ @memoize
221
+ getLagInEpochsForRandao() {
222
+ return this.rollup.read.getLagInEpochsForRandao();
223
+ }
224
+
226
225
  @memoize
227
226
  getActivationThreshold() {
228
227
  return this.rollup.read.getActivationThreshold();
@@ -260,20 +259,51 @@ export class RollupContract {
260
259
 
261
260
  @memoize
262
261
  async getGenesisArchiveTreeRoot(): Promise<`0x${string}`> {
263
- const block = await this.rollup.read.getBlock([0n]);
264
- return block.archive;
262
+ return await this.rollup.read.archiveAt([0n]);
263
+ }
264
+
265
+ /**
266
+ * Returns rollup constants used for epoch queries.
267
+ * Return type is `L1RollupConstants` which is defined in stdlib,
268
+ * so we cant reference it until we move this contract to that package.
269
+ */
270
+ @memoize
271
+ public async getRollupConstants(): Promise<{
272
+ l1StartBlock: bigint;
273
+ l1GenesisTime: bigint;
274
+ slotDuration: number;
275
+ epochDuration: number;
276
+ proofSubmissionEpochs: number;
277
+ }> {
278
+ const [l1StartBlock, l1GenesisTime, slotDuration, epochDuration, proofSubmissionEpochs] = await Promise.all([
279
+ this.getL1StartBlock(),
280
+ this.getL1GenesisTime(),
281
+ this.getSlotDuration(),
282
+ this.getEpochDuration(),
283
+ this.getProofSubmissionEpochs(),
284
+ ]);
285
+ return {
286
+ l1StartBlock,
287
+ l1GenesisTime,
288
+ slotDuration,
289
+ epochDuration: Number(epochDuration),
290
+ proofSubmissionEpochs: Number(proofSubmissionEpochs),
291
+ };
265
292
  }
266
293
 
267
- getSlasher() {
294
+ getSlasherAddress() {
268
295
  return this.rollup.read.getSlasher();
269
296
  }
270
297
 
271
298
  /**
272
299
  * Returns a SlasherContract instance for interacting with the slasher contract.
273
300
  */
274
- async getSlasherContract(): Promise<SlasherContract> {
275
- const slasherAddress = await this.getSlasher();
276
- return new SlasherContract(this.client, EthAddress.fromString(slasherAddress));
301
+ async getSlasherContract(): Promise<SlasherContract | undefined> {
302
+ const slasherAddress = EthAddress.fromString(await this.getSlasherAddress());
303
+ if (slasherAddress.isZero()) {
304
+ return undefined;
305
+ }
306
+ return new SlasherContract(this.client, slasherAddress);
277
307
  }
278
308
 
279
309
  getOwner() {
@@ -285,29 +315,27 @@ export class RollupContract {
285
315
  }
286
316
 
287
317
  public async getSlashingProposerAddress() {
288
- const slasherAddress = await this.getSlasher();
289
- const slasher = getContract({
290
- address: getAddress(slasherAddress.toString()),
291
- abi: SlasherAbi,
292
- client: this.client,
293
- });
294
- return EthAddress.fromString(await slasher.read.PROPOSER());
318
+ const slasher = await this.getSlasherContract();
319
+ if (!slasher) {
320
+ return EthAddress.ZERO;
321
+ }
322
+ return await slasher.getProposer();
295
323
  }
296
324
 
297
- getBlockReward() {
298
- return this.rollup.read.getBlockReward();
325
+ getCheckpointReward() {
326
+ return this.rollup.read.getCheckpointReward();
299
327
  }
300
328
 
301
- getBlockNumber() {
302
- return this.rollup.read.getPendingBlockNumber();
329
+ async getCheckpointNumber(): Promise<CheckpointNumber> {
330
+ return CheckpointNumber.fromBigInt(await this.rollup.read.getPendingCheckpointNumber());
303
331
  }
304
332
 
305
- getProvenBlockNumber() {
306
- return this.rollup.read.getProvenBlockNumber();
333
+ async getProvenCheckpointNumber(): Promise<CheckpointNumber> {
334
+ return CheckpointNumber.fromBigInt(await this.rollup.read.getProvenCheckpointNumber());
307
335
  }
308
336
 
309
- getSlotNumber() {
310
- return this.rollup.read.getCurrentSlot();
337
+ async getSlotNumber(): Promise<SlotNumber> {
338
+ return SlotNumber.fromBigInt(await this.rollup.read.getCurrentSlot());
311
339
  }
312
340
 
313
341
  getL1FeesAt(timestamp: bigint) {
@@ -344,8 +372,8 @@ export class RollupContract {
344
372
  return this.rollup.read.getCurrentSampleSeed();
345
373
  }
346
374
 
347
- getCurrentEpoch() {
348
- return this.rollup.read.getCurrentEpoch();
375
+ async getCurrentEpoch(): Promise<EpochNumber> {
376
+ return EpochNumber.fromBigInt(await this.rollup.read.getCurrentEpoch());
349
377
  }
350
378
 
351
379
  async getCurrentEpochCommittee(): Promise<readonly `0x${string}`[] | undefined> {
@@ -388,25 +416,40 @@ export class RollupContract {
388
416
  return result;
389
417
  }
390
418
 
391
- getBlock(blockNumber: bigint) {
392
- return this.rollup.read.getBlock([blockNumber]);
419
+ getCheckpoint(checkpointNumber: CheckpointNumber) {
420
+ return this.rollup.read.getCheckpoint([BigInt(checkpointNumber)]);
393
421
  }
394
422
 
395
- getTips() {
396
- return this.rollup.read.getTips();
423
+ async getTips(): Promise<{ pending: CheckpointNumber; proven: CheckpointNumber }> {
424
+ const { pending, proven } = await this.rollup.read.getTips();
425
+ return {
426
+ pending: CheckpointNumber.fromBigInt(pending),
427
+ proven: CheckpointNumber.fromBigInt(proven),
428
+ };
397
429
  }
398
430
 
399
- getTimestampForSlot(slot: bigint) {
400
- return this.rollup.read.getTimestampForSlot([slot]);
431
+ getTimestampForSlot(slot: SlotNumber) {
432
+ return this.rollup.read.getTimestampForSlot([BigInt(slot)]);
401
433
  }
402
434
 
403
435
  getEntryQueueLength() {
404
436
  return this.rollup.read.getEntryQueueLength();
405
437
  }
406
438
 
407
- async getEpochNumber(blockNumber?: bigint) {
408
- blockNumber ??= await this.getBlockNumber();
409
- return this.rollup.read.getEpochForBlock([BigInt(blockNumber)]);
439
+ getAvailableValidatorFlushes() {
440
+ return this.rollup.read.getAvailableValidatorFlushes();
441
+ }
442
+
443
+ async getNextFlushableEpoch(): Promise<EpochNumber> {
444
+ return EpochNumber.fromBigInt(await this.rollup.read.getNextFlushableEpoch());
445
+ }
446
+
447
+ async getCurrentEpochNumber(): Promise<EpochNumber> {
448
+ return EpochNumber.fromBigInt(await this.rollup.read.getCurrentEpoch());
449
+ }
450
+
451
+ async getEpochNumberForCheckpoint(checkpointNumber: CheckpointNumber): Promise<EpochNumber> {
452
+ return EpochNumber.fromBigInt(await this.rollup.read.getEpochForCheckpoint([BigInt(checkpointNumber)]));
410
453
  }
411
454
 
412
455
  async getRollupAddresses(): Promise<L1RollupContractAddresses> {
@@ -446,8 +489,8 @@ export class RollupContract {
446
489
  return EthAddress.fromString(await this.rollup.read.getFeeAssetPortal());
447
490
  }
448
491
 
449
- public async getEpochNumberForSlotNumber(slotNumber: bigint): Promise<bigint> {
450
- return await this.rollup.read.getEpochAtSlot([slotNumber]);
492
+ public async getEpochNumberForSlotNumber(slotNumber: SlotNumber): Promise<EpochNumber> {
493
+ return EpochNumber.fromBigInt(await this.rollup.read.getEpochAtSlot([BigInt(slotNumber)]));
451
494
  }
452
495
 
453
496
  getEpochProofPublicInputs(
@@ -461,6 +504,7 @@ export class RollupContract {
461
504
  ViemHeader,
462
505
  ViemCommitteeAttestations,
463
506
  `0x${string}`[],
507
+ ViemSignature,
464
508
  `0x${string}`,
465
509
  `0x${string}`,
466
510
  {
@@ -483,130 +527,63 @@ export class RollupContract {
483
527
  }
484
528
  }
485
529
 
486
- /**
487
- * Packs an array of committee attestations into the format expected by the Solidity contract
488
- *
489
- * @param attestations - Array of committee attestations with addresses and signatures
490
- * @returns Packed attestations with bitmap and tightly packed signature/address data
491
- */
492
- static packAttestations(attestations: ViemCommitteeAttestation[]): ViemCommitteeAttestations {
493
- const length = attestations.length;
494
-
495
- // Calculate bitmap size (1 bit per attestation, rounded up to nearest byte)
496
- const bitmapSize = Math.ceil(length / 8);
497
- const signatureIndices = new Uint8Array(bitmapSize);
498
-
499
- // Calculate total data size needed
500
- let totalDataSize = 0;
501
- for (let i = 0; i < length; i++) {
502
- const signature = attestations[i].signature;
503
- // Check if signature is empty (v = 0)
504
- const isEmpty = signature.v === 0;
505
-
506
- if (!isEmpty) {
507
- totalDataSize += 65; // v (1) + r (32) + s (32)
508
- } else {
509
- totalDataSize += 20; // address only
510
- }
511
- }
512
-
513
- const signaturesOrAddresses = new Uint8Array(totalDataSize);
514
- let dataIndex = 0;
515
-
516
- // Pack the data
517
- for (let i = 0; i < length; i++) {
518
- const attestation = attestations[i];
519
- const signature = attestation.signature;
520
-
521
- // Check if signature is empty
522
- const isEmpty = signature.v === 0;
523
-
524
- if (!isEmpty) {
525
- // Set bit in bitmap (bit 7-0 in each byte, left to right)
526
- const byteIndex = Math.floor(i / 8);
527
- const bitIndex = 7 - (i % 8);
528
- signatureIndices[byteIndex] |= 1 << bitIndex;
529
-
530
- // Pack signature: v + r + s
531
- signaturesOrAddresses[dataIndex] = signature.v;
532
- dataIndex++;
533
-
534
- // Pack r (32 bytes)
535
- const rBytes = Buffer.from(signature.r.slice(2), 'hex');
536
- signaturesOrAddresses.set(rBytes, dataIndex);
537
- dataIndex += 32;
538
-
539
- // Pack s (32 bytes)
540
- const sBytes = Buffer.from(signature.s.slice(2), 'hex');
541
- signaturesOrAddresses.set(sBytes, dataIndex);
542
- dataIndex += 32;
543
- } else {
544
- // Pack address only (20 bytes)
545
- const addrBytes = Buffer.from(attestation.addr.slice(2), 'hex');
546
- signaturesOrAddresses.set(addrBytes, dataIndex);
547
- dataIndex += 20;
548
- }
549
- }
550
-
551
- return {
552
- signatureIndices: `0x${Buffer.from(signatureIndices).toString('hex')}`,
553
- signaturesOrAddresses: `0x${Buffer.from(signaturesOrAddresses).toString('hex')}`,
554
- };
555
- }
556
-
557
530
  /**
558
531
  * @notice Calls `canProposeAtTime` with the time of the next Ethereum block and the sender address
559
532
  *
560
533
  * @dev Throws if unable to propose
561
534
  *
562
535
  * @param archive - The archive that we expect to be current state
563
- * @return [slot, blockNumber] - If you can propose, the L2 slot number and L2 block number of the next Ethereum block,
536
+ * @return [slot, checkpointNumber, timeOfNextL1Slot] - If you can propose, the L2 slot number, checkpoint number and
537
+ * timestamp of the next L1 block
564
538
  * @throws otherwise
565
539
  */
566
540
  public async canProposeAtNextEthBlock(
567
541
  archive: Buffer,
568
542
  account: `0x${string}` | Account,
569
- slotDuration: bigint | number,
570
- opts: { forcePendingBlockNumber?: number } = {},
571
- ): Promise<{ slot: bigint; blockNumber: bigint; timeOfNextL1Slot: bigint }> {
572
- if (typeof slotDuration === 'number') {
573
- slotDuration = BigInt(slotDuration);
574
- }
543
+ slotDuration: number,
544
+ opts: { forcePendingCheckpointNumber?: CheckpointNumber } = {},
545
+ ): Promise<{ slot: SlotNumber; checkpointNumber: CheckpointNumber; timeOfNextL1Slot: bigint }> {
575
546
  const latestBlock = await this.client.getBlock();
576
- const timeOfNextL1Slot = latestBlock.timestamp + slotDuration;
547
+ const timeOfNextL1Slot = latestBlock.timestamp + BigInt(slotDuration);
577
548
  const who = typeof account === 'string' ? account : account.address;
578
549
 
579
550
  try {
580
551
  const {
581
- result: [slot, blockNumber],
552
+ result: [slot, checkpointNumber],
582
553
  } = await this.client.simulateContract({
583
554
  address: this.address,
584
555
  abi: RollupAbi,
585
556
  functionName: 'canProposeAtTime',
586
557
  args: [timeOfNextL1Slot, `0x${archive.toString('hex')}`, who],
587
558
  account,
588
- stateOverride: await this.makePendingBlockNumberOverride(opts.forcePendingBlockNumber),
559
+ stateOverride: await this.makePendingCheckpointNumberOverride(opts.forcePendingCheckpointNumber),
589
560
  });
590
561
 
591
- return { slot, blockNumber, timeOfNextL1Slot };
562
+ return {
563
+ slot: SlotNumber.fromBigInt(slot),
564
+ checkpointNumber: CheckpointNumber.fromBigInt(checkpointNumber),
565
+ timeOfNextL1Slot,
566
+ };
592
567
  } catch (err: unknown) {
593
568
  throw formatViemError(err);
594
569
  }
595
570
  }
596
571
 
597
572
  /**
598
- * Returns a state override that sets the pending block number to the specified value. Useful for simulations.
599
- * Requires querying the current state of the contract to get the current proven block number, as they are both
573
+ * Returns a state override that sets the pending checkpoint number to the specified value. Useful for simulations.
574
+ * Requires querying the current state of the contract to get the current proven checkpoint number, as they are both
600
575
  * stored in the same slot. If the argument is undefined, it returns an empty override.
601
576
  */
602
- public async makePendingBlockNumberOverride(forcePendingBlockNumber: number | undefined): Promise<StateOverride> {
603
- if (forcePendingBlockNumber === undefined) {
577
+ public async makePendingCheckpointNumberOverride(
578
+ forcePendingCheckpointNumber: CheckpointNumber | undefined,
579
+ ): Promise<StateOverride> {
580
+ if (forcePendingCheckpointNumber === undefined) {
604
581
  return [];
605
582
  }
606
583
  const slot = RollupContract.stfStorageSlot;
607
584
  const currentValue = await this.client.getStorageAt({ address: this.address, slot });
608
- const currentProvenBlockNumber = currentValue ? hexToBigInt(currentValue) & ((1n << 128n) - 1n) : 0n;
609
- const newValue = (BigInt(forcePendingBlockNumber) << 128n) | currentProvenBlockNumber;
585
+ const currentProvenCheckpointNumber = currentValue ? hexToBigInt(currentValue) & ((1n << 128n) - 1n) : 0n;
586
+ const newValue = (BigInt(forcePendingCheckpointNumber) << 128n) | currentProvenCheckpointNumber;
610
587
  return [
611
588
  {
612
589
  address: this.address,
@@ -617,8 +594,8 @@ export class RollupContract {
617
594
 
618
595
  /** Creates a request to Rollup#invalidateBadAttestation to be simulated or sent */
619
596
  public buildInvalidateBadAttestationRequest(
620
- blockNumber: number,
621
- attestations: ViemCommitteeAttestation[],
597
+ checkpointNumber: CheckpointNumber,
598
+ attestationsAndSigners: ViemCommitteeAttestations,
622
599
  committee: EthAddress[],
623
600
  invalidIndex: number,
624
601
  ): L1TxRequest {
@@ -628,8 +605,8 @@ export class RollupContract {
628
605
  abi: RollupAbi,
629
606
  functionName: 'invalidateBadAttestation',
630
607
  args: [
631
- BigInt(blockNumber),
632
- RollupContract.packAttestations(attestations),
608
+ BigInt(checkpointNumber),
609
+ attestationsAndSigners,
633
610
  committee.map(addr => addr.toString()),
634
611
  BigInt(invalidIndex),
635
612
  ],
@@ -639,8 +616,8 @@ export class RollupContract {
639
616
 
640
617
  /** Creates a request to Rollup#invalidateInsufficientAttestations to be simulated or sent */
641
618
  public buildInvalidateInsufficientAttestationsRequest(
642
- blockNumber: number,
643
- attestations: ViemCommitteeAttestation[],
619
+ checkpointNumber: CheckpointNumber,
620
+ attestationsAndSigners: ViemCommitteeAttestations,
644
621
  committee: EthAddress[],
645
622
  ): L1TxRequest {
646
623
  return {
@@ -648,34 +625,30 @@ export class RollupContract {
648
625
  data: encodeFunctionData({
649
626
  abi: RollupAbi,
650
627
  functionName: 'invalidateInsufficientAttestations',
651
- args: [
652
- BigInt(blockNumber),
653
- RollupContract.packAttestations(attestations),
654
- committee.map(addr => addr.toString()),
655
- ],
628
+ args: [BigInt(checkpointNumber), attestationsAndSigners, committee.map(addr => addr.toString())],
656
629
  }),
657
630
  };
658
631
  }
659
632
 
660
633
  /** Calls getHasSubmitted directly. Returns whether the given prover has submitted a proof with the given length for the given epoch. */
661
- public getHasSubmittedProof(epochNumber: number, numberOfBlocksInEpoch: number, prover: Hex | EthAddress) {
634
+ public getHasSubmittedProof(epochNumber: EpochNumber, numberOfCheckpointsInEpoch: number, prover: Hex | EthAddress) {
662
635
  if (prover instanceof EthAddress) {
663
636
  prover = prover.toString();
664
637
  }
665
- return this.rollup.read.getHasSubmitted([BigInt(epochNumber), BigInt(numberOfBlocksInEpoch), prover]);
638
+ return this.rollup.read.getHasSubmitted([BigInt(epochNumber), BigInt(numberOfCheckpointsInEpoch), prover]);
666
639
  }
667
640
 
668
641
  getManaBaseFeeAt(timestamp: bigint, inFeeAsset: boolean) {
669
642
  return this.rollup.read.getManaBaseFeeAt([timestamp, inFeeAsset]);
670
643
  }
671
644
 
672
- getSlotAt(timestamp: bigint) {
673
- return this.rollup.read.getSlotAt([timestamp]);
645
+ async getSlotAt(timestamp: bigint): Promise<SlotNumber> {
646
+ return SlotNumber.fromBigInt(await this.rollup.read.getSlotAt([timestamp]));
674
647
  }
675
648
 
676
- async status(blockNumber: bigint, options?: { blockNumber?: bigint }) {
649
+ async status(checkpointNumber: CheckpointNumber, options?: { blockNumber?: bigint }) {
677
650
  await checkBlockTag(options?.blockNumber, this.client);
678
- return this.rollup.read.status([blockNumber], options);
651
+ return this.rollup.read.status([BigInt(checkpointNumber)], options);
679
652
  }
680
653
 
681
654
  async canPruneAtTime(timestamp: bigint, options?: { blockNumber?: bigint }) {
@@ -687,8 +660,8 @@ export class RollupContract {
687
660
  return this.rollup.read.archive();
688
661
  }
689
662
 
690
- archiveAt(blockNumber: bigint) {
691
- return this.rollup.read.archiveAt([blockNumber]);
663
+ archiveAt(checkpointNumber: CheckpointNumber) {
664
+ return this.rollup.read.archiveAt([BigInt(checkpointNumber)]);
692
665
  }
693
666
 
694
667
  getSequencerRewards(address: Hex | EthAddress) {
@@ -730,8 +703,8 @@ export class RollupContract {
730
703
  return this.rollup.read.getStatus([address]);
731
704
  }
732
705
 
733
- getBlobCommitmentsHash(blockNumber: bigint) {
734
- return this.rollup.read.getBlobCommitmentsHash([blockNumber]);
706
+ getBlobCommitmentsHash(checkpointNumber: CheckpointNumber) {
707
+ return this.rollup.read.getBlobCommitmentsHash([BigInt(checkpointNumber)]);
735
708
  }
736
709
 
737
710
  getCurrentBlobCommitmentsHash() {
@@ -742,6 +715,10 @@ export class RollupContract {
742
715
  return this.rollup.read.getStakingAsset();
743
716
  }
744
717
 
718
+ getRewardConfig() {
719
+ return this.rollup.read.getRewardConfig();
720
+ }
721
+
745
722
  setupEpoch(l1TxUtils: L1TxUtils) {
746
723
  return l1TxUtils.sendAndMonitorTransaction({
747
724
  to: this.address,
@@ -764,7 +741,9 @@ export class RollupContract {
764
741
  });
765
742
  }
766
743
 
767
- public listenToSlasherChanged(callback: (args: { oldSlasher: `0x${string}`; newSlasher: `0x${string}` }) => unknown) {
744
+ public listenToSlasherChanged(
745
+ callback: (args: { oldSlasher: `0x${string}`; newSlasher: `0x${string}` }) => unknown,
746
+ ): WatchContractEventReturnType {
768
747
  return this.rollup.watchEvent.SlasherUpdated(
769
748
  {},
770
749
  {
@@ -780,6 +759,24 @@ export class RollupContract {
780
759
  );
781
760
  }
782
761
 
762
+ public listenToCheckpointInvalidated(
763
+ callback: (args: { checkpointNumber: CheckpointNumber }) => unknown,
764
+ ): WatchContractEventReturnType {
765
+ return this.rollup.watchEvent.CheckpointInvalidated(
766
+ {},
767
+ {
768
+ onLogs: logs => {
769
+ for (const log of logs) {
770
+ const args = log.args;
771
+ if (args.checkpointNumber !== undefined) {
772
+ callback({ checkpointNumber: CheckpointNumber.fromBigInt(args.checkpointNumber) });
773
+ }
774
+ }
775
+ },
776
+ },
777
+ );
778
+ }
779
+
783
780
  public async getSlashEvents(l1BlockHash: Hex): Promise<{ amount: bigint; attester: EthAddress }[]> {
784
781
  const events = await this.rollup.getEvents.Slashed({}, { blockHash: l1BlockHash, strict: true });
785
782
  return events.map(event => ({
@@ -788,7 +785,9 @@ export class RollupContract {
788
785
  }));
789
786
  }
790
787
 
791
- public listenToSlash(callback: (args: { amount: bigint; attester: EthAddress }) => unknown) {
788
+ public listenToSlash(
789
+ callback: (args: { amount: bigint; attester: EthAddress }) => unknown,
790
+ ): WatchContractEventReturnType {
792
791
  return this.rollup.watchEvent.Slashed(
793
792
  {},
794
793
  {
@@ -38,6 +38,19 @@ export class SlasherContract {
38
38
  }
39
39
  }
40
40
 
41
+ /**
42
+ * Checks if slashing is currently enabled. Slashing can be disabled by the vetoer.
43
+ * @returns True if slashing is enabled, false otherwise
44
+ */
45
+ public async isSlashingEnabled(): Promise<boolean> {
46
+ try {
47
+ return await this.contract.read.isSlashingEnabled();
48
+ } catch (error) {
49
+ this.log.error(`Error checking if slashing is enabled`, error);
50
+ throw error;
51
+ }
52
+ }
53
+
41
54
  /**
42
55
  * Gets the current vetoer address.
43
56
  * @returns The vetoer address
@@ -47,6 +60,15 @@ export class SlasherContract {
47
60
  return EthAddress.fromString(vetoer);
48
61
  }
49
62
 
63
+ /**
64
+ * Gets the disable duration by the vetoer.
65
+ * @returns The disable duration in seconds
66
+ */
67
+ public async getSlashingDisableDuration(): Promise<number> {
68
+ const duration = await this.contract.read.SLASHING_DISABLE_DURATION();
69
+ return Number(duration);
70
+ }
71
+
50
72
  /**
51
73
  * Gets the current governance address.
52
74
  * @returns The governance address