@aztec/ethereum 4.0.0-nightly.20250907 → 4.0.0-nightly.20260107

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. package/dest/account.d.ts +1 -1
  2. package/dest/chain.d.ts +1 -1
  3. package/dest/client.d.ts +2 -2
  4. package/dest/client.d.ts.map +1 -1
  5. package/dest/client.js +6 -2
  6. package/dest/config.d.ts +18 -46
  7. package/dest/config.d.ts.map +1 -1
  8. package/dest/config.js +40 -285
  9. package/dest/constants.d.ts +1 -1
  10. package/dest/contracts/empire_base.d.ts +8 -6
  11. package/dest/contracts/empire_base.d.ts.map +1 -1
  12. package/dest/contracts/empire_base.js +1 -1
  13. package/dest/contracts/empire_slashing_proposer.d.ts +8 -6
  14. package/dest/contracts/empire_slashing_proposer.d.ts.map +1 -1
  15. package/dest/contracts/empire_slashing_proposer.js +18 -3
  16. package/dest/contracts/errors.d.ts +1 -1
  17. package/dest/contracts/errors.d.ts.map +1 -1
  18. package/dest/contracts/fee_asset_handler.d.ts +4 -4
  19. package/dest/contracts/fee_asset_handler.d.ts.map +1 -1
  20. package/dest/contracts/fee_juice.d.ts +1 -1
  21. package/dest/contracts/fee_juice.d.ts.map +1 -1
  22. package/dest/contracts/governance.d.ts +16 -16
  23. package/dest/contracts/governance.d.ts.map +1 -1
  24. package/dest/contracts/governance.js +7 -3
  25. package/dest/contracts/governance_proposer.d.ts +7 -6
  26. package/dest/contracts/governance_proposer.d.ts.map +1 -1
  27. package/dest/contracts/governance_proposer.js +400 -12
  28. package/dest/contracts/gse.d.ts +1 -1
  29. package/dest/contracts/gse.d.ts.map +1 -1
  30. package/dest/contracts/inbox.d.ts +7 -3
  31. package/dest/contracts/inbox.d.ts.map +1 -1
  32. package/dest/contracts/inbox.js +4 -0
  33. package/dest/contracts/index.d.ts +1 -1
  34. package/dest/contracts/multicall.d.ts +5 -7
  35. package/dest/contracts/multicall.d.ts.map +1 -1
  36. package/dest/contracts/multicall.js +6 -4
  37. package/dest/contracts/registry.d.ts +1 -1
  38. package/dest/contracts/registry.d.ts.map +1 -1
  39. package/dest/contracts/rollup.d.ts +168 -117
  40. package/dest/contracts/rollup.d.ts.map +1 -1
  41. package/dest/contracts/rollup.js +712 -241
  42. package/dest/contracts/slasher_contract.d.ts +11 -1
  43. package/dest/contracts/slasher_contract.d.ts.map +1 -1
  44. package/dest/contracts/slasher_contract.js +18 -0
  45. package/dest/contracts/tally_slashing_proposer.d.ts +15 -7
  46. package/dest/contracts/tally_slashing_proposer.d.ts.map +1 -1
  47. package/dest/contracts/tally_slashing_proposer.js +15 -5
  48. package/dest/contracts/utils.d.ts +1 -1
  49. package/dest/deploy_aztec_l1_contracts.d.ts +247 -0
  50. package/dest/deploy_aztec_l1_contracts.d.ts.map +1 -0
  51. package/dest/deploy_aztec_l1_contracts.js +336 -0
  52. package/dest/deploy_l1_contract.d.ts +68 -0
  53. package/dest/deploy_l1_contract.d.ts.map +1 -0
  54. package/dest/deploy_l1_contract.js +312 -0
  55. package/dest/eth-signer/eth-signer.d.ts +1 -1
  56. package/dest/eth-signer/index.d.ts +1 -1
  57. package/dest/forwarder_proxy.d.ts +32 -0
  58. package/dest/forwarder_proxy.d.ts.map +1 -0
  59. package/dest/forwarder_proxy.js +93 -0
  60. package/dest/l1_artifacts.d.ts +17698 -6245
  61. package/dest/l1_artifacts.d.ts.map +1 -1
  62. package/dest/l1_artifacts.js +10 -5
  63. package/dest/l1_contract_addresses.d.ts +8 -4
  64. package/dest/l1_contract_addresses.d.ts.map +1 -1
  65. package/dest/l1_contract_addresses.js +5 -4
  66. package/dest/l1_reader.d.ts +4 -2
  67. package/dest/l1_reader.d.ts.map +1 -1
  68. package/dest/l1_reader.js +7 -1
  69. package/dest/l1_tx_utils/config.d.ts +59 -0
  70. package/dest/l1_tx_utils/config.d.ts.map +1 -0
  71. package/dest/l1_tx_utils/config.js +96 -0
  72. package/dest/l1_tx_utils/constants.d.ts +12 -0
  73. package/dest/l1_tx_utils/constants.d.ts.map +1 -0
  74. package/dest/l1_tx_utils/constants.js +39 -0
  75. package/dest/l1_tx_utils/factory.d.ts +24 -0
  76. package/dest/l1_tx_utils/factory.d.ts.map +1 -0
  77. package/dest/l1_tx_utils/factory.js +12 -0
  78. package/dest/l1_tx_utils/fee-strategies/index.d.ts +10 -0
  79. package/dest/l1_tx_utils/fee-strategies/index.d.ts.map +1 -0
  80. package/dest/l1_tx_utils/fee-strategies/index.js +12 -0
  81. package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts +8 -0
  82. package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts.map +1 -0
  83. package/dest/l1_tx_utils/fee-strategies/p75_competitive.js +129 -0
  84. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts +23 -0
  85. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts.map +1 -0
  86. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.js +191 -0
  87. package/dest/l1_tx_utils/fee-strategies/types.d.ts +51 -0
  88. package/dest/l1_tx_utils/fee-strategies/types.d.ts.map +1 -0
  89. package/dest/l1_tx_utils/fee-strategies/types.js +3 -0
  90. package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts +41 -0
  91. package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts.map +1 -0
  92. package/dest/l1_tx_utils/forwarder_l1_tx_utils.js +48 -0
  93. package/dest/l1_tx_utils/index-blobs.d.ts +3 -0
  94. package/dest/l1_tx_utils/index-blobs.d.ts.map +1 -0
  95. package/dest/l1_tx_utils/index-blobs.js +2 -0
  96. package/dest/l1_tx_utils/index.d.ts +12 -0
  97. package/dest/l1_tx_utils/index.d.ts.map +1 -0
  98. package/dest/l1_tx_utils/index.js +12 -0
  99. package/dest/l1_tx_utils/interfaces.d.ts +76 -0
  100. package/dest/l1_tx_utils/interfaces.d.ts.map +1 -0
  101. package/dest/l1_tx_utils/interfaces.js +4 -0
  102. package/dest/l1_tx_utils/l1_fee_analyzer.d.ts +233 -0
  103. package/dest/l1_tx_utils/l1_fee_analyzer.d.ts.map +1 -0
  104. package/dest/l1_tx_utils/l1_fee_analyzer.js +506 -0
  105. package/dest/l1_tx_utils/l1_tx_utils.d.ts +94 -0
  106. package/dest/l1_tx_utils/l1_tx_utils.d.ts.map +1 -0
  107. package/dest/l1_tx_utils/l1_tx_utils.js +623 -0
  108. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts +26 -0
  109. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts.map +1 -0
  110. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.js +26 -0
  111. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts +83 -0
  112. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts.map +1 -0
  113. package/dest/l1_tx_utils/readonly_l1_tx_utils.js +323 -0
  114. package/dest/l1_tx_utils/signer.d.ts +4 -0
  115. package/dest/l1_tx_utils/signer.d.ts.map +1 -0
  116. package/dest/l1_tx_utils/signer.js +16 -0
  117. package/dest/l1_tx_utils/types.d.ts +67 -0
  118. package/dest/l1_tx_utils/types.d.ts.map +1 -0
  119. package/dest/l1_tx_utils/types.js +26 -0
  120. package/dest/l1_tx_utils/utils.d.ts +4 -0
  121. package/dest/l1_tx_utils/utils.d.ts.map +1 -0
  122. package/dest/l1_tx_utils/utils.js +14 -0
  123. package/dest/l1_types.d.ts +1 -1
  124. package/dest/publisher_manager.d.ts +8 -3
  125. package/dest/publisher_manager.d.ts.map +1 -1
  126. package/dest/publisher_manager.js +36 -8
  127. package/dest/queries.d.ts +1 -1
  128. package/dest/queries.d.ts.map +1 -1
  129. package/dest/queries.js +20 -14
  130. package/dest/test/chain_monitor.d.ts +29 -22
  131. package/dest/test/chain_monitor.d.ts.map +1 -1
  132. package/dest/test/chain_monitor.js +81 -38
  133. package/dest/test/delayed_tx_utils.d.ts +3 -3
  134. package/dest/test/delayed_tx_utils.d.ts.map +1 -1
  135. package/dest/test/delayed_tx_utils.js +2 -2
  136. package/dest/test/eth_cheat_codes.d.ts +36 -14
  137. package/dest/test/eth_cheat_codes.d.ts.map +1 -1
  138. package/dest/test/eth_cheat_codes.js +126 -31
  139. package/dest/test/eth_cheat_codes_with_state.d.ts +1 -1
  140. package/dest/test/eth_cheat_codes_with_state.d.ts.map +1 -1
  141. package/dest/test/index.d.ts +1 -1
  142. package/dest/test/rollup_cheat_codes.d.ts +23 -20
  143. package/dest/test/rollup_cheat_codes.d.ts.map +1 -1
  144. package/dest/test/rollup_cheat_codes.js +82 -43
  145. package/dest/test/start_anvil.d.ts +4 -1
  146. package/dest/test/start_anvil.d.ts.map +1 -1
  147. package/dest/test/start_anvil.js +2 -1
  148. package/dest/test/tx_delayer.d.ts +1 -1
  149. package/dest/test/tx_delayer.d.ts.map +1 -1
  150. package/dest/test/tx_delayer.js +4 -3
  151. package/dest/test/upgrade_utils.d.ts +1 -1
  152. package/dest/test/upgrade_utils.d.ts.map +1 -1
  153. package/dest/test/upgrade_utils.js +3 -2
  154. package/dest/types.d.ts +57 -2
  155. package/dest/types.d.ts.map +1 -1
  156. package/dest/utils.d.ts +15 -3
  157. package/dest/utils.d.ts.map +1 -1
  158. package/dest/utils.js +28 -161
  159. package/dest/zkPassportVerifierAddress.d.ts +1 -1
  160. package/dest/zkPassportVerifierAddress.js +1 -1
  161. package/package.json +33 -14
  162. package/src/client.ts +3 -3
  163. package/src/config.ts +49 -358
  164. package/src/contracts/empire_base.ts +7 -6
  165. package/src/contracts/empire_slashing_proposer.ts +23 -8
  166. package/src/contracts/fee_asset_handler.ts +1 -1
  167. package/src/contracts/governance.ts +3 -3
  168. package/src/contracts/governance_proposer.ts +19 -9
  169. package/src/contracts/inbox.ts +7 -2
  170. package/src/contracts/multicall.ts +12 -10
  171. package/src/contracts/rollup.ts +373 -235
  172. package/src/contracts/slasher_contract.ts +22 -0
  173. package/src/contracts/tally_slashing_proposer.ts +21 -9
  174. package/src/deploy_aztec_l1_contracts.ts +557 -0
  175. package/src/deploy_l1_contract.ts +362 -0
  176. package/src/forwarder_proxy.ts +108 -0
  177. package/src/l1_artifacts.ts +14 -6
  178. package/src/l1_contract_addresses.ts +24 -20
  179. package/src/l1_reader.ts +10 -2
  180. package/src/l1_tx_utils/README.md +177 -0
  181. package/src/l1_tx_utils/config.ts +161 -0
  182. package/src/l1_tx_utils/constants.ts +29 -0
  183. package/src/l1_tx_utils/factory.ts +64 -0
  184. package/src/l1_tx_utils/fee-strategies/index.ts +22 -0
  185. package/src/l1_tx_utils/fee-strategies/p75_competitive.ts +163 -0
  186. package/src/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.ts +245 -0
  187. package/src/l1_tx_utils/fee-strategies/types.ts +56 -0
  188. package/src/l1_tx_utils/forwarder_l1_tx_utils.ts +119 -0
  189. package/src/l1_tx_utils/index-blobs.ts +2 -0
  190. package/src/l1_tx_utils/index.ts +14 -0
  191. package/src/l1_tx_utils/interfaces.ts +86 -0
  192. package/src/l1_tx_utils/l1_fee_analyzer.ts +803 -0
  193. package/src/l1_tx_utils/l1_tx_utils.ts +738 -0
  194. package/src/l1_tx_utils/l1_tx_utils_with_blobs.ts +77 -0
  195. package/src/l1_tx_utils/readonly_l1_tx_utils.ts +419 -0
  196. package/src/l1_tx_utils/signer.ts +28 -0
  197. package/src/l1_tx_utils/types.ts +85 -0
  198. package/src/l1_tx_utils/utils.ts +16 -0
  199. package/src/publisher_manager.ts +51 -9
  200. package/src/queries.ts +24 -10
  201. package/src/test/chain_monitor.ts +102 -44
  202. package/src/test/delayed_tx_utils.ts +2 -2
  203. package/src/test/eth_cheat_codes.ts +150 -31
  204. package/src/test/rollup_cheat_codes.ts +95 -53
  205. package/src/test/start_anvil.ts +4 -0
  206. package/src/test/tx_delayer.ts +5 -3
  207. package/src/test/upgrade_utils.ts +3 -2
  208. package/src/types.ts +62 -0
  209. package/src/utils.ts +41 -184
  210. package/src/zkPassportVerifierAddress.ts +1 -1
  211. package/dest/deploy_l1_contracts.d.ts +0 -211
  212. package/dest/deploy_l1_contracts.d.ts.map +0 -1
  213. package/dest/deploy_l1_contracts.js +0 -1267
  214. package/dest/index.d.ts +0 -18
  215. package/dest/index.d.ts.map +0 -1
  216. package/dest/index.js +0 -17
  217. package/dest/l1_tx_utils.d.ts +0 -250
  218. package/dest/l1_tx_utils.d.ts.map +0 -1
  219. package/dest/l1_tx_utils.js +0 -826
  220. package/dest/l1_tx_utils_with_blobs.d.ts +0 -19
  221. package/dest/l1_tx_utils_with_blobs.d.ts.map +0 -1
  222. package/dest/l1_tx_utils_with_blobs.js +0 -85
  223. package/src/deploy_l1_contracts.ts +0 -1596
  224. package/src/index.ts +0 -17
  225. package/src/l1_tx_utils.ts +0 -1105
  226. package/src/l1_tx_utils_with_blobs.ts +0 -144
@@ -1,9 +1,12 @@
1
+ import { CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
2
+ import { Buffer32 } from '@aztec/foundation/buffer';
3
+ import { Fr } from '@aztec/foundation/curves/bn254';
1
4
  import { memoize } from '@aztec/foundation/decorators';
2
5
  import { EthAddress } from '@aztec/foundation/eth-address';
3
6
  import type { ViemSignature } from '@aztec/foundation/eth-signature';
7
+ import { makeBackoff, retry } from '@aztec/foundation/retry';
4
8
  import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
5
9
  import { RollupStorage } from '@aztec/l1-artifacts/RollupStorage';
6
- import { SlasherAbi } from '@aztec/l1-artifacts/SlasherAbi';
7
10
 
8
11
  import chunk from 'lodash.chunk';
9
12
  import {
@@ -11,18 +14,18 @@ import {
11
14
  type GetContractReturnType,
12
15
  type Hex,
13
16
  type StateOverride,
17
+ type WatchContractEventReturnType,
14
18
  encodeFunctionData,
15
- getAddress,
16
19
  getContract,
17
20
  hexToBigInt,
18
21
  keccak256,
19
22
  } from 'viem';
20
23
 
21
24
  import { getPublicClient } from '../client.js';
22
- import type { DeployL1ContractsReturnType } from '../deploy_l1_contracts.js';
25
+ import type { DeployAztecL1ContractsReturnType } from '../deploy_aztec_l1_contracts.js';
23
26
  import type { L1ContractAddresses } from '../l1_contract_addresses.js';
24
27
  import type { L1ReaderConfig } from '../l1_reader.js';
25
- import type { L1TxRequest, L1TxUtils } from '../l1_tx_utils.js';
28
+ import type { L1TxRequest, L1TxUtils } from '../l1_tx_utils/index.js';
26
29
  import type { ViemClient } from '../types.js';
27
30
  import { formatViemError } from '../utils.js';
28
31
  import { EmpireSlashingProposerContract } from './empire_slashing_proposer.js';
@@ -62,6 +65,7 @@ export type EpochProofPublicInputArgs = {
62
65
 
63
66
  export type ViemHeader = {
64
67
  lastArchiveRoot: `0x${string}`;
68
+ blockHeadersHash: `0x${string}`;
65
69
  contentCommitment: ViemContentCommitment;
66
70
  slotNumber: bigint;
67
71
  timestamp: bigint;
@@ -82,27 +86,108 @@ export type ViemGasFees = {
82
86
  feePerL2Gas: bigint;
83
87
  };
84
88
 
85
- export type ViemStateReference = {
86
- l1ToL2MessageTree: ViemAppendOnlyTreeSnapshot;
87
- partialStateReference: ViemPartialStateReference;
89
+ export enum SlashingProposerType {
90
+ None = 0,
91
+ Tally = 1,
92
+ Empire = 2,
93
+ }
94
+
95
+ /**
96
+ * Status of a validator/attester in the staking system.
97
+ * Matches the Status enum in StakingLib.sol
98
+ */
99
+ export enum AttesterStatus {
100
+ NONE = 0,
101
+ VALIDATING = 1,
102
+ ZOMBIE = 2,
103
+ EXITING = 3,
104
+ }
105
+
106
+ /**
107
+ * Fee header data for a checkpoint
108
+ */
109
+ export type FeeHeader = {
110
+ excessMana: bigint;
111
+ manaUsed: bigint;
112
+ feeAssetPriceNumerator: bigint;
113
+ congestionCost: bigint;
114
+ proverCost: bigint;
88
115
  };
89
116
 
90
- export type ViemPartialStateReference = {
91
- noteHashTree: ViemAppendOnlyTreeSnapshot;
92
- nullifierTree: ViemAppendOnlyTreeSnapshot;
93
- publicDataTree: ViemAppendOnlyTreeSnapshot;
117
+ /**
118
+ * Checkpoint log data returned from the rollup contract
119
+ */
120
+ export type CheckpointLog = {
121
+ archive: Fr;
122
+ headerHash: Buffer32;
123
+ blobCommitmentsHash: Buffer32;
124
+ attestationsHash: Buffer32;
125
+ payloadDigest: Buffer32;
126
+ slotNumber: SlotNumber;
127
+ feeHeader: FeeHeader;
94
128
  };
95
129
 
96
- export type ViemAppendOnlyTreeSnapshot = {
97
- root: `0x${string}`;
98
- nextAvailableLeafIndex: number;
130
+ /**
131
+ * L1 fee data (base fee and blob fee)
132
+ */
133
+ export type L1FeeData = {
134
+ baseFee: bigint;
135
+ blobFee: bigint;
99
136
  };
100
137
 
101
- export enum SlashingProposerType {
102
- None = 0,
103
- Tally = 1,
104
- Empire = 2,
105
- }
138
+ /**
139
+ * Reward configuration for the rollup
140
+ */
141
+ export type RewardConfig = {
142
+ rewardDistributor: EthAddress;
143
+ sequencerBps: bigint;
144
+ booster: EthAddress;
145
+ checkpointReward: bigint;
146
+ };
147
+
148
+ /**
149
+ * Exit information for a validator
150
+ */
151
+ export type Exit = {
152
+ withdrawalId: bigint;
153
+ amount: bigint;
154
+ exitableAt: bigint;
155
+ recipientOrWithdrawer: EthAddress;
156
+ isRecipient: boolean;
157
+ exists: boolean;
158
+ };
159
+
160
+ /**
161
+ * Attester configuration including public key and withdrawer
162
+ */
163
+ export type AttesterConfig = {
164
+ publicKey: {
165
+ x: bigint;
166
+ y: bigint;
167
+ };
168
+ withdrawer: EthAddress;
169
+ };
170
+
171
+ /**
172
+ * Complete view of an attester's state
173
+ */
174
+ export type AttesterView = {
175
+ status: AttesterStatus;
176
+ effectiveBalance: bigint;
177
+ exit: Exit;
178
+ config: AttesterConfig;
179
+ };
180
+
181
+ /**
182
+ * Return for a status call
183
+ */
184
+ export type RollupStatusResponse = {
185
+ provenCheckpointNumber: CheckpointNumber;
186
+ provenArchive: Fr;
187
+ pendingCheckpointNumber: CheckpointNumber;
188
+ pendingArchive: Fr;
189
+ archiveOfMyCheckpoint: Fr;
190
+ };
106
191
 
107
192
  export class RollupContract {
108
193
  private readonly rollup: GetContractReturnType<typeof RollupAbi, ViemClient>;
@@ -121,7 +206,7 @@ export class RollupContract {
121
206
  return (RollupContract.cachedStfStorageSlot ??= keccak256(Buffer.from('aztec.stf.storage', 'utf-8')));
122
207
  }
123
208
 
124
- static getFromL1ContractsValues(deployL1ContractsValues: DeployL1ContractsReturnType) {
209
+ static getFromL1ContractsValues(deployL1ContractsValues: DeployAztecL1ContractsReturnType) {
125
210
  const {
126
211
  l1Client,
127
212
  l1ContractAddresses: { rollupAddress },
@@ -145,8 +230,8 @@ export class RollupContract {
145
230
  this.rollup = getContract({ address, abi: RollupAbi, client });
146
231
  }
147
232
 
148
- getGSE() {
149
- return this.rollup.read.getGSE();
233
+ async getGSE(): Promise<EthAddress> {
234
+ return EthAddress.fromString(await this.rollup.read.getGSE());
150
235
  }
151
236
 
152
237
  public get address() {
@@ -160,13 +245,12 @@ export class RollupContract {
160
245
  public async getSlashingProposer(): Promise<
161
246
  EmpireSlashingProposerContract | TallySlashingProposerContract | undefined
162
247
  > {
163
- const slasherAddress = await this.rollup.read.getSlasher();
164
- if (EthAddress.fromString(slasherAddress).isZero()) {
248
+ const slasher = await this.getSlasherContract();
249
+ if (!slasher) {
165
250
  return undefined;
166
251
  }
167
252
 
168
- const slasher = getContract({ address: slasherAddress, abi: SlasherAbi, client: this.client });
169
- const proposerAddress = await slasher.read.PROPOSER();
253
+ const proposerAddress = await slasher.getProposer();
170
254
  const proposerAbi = [
171
255
  {
172
256
  type: 'function',
@@ -177,7 +261,7 @@ export class RollupContract {
177
261
  },
178
262
  ] as const;
179
263
 
180
- const proposer = getContract({ address: proposerAddress, abi: proposerAbi, client: this.client });
264
+ const proposer = getContract({ address: proposerAddress.toString(), abi: proposerAbi, client: this.client });
181
265
  const proposerType = await proposer.read.SLASHING_PROPOSER_TYPE();
182
266
  if (proposerType === SlashingProposerType.Tally.valueOf()) {
183
267
  return new TallySlashingProposerContract(this.client, proposerAddress);
@@ -189,79 +273,93 @@ export class RollupContract {
189
273
  }
190
274
 
191
275
  @memoize
192
- getL1StartBlock() {
276
+ getL1StartBlock(): Promise<bigint> {
193
277
  return this.rollup.read.L1_BLOCK_AT_GENESIS();
194
278
  }
195
279
 
196
280
  @memoize
197
- getL1GenesisTime() {
281
+ getL1GenesisTime(): Promise<bigint> {
198
282
  return this.rollup.read.getGenesisTime();
199
283
  }
200
284
 
201
285
  @memoize
202
- getProofSubmissionEpochs() {
203
- return this.rollup.read.getProofSubmissionEpochs();
286
+ async getProofSubmissionEpochs(): Promise<number> {
287
+ return Number(await this.rollup.read.getProofSubmissionEpochs());
204
288
  }
205
289
 
206
290
  @memoize
207
- getEpochDuration() {
208
- return this.rollup.read.getEpochDuration();
291
+ async getEpochDuration(): Promise<number> {
292
+ return Number(await this.rollup.read.getEpochDuration());
209
293
  }
210
294
 
211
295
  @memoize
212
- getSlotDuration() {
213
- return this.rollup.read.getSlotDuration();
296
+ async getSlotDuration(): Promise<number> {
297
+ return Number(await this.rollup.read.getSlotDuration());
214
298
  }
215
299
 
216
300
  @memoize
217
- getTargetCommitteeSize() {
218
- return this.rollup.read.getTargetCommitteeSize();
301
+ async getTargetCommitteeSize(): Promise<number> {
302
+ return Number(await this.rollup.read.getTargetCommitteeSize());
219
303
  }
220
304
 
221
305
  @memoize
222
- getEjectionThreshold() {
306
+ getEjectionThreshold(): Promise<bigint> {
223
307
  return this.rollup.read.getEjectionThreshold();
224
308
  }
225
309
 
226
310
  @memoize
227
- getActivationThreshold() {
311
+ getLocalEjectionThreshold(): Promise<bigint> {
312
+ return this.rollup.read.getLocalEjectionThreshold();
313
+ }
314
+
315
+ @memoize
316
+ async getLagInEpochsForValidatorSet(): Promise<number> {
317
+ return Number(await this.rollup.read.getLagInEpochsForValidatorSet());
318
+ }
319
+
320
+ @memoize
321
+ async getLagInEpochsForRandao(): Promise<number> {
322
+ return Number(await this.rollup.read.getLagInEpochsForRandao());
323
+ }
324
+
325
+ @memoize
326
+ getActivationThreshold(): Promise<bigint> {
228
327
  return this.rollup.read.getActivationThreshold();
229
328
  }
230
329
 
231
330
  @memoize
232
- getExitDelay() {
233
- return this.rollup.read.getExitDelay();
331
+ async getExitDelay(): Promise<number> {
332
+ return Number(await this.rollup.read.getExitDelay());
234
333
  }
235
334
 
236
335
  @memoize
237
- getManaTarget() {
336
+ getManaTarget(): Promise<bigint> {
238
337
  return this.rollup.read.getManaTarget();
239
338
  }
240
339
 
241
340
  @memoize
242
- getProvingCostPerMana() {
341
+ getProvingCostPerMana(): Promise<bigint> {
243
342
  return this.rollup.read.getProvingCostPerManaInEth();
244
343
  }
245
344
 
246
345
  @memoize
247
- getProvingCostPerManaInFeeAsset() {
346
+ getProvingCostPerManaInFeeAsset(): Promise<bigint> {
248
347
  return this.rollup.read.getProvingCostPerManaInFeeAsset();
249
348
  }
250
349
 
251
350
  @memoize
252
- getManaLimit() {
351
+ getManaLimit(): Promise<bigint> {
253
352
  return this.rollup.read.getManaLimit();
254
353
  }
255
354
 
256
355
  @memoize
257
- getVersion() {
356
+ getVersion(): Promise<bigint> {
258
357
  return this.rollup.read.getVersion();
259
358
  }
260
359
 
261
360
  @memoize
262
- async getGenesisArchiveTreeRoot(): Promise<`0x${string}`> {
263
- const block = await this.rollup.read.getBlock([0n]);
264
- return block.archive;
361
+ async getGenesisArchiveTreeRoot(): Promise<Fr> {
362
+ return Fr.fromString(await this.rollup.read.archiveAt([0n]));
265
363
  }
266
364
 
267
365
  /**
@@ -287,67 +385,72 @@ export class RollupContract {
287
385
  return {
288
386
  l1StartBlock,
289
387
  l1GenesisTime,
290
- slotDuration: Number(slotDuration),
388
+ slotDuration,
291
389
  epochDuration: Number(epochDuration),
292
390
  proofSubmissionEpochs: Number(proofSubmissionEpochs),
293
391
  };
294
392
  }
295
393
 
296
- getSlasher() {
297
- return this.rollup.read.getSlasher();
394
+ async getSlasherAddress(): Promise<EthAddress> {
395
+ return EthAddress.fromString(await this.rollup.read.getSlasher());
298
396
  }
299
397
 
300
398
  /**
301
399
  * Returns a SlasherContract instance for interacting with the slasher contract.
302
400
  */
303
- async getSlasherContract(): Promise<SlasherContract> {
304
- const slasherAddress = await this.getSlasher();
305
- return new SlasherContract(this.client, EthAddress.fromString(slasherAddress));
401
+ async getSlasherContract(): Promise<SlasherContract | undefined> {
402
+ const slasherAddress = await this.getSlasherAddress();
403
+ if (slasherAddress.isZero()) {
404
+ return undefined;
405
+ }
406
+ return new SlasherContract(this.client, slasherAddress);
306
407
  }
307
408
 
308
- getOwner() {
309
- return this.rollup.read.owner();
409
+ async getOwner(): Promise<EthAddress> {
410
+ return EthAddress.fromString(await this.rollup.read.owner());
310
411
  }
311
412
 
312
- getActiveAttesterCount() {
313
- return this.rollup.read.getActiveAttesterCount();
413
+ async getActiveAttesterCount(): Promise<number> {
414
+ return Number(await this.rollup.read.getActiveAttesterCount());
314
415
  }
315
416
 
316
417
  public async getSlashingProposerAddress() {
317
- const slasherAddress = await this.getSlasher();
318
- const slasher = getContract({
319
- address: getAddress(slasherAddress.toString()),
320
- abi: SlasherAbi,
321
- client: this.client,
322
- });
323
- return EthAddress.fromString(await slasher.read.PROPOSER());
418
+ const slasher = await this.getSlasherContract();
419
+ if (!slasher) {
420
+ return EthAddress.ZERO;
421
+ }
422
+ return await slasher.getProposer();
324
423
  }
325
424
 
326
- getBlockReward() {
327
- return this.rollup.read.getBlockReward();
425
+ getCheckpointReward(): Promise<bigint> {
426
+ return this.rollup.read.getCheckpointReward();
328
427
  }
329
428
 
330
- getBlockNumber() {
331
- return this.rollup.read.getPendingBlockNumber();
429
+ async getCheckpointNumber(): Promise<CheckpointNumber> {
430
+ return CheckpointNumber.fromBigInt(await this.rollup.read.getPendingCheckpointNumber());
332
431
  }
333
432
 
334
- getProvenBlockNumber() {
335
- return this.rollup.read.getProvenBlockNumber();
433
+ async getProvenCheckpointNumber(): Promise<CheckpointNumber> {
434
+ return CheckpointNumber.fromBigInt(await this.rollup.read.getProvenCheckpointNumber());
336
435
  }
337
436
 
338
- getSlotNumber() {
339
- return this.rollup.read.getCurrentSlot();
437
+ async getSlotNumber(): Promise<SlotNumber> {
438
+ return SlotNumber.fromBigInt(await this.rollup.read.getCurrentSlot());
340
439
  }
341
440
 
342
- getL1FeesAt(timestamp: bigint) {
343
- return this.rollup.read.getL1FeesAt([timestamp]);
441
+ async getL1FeesAt(timestamp: bigint): Promise<L1FeeData> {
442
+ const result = await this.rollup.read.getL1FeesAt([timestamp]);
443
+ return {
444
+ baseFee: result.baseFee,
445
+ blobFee: result.blobFee,
446
+ };
344
447
  }
345
448
 
346
- getFeeAssetPerEth() {
449
+ getFeeAssetPerEth(): Promise<bigint> {
347
450
  return this.rollup.read.getFeeAssetPerEth();
348
451
  }
349
452
 
350
- async getCommitteeAt(timestamp: bigint): Promise<readonly `0x${string}`[] | undefined> {
453
+ async getCommitteeAt(timestamp: bigint): Promise<EthAddress[] | undefined> {
351
454
  const { result } = await this.client
352
455
  .simulateContract({
353
456
  address: this.address,
@@ -362,22 +465,22 @@ export class RollupContract {
362
465
  throw e;
363
466
  });
364
467
 
365
- return result;
468
+ return result ? result.map(addr => EthAddress.fromString(addr)) : undefined;
366
469
  }
367
470
 
368
- getSampleSeedAt(timestamp: bigint) {
369
- return this.rollup.read.getSampleSeedAt([timestamp]);
471
+ async getSampleSeedAt(timestamp: bigint): Promise<Buffer32> {
472
+ return Buffer32.fromBigInt(await this.rollup.read.getSampleSeedAt([timestamp]));
370
473
  }
371
474
 
372
- getCurrentSampleSeed() {
373
- return this.rollup.read.getCurrentSampleSeed();
475
+ async getCurrentSampleSeed(): Promise<Buffer32> {
476
+ return Buffer32.fromBigInt(await this.rollup.read.getCurrentSampleSeed());
374
477
  }
375
478
 
376
- getCurrentEpoch() {
377
- return this.rollup.read.getCurrentEpoch();
479
+ async getCurrentEpoch(): Promise<EpochNumber> {
480
+ return EpochNumber.fromBigInt(await this.rollup.read.getCurrentEpoch());
378
481
  }
379
482
 
380
- async getCurrentEpochCommittee(): Promise<readonly `0x${string}`[] | undefined> {
483
+ async getCurrentEpochCommittee(): Promise<EthAddress[] | undefined> {
381
484
  const { result } = await this.client
382
485
  .simulateContract({
383
486
  address: this.address,
@@ -392,10 +495,10 @@ export class RollupContract {
392
495
  throw e;
393
496
  });
394
497
 
395
- return result;
498
+ return result ? result.map(addr => EthAddress.fromString(addr)) : undefined;
396
499
  }
397
500
 
398
- async getCurrentProposer() {
501
+ async getCurrentProposer(): Promise<EthAddress> {
399
502
  const { result } = await this.client.simulateContract({
400
503
  address: this.address,
401
504
  abi: RollupAbi,
@@ -403,10 +506,10 @@ export class RollupContract {
403
506
  args: [],
404
507
  });
405
508
 
406
- return result;
509
+ return EthAddress.fromString(result);
407
510
  }
408
511
 
409
- async getProposerAt(timestamp: bigint) {
512
+ async getProposerAt(timestamp: bigint): Promise<EthAddress> {
410
513
  const { result } = await this.client.simulateContract({
411
514
  address: this.address,
412
515
  abi: RollupAbi,
@@ -414,28 +517,73 @@ export class RollupContract {
414
517
  args: [timestamp],
415
518
  });
416
519
 
417
- return result;
520
+ return EthAddress.fromString(result);
418
521
  }
419
522
 
420
- getBlock(blockNumber: bigint) {
421
- return this.rollup.read.getBlock([blockNumber]);
523
+ async getCheckpoint(checkpointNumber: CheckpointNumber): Promise<CheckpointLog> {
524
+ const result = await this.rollup.read.getCheckpoint([BigInt(checkpointNumber)]);
525
+ return {
526
+ archive: Fr.fromString(result.archive),
527
+ headerHash: Buffer32.fromString(result.headerHash),
528
+ blobCommitmentsHash: Buffer32.fromString(result.blobCommitmentsHash),
529
+ attestationsHash: Buffer32.fromString(result.attestationsHash),
530
+ payloadDigest: Buffer32.fromString(result.payloadDigest),
531
+ slotNumber: SlotNumber.fromBigInt(result.slotNumber),
532
+ feeHeader: {
533
+ excessMana: result.feeHeader.excessMana,
534
+ manaUsed: result.feeHeader.manaUsed,
535
+ feeAssetPriceNumerator: result.feeHeader.feeAssetPriceNumerator,
536
+ congestionCost: result.feeHeader.congestionCost,
537
+ proverCost: result.feeHeader.proverCost,
538
+ },
539
+ };
422
540
  }
423
541
 
424
- getTips() {
425
- return this.rollup.read.getTips();
542
+ /** Returns the pending checkpoint from the rollup contract */
543
+ getPendingCheckpoint() {
544
+ // We retry because of race conditions during prunes: we may get a pending checkpoint number which is immediately
545
+ // reorged out due to a prune happening, causing the subsequent getCheckpoint call to fail. So we try again in that case.
546
+ return retry(
547
+ async () => {
548
+ const pendingCheckpointNumber = await this.getCheckpointNumber();
549
+ const pendingCheckpoint = await this.getCheckpoint(pendingCheckpointNumber);
550
+ return pendingCheckpoint;
551
+ },
552
+ 'getting pending checkpoint',
553
+ makeBackoff([0.5, 0.5, 0.5]),
554
+ );
555
+ }
556
+
557
+ async getTips(): Promise<{ pending: CheckpointNumber; proven: CheckpointNumber }> {
558
+ const { pending, proven } = await this.rollup.read.getTips();
559
+ return {
560
+ pending: CheckpointNumber.fromBigInt(pending),
561
+ proven: CheckpointNumber.fromBigInt(proven),
562
+ };
426
563
  }
427
564
 
428
- getTimestampForSlot(slot: bigint) {
429
- return this.rollup.read.getTimestampForSlot([slot]);
565
+ getTimestampForSlot(slot: SlotNumber): Promise<bigint> {
566
+ return this.rollup.read.getTimestampForSlot([BigInt(slot)]);
430
567
  }
431
568
 
432
- getEntryQueueLength() {
433
- return this.rollup.read.getEntryQueueLength();
569
+ async getEntryQueueLength(): Promise<number> {
570
+ return Number(await this.rollup.read.getEntryQueueLength());
434
571
  }
435
572
 
436
- async getEpochNumber(blockNumber?: bigint) {
437
- blockNumber ??= await this.getBlockNumber();
438
- return this.rollup.read.getEpochForBlock([BigInt(blockNumber)]);
573
+ async getAvailableValidatorFlushes(): Promise<number> {
574
+ return Number(await this.rollup.read.getAvailableValidatorFlushes());
575
+ }
576
+
577
+ async getNextFlushableEpoch(): Promise<EpochNumber> {
578
+ return EpochNumber.fromBigInt(await this.rollup.read.getNextFlushableEpoch());
579
+ }
580
+
581
+ async getCurrentEpochNumber(): Promise<EpochNumber> {
582
+ return EpochNumber.fromBigInt(await this.rollup.read.getCurrentEpoch());
583
+ }
584
+
585
+ async getEpochNumberForCheckpoint(checkpointNumber: CheckpointNumber): Promise<EpochNumber> {
586
+ return EpochNumber.fromBigInt(await this.rollup.read.getEpochForCheckpoint([BigInt(checkpointNumber)]));
439
587
  }
440
588
 
441
589
  async getRollupAddresses(): Promise<L1RollupContractAddresses> {
@@ -475,14 +623,15 @@ export class RollupContract {
475
623
  return EthAddress.fromString(await this.rollup.read.getFeeAssetPortal());
476
624
  }
477
625
 
478
- public async getEpochNumberForSlotNumber(slotNumber: bigint): Promise<bigint> {
479
- return await this.rollup.read.getEpochAtSlot([slotNumber]);
626
+ public async getEpochNumberForSlotNumber(slotNumber: SlotNumber): Promise<EpochNumber> {
627
+ return EpochNumber.fromBigInt(await this.rollup.read.getEpochAtSlot([BigInt(slotNumber)]));
480
628
  }
481
629
 
482
- getEpochProofPublicInputs(
630
+ async getEpochProofPublicInputs(
483
631
  args: readonly [bigint, bigint, EpochProofPublicInputArgs, readonly `0x${string}`[], `0x${string}`],
484
- ) {
485
- return this.rollup.read.getEpochProofPublicInputs(args);
632
+ ): Promise<Fr[]> {
633
+ const result = await this.rollup.read.getEpochProofPublicInputs(args);
634
+ return result.map(Fr.fromString);
486
635
  }
487
636
 
488
637
  public async validateHeader(
@@ -490,6 +639,7 @@ export class RollupContract {
490
639
  ViemHeader,
491
640
  ViemCommitteeAttestations,
492
641
  `0x${string}`[],
642
+ ViemSignature,
493
643
  `0x${string}`,
494
644
  `0x${string}`,
495
645
  {
@@ -512,130 +662,63 @@ export class RollupContract {
512
662
  }
513
663
  }
514
664
 
515
- /**
516
- * Packs an array of committee attestations into the format expected by the Solidity contract
517
- *
518
- * @param attestations - Array of committee attestations with addresses and signatures
519
- * @returns Packed attestations with bitmap and tightly packed signature/address data
520
- */
521
- static packAttestations(attestations: ViemCommitteeAttestation[]): ViemCommitteeAttestations {
522
- const length = attestations.length;
523
-
524
- // Calculate bitmap size (1 bit per attestation, rounded up to nearest byte)
525
- const bitmapSize = Math.ceil(length / 8);
526
- const signatureIndices = new Uint8Array(bitmapSize);
527
-
528
- // Calculate total data size needed
529
- let totalDataSize = 0;
530
- for (let i = 0; i < length; i++) {
531
- const signature = attestations[i].signature;
532
- // Check if signature is empty (v = 0)
533
- const isEmpty = signature.v === 0;
534
-
535
- if (!isEmpty) {
536
- totalDataSize += 65; // v (1) + r (32) + s (32)
537
- } else {
538
- totalDataSize += 20; // address only
539
- }
540
- }
541
-
542
- const signaturesOrAddresses = new Uint8Array(totalDataSize);
543
- let dataIndex = 0;
544
-
545
- // Pack the data
546
- for (let i = 0; i < length; i++) {
547
- const attestation = attestations[i];
548
- const signature = attestation.signature;
549
-
550
- // Check if signature is empty
551
- const isEmpty = signature.v === 0;
552
-
553
- if (!isEmpty) {
554
- // Set bit in bitmap (bit 7-0 in each byte, left to right)
555
- const byteIndex = Math.floor(i / 8);
556
- const bitIndex = 7 - (i % 8);
557
- signatureIndices[byteIndex] |= 1 << bitIndex;
558
-
559
- // Pack signature: v + r + s
560
- signaturesOrAddresses[dataIndex] = signature.v;
561
- dataIndex++;
562
-
563
- // Pack r (32 bytes)
564
- const rBytes = Buffer.from(signature.r.slice(2), 'hex');
565
- signaturesOrAddresses.set(rBytes, dataIndex);
566
- dataIndex += 32;
567
-
568
- // Pack s (32 bytes)
569
- const sBytes = Buffer.from(signature.s.slice(2), 'hex');
570
- signaturesOrAddresses.set(sBytes, dataIndex);
571
- dataIndex += 32;
572
- } else {
573
- // Pack address only (20 bytes)
574
- const addrBytes = Buffer.from(attestation.addr.slice(2), 'hex');
575
- signaturesOrAddresses.set(addrBytes, dataIndex);
576
- dataIndex += 20;
577
- }
578
- }
579
-
580
- return {
581
- signatureIndices: `0x${Buffer.from(signatureIndices).toString('hex')}`,
582
- signaturesOrAddresses: `0x${Buffer.from(signaturesOrAddresses).toString('hex')}`,
583
- };
584
- }
585
-
586
665
  /**
587
666
  * @notice Calls `canProposeAtTime` with the time of the next Ethereum block and the sender address
588
667
  *
589
668
  * @dev Throws if unable to propose
590
669
  *
591
670
  * @param archive - The archive that we expect to be current state
592
- * @return [slot, blockNumber] - If you can propose, the L2 slot number and L2 block number of the next Ethereum block,
671
+ * @return [slot, checkpointNumber, timeOfNextL1Slot] - If you can propose, the L2 slot number, checkpoint number and
672
+ * timestamp of the next L1 block
593
673
  * @throws otherwise
594
674
  */
595
675
  public async canProposeAtNextEthBlock(
596
676
  archive: Buffer,
597
677
  account: `0x${string}` | Account,
598
- slotDuration: bigint | number,
599
- opts: { forcePendingBlockNumber?: number } = {},
600
- ): Promise<{ slot: bigint; blockNumber: bigint; timeOfNextL1Slot: bigint }> {
601
- if (typeof slotDuration === 'number') {
602
- slotDuration = BigInt(slotDuration);
603
- }
678
+ slotDuration: number,
679
+ opts: { forcePendingCheckpointNumber?: CheckpointNumber } = {},
680
+ ): Promise<{ slot: SlotNumber; checkpointNumber: CheckpointNumber; timeOfNextL1Slot: bigint }> {
604
681
  const latestBlock = await this.client.getBlock();
605
- const timeOfNextL1Slot = latestBlock.timestamp + slotDuration;
682
+ const timeOfNextL1Slot = latestBlock.timestamp + BigInt(slotDuration);
606
683
  const who = typeof account === 'string' ? account : account.address;
607
684
 
608
685
  try {
609
686
  const {
610
- result: [slot, blockNumber],
687
+ result: [slot, checkpointNumber],
611
688
  } = await this.client.simulateContract({
612
689
  address: this.address,
613
690
  abi: RollupAbi,
614
691
  functionName: 'canProposeAtTime',
615
692
  args: [timeOfNextL1Slot, `0x${archive.toString('hex')}`, who],
616
693
  account,
617
- stateOverride: await this.makePendingBlockNumberOverride(opts.forcePendingBlockNumber),
694
+ stateOverride: await this.makePendingCheckpointNumberOverride(opts.forcePendingCheckpointNumber),
618
695
  });
619
696
 
620
- return { slot, blockNumber, timeOfNextL1Slot };
697
+ return {
698
+ slot: SlotNumber.fromBigInt(slot),
699
+ checkpointNumber: CheckpointNumber.fromBigInt(checkpointNumber),
700
+ timeOfNextL1Slot,
701
+ };
621
702
  } catch (err: unknown) {
622
703
  throw formatViemError(err);
623
704
  }
624
705
  }
625
706
 
626
707
  /**
627
- * Returns a state override that sets the pending block number to the specified value. Useful for simulations.
628
- * Requires querying the current state of the contract to get the current proven block number, as they are both
708
+ * Returns a state override that sets the pending checkpoint number to the specified value. Useful for simulations.
709
+ * Requires querying the current state of the contract to get the current proven checkpoint number, as they are both
629
710
  * stored in the same slot. If the argument is undefined, it returns an empty override.
630
711
  */
631
- public async makePendingBlockNumberOverride(forcePendingBlockNumber: number | undefined): Promise<StateOverride> {
632
- if (forcePendingBlockNumber === undefined) {
712
+ public async makePendingCheckpointNumberOverride(
713
+ forcePendingCheckpointNumber: CheckpointNumber | undefined,
714
+ ): Promise<StateOverride> {
715
+ if (forcePendingCheckpointNumber === undefined) {
633
716
  return [];
634
717
  }
635
718
  const slot = RollupContract.stfStorageSlot;
636
719
  const currentValue = await this.client.getStorageAt({ address: this.address, slot });
637
- const currentProvenBlockNumber = currentValue ? hexToBigInt(currentValue) & ((1n << 128n) - 1n) : 0n;
638
- const newValue = (BigInt(forcePendingBlockNumber) << 128n) | currentProvenBlockNumber;
720
+ const currentProvenCheckpointNumber = currentValue ? hexToBigInt(currentValue) & ((1n << 128n) - 1n) : 0n;
721
+ const newValue = (BigInt(forcePendingCheckpointNumber) << 128n) | currentProvenCheckpointNumber;
639
722
  return [
640
723
  {
641
724
  address: this.address,
@@ -646,8 +729,8 @@ export class RollupContract {
646
729
 
647
730
  /** Creates a request to Rollup#invalidateBadAttestation to be simulated or sent */
648
731
  public buildInvalidateBadAttestationRequest(
649
- blockNumber: number,
650
- attestations: ViemCommitteeAttestation[],
732
+ checkpointNumber: CheckpointNumber,
733
+ attestationsAndSigners: ViemCommitteeAttestations,
651
734
  committee: EthAddress[],
652
735
  invalidIndex: number,
653
736
  ): L1TxRequest {
@@ -657,8 +740,8 @@ export class RollupContract {
657
740
  abi: RollupAbi,
658
741
  functionName: 'invalidateBadAttestation',
659
742
  args: [
660
- BigInt(blockNumber),
661
- RollupContract.packAttestations(attestations),
743
+ BigInt(checkpointNumber),
744
+ attestationsAndSigners,
662
745
  committee.map(addr => addr.toString()),
663
746
  BigInt(invalidIndex),
664
747
  ],
@@ -668,8 +751,8 @@ export class RollupContract {
668
751
 
669
752
  /** Creates a request to Rollup#invalidateInsufficientAttestations to be simulated or sent */
670
753
  public buildInvalidateInsufficientAttestationsRequest(
671
- blockNumber: number,
672
- attestations: ViemCommitteeAttestation[],
754
+ checkpointNumber: CheckpointNumber,
755
+ attestationsAndSigners: ViemCommitteeAttestations,
673
756
  committee: EthAddress[],
674
757
  ): L1TxRequest {
675
758
  return {
@@ -677,98 +760,131 @@ export class RollupContract {
677
760
  data: encodeFunctionData({
678
761
  abi: RollupAbi,
679
762
  functionName: 'invalidateInsufficientAttestations',
680
- args: [
681
- BigInt(blockNumber),
682
- RollupContract.packAttestations(attestations),
683
- committee.map(addr => addr.toString()),
684
- ],
763
+ args: [BigInt(checkpointNumber), attestationsAndSigners, committee.map(addr => addr.toString())],
685
764
  }),
686
765
  };
687
766
  }
688
767
 
689
768
  /** Calls getHasSubmitted directly. Returns whether the given prover has submitted a proof with the given length for the given epoch. */
690
- public getHasSubmittedProof(epochNumber: number, numberOfBlocksInEpoch: number, prover: Hex | EthAddress) {
769
+ public getHasSubmittedProof(epochNumber: EpochNumber, numberOfCheckpointsInEpoch: number, prover: Hex | EthAddress) {
691
770
  if (prover instanceof EthAddress) {
692
771
  prover = prover.toString();
693
772
  }
694
- return this.rollup.read.getHasSubmitted([BigInt(epochNumber), BigInt(numberOfBlocksInEpoch), prover]);
773
+ return this.rollup.read.getHasSubmitted([BigInt(epochNumber), BigInt(numberOfCheckpointsInEpoch), prover]);
695
774
  }
696
775
 
697
- getManaBaseFeeAt(timestamp: bigint, inFeeAsset: boolean) {
776
+ getManaBaseFeeAt(timestamp: bigint, inFeeAsset: boolean): Promise<bigint> {
698
777
  return this.rollup.read.getManaBaseFeeAt([timestamp, inFeeAsset]);
699
778
  }
700
779
 
701
- getSlotAt(timestamp: bigint) {
702
- return this.rollup.read.getSlotAt([timestamp]);
780
+ async getSlotAt(timestamp: bigint): Promise<SlotNumber> {
781
+ return SlotNumber.fromBigInt(await this.rollup.read.getSlotAt([timestamp]));
703
782
  }
704
783
 
705
- async status(blockNumber: bigint, options?: { blockNumber?: bigint }) {
784
+ async status(checkpointNumber: CheckpointNumber, options?: { blockNumber?: bigint }): Promise<RollupStatusResponse> {
706
785
  await checkBlockTag(options?.blockNumber, this.client);
707
- return this.rollup.read.status([blockNumber], options);
786
+ const result = await this.rollup.read.status([BigInt(checkpointNumber)], options);
787
+ return {
788
+ provenCheckpointNumber: CheckpointNumber.fromBigInt(result[0]),
789
+ provenArchive: Fr.fromString(result[1]),
790
+ pendingCheckpointNumber: CheckpointNumber.fromBigInt(result[2]),
791
+ pendingArchive: Fr.fromString(result[3]),
792
+ archiveOfMyCheckpoint: Fr.fromString(result[4]),
793
+ };
708
794
  }
709
795
 
710
- async canPruneAtTime(timestamp: bigint, options?: { blockNumber?: bigint }) {
796
+ async canPruneAtTime(timestamp: bigint, options?: { blockNumber?: bigint }): Promise<boolean> {
711
797
  await checkBlockTag(options?.blockNumber, this.client);
712
798
  return this.rollup.read.canPruneAtTime([timestamp], options);
713
799
  }
714
800
 
715
- archive() {
716
- return this.rollup.read.archive();
801
+ async archive(): Promise<Fr> {
802
+ return Fr.fromString(await this.rollup.read.archive());
717
803
  }
718
804
 
719
- archiveAt(blockNumber: bigint) {
720
- return this.rollup.read.archiveAt([blockNumber]);
805
+ async archiveAt(checkpointNumber: CheckpointNumber): Promise<Fr> {
806
+ return Fr.fromString(await this.rollup.read.archiveAt([BigInt(checkpointNumber)]));
721
807
  }
722
808
 
723
- getSequencerRewards(address: Hex | EthAddress) {
809
+ getSequencerRewards(address: Hex | EthAddress): Promise<bigint> {
724
810
  if (address instanceof EthAddress) {
725
811
  address = address.toString();
726
812
  }
727
813
  return this.rollup.read.getSequencerRewards([address]);
728
814
  }
729
815
 
730
- getSpecificProverRewardsForEpoch(epoch: bigint, prover: Hex | EthAddress) {
816
+ getSpecificProverRewardsForEpoch(epoch: bigint, prover: Hex | EthAddress): Promise<bigint> {
731
817
  if (prover instanceof EthAddress) {
732
818
  prover = prover.toString();
733
819
  }
734
820
  return this.rollup.read.getSpecificProverRewardsForEpoch([epoch, prover]);
735
821
  }
736
822
 
737
- async getAttesters() {
823
+ async getAttesters(): Promise<EthAddress[]> {
738
824
  const attesterSize = await this.getActiveAttesterCount();
739
825
  const gse = new GSEContract(this.client, await this.getGSE());
740
826
  const ts = (await this.client.getBlock()).timestamp;
741
827
 
742
- const indices = Array.from({ length: Number(attesterSize) }, (_, i) => BigInt(i));
828
+ const indices = Array.from({ length: attesterSize }, (_, i) => BigInt(i));
743
829
  const chunks = chunk(indices, 1000);
744
830
 
745
- return (await Promise.all(chunks.map(chunk => gse.getAttestersFromIndicesAtTime(this.address, ts, chunk)))).flat();
831
+ const results = await Promise.all(chunks.map(chunk => gse.getAttestersFromIndicesAtTime(this.address, ts, chunk)));
832
+ return results.flat().map(addr => EthAddress.fromString(addr));
746
833
  }
747
834
 
748
- getAttesterView(address: Hex | EthAddress) {
835
+ async getAttesterView(address: Hex | EthAddress): Promise<AttesterView> {
749
836
  if (address instanceof EthAddress) {
750
837
  address = address.toString();
751
838
  }
752
- return this.rollup.read.getAttesterView([address]);
839
+ const result = await this.rollup.read.getAttesterView([address]);
840
+ return {
841
+ status: result.status as AttesterStatus,
842
+ effectiveBalance: result.effectiveBalance,
843
+ exit: {
844
+ withdrawalId: result.exit.withdrawalId,
845
+ amount: result.exit.amount,
846
+ exitableAt: result.exit.exitableAt,
847
+ recipientOrWithdrawer: EthAddress.fromString(result.exit.recipientOrWithdrawer),
848
+ isRecipient: result.exit.isRecipient,
849
+ exists: result.exit.exists,
850
+ },
851
+ config: {
852
+ publicKey: {
853
+ x: result.config.publicKey.x,
854
+ y: result.config.publicKey.y,
855
+ },
856
+ withdrawer: EthAddress.fromString(result.config.withdrawer),
857
+ },
858
+ };
753
859
  }
754
860
 
755
- getStatus(address: Hex | EthAddress) {
861
+ async getStatus(address: Hex | EthAddress): Promise<AttesterStatus> {
756
862
  if (address instanceof EthAddress) {
757
863
  address = address.toString();
758
864
  }
759
- return this.rollup.read.getStatus([address]);
865
+ return (await this.rollup.read.getStatus([address])) as AttesterStatus;
760
866
  }
761
867
 
762
- getBlobCommitmentsHash(blockNumber: bigint) {
763
- return this.rollup.read.getBlobCommitmentsHash([blockNumber]);
868
+ async getBlobCommitmentsHash(checkpointNumber: CheckpointNumber): Promise<Buffer32> {
869
+ return Buffer32.fromString(await this.rollup.read.getBlobCommitmentsHash([BigInt(checkpointNumber)]));
764
870
  }
765
871
 
766
- getCurrentBlobCommitmentsHash() {
767
- return this.rollup.read.getCurrentBlobCommitmentsHash();
872
+ async getCurrentBlobCommitmentsHash(): Promise<Buffer32> {
873
+ return Buffer32.fromString(await this.rollup.read.getCurrentBlobCommitmentsHash());
768
874
  }
769
875
 
770
- getStakingAsset() {
771
- return this.rollup.read.getStakingAsset();
876
+ async getStakingAsset(): Promise<EthAddress> {
877
+ return EthAddress.fromString(await this.rollup.read.getStakingAsset());
878
+ }
879
+
880
+ async getRewardConfig(): Promise<RewardConfig> {
881
+ const result = await this.rollup.read.getRewardConfig();
882
+ return {
883
+ rewardDistributor: EthAddress.fromString(result.rewardDistributor),
884
+ sequencerBps: BigInt(result.sequencerBps),
885
+ booster: EthAddress.fromString(result.booster),
886
+ checkpointReward: result.checkpointReward,
887
+ };
772
888
  }
773
889
 
774
890
  setupEpoch(l1TxUtils: L1TxUtils) {
@@ -793,7 +909,9 @@ export class RollupContract {
793
909
  });
794
910
  }
795
911
 
796
- public listenToSlasherChanged(callback: (args: { oldSlasher: `0x${string}`; newSlasher: `0x${string}` }) => unknown) {
912
+ public listenToSlasherChanged(
913
+ callback: (args: { oldSlasher: `0x${string}`; newSlasher: `0x${string}` }) => unknown,
914
+ ): WatchContractEventReturnType {
797
915
  return this.rollup.watchEvent.SlasherUpdated(
798
916
  {},
799
917
  {
@@ -809,6 +927,24 @@ export class RollupContract {
809
927
  );
810
928
  }
811
929
 
930
+ public listenToCheckpointInvalidated(
931
+ callback: (args: { checkpointNumber: CheckpointNumber }) => unknown,
932
+ ): WatchContractEventReturnType {
933
+ return this.rollup.watchEvent.CheckpointInvalidated(
934
+ {},
935
+ {
936
+ onLogs: logs => {
937
+ for (const log of logs) {
938
+ const args = log.args;
939
+ if (args.checkpointNumber !== undefined) {
940
+ callback({ checkpointNumber: CheckpointNumber.fromBigInt(args.checkpointNumber) });
941
+ }
942
+ }
943
+ },
944
+ },
945
+ );
946
+ }
947
+
812
948
  public async getSlashEvents(l1BlockHash: Hex): Promise<{ amount: bigint; attester: EthAddress }[]> {
813
949
  const events = await this.rollup.getEvents.Slashed({}, { blockHash: l1BlockHash, strict: true });
814
950
  return events.map(event => ({
@@ -817,7 +953,9 @@ export class RollupContract {
817
953
  }));
818
954
  }
819
955
 
820
- public listenToSlash(callback: (args: { amount: bigint; attester: EthAddress }) => unknown) {
956
+ public listenToSlash(
957
+ callback: (args: { amount: bigint; attester: EthAddress }) => unknown,
958
+ ): WatchContractEventReturnType {
821
959
  return this.rollup.watchEvent.Slashed(
822
960
  {},
823
961
  {