@aztec/ethereum 0.0.0-test.1 → 0.0.1-commit.21caa21

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 (232) hide show
  1. package/dest/account.d.ts +2 -0
  2. package/dest/account.d.ts.map +1 -0
  3. package/dest/account.js +4 -0
  4. package/dest/chain.d.ts +1 -1
  5. package/dest/client.d.ts +6 -4
  6. package/dest/client.d.ts.map +1 -1
  7. package/dest/client.js +16 -2
  8. package/dest/config.d.ts +111 -17
  9. package/dest/config.d.ts.map +1 -1
  10. package/dest/config.js +462 -22
  11. package/dest/constants.d.ts +1 -1
  12. package/dest/contracts/empire_base.d.ts +24 -8
  13. package/dest/contracts/empire_base.d.ts.map +1 -1
  14. package/dest/contracts/empire_base.js +75 -2
  15. package/dest/contracts/empire_slashing_proposer.d.ts +66 -0
  16. package/dest/contracts/empire_slashing_proposer.d.ts.map +1 -0
  17. package/dest/contracts/empire_slashing_proposer.js +200 -0
  18. package/dest/contracts/errors.d.ts +7 -0
  19. package/dest/contracts/errors.d.ts.map +1 -0
  20. package/dest/contracts/errors.js +12 -0
  21. package/dest/contracts/fee_asset_handler.d.ts +19 -0
  22. package/dest/contracts/fee_asset_handler.d.ts.map +1 -0
  23. package/dest/contracts/fee_asset_handler.js +57 -0
  24. package/dest/contracts/fee_juice.d.ts +6 -7
  25. package/dest/contracts/fee_juice.d.ts.map +1 -1
  26. package/dest/contracts/fee_juice.js +27 -20
  27. package/dest/contracts/governance.d.ts +43 -32
  28. package/dest/contracts/governance.d.ts.map +1 -1
  29. package/dest/contracts/governance.js +87 -84
  30. package/dest/contracts/governance_proposer.d.ts +16 -13
  31. package/dest/contracts/governance_proposer.d.ts.map +1 -1
  32. package/dest/contracts/governance_proposer.js +37 -17
  33. package/dest/contracts/gse.d.ts +32 -0
  34. package/dest/contracts/gse.d.ts.map +1 -0
  35. package/dest/contracts/gse.js +72 -0
  36. package/dest/contracts/inbox.d.ts +26 -0
  37. package/dest/contracts/inbox.d.ts.map +1 -0
  38. package/dest/contracts/inbox.js +45 -0
  39. package/dest/contracts/index.d.ts +9 -3
  40. package/dest/contracts/index.d.ts.map +1 -1
  41. package/dest/contracts/index.js +8 -2
  42. package/dest/contracts/multicall.d.ts +21 -0
  43. package/dest/contracts/multicall.d.ts.map +1 -0
  44. package/dest/contracts/multicall.js +156 -0
  45. package/dest/contracts/registry.d.ts +10 -5
  46. package/dest/contracts/registry.d.ts.map +1 -1
  47. package/dest/contracts/registry.js +44 -16
  48. package/dest/contracts/rollup.d.ts +204 -40
  49. package/dest/contracts/rollup.d.ts.map +1 -1
  50. package/dest/contracts/rollup.js +529 -79
  51. package/dest/contracts/slasher_contract.d.ts +44 -0
  52. package/dest/contracts/slasher_contract.d.ts.map +1 -0
  53. package/dest/contracts/slasher_contract.js +75 -0
  54. package/dest/contracts/tally_slashing_proposer.d.ts +139 -0
  55. package/dest/contracts/tally_slashing_proposer.d.ts.map +1 -0
  56. package/dest/contracts/tally_slashing_proposer.js +313 -0
  57. package/dest/contracts/utils.d.ts +3 -0
  58. package/dest/contracts/utils.d.ts.map +1 -0
  59. package/dest/contracts/utils.js +11 -0
  60. package/dest/deploy_l1_contracts.d.ts +577 -21114
  61. package/dest/deploy_l1_contracts.d.ts.map +1 -1
  62. package/dest/deploy_l1_contracts.js +1225 -421
  63. package/dest/eth-signer/eth-signer.d.ts +21 -0
  64. package/dest/eth-signer/eth-signer.d.ts.map +1 -0
  65. package/dest/eth-signer/eth-signer.js +5 -0
  66. package/dest/eth-signer/index.d.ts +2 -0
  67. package/dest/eth-signer/index.d.ts.map +1 -0
  68. package/dest/eth-signer/index.js +1 -0
  69. package/dest/index.d.ts +7 -3
  70. package/dest/index.d.ts.map +1 -1
  71. package/dest/index.js +6 -2
  72. package/dest/l1_artifacts.d.ts +77344 -0
  73. package/dest/l1_artifacts.d.ts.map +1 -0
  74. package/dest/l1_artifacts.js +166 -0
  75. package/dest/l1_contract_addresses.d.ts +24 -4
  76. package/dest/l1_contract_addresses.d.ts.map +1 -1
  77. package/dest/l1_contract_addresses.js +22 -18
  78. package/dest/l1_reader.d.ts +2 -2
  79. package/dest/l1_reader.d.ts.map +1 -1
  80. package/dest/l1_reader.js +8 -8
  81. package/dest/l1_tx_utils/config.d.ts +59 -0
  82. package/dest/l1_tx_utils/config.d.ts.map +1 -0
  83. package/dest/l1_tx_utils/config.js +82 -0
  84. package/dest/l1_tx_utils/constants.d.ts +6 -0
  85. package/dest/l1_tx_utils/constants.d.ts.map +1 -0
  86. package/dest/l1_tx_utils/constants.js +14 -0
  87. package/dest/l1_tx_utils/factory.d.ts +24 -0
  88. package/dest/l1_tx_utils/factory.d.ts.map +1 -0
  89. package/dest/l1_tx_utils/factory.js +12 -0
  90. package/dest/l1_tx_utils/index.d.ts +10 -0
  91. package/dest/l1_tx_utils/index.d.ts.map +1 -0
  92. package/dest/l1_tx_utils/index.js +10 -0
  93. package/dest/l1_tx_utils/interfaces.d.ts +76 -0
  94. package/dest/l1_tx_utils/interfaces.d.ts.map +1 -0
  95. package/dest/l1_tx_utils/interfaces.js +4 -0
  96. package/dest/l1_tx_utils/l1_tx_utils.d.ts +94 -0
  97. package/dest/l1_tx_utils/l1_tx_utils.d.ts.map +1 -0
  98. package/dest/l1_tx_utils/l1_tx_utils.js +610 -0
  99. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts +26 -0
  100. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts.map +1 -0
  101. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.js +26 -0
  102. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts +94 -0
  103. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts.map +1 -0
  104. package/dest/l1_tx_utils/readonly_l1_tx_utils.js +430 -0
  105. package/dest/l1_tx_utils/signer.d.ts +4 -0
  106. package/dest/l1_tx_utils/signer.d.ts.map +1 -0
  107. package/dest/l1_tx_utils/signer.js +16 -0
  108. package/dest/l1_tx_utils/types.d.ts +67 -0
  109. package/dest/l1_tx_utils/types.d.ts.map +1 -0
  110. package/dest/l1_tx_utils/types.js +26 -0
  111. package/dest/l1_tx_utils/utils.d.ts +4 -0
  112. package/dest/l1_tx_utils/utils.d.ts.map +1 -0
  113. package/dest/l1_tx_utils/utils.js +14 -0
  114. package/dest/l1_types.d.ts +6 -0
  115. package/dest/l1_types.d.ts.map +1 -0
  116. package/dest/l1_types.js +1 -0
  117. package/dest/publisher_manager.d.ts +15 -0
  118. package/dest/publisher_manager.d.ts.map +1 -0
  119. package/dest/publisher_manager.js +88 -0
  120. package/dest/queries.d.ts +4 -2
  121. package/dest/queries.d.ts.map +1 -1
  122. package/dest/queries.js +53 -12
  123. package/dest/test/chain_monitor.d.ts +73 -0
  124. package/dest/test/chain_monitor.d.ts.map +1 -0
  125. package/dest/test/chain_monitor.js +215 -0
  126. package/dest/test/delayed_tx_utils.d.ts +8 -3
  127. package/dest/test/delayed_tx_utils.d.ts.map +1 -1
  128. package/dest/test/delayed_tx_utils.js +13 -6
  129. package/dest/test/eth_cheat_codes.d.ts +217 -0
  130. package/dest/test/eth_cheat_codes.d.ts.map +1 -0
  131. package/dest/test/eth_cheat_codes.js +558 -0
  132. package/dest/test/eth_cheat_codes_with_state.d.ts +2 -2
  133. package/dest/test/eth_cheat_codes_with_state.d.ts.map +1 -1
  134. package/dest/test/eth_cheat_codes_with_state.js +1 -1
  135. package/dest/test/index.d.ts +4 -1
  136. package/dest/test/index.d.ts.map +1 -1
  137. package/dest/test/index.js +3 -0
  138. package/dest/test/rollup_cheat_codes.d.ts +87 -0
  139. package/dest/test/rollup_cheat_codes.d.ts.map +1 -0
  140. package/dest/test/rollup_cheat_codes.js +266 -0
  141. package/dest/test/start_anvil.d.ts +7 -1
  142. package/dest/test/start_anvil.d.ts.map +1 -1
  143. package/dest/test/start_anvil.js +16 -7
  144. package/dest/test/tx_delayer.d.ts +18 -7
  145. package/dest/test/tx_delayer.d.ts.map +1 -1
  146. package/dest/test/tx_delayer.js +95 -19
  147. package/dest/test/upgrade_utils.d.ts +6 -5
  148. package/dest/test/upgrade_utils.d.ts.map +1 -1
  149. package/dest/test/upgrade_utils.js +23 -16
  150. package/dest/types.d.ts +7 -8
  151. package/dest/types.d.ts.map +1 -1
  152. package/dest/types.js +3 -1
  153. package/dest/utils.d.ts +2 -1
  154. package/dest/utils.d.ts.map +1 -1
  155. package/dest/utils.js +43 -88
  156. package/dest/zkPassportVerifierAddress.d.ts +15 -0
  157. package/dest/zkPassportVerifierAddress.d.ts.map +1 -0
  158. package/dest/zkPassportVerifierAddress.js +11 -0
  159. package/package.json +28 -19
  160. package/src/account.ts +5 -0
  161. package/src/client.ts +42 -4
  162. package/src/config.ts +592 -31
  163. package/src/contracts/empire_base.ts +77 -7
  164. package/src/contracts/empire_slashing_proposer.ts +265 -0
  165. package/src/contracts/errors.ts +13 -0
  166. package/src/contracts/fee_asset_handler.ts +63 -0
  167. package/src/contracts/fee_juice.ts +29 -15
  168. package/src/contracts/governance.ts +80 -77
  169. package/src/contracts/governance_proposer.ts +66 -24
  170. package/src/contracts/gse.ts +88 -0
  171. package/src/contracts/inbox.ts +63 -0
  172. package/src/contracts/index.ts +8 -2
  173. package/src/contracts/multicall.ts +155 -0
  174. package/src/contracts/registry.ts +51 -26
  175. package/src/contracts/rollup.ts +596 -74
  176. package/src/contracts/slasher_contract.ts +89 -0
  177. package/src/contracts/tally_slashing_proposer.ts +316 -0
  178. package/src/contracts/utils.ts +14 -0
  179. package/src/deploy_l1_contracts.ts +1459 -538
  180. package/src/eth-signer/eth-signer.ts +25 -0
  181. package/src/eth-signer/index.ts +1 -0
  182. package/src/index.ts +6 -2
  183. package/src/l1_artifacts.ts +254 -0
  184. package/src/l1_contract_addresses.ts +32 -19
  185. package/src/l1_reader.ts +9 -9
  186. package/src/l1_tx_utils/README.md +177 -0
  187. package/src/l1_tx_utils/config.ts +143 -0
  188. package/src/l1_tx_utils/constants.ts +18 -0
  189. package/src/l1_tx_utils/factory.ts +64 -0
  190. package/src/l1_tx_utils/index.ts +12 -0
  191. package/src/l1_tx_utils/interfaces.ts +86 -0
  192. package/src/l1_tx_utils/l1_tx_utils.ts +718 -0
  193. package/src/l1_tx_utils/l1_tx_utils_with_blobs.ts +77 -0
  194. package/src/l1_tx_utils/readonly_l1_tx_utils.ts +558 -0
  195. package/src/l1_tx_utils/signer.ts +28 -0
  196. package/src/l1_tx_utils/types.ts +85 -0
  197. package/src/l1_tx_utils/utils.ts +16 -0
  198. package/src/l1_types.ts +6 -0
  199. package/src/publisher_manager.ts +106 -0
  200. package/src/queries.ts +73 -15
  201. package/src/test/chain_monitor.ts +243 -0
  202. package/src/test/delayed_tx_utils.ts +34 -6
  203. package/src/test/eth_cheat_codes.ts +588 -0
  204. package/src/test/eth_cheat_codes_with_state.ts +1 -1
  205. package/src/test/index.ts +3 -0
  206. package/src/test/rollup_cheat_codes.ts +307 -0
  207. package/src/test/start_anvil.ts +22 -5
  208. package/src/test/tx_delayer.ts +127 -26
  209. package/src/test/upgrade_utils.ts +30 -21
  210. package/src/types.ts +10 -8
  211. package/src/utils.ts +49 -90
  212. package/src/zkPassportVerifierAddress.ts +15 -0
  213. package/dest/contracts/forwarder.d.ts +0 -24
  214. package/dest/contracts/forwarder.d.ts.map +0 -1
  215. package/dest/contracts/forwarder.js +0 -101
  216. package/dest/contracts/slashing_proposer.d.ts +0 -21
  217. package/dest/contracts/slashing_proposer.d.ts.map +0 -1
  218. package/dest/contracts/slashing_proposer.js +0 -47
  219. package/dest/eth_cheat_codes.d.ts +0 -147
  220. package/dest/eth_cheat_codes.d.ts.map +0 -1
  221. package/dest/eth_cheat_codes.js +0 -303
  222. package/dest/l1_tx_utils.d.ts +0 -192
  223. package/dest/l1_tx_utils.d.ts.map +0 -1
  224. package/dest/l1_tx_utils.js +0 -641
  225. package/dest/l1_tx_utils_with_blobs.d.ts +0 -12
  226. package/dest/l1_tx_utils_with_blobs.d.ts.map +0 -1
  227. package/dest/l1_tx_utils_with_blobs.js +0 -64
  228. package/src/contracts/forwarder.ts +0 -132
  229. package/src/contracts/slashing_proposer.ts +0 -51
  230. package/src/eth_cheat_codes.ts +0 -314
  231. package/src/l1_tx_utils.ts +0 -847
  232. package/src/l1_tx_utils_with_blobs.ts +0 -86
@@ -1,17 +1,45 @@
1
+ import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
1
2
  import { memoize } from '@aztec/foundation/decorators';
2
3
  import { EthAddress } from '@aztec/foundation/eth-address';
3
4
  import type { ViemSignature } from '@aztec/foundation/eth-signature';
4
- import { RollupAbi, RollupStorage, SlasherAbi } from '@aztec/l1-artifacts';
5
-
6
- import { type Account, type GetContractReturnType, type Hex, getAddress, getContract } from 'viem';
5
+ import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
6
+ import { RollupStorage } from '@aztec/l1-artifacts/RollupStorage';
7
+
8
+ import chunk from 'lodash.chunk';
9
+ import {
10
+ type Account,
11
+ type GetContractReturnType,
12
+ type Hex,
13
+ type StateOverride,
14
+ type WatchContractEventReturnType,
15
+ encodeFunctionData,
16
+ getContract,
17
+ hexToBigInt,
18
+ keccak256,
19
+ } from 'viem';
7
20
 
8
21
  import { getPublicClient } from '../client.js';
9
22
  import type { DeployL1ContractsReturnType } from '../deploy_l1_contracts.js';
10
23
  import type { L1ContractAddresses } from '../l1_contract_addresses.js';
11
24
  import type { L1ReaderConfig } from '../l1_reader.js';
12
- import type { ViemPublicClient } from '../types.js';
25
+ import type { L1TxRequest, L1TxUtils } from '../l1_tx_utils/index.js';
26
+ import type { ViemClient } from '../types.js';
13
27
  import { formatViemError } from '../utils.js';
14
- import { SlashingProposerContract } from './slashing_proposer.js';
28
+ import { EmpireSlashingProposerContract } from './empire_slashing_proposer.js';
29
+ import { GSEContract } from './gse.js';
30
+ import { SlasherContract } from './slasher_contract.js';
31
+ import { TallySlashingProposerContract } from './tally_slashing_proposer.js';
32
+ import { checkBlockTag } from './utils.js';
33
+
34
+ export type ViemCommitteeAttestation = {
35
+ addr: `0x${string}`;
36
+ signature: ViemSignature;
37
+ };
38
+
39
+ export type ViemCommitteeAttestations = {
40
+ signatureIndices: `0x${string}`;
41
+ signaturesOrAddresses: `0x${string}`;
42
+ };
15
43
 
16
44
  export type L1RollupContractAddresses = Pick<
17
45
  L1ContractAddresses,
@@ -23,20 +51,48 @@ export type L1RollupContractAddresses = Pick<
23
51
  | 'stakingAssetAddress'
24
52
  | 'rewardDistributorAddress'
25
53
  | 'slashFactoryAddress'
54
+ | 'gseAddress'
26
55
  >;
27
56
 
28
57
  export type EpochProofPublicInputArgs = {
29
58
  previousArchive: `0x${string}`;
30
59
  endArchive: `0x${string}`;
31
- previousBlockHash: `0x${string}`;
32
- endBlockHash: `0x${string}`;
33
- endTimestamp: bigint;
34
- outHash: `0x${string}`;
35
60
  proverId: `0x${string}`;
36
61
  };
37
62
 
63
+ export type ViemHeader = {
64
+ lastArchiveRoot: `0x${string}`;
65
+ blockHeadersHash: `0x${string}`;
66
+ contentCommitment: ViemContentCommitment;
67
+ slotNumber: bigint;
68
+ timestamp: bigint;
69
+ coinbase: `0x${string}`;
70
+ feeRecipient: `0x${string}`;
71
+ gasFees: ViemGasFees;
72
+ totalManaUsed: bigint;
73
+ };
74
+
75
+ export type ViemContentCommitment = {
76
+ blobsHash: `0x${string}`;
77
+ inHash: `0x${string}`;
78
+ outHash: `0x${string}`;
79
+ };
80
+
81
+ export type ViemGasFees = {
82
+ feePerDaGas: bigint;
83
+ feePerL2Gas: bigint;
84
+ };
85
+
86
+ export enum SlashingProposerType {
87
+ None = 0,
88
+ Tally = 1,
89
+ Empire = 2,
90
+ }
91
+
38
92
  export class RollupContract {
39
- private readonly rollup: GetContractReturnType<typeof RollupAbi, ViemPublicClient>;
93
+ private readonly rollup: GetContractReturnType<typeof RollupAbi, ViemClient>;
94
+
95
+ private static cachedStfStorageSlot: Hex | undefined;
40
96
 
41
97
  static get checkBlobStorageSlot(): bigint {
42
98
  const asString = RollupStorage.find(storage => storage.label === 'checkBlob')?.slot;
@@ -46,12 +102,16 @@ export class RollupContract {
46
102
  return BigInt(asString);
47
103
  }
48
104
 
105
+ static get stfStorageSlot(): Hex {
106
+ return (RollupContract.cachedStfStorageSlot ??= keccak256(Buffer.from('aztec.stf.storage', 'utf-8')));
107
+ }
108
+
49
109
  static getFromL1ContractsValues(deployL1ContractsValues: DeployL1ContractsReturnType) {
50
110
  const {
51
- publicClient,
111
+ l1Client,
52
112
  l1ContractAddresses: { rollupAddress },
53
113
  } = deployL1ContractsValues;
54
- return new RollupContract(publicClient, rollupAddress.toString());
114
+ return new RollupContract(l1Client, rollupAddress.toString());
55
115
  }
56
116
 
57
117
  static getFromConfig(config: L1ReaderConfig) {
@@ -60,23 +120,56 @@ export class RollupContract {
60
120
  return new RollupContract(client, address);
61
121
  }
62
122
 
63
- constructor(public readonly client: ViemPublicClient, address: Hex | EthAddress) {
123
+ constructor(
124
+ public readonly client: ViemClient,
125
+ address: Hex | EthAddress,
126
+ ) {
64
127
  if (address instanceof EthAddress) {
65
128
  address = address.toString();
66
129
  }
67
130
  this.rollup = getContract({ address, abi: RollupAbi, client });
68
131
  }
69
132
 
133
+ getGSE() {
134
+ return this.rollup.read.getGSE();
135
+ }
136
+
70
137
  public get address() {
71
138
  return this.rollup.address;
72
139
  }
73
140
 
74
- @memoize
75
- public async getSlashingProposer() {
76
- const slasherAddress = await this.rollup.read.getSlasher();
77
- const slasher = getContract({ address: slasherAddress, abi: SlasherAbi, client: this.client });
78
- const proposerAddress = await slasher.read.PROPOSER();
79
- return new SlashingProposerContract(this.client, proposerAddress);
141
+ getContract(): GetContractReturnType<typeof RollupAbi, ViemClient> {
142
+ return this.rollup;
143
+ }
144
+
145
+ public async getSlashingProposer(): Promise<
146
+ EmpireSlashingProposerContract | TallySlashingProposerContract | undefined
147
+ > {
148
+ const slasher = await this.getSlasherContract();
149
+ if (!slasher) {
150
+ return undefined;
151
+ }
152
+
153
+ const proposerAddress = await slasher.getProposer();
154
+ const proposerAbi = [
155
+ {
156
+ type: 'function',
157
+ name: 'SLASHING_PROPOSER_TYPE',
158
+ inputs: [],
159
+ outputs: [{ name: '', type: 'uint8', internalType: 'enum SlasherFlavor' }],
160
+ stateMutability: 'view',
161
+ },
162
+ ] as const;
163
+
164
+ const proposer = getContract({ address: proposerAddress.toString(), abi: proposerAbi, client: this.client });
165
+ const proposerType = await proposer.read.SLASHING_PROPOSER_TYPE();
166
+ if (proposerType === SlashingProposerType.Tally.valueOf()) {
167
+ return new TallySlashingProposerContract(this.client, proposerAddress);
168
+ } else if (proposerType === SlashingProposerType.Empire.valueOf()) {
169
+ return new EmpireSlashingProposerContract(this.client, proposerAddress);
170
+ } else {
171
+ throw new Error(`Unknown slashing proposer type: ${proposerType}`);
172
+ }
80
173
  }
81
174
 
82
175
  @memoize
@@ -90,8 +183,8 @@ export class RollupContract {
90
183
  }
91
184
 
92
185
  @memoize
93
- getProofSubmissionWindow() {
94
- return this.rollup.read.getProofSubmissionWindow();
186
+ getProofSubmissionEpochs() {
187
+ return this.rollup.read.getProofSubmissionEpochs();
95
188
  }
96
189
 
97
190
  @memoize
@@ -100,8 +193,8 @@ export class RollupContract {
100
193
  }
101
194
 
102
195
  @memoize
103
- getSlotDuration() {
104
- return this.rollup.read.getSlotDuration();
196
+ async getSlotDuration(): Promise<number> {
197
+ return Number(await this.rollup.read.getSlotDuration());
105
198
  }
106
199
 
107
200
  @memoize
@@ -110,34 +203,165 @@ export class RollupContract {
110
203
  }
111
204
 
112
205
  @memoize
113
- getMinimumStake() {
114
- return this.rollup.read.getMinimumStake();
206
+ getEjectionThreshold() {
207
+ return this.rollup.read.getEjectionThreshold();
208
+ }
209
+
210
+ @memoize
211
+ getLocalEjectionThreshold() {
212
+ return this.rollup.read.getLocalEjectionThreshold();
213
+ }
214
+
215
+ @memoize
216
+ getLagInEpochsForValidatorSet() {
217
+ return this.rollup.read.getLagInEpochsForValidatorSet();
218
+ }
219
+
220
+ @memoize
221
+ getLagInEpochsForRandao() {
222
+ return this.rollup.read.getLagInEpochsForRandao();
223
+ }
224
+
225
+ @memoize
226
+ getActivationThreshold() {
227
+ return this.rollup.read.getActivationThreshold();
228
+ }
229
+
230
+ @memoize
231
+ getExitDelay() {
232
+ return this.rollup.read.getExitDelay();
233
+ }
234
+
235
+ @memoize
236
+ getManaTarget() {
237
+ return this.rollup.read.getManaTarget();
238
+ }
239
+
240
+ @memoize
241
+ getProvingCostPerMana() {
242
+ return this.rollup.read.getProvingCostPerManaInEth();
243
+ }
244
+
245
+ @memoize
246
+ getProvingCostPerManaInFeeAsset() {
247
+ return this.rollup.read.getProvingCostPerManaInFeeAsset();
248
+ }
249
+
250
+ @memoize
251
+ getManaLimit() {
252
+ return this.rollup.read.getManaLimit();
253
+ }
254
+
255
+ @memoize
256
+ getVersion() {
257
+ return this.rollup.read.getVersion();
258
+ }
259
+
260
+ @memoize
261
+ async getGenesisArchiveTreeRoot(): Promise<`0x${string}`> {
262
+ return await this.rollup.read.archiveAt([0n]);
263
+ }
264
+
265
+ /**
266
+ * Returns rollup constants used for epoch queries.
267
+ * Return type is `L1RollupConstants` which is defined in stdlib,
268
+ * so we cant reference it until we move this contract to that package.
269
+ */
270
+ @memoize
271
+ public async getRollupConstants(): Promise<{
272
+ l1StartBlock: bigint;
273
+ l1GenesisTime: bigint;
274
+ slotDuration: number;
275
+ epochDuration: number;
276
+ proofSubmissionEpochs: number;
277
+ }> {
278
+ const [l1StartBlock, l1GenesisTime, slotDuration, epochDuration, proofSubmissionEpochs] = await Promise.all([
279
+ this.getL1StartBlock(),
280
+ this.getL1GenesisTime(),
281
+ this.getSlotDuration(),
282
+ this.getEpochDuration(),
283
+ this.getProofSubmissionEpochs(),
284
+ ]);
285
+ return {
286
+ l1StartBlock,
287
+ l1GenesisTime,
288
+ slotDuration,
289
+ epochDuration: Number(epochDuration),
290
+ proofSubmissionEpochs: Number(proofSubmissionEpochs),
291
+ };
292
+ }
293
+
294
+ getSlasherAddress() {
295
+ return this.rollup.read.getSlasher();
296
+ }
297
+
298
+ /**
299
+ * Returns a SlasherContract instance for interacting with the slasher contract.
300
+ */
301
+ async getSlasherContract(): Promise<SlasherContract | undefined> {
302
+ const slasherAddress = EthAddress.fromString(await this.getSlasherAddress());
303
+ if (slasherAddress.isZero()) {
304
+ return undefined;
305
+ }
306
+ return new SlasherContract(this.client, slasherAddress);
307
+ }
308
+
309
+ getOwner() {
310
+ return this.rollup.read.owner();
311
+ }
312
+
313
+ getActiveAttesterCount() {
314
+ return this.rollup.read.getActiveAttesterCount();
115
315
  }
116
316
 
117
317
  public async getSlashingProposerAddress() {
118
- const slasherAddress = await this.rollup.read.getSlasher();
119
- const slasher = getContract({
120
- address: getAddress(slasherAddress.toString()),
121
- abi: SlasherAbi,
122
- client: this.client,
123
- });
124
- return EthAddress.fromString(await slasher.read.PROPOSER());
318
+ const slasher = await this.getSlasherContract();
319
+ if (!slasher) {
320
+ return EthAddress.ZERO;
321
+ }
322
+ return await slasher.getProposer();
125
323
  }
126
324
 
127
- getBlockNumber() {
128
- return this.rollup.read.getPendingBlockNumber();
325
+ getCheckpointReward() {
326
+ return this.rollup.read.getCheckpointReward();
129
327
  }
130
328
 
131
- getProvenBlockNumber() {
132
- return this.rollup.read.getProvenBlockNumber();
329
+ getCheckpointNumber() {
330
+ return this.rollup.read.getPendingCheckpointNumber();
133
331
  }
134
332
 
135
- getSlotNumber() {
136
- return this.rollup.read.getCurrentSlot();
333
+ getProvenCheckpointNumber() {
334
+ return this.rollup.read.getProvenCheckpointNumber();
137
335
  }
138
336
 
139
- getCommitteeAt(timestamp: bigint) {
140
- return this.rollup.read.getCommitteeAt([timestamp]);
337
+ async getSlotNumber(): Promise<SlotNumber> {
338
+ return SlotNumber.fromBigInt(await this.rollup.read.getCurrentSlot());
339
+ }
340
+
341
+ getL1FeesAt(timestamp: bigint) {
342
+ return this.rollup.read.getL1FeesAt([timestamp]);
343
+ }
344
+
345
+ getFeeAssetPerEth() {
346
+ return this.rollup.read.getFeeAssetPerEth();
347
+ }
348
+
349
+ async getCommitteeAt(timestamp: bigint): Promise<readonly `0x${string}`[] | undefined> {
350
+ const { result } = await this.client
351
+ .simulateContract({
352
+ address: this.address,
353
+ abi: RollupAbi,
354
+ functionName: 'getCommitteeAt',
355
+ args: [timestamp],
356
+ })
357
+ .catch(e => {
358
+ if (e instanceof Error && e.message.includes('ValidatorSelection__InsufficientValidatorSetSize')) {
359
+ return { result: undefined };
360
+ }
361
+ throw e;
362
+ });
363
+
364
+ return result;
141
365
  }
142
366
 
143
367
  getSampleSeedAt(timestamp: bigint) {
@@ -148,33 +372,80 @@ export class RollupContract {
148
372
  return this.rollup.read.getCurrentSampleSeed();
149
373
  }
150
374
 
151
- getCurrentEpochCommittee() {
152
- return this.rollup.read.getCurrentEpochCommittee();
375
+ async getCurrentEpoch(): Promise<EpochNumber> {
376
+ return EpochNumber.fromBigInt(await this.rollup.read.getCurrentEpoch());
153
377
  }
154
378
 
155
- getCurrentProposer() {
156
- return this.rollup.read.getCurrentProposer();
379
+ async getCurrentEpochCommittee(): Promise<readonly `0x${string}`[] | undefined> {
380
+ const { result } = await this.client
381
+ .simulateContract({
382
+ address: this.address,
383
+ abi: RollupAbi,
384
+ functionName: 'getCurrentEpochCommittee',
385
+ args: [],
386
+ })
387
+ .catch(e => {
388
+ if (e instanceof Error && e.message.includes('ValidatorSelection__InsufficientValidatorSetSize')) {
389
+ return { result: undefined };
390
+ }
391
+ throw e;
392
+ });
393
+
394
+ return result;
395
+ }
396
+
397
+ async getCurrentProposer() {
398
+ const { result } = await this.client.simulateContract({
399
+ address: this.address,
400
+ abi: RollupAbi,
401
+ functionName: 'getCurrentProposer',
402
+ args: [],
403
+ });
404
+
405
+ return result;
157
406
  }
158
407
 
159
- getProposerAt(timestamp: bigint) {
160
- return this.rollup.read.getProposerAt([timestamp]);
408
+ async getProposerAt(timestamp: bigint) {
409
+ const { result } = await this.client.simulateContract({
410
+ address: this.address,
411
+ abi: RollupAbi,
412
+ functionName: 'getProposerAt',
413
+ args: [timestamp],
414
+ });
415
+
416
+ return result;
161
417
  }
162
418
 
163
- getBlock(blockNumber: bigint) {
164
- return this.rollup.read.getBlock([blockNumber]);
419
+ getCheckpoint(checkpointNumber: bigint | number) {
420
+ return this.rollup.read.getCheckpoint([BigInt(checkpointNumber)]);
165
421
  }
166
422
 
167
423
  getTips() {
168
424
  return this.rollup.read.getTips();
169
425
  }
170
426
 
171
- getTimestampForSlot(slot: bigint) {
172
- return this.rollup.read.getTimestampForSlot([slot]);
427
+ getTimestampForSlot(slot: SlotNumber) {
428
+ return this.rollup.read.getTimestampForSlot([BigInt(slot)]);
429
+ }
430
+
431
+ getEntryQueueLength() {
432
+ return this.rollup.read.getEntryQueueLength();
433
+ }
434
+
435
+ getAvailableValidatorFlushes() {
436
+ return this.rollup.read.getAvailableValidatorFlushes();
173
437
  }
174
438
 
175
- async getEpochNumber(blockNumber?: bigint) {
176
- blockNumber ??= await this.getBlockNumber();
177
- return this.rollup.read.getEpochForBlock([BigInt(blockNumber)]);
439
+ async getNextFlushableEpoch(): Promise<EpochNumber> {
440
+ return EpochNumber.fromBigInt(await this.rollup.read.getNextFlushableEpoch());
441
+ }
442
+
443
+ async getCurrentEpochNumber(): Promise<EpochNumber> {
444
+ return EpochNumber.fromBigInt(await this.rollup.read.getCurrentEpoch());
445
+ }
446
+
447
+ async getEpochNumberForCheckpoint(checkpointNumber: bigint): Promise<EpochNumber> {
448
+ return EpochNumber.fromBigInt(await this.rollup.read.getEpochForCheckpoint([BigInt(checkpointNumber)]));
178
449
  }
179
450
 
180
451
  async getRollupAddresses(): Promise<L1RollupContractAddresses> {
@@ -185,6 +456,7 @@ export class RollupContract {
185
456
  rewardDistributorAddress,
186
457
  feeJuiceAddress,
187
458
  stakingAssetAddress,
459
+ gseAddress,
188
460
  ] = (
189
461
  await Promise.all([
190
462
  this.rollup.read.getInbox(),
@@ -193,6 +465,7 @@ export class RollupContract {
193
465
  this.rollup.read.getRewardDistributor(),
194
466
  this.rollup.read.getFeeAsset(),
195
467
  this.rollup.read.getStakingAsset(),
468
+ this.rollup.read.getGSE(),
196
469
  ] as const)
197
470
  ).map(EthAddress.fromString);
198
471
 
@@ -204,25 +477,31 @@ export class RollupContract {
204
477
  feeJuiceAddress,
205
478
  stakingAssetAddress,
206
479
  rewardDistributorAddress,
480
+ gseAddress,
207
481
  };
208
482
  }
209
483
 
210
- public async getEpochNumberForSlotNumber(slotNumber: bigint): Promise<bigint> {
211
- return await this.rollup.read.getEpochAtSlot([slotNumber]);
484
+ public async getFeeJuicePortal() {
485
+ return EthAddress.fromString(await this.rollup.read.getFeeAssetPortal());
486
+ }
487
+
488
+ public async getEpochNumberForSlotNumber(slotNumber: SlotNumber): Promise<EpochNumber> {
489
+ return EpochNumber.fromBigInt(await this.rollup.read.getEpochAtSlot([BigInt(slotNumber)]));
212
490
  }
213
491
 
214
492
  getEpochProofPublicInputs(
215
- args: readonly [bigint, bigint, EpochProofPublicInputArgs, readonly `0x${string}`[], `0x${string}`, `0x${string}`],
493
+ args: readonly [bigint, bigint, EpochProofPublicInputArgs, readonly `0x${string}`[], `0x${string}`],
216
494
  ) {
217
495
  return this.rollup.read.getEpochProofPublicInputs(args);
218
496
  }
219
497
 
220
498
  public async validateHeader(
221
499
  args: readonly [
500
+ ViemHeader,
501
+ ViemCommitteeAttestations,
502
+ `0x${string}`[],
503
+ ViemSignature,
222
504
  `0x${string}`,
223
- ViemSignature[],
224
- `0x${string}`,
225
- bigint,
226
505
  `0x${string}`,
227
506
  {
228
507
  ignoreDA: boolean;
@@ -232,7 +511,13 @@ export class RollupContract {
232
511
  account: `0x${string}` | Account,
233
512
  ): Promise<void> {
234
513
  try {
235
- await this.rollup.read.validateHeader(args, { account });
514
+ await this.client.simulateContract({
515
+ address: this.address,
516
+ abi: RollupAbi,
517
+ functionName: 'validateHeaderWithAttestations',
518
+ args,
519
+ account,
520
+ });
236
521
  } catch (error: unknown) {
237
522
  throw formatViemError(error);
238
523
  }
@@ -244,31 +529,268 @@ export class RollupContract {
244
529
  * @dev Throws if unable to propose
245
530
  *
246
531
  * @param archive - The archive that we expect to be current state
247
- * @return [slot, blockNumber] - If you can propose, the L2 slot number and L2 block number of the next Ethereum block,
532
+ * @return [slot, checkpointNumber, timeOfNextL1Slot] - If you can propose, the L2 slot number, checkpoint number and
533
+ * timestamp of the next L1 block
248
534
  * @throws otherwise
249
535
  */
250
536
  public async canProposeAtNextEthBlock(
251
537
  archive: Buffer,
252
538
  account: `0x${string}` | Account,
253
- slotDuration: bigint | number,
254
- ): Promise<[bigint, bigint]> {
255
- if (typeof slotDuration === 'number') {
256
- slotDuration = BigInt(slotDuration);
257
- }
258
- const timeOfNextL1Slot = (await this.client.getBlock()).timestamp + slotDuration;
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);
544
+ const who = typeof account === 'string' ? account : account.address;
545
+
259
546
  try {
260
- const [slot, blockNumber] = await this.rollup.read.canProposeAtTime(
261
- [timeOfNextL1Slot, `0x${archive.toString('hex')}`],
262
- { account },
263
- );
264
- return [slot, blockNumber];
547
+ const {
548
+ result: [slot, checkpointNumber],
549
+ } = await this.client.simulateContract({
550
+ address: this.address,
551
+ abi: RollupAbi,
552
+ functionName: 'canProposeAtTime',
553
+ args: [timeOfNextL1Slot, `0x${archive.toString('hex')}`, who],
554
+ account,
555
+ stateOverride: await this.makePendingCheckpointNumberOverride(opts.forcePendingCheckpointNumber),
556
+ });
557
+
558
+ return { slot: SlotNumber.fromBigInt(slot), checkpointNumber, timeOfNextL1Slot };
265
559
  } catch (err: unknown) {
266
560
  throw formatViemError(err);
267
561
  }
268
562
  }
269
563
 
564
+ /**
565
+ * Returns a state override that sets the pending checkpoint number to the specified value. Useful for simulations.
566
+ * Requires querying the current state of the contract to get the current proven checkpoint number, as they are both
567
+ * stored in the same slot. If the argument is undefined, it returns an empty override.
568
+ */
569
+ public async makePendingCheckpointNumberOverride(
570
+ forcePendingCheckpointNumber: number | undefined,
571
+ ): Promise<StateOverride> {
572
+ if (forcePendingCheckpointNumber === undefined) {
573
+ return [];
574
+ }
575
+ const slot = RollupContract.stfStorageSlot;
576
+ const currentValue = await this.client.getStorageAt({ address: this.address, slot });
577
+ const currentProvenCheckpointNumber = currentValue ? hexToBigInt(currentValue) & ((1n << 128n) - 1n) : 0n;
578
+ const newValue = (BigInt(forcePendingCheckpointNumber) << 128n) | currentProvenCheckpointNumber;
579
+ return [
580
+ {
581
+ address: this.address,
582
+ stateDiff: [{ slot, value: `0x${newValue.toString(16).padStart(64, '0')}` }],
583
+ },
584
+ ];
585
+ }
586
+
587
+ /** Creates a request to Rollup#invalidateBadAttestation to be simulated or sent */
588
+ public buildInvalidateBadAttestationRequest(
589
+ checkpointNumber: number,
590
+ attestationsAndSigners: ViemCommitteeAttestations,
591
+ committee: EthAddress[],
592
+ invalidIndex: number,
593
+ ): L1TxRequest {
594
+ return {
595
+ to: this.address,
596
+ data: encodeFunctionData({
597
+ abi: RollupAbi,
598
+ functionName: 'invalidateBadAttestation',
599
+ args: [
600
+ BigInt(checkpointNumber),
601
+ attestationsAndSigners,
602
+ committee.map(addr => addr.toString()),
603
+ BigInt(invalidIndex),
604
+ ],
605
+ }),
606
+ };
607
+ }
608
+
609
+ /** Creates a request to Rollup#invalidateInsufficientAttestations to be simulated or sent */
610
+ public buildInvalidateInsufficientAttestationsRequest(
611
+ checkpointNumber: number,
612
+ attestationsAndSigners: ViemCommitteeAttestations,
613
+ committee: EthAddress[],
614
+ ): L1TxRequest {
615
+ return {
616
+ to: this.address,
617
+ data: encodeFunctionData({
618
+ abi: RollupAbi,
619
+ functionName: 'invalidateInsufficientAttestations',
620
+ args: [BigInt(checkpointNumber), attestationsAndSigners, committee.map(addr => addr.toString())],
621
+ }),
622
+ };
623
+ }
624
+
270
625
  /** Calls getHasSubmitted directly. Returns whether the given prover has submitted a proof with the given length for the given epoch. */
271
- public getHasSubmittedProof(epochNumber: number, numberOfBlocksInEpoch: number, prover: EthAddress) {
272
- return this.rollup.read.getHasSubmitted([BigInt(epochNumber), BigInt(numberOfBlocksInEpoch), prover.toString()]);
626
+ public getHasSubmittedProof(epochNumber: EpochNumber, numberOfCheckpointsInEpoch: number, prover: Hex | EthAddress) {
627
+ if (prover instanceof EthAddress) {
628
+ prover = prover.toString();
629
+ }
630
+ return this.rollup.read.getHasSubmitted([BigInt(epochNumber), BigInt(numberOfCheckpointsInEpoch), prover]);
631
+ }
632
+
633
+ getManaBaseFeeAt(timestamp: bigint, inFeeAsset: boolean) {
634
+ return this.rollup.read.getManaBaseFeeAt([timestamp, inFeeAsset]);
635
+ }
636
+
637
+ async getSlotAt(timestamp: bigint): Promise<SlotNumber> {
638
+ return SlotNumber.fromBigInt(await this.rollup.read.getSlotAt([timestamp]));
639
+ }
640
+
641
+ async status(checkpointNumber: bigint, options?: { blockNumber?: bigint }) {
642
+ await checkBlockTag(options?.blockNumber, this.client);
643
+ return this.rollup.read.status([checkpointNumber], options);
644
+ }
645
+
646
+ async canPruneAtTime(timestamp: bigint, options?: { blockNumber?: bigint }) {
647
+ await checkBlockTag(options?.blockNumber, this.client);
648
+ return this.rollup.read.canPruneAtTime([timestamp], options);
649
+ }
650
+
651
+ archive() {
652
+ return this.rollup.read.archive();
653
+ }
654
+
655
+ archiveAt(checkpointNumber: bigint) {
656
+ return this.rollup.read.archiveAt([checkpointNumber]);
657
+ }
658
+
659
+ getSequencerRewards(address: Hex | EthAddress) {
660
+ if (address instanceof EthAddress) {
661
+ address = address.toString();
662
+ }
663
+ return this.rollup.read.getSequencerRewards([address]);
664
+ }
665
+
666
+ getSpecificProverRewardsForEpoch(epoch: bigint, prover: Hex | EthAddress) {
667
+ if (prover instanceof EthAddress) {
668
+ prover = prover.toString();
669
+ }
670
+ return this.rollup.read.getSpecificProverRewardsForEpoch([epoch, prover]);
671
+ }
672
+
673
+ async getAttesters() {
674
+ const attesterSize = await this.getActiveAttesterCount();
675
+ 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));
679
+ const chunks = chunk(indices, 1000);
680
+
681
+ return (await Promise.all(chunks.map(chunk => gse.getAttestersFromIndicesAtTime(this.address, ts, chunk)))).flat();
682
+ }
683
+
684
+ getAttesterView(address: Hex | EthAddress) {
685
+ if (address instanceof EthAddress) {
686
+ address = address.toString();
687
+ }
688
+ return this.rollup.read.getAttesterView([address]);
689
+ }
690
+
691
+ getStatus(address: Hex | EthAddress) {
692
+ if (address instanceof EthAddress) {
693
+ address = address.toString();
694
+ }
695
+ return this.rollup.read.getStatus([address]);
696
+ }
697
+
698
+ getBlobCommitmentsHash(checkpointNumber: bigint) {
699
+ return this.rollup.read.getBlobCommitmentsHash([checkpointNumber]);
700
+ }
701
+
702
+ getCurrentBlobCommitmentsHash() {
703
+ return this.rollup.read.getCurrentBlobCommitmentsHash();
704
+ }
705
+
706
+ getStakingAsset() {
707
+ return this.rollup.read.getStakingAsset();
708
+ }
709
+
710
+ getRewardConfig() {
711
+ return this.rollup.read.getRewardConfig();
712
+ }
713
+
714
+ setupEpoch(l1TxUtils: L1TxUtils) {
715
+ return l1TxUtils.sendAndMonitorTransaction({
716
+ to: this.address,
717
+ data: encodeFunctionData({
718
+ abi: RollupAbi,
719
+ functionName: 'setupEpoch',
720
+ args: [],
721
+ }),
722
+ });
723
+ }
724
+
725
+ vote(l1TxUtils: L1TxUtils, proposalId: bigint) {
726
+ return l1TxUtils.sendAndMonitorTransaction({
727
+ to: this.address,
728
+ data: encodeFunctionData({
729
+ abi: RollupAbi,
730
+ functionName: 'vote',
731
+ args: [proposalId],
732
+ }),
733
+ });
734
+ }
735
+
736
+ public listenToSlasherChanged(
737
+ callback: (args: { oldSlasher: `0x${string}`; newSlasher: `0x${string}` }) => unknown,
738
+ ): WatchContractEventReturnType {
739
+ return this.rollup.watchEvent.SlasherUpdated(
740
+ {},
741
+ {
742
+ onLogs: logs => {
743
+ for (const log of logs) {
744
+ const args = log.args;
745
+ if (args.oldSlasher && args.newSlasher) {
746
+ callback(args as { oldSlasher: `0x${string}`; newSlasher: `0x${string}` });
747
+ }
748
+ }
749
+ },
750
+ },
751
+ );
752
+ }
753
+
754
+ public listenToCheckpointInvalidated(
755
+ callback: (args: { checkpointNumber: bigint }) => unknown,
756
+ ): WatchContractEventReturnType {
757
+ return this.rollup.watchEvent.CheckpointInvalidated(
758
+ {},
759
+ {
760
+ onLogs: logs => {
761
+ for (const log of logs) {
762
+ const args = log.args;
763
+ if (args.checkpointNumber !== undefined) {
764
+ callback({ checkpointNumber: args.checkpointNumber });
765
+ }
766
+ }
767
+ },
768
+ },
769
+ );
770
+ }
771
+
772
+ public async getSlashEvents(l1BlockHash: Hex): Promise<{ amount: bigint; attester: EthAddress }[]> {
773
+ const events = await this.rollup.getEvents.Slashed({}, { blockHash: l1BlockHash, strict: true });
774
+ return events.map(event => ({
775
+ amount: event.args.amount!,
776
+ attester: EthAddress.fromString(event.args.attester!),
777
+ }));
778
+ }
779
+
780
+ public listenToSlash(
781
+ callback: (args: { amount: bigint; attester: EthAddress }) => unknown,
782
+ ): WatchContractEventReturnType {
783
+ return this.rollup.watchEvent.Slashed(
784
+ {},
785
+ {
786
+ strict: true,
787
+ onLogs: logs => {
788
+ for (const log of logs) {
789
+ const args = log.args;
790
+ callback({ amount: args.amount!, attester: EthAddress.fromString(args.attester!) });
791
+ }
792
+ },
793
+ },
794
+ );
273
795
  }
274
796
  }