@aztec/ethereum 0.23.0 → 0.24.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/ethereum",
3
- "version": "0.23.0",
3
+ "version": "0.24.0",
4
4
  "type": "module",
5
5
  "exports": "./dest/index.js",
6
6
  "typedocOptions": {
@@ -24,7 +24,7 @@
24
24
  "../package.common.json"
25
25
  ],
26
26
  "dependencies": {
27
- "@aztec/foundation": "0.23.0",
27
+ "@aztec/foundation": "0.24.0",
28
28
  "dotenv": "^16.0.3",
29
29
  "tslib": "^2.4.0",
30
30
  "viem": "^1.2.5"
@@ -0,0 +1,3 @@
1
+ import { Hex } from 'viem';
2
+
3
+ export const NULL_KEY: Hex = `0x${'0000000000000000000000000000000000000000000000000000000000000000'}`;
@@ -0,0 +1,223 @@
1
+ import { EthAddress } from '@aztec/foundation/eth-address';
2
+ import { DebugLogger } from '@aztec/foundation/log';
3
+
4
+ import type { Abi, Narrow } from 'abitype';
5
+ import {
6
+ Account,
7
+ Chain,
8
+ Hex,
9
+ HttpTransport,
10
+ PublicClient,
11
+ WalletClient,
12
+ createPublicClient,
13
+ createWalletClient,
14
+ getAddress,
15
+ getContract,
16
+ http,
17
+ } from 'viem';
18
+ import { HDAccount, PrivateKeyAccount } from 'viem/accounts';
19
+
20
+ import { L1ContractAddresses } from './l1_contract_addresses.js';
21
+
22
+ /**
23
+ * Return type of the deployL1Contract function.
24
+ */
25
+ export type DeployL1Contracts = {
26
+ /**
27
+ * Wallet Client Type.
28
+ */
29
+ walletClient: WalletClient<HttpTransport, Chain, Account>;
30
+ /**
31
+ * Public Client Type.
32
+ */
33
+ publicClient: PublicClient<HttpTransport, Chain>;
34
+
35
+ /**
36
+ * The currently deployed l1 contract addresses
37
+ */
38
+ l1ContractAddresses: L1ContractAddresses;
39
+ };
40
+
41
+ /**
42
+ * Contract artifacts
43
+ */
44
+ export interface ContractArtifacts {
45
+ /**
46
+ * The contract abi.
47
+ */
48
+ contractAbi: Narrow<Abi | readonly unknown[]>;
49
+ /**
50
+ * The contract bytecode
51
+ */
52
+ contractBytecode: Hex;
53
+ }
54
+
55
+ /**
56
+ * All L1 Contract Artifacts for deployment
57
+ */
58
+ export interface L1ContractArtifactsForDeployment {
59
+ /**
60
+ * Contract deployment emitter artifacts
61
+ */
62
+ contractDeploymentEmitter: ContractArtifacts;
63
+ /**
64
+ * Inbox contract artifacts
65
+ */
66
+ inbox: ContractArtifacts;
67
+ /**
68
+ * Outbox contract artifacts
69
+ */
70
+ outbox: ContractArtifacts;
71
+ /**
72
+ * Availability Oracle contract artifacts
73
+ */
74
+ availabilityOracle: ContractArtifacts;
75
+ /**
76
+ * Registry contract artifacts
77
+ */
78
+ registry: ContractArtifacts;
79
+ /**
80
+ * Rollup contract artifacts
81
+ */
82
+ rollup: ContractArtifacts;
83
+ }
84
+
85
+ /**
86
+ * Deploys the aztec L1 contracts; Rollup, Contract Deployment Emitter & (optionally) Decoder Helper.
87
+ * @param rpcUrl - URL of the ETH RPC to use for deployment.
88
+ * @param account - Private Key or HD Account that will deploy the contracts.
89
+ * @param chain - The chain instance to deploy to.
90
+ * @param logger - A logger object.
91
+ * @param contractsToDeploy - The set of L1 artifacts to be deployed
92
+ * @returns A list of ETH addresses of the deployed contracts.
93
+ */
94
+ export const deployL1Contracts = async (
95
+ rpcUrl: string,
96
+ account: HDAccount | PrivateKeyAccount,
97
+ chain: Chain,
98
+ logger: DebugLogger,
99
+ contractsToDeploy: L1ContractArtifactsForDeployment,
100
+ ): Promise<DeployL1Contracts> => {
101
+ logger('Deploying contracts...');
102
+
103
+ const walletClient = createWalletClient({
104
+ account,
105
+ chain,
106
+ transport: http(rpcUrl),
107
+ });
108
+ const publicClient = createPublicClient({
109
+ chain,
110
+ transport: http(rpcUrl),
111
+ });
112
+
113
+ const registryAddress = await deployL1Contract(
114
+ walletClient,
115
+ publicClient,
116
+ contractsToDeploy.registry.contractAbi,
117
+ contractsToDeploy.registry.contractBytecode,
118
+ );
119
+ logger(`Deployed Registry at ${registryAddress}`);
120
+
121
+ const inboxAddress = await deployL1Contract(
122
+ walletClient,
123
+ publicClient,
124
+ contractsToDeploy.inbox.contractAbi,
125
+ contractsToDeploy.inbox.contractBytecode,
126
+ [getAddress(registryAddress.toString())],
127
+ );
128
+ logger(`Deployed Inbox at ${inboxAddress}`);
129
+
130
+ const outboxAddress = await deployL1Contract(
131
+ walletClient,
132
+ publicClient,
133
+ contractsToDeploy.outbox.contractAbi,
134
+ contractsToDeploy.outbox.contractBytecode,
135
+ [getAddress(registryAddress.toString())],
136
+ );
137
+ logger(`Deployed Outbox at ${outboxAddress}`);
138
+
139
+ const availabilityOracleAddress = await deployL1Contract(
140
+ walletClient,
141
+ publicClient,
142
+ contractsToDeploy.availabilityOracle.contractAbi,
143
+ contractsToDeploy.availabilityOracle.contractBytecode,
144
+ );
145
+ logger(`Deployed AvailabilityOracle at ${availabilityOracleAddress}`);
146
+
147
+ const rollupAddress = await deployL1Contract(
148
+ walletClient,
149
+ publicClient,
150
+ contractsToDeploy.rollup.contractAbi,
151
+ contractsToDeploy.rollup.contractBytecode,
152
+ [getAddress(registryAddress.toString()), getAddress(availabilityOracleAddress.toString())],
153
+ );
154
+ logger(`Deployed Rollup at ${rollupAddress}`);
155
+
156
+ // We need to call a function on the registry to set the various contract addresses.
157
+ const registryContract = getContract({
158
+ address: getAddress(registryAddress.toString()),
159
+ abi: contractsToDeploy.registry.contractAbi,
160
+ publicClient,
161
+ walletClient,
162
+ });
163
+ await registryContract.write.upgrade(
164
+ [getAddress(rollupAddress.toString()), getAddress(inboxAddress.toString()), getAddress(outboxAddress.toString())],
165
+ { account },
166
+ );
167
+
168
+ const contractDeploymentEmitterAddress = await deployL1Contract(
169
+ walletClient,
170
+ publicClient,
171
+ contractsToDeploy.contractDeploymentEmitter.contractAbi,
172
+ contractsToDeploy.contractDeploymentEmitter.contractBytecode,
173
+ );
174
+ logger(`Deployed contract deployment emitter at ${contractDeploymentEmitterAddress}`);
175
+
176
+ const l1Contracts: L1ContractAddresses = {
177
+ availabilityOracleAddress,
178
+ rollupAddress,
179
+ registryAddress,
180
+ inboxAddress,
181
+ outboxAddress,
182
+ contractDeploymentEmitterAddress,
183
+ };
184
+
185
+ return {
186
+ walletClient,
187
+ publicClient,
188
+ l1ContractAddresses: l1Contracts,
189
+ };
190
+ };
191
+
192
+ // docs:start:deployL1Contract
193
+ /**
194
+ * Helper function to deploy ETH contracts.
195
+ * @param walletClient - A viem WalletClient.
196
+ * @param publicClient - A viem PublicClient.
197
+ * @param abi - The ETH contract's ABI (as abitype's Abi).
198
+ * @param bytecode - The ETH contract's bytecode.
199
+ * @param args - Constructor arguments for the contract.
200
+ * @returns The ETH address the contract was deployed to.
201
+ */
202
+ export async function deployL1Contract(
203
+ walletClient: WalletClient<HttpTransport, Chain, Account>,
204
+ publicClient: PublicClient<HttpTransport, Chain>,
205
+ abi: Narrow<Abi | readonly unknown[]>,
206
+ bytecode: Hex,
207
+ args: readonly unknown[] = [],
208
+ ): Promise<EthAddress> {
209
+ const hash = await walletClient.deployContract({
210
+ abi,
211
+ bytecode,
212
+ args,
213
+ });
214
+
215
+ const receipt = await publicClient.waitForTransactionReceipt({ hash });
216
+ const contractAddress = receipt.contractAddress;
217
+ if (!contractAddress) {
218
+ throw new Error(`No contract address found in receipt: ${JSON.stringify(receipt)}`);
219
+ }
220
+
221
+ return EthAddress.fromString(receipt.contractAddress!);
222
+ }
223
+ // docs:end:deployL1Contract
@@ -0,0 +1,16 @@
1
+ import { Chain } from 'viem';
2
+
3
+ /**
4
+ * Interface containing the connection and chain properties to interact with a blockchain.
5
+ */
6
+ export interface EthereumChain {
7
+ /**
8
+ * An instance of the viem chain data.
9
+ */
10
+ chainInfo: Chain;
11
+
12
+ /**
13
+ * The actual url to be used.
14
+ */
15
+ rpcUrl: string;
16
+ }
package/src/index.ts ADDED
@@ -0,0 +1,27 @@
1
+ import { foundry } from 'viem/chains';
2
+
3
+ import { EthereumChain } from './ethereum_chain.js';
4
+ import { createTestnetChain } from './testnet.js';
5
+
6
+ export * from './testnet.js';
7
+ export * from './deploy_l1_contracts.js';
8
+ export * from './l1_contract_addresses.js';
9
+ export * from './constants.js';
10
+
11
+ /**
12
+ * Helper function to create an instance of Aztec Chain from an rpc url and api key.
13
+ * @param rpcUrl - The rpc url of the chain or a chain identifier (e.g. 'testnet')
14
+ * @param apiKey - An optional API key for the chain client.
15
+ */
16
+ export function createEthereumChain(rpcUrl: string, apiKey?: string) {
17
+ if (rpcUrl === 'testnet') {
18
+ if (apiKey === undefined || apiKey === '') {
19
+ throw new Error('API Key must be provided for aztec testnet');
20
+ }
21
+ return createTestnetChain(apiKey!);
22
+ }
23
+ return {
24
+ chainInfo: foundry,
25
+ rpcUrl,
26
+ } as EthereumChain;
27
+ }
@@ -0,0 +1,31 @@
1
+ import { EthAddress } from '@aztec/foundation/eth-address';
2
+
3
+ /**
4
+ * Provides the directory of current L1 contract addresses
5
+ */
6
+ export interface L1ContractAddresses {
7
+ /**
8
+ * Availability Oracle Address.
9
+ */
10
+ availabilityOracleAddress: EthAddress;
11
+ /**
12
+ * Rollup Address.
13
+ */
14
+ rollupAddress: EthAddress;
15
+ /**
16
+ * Registry Address.
17
+ */
18
+ registryAddress: EthAddress;
19
+ /**
20
+ * Inbox Address.
21
+ */
22
+ inboxAddress: EthAddress;
23
+ /**
24
+ * Outbox Address.
25
+ */
26
+ outboxAddress: EthAddress;
27
+ /**
28
+ * Data Emitter Address.
29
+ */
30
+ contractDeploymentEmitterAddress: EthAddress;
31
+ }
package/src/testnet.ts ADDED
@@ -0,0 +1,30 @@
1
+ import { Chain } from 'viem';
2
+
3
+ import { EthereumChain } from './ethereum_chain.js';
4
+
5
+ const { DEPLOY_TAG = 'aztec-dev', CHAIN_ID = 31337 } = process.env;
6
+
7
+ export const createTestnetChain = (apiKey: string) => {
8
+ const chain: Chain = {
9
+ id: +CHAIN_ID,
10
+ name: 'testnet',
11
+ network: 'aztec',
12
+ nativeCurrency: {
13
+ name: 'Ether',
14
+ symbol: 'ETH',
15
+ decimals: 18,
16
+ },
17
+ rpcUrls: {
18
+ default: {
19
+ http: [`https://${DEPLOY_TAG}-mainnet-fork.aztec.network:8545/${apiKey}`],
20
+ },
21
+ public: {
22
+ http: [`https://${DEPLOY_TAG}-mainnet-fork.aztec.network:8545/${apiKey}`],
23
+ },
24
+ },
25
+ };
26
+ return {
27
+ chainInfo: chain,
28
+ rpcUrl: chain.rpcUrls.default.http[0],
29
+ } as EthereumChain;
30
+ };