@aztec/ethereum 0.0.1-commit.9b94fc1 → 0.0.1-commit.9ee6fcc6

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