@aztec/ethereum 0.0.1-commit.d3ec352c → 0.0.1-commit.e3c1de76

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 (175) hide show
  1. package/dest/client.js +6 -2
  2. package/dest/config.d.ts +19 -68
  3. package/dest/config.d.ts.map +1 -1
  4. package/dest/config.js +51 -378
  5. package/dest/contracts/empire_base.d.ts +2 -1
  6. package/dest/contracts/empire_base.d.ts.map +1 -1
  7. package/dest/contracts/empire_slashing_proposer.d.ts +2 -1
  8. package/dest/contracts/empire_slashing_proposer.d.ts.map +1 -1
  9. package/dest/contracts/empire_slashing_proposer.js +22 -15
  10. package/dest/contracts/fee_asset_handler.d.ts +6 -5
  11. package/dest/contracts/fee_asset_handler.d.ts.map +1 -1
  12. package/dest/contracts/fee_asset_handler.js +11 -9
  13. package/dest/contracts/governance.d.ts +3 -1
  14. package/dest/contracts/governance.d.ts.map +1 -1
  15. package/dest/contracts/governance.js +11 -1
  16. package/dest/contracts/governance_proposer.d.ts +2 -1
  17. package/dest/contracts/governance_proposer.d.ts.map +1 -1
  18. package/dest/contracts/governance_proposer.js +395 -9
  19. package/dest/contracts/inbox.d.ts +24 -3
  20. package/dest/contracts/inbox.d.ts.map +1 -1
  21. package/dest/contracts/inbox.js +36 -1
  22. package/dest/contracts/index.d.ts +3 -1
  23. package/dest/contracts/index.d.ts.map +1 -1
  24. package/dest/contracts/index.js +2 -0
  25. package/dest/contracts/log.d.ts +13 -0
  26. package/dest/contracts/log.d.ts.map +1 -0
  27. package/dest/contracts/log.js +1 -0
  28. package/dest/contracts/multicall.d.ts +1 -1
  29. package/dest/contracts/multicall.d.ts.map +1 -1
  30. package/dest/contracts/multicall.js +2 -1
  31. package/dest/contracts/outbox.d.ts +41 -0
  32. package/dest/contracts/outbox.d.ts.map +1 -0
  33. package/dest/contracts/outbox.js +86 -0
  34. package/dest/contracts/rollup.d.ts +163 -83
  35. package/dest/contracts/rollup.d.ts.map +1 -1
  36. package/dest/contracts/rollup.js +686 -129
  37. package/dest/contracts/tally_slashing_proposer.d.ts +3 -2
  38. package/dest/contracts/tally_slashing_proposer.d.ts.map +1 -1
  39. package/dest/contracts/tally_slashing_proposer.js +8 -1
  40. package/dest/deploy_aztec_l1_contracts.d.ts +260 -0
  41. package/dest/deploy_aztec_l1_contracts.d.ts.map +1 -0
  42. package/dest/deploy_aztec_l1_contracts.js +398 -0
  43. package/dest/deploy_l1_contract.d.ts +68 -0
  44. package/dest/deploy_l1_contract.d.ts.map +1 -0
  45. package/dest/deploy_l1_contract.js +312 -0
  46. package/dest/forwarder_proxy.d.ts +32 -0
  47. package/dest/forwarder_proxy.d.ts.map +1 -0
  48. package/dest/forwarder_proxy.js +93 -0
  49. package/dest/generated/l1-contracts-defaults.d.ts +30 -0
  50. package/dest/generated/l1-contracts-defaults.d.ts.map +1 -0
  51. package/dest/generated/l1-contracts-defaults.js +30 -0
  52. package/dest/l1_artifacts.d.ts +4964 -1573
  53. package/dest/l1_artifacts.d.ts.map +1 -1
  54. package/dest/l1_contract_addresses.d.ts +1 -1
  55. package/dest/l1_contract_addresses.d.ts.map +1 -1
  56. package/dest/l1_contract_addresses.js +3 -3
  57. package/dest/l1_reader.d.ts +3 -1
  58. package/dest/l1_reader.d.ts.map +1 -1
  59. package/dest/l1_reader.js +6 -0
  60. package/dest/l1_tx_utils/config.d.ts +3 -3
  61. package/dest/l1_tx_utils/config.d.ts.map +1 -1
  62. package/dest/l1_tx_utils/config.js +17 -3
  63. package/dest/l1_tx_utils/constants.d.ts +8 -2
  64. package/dest/l1_tx_utils/constants.d.ts.map +1 -1
  65. package/dest/l1_tx_utils/constants.js +27 -2
  66. package/dest/l1_tx_utils/fee-strategies/index.d.ts +10 -0
  67. package/dest/l1_tx_utils/fee-strategies/index.d.ts.map +1 -0
  68. package/dest/l1_tx_utils/fee-strategies/index.js +12 -0
  69. package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts +8 -0
  70. package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts.map +1 -0
  71. package/dest/l1_tx_utils/fee-strategies/p75_competitive.js +129 -0
  72. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts +23 -0
  73. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts.map +1 -0
  74. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.js +191 -0
  75. package/dest/l1_tx_utils/fee-strategies/types.d.ts +51 -0
  76. package/dest/l1_tx_utils/fee-strategies/types.d.ts.map +1 -0
  77. package/dest/l1_tx_utils/fee-strategies/types.js +3 -0
  78. package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts +41 -0
  79. package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts.map +1 -0
  80. package/dest/l1_tx_utils/forwarder_l1_tx_utils.js +48 -0
  81. package/dest/l1_tx_utils/index-blobs.d.ts +3 -0
  82. package/dest/l1_tx_utils/index-blobs.d.ts.map +1 -0
  83. package/dest/l1_tx_utils/index-blobs.js +2 -0
  84. package/dest/l1_tx_utils/index.d.ts +3 -1
  85. package/dest/l1_tx_utils/index.d.ts.map +1 -1
  86. package/dest/l1_tx_utils/index.js +2 -0
  87. package/dest/l1_tx_utils/interfaces.d.ts +2 -2
  88. package/dest/l1_tx_utils/interfaces.d.ts.map +1 -1
  89. package/dest/l1_tx_utils/l1_fee_analyzer.d.ts +233 -0
  90. package/dest/l1_tx_utils/l1_fee_analyzer.d.ts.map +1 -0
  91. package/dest/l1_tx_utils/l1_fee_analyzer.js +506 -0
  92. package/dest/l1_tx_utils/l1_tx_utils.d.ts +1 -1
  93. package/dest/l1_tx_utils/l1_tx_utils.d.ts.map +1 -1
  94. package/dest/l1_tx_utils/l1_tx_utils.js +23 -10
  95. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts +4 -15
  96. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts.map +1 -1
  97. package/dest/l1_tx_utils/readonly_l1_tx_utils.js +53 -160
  98. package/dest/publisher_manager.d.ts +3 -2
  99. package/dest/publisher_manager.d.ts.map +1 -1
  100. package/dest/publisher_manager.js +2 -2
  101. package/dest/queries.d.ts +2 -2
  102. package/dest/queries.d.ts.map +1 -1
  103. package/dest/queries.js +12 -4
  104. package/dest/test/chain_monitor.d.ts +2 -2
  105. package/dest/test/chain_monitor.d.ts.map +1 -1
  106. package/dest/test/chain_monitor.js +1 -2
  107. package/dest/test/eth_cheat_codes.d.ts +13 -1
  108. package/dest/test/eth_cheat_codes.d.ts.map +1 -1
  109. package/dest/test/eth_cheat_codes.js +4 -2
  110. package/dest/test/rollup_cheat_codes.d.ts +6 -3
  111. package/dest/test/rollup_cheat_codes.d.ts.map +1 -1
  112. package/dest/test/rollup_cheat_codes.js +26 -4
  113. package/dest/test/start_anvil.d.ts +3 -1
  114. package/dest/test/start_anvil.d.ts.map +1 -1
  115. package/dest/test/start_anvil.js +1 -1
  116. package/dest/test/tx_delayer.d.ts +1 -1
  117. package/dest/test/tx_delayer.d.ts.map +1 -1
  118. package/dest/test/tx_delayer.js +4 -3
  119. package/dest/types.d.ts +57 -2
  120. package/dest/types.d.ts.map +1 -1
  121. package/dest/utils.d.ts +16 -3
  122. package/dest/utils.d.ts.map +1 -1
  123. package/dest/utils.js +64 -0
  124. package/package.json +31 -12
  125. package/src/client.ts +2 -2
  126. package/src/config.ts +62 -457
  127. package/src/contracts/README.md +157 -0
  128. package/src/contracts/empire_base.ts +1 -1
  129. package/src/contracts/empire_slashing_proposer.ts +22 -28
  130. package/src/contracts/fee_asset_handler.ts +10 -7
  131. package/src/contracts/governance.ts +10 -1
  132. package/src/contracts/governance_proposer.ts +10 -2
  133. package/src/contracts/inbox.ts +55 -3
  134. package/src/contracts/index.ts +2 -0
  135. package/src/contracts/log.ts +13 -0
  136. package/src/contracts/multicall.ts +5 -2
  137. package/src/contracts/outbox.ts +98 -0
  138. package/src/contracts/rollup.ts +355 -95
  139. package/src/contracts/tally_slashing_proposer.ts +7 -1
  140. package/src/deploy_aztec_l1_contracts.ts +619 -0
  141. package/src/deploy_l1_contract.ts +362 -0
  142. package/src/forwarder_proxy.ts +108 -0
  143. package/src/generated/l1-contracts-defaults.ts +32 -0
  144. package/src/l1_contract_addresses.ts +22 -20
  145. package/src/l1_reader.ts +8 -0
  146. package/src/l1_tx_utils/config.ts +24 -6
  147. package/src/l1_tx_utils/constants.ts +13 -2
  148. package/src/l1_tx_utils/fee-strategies/index.ts +22 -0
  149. package/src/l1_tx_utils/fee-strategies/p75_competitive.ts +163 -0
  150. package/src/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.ts +245 -0
  151. package/src/l1_tx_utils/fee-strategies/types.ts +56 -0
  152. package/src/l1_tx_utils/forwarder_l1_tx_utils.ts +119 -0
  153. package/src/l1_tx_utils/index-blobs.ts +2 -0
  154. package/src/l1_tx_utils/index.ts +2 -0
  155. package/src/l1_tx_utils/interfaces.ts +1 -1
  156. package/src/l1_tx_utils/l1_fee_analyzer.ts +803 -0
  157. package/src/l1_tx_utils/l1_tx_utils.ts +30 -10
  158. package/src/l1_tx_utils/readonly_l1_tx_utils.ts +67 -206
  159. package/src/publisher_manager.ts +4 -2
  160. package/src/queries.ts +11 -3
  161. package/src/test/chain_monitor.ts +3 -2
  162. package/src/test/eth_cheat_codes.ts +2 -2
  163. package/src/test/rollup_cheat_codes.ts +24 -5
  164. package/src/test/start_anvil.ts +3 -1
  165. package/src/test/tx_delayer.ts +5 -3
  166. package/src/types.ts +62 -0
  167. package/src/utils.ts +83 -1
  168. package/dest/deploy_l1_contracts.d.ts +0 -673
  169. package/dest/deploy_l1_contracts.d.ts.map +0 -1
  170. package/dest/deploy_l1_contracts.js +0 -1491
  171. package/dest/index.d.ts +0 -18
  172. package/dest/index.d.ts.map +0 -1
  173. package/dest/index.js +0 -17
  174. package/src/deploy_l1_contracts.ts +0 -1869
  175. package/src/index.ts +0 -17
@@ -1,7 +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';
7
+ import { makeBackoff, retry } from '@aztec/foundation/retry';
8
+ import { EscapeHatchAbi } from '@aztec/l1-artifacts/EscapeHatchAbi';
5
9
  import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
6
10
  import { RollupStorage } from '@aztec/l1-artifacts/RollupStorage';
7
11
 
@@ -19,7 +23,7 @@ import {
19
23
  } from 'viem';
20
24
 
21
25
  import { getPublicClient } from '../client.js';
22
- import type { DeployL1ContractsReturnType } from '../deploy_l1_contracts.js';
26
+ import type { DeployAztecL1ContractsReturnType } from '../deploy_aztec_l1_contracts.js';
23
27
  import type { L1ContractAddresses } from '../l1_contract_addresses.js';
24
28
  import type { L1ReaderConfig } from '../l1_reader.js';
25
29
  import type { L1TxRequest, L1TxUtils } from '../l1_tx_utils/index.js';
@@ -27,6 +31,7 @@ import type { ViemClient } from '../types.js';
27
31
  import { formatViemError } from '../utils.js';
28
32
  import { EmpireSlashingProposerContract } from './empire_slashing_proposer.js';
29
33
  import { GSEContract } from './gse.js';
34
+ import type { L1EventLog } from './log.js';
30
35
  import { SlasherContract } from './slasher_contract.js';
31
36
  import { TallySlashingProposerContract } from './tally_slashing_proposer.js';
32
37
  import { checkBlockTag } from './utils.js';
@@ -57,13 +62,16 @@ export type L1RollupContractAddresses = Pick<
57
62
  export type EpochProofPublicInputArgs = {
58
63
  previousArchive: `0x${string}`;
59
64
  endArchive: `0x${string}`;
65
+ outHash: `0x${string}`;
60
66
  proverId: `0x${string}`;
61
67
  };
62
68
 
63
69
  export type ViemHeader = {
64
70
  lastArchiveRoot: `0x${string}`;
65
71
  blockHeadersHash: `0x${string}`;
66
- contentCommitment: ViemContentCommitment;
72
+ blobsHash: `0x${string}`;
73
+ inHash: `0x${string}`;
74
+ outHash: `0x${string}`;
67
75
  slotNumber: bigint;
68
76
  timestamp: bigint;
69
77
  coinbase: `0x${string}`;
@@ -72,12 +80,6 @@ export type ViemHeader = {
72
80
  totalManaUsed: bigint;
73
81
  };
74
82
 
75
- export type ViemContentCommitment = {
76
- blobsHash: `0x${string}`;
77
- inHash: `0x${string}`;
78
- outHash: `0x${string}`;
79
- };
80
-
81
83
  export type ViemGasFees = {
82
84
  feePerDaGas: bigint;
83
85
  feePerL2Gas: bigint;
@@ -89,10 +91,125 @@ export enum SlashingProposerType {
89
91
  Empire = 2,
90
92
  }
91
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
+
92
205
  export class RollupContract {
93
206
  private readonly rollup: GetContractReturnType<typeof RollupAbi, ViemClient>;
94
207
 
95
208
  private static cachedStfStorageSlot: Hex | undefined;
209
+ private cachedEscapeHatch?: {
210
+ address: EthAddress;
211
+ contract: GetContractReturnType<typeof EscapeHatchAbi, ViemClient>;
212
+ };
96
213
 
97
214
  static get checkBlobStorageSlot(): bigint {
98
215
  const asString = RollupStorage.find(storage => storage.label === 'checkBlob')?.slot;
@@ -106,7 +223,7 @@ export class RollupContract {
106
223
  return (RollupContract.cachedStfStorageSlot ??= keccak256(Buffer.from('aztec.stf.storage', 'utf-8')));
107
224
  }
108
225
 
109
- static getFromL1ContractsValues(deployL1ContractsValues: DeployL1ContractsReturnType) {
226
+ static getFromL1ContractsValues(deployL1ContractsValues: DeployAztecL1ContractsReturnType) {
110
227
  const {
111
228
  l1Client,
112
229
  l1ContractAddresses: { rollupAddress },
@@ -130,8 +247,8 @@ export class RollupContract {
130
247
  this.rollup = getContract({ address, abi: RollupAbi, client });
131
248
  }
132
249
 
133
- getGSE() {
134
- return this.rollup.read.getGSE();
250
+ async getGSE(): Promise<EthAddress> {
251
+ return EthAddress.fromString(await this.rollup.read.getGSE());
135
252
  }
136
253
 
137
254
  public get address() {
@@ -173,23 +290,23 @@ export class RollupContract {
173
290
  }
174
291
 
175
292
  @memoize
176
- getL1StartBlock() {
293
+ getL1StartBlock(): Promise<bigint> {
177
294
  return this.rollup.read.L1_BLOCK_AT_GENESIS();
178
295
  }
179
296
 
180
297
  @memoize
181
- getL1GenesisTime() {
298
+ getL1GenesisTime(): Promise<bigint> {
182
299
  return this.rollup.read.getGenesisTime();
183
300
  }
184
301
 
185
302
  @memoize
186
- getProofSubmissionEpochs() {
187
- return this.rollup.read.getProofSubmissionEpochs();
303
+ async getProofSubmissionEpochs(): Promise<number> {
304
+ return Number(await this.rollup.read.getProofSubmissionEpochs());
188
305
  }
189
306
 
190
307
  @memoize
191
- getEpochDuration() {
192
- return this.rollup.read.getEpochDuration();
308
+ async getEpochDuration(): Promise<number> {
309
+ return Number(await this.rollup.read.getEpochDuration());
193
310
  }
194
311
 
195
312
  @memoize
@@ -198,68 +315,68 @@ export class RollupContract {
198
315
  }
199
316
 
200
317
  @memoize
201
- getTargetCommitteeSize() {
202
- return this.rollup.read.getTargetCommitteeSize();
318
+ async getTargetCommitteeSize(): Promise<number> {
319
+ return Number(await this.rollup.read.getTargetCommitteeSize());
203
320
  }
204
321
 
205
322
  @memoize
206
- getEjectionThreshold() {
323
+ getEjectionThreshold(): Promise<bigint> {
207
324
  return this.rollup.read.getEjectionThreshold();
208
325
  }
209
326
 
210
327
  @memoize
211
- getLocalEjectionThreshold() {
328
+ getLocalEjectionThreshold(): Promise<bigint> {
212
329
  return this.rollup.read.getLocalEjectionThreshold();
213
330
  }
214
331
 
215
332
  @memoize
216
- getLagInEpochsForValidatorSet() {
217
- return this.rollup.read.getLagInEpochsForValidatorSet();
333
+ async getLagInEpochsForValidatorSet(): Promise<number> {
334
+ return Number(await this.rollup.read.getLagInEpochsForValidatorSet());
218
335
  }
219
336
 
220
337
  @memoize
221
- getLagInEpochsForRandao() {
222
- return this.rollup.read.getLagInEpochsForRandao();
338
+ async getLagInEpochsForRandao(): Promise<number> {
339
+ return Number(await this.rollup.read.getLagInEpochsForRandao());
223
340
  }
224
341
 
225
342
  @memoize
226
- getActivationThreshold() {
343
+ getActivationThreshold(): Promise<bigint> {
227
344
  return this.rollup.read.getActivationThreshold();
228
345
  }
229
346
 
230
347
  @memoize
231
- getExitDelay() {
232
- return this.rollup.read.getExitDelay();
348
+ async getExitDelay(): Promise<number> {
349
+ return Number(await this.rollup.read.getExitDelay());
233
350
  }
234
351
 
235
352
  @memoize
236
- getManaTarget() {
353
+ getManaTarget(): Promise<bigint> {
237
354
  return this.rollup.read.getManaTarget();
238
355
  }
239
356
 
240
357
  @memoize
241
- getProvingCostPerMana() {
358
+ getProvingCostPerMana(): Promise<bigint> {
242
359
  return this.rollup.read.getProvingCostPerManaInEth();
243
360
  }
244
361
 
245
362
  @memoize
246
- getProvingCostPerManaInFeeAsset() {
363
+ getProvingCostPerManaInFeeAsset(): Promise<bigint> {
247
364
  return this.rollup.read.getProvingCostPerManaInFeeAsset();
248
365
  }
249
366
 
250
367
  @memoize
251
- getManaLimit() {
368
+ getManaLimit(): Promise<bigint> {
252
369
  return this.rollup.read.getManaLimit();
253
370
  }
254
371
 
255
372
  @memoize
256
- getVersion() {
373
+ getVersion(): Promise<bigint> {
257
374
  return this.rollup.read.getVersion();
258
375
  }
259
376
 
260
377
  @memoize
261
- async getGenesisArchiveTreeRoot(): Promise<`0x${string}`> {
262
- return await this.rollup.read.archiveAt([0n]);
378
+ async getGenesisArchiveTreeRoot(): Promise<Fr> {
379
+ return Fr.fromString(await this.rollup.read.archiveAt([0n]));
263
380
  }
264
381
 
265
382
  /**
@@ -291,27 +408,79 @@ export class RollupContract {
291
408
  };
292
409
  }
293
410
 
294
- getSlasherAddress() {
295
- return this.rollup.read.getSlasher();
411
+ async getSlasherAddress(): Promise<EthAddress> {
412
+ return EthAddress.fromString(await this.rollup.read.getSlasher());
413
+ }
414
+
415
+ /**
416
+ * Returns the configured escape hatch contract address, or zero if disabled.
417
+ */
418
+ async getEscapeHatchAddress(): Promise<EthAddress> {
419
+ return EthAddress.fromString(await this.rollup.read.getEscapeHatch());
420
+ }
421
+
422
+ private async getEscapeHatchContract(): Promise<
423
+ GetContractReturnType<typeof EscapeHatchAbi, ViemClient> | undefined
424
+ > {
425
+ const escapeHatchAddress = await this.getEscapeHatchAddress();
426
+ if (escapeHatchAddress.isZero()) {
427
+ return undefined;
428
+ }
429
+
430
+ // Cache the viem contract wrapper since it will be used frequently.
431
+ if (!this.cachedEscapeHatch || !this.cachedEscapeHatch.address.equals(escapeHatchAddress)) {
432
+ this.cachedEscapeHatch = {
433
+ address: escapeHatchAddress,
434
+ contract: getContract({
435
+ address: escapeHatchAddress.toString(),
436
+ abi: EscapeHatchAbi,
437
+ client: this.client,
438
+ }),
439
+ };
440
+ }
441
+
442
+ return this.cachedEscapeHatch.contract;
443
+ }
444
+
445
+ /**
446
+ * Returns whether the escape hatch is open for the given epoch.
447
+ * If escape hatch is not configured, returns false.
448
+ *
449
+ * This function is intentionally defensive: any failure to query the escape hatch
450
+ * (RPC issues, transient errors, etc.) is treated as "closed" to avoid callers
451
+ * needing to sprinkle try/catch everywhere.
452
+ */
453
+ async isEscapeHatchOpen(epoch: EpochNumber): Promise<boolean> {
454
+ try {
455
+ const escapeHatch = await this.getEscapeHatchContract();
456
+ if (!escapeHatch) {
457
+ return false;
458
+ }
459
+
460
+ const [isOpen] = await escapeHatch.read.isHatchOpen([BigInt(epoch)]);
461
+ return isOpen;
462
+ } catch {
463
+ return false;
464
+ }
296
465
  }
297
466
 
298
467
  /**
299
468
  * Returns a SlasherContract instance for interacting with the slasher contract.
300
469
  */
301
470
  async getSlasherContract(): Promise<SlasherContract | undefined> {
302
- const slasherAddress = EthAddress.fromString(await this.getSlasherAddress());
471
+ const slasherAddress = await this.getSlasherAddress();
303
472
  if (slasherAddress.isZero()) {
304
473
  return undefined;
305
474
  }
306
475
  return new SlasherContract(this.client, slasherAddress);
307
476
  }
308
477
 
309
- getOwner() {
310
- return this.rollup.read.owner();
478
+ async getOwner(): Promise<EthAddress> {
479
+ return EthAddress.fromString(await this.rollup.read.owner());
311
480
  }
312
481
 
313
- getActiveAttesterCount() {
314
- return this.rollup.read.getActiveAttesterCount();
482
+ async getActiveAttesterCount(): Promise<number> {
483
+ return Number(await this.rollup.read.getActiveAttesterCount());
315
484
  }
316
485
 
317
486
  public async getSlashingProposerAddress() {
@@ -322,7 +491,7 @@ export class RollupContract {
322
491
  return await slasher.getProposer();
323
492
  }
324
493
 
325
- getCheckpointReward() {
494
+ getCheckpointReward(): Promise<bigint> {
326
495
  return this.rollup.read.getCheckpointReward();
327
496
  }
328
497
 
@@ -338,15 +507,19 @@ export class RollupContract {
338
507
  return SlotNumber.fromBigInt(await this.rollup.read.getCurrentSlot());
339
508
  }
340
509
 
341
- getL1FeesAt(timestamp: bigint) {
342
- return this.rollup.read.getL1FeesAt([timestamp]);
510
+ async getL1FeesAt(timestamp: bigint): Promise<L1FeeData> {
511
+ const result = await this.rollup.read.getL1FeesAt([timestamp]);
512
+ return {
513
+ baseFee: result.baseFee,
514
+ blobFee: result.blobFee,
515
+ };
343
516
  }
344
517
 
345
- getFeeAssetPerEth() {
346
- return this.rollup.read.getFeeAssetPerEth();
518
+ getEthPerFeeAsset(): Promise<bigint> {
519
+ return this.rollup.read.getEthPerFeeAsset();
347
520
  }
348
521
 
349
- async getCommitteeAt(timestamp: bigint): Promise<readonly `0x${string}`[] | undefined> {
522
+ async getCommitteeAt(timestamp: bigint): Promise<EthAddress[] | undefined> {
350
523
  const { result } = await this.client
351
524
  .simulateContract({
352
525
  address: this.address,
@@ -361,22 +534,22 @@ export class RollupContract {
361
534
  throw e;
362
535
  });
363
536
 
364
- return result;
537
+ return result ? result.map(addr => EthAddress.fromString(addr)) : undefined;
365
538
  }
366
539
 
367
- getSampleSeedAt(timestamp: bigint) {
368
- return this.rollup.read.getSampleSeedAt([timestamp]);
540
+ async getSampleSeedAt(timestamp: bigint): Promise<Buffer32> {
541
+ return Buffer32.fromBigInt(await this.rollup.read.getSampleSeedAt([timestamp]));
369
542
  }
370
543
 
371
- getCurrentSampleSeed() {
372
- return this.rollup.read.getCurrentSampleSeed();
544
+ async getCurrentSampleSeed(): Promise<Buffer32> {
545
+ return Buffer32.fromBigInt(await this.rollup.read.getCurrentSampleSeed());
373
546
  }
374
547
 
375
548
  async getCurrentEpoch(): Promise<EpochNumber> {
376
549
  return EpochNumber.fromBigInt(await this.rollup.read.getCurrentEpoch());
377
550
  }
378
551
 
379
- async getCurrentEpochCommittee(): Promise<readonly `0x${string}`[] | undefined> {
552
+ async getCurrentEpochCommittee(): Promise<EthAddress[] | undefined> {
380
553
  const { result } = await this.client
381
554
  .simulateContract({
382
555
  address: this.address,
@@ -391,10 +564,10 @@ export class RollupContract {
391
564
  throw e;
392
565
  });
393
566
 
394
- return result;
567
+ return result ? result.map(addr => EthAddress.fromString(addr)) : undefined;
395
568
  }
396
569
 
397
- async getCurrentProposer() {
570
+ async getCurrentProposer(): Promise<EthAddress> {
398
571
  const { result } = await this.client.simulateContract({
399
572
  address: this.address,
400
573
  abi: RollupAbi,
@@ -402,10 +575,10 @@ export class RollupContract {
402
575
  args: [],
403
576
  });
404
577
 
405
- return result;
578
+ return EthAddress.fromString(result);
406
579
  }
407
580
 
408
- async getProposerAt(timestamp: bigint) {
581
+ async getProposerAt(timestamp: bigint): Promise<EthAddress> {
409
582
  const { result } = await this.client.simulateContract({
410
583
  address: this.address,
411
584
  abi: RollupAbi,
@@ -413,11 +586,41 @@ export class RollupContract {
413
586
  args: [timestamp],
414
587
  });
415
588
 
416
- return result;
589
+ return EthAddress.fromString(result);
590
+ }
591
+
592
+ async getCheckpoint(checkpointNumber: CheckpointNumber): Promise<CheckpointLog> {
593
+ const result = await this.rollup.read.getCheckpoint([BigInt(checkpointNumber)]);
594
+ return {
595
+ archive: Fr.fromString(result.archive),
596
+ headerHash: Buffer32.fromString(result.headerHash),
597
+ blobCommitmentsHash: Buffer32.fromString(result.blobCommitmentsHash),
598
+ attestationsHash: Buffer32.fromString(result.attestationsHash),
599
+ payloadDigest: Buffer32.fromString(result.payloadDigest),
600
+ slotNumber: SlotNumber.fromBigInt(result.slotNumber),
601
+ feeHeader: {
602
+ excessMana: result.feeHeader.excessMana,
603
+ manaUsed: result.feeHeader.manaUsed,
604
+ ethPerFeeAsset: result.feeHeader.ethPerFeeAsset,
605
+ congestionCost: result.feeHeader.congestionCost,
606
+ proverCost: result.feeHeader.proverCost,
607
+ },
608
+ };
417
609
  }
418
610
 
419
- getCheckpoint(checkpointNumber: CheckpointNumber) {
420
- return this.rollup.read.getCheckpoint([BigInt(checkpointNumber)]);
611
+ /** Returns the pending checkpoint from the rollup contract */
612
+ getPendingCheckpoint() {
613
+ // We retry because of race conditions during prunes: we may get a pending checkpoint number which is immediately
614
+ // reorged out due to a prune happening, causing the subsequent getCheckpoint call to fail. So we try again in that case.
615
+ return retry(
616
+ async () => {
617
+ const pendingCheckpointNumber = await this.getCheckpointNumber();
618
+ const pendingCheckpoint = await this.getCheckpoint(pendingCheckpointNumber);
619
+ return pendingCheckpoint;
620
+ },
621
+ 'getting pending checkpoint',
622
+ makeBackoff([0.5, 0.5, 0.5]),
623
+ );
421
624
  }
422
625
 
423
626
  async getTips(): Promise<{ pending: CheckpointNumber; proven: CheckpointNumber }> {
@@ -428,16 +631,16 @@ export class RollupContract {
428
631
  };
429
632
  }
430
633
 
431
- getTimestampForSlot(slot: SlotNumber) {
634
+ getTimestampForSlot(slot: SlotNumber): Promise<bigint> {
432
635
  return this.rollup.read.getTimestampForSlot([BigInt(slot)]);
433
636
  }
434
637
 
435
- getEntryQueueLength() {
436
- return this.rollup.read.getEntryQueueLength();
638
+ async getEntryQueueLength(): Promise<number> {
639
+ return Number(await this.rollup.read.getEntryQueueLength());
437
640
  }
438
641
 
439
- getAvailableValidatorFlushes() {
440
- return this.rollup.read.getAvailableValidatorFlushes();
642
+ async getAvailableValidatorFlushes(): Promise<number> {
643
+ return Number(await this.rollup.read.getAvailableValidatorFlushes());
441
644
  }
442
645
 
443
646
  async getNextFlushableEpoch(): Promise<EpochNumber> {
@@ -493,10 +696,11 @@ export class RollupContract {
493
696
  return EpochNumber.fromBigInt(await this.rollup.read.getEpochAtSlot([BigInt(slotNumber)]));
494
697
  }
495
698
 
496
- getEpochProofPublicInputs(
699
+ async getEpochProofPublicInputs(
497
700
  args: readonly [bigint, bigint, EpochProofPublicInputArgs, readonly `0x${string}`[], `0x${string}`],
498
- ) {
499
- return this.rollup.read.getEpochProofPublicInputs(args);
701
+ ): Promise<Fr[]> {
702
+ const result = await this.rollup.read.getEpochProofPublicInputs(args);
703
+ return result.map(Fr.fromString);
500
704
  }
501
705
 
502
706
  public async validateHeader(
@@ -601,6 +805,7 @@ export class RollupContract {
601
805
  ): L1TxRequest {
602
806
  return {
603
807
  to: this.address,
808
+ abi: RollupAbi,
604
809
  data: encodeFunctionData({
605
810
  abi: RollupAbi,
606
811
  functionName: 'invalidateBadAttestation',
@@ -622,6 +827,7 @@ export class RollupContract {
622
827
  ): L1TxRequest {
623
828
  return {
624
829
  to: this.address,
830
+ abi: RollupAbi,
625
831
  data: encodeFunctionData({
626
832
  abi: RollupAbi,
627
833
  functionName: 'invalidateInsufficientAttestations',
@@ -638,90 +844,124 @@ export class RollupContract {
638
844
  return this.rollup.read.getHasSubmitted([BigInt(epochNumber), BigInt(numberOfCheckpointsInEpoch), prover]);
639
845
  }
640
846
 
641
- getManaBaseFeeAt(timestamp: bigint, inFeeAsset: boolean) {
642
- return this.rollup.read.getManaBaseFeeAt([timestamp, inFeeAsset]);
847
+ getManaMinFeeAt(timestamp: bigint, inFeeAsset: boolean): Promise<bigint> {
848
+ return this.rollup.read.getManaMinFeeAt([timestamp, inFeeAsset]);
643
849
  }
644
850
 
645
851
  async getSlotAt(timestamp: bigint): Promise<SlotNumber> {
646
852
  return SlotNumber.fromBigInt(await this.rollup.read.getSlotAt([timestamp]));
647
853
  }
648
854
 
649
- async status(checkpointNumber: CheckpointNumber, options?: { blockNumber?: bigint }) {
855
+ async status(checkpointNumber: CheckpointNumber, options?: { blockNumber?: bigint }): Promise<RollupStatusResponse> {
650
856
  await checkBlockTag(options?.blockNumber, this.client);
651
- return this.rollup.read.status([BigInt(checkpointNumber)], options);
857
+ const result = await this.rollup.read.status([BigInt(checkpointNumber)], options);
858
+ return {
859
+ provenCheckpointNumber: CheckpointNumber.fromBigInt(result[0]),
860
+ provenArchive: Fr.fromString(result[1]),
861
+ pendingCheckpointNumber: CheckpointNumber.fromBigInt(result[2]),
862
+ pendingArchive: Fr.fromString(result[3]),
863
+ archiveOfMyCheckpoint: Fr.fromString(result[4]),
864
+ };
652
865
  }
653
866
 
654
- async canPruneAtTime(timestamp: bigint, options?: { blockNumber?: bigint }) {
867
+ async canPruneAtTime(timestamp: bigint, options?: { blockNumber?: bigint }): Promise<boolean> {
655
868
  await checkBlockTag(options?.blockNumber, this.client);
656
869
  return this.rollup.read.canPruneAtTime([timestamp], options);
657
870
  }
658
871
 
659
- archive() {
660
- return this.rollup.read.archive();
872
+ async archive(): Promise<Fr> {
873
+ return Fr.fromString(await this.rollup.read.archive());
661
874
  }
662
875
 
663
- archiveAt(checkpointNumber: CheckpointNumber) {
664
- return this.rollup.read.archiveAt([BigInt(checkpointNumber)]);
876
+ async archiveAt(checkpointNumber: CheckpointNumber): Promise<Fr> {
877
+ return Fr.fromString(await this.rollup.read.archiveAt([BigInt(checkpointNumber)]));
665
878
  }
666
879
 
667
- getSequencerRewards(address: Hex | EthAddress) {
880
+ getSequencerRewards(address: Hex | EthAddress): Promise<bigint> {
668
881
  if (address instanceof EthAddress) {
669
882
  address = address.toString();
670
883
  }
671
884
  return this.rollup.read.getSequencerRewards([address]);
672
885
  }
673
886
 
674
- getSpecificProverRewardsForEpoch(epoch: bigint, prover: Hex | EthAddress) {
887
+ getSpecificProverRewardsForEpoch(epoch: bigint, prover: Hex | EthAddress): Promise<bigint> {
675
888
  if (prover instanceof EthAddress) {
676
889
  prover = prover.toString();
677
890
  }
678
891
  return this.rollup.read.getSpecificProverRewardsForEpoch([epoch, prover]);
679
892
  }
680
893
 
681
- async getAttesters() {
894
+ async getAttesters(): Promise<EthAddress[]> {
682
895
  const attesterSize = await this.getActiveAttesterCount();
683
896
  const gse = new GSEContract(this.client, await this.getGSE());
684
897
  const ts = (await this.client.getBlock()).timestamp;
685
898
 
686
- const indices = Array.from({ length: Number(attesterSize) }, (_, i) => BigInt(i));
899
+ const indices = Array.from({ length: attesterSize }, (_, i) => BigInt(i));
687
900
  const chunks = chunk(indices, 1000);
688
901
 
689
- return (await Promise.all(chunks.map(chunk => gse.getAttestersFromIndicesAtTime(this.address, ts, chunk)))).flat();
902
+ const results = await Promise.all(chunks.map(chunk => gse.getAttestersFromIndicesAtTime(this.address, ts, chunk)));
903
+ return results.flat().map(addr => EthAddress.fromString(addr));
690
904
  }
691
905
 
692
- getAttesterView(address: Hex | EthAddress) {
906
+ async getAttesterView(address: Hex | EthAddress): Promise<AttesterView> {
693
907
  if (address instanceof EthAddress) {
694
908
  address = address.toString();
695
909
  }
696
- return this.rollup.read.getAttesterView([address]);
910
+ const result = await this.rollup.read.getAttesterView([address]);
911
+ return {
912
+ status: result.status as AttesterStatus,
913
+ effectiveBalance: result.effectiveBalance,
914
+ exit: {
915
+ withdrawalId: result.exit.withdrawalId,
916
+ amount: result.exit.amount,
917
+ exitableAt: result.exit.exitableAt,
918
+ recipientOrWithdrawer: EthAddress.fromString(result.exit.recipientOrWithdrawer),
919
+ isRecipient: result.exit.isRecipient,
920
+ exists: result.exit.exists,
921
+ },
922
+ config: {
923
+ publicKey: {
924
+ x: result.config.publicKey.x,
925
+ y: result.config.publicKey.y,
926
+ },
927
+ withdrawer: EthAddress.fromString(result.config.withdrawer),
928
+ },
929
+ };
697
930
  }
698
931
 
699
- getStatus(address: Hex | EthAddress) {
932
+ async getStatus(address: Hex | EthAddress): Promise<AttesterStatus> {
700
933
  if (address instanceof EthAddress) {
701
934
  address = address.toString();
702
935
  }
703
- return this.rollup.read.getStatus([address]);
936
+ return (await this.rollup.read.getStatus([address])) as AttesterStatus;
704
937
  }
705
938
 
706
- getBlobCommitmentsHash(checkpointNumber: CheckpointNumber) {
707
- return this.rollup.read.getBlobCommitmentsHash([BigInt(checkpointNumber)]);
939
+ async getBlobCommitmentsHash(checkpointNumber: CheckpointNumber): Promise<Buffer32> {
940
+ return Buffer32.fromString(await this.rollup.read.getBlobCommitmentsHash([BigInt(checkpointNumber)]));
708
941
  }
709
942
 
710
- getCurrentBlobCommitmentsHash() {
711
- return this.rollup.read.getCurrentBlobCommitmentsHash();
943
+ async getCurrentBlobCommitmentsHash(): Promise<Buffer32> {
944
+ return Buffer32.fromString(await this.rollup.read.getCurrentBlobCommitmentsHash());
712
945
  }
713
946
 
714
- getStakingAsset() {
715
- return this.rollup.read.getStakingAsset();
947
+ async getStakingAsset(): Promise<EthAddress> {
948
+ return EthAddress.fromString(await this.rollup.read.getStakingAsset());
716
949
  }
717
950
 
718
- getRewardConfig() {
719
- return this.rollup.read.getRewardConfig();
951
+ async getRewardConfig(): Promise<RewardConfig> {
952
+ const result = await this.rollup.read.getRewardConfig();
953
+ return {
954
+ rewardDistributor: EthAddress.fromString(result.rewardDistributor),
955
+ sequencerBps: BigInt(result.sequencerBps),
956
+ booster: EthAddress.fromString(result.booster),
957
+ checkpointReward: result.checkpointReward,
958
+ };
720
959
  }
721
960
 
722
961
  setupEpoch(l1TxUtils: L1TxUtils) {
723
962
  return l1TxUtils.sendAndMonitorTransaction({
724
963
  to: this.address,
964
+ abi: RollupAbi,
725
965
  data: encodeFunctionData({
726
966
  abi: RollupAbi,
727
967
  functionName: 'setupEpoch',
@@ -733,6 +973,7 @@ export class RollupContract {
733
973
  vote(l1TxUtils: L1TxUtils, proposalId: bigint) {
734
974
  return l1TxUtils.sendAndMonitorTransaction({
735
975
  to: this.address,
976
+ abi: RollupAbi,
736
977
  data: encodeFunctionData({
737
978
  abi: RollupAbi,
738
979
  functionName: 'vote',
@@ -801,4 +1042,23 @@ export class RollupContract {
801
1042
  },
802
1043
  );
803
1044
  }
1045
+
1046
+ /** Fetches CheckpointProposed events within the given block range. */
1047
+ async getCheckpointProposedEvents(fromBlock: bigint, toBlock: bigint): Promise<CheckpointProposedLog[]> {
1048
+ const logs = await this.rollup.getEvents.CheckpointProposed({}, { fromBlock, toBlock });
1049
+ return logs
1050
+ .filter(log => log.blockNumber! >= fromBlock && log.blockNumber! <= toBlock)
1051
+ .map(log => ({
1052
+ l1BlockNumber: log.blockNumber!,
1053
+ l1BlockHash: Buffer32.fromString(log.blockHash!),
1054
+ l1TransactionHash: log.transactionHash!,
1055
+ args: {
1056
+ checkpointNumber: CheckpointNumber.fromBigInt(log.args.checkpointNumber!),
1057
+ archive: Fr.fromString(log.args.archive!),
1058
+ versionedBlobHashes: log.args.versionedBlobHashes!.map(h => Buffer.from(h.slice(2), 'hex')),
1059
+ attestationsHash: log.args.attestationsHash ? Buffer32.fromString(log.args.attestationsHash) : undefined,
1060
+ payloadDigest: log.args.payloadDigest ? Buffer32.fromString(log.args.payloadDigest) : undefined,
1061
+ },
1062
+ }));
1063
+ }
804
1064
  }