@aztec/cli 0.1.0-alpha29 → 0.1.0-alpha31
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/.tsbuildinfo +1 -1
- package/README.md +53 -21
- package/dest/index.js +71 -35
- package/dest/utils.d.ts +22 -3
- package/dest/utils.d.ts.map +1 -1
- package/dest/utils.js +39 -9
- package/package.json +6 -6
- package/src/index.ts +117 -41
- package/src/utils.ts +48 -9
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/cli",
|
|
3
|
-
"version": "0.1.0-
|
|
3
|
+
"version": "0.1.0-alpha31",
|
|
4
4
|
"main": "./dest/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@aztec/aztec.js": "0.1.0-
|
|
8
|
-
"@aztec/ethereum": "0.1.0-
|
|
9
|
-
"@aztec/foundation": "0.1.0-
|
|
10
|
-
"@aztec/noir-contracts": "0.1.0-
|
|
11
|
-
"@aztec/types": "0.1.0-
|
|
7
|
+
"@aztec/aztec.js": "0.1.0-alpha31",
|
|
8
|
+
"@aztec/ethereum": "0.1.0-alpha31",
|
|
9
|
+
"@aztec/foundation": "0.1.0-alpha31",
|
|
10
|
+
"@aztec/noir-contracts": "0.1.0-alpha31",
|
|
11
|
+
"@aztec/types": "0.1.0-alpha31",
|
|
12
12
|
"commander": "^9.0.0",
|
|
13
13
|
"tslib": "^2.4.0",
|
|
14
14
|
"viem": "^1.2.5"
|
package/src/index.ts
CHANGED
|
@@ -20,7 +20,14 @@ import { Command } from 'commander';
|
|
|
20
20
|
import { mnemonicToAccount } from 'viem/accounts';
|
|
21
21
|
|
|
22
22
|
import { encodeArgs, parseStructString } from './cli_encoder.js';
|
|
23
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
deployAztecContracts,
|
|
25
|
+
getAbiFunction,
|
|
26
|
+
getContractAbi,
|
|
27
|
+
getExampleContractArtifacts,
|
|
28
|
+
getTxSender,
|
|
29
|
+
prepTx,
|
|
30
|
+
} from './utils.js';
|
|
24
31
|
|
|
25
32
|
const accountCreationSalt = Fr.ZERO;
|
|
26
33
|
|
|
@@ -46,8 +53,8 @@ async function main() {
|
|
|
46
53
|
program
|
|
47
54
|
.command('deploy-l1-contracts')
|
|
48
55
|
.description('Deploys all necessary Ethereum contracts for Aztec.')
|
|
49
|
-
.
|
|
50
|
-
'
|
|
56
|
+
.option(
|
|
57
|
+
'-u, --rpc-url <string>',
|
|
51
58
|
'Url of the ethereum host. Chain identifiers localhost and testnet can be used',
|
|
52
59
|
ETHEREUM_HOST || 'http://localhost:8545',
|
|
53
60
|
)
|
|
@@ -58,9 +65,15 @@ async function main() {
|
|
|
58
65
|
'The mnemonic to use in deployment',
|
|
59
66
|
'test test test test test test test test test test test junk',
|
|
60
67
|
)
|
|
61
|
-
.action(async
|
|
68
|
+
.action(async options => {
|
|
62
69
|
const { rollupAddress, registryAddress, inboxAddress, outboxAddress, contractDeploymentEmitterAddress } =
|
|
63
|
-
await deployAztecContracts(
|
|
70
|
+
await deployAztecContracts(
|
|
71
|
+
options.rpcUrl,
|
|
72
|
+
options.apiKey ?? '',
|
|
73
|
+
options.privateKey,
|
|
74
|
+
options.mnemonic,
|
|
75
|
+
debugLogger,
|
|
76
|
+
);
|
|
64
77
|
log('\n');
|
|
65
78
|
log(`Rollup Address: ${rollupAddress.toString()}`);
|
|
66
79
|
log(`Registry Address: ${registryAddress.toString()}`);
|
|
@@ -105,7 +118,7 @@ async function main() {
|
|
|
105
118
|
const wallet = await createAccounts(
|
|
106
119
|
client,
|
|
107
120
|
SchnorrSingleKeyAccountContractAbi,
|
|
108
|
-
new PrivateKey(privateKey),
|
|
121
|
+
privateKey && new PrivateKey(privateKey),
|
|
109
122
|
accountCreationSalt,
|
|
110
123
|
1,
|
|
111
124
|
);
|
|
@@ -118,16 +131,20 @@ async function main() {
|
|
|
118
131
|
program
|
|
119
132
|
.command('deploy')
|
|
120
133
|
.description('Deploys a compiled Noir contract to Aztec.')
|
|
121
|
-
.
|
|
122
|
-
|
|
134
|
+
.option(
|
|
135
|
+
'-c, --contract-abi <file>',
|
|
136
|
+
"A compiled Noir contract's ABI in JSON format or name of a contract ABI exported by @aztec/noir-contracts",
|
|
137
|
+
undefined,
|
|
138
|
+
)
|
|
139
|
+
.option('-a, --args <constructorArgs...>', 'Contract constructor arguments', [])
|
|
123
140
|
.option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
|
|
124
141
|
.option(
|
|
125
142
|
'-k, --public-key <string>',
|
|
126
143
|
'Public key of the deployer. If not provided, it will check the RPC for existing ones.',
|
|
127
144
|
PUBLIC_KEY,
|
|
128
145
|
)
|
|
129
|
-
.action(async (
|
|
130
|
-
const contractAbi = getContractAbi(
|
|
146
|
+
.action(async (options: any) => {
|
|
147
|
+
const contractAbi = await getContractAbi(options.contractAbi, log);
|
|
131
148
|
const constructorAbi = contractAbi.functions.find(({ name }) => name === 'constructor');
|
|
132
149
|
|
|
133
150
|
const client = createAztecRpcClient(options.rpcUrl);
|
|
@@ -146,7 +163,14 @@ async function main() {
|
|
|
146
163
|
|
|
147
164
|
const deployer = new ContractDeployer(contractAbi, client);
|
|
148
165
|
|
|
149
|
-
const
|
|
166
|
+
const constructor = getAbiFunction(contractAbi, 'constructor');
|
|
167
|
+
if (constructor.parameters.length !== options.args.length) {
|
|
168
|
+
throw Error(
|
|
169
|
+
`Invalid number of args passed. Expected ${constructor.parameters.length}; Received: ${options.args.length}`,
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const tx = deployer.deploy(...encodeArgs(options.args, constructorAbi!.parameters), publicKey.toBigInts()).send();
|
|
150
174
|
await tx.isMined();
|
|
151
175
|
const receipt = await tx.getReceipt();
|
|
152
176
|
log(`\nAztec Contract deployed at ${receipt.contractAddress?.toString()}\n`);
|
|
@@ -155,19 +179,19 @@ async function main() {
|
|
|
155
179
|
program
|
|
156
180
|
.command('check-deploy')
|
|
157
181
|
.description('Checks if a contract is deployed to the specified Aztec address.')
|
|
158
|
-
.
|
|
159
|
-
.option('-u, --rpc-url <
|
|
160
|
-
.action(async
|
|
182
|
+
.option('-ca, --contract-address <address>', 'An Aztec address to check if contract has been deployed to.')
|
|
183
|
+
.option('-u, --rpc-url <url>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
|
|
184
|
+
.action(async options => {
|
|
161
185
|
const client = createAztecRpcClient(options.rpcUrl);
|
|
162
|
-
const address = AztecAddress.fromString(
|
|
186
|
+
const address = AztecAddress.fromString(options.contractAddress);
|
|
163
187
|
const isDeployed = await client.isContractDeployed(address);
|
|
164
188
|
log(`\n${isDeployed.toString()}\n`);
|
|
165
189
|
});
|
|
166
190
|
|
|
167
191
|
program
|
|
168
192
|
.command('get-tx-receipt')
|
|
169
|
-
.description('Gets the receipt for the specified transaction hash.')
|
|
170
193
|
.argument('<txHash>', 'A TX hash to get the receipt for.')
|
|
194
|
+
.description('Gets the receipt for the specified transaction hash.')
|
|
171
195
|
.option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
|
|
172
196
|
.action(async (_txHash, options) => {
|
|
173
197
|
const client = createAztecRpcClient(options.rpcUrl);
|
|
@@ -186,15 +210,15 @@ async function main() {
|
|
|
186
210
|
.argument('<contractAddress>', 'Aztec address of the contract.')
|
|
187
211
|
.option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
|
|
188
212
|
.option('-b, --include-bytecode', "Include the contract's public function bytecode, if any.")
|
|
189
|
-
.action(async (
|
|
213
|
+
.action(async (contractAddress, options) => {
|
|
190
214
|
const client = createAztecRpcClient(options.rpcUrl);
|
|
191
|
-
const address = AztecAddress.fromString(
|
|
215
|
+
const address = AztecAddress.fromString(contractAddress);
|
|
192
216
|
const contractDataOrInfo = options.includeBytecode
|
|
193
217
|
? await client.getContractData(address)
|
|
194
218
|
: await client.getContractInfo(address);
|
|
195
219
|
|
|
196
220
|
if (!contractDataOrInfo) {
|
|
197
|
-
log(`No contract data found at ${
|
|
221
|
+
log(`No contract data found at ${contractAddress}`);
|
|
198
222
|
return;
|
|
199
223
|
}
|
|
200
224
|
let contractData: ContractData;
|
|
@@ -238,8 +262,26 @@ async function main() {
|
|
|
238
262
|
}
|
|
239
263
|
});
|
|
240
264
|
|
|
265
|
+
program
|
|
266
|
+
.command('register-public-key')
|
|
267
|
+
.description("Register an account's public key to the RPC server")
|
|
268
|
+
.option('-a, --address <aztecAddress>', "The account's Aztec address.")
|
|
269
|
+
.option('-p, --public-key <publicKey>', 'The account public key.')
|
|
270
|
+
.option('-pa, --partial-address <partialAddress', 'The partially computed address of the account contract.')
|
|
271
|
+
.option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
|
|
272
|
+
.action(async options => {
|
|
273
|
+
const client = createAztecRpcClient(options.rpcUrl);
|
|
274
|
+
const address = AztecAddress.fromString(options.address);
|
|
275
|
+
const publicKey = Point.fromString(options.publicKey);
|
|
276
|
+
const partialAddress = Fr.fromString(options.partialAddress);
|
|
277
|
+
|
|
278
|
+
await client.addPublicKeyAndPartialAddress(address, publicKey, partialAddress);
|
|
279
|
+
log(`\nRegistered details for Address: ${options.address}\n`);
|
|
280
|
+
});
|
|
281
|
+
|
|
241
282
|
program
|
|
242
283
|
.command('get-accounts')
|
|
284
|
+
.description('Gets all the Aztec accounts stored in the Aztec RPC.')
|
|
243
285
|
.option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
|
|
244
286
|
.action(async (options: any) => {
|
|
245
287
|
const client = createAztecRpcClient(options.rpcUrl);
|
|
@@ -277,22 +319,33 @@ async function main() {
|
|
|
277
319
|
program
|
|
278
320
|
.command('send')
|
|
279
321
|
.description('Calls a function on an Aztec contract.')
|
|
280
|
-
.argument('<contractAbi>', "The compiled contract's ABI in JSON format", undefined)
|
|
281
|
-
.argument('<contractAddress>', 'Address of the contract')
|
|
282
322
|
.argument('<functionName>', 'Name of Function to view')
|
|
283
|
-
.
|
|
323
|
+
.option('-a, --args [functionArgs...]', 'Function arguments', [])
|
|
324
|
+
.option(
|
|
325
|
+
'-c, --contract-abi <fileLocation>',
|
|
326
|
+
"A compiled Noir contract's ABI in JSON format or name of a contract ABI exported by @aztec/noir-contracts",
|
|
327
|
+
undefined,
|
|
328
|
+
)
|
|
329
|
+
.option('-ca, --contract-address <address>', 'Aztec address of the contract.')
|
|
284
330
|
.option('-k, --private-key <string>', "The sender's private key.", PRIVATE_KEY)
|
|
285
331
|
.option('-u, --rpcUrl <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
|
|
286
332
|
|
|
287
|
-
.action(async (
|
|
288
|
-
const { contractAddress, functionArgs, contractAbi } = prepTx(
|
|
289
|
-
|
|
290
|
-
|
|
333
|
+
.action(async (functionName, options) => {
|
|
334
|
+
const { contractAddress, functionArgs, contractAbi } = await prepTx(
|
|
335
|
+
options.contractAbi,
|
|
336
|
+
options.contractAddress,
|
|
291
337
|
functionName,
|
|
292
|
-
|
|
338
|
+
options.args,
|
|
293
339
|
log,
|
|
294
340
|
);
|
|
295
341
|
|
|
342
|
+
const fnAbi = getAbiFunction(contractAbi, functionName);
|
|
343
|
+
if (fnAbi.parameters.length !== options.args.length) {
|
|
344
|
+
throw Error(
|
|
345
|
+
`Invalid number of args passed. Expected ${fnAbi.parameters.length}; Received: ${options.args.length}`,
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
|
|
296
349
|
const client = createAztecRpcClient(options.rpcUrl);
|
|
297
350
|
const wallet = await getAccountWallet(
|
|
298
351
|
client,
|
|
@@ -319,20 +372,30 @@ async function main() {
|
|
|
319
372
|
.description(
|
|
320
373
|
'Simulates the execution of a view (read-only) function on a deployed contract, without modifying state.',
|
|
321
374
|
)
|
|
322
|
-
.argument('<contractAbi>', "The compiled contract's ABI in JSON format", undefined)
|
|
323
|
-
.argument('<contractAddress>', 'Address of the contract')
|
|
324
375
|
.argument('<functionName>', 'Name of Function to view')
|
|
325
|
-
.
|
|
376
|
+
.option('-a, --args [functionArgs...]', 'Function arguments', [])
|
|
377
|
+
.option(
|
|
378
|
+
'-c, --contract-abi <fileLocation>',
|
|
379
|
+
"A compiled Noir contract's ABI in JSON format or name of a contract ABI exported by @aztec/noir-contracts",
|
|
380
|
+
undefined,
|
|
381
|
+
)
|
|
382
|
+
.option('-ca, --contract-address <address>', 'Aztec address of the contract.')
|
|
326
383
|
.option('-f, --from <string>', 'Public key of the TX viewer. If empty, will try to find account in RPC.')
|
|
327
384
|
.option('-u, --rpcUrl <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
|
|
328
|
-
.action(async (
|
|
329
|
-
const { contractAddress, functionArgs } = prepTx(
|
|
330
|
-
|
|
331
|
-
|
|
385
|
+
.action(async (functionName, options) => {
|
|
386
|
+
const { contractAddress, functionArgs, contractAbi } = await prepTx(
|
|
387
|
+
options.contractAbi,
|
|
388
|
+
options.contractAddress,
|
|
332
389
|
functionName,
|
|
333
|
-
|
|
390
|
+
options.args,
|
|
334
391
|
log,
|
|
335
392
|
);
|
|
393
|
+
const fnAbi = getAbiFunction(contractAbi, functionName);
|
|
394
|
+
if (fnAbi.parameters.length !== options.args.length) {
|
|
395
|
+
throw Error(
|
|
396
|
+
`Invalid number of args passed. Expected ${fnAbi.parameters.length}; Received: ${options.args.length}`,
|
|
397
|
+
);
|
|
398
|
+
}
|
|
336
399
|
const client = createAztecRpcClient(options.rpcUrl);
|
|
337
400
|
const from = await getTxSender(client, options.from);
|
|
338
401
|
const result = await client.viewTx(functionName, functionArgs, contractAddress, from);
|
|
@@ -344,16 +407,20 @@ async function main() {
|
|
|
344
407
|
.command('parse-parameter-struct')
|
|
345
408
|
.description("Helper for parsing an encoded string into a contract's parameter struct.")
|
|
346
409
|
.argument('<encodedString>', 'The encoded hex string')
|
|
347
|
-
.
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
410
|
+
.option(
|
|
411
|
+
'-c, --contract-abi <fileLocation>',
|
|
412
|
+
"A compiled Noir contract's ABI in JSON format or name of a contract ABI exported by @aztec/noir-contracts",
|
|
413
|
+
undefined,
|
|
414
|
+
)
|
|
415
|
+
.option('-p, --parameter <parameterName>', 'The name of the struct parameter to decode into')
|
|
416
|
+
.action(async (encodedString, options) => {
|
|
417
|
+
const contractAbi = await getContractAbi(options.contractAbi, log);
|
|
351
418
|
const parameterAbitype = contractAbi.functions
|
|
352
419
|
.map(({ parameters }) => parameters)
|
|
353
420
|
.flat()
|
|
354
|
-
.find(({ name, type }) => name ===
|
|
421
|
+
.find(({ name, type }) => name === options.parameter && type.kind === 'struct');
|
|
355
422
|
if (!parameterAbitype) {
|
|
356
|
-
log(`No struct parameter found with name ${
|
|
423
|
+
log(`No struct parameter found with name ${options.parameter}`);
|
|
357
424
|
return;
|
|
358
425
|
}
|
|
359
426
|
const data = parseStructString(encodedString, parameterAbitype.type as StructType);
|
|
@@ -370,6 +437,15 @@ async function main() {
|
|
|
370
437
|
log(`${num}\n`);
|
|
371
438
|
});
|
|
372
439
|
|
|
440
|
+
program
|
|
441
|
+
.command('example-contracts')
|
|
442
|
+
.description('Lists the example contracts available to deploy from @aztec/noir-contracts')
|
|
443
|
+
.action(async () => {
|
|
444
|
+
const abisList = await getExampleContractArtifacts();
|
|
445
|
+
const names = Object.keys(abisList);
|
|
446
|
+
names.forEach(name => log(name));
|
|
447
|
+
});
|
|
448
|
+
|
|
373
449
|
await program.parseAsync(process.argv);
|
|
374
450
|
}
|
|
375
451
|
|
package/src/utils.ts
CHANGED
|
@@ -8,6 +8,27 @@ import { mnemonicToAccount, privateKeyToAccount } from 'viem/accounts';
|
|
|
8
8
|
|
|
9
9
|
import { encodeArgs } from './cli_encoder.js';
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Helper type to dynamically import contarcts.
|
|
13
|
+
*/
|
|
14
|
+
interface ArtifactsType {
|
|
15
|
+
[key: string]: ContractAbi;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Helper to get an ABI function or throw error if it doesn't exist.
|
|
20
|
+
* @param abi - Contract's ABI in JSON format.
|
|
21
|
+
* @param fnName - Function name to be found.
|
|
22
|
+
* @returns The function's ABI.
|
|
23
|
+
*/
|
|
24
|
+
export function getAbiFunction(abi: ContractAbi, fnName: string) {
|
|
25
|
+
const fn = abi.functions.find(({ name }) => name === fnName);
|
|
26
|
+
if (!fn) {
|
|
27
|
+
throw Error(`Function ${fnName} not found in contract ABI.`);
|
|
28
|
+
}
|
|
29
|
+
return fn;
|
|
30
|
+
}
|
|
31
|
+
|
|
11
32
|
/**
|
|
12
33
|
* Function to execute the 'deployRollupContracts' command.
|
|
13
34
|
* @param rpcUrl - The RPC URL of the ethereum node.
|
|
@@ -27,13 +48,35 @@ export async function deployAztecContracts(
|
|
|
27
48
|
return await deployL1Contracts(chain.rpcUrl, account, chain.chainInfo, debugLogger);
|
|
28
49
|
}
|
|
29
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Gets all contracts available in \@aztec/noir-contracts.
|
|
53
|
+
* @returns The contract ABIs.
|
|
54
|
+
*/
|
|
55
|
+
export async function getExampleContractArtifacts() {
|
|
56
|
+
const artifacts: ArtifactsType = await import('@aztec/noir-contracts/artifacts');
|
|
57
|
+
return artifacts;
|
|
58
|
+
}
|
|
59
|
+
|
|
30
60
|
/**
|
|
31
61
|
* Reads a file and converts it to an Aztec Contract ABI.
|
|
32
62
|
* @param fileDir - The directory of the compiled contract ABI.
|
|
33
63
|
* @returns The parsed ContractABI.
|
|
34
64
|
*/
|
|
35
|
-
export function getContractAbi(fileDir: string, log: LogFn) {
|
|
36
|
-
|
|
65
|
+
export async function getContractAbi(fileDir: string, log: LogFn) {
|
|
66
|
+
// first check if it's a noir-contracts example
|
|
67
|
+
let contents: string;
|
|
68
|
+
const artifacts = await getExampleContractArtifacts();
|
|
69
|
+
if (artifacts[fileDir]) {
|
|
70
|
+
return artifacts[fileDir] as ContractAbi;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
contents = fs.readFileSync(fileDir, 'utf8');
|
|
75
|
+
} catch {
|
|
76
|
+
throw Error(`Contract ${fileDir} not found`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// if not found, try reading as path directly
|
|
37
80
|
let contractAbi: ContractAbi;
|
|
38
81
|
try {
|
|
39
82
|
contractAbi = JSON.parse(contents) as ContractAbi;
|
|
@@ -78,7 +121,7 @@ export async function getTxSender(client: AztecRPC, _from?: string) {
|
|
|
78
121
|
* @param log - Logger instance that will output to the CLI
|
|
79
122
|
* @returns Formatted contract address, function arguments and caller's aztec address.
|
|
80
123
|
*/
|
|
81
|
-
export function prepTx(
|
|
124
|
+
export async function prepTx(
|
|
82
125
|
contractFile: string,
|
|
83
126
|
_contractAddress: string,
|
|
84
127
|
functionName: string,
|
|
@@ -91,12 +134,8 @@ export function prepTx(
|
|
|
91
134
|
} catch {
|
|
92
135
|
throw new Error(`Unable to parse contract address ${_contractAddress}.`);
|
|
93
136
|
}
|
|
94
|
-
const contractAbi = getContractAbi(contractFile, log);
|
|
95
|
-
const functionAbi = contractAbi
|
|
96
|
-
if (!functionAbi) {
|
|
97
|
-
throw new Error(`Function ${functionName} not found on contract ABI.`);
|
|
98
|
-
}
|
|
99
|
-
|
|
137
|
+
const contractAbi = await getContractAbi(contractFile, log);
|
|
138
|
+
const functionAbi = getAbiFunction(contractAbi, functionName);
|
|
100
139
|
const functionArgs = encodeArgs(_functionArgs, functionAbi.parameters);
|
|
101
140
|
|
|
102
141
|
return { contractAddress, functionArgs, contractAbi };
|