@aztec/ethereum 0.0.0-test.1 → 0.0.1-commit.24de95ac

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