@aztec/ethereum 3.0.0-nightly.20251211 → 3.0.0-nightly.20251213
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/dest/config.d.ts +3 -42
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +3 -327
- package/dest/contracts/inbox.d.ts +3 -3
- package/dest/contracts/inbox.d.ts.map +1 -1
- package/dest/contracts/rollup.d.ts +3 -3
- package/dest/contracts/rollup.d.ts.map +1 -1
- package/dest/deploy_aztec_l1_contracts.d.ts +245 -0
- package/dest/deploy_aztec_l1_contracts.d.ts.map +1 -0
- package/dest/deploy_aztec_l1_contracts.js +329 -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/forwarder_proxy.js +1 -1
- package/dest/l1_artifacts.d.ts +37 -37
- package/dest/test/rollup_cheat_codes.js +4 -1
- package/dest/test/start_anvil.d.ts +3 -1
- package/dest/test/start_anvil.d.ts.map +1 -1
- package/package.json +10 -6
- package/src/config.ts +2 -406
- package/src/contracts/inbox.ts +2 -2
- package/src/contracts/rollup.ts +2 -2
- package/src/deploy_aztec_l1_contracts.ts +545 -0
- package/src/deploy_l1_contract.ts +362 -0
- package/src/forwarder_proxy.ts +1 -1
- package/src/test/rollup_cheat_codes.ts +1 -1
- package/src/test/start_anvil.ts +2 -0
- package/dest/deploy_l1_contracts.d.ts +0 -673
- package/dest/deploy_l1_contracts.d.ts.map +0 -1
- package/dest/deploy_l1_contracts.js +0 -1491
- package/src/deploy_l1_contracts.ts +0 -1869
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { SecretValue } from '@aztec/foundation/config';
|
|
2
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
|
+
import type { Fr } from '@aztec/foundation/schemas';
|
|
4
|
+
import type { Abi, Narrow } from 'abitype';
|
|
5
|
+
import type { Hex } from 'viem';
|
|
6
|
+
import type { L1ContractsConfig } from './config.js';
|
|
7
|
+
import { RollupContract } from './contracts/rollup.js';
|
|
8
|
+
import type { L1ContractAddresses } from './l1_contract_addresses.js';
|
|
9
|
+
import type { L1TxUtilsConfig } from './l1_tx_utils/config.js';
|
|
10
|
+
import type { ExtendedViemWalletClient } from './types.js';
|
|
11
|
+
export interface G2PointJson {
|
|
12
|
+
x0: string;
|
|
13
|
+
x1: string;
|
|
14
|
+
y0: string;
|
|
15
|
+
y1: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Validator data passed to Solidity for registration.
|
|
19
|
+
* Solidity will derive publicKeyG1 and proofOfPossession from the privateKey.
|
|
20
|
+
*/
|
|
21
|
+
export interface ValidatorJson {
|
|
22
|
+
attester: string;
|
|
23
|
+
withdrawer: string;
|
|
24
|
+
/** BN254 secret key (private key) */
|
|
25
|
+
privateKey: string;
|
|
26
|
+
/** Pre-computed G2 public key (cannot be computed in Solidity) */
|
|
27
|
+
publicKeyInG2: G2PointJson;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Gets the path to the l1-contracts directory.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getL1ContractsPath(): string;
|
|
33
|
+
/**
|
|
34
|
+
* Computes the validator data for passing to Solidity.
|
|
35
|
+
* Only computes the G2 public key (which requires scalar multiplication on G2, not available in EVM).
|
|
36
|
+
* Solidity will derive G1 public key and proof of possession from the private key.
|
|
37
|
+
*/
|
|
38
|
+
export declare function computeValidatorData(operator: Operator): ValidatorJson;
|
|
39
|
+
/**
|
|
40
|
+
* Deployed addresses from the rollup upgrade deployment.
|
|
41
|
+
*/
|
|
42
|
+
export interface RollupUpgradeAddresses {
|
|
43
|
+
rollupAddress: string;
|
|
44
|
+
verifierAddress: string;
|
|
45
|
+
slashFactoryAddress: string;
|
|
46
|
+
inboxAddress: string;
|
|
47
|
+
outboxAddress: string;
|
|
48
|
+
feeJuicePortalAddress: string;
|
|
49
|
+
rollupVersion: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Return type for rollup upgrade via forge.
|
|
53
|
+
*/
|
|
54
|
+
export interface ForgeRollupUpgradeResult {
|
|
55
|
+
rollupAddress: Hex;
|
|
56
|
+
verifierAddress: Hex;
|
|
57
|
+
slashFactoryAddress: Hex;
|
|
58
|
+
inboxAddress: Hex;
|
|
59
|
+
outboxAddress: Hex;
|
|
60
|
+
feeJuicePortalAddress: Hex;
|
|
61
|
+
rollupVersion: number;
|
|
62
|
+
}
|
|
63
|
+
export interface ForgeL1ContractsDeployResult extends ForgeRollupUpgradeResult {
|
|
64
|
+
registryAddress: Hex;
|
|
65
|
+
feeAssetAddress: Hex;
|
|
66
|
+
stakingAssetAddress: Hex;
|
|
67
|
+
gseAddress?: Hex;
|
|
68
|
+
rewardDistributorAddress: Hex;
|
|
69
|
+
coinIssuerAddress: Hex;
|
|
70
|
+
governanceProposerAddress: Hex;
|
|
71
|
+
governanceAddress: Hex;
|
|
72
|
+
dateGatedRelayerAddress?: Hex;
|
|
73
|
+
feeAssetHandlerAddress?: Hex;
|
|
74
|
+
stakingAssetHandlerAddress?: Hex;
|
|
75
|
+
zkPassportVerifierAddress?: Hex;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Deploys L1 contracts using forge and returns a result compatible with the TypeScript deployAztecL1Contracts function.
|
|
79
|
+
* This queries the Rollup contract to get the inbox, outbox, and feeJuicePortal addresses.
|
|
80
|
+
*
|
|
81
|
+
* All configuration is passed via environment variables to the forge script. The DeploymentConfiguration.sol
|
|
82
|
+
* contract reads these values and applies defaults for any unspecified parameters.
|
|
83
|
+
*
|
|
84
|
+
* @param rpcUrl - The RPC URL to use
|
|
85
|
+
* @param privateKey - The private key for the deployer (with 0x prefix)
|
|
86
|
+
* @param options - Additional deployment options (all optional with sensible defaults)
|
|
87
|
+
* @returns The deployment result with all contract addresses and an l1Client
|
|
88
|
+
*/
|
|
89
|
+
export declare function deployAztecL1Contracts(rpcUrl: string, privateKey: `0x${string}`, chainId: number, args: DeployAztecL1ContractsArgs): Promise<DeployAztecL1ContractsReturnType>;
|
|
90
|
+
export declare const DEPLOYER_ADDRESS: Hex;
|
|
91
|
+
export type Operator = {
|
|
92
|
+
attester: EthAddress;
|
|
93
|
+
withdrawer: EthAddress;
|
|
94
|
+
bn254SecretKey: SecretValue<bigint>;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Return type of the deployAztecL1Contracts function.
|
|
98
|
+
*/
|
|
99
|
+
export type DeployAztecL1ContractsReturnType = {
|
|
100
|
+
/** Extended Wallet Client Type. */
|
|
101
|
+
l1Client: ExtendedViemWalletClient;
|
|
102
|
+
/** The currently deployed l1 contract addresses */
|
|
103
|
+
l1ContractAddresses: L1ContractAddresses;
|
|
104
|
+
/** Version of the current rollup contract. */
|
|
105
|
+
rollupVersion: number;
|
|
106
|
+
};
|
|
107
|
+
export interface LinkReferences {
|
|
108
|
+
[fileName: string]: {
|
|
109
|
+
[contractName: string]: ReadonlyArray<{
|
|
110
|
+
start: number;
|
|
111
|
+
length: number;
|
|
112
|
+
}>;
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
export interface Libraries {
|
|
116
|
+
linkReferences: LinkReferences;
|
|
117
|
+
libraryCode: Record<string, ContractArtifacts>;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Contract artifacts
|
|
121
|
+
*/
|
|
122
|
+
export interface ContractArtifacts<TAbi extends Abi | readonly unknown[] = Abi> {
|
|
123
|
+
/**
|
|
124
|
+
* The contract name.
|
|
125
|
+
*/
|
|
126
|
+
name: string;
|
|
127
|
+
/**
|
|
128
|
+
* The contract abi.
|
|
129
|
+
*/
|
|
130
|
+
contractAbi: Narrow<TAbi>;
|
|
131
|
+
/**
|
|
132
|
+
* The contract bytecode
|
|
133
|
+
*/
|
|
134
|
+
contractBytecode: Hex;
|
|
135
|
+
/**
|
|
136
|
+
* The contract libraries
|
|
137
|
+
*/
|
|
138
|
+
libraries?: Libraries;
|
|
139
|
+
}
|
|
140
|
+
export type VerificationLibraryEntry = {
|
|
141
|
+
file: string;
|
|
142
|
+
contract: string;
|
|
143
|
+
address: string;
|
|
144
|
+
};
|
|
145
|
+
export type VerificationRecord = {
|
|
146
|
+
name: string;
|
|
147
|
+
address: string;
|
|
148
|
+
constructorArgsHex: Hex;
|
|
149
|
+
libraries: VerificationLibraryEntry[];
|
|
150
|
+
};
|
|
151
|
+
export interface DeployAztecL1ContractsArgs extends Omit<L1ContractsConfig, keyof L1TxUtilsConfig> {
|
|
152
|
+
/** The vk tree root. */
|
|
153
|
+
vkTreeRoot: Fr;
|
|
154
|
+
/** The hash of the protocol contracts. */
|
|
155
|
+
protocolContractsHash: Fr;
|
|
156
|
+
/** The genesis root of the archive tree. */
|
|
157
|
+
genesisArchiveRoot: Fr;
|
|
158
|
+
/** The initial validators for the rollup contract. */
|
|
159
|
+
initialValidators?: Operator[];
|
|
160
|
+
/** The initial balance of the fee juice portal. This is the amount of fee juice that is prefunded to accounts */
|
|
161
|
+
feeJuicePortalInitialBalance?: bigint;
|
|
162
|
+
/** Whether to deploy the real verifier or the mock verifier */
|
|
163
|
+
realVerifier?: boolean;
|
|
164
|
+
/** The zk passport args */
|
|
165
|
+
zkPassportArgs?: ZKPassportArgs;
|
|
166
|
+
/** If provided, use this token for BOTH fee and staking assets (skip deployments) */
|
|
167
|
+
existingTokenAddress?: EthAddress;
|
|
168
|
+
}
|
|
169
|
+
export interface ZKPassportArgs {
|
|
170
|
+
/** The domain of the zk passport (url) */
|
|
171
|
+
zkPassportDomain?: string;
|
|
172
|
+
/** The scope of the zk passport (personhood, etc) */
|
|
173
|
+
zkPassportScope?: string;
|
|
174
|
+
}
|
|
175
|
+
export declare function getDeployAztecL1ContractsEnvVars(args: DeployAztecL1ContractsArgs): {
|
|
176
|
+
readonly EXISTING_TOKEN_ADDRESS: `0x${string}` | undefined;
|
|
177
|
+
readonly AZTEC_ACTIVATION_THRESHOLD: string;
|
|
178
|
+
readonly AZTEC_EJECTION_THRESHOLD: string;
|
|
179
|
+
readonly AZTEC_GOVERNANCE_PROPOSER_ROUND_SIZE: string;
|
|
180
|
+
readonly AZTEC_GOVERNANCE_PROPOSER_QUORUM: string | undefined;
|
|
181
|
+
readonly ZKPASSPORT_DOMAIN: string | undefined;
|
|
182
|
+
readonly ZKPASSPORT_SCOPE: string | undefined;
|
|
183
|
+
readonly INITIAL_VALIDATORS: string;
|
|
184
|
+
readonly REAL_VERIFIER: "false" | "true";
|
|
185
|
+
readonly FEE_JUICE_PORTAL_INITIAL_BALANCE: string;
|
|
186
|
+
readonly VK_TREE_ROOT: `0x${string}`;
|
|
187
|
+
readonly PROTOCOL_CONTRACTS_HASH: `0x${string}`;
|
|
188
|
+
readonly GENESIS_ARCHIVE_ROOT: `0x${string}`;
|
|
189
|
+
readonly AZTEC_SLOT_DURATION: string;
|
|
190
|
+
readonly AZTEC_EPOCH_DURATION: string;
|
|
191
|
+
readonly AZTEC_TARGET_COMMITTEE_SIZE: string;
|
|
192
|
+
readonly AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET: string;
|
|
193
|
+
readonly AZTEC_LAG_IN_EPOCHS_FOR_RANDAO: string;
|
|
194
|
+
readonly AZTEC_PROOF_SUBMISSION_EPOCHS: string;
|
|
195
|
+
readonly AZTEC_LOCAL_EJECTION_THRESHOLD: string;
|
|
196
|
+
readonly AZTEC_SLASHING_LIFETIME_IN_ROUNDS: string;
|
|
197
|
+
readonly AZTEC_SLASHING_VETOER: `0x${string}`;
|
|
198
|
+
readonly AZTEC_SLASHING_DISABLE_DURATION: string;
|
|
199
|
+
readonly AZTEC_MANA_TARGET: string;
|
|
200
|
+
readonly AZTEC_EXIT_DELAY_SECONDS: string;
|
|
201
|
+
readonly AZTEC_PROVING_COST_PER_MANA: string;
|
|
202
|
+
readonly AZTEC_SLASHER_FLAVOR: "empire" | "none" | "tally";
|
|
203
|
+
readonly AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS: string;
|
|
204
|
+
readonly AZTEC_SLASHING_QUORUM: string | undefined;
|
|
205
|
+
readonly AZTEC_SLASHING_OFFSET_IN_ROUNDS: string;
|
|
206
|
+
readonly AZTEC_SLASH_AMOUNT_SMALL: string;
|
|
207
|
+
readonly AZTEC_SLASH_AMOUNT_MEDIUM: string;
|
|
208
|
+
readonly AZTEC_SLASH_AMOUNT_LARGE: string;
|
|
209
|
+
};
|
|
210
|
+
export declare function getDeployRollupForUpgradeEnvVars(args: Omit<DeployAztecL1ContractsArgs, 'governanceProposerQuorum' | 'governanceProposerRoundSize' | 'ejectionThreshold' | 'activationThreshold' | 'getZkPassportArgs'>): {
|
|
211
|
+
readonly INITIAL_VALIDATORS: string;
|
|
212
|
+
readonly REAL_VERIFIER: "false" | "true";
|
|
213
|
+
readonly FEE_JUICE_PORTAL_INITIAL_BALANCE: string;
|
|
214
|
+
readonly VK_TREE_ROOT: `0x${string}`;
|
|
215
|
+
readonly PROTOCOL_CONTRACTS_HASH: `0x${string}`;
|
|
216
|
+
readonly GENESIS_ARCHIVE_ROOT: `0x${string}`;
|
|
217
|
+
readonly AZTEC_SLOT_DURATION: string;
|
|
218
|
+
readonly AZTEC_EPOCH_DURATION: string;
|
|
219
|
+
readonly AZTEC_TARGET_COMMITTEE_SIZE: string;
|
|
220
|
+
readonly AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET: string;
|
|
221
|
+
readonly AZTEC_LAG_IN_EPOCHS_FOR_RANDAO: string;
|
|
222
|
+
readonly AZTEC_PROOF_SUBMISSION_EPOCHS: string;
|
|
223
|
+
readonly AZTEC_LOCAL_EJECTION_THRESHOLD: string;
|
|
224
|
+
readonly AZTEC_SLASHING_LIFETIME_IN_ROUNDS: string;
|
|
225
|
+
readonly AZTEC_SLASHING_VETOER: `0x${string}`;
|
|
226
|
+
readonly AZTEC_SLASHING_DISABLE_DURATION: string;
|
|
227
|
+
readonly AZTEC_MANA_TARGET: string;
|
|
228
|
+
readonly AZTEC_EXIT_DELAY_SECONDS: string;
|
|
229
|
+
readonly AZTEC_PROVING_COST_PER_MANA: string;
|
|
230
|
+
readonly AZTEC_SLASHER_FLAVOR: "empire" | "none" | "tally";
|
|
231
|
+
readonly AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS: string;
|
|
232
|
+
readonly AZTEC_SLASHING_QUORUM: string | undefined;
|
|
233
|
+
readonly AZTEC_SLASHING_OFFSET_IN_ROUNDS: string;
|
|
234
|
+
readonly AZTEC_SLASH_AMOUNT_SMALL: string;
|
|
235
|
+
readonly AZTEC_SLASH_AMOUNT_MEDIUM: string;
|
|
236
|
+
readonly AZTEC_SLASH_AMOUNT_LARGE: string;
|
|
237
|
+
};
|
|
238
|
+
/**
|
|
239
|
+
* Deploys a new rollup, using the existing canonical version to derive certain values (addresses of assets etc).
|
|
240
|
+
*/
|
|
241
|
+
export declare const deployRollupForUpgrade: (privateKey: `0x${string}`, rpcUrl: string, chainId: number, registryAddress: EthAddress, args: Omit<DeployAztecL1ContractsArgs, "activationThreshold" | "ejectionThreshold" | "governanceProposerQuorum" | "governanceProposerRoundSize" | "zkPassportArgs">) => Promise<{
|
|
242
|
+
rollup: RollupContract;
|
|
243
|
+
slashFactoryAddress: `0x${string}`;
|
|
244
|
+
}>;
|
|
245
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwbG95X2F6dGVjX2wxX2NvbnRyYWN0cy5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2RlcGxveV9henRlY19sMV9jb250cmFjdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLFdBQVcsRUFBd0IsTUFBTSwwQkFBMEIsQ0FBQztBQUM3RSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFJM0QsT0FBTyxLQUFLLEVBQUUsRUFBRSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFJcEQsT0FBTyxLQUFLLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUkzQyxPQUFPLEtBQUssRUFBRSxHQUFHLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFLaEMsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFckQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3ZELE9BQU8sS0FBSyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDdEUsT0FBTyxLQUFLLEVBQUUsZUFBZSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDL0QsT0FBTyxLQUFLLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFnRTNELE1BQU0sV0FBVyxXQUFXO0lBQzFCLEVBQUUsRUFBRSxNQUFNLENBQUM7SUFDWCxFQUFFLEVBQUUsTUFBTSxDQUFDO0lBQ1gsRUFBRSxFQUFFLE1BQU0sQ0FBQztJQUNYLEVBQUUsRUFBRSxNQUFNLENBQUM7Q0FDWjtBQUVEOzs7R0FHRztBQUNILE1BQU0sV0FBVyxhQUFhO0lBQzVCLFFBQVEsRUFBRSxNQUFNLENBQUM7SUFDakIsVUFBVSxFQUFFLE1BQU0sQ0FBQztJQUNuQixxQ0FBcUM7SUFDckMsVUFBVSxFQUFFLE1BQU0sQ0FBQztJQUNuQixrRUFBa0U7SUFDbEUsYUFBYSxFQUFFLFdBQVcs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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy_aztec_l1_contracts.d.ts","sourceRoot":"","sources":["../src/deploy_aztec_l1_contracts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import { getActiveNetworkName } from '@aztec/foundation/config';
|
|
3
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
|
+
import { jsonStringify } from '@aztec/foundation/json-rpc';
|
|
5
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
6
|
+
import { promiseWithResolvers } from '@aztec/foundation/promise';
|
|
7
|
+
import { fileURLToPath } from '@aztec/foundation/url';
|
|
8
|
+
import { bn254 } from '@noble/curves/bn254';
|
|
9
|
+
import { spawn } from 'child_process';
|
|
10
|
+
import { dirname, resolve } from 'path';
|
|
11
|
+
import readline from 'readline';
|
|
12
|
+
import { foundry, mainnet } from 'viem/chains';
|
|
13
|
+
import { createEthereumChain, isAnvilTestChain } from './chain.js';
|
|
14
|
+
import { createExtendedL1Client } from './client.js';
|
|
15
|
+
import { deployMulticall3 } from './contracts/multicall.js';
|
|
16
|
+
import { RollupContract } from './contracts/rollup.js';
|
|
17
|
+
const logger = createLogger('ethereum:deploy_aztec_l1_contracts');
|
|
18
|
+
const JSON_DEPLOY_RESULT_PREFIX = 'JSON DEPLOY RESULT:';
|
|
19
|
+
/**
|
|
20
|
+
* Runs a process with the given command, arguments, and environment.
|
|
21
|
+
* If the process outputs a line starting with JSON_DEPLOY_RESULT_PREFIX,
|
|
22
|
+
* the JSON is parsed and returned.
|
|
23
|
+
*/ function runProcess(command, args, env, cwd) {
|
|
24
|
+
const { promise, resolve, reject } = promiseWithResolvers();
|
|
25
|
+
const proc = spawn(command, args, {
|
|
26
|
+
cwd,
|
|
27
|
+
env: {
|
|
28
|
+
...process.env,
|
|
29
|
+
...env
|
|
30
|
+
},
|
|
31
|
+
stdio: [
|
|
32
|
+
'ignore',
|
|
33
|
+
'pipe',
|
|
34
|
+
'pipe'
|
|
35
|
+
]
|
|
36
|
+
});
|
|
37
|
+
let result;
|
|
38
|
+
readline.createInterface({
|
|
39
|
+
input: proc.stdout
|
|
40
|
+
}).on('line', (line)=>{
|
|
41
|
+
const trimmedLine = line.trim();
|
|
42
|
+
if (trimmedLine.startsWith(JSON_DEPLOY_RESULT_PREFIX)) {
|
|
43
|
+
const jsonStr = trimmedLine.slice(JSON_DEPLOY_RESULT_PREFIX.length).trim();
|
|
44
|
+
// TODO(AD): should this be a zod parse?
|
|
45
|
+
result = JSON.parse(jsonStr);
|
|
46
|
+
} else {
|
|
47
|
+
logger.info(line);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
readline.createInterface({
|
|
51
|
+
input: proc.stderr
|
|
52
|
+
}).on('line', logger.error.bind(logger));
|
|
53
|
+
proc.on('error', (error)=>{
|
|
54
|
+
reject(new Error(`Failed to spawn ${command}: ${error.message}`));
|
|
55
|
+
});
|
|
56
|
+
proc.on('close', (code)=>{
|
|
57
|
+
if (code !== 0) {
|
|
58
|
+
reject(new Error(`${command} exited with code ${code}. See logs for details.\n`));
|
|
59
|
+
} else {
|
|
60
|
+
resolve(result);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
return promise;
|
|
64
|
+
}
|
|
65
|
+
// Covers an edge where where we may have a cached BlobLib that is not meant for production.
|
|
66
|
+
// Despite the profile apparently sometimes cached code remains (so says Lasse after his ignition-monorepo arc).
|
|
67
|
+
async function maybeForgeForceProductionBuild(l1ContractsPath, script, chainId) {
|
|
68
|
+
if (chainId === mainnet.id) {
|
|
69
|
+
logger.info(`Recompiling ${script} with production profile for mainnet deployment`);
|
|
70
|
+
logger.info('This may take a minute but ensures production BlobLib is used.');
|
|
71
|
+
await runProcess('forge', [
|
|
72
|
+
'build',
|
|
73
|
+
script,
|
|
74
|
+
'--force'
|
|
75
|
+
], {
|
|
76
|
+
FOUNDRY_PROFILE: 'production'
|
|
77
|
+
}, l1ContractsPath);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Gets the path to the l1-contracts directory.
|
|
82
|
+
*/ export function getL1ContractsPath() {
|
|
83
|
+
// Try to find l1-contracts relative to this file
|
|
84
|
+
const currentDir = dirname(fileURLToPath(import.meta.url));
|
|
85
|
+
// Go up from yarn-project/ethereum/src to yarn-project, then to repo root, then to l1-contracts
|
|
86
|
+
const l1ContractsPath = resolve(currentDir, '..', '..', '..', 'l1-contracts');
|
|
87
|
+
return l1ContractsPath;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Computes the validator data for passing to Solidity.
|
|
91
|
+
* Only computes the G2 public key (which requires scalar multiplication on G2, not available in EVM).
|
|
92
|
+
* Solidity will derive G1 public key and proof of possession from the private key.
|
|
93
|
+
*/ export function computeValidatorData(operator) {
|
|
94
|
+
const privateKey = operator.bn254SecretKey.getValue();
|
|
95
|
+
// Compute G2 public key: pk2 = privateKey * G2
|
|
96
|
+
// This is the only computation we need to do in TypeScript since G2 scalar mul
|
|
97
|
+
// is not available as an EVM precompile
|
|
98
|
+
const publicKeyG2 = bn254.G2.ProjectivePoint.BASE.multiply(privateKey);
|
|
99
|
+
const publicKeyG2Affine = publicKeyG2.toAffine();
|
|
100
|
+
return {
|
|
101
|
+
attester: operator.attester.toString(),
|
|
102
|
+
withdrawer: operator.withdrawer.toString(),
|
|
103
|
+
privateKey: privateKey.toString(),
|
|
104
|
+
publicKeyInG2: {
|
|
105
|
+
x0: publicKeyG2Affine.x.c0.toString(),
|
|
106
|
+
x1: publicKeyG2Affine.x.c1.toString(),
|
|
107
|
+
y0: publicKeyG2Affine.y.c0.toString(),
|
|
108
|
+
y1: publicKeyG2Affine.y.c1.toString()
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Deploys L1 contracts using forge and returns a result compatible with the TypeScript deployAztecL1Contracts function.
|
|
114
|
+
* This queries the Rollup contract to get the inbox, outbox, and feeJuicePortal addresses.
|
|
115
|
+
*
|
|
116
|
+
* All configuration is passed via environment variables to the forge script. The DeploymentConfiguration.sol
|
|
117
|
+
* contract reads these values and applies defaults for any unspecified parameters.
|
|
118
|
+
*
|
|
119
|
+
* @param rpcUrl - The RPC URL to use
|
|
120
|
+
* @param privateKey - The private key for the deployer (with 0x prefix)
|
|
121
|
+
* @param options - Additional deployment options (all optional with sensible defaults)
|
|
122
|
+
* @returns The deployment result with all contract addresses and an l1Client
|
|
123
|
+
*/ export async function deployAztecL1Contracts(rpcUrl, privateKey, chainId, args) {
|
|
124
|
+
logger.info(`Deploying L1 contracts with config: ${jsonStringify(args)}`);
|
|
125
|
+
if (args.initialValidators && args.initialValidators.length > 0 && args.existingTokenAddress) {
|
|
126
|
+
throw new Error('Cannot deploy with both initialValidators and existingTokenAddress. ' + 'Initial validator funding requires minting tokens, which is not possible with an external token.');
|
|
127
|
+
}
|
|
128
|
+
const currentDir = dirname(fileURLToPath(import.meta.url));
|
|
129
|
+
const chain = createEthereumChain([
|
|
130
|
+
rpcUrl
|
|
131
|
+
], chainId);
|
|
132
|
+
const l1Client = createExtendedL1Client([
|
|
133
|
+
rpcUrl
|
|
134
|
+
], privateKey, chain.chainInfo);
|
|
135
|
+
const rpcCall = async (method, params)=>{
|
|
136
|
+
logger.info(`Calling ${method} with params: ${JSON.stringify(params)}`);
|
|
137
|
+
return await l1Client.transport.request({
|
|
138
|
+
method,
|
|
139
|
+
params
|
|
140
|
+
});
|
|
141
|
+
};
|
|
142
|
+
logger.verbose(`Deploying contracts from ${l1Client.account.address.toString()}`);
|
|
143
|
+
// Deploy multicall3 if it does not exist in this network
|
|
144
|
+
// Sepolia and mainnet will have this.
|
|
145
|
+
await deployMulticall3(l1Client, logger);
|
|
146
|
+
if (isAnvilTestChain(chainId)) {
|
|
147
|
+
try {
|
|
148
|
+
// We are assuming that you are running this on a local anvil node which have 1s block times
|
|
149
|
+
// To align better with actual deployment, we update the block interval to 12s
|
|
150
|
+
await rpcCall('anvil_setBlockTimestampInterval', [
|
|
151
|
+
args.ethereumSlotDuration
|
|
152
|
+
]);
|
|
153
|
+
logger.warn(`Set block interval to ${args.ethereumSlotDuration}`);
|
|
154
|
+
} catch (e) {
|
|
155
|
+
logger.error(`Error setting block interval: ${e}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// Relative location of l1-contracts in monorepo or docker image.
|
|
159
|
+
const l1ContractsPath = resolve(currentDir, '..', '..', '..', 'l1-contracts');
|
|
160
|
+
const FORGE_SCRIPT = 'script/deploy/DeployAztecL1Contracts.s.sol';
|
|
161
|
+
await maybeForgeForceProductionBuild(l1ContractsPath, FORGE_SCRIPT, chainId);
|
|
162
|
+
// From heuristic testing. More caused issues with anvil.
|
|
163
|
+
const MAGIC_ANVIL_BATCH_SIZE = 12;
|
|
164
|
+
// Anvil seems to stall with unbounded batch size. Otherwise no max batch size is desirable.
|
|
165
|
+
// On sepolia and mainnet, we verify on etherscan (if etherscan API key is in env)
|
|
166
|
+
const forgeArgs = [
|
|
167
|
+
'script',
|
|
168
|
+
FORGE_SCRIPT,
|
|
169
|
+
'--sig',
|
|
170
|
+
'run()',
|
|
171
|
+
'--private-key',
|
|
172
|
+
privateKey,
|
|
173
|
+
'--rpc-url',
|
|
174
|
+
rpcUrl,
|
|
175
|
+
'--broadcast',
|
|
176
|
+
...chainId === foundry.id ? [
|
|
177
|
+
'--batch-size',
|
|
178
|
+
MAGIC_ANVIL_BATCH_SIZE.toString()
|
|
179
|
+
] : [
|
|
180
|
+
'--verify'
|
|
181
|
+
]
|
|
182
|
+
];
|
|
183
|
+
const forgeEnv = {
|
|
184
|
+
// Env vars required by l1-contracts/script/deploy/DeploymentConfiguration.sol.
|
|
185
|
+
NETWORK: getActiveNetworkName(),
|
|
186
|
+
FOUNDRY_PROFILE: chainId === mainnet.id ? 'production' : undefined,
|
|
187
|
+
...getDeployAztecL1ContractsEnvVars(args)
|
|
188
|
+
};
|
|
189
|
+
const result = await runProcess('forge', forgeArgs, forgeEnv, l1ContractsPath);
|
|
190
|
+
if (!result) {
|
|
191
|
+
throw new Error('Forge script did not output deployment result');
|
|
192
|
+
}
|
|
193
|
+
logger.info(`Deployed L1 contracts with L1 addresses: ${jsonStringify(result)}`);
|
|
194
|
+
const rollup = new RollupContract(l1Client, result.rollupAddress);
|
|
195
|
+
if (isAnvilTestChain(chainId)) {
|
|
196
|
+
// @note We make a time jump PAST the very first slot to not have to deal with the edge case of the first slot.
|
|
197
|
+
// The edge case being that the genesis block is already occupying slot 0, so we cannot have another block.
|
|
198
|
+
try {
|
|
199
|
+
// Need to get the time
|
|
200
|
+
const currentSlot = await rollup.getSlotNumber();
|
|
201
|
+
if (currentSlot === 0) {
|
|
202
|
+
const ts = Number(await rollup.getTimestampForSlot(SlotNumber(1)));
|
|
203
|
+
await rpcCall('evm_setNextBlockTimestamp', [
|
|
204
|
+
ts
|
|
205
|
+
]);
|
|
206
|
+
await rpcCall('hardhat_mine', [
|
|
207
|
+
1
|
|
208
|
+
]);
|
|
209
|
+
const currentSlot = await rollup.getSlotNumber();
|
|
210
|
+
if (currentSlot !== 1) {
|
|
211
|
+
throw new Error(`Error jumping time: current slot is ${currentSlot}`);
|
|
212
|
+
}
|
|
213
|
+
logger.info(`Jumped to slot 1`);
|
|
214
|
+
}
|
|
215
|
+
} catch (e) {
|
|
216
|
+
throw new Error(`Error jumping time: ${e}`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return {
|
|
220
|
+
l1Client,
|
|
221
|
+
rollupVersion: result.rollupVersion,
|
|
222
|
+
l1ContractAddresses: {
|
|
223
|
+
rollupAddress: EthAddress.fromString(result.rollupAddress),
|
|
224
|
+
registryAddress: EthAddress.fromString(result.registryAddress),
|
|
225
|
+
inboxAddress: EthAddress.fromString(result.inboxAddress),
|
|
226
|
+
outboxAddress: EthAddress.fromString(result.outboxAddress),
|
|
227
|
+
feeJuiceAddress: EthAddress.fromString(result.feeAssetAddress),
|
|
228
|
+
feeJuicePortalAddress: EthAddress.fromString(result.feeJuicePortalAddress),
|
|
229
|
+
coinIssuerAddress: EthAddress.fromString(result.coinIssuerAddress),
|
|
230
|
+
rewardDistributorAddress: EthAddress.fromString(result.rewardDistributorAddress),
|
|
231
|
+
governanceProposerAddress: EthAddress.fromString(result.governanceProposerAddress),
|
|
232
|
+
governanceAddress: EthAddress.fromString(result.governanceAddress),
|
|
233
|
+
stakingAssetAddress: EthAddress.fromString(result.stakingAssetAddress),
|
|
234
|
+
slashFactoryAddress: result.slashFactoryAddress ? EthAddress.fromString(result.slashFactoryAddress) : undefined,
|
|
235
|
+
feeAssetHandlerAddress: result.feeAssetHandlerAddress ? EthAddress.fromString(result.feeAssetHandlerAddress) : undefined,
|
|
236
|
+
stakingAssetHandlerAddress: result.stakingAssetHandlerAddress ? EthAddress.fromString(result.stakingAssetHandlerAddress) : undefined,
|
|
237
|
+
zkPassportVerifierAddress: result.zkPassportVerifierAddress ? EthAddress.fromString(result.zkPassportVerifierAddress) : undefined,
|
|
238
|
+
gseAddress: result.gseAddress ? EthAddress.fromString(result.gseAddress) : undefined,
|
|
239
|
+
dateGatedRelayerAddress: result.dateGatedRelayerAddress ? EthAddress.fromString(result.dateGatedRelayerAddress) : undefined
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
export const DEPLOYER_ADDRESS = '0x4e59b44847b379578588920cA78FbF26c0B4956C';
|
|
244
|
+
// picked up by l1-contracts DeploymentConfiguration.sol
|
|
245
|
+
export function getDeployAztecL1ContractsEnvVars(args) {
|
|
246
|
+
return {
|
|
247
|
+
...getDeployRollupForUpgradeEnvVars(args),
|
|
248
|
+
EXISTING_TOKEN_ADDRESS: args.existingTokenAddress?.toString(),
|
|
249
|
+
AZTEC_ACTIVATION_THRESHOLD: args.activationThreshold?.toString(),
|
|
250
|
+
AZTEC_EJECTION_THRESHOLD: args.ejectionThreshold?.toString(),
|
|
251
|
+
AZTEC_GOVERNANCE_PROPOSER_ROUND_SIZE: args.governanceProposerRoundSize?.toString(),
|
|
252
|
+
AZTEC_GOVERNANCE_PROPOSER_QUORUM: args.governanceProposerQuorum?.toString(),
|
|
253
|
+
ZKPASSPORT_DOMAIN: args.zkPassportArgs?.zkPassportDomain,
|
|
254
|
+
ZKPASSPORT_SCOPE: args.zkPassportArgs?.zkPassportScope
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
// picked up by l1-contracts RollupConfiguration.sol
|
|
258
|
+
export function getDeployRollupForUpgradeEnvVars(args) {
|
|
259
|
+
return {
|
|
260
|
+
INITIAL_VALIDATORS: JSON.stringify((args.initialValidators ?? []).map(computeValidatorData)),
|
|
261
|
+
REAL_VERIFIER: args.realVerifier ? 'true' : 'false',
|
|
262
|
+
FEE_JUICE_PORTAL_INITIAL_BALANCE: (args.feeJuicePortalInitialBalance ?? 0n).toString(),
|
|
263
|
+
// Genesis state
|
|
264
|
+
VK_TREE_ROOT: args.vkTreeRoot.toString(),
|
|
265
|
+
PROTOCOL_CONTRACTS_HASH: args.protocolContractsHash.toString(),
|
|
266
|
+
GENESIS_ARCHIVE_ROOT: args.genesisArchiveRoot.toString(),
|
|
267
|
+
// Rollup config
|
|
268
|
+
AZTEC_SLOT_DURATION: args.aztecSlotDuration.toString(),
|
|
269
|
+
AZTEC_EPOCH_DURATION: args.aztecEpochDuration.toString(),
|
|
270
|
+
AZTEC_TARGET_COMMITTEE_SIZE: args.aztecTargetCommitteeSize.toString(),
|
|
271
|
+
AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET: args.lagInEpochsForValidatorSet.toString(),
|
|
272
|
+
AZTEC_LAG_IN_EPOCHS_FOR_RANDAO: args.lagInEpochsForRandao.toString(),
|
|
273
|
+
AZTEC_PROOF_SUBMISSION_EPOCHS: args.aztecProofSubmissionEpochs.toString(),
|
|
274
|
+
AZTEC_LOCAL_EJECTION_THRESHOLD: args.localEjectionThreshold.toString(),
|
|
275
|
+
AZTEC_SLASHING_LIFETIME_IN_ROUNDS: args.slashingLifetimeInRounds.toString(),
|
|
276
|
+
AZTEC_SLASHING_VETOER: args.slashingVetoer.toString(),
|
|
277
|
+
AZTEC_SLASHING_DISABLE_DURATION: args.slashingDisableDuration.toString(),
|
|
278
|
+
AZTEC_MANA_TARGET: args.manaTarget.toString(),
|
|
279
|
+
AZTEC_EXIT_DELAY_SECONDS: args.exitDelaySeconds.toString(),
|
|
280
|
+
AZTEC_PROVING_COST_PER_MANA: args.provingCostPerMana.toString(),
|
|
281
|
+
AZTEC_SLASHER_FLAVOR: args.slasherFlavor,
|
|
282
|
+
AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS: args.slashingRoundSizeInEpochs.toString(),
|
|
283
|
+
AZTEC_SLASHING_QUORUM: args.slashingQuorum?.toString(),
|
|
284
|
+
AZTEC_SLASHING_OFFSET_IN_ROUNDS: args.slashingOffsetInRounds.toString(),
|
|
285
|
+
AZTEC_SLASH_AMOUNT_SMALL: args.slashAmountSmall.toString(),
|
|
286
|
+
AZTEC_SLASH_AMOUNT_MEDIUM: args.slashAmountMedium.toString(),
|
|
287
|
+
AZTEC_SLASH_AMOUNT_LARGE: args.slashAmountLarge.toString()
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Deploys a new rollup, using the existing canonical version to derive certain values (addresses of assets etc).
|
|
292
|
+
*/ export const deployRollupForUpgrade = async (privateKey, rpcUrl, chainId, registryAddress, args)=>{
|
|
293
|
+
const currentDir = dirname(fileURLToPath(import.meta.url));
|
|
294
|
+
// Relative location of l1-contracts in monorepo or docker image.
|
|
295
|
+
const l1ContractsPath = resolve(currentDir, '..', '..', '..', 'l1-contracts');
|
|
296
|
+
const FORGE_SCRIPT = 'script/deploy/DeployRollupForUpgrade.s.sol';
|
|
297
|
+
await maybeForgeForceProductionBuild(l1ContractsPath, FORGE_SCRIPT, chainId);
|
|
298
|
+
const forgeArgs = [
|
|
299
|
+
'script',
|
|
300
|
+
FORGE_SCRIPT,
|
|
301
|
+
'--sig',
|
|
302
|
+
'run()',
|
|
303
|
+
'--private-key',
|
|
304
|
+
privateKey,
|
|
305
|
+
'--rpc-url',
|
|
306
|
+
rpcUrl,
|
|
307
|
+
'--broadcast'
|
|
308
|
+
];
|
|
309
|
+
const forgeEnv = {
|
|
310
|
+
FOUNDRY_PROFILE: chainId === mainnet.id ? 'production' : undefined,
|
|
311
|
+
// Env vars required by l1-contracts/script/deploy/RollupConfiguration.sol.
|
|
312
|
+
REGISTRY_ADDRESS: registryAddress.toString(),
|
|
313
|
+
NETWORK: getActiveNetworkName(),
|
|
314
|
+
...getDeployRollupForUpgradeEnvVars(args)
|
|
315
|
+
};
|
|
316
|
+
const result = await runProcess('forge', forgeArgs, forgeEnv, l1ContractsPath);
|
|
317
|
+
if (!result) {
|
|
318
|
+
throw new Error('Forge script did not output deployment result');
|
|
319
|
+
}
|
|
320
|
+
const extendedClient = createExtendedL1Client([
|
|
321
|
+
rpcUrl
|
|
322
|
+
], privateKey);
|
|
323
|
+
// Create RollupContract wrapper for the deployed rollup
|
|
324
|
+
const rollup = new RollupContract(extendedClient, result.rollupAddress);
|
|
325
|
+
return {
|
|
326
|
+
rollup,
|
|
327
|
+
slashFactoryAddress: result.slashFactoryAddress
|
|
328
|
+
};
|
|
329
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
|
+
import { type Logger } from '@aztec/foundation/log';
|
|
3
|
+
import { DateProvider } from '@aztec/foundation/timer';
|
|
4
|
+
import { type Abi, type ContractConstructorArgs, type Hex, type Narrow } from 'viem';
|
|
5
|
+
import { type ContractArtifacts, type Libraries, type VerificationLibraryEntry, type VerificationRecord } from './deploy_aztec_l1_contracts.js';
|
|
6
|
+
import { type L1TxUtilsConfig } from './l1_tx_utils/config.js';
|
|
7
|
+
import type { L1TxUtils } from './l1_tx_utils/l1_tx_utils.js';
|
|
8
|
+
import type { GasPrice, L1TxConfig, L1TxRequest } from './l1_tx_utils/types.js';
|
|
9
|
+
import type { ExtendedViemWalletClient } from './types.js';
|
|
10
|
+
export declare class L1Deployer {
|
|
11
|
+
readonly client: ExtendedViemWalletClient;
|
|
12
|
+
private acceleratedTestDeployments;
|
|
13
|
+
private logger;
|
|
14
|
+
private txUtilsConfig?;
|
|
15
|
+
private createVerificationJson;
|
|
16
|
+
private salt;
|
|
17
|
+
private txHashes;
|
|
18
|
+
readonly l1TxUtils: L1TxUtils;
|
|
19
|
+
readonly verificationRecords: VerificationRecord[];
|
|
20
|
+
constructor(client: ExtendedViemWalletClient, maybeSalt: number | undefined, dateProvider?: DateProvider, acceleratedTestDeployments?: boolean, logger?: Logger, txUtilsConfig?: L1TxUtilsConfig | undefined, createVerificationJson?: boolean);
|
|
21
|
+
deploy<const TAbi extends Abi>(params: ContractArtifacts<TAbi>, args?: ContractConstructorArgs<TAbi>, opts?: {
|
|
22
|
+
gasLimit?: bigint;
|
|
23
|
+
noSimulation?: boolean;
|
|
24
|
+
}): Promise<{
|
|
25
|
+
address: EthAddress;
|
|
26
|
+
existed: boolean;
|
|
27
|
+
}>;
|
|
28
|
+
waitForDeployments(): Promise<void>;
|
|
29
|
+
sendTransaction(tx: L1TxRequest, options?: L1TxConfig): Promise<{
|
|
30
|
+
txHash: Hex;
|
|
31
|
+
gasLimit: bigint;
|
|
32
|
+
gasPrice: GasPrice;
|
|
33
|
+
}>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Helper function to deploy ETH contracts.
|
|
37
|
+
* @param walletClient - A viem WalletClient.
|
|
38
|
+
* @param publicClient - A viem PublicClient.
|
|
39
|
+
* @param abi - The ETH contract's ABI (as abitype's Abi).
|
|
40
|
+
* @param bytecode - The ETH contract's bytecode.
|
|
41
|
+
* @param args - Constructor arguments for the contract.
|
|
42
|
+
* @param salt - Optional salt for CREATE2 deployment (does not wait for deployment tx to be mined if set, does not send tx if contract already exists).
|
|
43
|
+
* @returns The ETH address the contract was deployed to.
|
|
44
|
+
*/
|
|
45
|
+
export declare function deployL1Contract(extendedClient: ExtendedViemWalletClient, abi: Narrow<Abi | readonly unknown[]>, bytecode: Hex, args?: readonly unknown[], opts?: {
|
|
46
|
+
salt?: Hex;
|
|
47
|
+
libraries?: Libraries;
|
|
48
|
+
logger?: Logger;
|
|
49
|
+
l1TxUtils?: L1TxUtils;
|
|
50
|
+
gasLimit?: bigint;
|
|
51
|
+
acceleratedTestDeployments?: boolean;
|
|
52
|
+
noSimulation?: boolean;
|
|
53
|
+
}): Promise<{
|
|
54
|
+
address: EthAddress;
|
|
55
|
+
txHash: Hex | undefined;
|
|
56
|
+
deployedLibraries?: VerificationLibraryEntry[];
|
|
57
|
+
existed: boolean;
|
|
58
|
+
}>;
|
|
59
|
+
export declare function getExpectedAddress(abi: Narrow<Abi | readonly unknown[]>, bytecode: Hex, args: readonly unknown[], salt: Hex): {
|
|
60
|
+
address: `0x${string}`;
|
|
61
|
+
paddedSalt: `0x${string}`;
|
|
62
|
+
calldata: `0x${string}`;
|
|
63
|
+
};
|
|
64
|
+
export declare const deployUpgradePayload: (deployer: L1Deployer, addresses: {
|
|
65
|
+
registryAddress: EthAddress;
|
|
66
|
+
rollupAddress: EthAddress;
|
|
67
|
+
}) => Promise<EthAddress>;
|
|
68
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwbG95X2wxX2NvbnRyYWN0LmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZGVwbG95X2wxX2NvbnRyYWN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUMzRCxPQUFPLEVBQUUsS0FBSyxNQUFNLEVBQWdCLE1BQU0sdUJBQXVCLENBQUM7QUFDbEUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRXZELE9BQU8sRUFDTCxLQUFLLEdBQUcsRUFDUixLQUFLLHVCQUF1QixFQUM1QixLQUFLLEdBQUcsRUFDUixLQUFLLE1BQU0sRUFPWixNQUFNLE1BQU0sQ0FBQztBQUVkLE9BQU8sRUFDTCxLQUFLLGlCQUFpQixFQUV0QixLQUFLLFNBQVMsRUFDZCxLQUFLLHdCQUF3QixFQUM3QixLQUFLLGtCQUFrQixFQUN4QixNQUFNLGdDQUFnQyxDQUFDO0FBRXhDLE9BQU8sRUFBRSxLQUFLLGVBQWUsRUFBNkIsTUFBTSx5QkFBeUIsQ0FBQztBQUUxRixPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM5RCxPQUFPLEtBQUssRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2hGLE9BQU8sS0FBSyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRzNELHFCQUFhLFVBQVU7YUFPSCxNQUFNLEVBQUUsd0JBQXdCO0lBR2hELE9BQU8sQ0FBQywwQkFBMEI7SUFDbEMsT0FBTyxDQUFDLE1BQU07SUFDZCxPQUFPLENBQUMsYUFBYSxDQUFDO0lBQ3RCLE9BQU8sQ0FBQyxzQkFBc0I7SUFaaEMsT0FBTyxDQUFDLElBQUksQ0FBa0I7SUFDOUIsT0FBTyxDQUFDLFFBQVEsQ0FBYTtJQUM3QixTQUFnQixTQUFTLEVBQUUsU0FBUyxDQUFDO0lBQ3JDLFNBQWdCLG1CQUFtQixFQUFFLGtCQUFrQixFQUFFLENBQU07SUFFL0QsWUFDa0IsTUFBTSxFQUFFLHdCQUF3QixFQUNoRCxTQUFTLEVBQUUsTUFBTSxHQUFHLFNBQVMsRUFDN0IsWUFBWSxHQUFFLFlBQWlDLEVBQ3ZDLDBCQUEwQixHQUFFLE9BQWUsRUFDM0MsTUFBTSxHQUFFLE1BQW1DLEVBQzNDLGFBQWEsQ0FBQyw2QkFBaUIsRUFDL0Isc0JBQXNCLEdBQUUsT0FBZSxFQVFoRDtJQUVLLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxTQUFTLEdBQUcsRUFDakMsTUFBTSxFQUFFLGlCQUFpQixDQUFDLElBQUksQ0FBQyxFQUMvQixJQUFJLENBQUMsRUFBRSx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsRUFDcEMsSUFBSSxHQUFFO1FBQUUsUUFBUSxDQUFDLEVBQUUsTUFBTSxDQUFDO1FBQUMsWUFBWSxDQUFDLEVBQUUsT0FBTyxDQUFBO0tBQU8sR0FDdkQsT0FBTyxDQUFDO1FBQUUsT0FBTyxFQUFFLFVBQVUsQ0FBQztRQUFDLE9BQU8sRUFBRSxPQUFPLENBQUE7S0FBRSxDQUFDLENBaURwRDtJQUVLLGtCQUFrQixJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FrQnhDO0lBRUQsZUFBZSxDQUNiLEVBQUUsRUFBRSxXQUFXLEVBQ2YsT0FBTyxDQUFDLEVBQUUsVUFBVSxHQUNuQixPQUFPLENBQUM7UUFBRSxNQUFNLEVBQUUsR0FBRyxDQUFDO1FBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQztRQUFDLFFBQVEsRUFBRSxRQUFRLENBQUE7S0FBRSxDQUFDLENBTWhFO0NBQ0Y7QUFFRDs7Ozs7Ozs7O0dBU0c7QUFDSCx3QkFBc0IsZ0JBQWdCLENBQ3BDLGNBQWMsRUFBRSx3QkFBd0IsRUFDeEMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxHQUFHLEdBQUcsU0FBUyxPQUFPLEVBQUUsQ0FBQyxFQUNyQyxRQUFRLEVBQUUsR0FBRyxFQUNiLElBQUksR0FBRSxTQUFTLE9BQU8sRUFBTyxFQUM3QixJQUFJLEdBQUU7SUFDSixJQUFJLENBQUMsRUFBRSxHQUFHLENBQUM7SUFDWCxTQUFTLENBQUMsRUFBRSxTQUFTLENBQUM7SUFDdEIsTUFBTSxDQUFDLEVBQUUsTUFBTSxDQUFDO0lBQ2hCLFNBQVMsQ0FBQyxFQUFFLFNBQVMsQ0FBQztJQUN0QixRQUFRLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDbEIsMEJBQTBCLENBQUMsRUFBRSxPQUFPLENBQUM7SUFDckMsWUFBWSxDQUFDLEVBQUUsT0FBTyxDQUFDO0NBQ25CLEdBQ0wsT0FBTyxDQUFDO0lBQ1QsT0FBTyxFQUFFLFVBQVUsQ0FBQztJQUNwQixNQUFNLEVBQUUsR0FBRyxHQUFHLFNBQVMsQ0FBQztJQUN4QixpQkFBaUIsQ0FBQyxFQUFFLHdCQUF3QixFQUFFLENBQUM7SUFDL0MsT0FBTyxFQUFFLE9BQU8sQ0FBQztDQUNsQixDQUFDLENBMkpEO0FBRUQsd0JBQWdCLGtCQUFrQixDQUNoQyxHQUFHLEVBQUUsTUFBTSxDQUFDLEdBQUcsR0FBRyxTQUFTLE9BQU8sRUFBRSxDQUFDLEVBQ3JDLFFBQVEsRUFBRSxHQUFHLEVBQ2IsSUFBSSxFQUFFLFNBQVMsT0FBTyxFQUFFLEVBQ3hCLElBQUksRUFBRSxHQUFHOzs7O0VBZVY7QUFFRCxlQUFPLE1BQU0sb0JBQW9COzs7eUJBWWhDLENBQUMifQ==
|