@aztec/ethereum 0.0.1-commit.c7c42ec → 0.0.1-commit.cd76b27

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 (162) hide show
  1. package/dest/config.d.ts +15 -28
  2. package/dest/config.d.ts.map +1 -1
  3. package/dest/config.js +50 -57
  4. package/dest/contracts/empire_base.d.ts +3 -1
  5. package/dest/contracts/empire_base.d.ts.map +1 -1
  6. package/dest/contracts/empire_slashing_proposer.d.ts +3 -1
  7. package/dest/contracts/empire_slashing_proposer.d.ts.map +1 -1
  8. package/dest/contracts/empire_slashing_proposer.js +22 -15
  9. package/dest/contracts/fee_asset_handler.d.ts +6 -5
  10. package/dest/contracts/fee_asset_handler.d.ts.map +1 -1
  11. package/dest/contracts/fee_asset_handler.js +11 -9
  12. package/dest/contracts/fee_asset_price_oracle.d.ts +101 -0
  13. package/dest/contracts/fee_asset_price_oracle.d.ts.map +1 -0
  14. package/dest/contracts/fee_asset_price_oracle.js +651 -0
  15. package/dest/contracts/governance.d.ts +3 -1
  16. package/dest/contracts/governance.d.ts.map +1 -1
  17. package/dest/contracts/governance.js +14 -4
  18. package/dest/contracts/governance_proposer.d.ts +3 -1
  19. package/dest/contracts/governance_proposer.d.ts.map +1 -1
  20. package/dest/contracts/governance_proposer.js +395 -9
  21. package/dest/contracts/inbox.d.ts +18 -1
  22. package/dest/contracts/inbox.d.ts.map +1 -1
  23. package/dest/contracts/inbox.js +32 -1
  24. package/dest/contracts/index.d.ts +4 -1
  25. package/dest/contracts/index.d.ts.map +1 -1
  26. package/dest/contracts/index.js +3 -0
  27. package/dest/contracts/log.d.ts +13 -0
  28. package/dest/contracts/log.d.ts.map +1 -0
  29. package/dest/contracts/log.js +1 -0
  30. package/dest/contracts/multicall.d.ts +1 -1
  31. package/dest/contracts/multicall.d.ts.map +1 -1
  32. package/dest/contracts/multicall.js +2 -1
  33. package/dest/contracts/outbox.d.ts +41 -0
  34. package/dest/contracts/outbox.d.ts.map +1 -0
  35. package/dest/contracts/outbox.js +86 -0
  36. package/dest/contracts/rollup.d.ts +161 -96
  37. package/dest/contracts/rollup.d.ts.map +1 -1
  38. package/dest/contracts/rollup.js +677 -132
  39. package/dest/contracts/tally_slashing_proposer.d.ts +1 -1
  40. package/dest/contracts/tally_slashing_proposer.d.ts.map +1 -1
  41. package/dest/contracts/tally_slashing_proposer.js +8 -1
  42. package/dest/deploy_aztec_l1_contracts.d.ts +16 -4
  43. package/dest/deploy_aztec_l1_contracts.d.ts.map +1 -1
  44. package/dest/deploy_aztec_l1_contracts.js +110 -33
  45. package/dest/deploy_l1_contract.js +3 -3
  46. package/dest/generated/l1-contracts-defaults.d.ts +30 -0
  47. package/dest/generated/l1-contracts-defaults.d.ts.map +1 -0
  48. package/dest/generated/l1-contracts-defaults.js +30 -0
  49. package/dest/l1_artifacts.d.ts +5877 -1515
  50. package/dest/l1_artifacts.d.ts.map +1 -1
  51. package/dest/l1_tx_utils/config.d.ts +7 -1
  52. package/dest/l1_tx_utils/config.d.ts.map +1 -1
  53. package/dest/l1_tx_utils/config.js +14 -1
  54. package/dest/l1_tx_utils/constants.d.ts +1 -1
  55. package/dest/l1_tx_utils/constants.js +2 -2
  56. package/dest/l1_tx_utils/factory.d.ts +18 -10
  57. package/dest/l1_tx_utils/factory.d.ts.map +1 -1
  58. package/dest/l1_tx_utils/factory.js +17 -7
  59. package/dest/l1_tx_utils/fee-strategies/index.d.ts +3 -2
  60. package/dest/l1_tx_utils/fee-strategies/index.d.ts.map +1 -1
  61. package/dest/l1_tx_utils/fee-strategies/index.js +2 -1
  62. package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts +2 -12
  63. package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts.map +1 -1
  64. package/dest/l1_tx_utils/fee-strategies/p75_competitive.js +36 -18
  65. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts +2 -11
  66. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts.map +1 -1
  67. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.js +37 -19
  68. package/dest/l1_tx_utils/fee-strategies/types.d.ts +14 -27
  69. package/dest/l1_tx_utils/fee-strategies/types.d.ts.map +1 -1
  70. package/dest/l1_tx_utils/fee-strategies/types.js +0 -21
  71. package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts +15 -15
  72. package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts.map +1 -1
  73. package/dest/l1_tx_utils/forwarder_l1_tx_utils.js +9 -15
  74. package/dest/l1_tx_utils/index-blobs.d.ts +3 -3
  75. package/dest/l1_tx_utils/index-blobs.d.ts.map +1 -1
  76. package/dest/l1_tx_utils/index-blobs.js +2 -2
  77. package/dest/l1_tx_utils/index.d.ts +2 -1
  78. package/dest/l1_tx_utils/index.d.ts.map +1 -1
  79. package/dest/l1_tx_utils/index.js +1 -0
  80. package/dest/l1_tx_utils/l1_fee_analyzer.d.ts +2 -2
  81. package/dest/l1_tx_utils/l1_fee_analyzer.d.ts.map +1 -1
  82. package/dest/l1_tx_utils/l1_fee_analyzer.js +3 -3
  83. package/dest/l1_tx_utils/l1_tx_utils.d.ts +15 -5
  84. package/dest/l1_tx_utils/l1_tx_utils.d.ts.map +1 -1
  85. package/dest/l1_tx_utils/l1_tx_utils.js +47 -13
  86. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts +1 -5
  87. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts.map +1 -1
  88. package/dest/l1_tx_utils/readonly_l1_tx_utils.js +17 -54
  89. package/dest/l1_tx_utils/tx_delayer.d.ts +56 -0
  90. package/dest/l1_tx_utils/tx_delayer.d.ts.map +1 -0
  91. package/dest/{test → l1_tx_utils}/tx_delayer.js +62 -34
  92. package/dest/publisher_manager.d.ts +3 -2
  93. package/dest/publisher_manager.d.ts.map +1 -1
  94. package/dest/publisher_manager.js +2 -2
  95. package/dest/queries.d.ts +2 -2
  96. package/dest/queries.d.ts.map +1 -1
  97. package/dest/queries.js +6 -3
  98. package/dest/test/chain_monitor.js +1 -2
  99. package/dest/test/eth_cheat_codes.d.ts +13 -1
  100. package/dest/test/eth_cheat_codes.d.ts.map +1 -1
  101. package/dest/test/index.d.ts +1 -3
  102. package/dest/test/index.d.ts.map +1 -1
  103. package/dest/test/index.js +0 -2
  104. package/dest/test/rollup_cheat_codes.d.ts +5 -2
  105. package/dest/test/rollup_cheat_codes.d.ts.map +1 -1
  106. package/dest/test/rollup_cheat_codes.js +19 -2
  107. package/dest/test/start_anvil.js +1 -1
  108. package/dest/test/upgrade_utils.js +2 -2
  109. package/dest/utils.d.ts +2 -1
  110. package/dest/utils.d.ts.map +1 -1
  111. package/dest/utils.js +46 -0
  112. package/package.json +8 -7
  113. package/src/config.ts +58 -56
  114. package/src/contracts/README.md +157 -0
  115. package/src/contracts/empire_base.ts +2 -0
  116. package/src/contracts/empire_slashing_proposer.ts +22 -27
  117. package/src/contracts/fee_asset_handler.ts +10 -7
  118. package/src/contracts/fee_asset_price_oracle.ts +280 -0
  119. package/src/contracts/governance.ts +13 -4
  120. package/src/contracts/governance_proposer.ts +10 -1
  121. package/src/contracts/inbox.ts +48 -1
  122. package/src/contracts/index.ts +3 -0
  123. package/src/contracts/log.ts +13 -0
  124. package/src/contracts/multicall.ts +5 -2
  125. package/src/contracts/outbox.ts +98 -0
  126. package/src/contracts/rollup.ts +348 -100
  127. package/src/contracts/tally_slashing_proposer.ts +5 -1
  128. package/src/deploy_aztec_l1_contracts.ts +135 -42
  129. package/src/deploy_l1_contract.ts +3 -3
  130. package/src/generated/l1-contracts-defaults.ts +32 -0
  131. package/src/l1_tx_utils/config.ts +20 -0
  132. package/src/l1_tx_utils/constants.ts +2 -2
  133. package/src/l1_tx_utils/factory.ts +31 -31
  134. package/src/l1_tx_utils/fee-strategies/index.ts +1 -1
  135. package/src/l1_tx_utils/fee-strategies/p75_competitive.ts +46 -42
  136. package/src/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.ts +49 -45
  137. package/src/l1_tx_utils/fee-strategies/types.ts +14 -46
  138. package/src/l1_tx_utils/forwarder_l1_tx_utils.ts +43 -54
  139. package/src/l1_tx_utils/index-blobs.ts +2 -2
  140. package/src/l1_tx_utils/index.ts +1 -0
  141. package/src/l1_tx_utils/l1_fee_analyzer.ts +2 -3
  142. package/src/l1_tx_utils/l1_tx_utils.ts +52 -17
  143. package/src/l1_tx_utils/readonly_l1_tx_utils.ts +23 -62
  144. package/src/{test → l1_tx_utils}/tx_delayer.ts +78 -50
  145. package/src/publisher_manager.ts +4 -2
  146. package/src/queries.ts +5 -3
  147. package/src/test/chain_monitor.ts +1 -1
  148. package/src/test/index.ts +0 -2
  149. package/src/test/rollup_cheat_codes.ts +21 -3
  150. package/src/test/start_anvil.ts +1 -1
  151. package/src/test/upgrade_utils.ts +2 -2
  152. package/src/utils.ts +53 -0
  153. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts +0 -26
  154. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts.map +0 -1
  155. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.js +0 -26
  156. package/dest/test/delayed_tx_utils.d.ts +0 -13
  157. package/dest/test/delayed_tx_utils.d.ts.map +0 -1
  158. package/dest/test/delayed_tx_utils.js +0 -28
  159. package/dest/test/tx_delayer.d.ts +0 -36
  160. package/dest/test/tx_delayer.d.ts.map +0 -1
  161. package/src/l1_tx_utils/l1_tx_utils_with_blobs.ts +0 -77
  162. package/src/test/delayed_tx_utils.ts +0 -52
@@ -1,8 +1,11 @@
1
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';
2
4
  import { memoize } from '@aztec/foundation/decorators';
3
5
  import { EthAddress } from '@aztec/foundation/eth-address';
4
6
  import type { ViemSignature } from '@aztec/foundation/eth-signature';
5
7
  import { makeBackoff, retry } from '@aztec/foundation/retry';
8
+ import { EscapeHatchAbi } from '@aztec/l1-artifacts/EscapeHatchAbi';
6
9
  import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
7
10
  import { RollupStorage } from '@aztec/l1-artifacts/RollupStorage';
8
11
 
@@ -28,6 +31,7 @@ import type { ViemClient } from '../types.js';
28
31
  import { formatViemError } from '../utils.js';
29
32
  import { EmpireSlashingProposerContract } from './empire_slashing_proposer.js';
30
33
  import { GSEContract } from './gse.js';
34
+ import type { L1EventLog } from './log.js';
31
35
  import { SlasherContract } from './slasher_contract.js';
32
36
  import { TallySlashingProposerContract } from './tally_slashing_proposer.js';
33
37
  import { checkBlockTag } from './utils.js';
@@ -58,13 +62,16 @@ export type L1RollupContractAddresses = Pick<
58
62
  export type EpochProofPublicInputArgs = {
59
63
  previousArchive: `0x${string}`;
60
64
  endArchive: `0x${string}`;
65
+ outHash: `0x${string}`;
61
66
  proverId: `0x${string}`;
62
67
  };
63
68
 
64
69
  export type ViemHeader = {
65
70
  lastArchiveRoot: `0x${string}`;
66
71
  blockHeadersHash: `0x${string}`;
67
- contentCommitment: ViemContentCommitment;
72
+ blobsHash: `0x${string}`;
73
+ inHash: `0x${string}`;
74
+ outHash: `0x${string}`;
68
75
  slotNumber: bigint;
69
76
  timestamp: bigint;
70
77
  coinbase: `0x${string}`;
@@ -73,12 +80,6 @@ export type ViemHeader = {
73
80
  totalManaUsed: bigint;
74
81
  };
75
82
 
76
- export type ViemContentCommitment = {
77
- blobsHash: `0x${string}`;
78
- inHash: `0x${string}`;
79
- outHash: `0x${string}`;
80
- };
81
-
82
83
  export type ViemGasFees = {
83
84
  feePerDaGas: bigint;
84
85
  feePerL2Gas: bigint;
@@ -90,10 +91,125 @@ export enum SlashingProposerType {
90
91
  Empire = 2,
91
92
  }
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;
114
+ };
115
+
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;
127
+ };
128
+
129
+ /**
130
+ * L1 fee data (base fee and blob fee)
131
+ */
132
+ export type L1FeeData = {
133
+ baseFee: bigint;
134
+ blobFee: bigint;
135
+ };
136
+
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. Undefined for older events (backwards compatibility). */
197
+ attestationsHash?: Buffer32;
198
+ /** Digest of the payload. Undefined for older events (backwards compatibility). */
199
+ payloadDigest?: Buffer32;
200
+ };
201
+
202
+ /** Log type for CheckpointProposed events. */
203
+ export type CheckpointProposedLog = L1EventLog<CheckpointProposedArgs>;
204
+
93
205
  export class RollupContract {
94
206
  private readonly rollup: GetContractReturnType<typeof RollupAbi, ViemClient>;
95
207
 
96
208
  private static cachedStfStorageSlot: Hex | undefined;
209
+ private cachedEscapeHatch?: {
210
+ address: EthAddress;
211
+ contract: GetContractReturnType<typeof EscapeHatchAbi, ViemClient>;
212
+ };
97
213
 
98
214
  static get checkBlobStorageSlot(): bigint {
99
215
  const asString = RollupStorage.find(storage => storage.label === 'checkBlob')?.slot;
@@ -131,8 +247,8 @@ export class RollupContract {
131
247
  this.rollup = getContract({ address, abi: RollupAbi, client });
132
248
  }
133
249
 
134
- getGSE() {
135
- return this.rollup.read.getGSE();
250
+ async getGSE(): Promise<EthAddress> {
251
+ return EthAddress.fromString(await this.rollup.read.getGSE());
136
252
  }
137
253
 
138
254
  public get address() {
@@ -174,23 +290,23 @@ export class RollupContract {
174
290
  }
175
291
 
176
292
  @memoize
177
- getL1StartBlock() {
293
+ getL1StartBlock(): Promise<bigint> {
178
294
  return this.rollup.read.L1_BLOCK_AT_GENESIS();
179
295
  }
180
296
 
181
297
  @memoize
182
- getL1GenesisTime() {
298
+ getL1GenesisTime(): Promise<bigint> {
183
299
  return this.rollup.read.getGenesisTime();
184
300
  }
185
301
 
186
302
  @memoize
187
- getProofSubmissionEpochs() {
188
- return this.rollup.read.getProofSubmissionEpochs();
303
+ async getProofSubmissionEpochs(): Promise<number> {
304
+ return Number(await this.rollup.read.getProofSubmissionEpochs());
189
305
  }
190
306
 
191
307
  @memoize
192
- getEpochDuration() {
193
- return this.rollup.read.getEpochDuration();
308
+ async getEpochDuration(): Promise<number> {
309
+ return Number(await this.rollup.read.getEpochDuration());
194
310
  }
195
311
 
196
312
  @memoize
@@ -199,68 +315,68 @@ export class RollupContract {
199
315
  }
200
316
 
201
317
  @memoize
202
- getTargetCommitteeSize() {
203
- return this.rollup.read.getTargetCommitteeSize();
318
+ async getTargetCommitteeSize(): Promise<number> {
319
+ return Number(await this.rollup.read.getTargetCommitteeSize());
204
320
  }
205
321
 
206
322
  @memoize
207
- getEjectionThreshold() {
323
+ getEjectionThreshold(): Promise<bigint> {
208
324
  return this.rollup.read.getEjectionThreshold();
209
325
  }
210
326
 
211
327
  @memoize
212
- getLocalEjectionThreshold() {
328
+ getLocalEjectionThreshold(): Promise<bigint> {
213
329
  return this.rollup.read.getLocalEjectionThreshold();
214
330
  }
215
331
 
216
332
  @memoize
217
- getLagInEpochsForValidatorSet() {
218
- return this.rollup.read.getLagInEpochsForValidatorSet();
333
+ async getLagInEpochsForValidatorSet(): Promise<number> {
334
+ return Number(await this.rollup.read.getLagInEpochsForValidatorSet());
219
335
  }
220
336
 
221
337
  @memoize
222
- getLagInEpochsForRandao() {
223
- return this.rollup.read.getLagInEpochsForRandao();
338
+ async getLagInEpochsForRandao(): Promise<number> {
339
+ return Number(await this.rollup.read.getLagInEpochsForRandao());
224
340
  }
225
341
 
226
342
  @memoize
227
- getActivationThreshold() {
343
+ getActivationThreshold(): Promise<bigint> {
228
344
  return this.rollup.read.getActivationThreshold();
229
345
  }
230
346
 
231
347
  @memoize
232
- getExitDelay() {
233
- return this.rollup.read.getExitDelay();
348
+ async getExitDelay(): Promise<number> {
349
+ return Number(await this.rollup.read.getExitDelay());
234
350
  }
235
351
 
236
352
  @memoize
237
- getManaTarget() {
353
+ getManaTarget(): Promise<bigint> {
238
354
  return this.rollup.read.getManaTarget();
239
355
  }
240
356
 
241
357
  @memoize
242
- getProvingCostPerMana() {
358
+ getProvingCostPerMana(): Promise<bigint> {
243
359
  return this.rollup.read.getProvingCostPerManaInEth();
244
360
  }
245
361
 
246
362
  @memoize
247
- getProvingCostPerManaInFeeAsset() {
363
+ getProvingCostPerManaInFeeAsset(): Promise<bigint> {
248
364
  return this.rollup.read.getProvingCostPerManaInFeeAsset();
249
365
  }
250
366
 
251
367
  @memoize
252
- getManaLimit() {
368
+ getManaLimit(): Promise<bigint> {
253
369
  return this.rollup.read.getManaLimit();
254
370
  }
255
371
 
256
372
  @memoize
257
- getVersion() {
373
+ getVersion(): Promise<bigint> {
258
374
  return this.rollup.read.getVersion();
259
375
  }
260
376
 
261
377
  @memoize
262
- async getGenesisArchiveTreeRoot(): Promise<`0x${string}`> {
263
- return await this.rollup.read.archiveAt([0n]);
378
+ async getGenesisArchiveTreeRoot(): Promise<Fr> {
379
+ return Fr.fromString(await this.rollup.read.archiveAt([0n]));
264
380
  }
265
381
 
266
382
  /**
@@ -275,44 +391,100 @@ export class RollupContract {
275
391
  slotDuration: number;
276
392
  epochDuration: number;
277
393
  proofSubmissionEpochs: number;
394
+ targetCommitteeSize: number;
278
395
  }> {
279
- const [l1StartBlock, l1GenesisTime, slotDuration, epochDuration, proofSubmissionEpochs] = await Promise.all([
280
- this.getL1StartBlock(),
281
- this.getL1GenesisTime(),
282
- this.getSlotDuration(),
283
- this.getEpochDuration(),
284
- this.getProofSubmissionEpochs(),
285
- ]);
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
+ ]);
286
405
  return {
287
406
  l1StartBlock,
288
407
  l1GenesisTime,
289
408
  slotDuration,
290
409
  epochDuration: Number(epochDuration),
291
410
  proofSubmissionEpochs: Number(proofSubmissionEpochs),
411
+ targetCommitteeSize,
292
412
  };
293
413
  }
294
414
 
295
- getSlasherAddress() {
296
- 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
+ }
297
469
  }
298
470
 
299
471
  /**
300
472
  * Returns a SlasherContract instance for interacting with the slasher contract.
301
473
  */
302
474
  async getSlasherContract(): Promise<SlasherContract | undefined> {
303
- const slasherAddress = EthAddress.fromString(await this.getSlasherAddress());
475
+ const slasherAddress = await this.getSlasherAddress();
304
476
  if (slasherAddress.isZero()) {
305
477
  return undefined;
306
478
  }
307
479
  return new SlasherContract(this.client, slasherAddress);
308
480
  }
309
481
 
310
- getOwner() {
311
- return this.rollup.read.owner();
482
+ async getOwner(): Promise<EthAddress> {
483
+ return EthAddress.fromString(await this.rollup.read.owner());
312
484
  }
313
485
 
314
- getActiveAttesterCount() {
315
- return this.rollup.read.getActiveAttesterCount();
486
+ async getActiveAttesterCount(): Promise<number> {
487
+ return Number(await this.rollup.read.getActiveAttesterCount());
316
488
  }
317
489
 
318
490
  public async getSlashingProposerAddress() {
@@ -323,7 +495,7 @@ export class RollupContract {
323
495
  return await slasher.getProposer();
324
496
  }
325
497
 
326
- getCheckpointReward() {
498
+ getCheckpointReward(): Promise<bigint> {
327
499
  return this.rollup.read.getCheckpointReward();
328
500
  }
329
501
 
@@ -339,15 +511,19 @@ export class RollupContract {
339
511
  return SlotNumber.fromBigInt(await this.rollup.read.getCurrentSlot());
340
512
  }
341
513
 
342
- getL1FeesAt(timestamp: bigint) {
343
- 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
+ };
344
520
  }
345
521
 
346
- getFeeAssetPerEth() {
347
- return this.rollup.read.getFeeAssetPerEth();
522
+ getEthPerFeeAsset(): Promise<bigint> {
523
+ return this.rollup.read.getEthPerFeeAsset();
348
524
  }
349
525
 
350
- async getCommitteeAt(timestamp: bigint): Promise<readonly `0x${string}`[] | undefined> {
526
+ async getCommitteeAt(timestamp: bigint): Promise<EthAddress[] | undefined> {
351
527
  const { result } = await this.client
352
528
  .simulateContract({
353
529
  address: this.address,
@@ -362,22 +538,22 @@ export class RollupContract {
362
538
  throw e;
363
539
  });
364
540
 
365
- return result;
541
+ return result ? result.map(addr => EthAddress.fromString(addr)) : undefined;
366
542
  }
367
543
 
368
- getSampleSeedAt(timestamp: bigint) {
369
- return this.rollup.read.getSampleSeedAt([timestamp]);
544
+ async getSampleSeedAt(timestamp: bigint): Promise<Buffer32> {
545
+ return Buffer32.fromBigInt(await this.rollup.read.getSampleSeedAt([timestamp]));
370
546
  }
371
547
 
372
- getCurrentSampleSeed() {
373
- return this.rollup.read.getCurrentSampleSeed();
548
+ async getCurrentSampleSeed(): Promise<Buffer32> {
549
+ return Buffer32.fromBigInt(await this.rollup.read.getCurrentSampleSeed());
374
550
  }
375
551
 
376
552
  async getCurrentEpoch(): Promise<EpochNumber> {
377
553
  return EpochNumber.fromBigInt(await this.rollup.read.getCurrentEpoch());
378
554
  }
379
555
 
380
- async getCurrentEpochCommittee(): Promise<readonly `0x${string}`[] | undefined> {
556
+ async getCurrentEpochCommittee(): Promise<EthAddress[] | undefined> {
381
557
  const { result } = await this.client
382
558
  .simulateContract({
383
559
  address: this.address,
@@ -392,10 +568,10 @@ export class RollupContract {
392
568
  throw e;
393
569
  });
394
570
 
395
- return result;
571
+ return result ? result.map(addr => EthAddress.fromString(addr)) : undefined;
396
572
  }
397
573
 
398
- async getCurrentProposer() {
574
+ async getCurrentProposer(): Promise<EthAddress> {
399
575
  const { result } = await this.client.simulateContract({
400
576
  address: this.address,
401
577
  abi: RollupAbi,
@@ -403,10 +579,10 @@ export class RollupContract {
403
579
  args: [],
404
580
  });
405
581
 
406
- return result;
582
+ return EthAddress.fromString(result);
407
583
  }
408
584
 
409
- async getProposerAt(timestamp: bigint) {
585
+ async getProposerAt(timestamp: bigint): Promise<EthAddress> {
410
586
  const { result } = await this.client.simulateContract({
411
587
  address: this.address,
412
588
  abi: RollupAbi,
@@ -414,11 +590,26 @@ export class RollupContract {
414
590
  args: [timestamp],
415
591
  });
416
592
 
417
- return result;
593
+ return EthAddress.fromString(result);
418
594
  }
419
595
 
420
- getCheckpoint(checkpointNumber: CheckpointNumber) {
421
- return this.rollup.read.getCheckpoint([BigInt(checkpointNumber)]);
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
+ };
422
613
  }
423
614
 
424
615
  /** Returns the pending checkpoint from the rollup contract */
@@ -444,16 +635,16 @@ export class RollupContract {
444
635
  };
445
636
  }
446
637
 
447
- getTimestampForSlot(slot: SlotNumber) {
638
+ getTimestampForSlot(slot: SlotNumber): Promise<bigint> {
448
639
  return this.rollup.read.getTimestampForSlot([BigInt(slot)]);
449
640
  }
450
641
 
451
- getEntryQueueLength() {
452
- return this.rollup.read.getEntryQueueLength();
642
+ async getEntryQueueLength(): Promise<number> {
643
+ return Number(await this.rollup.read.getEntryQueueLength());
453
644
  }
454
645
 
455
- getAvailableValidatorFlushes() {
456
- return this.rollup.read.getAvailableValidatorFlushes();
646
+ async getAvailableValidatorFlushes(): Promise<number> {
647
+ return Number(await this.rollup.read.getAvailableValidatorFlushes());
457
648
  }
458
649
 
459
650
  async getNextFlushableEpoch(): Promise<EpochNumber> {
@@ -509,10 +700,11 @@ export class RollupContract {
509
700
  return EpochNumber.fromBigInt(await this.rollup.read.getEpochAtSlot([BigInt(slotNumber)]));
510
701
  }
511
702
 
512
- getEpochProofPublicInputs(
703
+ async getEpochProofPublicInputs(
513
704
  args: readonly [bigint, bigint, EpochProofPublicInputArgs, readonly `0x${string}`[], `0x${string}`],
514
- ) {
515
- return this.rollup.read.getEpochProofPublicInputs(args);
705
+ ): Promise<Fr[]> {
706
+ const result = await this.rollup.read.getEpochProofPublicInputs(args);
707
+ return result.map(Fr.fromString);
516
708
  }
517
709
 
518
710
  public async validateHeader(
@@ -617,6 +809,7 @@ export class RollupContract {
617
809
  ): L1TxRequest {
618
810
  return {
619
811
  to: this.address,
812
+ abi: RollupAbi,
620
813
  data: encodeFunctionData({
621
814
  abi: RollupAbi,
622
815
  functionName: 'invalidateBadAttestation',
@@ -638,6 +831,7 @@ export class RollupContract {
638
831
  ): L1TxRequest {
639
832
  return {
640
833
  to: this.address,
834
+ abi: RollupAbi,
641
835
  data: encodeFunctionData({
642
836
  abi: RollupAbi,
643
837
  functionName: 'invalidateInsufficientAttestations',
@@ -654,90 +848,124 @@ export class RollupContract {
654
848
  return this.rollup.read.getHasSubmitted([BigInt(epochNumber), BigInt(numberOfCheckpointsInEpoch), prover]);
655
849
  }
656
850
 
657
- getManaBaseFeeAt(timestamp: bigint, inFeeAsset: boolean) {
658
- return this.rollup.read.getManaBaseFeeAt([timestamp, inFeeAsset]);
851
+ getManaMinFeeAt(timestamp: bigint, inFeeAsset: boolean): Promise<bigint> {
852
+ return this.rollup.read.getManaMinFeeAt([timestamp, inFeeAsset]);
659
853
  }
660
854
 
661
855
  async getSlotAt(timestamp: bigint): Promise<SlotNumber> {
662
856
  return SlotNumber.fromBigInt(await this.rollup.read.getSlotAt([timestamp]));
663
857
  }
664
858
 
665
- async status(checkpointNumber: CheckpointNumber, options?: { blockNumber?: bigint }) {
859
+ async status(checkpointNumber: CheckpointNumber, options?: { blockNumber?: bigint }): Promise<RollupStatusResponse> {
666
860
  await checkBlockTag(options?.blockNumber, this.client);
667
- return this.rollup.read.status([BigInt(checkpointNumber)], 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
+ };
668
869
  }
669
870
 
670
- async canPruneAtTime(timestamp: bigint, options?: { blockNumber?: bigint }) {
871
+ async canPruneAtTime(timestamp: bigint, options?: { blockNumber?: bigint }): Promise<boolean> {
671
872
  await checkBlockTag(options?.blockNumber, this.client);
672
873
  return this.rollup.read.canPruneAtTime([timestamp], options);
673
874
  }
674
875
 
675
- archive() {
676
- return this.rollup.read.archive();
876
+ async archive(): Promise<Fr> {
877
+ return Fr.fromString(await this.rollup.read.archive());
677
878
  }
678
879
 
679
- archiveAt(checkpointNumber: CheckpointNumber) {
680
- return this.rollup.read.archiveAt([BigInt(checkpointNumber)]);
880
+ async archiveAt(checkpointNumber: CheckpointNumber): Promise<Fr> {
881
+ return Fr.fromString(await this.rollup.read.archiveAt([BigInt(checkpointNumber)]));
681
882
  }
682
883
 
683
- getSequencerRewards(address: Hex | EthAddress) {
884
+ getSequencerRewards(address: Hex | EthAddress): Promise<bigint> {
684
885
  if (address instanceof EthAddress) {
685
886
  address = address.toString();
686
887
  }
687
888
  return this.rollup.read.getSequencerRewards([address]);
688
889
  }
689
890
 
690
- getSpecificProverRewardsForEpoch(epoch: bigint, prover: Hex | EthAddress) {
891
+ getSpecificProverRewardsForEpoch(epoch: bigint, prover: Hex | EthAddress): Promise<bigint> {
691
892
  if (prover instanceof EthAddress) {
692
893
  prover = prover.toString();
693
894
  }
694
895
  return this.rollup.read.getSpecificProverRewardsForEpoch([epoch, prover]);
695
896
  }
696
897
 
697
- async getAttesters() {
898
+ async getAttesters(): Promise<EthAddress[]> {
698
899
  const attesterSize = await this.getActiveAttesterCount();
699
900
  const gse = new GSEContract(this.client, await this.getGSE());
700
901
  const ts = (await this.client.getBlock()).timestamp;
701
902
 
702
- const indices = Array.from({ length: Number(attesterSize) }, (_, i) => BigInt(i));
903
+ const indices = Array.from({ length: attesterSize }, (_, i) => BigInt(i));
703
904
  const chunks = chunk(indices, 1000);
704
905
 
705
- 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));
706
908
  }
707
909
 
708
- getAttesterView(address: Hex | EthAddress) {
910
+ async getAttesterView(address: Hex | EthAddress): Promise<AttesterView> {
709
911
  if (address instanceof EthAddress) {
710
912
  address = address.toString();
711
913
  }
712
- 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
+ };
713
934
  }
714
935
 
715
- getStatus(address: Hex | EthAddress) {
936
+ async getStatus(address: Hex | EthAddress): Promise<AttesterStatus> {
716
937
  if (address instanceof EthAddress) {
717
938
  address = address.toString();
718
939
  }
719
- return this.rollup.read.getStatus([address]);
940
+ return (await this.rollup.read.getStatus([address])) as AttesterStatus;
720
941
  }
721
942
 
722
- getBlobCommitmentsHash(checkpointNumber: CheckpointNumber) {
723
- return this.rollup.read.getBlobCommitmentsHash([BigInt(checkpointNumber)]);
943
+ async getBlobCommitmentsHash(checkpointNumber: CheckpointNumber): Promise<Buffer32> {
944
+ return Buffer32.fromString(await this.rollup.read.getBlobCommitmentsHash([BigInt(checkpointNumber)]));
724
945
  }
725
946
 
726
- getCurrentBlobCommitmentsHash() {
727
- return this.rollup.read.getCurrentBlobCommitmentsHash();
947
+ async getCurrentBlobCommitmentsHash(): Promise<Buffer32> {
948
+ return Buffer32.fromString(await this.rollup.read.getCurrentBlobCommitmentsHash());
728
949
  }
729
950
 
730
- getStakingAsset() {
731
- return this.rollup.read.getStakingAsset();
951
+ async getStakingAsset(): Promise<EthAddress> {
952
+ return EthAddress.fromString(await this.rollup.read.getStakingAsset());
732
953
  }
733
954
 
734
- getRewardConfig() {
735
- 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
+ };
736
963
  }
737
964
 
738
965
  setupEpoch(l1TxUtils: L1TxUtils) {
739
966
  return l1TxUtils.sendAndMonitorTransaction({
740
967
  to: this.address,
968
+ abi: RollupAbi,
741
969
  data: encodeFunctionData({
742
970
  abi: RollupAbi,
743
971
  functionName: 'setupEpoch',
@@ -749,6 +977,7 @@ export class RollupContract {
749
977
  vote(l1TxUtils: L1TxUtils, proposalId: bigint) {
750
978
  return l1TxUtils.sendAndMonitorTransaction({
751
979
  to: this.address,
980
+ abi: RollupAbi,
752
981
  data: encodeFunctionData({
753
982
  abi: RollupAbi,
754
983
  functionName: 'vote',
@@ -817,4 +1046,23 @@ export class RollupContract {
817
1046
  },
818
1047
  );
819
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: log.args.attestationsHash ? Buffer32.fromString(log.args.attestationsHash) : undefined,
1064
+ payloadDigest: log.args.payloadDigest ? Buffer32.fromString(log.args.payloadDigest) : undefined,
1065
+ },
1066
+ }));
1067
+ }
820
1068
  }