@aztec-labs/ethereum 6.0.0-nightly.20260829
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.
- package/README.md +3 -0
- package/dest/account.d.ts +2 -0
- package/dest/account.d.ts.map +1 -0
- package/dest/account.js +4 -0
- package/dest/chain.d.ts +25 -0
- package/dest/chain.d.ts.map +1 -0
- package/dest/chain.js +53 -0
- package/dest/client.d.ts +42 -0
- package/dest/client.d.ts.map +1 -0
- package/dest/client.js +104 -0
- package/dest/config.d.ts +103 -0
- package/dest/config.d.ts.map +1 -0
- package/dest/config.js +233 -0
- package/dest/constants.d.ts +4 -0
- package/dest/constants.d.ts.map +1 -0
- package/dest/constants.js +2 -0
- package/dest/contracts/chain_state_override.d.ts +81 -0
- package/dest/contracts/chain_state_override.d.ts.map +1 -0
- package/dest/contracts/chain_state_override.js +139 -0
- package/dest/contracts/empire_base.d.ts +30 -0
- package/dest/contracts/empire_base.d.ts.map +1 -0
- package/dest/contracts/empire_base.js +84 -0
- package/dest/contracts/errors.d.ts +7 -0
- package/dest/contracts/errors.d.ts.map +1 -0
- package/dest/contracts/errors.js +12 -0
- package/dest/contracts/fee_asset_handler.d.ts +20 -0
- package/dest/contracts/fee_asset_handler.d.ts.map +1 -0
- package/dest/contracts/fee_asset_handler.js +59 -0
- package/dest/contracts/fee_asset_price_oracle.d.ts +105 -0
- package/dest/contracts/fee_asset_price_oracle.d.ts.map +1 -0
- package/dest/contracts/fee_asset_price_oracle.js +656 -0
- package/dest/contracts/fee_juice.d.ts +14 -0
- package/dest/contracts/fee_juice.d.ts.map +1 -0
- package/dest/contracts/fee_juice.js +59 -0
- package/dest/contracts/governance.d.ts +192 -0
- package/dest/contracts/governance.d.ts.map +1 -0
- package/dest/contracts/governance.js +471 -0
- package/dest/contracts/governance_proposer.d.ts +63 -0
- package/dest/contracts/governance_proposer.d.ts.map +1 -0
- package/dest/contracts/governance_proposer.js +536 -0
- package/dest/contracts/gse.d.ts +38 -0
- package/dest/contracts/gse.d.ts.map +1 -0
- package/dest/contracts/gse.js +81 -0
- package/dest/contracts/inbox.d.ts +94 -0
- package/dest/contracts/inbox.d.ts.map +1 -0
- package/dest/contracts/inbox.js +141 -0
- package/dest/contracts/index.d.ts +18 -0
- package/dest/contracts/index.d.ts.map +1 -0
- package/dest/contracts/index.js +17 -0
- package/dest/contracts/log.d.ts +13 -0
- package/dest/contracts/log.d.ts.map +1 -0
- package/dest/contracts/log.js +1 -0
- package/dest/contracts/multicall.d.ts +138 -0
- package/dest/contracts/multicall.d.ts.map +1 -0
- package/dest/contracts/multicall.js +266 -0
- package/dest/contracts/outbox.d.ts +64 -0
- package/dest/contracts/outbox.d.ts.map +1 -0
- package/dest/contracts/outbox.js +113 -0
- package/dest/contracts/registry.d.ts +31 -0
- package/dest/contracts/registry.d.ts.map +1 -0
- package/dest/contracts/registry.js +142 -0
- package/dest/contracts/rollup.d.ts +5836 -0
- package/dest/contracts/rollup.d.ts.map +1 -0
- package/dest/contracts/rollup.js +1612 -0
- package/dest/contracts/slasher_contract.d.ts +44 -0
- package/dest/contracts/slasher_contract.d.ts.map +1 -0
- package/dest/contracts/slasher_contract.js +75 -0
- package/dest/contracts/slashing_proposer.d.ts +174 -0
- package/dest/contracts/slashing_proposer.d.ts.map +1 -0
- package/dest/contracts/slashing_proposer.js +755 -0
- package/dest/contracts/utils.d.ts +3 -0
- package/dest/contracts/utils.d.ts.map +1 -0
- package/dest/contracts/utils.js +11 -0
- package/dest/contracts/watch_event.d.ts +36 -0
- package/dest/contracts/watch_event.d.ts.map +1 -0
- package/dest/contracts/watch_event.js +66 -0
- package/dest/deploy_aztec_l1_contracts.d.ts +267 -0
- package/dest/deploy_aztec_l1_contracts.d.ts.map +1 -0
- package/dest/deploy_aztec_l1_contracts.js +424 -0
- package/dest/deploy_l1_contract.d.ts +68 -0
- package/dest/deploy_l1_contract.d.ts.map +1 -0
- package/dest/deploy_l1_contract.js +312 -0
- package/dest/eth-signer/eth-signer.d.ts +21 -0
- package/dest/eth-signer/eth-signer.d.ts.map +1 -0
- package/dest/eth-signer/eth-signer.js +5 -0
- package/dest/eth-signer/index.d.ts +2 -0
- package/dest/eth-signer/index.d.ts.map +1 -0
- package/dest/eth-signer/index.js +1 -0
- package/dest/forwarder_proxy.d.ts +32 -0
- package/dest/forwarder_proxy.d.ts.map +1 -0
- package/dest/forwarder_proxy.js +93 -0
- package/dest/foundry_binary.d.ts +13 -0
- package/dest/foundry_binary.d.ts.map +1 -0
- package/dest/foundry_binary.js +52 -0
- package/dest/l1_artifacts.d.ts +81896 -0
- package/dest/l1_artifacts.d.ts.map +1 -0
- package/dest/l1_artifacts.js +151 -0
- package/dest/l1_contract_addresses.d.ts +73 -0
- package/dest/l1_contract_addresses.d.ts.map +1 -0
- package/dest/l1_contract_addresses.js +120 -0
- package/dest/l1_reader.d.ts +18 -0
- package/dest/l1_reader.d.ts.map +1 -0
- package/dest/l1_reader.js +35 -0
- package/dest/l1_tx_utils/config.d.ts +65 -0
- package/dest/l1_tx_utils/config.d.ts.map +1 -0
- package/dest/l1_tx_utils/config.js +109 -0
- package/dest/l1_tx_utils/constants.d.ts +12 -0
- package/dest/l1_tx_utils/constants.d.ts.map +1 -0
- package/dest/l1_tx_utils/constants.js +39 -0
- package/dest/l1_tx_utils/factory.d.ts +32 -0
- package/dest/l1_tx_utils/factory.d.ts.map +1 -0
- package/dest/l1_tx_utils/factory.js +22 -0
- package/dest/l1_tx_utils/fee-strategies/index.d.ts +10 -0
- package/dest/l1_tx_utils/fee-strategies/index.d.ts.map +1 -0
- package/dest/l1_tx_utils/fee-strategies/index.js +12 -0
- package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts +8 -0
- package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts.map +1 -0
- package/dest/l1_tx_utils/fee-strategies/p75_competitive.js +129 -0
- package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts +23 -0
- package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts.map +1 -0
- package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.js +191 -0
- package/dest/l1_tx_utils/fee-strategies/types.d.ts +51 -0
- package/dest/l1_tx_utils/fee-strategies/types.d.ts.map +1 -0
- package/dest/l1_tx_utils/fee-strategies/types.js +3 -0
- package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts +41 -0
- package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts.map +1 -0
- package/dest/l1_tx_utils/forwarder_l1_tx_utils.js +42 -0
- package/dest/l1_tx_utils/index-blobs.d.ts +3 -0
- package/dest/l1_tx_utils/index-blobs.d.ts.map +1 -0
- package/dest/l1_tx_utils/index-blobs.js +2 -0
- package/dest/l1_tx_utils/index.d.ts +13 -0
- package/dest/l1_tx_utils/index.d.ts.map +1 -0
- package/dest/l1_tx_utils/index.js +13 -0
- package/dest/l1_tx_utils/interfaces.d.ts +76 -0
- package/dest/l1_tx_utils/interfaces.d.ts.map +1 -0
- package/dest/l1_tx_utils/interfaces.js +4 -0
- package/dest/l1_tx_utils/l1_fee_analyzer.d.ts +252 -0
- package/dest/l1_tx_utils/l1_fee_analyzer.d.ts.map +1 -0
- package/dest/l1_tx_utils/l1_fee_analyzer.js +568 -0
- package/dest/l1_tx_utils/l1_tx_utils.d.ts +113 -0
- package/dest/l1_tx_utils/l1_tx_utils.d.ts.map +1 -0
- package/dest/l1_tx_utils/l1_tx_utils.js +720 -0
- package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts +83 -0
- package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts.map +1 -0
- package/dest/l1_tx_utils/readonly_l1_tx_utils.js +357 -0
- package/dest/l1_tx_utils/signer.d.ts +4 -0
- package/dest/l1_tx_utils/signer.d.ts.map +1 -0
- package/dest/l1_tx_utils/signer.js +16 -0
- package/dest/l1_tx_utils/tx_delayer.d.ts +58 -0
- package/dest/l1_tx_utils/tx_delayer.d.ts.map +1 -0
- package/dest/l1_tx_utils/tx_delayer.js +223 -0
- package/dest/l1_tx_utils/types.d.ts +93 -0
- package/dest/l1_tx_utils/types.d.ts.map +1 -0
- package/dest/l1_tx_utils/types.js +36 -0
- package/dest/l1_tx_utils/utils.d.ts +4 -0
- package/dest/l1_tx_utils/utils.d.ts.map +1 -0
- package/dest/l1_tx_utils/utils.js +14 -0
- package/dest/l1_types.d.ts +6 -0
- package/dest/l1_types.d.ts.map +1 -0
- package/dest/l1_types.js +1 -0
- package/dest/publisher_manager.d.ts +42 -0
- package/dest/publisher_manager.d.ts.map +1 -0
- package/dest/publisher_manager.js +199 -0
- package/dest/queries.d.ts +25 -0
- package/dest/queries.d.ts.map +1 -0
- package/dest/queries.js +144 -0
- package/dest/test/blob_kzg_warmup.d.ts +19 -0
- package/dest/test/blob_kzg_warmup.d.ts.map +1 -0
- package/dest/test/blob_kzg_warmup.js +64 -0
- package/dest/test/chain_monitor.d.ts +126 -0
- package/dest/test/chain_monitor.d.ts.map +1 -0
- package/dest/test/chain_monitor.js +314 -0
- package/dest/test/eth_cheat_codes.d.ts +260 -0
- package/dest/test/eth_cheat_codes.d.ts.map +1 -0
- package/dest/test/eth_cheat_codes.js +608 -0
- package/dest/test/eth_cheat_codes_with_state.d.ts +18 -0
- package/dest/test/eth_cheat_codes_with_state.d.ts.map +1 -0
- package/dest/test/eth_cheat_codes_with_state.js +34 -0
- package/dest/test/index.d.ts +8 -0
- package/dest/test/index.d.ts.map +1 -0
- package/dest/test/index.js +7 -0
- package/dest/test/recording_rpc_server.d.ts +18 -0
- package/dest/test/recording_rpc_server.d.ts.map +1 -0
- package/dest/test/recording_rpc_server.js +68 -0
- package/dest/test/rollup_cheat_codes.d.ts +142 -0
- package/dest/test/rollup_cheat_codes.d.ts.map +1 -0
- package/dest/test/rollup_cheat_codes.js +338 -0
- package/dest/test/start_anvil.d.ts +40 -0
- package/dest/test/start_anvil.d.ts.map +1 -0
- package/dest/test/start_anvil.js +210 -0
- package/dest/test/upgrade_utils.d.ts +12 -0
- package/dest/test/upgrade_utils.d.ts.map +1 -0
- package/dest/test/upgrade_utils.js +111 -0
- package/dest/types.d.ts +68 -0
- package/dest/types.d.ts.map +1 -0
- package/dest/types.js +3 -0
- package/dest/utils.d.ts +45 -0
- package/dest/utils.d.ts.map +1 -0
- package/dest/utils.js +260 -0
- package/dest/zkPassportVerifierAddress.d.ts +15 -0
- package/dest/zkPassportVerifierAddress.d.ts.map +1 -0
- package/dest/zkPassportVerifierAddress.js +11 -0
- package/package.json +122 -0
- package/src/account.ts +5 -0
- package/src/chain.ts +71 -0
- package/src/client.ts +165 -0
- package/src/config.ts +342 -0
- package/src/constants.ts +4 -0
- package/src/contracts/README.md +157 -0
- package/src/contracts/chain_state_override.ts +203 -0
- package/src/contracts/empire_base.ts +89 -0
- package/src/contracts/errors.ts +13 -0
- package/src/contracts/fee_asset_handler.ts +66 -0
- package/src/contracts/fee_asset_price_oracle.ts +284 -0
- package/src/contracts/fee_juice.ts +57 -0
- package/src/contracts/governance.ts +597 -0
- package/src/contracts/governance_proposer.ts +181 -0
- package/src/contracts/gse.ts +105 -0
- package/src/contracts/inbox.ts +223 -0
- package/src/contracts/index.ts +17 -0
- package/src/contracts/log.ts +13 -0
- package/src/contracts/multicall.ts +298 -0
- package/src/contracts/outbox.ts +132 -0
- package/src/contracts/registry.ts +161 -0
- package/src/contracts/rollup.ts +1502 -0
- package/src/contracts/slasher_contract.ts +89 -0
- package/src/contracts/slashing_proposer.ts +397 -0
- package/src/contracts/utils.ts +14 -0
- package/src/contracts/watch_event.ts +109 -0
- package/src/deploy_aztec_l1_contracts.ts +663 -0
- package/src/deploy_l1_contract.ts +361 -0
- package/src/eth-signer/eth-signer.ts +24 -0
- package/src/eth-signer/index.ts +1 -0
- package/src/forwarder_proxy.ts +107 -0
- package/src/foundry_binary.ts +57 -0
- package/src/l1_artifacts.ts +231 -0
- package/src/l1_contract_addresses.ts +149 -0
- package/src/l1_reader.ts +57 -0
- package/src/l1_tx_utils/README.md +177 -0
- package/src/l1_tx_utils/config.ts +181 -0
- package/src/l1_tx_utils/constants.ts +29 -0
- package/src/l1_tx_utils/factory.ts +64 -0
- package/src/l1_tx_utils/fee-strategies/index.ts +22 -0
- package/src/l1_tx_utils/fee-strategies/p75_competitive.ts +162 -0
- package/src/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.ts +244 -0
- package/src/l1_tx_utils/fee-strategies/types.ts +55 -0
- package/src/l1_tx_utils/forwarder_l1_tx_utils.ts +107 -0
- package/src/l1_tx_utils/index-blobs.ts +2 -0
- package/src/l1_tx_utils/index.ts +15 -0
- package/src/l1_tx_utils/interfaces.ts +86 -0
- package/src/l1_tx_utils/l1_fee_analyzer.ts +874 -0
- package/src/l1_tx_utils/l1_tx_utils.ts +840 -0
- package/src/l1_tx_utils/readonly_l1_tx_utils.ts +459 -0
- package/src/l1_tx_utils/signer.ts +27 -0
- package/src/l1_tx_utils/tx_delayer.ts +302 -0
- package/src/l1_tx_utils/types.ts +116 -0
- package/src/l1_tx_utils/utils.ts +15 -0
- package/src/l1_types.ts +6 -0
- package/src/publisher_manager.ts +239 -0
- package/src/queries.ts +189 -0
- package/src/test/blob_kzg_warmup.ts +65 -0
- package/src/test/chain_monitor.ts +389 -0
- package/src/test/eth_cheat_codes.ts +624 -0
- package/src/test/eth_cheat_codes_with_state.ts +38 -0
- package/src/test/index.ts +7 -0
- package/src/test/recording_rpc_server.ts +69 -0
- package/src/test/rollup_cheat_codes.ts +398 -0
- package/src/test/start_anvil.ts +255 -0
- package/src/test/upgrade_utils.ts +109 -0
- package/src/types.ts +97 -0
- package/src/utils.ts +344 -0
- package/src/zkPassportVerifierAddress.ts +15 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { EthAddress } from '@aztec-labs/foundation/eth-address';
|
|
2
|
+
import { decodeFunctionResult, encodeFunctionData, multicall3Abi } from 'viem';
|
|
3
|
+
import { tryDecodeRevertReason } from '../utils.js';
|
|
4
|
+
export const MULTI_CALL_3_ADDRESS = '0xcA11bde05977b3631167028862bE2a173976CA11';
|
|
5
|
+
/**
|
|
6
|
+
* Thrown by `Multicall3.forward` when the forwarder transaction lands but the receipt reports a
|
|
7
|
+
* reverted status. This is not expected (aggregate3 uses allowFailure: true), so callers should
|
|
8
|
+
* treat it as a fatal on-chain failure rather than retrying on a different publisher.
|
|
9
|
+
*/ export class MulticallForwarderRevertedError extends Error {
|
|
10
|
+
receipt;
|
|
11
|
+
txState;
|
|
12
|
+
constructor(receipt, txState){
|
|
13
|
+
super(`Multicall3 forwarder tx reverted: ${receipt.transactionHash}`), this.receipt = receipt, this.txState = txState;
|
|
14
|
+
this.name = 'MulticallForwarderRevertedError';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/** ABI fragment for aggregate3Value — not included in viem's multicall3Abi. */ export const aggregate3ValueAbi = [
|
|
18
|
+
{
|
|
19
|
+
inputs: [
|
|
20
|
+
{
|
|
21
|
+
components: [
|
|
22
|
+
{
|
|
23
|
+
internalType: 'address',
|
|
24
|
+
name: 'target',
|
|
25
|
+
type: 'address'
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
internalType: 'bool',
|
|
29
|
+
name: 'allowFailure',
|
|
30
|
+
type: 'bool'
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
internalType: 'uint256',
|
|
34
|
+
name: 'value',
|
|
35
|
+
type: 'uint256'
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
internalType: 'bytes',
|
|
39
|
+
name: 'callData',
|
|
40
|
+
type: 'bytes'
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
internalType: 'struct Multicall3.Call3Value[]',
|
|
44
|
+
name: 'calls',
|
|
45
|
+
type: 'tuple[]'
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
name: 'aggregate3Value',
|
|
49
|
+
outputs: [
|
|
50
|
+
{
|
|
51
|
+
components: [
|
|
52
|
+
{
|
|
53
|
+
internalType: 'bool',
|
|
54
|
+
name: 'success',
|
|
55
|
+
type: 'bool'
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
internalType: 'bytes',
|
|
59
|
+
name: 'returnData',
|
|
60
|
+
type: 'bytes'
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
internalType: 'struct Multicall3.Result[]',
|
|
64
|
+
name: 'returnData',
|
|
65
|
+
type: 'tuple[]'
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
stateMutability: 'payable',
|
|
69
|
+
type: 'function'
|
|
70
|
+
}
|
|
71
|
+
];
|
|
72
|
+
export class Multicall3 {
|
|
73
|
+
/**
|
|
74
|
+
* Returns true iff Multicall3 bytecode is deployed at MULTI_CALL_3_ADDRESS. An empty result from
|
|
75
|
+
* a non-existent contract would otherwise silently validate any bundle that uses Multicall3.
|
|
76
|
+
*/ static async hasCode(l1TxUtils) {
|
|
77
|
+
const code = await l1TxUtils.getCode(EthAddress.fromString(MULTI_CALL_3_ADDRESS));
|
|
78
|
+
return !!code && code !== '0x';
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Simulates an aggregate3 call composed of the given requests via eth_simulateV1 and decodes the
|
|
82
|
+
* per-entry Result[]. Entries that revert are returned with a decoded revertReason (if the request
|
|
83
|
+
* provided an abi).
|
|
84
|
+
*
|
|
85
|
+
* Use this to pre-validate a bundle before sending it through `Multicall3.forward`. The caller can
|
|
86
|
+
* drop reverted entries from the bundle and re-simulate with the reduced list to get an accurate
|
|
87
|
+
* `gasUsed`.
|
|
88
|
+
*/ static async simulateAggregate3(requests, l1TxUtils, opts = {}) {
|
|
89
|
+
const calldata = encodeFunctionData({
|
|
90
|
+
abi: multicall3Abi,
|
|
91
|
+
functionName: 'aggregate3',
|
|
92
|
+
args: [
|
|
93
|
+
requests.map((r)=>({
|
|
94
|
+
target: r.to,
|
|
95
|
+
callData: r.data,
|
|
96
|
+
allowFailure: true
|
|
97
|
+
}))
|
|
98
|
+
]
|
|
99
|
+
});
|
|
100
|
+
const stateOverrides = [
|
|
101
|
+
...opts.stateOverrides ?? []
|
|
102
|
+
];
|
|
103
|
+
if (opts.fakeSenderBalance !== undefined) {
|
|
104
|
+
stateOverrides.push({
|
|
105
|
+
address: l1TxUtils.getSenderAddress().toString(),
|
|
106
|
+
balance: opts.fakeSenderBalance
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
const simResult = await l1TxUtils.simulate({
|
|
110
|
+
to: MULTI_CALL_3_ADDRESS,
|
|
111
|
+
data: calldata,
|
|
112
|
+
gas: opts.gas
|
|
113
|
+
}, opts.blockOverrides, stateOverrides, multicall3Abi, {
|
|
114
|
+
fallbackGasEstimate: opts.fallbackGasEstimate
|
|
115
|
+
});
|
|
116
|
+
if (simResult.result === '0x') {
|
|
117
|
+
return {
|
|
118
|
+
kind: 'fallback',
|
|
119
|
+
gasUsed: simResult.gasUsed
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
const decoded = decodeFunctionResult({
|
|
123
|
+
abi: multicall3Abi,
|
|
124
|
+
functionName: 'aggregate3',
|
|
125
|
+
data: simResult.result
|
|
126
|
+
});
|
|
127
|
+
const entries = decoded.map((entry, i)=>{
|
|
128
|
+
if (entry.success) {
|
|
129
|
+
return {
|
|
130
|
+
success: true,
|
|
131
|
+
returnData: entry.returnData
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
const abi = requests[i].abi;
|
|
135
|
+
const revertReason = abi ? tryDecodeRevertReason(entry.returnData, abi) : undefined;
|
|
136
|
+
return {
|
|
137
|
+
success: false,
|
|
138
|
+
returnData: entry.returnData,
|
|
139
|
+
revertReason
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
return {
|
|
143
|
+
kind: 'decoded',
|
|
144
|
+
entries,
|
|
145
|
+
gasUsed: simResult.gasUsed
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Sends a batch of requests through aggregate3. Individual calls may fail (allowFailure: true),
|
|
150
|
+
* but the top-level multicall is expected to land successfully. Throws if the send fails or if
|
|
151
|
+
* the receipt reports a reverted status.
|
|
152
|
+
*/ static async forward(requests, l1TxUtils, gasConfig, blobConfig, opts = {}) {
|
|
153
|
+
if (opts.gasLimitRequired && !gasConfig?.gasLimit) {
|
|
154
|
+
throw new Error('Multicall gasLimit is required when gasLimitRequired is true');
|
|
155
|
+
}
|
|
156
|
+
const args = requests.filter((request)=>request.to !== null).map((r)=>({
|
|
157
|
+
target: r.to,
|
|
158
|
+
callData: r.data,
|
|
159
|
+
allowFailure: true
|
|
160
|
+
}));
|
|
161
|
+
const encodedForwarderData = encodeFunctionData({
|
|
162
|
+
abi: multicall3Abi,
|
|
163
|
+
functionName: 'aggregate3',
|
|
164
|
+
args: [
|
|
165
|
+
args
|
|
166
|
+
]
|
|
167
|
+
});
|
|
168
|
+
const { receipt, state } = await l1TxUtils.sendAndMonitorTransaction({
|
|
169
|
+
to: MULTI_CALL_3_ADDRESS,
|
|
170
|
+
data: encodedForwarderData,
|
|
171
|
+
abi: multicall3Abi
|
|
172
|
+
}, gasConfig, blobConfig);
|
|
173
|
+
// This shouldn't happen. Any failure in individual calls is swallowed by forward since we set
|
|
174
|
+
// allowFailure to true for all calls, so a reverted status here would indicate a problem with
|
|
175
|
+
// the Multicall3 contract itself or the forwarder transaction (such as an out-of-gas).
|
|
176
|
+
if (receipt.status !== 'success') {
|
|
177
|
+
throw new MulticallForwarderRevertedError(receipt, state);
|
|
178
|
+
}
|
|
179
|
+
const stats = await l1TxUtils.getTransactionStats(receipt.transactionHash);
|
|
180
|
+
return {
|
|
181
|
+
receipt,
|
|
182
|
+
stats,
|
|
183
|
+
multicallData: encodedForwarderData,
|
|
184
|
+
state
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
/** Batch multiple value transfers into a single aggregate3Value call on Multicall3. */ static async forwardValue(calls, l1TxUtils, logger) {
|
|
188
|
+
const args = calls.map((c)=>({
|
|
189
|
+
target: c.to,
|
|
190
|
+
allowFailure: false,
|
|
191
|
+
value: c.value,
|
|
192
|
+
callData: '0x'
|
|
193
|
+
}));
|
|
194
|
+
const data = encodeFunctionData({
|
|
195
|
+
abi: aggregate3ValueAbi,
|
|
196
|
+
functionName: 'aggregate3Value',
|
|
197
|
+
args: [
|
|
198
|
+
args
|
|
199
|
+
]
|
|
200
|
+
});
|
|
201
|
+
const totalValue = calls.reduce((sum, c)=>sum + c.value, 0n);
|
|
202
|
+
logger.info(`Sending aggregate3Value with ${calls.length} calls`, {
|
|
203
|
+
totalValue
|
|
204
|
+
});
|
|
205
|
+
const { receipt } = await l1TxUtils.sendAndMonitorTransaction({
|
|
206
|
+
to: MULTI_CALL_3_ADDRESS,
|
|
207
|
+
data,
|
|
208
|
+
value: totalValue
|
|
209
|
+
});
|
|
210
|
+
if (receipt.status !== 'success') {
|
|
211
|
+
throw new Error(`aggregate3Value transaction reverted: ${receipt.transactionHash}`);
|
|
212
|
+
}
|
|
213
|
+
return {
|
|
214
|
+
receipt
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
export async function deployMulticall3(l1Client, logger) {
|
|
219
|
+
const existing = await l1Client.getCode({
|
|
220
|
+
address: MULTI_CALL_3_ADDRESS
|
|
221
|
+
});
|
|
222
|
+
if (existing && existing !== '0x') {
|
|
223
|
+
logger.verbose('Multicall3 already deployed', {
|
|
224
|
+
address: MULTI_CALL_3_ADDRESS
|
|
225
|
+
});
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
const deployer = '0x05f32b3cc3888453ff71b01135b34ff8e41263f2';
|
|
229
|
+
const sendEth = await l1Client.sendTransaction({
|
|
230
|
+
to: deployer,
|
|
231
|
+
value: 10n ** 17n
|
|
232
|
+
});
|
|
233
|
+
logger.info('Sent 0.1 ETH to deployer', {
|
|
234
|
+
deployer,
|
|
235
|
+
value: 10n ** 17n
|
|
236
|
+
});
|
|
237
|
+
const sendEthReceipt = await l1Client.waitForTransactionReceipt({
|
|
238
|
+
hash: sendEth
|
|
239
|
+
});
|
|
240
|
+
if (sendEthReceipt.status !== 'success') {
|
|
241
|
+
logger.error('Failed to send ETH to deployer', undefined, {
|
|
242
|
+
sendEthReceipt
|
|
243
|
+
});
|
|
244
|
+
throw new Error('Failed to send ETH to deployer');
|
|
245
|
+
} else {
|
|
246
|
+
logger.info('Sent 0.1 ETH to deployer', {
|
|
247
|
+
deployer,
|
|
248
|
+
value: 10n ** 17n
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
const tx = '0xf90f538085174876e800830f42408080b90f00608060405234801561001057600080fd5b50610ee0806100206000396000f3fe6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461025a578063bce38bd714610275578063c3077fa914610288578063ee82ac5e1461029b57600080fd5b80634d2301cc146101ec57806372425d9d1461022157806382ad56cb1461023457806386d516e81461024757600080fd5b80633408e470116100c65780633408e47014610191578063399542e9146101a45780633e64a696146101c657806342cbb15c146101d957600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d610128366004610a85565b6102ba565b6040516101119190610bbe565b61014d610148366004610a85565b6104ef565b604051610111929190610bd8565b34801561016757600080fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610107565b34801561019d57600080fd5b5046610107565b6101b76101b2366004610c60565b610690565b60405161011193929190610cba565b3480156101d257600080fd5b5048610107565b3480156101e557600080fd5b5043610107565b3480156101f857600080fd5b50610107610207366004610ce2565b73ffffffffffffffffffffffffffffffffffffffff163190565b34801561022d57600080fd5b5044610107565b61012d610242366004610a85565b6106ab565b34801561025357600080fd5b5045610107565b34801561026657600080fd5b50604051418152602001610111565b61012d610283366004610c60565b61085a565b6101b7610296366004610a85565b610a1a565b3480156102a757600080fd5b506101076102b6366004610d18565b4090565b60606000828067ffffffffffffffff8111156102d8576102d8610d31565b60405190808252806020026020018201604052801561031e57816020015b6040805180820190915260008152606060208201528152602001906001900390816102f65790505b5092503660005b8281101561047757600085828151811061034157610341610d60565b6020026020010151905087878381811061035d5761035d610d60565b905060200281019061036f9190610d8f565b6040810135958601959093506103886020850185610ce2565b73ffffffffffffffffffffffffffffffffffffffff16816103ac6060870187610dcd565b6040516103ba929190610e32565b60006040518083038185875af1925050503d80600081146103f7576040519150601f19603f3d011682016040523d82523d6000602084013e6103fc565b606091505b50602080850191909152901515808452908501351761046d577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fd5b5050600101610325565b508234146104e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561050c5761050c610d31565b60405190808252806020026020018201604052801561053f57816020015b606081526020019060019003908161052a5790505b5091503660005b8281101561068657600087878381811061056257610562610d60565b90506020028101906105749190610e42565b92506105836020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166105a66020850185610dcd565b6040516105b4929190610e32565b6000604051808303816000865af19150503d80600081146105f1576040519150601f19603f3d011682016040523d82523d6000602084013e6105f6565b606091505b5086848151811061060957610609610d60565b602090810291909101015290508061067d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b50600101610546565b5050509250929050565b43804060606106a086868661085a565b905093509350939050565b6060818067ffffffffffffffff8111156106c7576106c7610d31565b60405190808252806020026020018201604052801561070d57816020015b6040805180820190915260008152606060208201528152602001906001900390816106e55790505b5091503660005b828110156104e657600084828151811061073057610730610d60565b6020026020010151905086868381811061074c5761074c610d60565b905060200281019061075e9190610e76565b925061076d6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166107906040850185610dcd565b60405161079e929190610e32565b6000604051808303816000865af19150503d80600081146107db576040519150601f19603f3d011682016040523d82523d6000602084013e6107e0565b606091505b506020808401919091529015158083529084013517610851577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b50600101610714565b6060818067ffffffffffffffff81111561087657610876610d31565b6040519080825280602002602001820160405280156108bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816108945790505b5091503660005b82811015610a105760008482815181106108df576108df610d60565b602002602001015190508686838181106108fb576108fb610d60565b905060200281019061090d9190610e42565b925061091c6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff1661093f6020850185610dcd565b60405161094d929190610e32565b6000604051808303816000865af19150503d806000811461098a576040519150601f19603f3d011682016040523d82523d6000602084013e61098f565b606091505b506020830152151581528715610a07578051610a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b506001016108c3565b5050509392505050565b6000806060610a2b60018686610690565b919790965090945092505050565b60008083601f840112610a4b57600080fd5b50813567ffffffffffffffff811115610a6357600080fd5b6020830191508360208260051b8501011115610a7e57600080fd5b9250929050565b60008060208385031215610a9857600080fd5b823567ffffffffffffffff811115610aaf57600080fd5b610abb85828601610a39565b90969095509350505050565b6000815180845260005b81811015610aed57602081850181015186830182015201610ad1565b81811115610aff576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b84811015610bb1578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b9d81860183610ac7565b9a86019a9450505090830190600101610b4f565b5090979650505050505050565b602081526000610bd16020830184610b32565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610c52577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610c40868351610ac7565b95509284019290840190600101610c06565b509398975050505050505050565b600080600060408486031215610c7557600080fd5b83358015158114610c8557600080fd5b9250602084013567ffffffffffffffff811115610ca157600080fd5b610cad86828701610a39565b9497909650939450505050565b838152826020820152606060408201526000610cd96060830184610b32565b95945050505050565b600060208284031215610cf457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610bd157600080fd5b600060208284031215610d2a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610dc357600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610e0257600080fd5b83018035915067ffffffffffffffff821115610e1d57600080fd5b602001915036819003821315610a7e57600080fd5b8183823760009101908152919050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610dc357600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610dc357600080fdfea2646970667358221220bb2b5c71a328032f97c676ae39a1ec2148d3e5d6f73d95e9b17910152d61f16264736f6c634300080c00331ca0edce47092c0f398cebf3ffc267f05c8e7076e3b89445e0fe50f6332273d4569ba01b0b9d000e19b24c5869b0fc3b22b0d6fa47cd63316875cbbd577d76e6fde086';
|
|
252
|
+
const deployTx = await l1Client.sendRawTransaction({
|
|
253
|
+
serializedTransaction: tx
|
|
254
|
+
});
|
|
255
|
+
const deployTxReceipt = await l1Client.waitForTransactionReceipt({
|
|
256
|
+
hash: deployTx
|
|
257
|
+
});
|
|
258
|
+
if (deployTxReceipt.status !== 'success') {
|
|
259
|
+
logger.error('Failed to deploy Multicall3', undefined, {
|
|
260
|
+
deployTxReceipt
|
|
261
|
+
});
|
|
262
|
+
throw new Error('Failed to deploy Multicall3');
|
|
263
|
+
} else {
|
|
264
|
+
logger.info('Deployed Multicall3');
|
|
265
|
+
}
|
|
266
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { OutboxAbi } from '@aztec/l1-artifacts/OutboxAbi';
|
|
2
|
+
import type { EpochNumber } from '@aztec-labs/foundation/branded-types';
|
|
3
|
+
import { Fr } from '@aztec-labs/foundation/curves/bn254';
|
|
4
|
+
import { EthAddress } from '@aztec-labs/foundation/eth-address';
|
|
5
|
+
import { type GetContractReturnType, type Hex } from 'viem';
|
|
6
|
+
import type { DeployAztecL1ContractsReturnType } from '../deploy_aztec_l1_contracts.js';
|
|
7
|
+
import type { L1ReaderConfig } from '../l1_reader.js';
|
|
8
|
+
import { type ViemClient } from '../types.js';
|
|
9
|
+
export type ViemL1Actor = {
|
|
10
|
+
actor: Hex;
|
|
11
|
+
chainId: bigint;
|
|
12
|
+
};
|
|
13
|
+
export type ViemL2Actor = {
|
|
14
|
+
actor: Hex;
|
|
15
|
+
version: bigint;
|
|
16
|
+
};
|
|
17
|
+
export type ViemL2ToL1Msg = {
|
|
18
|
+
sender: ViemL2Actor;
|
|
19
|
+
recipient: ViemL1Actor;
|
|
20
|
+
content: Hex;
|
|
21
|
+
};
|
|
22
|
+
export declare class OutboxContract {
|
|
23
|
+
readonly client: ViemClient;
|
|
24
|
+
private readonly outbox;
|
|
25
|
+
static getFromL1ContractsValues(deployL1ContractsValues: DeployAztecL1ContractsReturnType): OutboxContract;
|
|
26
|
+
static getFromConfig(config: L1ReaderConfig): OutboxContract;
|
|
27
|
+
/**
|
|
28
|
+
* Storage slot of `epochs[epoch].roots[numCheckpointsInEpoch - 1]` in the Outbox contract.
|
|
29
|
+
*
|
|
30
|
+
* The Outbox lays out storage as `mapping(Epoch => EpochData) internal epochs` at base slot 0
|
|
31
|
+
* (ROLLUP and VERSION are immutable and do not occupy slots). For a mapping at slot `b`, the
|
|
32
|
+
* value for key `k` begins at `keccak256(abi.encode(k, b))`. `EpochData` starts with a fixed-
|
|
33
|
+
* size `bytes32[MAX_CHECKPOINTS_PER_EPOCH] roots` array, so `roots[i]` sits at the EpochData's
|
|
34
|
+
* base slot plus `i`. `numCheckpointsInEpoch` is 1-indexed (matches `Outbox.insert`/`consume`).
|
|
35
|
+
*/
|
|
36
|
+
static getEpochRootStorageSlot(epoch: EpochNumber, numCheckpointsInEpoch: number): bigint;
|
|
37
|
+
constructor(client: ViemClient, address: Hex | EthAddress);
|
|
38
|
+
get address(): `0x${string}`;
|
|
39
|
+
getContract(): GetContractReturnType<typeof OutboxAbi, ViemClient>;
|
|
40
|
+
hasMessageBeenConsumedAtEpoch(epoch: EpochNumber, leafId: bigint): Promise<boolean>;
|
|
41
|
+
getRootData(epoch: EpochNumber, numCheckpointsInEpoch: number): Promise<`0x${string}`>;
|
|
42
|
+
/**
|
|
43
|
+
* Returns every root stored for `epoch`. Slot `i` of the returned array holds the root inserted
|
|
44
|
+
* for `numCheckpointsInEpoch = i + 1`, or `Fr.ZERO` if no proof of that depth has been inserted
|
|
45
|
+
* yet. The array length is always `MAX_CHECKPOINTS_PER_EPOCH`.
|
|
46
|
+
*
|
|
47
|
+
* @param opts - Optional viem read options. Pass `blockNumber` to pin the read to a specific L1
|
|
48
|
+
* block, which is important for callers that want a consistent snapshot across multiple reads
|
|
49
|
+
* (e.g. the archiver's outbox-trees resolver, which pins to the node's synced L1 block).
|
|
50
|
+
*/
|
|
51
|
+
getRoots(epoch: EpochNumber, opts?: {
|
|
52
|
+
blockNumber?: bigint;
|
|
53
|
+
}): Promise<Fr[]>;
|
|
54
|
+
consume(message: ViemL2ToL1Msg, epoch: EpochNumber, numCheckpointsInEpoch: number, leafIndex: bigint, path: Hex[]): Promise<`0x${string}`>;
|
|
55
|
+
getMessageConsumedEvents(l1BlockHash: Hex): Promise<{
|
|
56
|
+
epoch: bigint;
|
|
57
|
+
root: Hex;
|
|
58
|
+
messageHash: Hex;
|
|
59
|
+
leafId: bigint;
|
|
60
|
+
numCheckpointsInEpoch: bigint;
|
|
61
|
+
}[]>;
|
|
62
|
+
private assertWallet;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3V0Ym94LmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29udHJhY3RzL291dGJveC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFMUQsT0FBTyxLQUFLLEVBQUUsV0FBVyxFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDeEUsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQ3pELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUNoRSxPQUFPLEVBQUUsS0FBSyxxQkFBcUIsRUFBRSxLQUFLLEdBQUcsRUFBNEQsTUFBTSxNQUFNLENBQUM7QUFHdEgsT0FBTyxLQUFLLEVBQUUsZ0NBQWdDLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUN4RixPQUFPLEtBQUssRUFBRSxjQUFjLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN0RCxPQUFPLEVBQWlDLEtBQUssVUFBVSxFQUFvQixNQUFNLGFBQWEsQ0FBQztBQUUvRixNQUFNLE1BQU0sV0FBVyxHQUFHO0lBQ3hCLEtBQUssRUFBRSxHQUFHLENBQUM7SUFDWCxPQUFPLEVBQUUsTUFBTSxDQUFDO0NBQ2pCLENBQUM7QUFFRixNQUFNLE1BQU0sV0FBVyxHQUFHO0lBQ3hCLEtBQUssRUFBRSxHQUFHLENBQUM7SUFDWCxPQUFPLEVBQUUsTUFBTSxDQUFDO0NBQ2pCLENBQUM7QUFFRixNQUFNLE1BQU0sYUFBYSxHQUFHO0lBQzFCLE1BQU0sRUFBRSxXQUFXLENBQUM7SUFDcEIsU0FBUyxFQUFFLFdBQVcsQ0FBQztJQUN2QixPQUFPLEVBQUUsR0FBRyxDQUFDO0NBQ2QsQ0FBQztBQUVGLHFCQUFhLGNBQWM7YUFrQ1AsTUFBTSxFQUFFLFVBQVU7SUFqQ3BDLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFzRDtJQUU3RSxNQUFNLENBQUMsd0JBQXdCLENBQUMsdUJBQXVCLEVBQUUsZ0NBQWdDLGtCQU14RjtJQUVELE1BQU0sQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLGNBQWMsa0JBSTFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSCxNQUFNLENBQUMsdUJBQXVCLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLFVBSy9FO0lBRUQsWUFDa0IsTUFBTSxFQUFFLFVBQVUsRUFDbEMsT0FBTyxFQUFFLEdBQUcsR0FBRyxVQUFVLEVBTTFCO0lBRUQsSUFBVyxPQUFPLGtCQUVqQjtJQUVNLFdBQVcsSUFBSSxxQkFBcUIsQ0FBQyxPQUFPLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FFeEU7SUFFTSw2QkFBNkIsQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxNQUFNLG9CQUV0RTtJQUVNLFdBQVcsQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMEJBRW5FO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDVSxRQUFRLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRSxJQUFJLENBQUMsRUFBRTtRQUFFLFdBQVcsQ0FBQyxFQUFFLE1BQU0sQ0FBQTtLQUFFLEdBQUcsT0FBTyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBR3hGO0lBRU0sT0FBTyxDQUNaLE9BQU8sRUFBRSxhQUFhLEVBQ3RCLEtBQUssRUFBRSxXQUFXLEVBQ2xCLHFCQUFxQixFQUFFLE1BQU0sRUFDN0IsU0FBUyxFQUFFLE1BQU0sRUFDakIsSUFBSSxFQUFFLEdBQUcsRUFBRSwwQkFJWjtJQUVZLHdCQUF3QixDQUNuQyxXQUFXLEVBQUUsR0FBRyxHQUNmLE9BQU8sQ0FBQztRQUFFLEtBQUssRUFBRSxNQUFNLENBQUM7UUFBQyxJQUFJLEVBQUUsR0FBRyxDQUFDO1FBQUMsV0FBVyxFQUFFLEdBQUcsQ0FBQztRQUFDLE1BQU0sRUFBRSxNQUFNLENBQUM7UUFBQyxxQkFBcUIsRUFBRSxNQUFNLENBQUE7S0FBRSxFQUFFLENBQUMsQ0FTMUc7SUFFRCxPQUFPLENBQUMsWUFBWTtDQU1yQiJ9
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outbox.d.ts","sourceRoot":"","sources":["../../src/contracts/outbox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AACxE,OAAO,EAAE,EAAE,EAAE,MAAM,qCAAqC,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAChE,OAAO,EAAE,KAAK,qBAAqB,EAAE,KAAK,GAAG,EAA4D,MAAM,MAAM,CAAC;AAGtH,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,iCAAiC,CAAC;AACxF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAiC,KAAK,UAAU,EAAoB,MAAM,aAAa,CAAC;AAE/F,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,GAAG,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,GAAG,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,EAAE,WAAW,CAAC;IACvB,OAAO,EAAE,GAAG,CAAC;CACd,CAAC;AAEF,qBAAa,cAAc;aAkCP,MAAM,EAAE,UAAU;IAjCpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsD;IAE7E,MAAM,CAAC,wBAAwB,CAAC,uBAAuB,EAAE,gCAAgC,kBAMxF;IAED,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,cAAc,kBAI1C;IAED;;;;;;;;OAQG;IACH,MAAM,CAAC,uBAAuB,CAAC,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,UAK/E;IAED,YACkB,MAAM,EAAE,UAAU,EAClC,OAAO,EAAE,GAAG,GAAG,UAAU,EAM1B;IAED,IAAW,OAAO,kBAEjB;IAEM,WAAW,IAAI,qBAAqB,CAAC,OAAO,SAAS,EAAE,UAAU,CAAC,CAExE;IAEM,6BAA6B,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,oBAEtE;IAEM,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,0BAEnE;IAED;;;;;;;;OAQG;IACU,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,EAAE,EAAE,CAAC,CAGxF;IAEM,OAAO,CACZ,OAAO,EAAE,aAAa,EACtB,KAAK,EAAE,WAAW,EAClB,qBAAqB,EAAE,MAAM,EAC7B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,GAAG,EAAE,0BAIZ;IAEY,wBAAwB,CACnC,WAAW,EAAE,GAAG,GACf,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,GAAG,CAAC;QAAC,WAAW,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,qBAAqB,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC,CAS1G;IAED,OAAO,CAAC,YAAY;CAMrB"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { OutboxAbi } from '@aztec/l1-artifacts/OutboxAbi';
|
|
2
|
+
import { Fr } from '@aztec-labs/foundation/curves/bn254';
|
|
3
|
+
import { EthAddress } from '@aztec-labs/foundation/eth-address';
|
|
4
|
+
import { encodeAbiParameters, getContract, hexToBigInt, keccak256 } from 'viem';
|
|
5
|
+
import { getPublicClient } from '../client.js';
|
|
6
|
+
import { isExtendedClient } from '../types.js';
|
|
7
|
+
export class OutboxContract {
|
|
8
|
+
client;
|
|
9
|
+
outbox;
|
|
10
|
+
static getFromL1ContractsValues(deployL1ContractsValues) {
|
|
11
|
+
const { l1Client, l1ContractAddresses: { outboxAddress } } = deployL1ContractsValues;
|
|
12
|
+
return new OutboxContract(l1Client, outboxAddress.toString());
|
|
13
|
+
}
|
|
14
|
+
static getFromConfig(config) {
|
|
15
|
+
const client = getPublicClient(config);
|
|
16
|
+
const address = config.outboxAddress.toString();
|
|
17
|
+
return new OutboxContract(client, address);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Storage slot of `epochs[epoch].roots[numCheckpointsInEpoch - 1]` in the Outbox contract.
|
|
21
|
+
*
|
|
22
|
+
* The Outbox lays out storage as `mapping(Epoch => EpochData) internal epochs` at base slot 0
|
|
23
|
+
* (ROLLUP and VERSION are immutable and do not occupy slots). For a mapping at slot `b`, the
|
|
24
|
+
* value for key `k` begins at `keccak256(abi.encode(k, b))`. `EpochData` starts with a fixed-
|
|
25
|
+
* size `bytes32[MAX_CHECKPOINTS_PER_EPOCH] roots` array, so `roots[i]` sits at the EpochData's
|
|
26
|
+
* base slot plus `i`. `numCheckpointsInEpoch` is 1-indexed (matches `Outbox.insert`/`consume`).
|
|
27
|
+
*/ static getEpochRootStorageSlot(epoch, numCheckpointsInEpoch) {
|
|
28
|
+
const epochDataSlot = hexToBigInt(keccak256(encodeAbiParameters([
|
|
29
|
+
{
|
|
30
|
+
type: 'uint256'
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
type: 'uint256'
|
|
34
|
+
}
|
|
35
|
+
], [
|
|
36
|
+
BigInt(epoch),
|
|
37
|
+
0n
|
|
38
|
+
])));
|
|
39
|
+
return epochDataSlot + BigInt(numCheckpointsInEpoch - 1);
|
|
40
|
+
}
|
|
41
|
+
constructor(client, address){
|
|
42
|
+
this.client = client;
|
|
43
|
+
if (address instanceof EthAddress) {
|
|
44
|
+
address = address.toString();
|
|
45
|
+
}
|
|
46
|
+
this.outbox = getContract({
|
|
47
|
+
address,
|
|
48
|
+
abi: OutboxAbi,
|
|
49
|
+
client
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
get address() {
|
|
53
|
+
return this.outbox.address;
|
|
54
|
+
}
|
|
55
|
+
getContract() {
|
|
56
|
+
return this.outbox;
|
|
57
|
+
}
|
|
58
|
+
hasMessageBeenConsumedAtEpoch(epoch, leafId) {
|
|
59
|
+
return this.outbox.read.hasMessageBeenConsumedAtEpoch([
|
|
60
|
+
BigInt(epoch),
|
|
61
|
+
leafId
|
|
62
|
+
]);
|
|
63
|
+
}
|
|
64
|
+
getRootData(epoch, numCheckpointsInEpoch) {
|
|
65
|
+
return this.outbox.read.getRootData([
|
|
66
|
+
BigInt(epoch),
|
|
67
|
+
BigInt(numCheckpointsInEpoch)
|
|
68
|
+
]);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Returns every root stored for `epoch`. Slot `i` of the returned array holds the root inserted
|
|
72
|
+
* for `numCheckpointsInEpoch = i + 1`, or `Fr.ZERO` if no proof of that depth has been inserted
|
|
73
|
+
* yet. The array length is always `MAX_CHECKPOINTS_PER_EPOCH`.
|
|
74
|
+
*
|
|
75
|
+
* @param opts - Optional viem read options. Pass `blockNumber` to pin the read to a specific L1
|
|
76
|
+
* block, which is important for callers that want a consistent snapshot across multiple reads
|
|
77
|
+
* (e.g. the archiver's outbox-trees resolver, which pins to the node's synced L1 block).
|
|
78
|
+
*/ async getRoots(epoch, opts) {
|
|
79
|
+
const raw = await this.outbox.read.getRoots([
|
|
80
|
+
BigInt(epoch)
|
|
81
|
+
], opts);
|
|
82
|
+
return raw.map((hex)=>Fr.fromString(hex));
|
|
83
|
+
}
|
|
84
|
+
consume(message, epoch, numCheckpointsInEpoch, leafIndex, path) {
|
|
85
|
+
const wallet = this.assertWallet();
|
|
86
|
+
return wallet.write.consume([
|
|
87
|
+
message,
|
|
88
|
+
BigInt(epoch),
|
|
89
|
+
BigInt(numCheckpointsInEpoch),
|
|
90
|
+
leafIndex,
|
|
91
|
+
path
|
|
92
|
+
]);
|
|
93
|
+
}
|
|
94
|
+
async getMessageConsumedEvents(l1BlockHash) {
|
|
95
|
+
const events = await this.outbox.getEvents.MessageConsumed({}, {
|
|
96
|
+
blockHash: l1BlockHash,
|
|
97
|
+
strict: true
|
|
98
|
+
});
|
|
99
|
+
return events.map((event)=>({
|
|
100
|
+
epoch: event.args.epoch,
|
|
101
|
+
root: event.args.root,
|
|
102
|
+
messageHash: event.args.messageHash,
|
|
103
|
+
leafId: event.args.leafId,
|
|
104
|
+
numCheckpointsInEpoch: event.args.numCheckpointsInEpoch
|
|
105
|
+
}));
|
|
106
|
+
}
|
|
107
|
+
assertWallet() {
|
|
108
|
+
if (!isExtendedClient(this.client)) {
|
|
109
|
+
throw new Error('Wallet client is required for this operation');
|
|
110
|
+
}
|
|
111
|
+
return this.outbox;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { EthAddress } from '@aztec-labs/foundation/eth-address';
|
|
2
|
+
import { type Hex } from 'viem';
|
|
3
|
+
import type { L1ContractAddresses } from '../l1_contract_addresses.js';
|
|
4
|
+
import type { ViemClient } from '../types.js';
|
|
5
|
+
export declare class RegistryContract {
|
|
6
|
+
readonly client: ViemClient;
|
|
7
|
+
address: EthAddress;
|
|
8
|
+
private readonly log;
|
|
9
|
+
private readonly registry;
|
|
10
|
+
constructor(client: ViemClient, address: Hex | EthAddress);
|
|
11
|
+
getOwner(): Promise<EthAddress>;
|
|
12
|
+
/**
|
|
13
|
+
* Returns the address of the rollup for a given version.
|
|
14
|
+
* @param version - The version of the rollup. 'canonical' can be used to get the canonical address (i.e. the latest version).
|
|
15
|
+
* @returns The address of the rollup. If the rollup is not set for this version, throws an error.
|
|
16
|
+
*/
|
|
17
|
+
getRollupAddress(version: number | bigint | 'canonical'): Promise<EthAddress>;
|
|
18
|
+
/**
|
|
19
|
+
* Returns the canonical address of the rollup.
|
|
20
|
+
* @returns The canonical address of the rollup. If the rollup is not set, throws an error.
|
|
21
|
+
*/
|
|
22
|
+
getCanonicalAddress(): Promise<EthAddress>;
|
|
23
|
+
getGovernanceAddresses(): Promise<Pick<L1ContractAddresses, 'governanceProposerAddress' | 'governanceAddress'>>;
|
|
24
|
+
static collectAddresses(client: ViemClient, registryAddress: Hex | EthAddress, rollupVersion: number | bigint | 'canonical'): Promise<L1ContractAddresses>;
|
|
25
|
+
getNumberOfVersions(): Promise<number>;
|
|
26
|
+
getRollupVersions(): Promise<bigint[]>;
|
|
27
|
+
getRewardDistributor(): Promise<EthAddress>;
|
|
28
|
+
/** Returns the L1 timestamp at which the given rollup was registered via addRollup(). */
|
|
29
|
+
getCanonicalRollupRegistrationTimestamp(rollupAddress: EthAddress, fromBlock?: bigint): Promise<bigint | undefined>;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaXN0cnkuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb250cmFjdHMvcmVnaXN0cnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0EsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBRWhFLE9BQU8sRUFBOEIsS0FBSyxHQUFHLEVBQTJCLE1BQU0sTUFBTSxDQUFDO0FBRXJGLE9BQU8sS0FBSyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDdkUsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBSTlDLHFCQUFhLGdCQUFnQjthQU9ULE1BQU0sRUFBRSxVQUFVO0lBTjdCLE9BQU8sRUFBRSxVQUFVLENBQUM7SUFFM0IsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQStDO0lBQ25FLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUF3RDtJQUVqRixZQUNrQixNQUFNLEVBQUUsVUFBVSxFQUNsQyxPQUFPLEVBQUUsR0FBRyxHQUFHLFVBQVUsRUFPMUI7SUFFWSxRQUFRLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUUzQztJQUVEOzs7O09BSUc7SUFDVSxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsTUFBTSxHQUFHLE1BQU0sR0FBRyxXQUFXLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQXNCekY7SUFFRDs7O09BR0c7SUFDVSxtQkFBbUIsSUFBSSxPQUFPLENBQUMsVUFBVSxDQUFDLENBRXREO0lBRVksc0JBQXNCLElBQUksT0FBTyxDQUM1QyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsMkJBQTJCLEdBQUcsbUJBQW1CLENBQUMsQ0FDN0UsQ0FRQTtJQUVELE9BQW9CLGdCQUFnQixDQUNsQyxNQUFNLEVBQUUsVUFBVSxFQUNsQixlQUFlLEVBQUUsR0FBRyxHQUFHLFVBQVUsRUFDakMsYUFBYSxFQUFFLE1BQU0sR0FBRyxNQUFNLEdBQUcsV0FBVyxHQUMzQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsQ0F1QjlCO0lBRVksbUJBQW1CLElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUdsRDtJQUVZLGlCQUFpQixJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQVNsRDtJQUVZLG9CQUFvQixJQUFJLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FFdkQ7SUFFRCx5RkFBeUY7SUFDNUUsdUNBQXVDLENBQ2xELGFBQWEsRUFBRSxVQUFVLEVBQ3pCLFNBQVMsQ0FBQyxFQUFFLE1BQU0sR0FDakIsT0FBTyxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUMsQ0F3QjdCO0NBQ0YifQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/contracts/registry.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAEhE,OAAO,EAA8B,KAAK,GAAG,EAA2B,MAAM,MAAM,CAAC;AAErF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAI9C,qBAAa,gBAAgB;aAOT,MAAM,EAAE,UAAU;IAN7B,OAAO,EAAE,UAAU,CAAC;IAE3B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA+C;IACnE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwD;IAEjF,YACkB,MAAM,EAAE,UAAU,EAClC,OAAO,EAAE,GAAG,GAAG,UAAU,EAO1B;IAEY,QAAQ,IAAI,OAAO,CAAC,UAAU,CAAC,CAE3C;IAED;;;;OAIG;IACU,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAsBzF;IAED;;;OAGG;IACU,mBAAmB,IAAI,OAAO,CAAC,UAAU,CAAC,CAEtD;IAEY,sBAAsB,IAAI,OAAO,CAC5C,IAAI,CAAC,mBAAmB,EAAE,2BAA2B,GAAG,mBAAmB,CAAC,CAC7E,CAQA;IAED,OAAoB,gBAAgB,CAClC,MAAM,EAAE,UAAU,EAClB,eAAe,EAAE,GAAG,GAAG,UAAU,EACjC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,WAAW,GAC3C,OAAO,CAAC,mBAAmB,CAAC,CAuB9B;IAEY,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,CAGlD;IAEY,iBAAiB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CASlD;IAEY,oBAAoB,IAAI,OAAO,CAAC,UAAU,CAAC,CAEvD;IAED,yFAAyF;IAC5E,uCAAuC,CAClD,aAAa,EAAE,UAAU,EACzB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAwB7B;CACF"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { RegistryAbi } from '@aztec/l1-artifacts/RegistryAbi';
|
|
2
|
+
import { TestERC20Abi } from '@aztec/l1-artifacts/TestERC20Abi';
|
|
3
|
+
import { EthAddress } from '@aztec-labs/foundation/eth-address';
|
|
4
|
+
import { createLogger } from '@aztec-labs/foundation/log';
|
|
5
|
+
import { getAbiItem, getContract } from 'viem';
|
|
6
|
+
import { ReadOnlyGovernanceContract } from './governance.js';
|
|
7
|
+
import { RollupContract } from './rollup.js';
|
|
8
|
+
export class RegistryContract {
|
|
9
|
+
client;
|
|
10
|
+
address;
|
|
11
|
+
log;
|
|
12
|
+
registry;
|
|
13
|
+
constructor(client, address){
|
|
14
|
+
this.client = client;
|
|
15
|
+
this.log = createLogger('ethereum:contracts:registry');
|
|
16
|
+
if (address instanceof EthAddress) {
|
|
17
|
+
address = address.toString();
|
|
18
|
+
}
|
|
19
|
+
this.address = EthAddress.fromString(address);
|
|
20
|
+
this.registry = getContract({
|
|
21
|
+
address,
|
|
22
|
+
abi: RegistryAbi,
|
|
23
|
+
client
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
async getOwner() {
|
|
27
|
+
return EthAddress.fromString(await this.registry.read.owner());
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Returns the address of the rollup for a given version.
|
|
31
|
+
* @param version - The version of the rollup. 'canonical' can be used to get the canonical address (i.e. the latest version).
|
|
32
|
+
* @returns The address of the rollup. If the rollup is not set for this version, throws an error.
|
|
33
|
+
*/ async getRollupAddress(version) {
|
|
34
|
+
if (version === 'canonical') {
|
|
35
|
+
return this.getCanonicalAddress();
|
|
36
|
+
}
|
|
37
|
+
if (typeof version === 'number') {
|
|
38
|
+
version = BigInt(version);
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
return EthAddress.fromString(await this.registry.read.getRollup([
|
|
42
|
+
version
|
|
43
|
+
]));
|
|
44
|
+
} catch {
|
|
45
|
+
this.log.warn(`Failed fetching rollup address for version ${version}. Retrying as index.`);
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
const actualVersion = await this.registry.read.getVersion([
|
|
49
|
+
version
|
|
50
|
+
]);
|
|
51
|
+
const rollupAddress = await this.registry.read.getRollup([
|
|
52
|
+
actualVersion
|
|
53
|
+
]);
|
|
54
|
+
return EthAddress.fromString(rollupAddress);
|
|
55
|
+
} catch {
|
|
56
|
+
throw new Error('Rollup address is undefined');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Returns the canonical address of the rollup.
|
|
61
|
+
* @returns The canonical address of the rollup. If the rollup is not set, throws an error.
|
|
62
|
+
*/ async getCanonicalAddress() {
|
|
63
|
+
return EthAddress.fromString(await this.registry.read.getCanonicalRollup());
|
|
64
|
+
}
|
|
65
|
+
async getGovernanceAddresses() {
|
|
66
|
+
const governanceAddress = await this.registry.read.getGovernance();
|
|
67
|
+
const governance = new ReadOnlyGovernanceContract(governanceAddress, this.client);
|
|
68
|
+
const governanceProposerAddress = await governance.getGovernanceProposerAddress();
|
|
69
|
+
return {
|
|
70
|
+
governanceAddress: governance.address,
|
|
71
|
+
governanceProposerAddress: governanceProposerAddress
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
static async collectAddresses(client, registryAddress, rollupVersion) {
|
|
75
|
+
const registry = new RegistryContract(client, registryAddress);
|
|
76
|
+
const governanceAddresses = await registry.getGovernanceAddresses();
|
|
77
|
+
const rollupAddress = await registry.getRollupAddress(rollupVersion);
|
|
78
|
+
if (rollupAddress === undefined) {
|
|
79
|
+
throw new Error('Rollup address is undefined');
|
|
80
|
+
}
|
|
81
|
+
const rollup = new RollupContract(client, rollupAddress);
|
|
82
|
+
const addresses = await rollup.getRollupAddresses();
|
|
83
|
+
const feeAsset = getContract({
|
|
84
|
+
address: addresses.feeJuiceAddress.toString(),
|
|
85
|
+
abi: TestERC20Abi,
|
|
86
|
+
client
|
|
87
|
+
});
|
|
88
|
+
const coinIssuer = await feeAsset.read.owner();
|
|
89
|
+
return {
|
|
90
|
+
registryAddress: registry.address,
|
|
91
|
+
...governanceAddresses,
|
|
92
|
+
...addresses,
|
|
93
|
+
coinIssuerAddress: EthAddress.fromString(coinIssuer)
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
async getNumberOfVersions() {
|
|
97
|
+
const version = await this.registry.read.numberOfVersions();
|
|
98
|
+
return Number(version);
|
|
99
|
+
}
|
|
100
|
+
async getRollupVersions() {
|
|
101
|
+
const count = await this.getNumberOfVersions();
|
|
102
|
+
const versions = [];
|
|
103
|
+
for(let i = 0; i < count; i++){
|
|
104
|
+
versions.push(await this.registry.read.getVersion([
|
|
105
|
+
BigInt(i)
|
|
106
|
+
]));
|
|
107
|
+
}
|
|
108
|
+
return versions;
|
|
109
|
+
}
|
|
110
|
+
async getRewardDistributor() {
|
|
111
|
+
return EthAddress.fromString(await this.registry.read.getRewardDistributor());
|
|
112
|
+
}
|
|
113
|
+
/** Returns the L1 timestamp at which the given rollup was registered via addRollup(). */ async getCanonicalRollupRegistrationTimestamp(rollupAddress, fromBlock) {
|
|
114
|
+
const event = getAbiItem({
|
|
115
|
+
abi: RegistryAbi,
|
|
116
|
+
name: 'CanonicalRollupUpdated'
|
|
117
|
+
});
|
|
118
|
+
const start = fromBlock ?? 0n;
|
|
119
|
+
const latestBlock = await this.client.getBlockNumber();
|
|
120
|
+
const chunkSize = 1_000n;
|
|
121
|
+
for(let from = start; from <= latestBlock; from += chunkSize){
|
|
122
|
+
const to = from + chunkSize - 1n > latestBlock ? latestBlock : from + chunkSize - 1n;
|
|
123
|
+
const logs = await this.client.getLogs({
|
|
124
|
+
address: this.address.toString(),
|
|
125
|
+
fromBlock: from,
|
|
126
|
+
toBlock: to,
|
|
127
|
+
strict: true,
|
|
128
|
+
event,
|
|
129
|
+
args: {
|
|
130
|
+
instance: rollupAddress.toString()
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
if (logs.length > 0) {
|
|
134
|
+
const block = await this.client.getBlock({
|
|
135
|
+
blockNumber: logs[0].blockNumber
|
|
136
|
+
});
|
|
137
|
+
return block.timestamp;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
142
|
+
}
|