@aztec/cli 0.1.0-alpha37 → 0.1.0-alpha39
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 +8 -8
- package/dest/bin/index.d.ts +3 -0
- package/dest/bin/index.d.ts.map +1 -0
- package/dest/bin/index.js +17 -0
- package/dest/{cli_encoder.d.ts → encoding.d.ts} +1 -1
- package/dest/encoding.d.ts.map +1 -0
- package/dest/encoding.js +87 -0
- package/dest/index.d.ts +9 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +134 -100
- package/dest/utils.d.ts +1 -1
- package/dest/utils.js +4 -4
- package/package.json +8 -7
- package/src/bin/index.ts +20 -0
- package/src/index.ts +150 -122
- package/src/utils.ts +4 -4
- package/tsconfig.json +3 -0
- package/dest/cli_encoder.d.ts.map +0 -1
- package/dest/cli_encoder.js +0 -87
- /package/src/{cli_encoder.ts → encoding.ts} +0 -0
package/src/index.ts
CHANGED
|
@@ -1,26 +1,29 @@
|
|
|
1
|
-
#!/usr/bin/env -S node --no-warnings
|
|
2
1
|
import {
|
|
3
2
|
AztecAddress,
|
|
4
3
|
Contract,
|
|
5
4
|
ContractDeployer,
|
|
6
5
|
Fr,
|
|
7
6
|
Point,
|
|
8
|
-
createAccounts,
|
|
9
7
|
createAztecRpcClient,
|
|
10
8
|
generatePublicKey,
|
|
11
|
-
|
|
9
|
+
getAccountWallets,
|
|
10
|
+
getSchnorrAccount,
|
|
12
11
|
isContractDeployed,
|
|
13
12
|
} from '@aztec/aztec.js';
|
|
14
13
|
import { StructType } from '@aztec/foundation/abi';
|
|
15
14
|
import { JsonStringify } from '@aztec/foundation/json-rpc';
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
15
|
+
import { DebugLogger, LogFn } from '@aztec/foundation/log';
|
|
16
|
+
import { compileContract } from '@aztec/noir-compiler/cli';
|
|
17
|
+
import { SchnorrAccountContractAbi } from '@aztec/noir-contracts/artifacts';
|
|
18
|
+
import { CompleteAddress, ContractData, L2BlockL2Logs, PrivateKey, TxHash } from '@aztec/types';
|
|
19
19
|
|
|
20
20
|
import { Command } from 'commander';
|
|
21
|
+
import { readFileSync } from 'fs';
|
|
22
|
+
import { dirname, resolve } from 'path';
|
|
23
|
+
import { fileURLToPath } from 'url';
|
|
21
24
|
import { mnemonicToAccount } from 'viem/accounts';
|
|
22
25
|
|
|
23
|
-
import { encodeArgs, parseStructString } from './
|
|
26
|
+
import { encodeArgs, parseStructString } from './encoding.js';
|
|
24
27
|
import {
|
|
25
28
|
deployAztecContracts,
|
|
26
29
|
getAbiFunction,
|
|
@@ -32,8 +35,6 @@ import {
|
|
|
32
35
|
|
|
33
36
|
const accountCreationSalt = Fr.ZERO;
|
|
34
37
|
|
|
35
|
-
const debugLogger = createDebugLogger('aztec:cli');
|
|
36
|
-
const log = createConsoleLogger();
|
|
37
38
|
const stripLeadingHex = (hex: string) => {
|
|
38
39
|
if (hex.length > 2 && hex.startsWith('0x')) {
|
|
39
40
|
return hex.substring(2);
|
|
@@ -41,16 +42,22 @@ const stripLeadingHex = (hex: string) => {
|
|
|
41
42
|
return hex;
|
|
42
43
|
};
|
|
43
44
|
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
program.name('aztec-cli').description('CLI for interacting with Aztec.').version('0.1.0');
|
|
47
|
-
|
|
48
|
-
const { ETHEREUM_HOST, AZTEC_RPC_HOST, PRIVATE_KEY, PUBLIC_KEY, API_KEY } = process.env;
|
|
45
|
+
const { ETHEREUM_HOST, AZTEC_RPC_HOST, PRIVATE_KEY, API_KEY } = process.env;
|
|
49
46
|
|
|
50
47
|
/**
|
|
51
|
-
*
|
|
48
|
+
* Returns commander program that defines the CLI.
|
|
49
|
+
* @param log - Console logger.
|
|
50
|
+
* @param debugLogger - Debug logger.
|
|
51
|
+
* @returns The CLI.
|
|
52
52
|
*/
|
|
53
|
-
|
|
53
|
+
export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
|
|
54
|
+
const program = new Command();
|
|
55
|
+
|
|
56
|
+
const packageJsonPath = resolve(dirname(fileURLToPath(import.meta.url)), '../package.json');
|
|
57
|
+
const version: string = JSON.parse(readFileSync(packageJsonPath).toString()).version;
|
|
58
|
+
|
|
59
|
+
program.name('aztec-cli').description('CLI for interacting with Aztec.').version(version);
|
|
60
|
+
|
|
54
61
|
program
|
|
55
62
|
.command('deploy-l1-contracts')
|
|
56
63
|
.description('Deploys all necessary Ethereum contracts for Aztec.')
|
|
@@ -87,7 +94,10 @@ async function main() {
|
|
|
87
94
|
program
|
|
88
95
|
.command('generate-private-key')
|
|
89
96
|
.description('Generates a 32-byte private key.')
|
|
90
|
-
.option(
|
|
97
|
+
.option(
|
|
98
|
+
'-m, --mnemonic',
|
|
99
|
+
'An optional mnemonic string used for the private key generation. If not provided, random private key will be generated.',
|
|
100
|
+
)
|
|
91
101
|
.action(async options => {
|
|
92
102
|
let privKey;
|
|
93
103
|
let publicKey;
|
|
@@ -98,7 +108,7 @@ async function main() {
|
|
|
98
108
|
publicKey = await generatePublicKey(new PrivateKey(key));
|
|
99
109
|
} else {
|
|
100
110
|
const key = PrivateKey.random();
|
|
101
|
-
privKey =
|
|
111
|
+
privKey = key.toString();
|
|
102
112
|
publicKey = await generatePublicKey(key);
|
|
103
113
|
}
|
|
104
114
|
log(`\nPrivate Key: ${privKey}\nPublic Key: ${publicKey.toString()}\n`);
|
|
@@ -106,96 +116,89 @@ async function main() {
|
|
|
106
116
|
|
|
107
117
|
program
|
|
108
118
|
.command('create-account')
|
|
109
|
-
.description(
|
|
119
|
+
.description(
|
|
120
|
+
'Creates an aztec account that can be used for sending transactions. Registers the account on the RPC server and deploys an account contract. Uses a Schnorr single-key account which uses the same key for encryption and authentication (not secure for production usage).',
|
|
121
|
+
)
|
|
122
|
+
.summary('Creates an aztec account that can be used for sending transactions.')
|
|
110
123
|
.option(
|
|
111
124
|
'-k, --private-key <string>',
|
|
112
|
-
'Private
|
|
125
|
+
'Private key for note encryption and transaction signing. Uses random by default.',
|
|
113
126
|
PRIVATE_KEY,
|
|
114
127
|
)
|
|
115
128
|
.option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
|
|
116
129
|
.action(async options => {
|
|
117
130
|
const client = createAztecRpcClient(options.rpcUrl);
|
|
118
|
-
const privateKey = options.privateKey
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
);
|
|
130
|
-
log(
|
|
131
|
-
accounts.map((acc, i) =>
|
|
132
|
-
log(`\nAddress: ${acc.toString()}\nPublic Key: ${pubKeysAndPartialAddresses[i][0].toString()}\n`),
|
|
133
|
-
);
|
|
131
|
+
const privateKey = options.privateKey
|
|
132
|
+
? new PrivateKey(Buffer.from(stripLeadingHex(options.privateKey), 'hex'))
|
|
133
|
+
: PrivateKey.random();
|
|
134
|
+
|
|
135
|
+
const account = getSchnorrAccount(client, privateKey, privateKey, accountCreationSalt);
|
|
136
|
+
const wallet = await account.waitDeploy();
|
|
137
|
+
const { address, publicKey, partialAddress } = wallet.getCompleteAddress();
|
|
138
|
+
|
|
139
|
+
log(`\nCreated new account:\n`);
|
|
140
|
+
log(`Address: ${address.toString()}`);
|
|
141
|
+
log(`Public key: ${publicKey.toString()}`);
|
|
142
|
+
if (!options.privateKey) log(`Private key: ${privateKey.toString()}`);
|
|
143
|
+
log(`Partial address: ${partialAddress.toString()}`);
|
|
134
144
|
});
|
|
135
145
|
|
|
136
146
|
program
|
|
137
147
|
.command('deploy')
|
|
138
148
|
.description('Deploys a compiled Noir contract to Aztec.')
|
|
139
|
-
.
|
|
149
|
+
.requiredOption(
|
|
140
150
|
'-c, --contract-abi <file>',
|
|
141
151
|
"A compiled Noir contract's ABI in JSON format or name of a contract ABI exported by @aztec/noir-contracts",
|
|
142
|
-
undefined,
|
|
143
152
|
)
|
|
144
153
|
.option('-a, --args <constructorArgs...>', 'Contract constructor arguments', [])
|
|
145
154
|
.option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
|
|
146
155
|
.option(
|
|
147
156
|
'-k, --public-key <string>',
|
|
148
|
-
'
|
|
149
|
-
PUBLIC_KEY,
|
|
157
|
+
'Optional encryption public key for this address. Set this value only if this contract is expected to receive private notes, which will be encrypted using this public key.',
|
|
150
158
|
)
|
|
159
|
+
.option('-s, --salt <string>', 'Optional deployment salt as a hex string for generating the deployment address.')
|
|
151
160
|
.action(async (options: any) => {
|
|
152
161
|
const contractAbi = await getContractAbi(options.contractAbi, log);
|
|
153
162
|
const constructorAbi = contractAbi.functions.find(({ name }) => name === 'constructor');
|
|
154
163
|
|
|
155
164
|
const client = createAztecRpcClient(options.rpcUrl);
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
} else {
|
|
160
|
-
const accounts = await client.getAccounts();
|
|
161
|
-
if (!accounts) {
|
|
162
|
-
throw new Error('No public key provided or found in Aztec RPC.');
|
|
163
|
-
}
|
|
164
|
-
publicKey = (await client.getPublicKeyAndPartialAddress(accounts[0]))[0];
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
log(`Using Public Key: ${publicKey.toString()}`);
|
|
168
|
-
|
|
169
|
-
const deployer = new ContractDeployer(contractAbi, client);
|
|
165
|
+
const publicKey = options.publicKey ? Point.fromString(options.publicKey) : undefined;
|
|
166
|
+
const salt = options.salt ? Fr.fromBuffer(Buffer.from(stripLeadingHex(options.salt), 'hex')) : undefined;
|
|
167
|
+
const deployer = new ContractDeployer(contractAbi, client, publicKey);
|
|
170
168
|
|
|
171
169
|
const constructor = getAbiFunction(contractAbi, 'constructor');
|
|
170
|
+
if (!constructor) throw new Error(`Constructor not found in contract ABI`);
|
|
172
171
|
if (constructor.parameters.length !== options.args.length) {
|
|
173
|
-
throw Error(
|
|
174
|
-
`Invalid number of args passed
|
|
172
|
+
throw new Error(
|
|
173
|
+
`Invalid number of args passed (expected ${constructor.parameters.length} but got ${options.args.length})`,
|
|
175
174
|
);
|
|
176
175
|
}
|
|
177
176
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
177
|
+
debugLogger(`Input arguments: ${options.args.map((x: any) => `"${x}"`).join(', ')}`);
|
|
178
|
+
const args = encodeArgs(options.args, constructorAbi!.parameters);
|
|
179
|
+
debugLogger(`Encoded arguments: ${args.join(', ')}`);
|
|
180
|
+
const tx = deployer.deploy(...args).send({ contractAddressSalt: salt });
|
|
181
|
+
debugLogger(`Deploy tx sent with hash ${await tx.getTxHash()}`);
|
|
182
|
+
const deployed = await tx.wait();
|
|
183
|
+
log(`\nContract deployed at ${deployed.contractAddress!.toString()}\n`);
|
|
182
184
|
});
|
|
183
185
|
|
|
184
186
|
program
|
|
185
187
|
.command('check-deploy')
|
|
186
188
|
.description('Checks if a contract is deployed to the specified Aztec address.')
|
|
187
|
-
.
|
|
189
|
+
.requiredOption('-ca, --contract-address <address>', 'An Aztec address to check if contract has been deployed to.')
|
|
188
190
|
.option('-u, --rpc-url <url>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
|
|
189
191
|
.action(async options => {
|
|
190
192
|
const client = createAztecRpcClient(options.rpcUrl);
|
|
191
193
|
const address = AztecAddress.fromString(options.contractAddress);
|
|
192
194
|
const isDeployed = await isContractDeployed(client, address);
|
|
193
|
-
log(`\
|
|
195
|
+
if (isDeployed) log(`\nContract found at ${address.toString()}\n`);
|
|
196
|
+
else log(`\nNo contract found at ${address.toString()}\n`);
|
|
194
197
|
});
|
|
195
198
|
|
|
196
199
|
program
|
|
197
200
|
.command('get-tx-receipt')
|
|
198
|
-
.argument('<txHash>', 'A
|
|
201
|
+
.argument('<txHash>', 'A transaction hash to get the receipt for.')
|
|
199
202
|
.description('Gets the receipt for the specified transaction hash.')
|
|
200
203
|
.option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
|
|
201
204
|
.action(async (_txHash, options) => {
|
|
@@ -203,9 +206,9 @@ async function main() {
|
|
|
203
206
|
const txHash = TxHash.fromString(_txHash);
|
|
204
207
|
const receipt = await client.getTxReceipt(txHash);
|
|
205
208
|
if (!receipt) {
|
|
206
|
-
log(`No receipt found for
|
|
209
|
+
log(`No receipt found for transaction hash ${_txHash}`);
|
|
207
210
|
} else {
|
|
208
|
-
log(`\
|
|
211
|
+
log(`\nTransaction receipt: \n${JsonStringify(receipt, true)}\n`);
|
|
209
212
|
}
|
|
210
213
|
});
|
|
211
214
|
|
|
@@ -214,7 +217,7 @@ async function main() {
|
|
|
214
217
|
.description('Gets information about the Aztec contract deployed at the specified address.')
|
|
215
218
|
.argument('<contractAddress>', 'Aztec address of the contract.')
|
|
216
219
|
.option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
|
|
217
|
-
.option('-b, --include-bytecode', "Include the contract's public function bytecode, if any.")
|
|
220
|
+
.option('-b, --include-bytecode <boolean>', "Include the contract's public function bytecode, if any.", false)
|
|
218
221
|
.action(async (contractAddress, options) => {
|
|
219
222
|
const client = createAztecRpcClient(options.rpcUrl);
|
|
220
223
|
const address = AztecAddress.fromString(contractAddress);
|
|
@@ -234,7 +237,7 @@ async function main() {
|
|
|
234
237
|
contractData = contractDataWithOrWithoutBytecode;
|
|
235
238
|
}
|
|
236
239
|
log(`\nContract Data: \nAddress: ${contractData.contractAddress.toString()}`);
|
|
237
|
-
log(`Portal:
|
|
240
|
+
log(`Portal: ${contractData.portalContractAddress.toString()}`);
|
|
238
241
|
if ('bytecode' in contractDataWithOrWithoutBytecode) {
|
|
239
242
|
log(`Bytecode: ${contractDataWithOrWithoutBytecode.bytecode}`);
|
|
240
243
|
}
|
|
@@ -244,23 +247,18 @@ async function main() {
|
|
|
244
247
|
program
|
|
245
248
|
.command('get-logs')
|
|
246
249
|
.description('Gets all the unencrypted logs from L2 blocks in the range specified.')
|
|
247
|
-
.
|
|
248
|
-
.
|
|
250
|
+
.option('-f, --from <blockNum>', 'Initial block number for getting logs (defaults to 1).')
|
|
251
|
+
.option('-l, --limit <blockCount>', 'How many blocks to fetch (defaults to 100).')
|
|
249
252
|
.option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
|
|
250
|
-
.action(async
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
limit = parseInt(_take);
|
|
256
|
-
} catch {
|
|
257
|
-
log(`Invalid integer value(s) passed: ${_from}, ${_take}`);
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
253
|
+
.action(async options => {
|
|
254
|
+
const { from, limit } = options;
|
|
255
|
+
const fromBlock = from ? parseInt(from) : 1;
|
|
256
|
+
const limitCount = limit ? parseInt(limit) : 100;
|
|
257
|
+
|
|
260
258
|
const client = createAztecRpcClient(options.rpcUrl);
|
|
261
|
-
const logs = await client.getUnencryptedLogs(
|
|
259
|
+
const logs = await client.getUnencryptedLogs(fromBlock, limitCount);
|
|
262
260
|
if (!logs.length) {
|
|
263
|
-
log(`No logs found in blocks ${
|
|
261
|
+
log(`No logs found in blocks ${fromBlock} to ${fromBlock + limitCount}`);
|
|
264
262
|
} else {
|
|
265
263
|
log('Logs found: \n');
|
|
266
264
|
L2BlockL2Logs.unrollLogs(logs).forEach(fnLog => log(`${fnLog.toString('ascii')}\n`));
|
|
@@ -268,11 +266,11 @@ async function main() {
|
|
|
268
266
|
});
|
|
269
267
|
|
|
270
268
|
program
|
|
271
|
-
.command('register-
|
|
272
|
-
.description(
|
|
273
|
-
.
|
|
274
|
-
.
|
|
275
|
-
.
|
|
269
|
+
.command('register-recipient')
|
|
270
|
+
.description('Register a recipient in the Aztec RPC.')
|
|
271
|
+
.requiredOption('-a, --address <aztecAddress>', "The account's Aztec address.")
|
|
272
|
+
.requiredOption('-p, --public-key <publicKey>', 'The account public key.')
|
|
273
|
+
.requiredOption('-pa, --partial-address <partialAddress', 'The partially computed address of the account contract.')
|
|
276
274
|
.option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
|
|
277
275
|
.action(async options => {
|
|
278
276
|
const client = createAztecRpcClient(options.rpcUrl);
|
|
@@ -280,7 +278,7 @@ async function main() {
|
|
|
280
278
|
const publicKey = Point.fromString(options.publicKey);
|
|
281
279
|
const partialAddress = Fr.fromString(options.partialAddress);
|
|
282
280
|
|
|
283
|
-
await client.
|
|
281
|
+
await client.registerRecipient(await CompleteAddress.create(address, publicKey, partialAddress));
|
|
284
282
|
log(`\nRegistered details for Address: ${options.address}\n`);
|
|
285
283
|
});
|
|
286
284
|
|
|
@@ -295,27 +293,60 @@ async function main() {
|
|
|
295
293
|
log('No accounts found.');
|
|
296
294
|
} else {
|
|
297
295
|
log(`Accounts found: \n`);
|
|
298
|
-
for (const
|
|
299
|
-
|
|
300
|
-
log(`Address: ${address}\nPublic Key: ${pk.toString()}\nPartial Address: ${partialAddress.toString()}\n`);
|
|
296
|
+
for (const account of accounts) {
|
|
297
|
+
log(account.toReadableString());
|
|
301
298
|
}
|
|
302
299
|
}
|
|
303
300
|
});
|
|
304
301
|
|
|
305
302
|
program
|
|
306
|
-
.command('get-account
|
|
307
|
-
.description(
|
|
308
|
-
.argument('<address>', 'The Aztec address to get
|
|
303
|
+
.command('get-account')
|
|
304
|
+
.description('Gets an account given its Aztec address.')
|
|
305
|
+
.argument('<address>', 'The Aztec address to get account for')
|
|
309
306
|
.option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
|
|
310
307
|
.action(async (_address, options) => {
|
|
311
308
|
const client = createAztecRpcClient(options.rpcUrl);
|
|
312
309
|
const address = AztecAddress.fromString(_address);
|
|
313
|
-
const
|
|
310
|
+
const account = await client.getAccount(address);
|
|
314
311
|
|
|
315
|
-
if (!
|
|
312
|
+
if (!account) {
|
|
316
313
|
log(`Unknown account ${_address}`);
|
|
317
314
|
} else {
|
|
318
|
-
log(
|
|
315
|
+
log(account.toReadableString());
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
program
|
|
320
|
+
.command('get-recipients')
|
|
321
|
+
.description('Gets all the recipients stored in the Aztec RPC.')
|
|
322
|
+
.option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
|
|
323
|
+
.action(async (options: any) => {
|
|
324
|
+
const client = createAztecRpcClient(options.rpcUrl);
|
|
325
|
+
const recipients = await client.getRecipients();
|
|
326
|
+
if (!recipients.length) {
|
|
327
|
+
log('No recipients found.');
|
|
328
|
+
} else {
|
|
329
|
+
log(`Recipients found: \n`);
|
|
330
|
+
for (const recipient of recipients) {
|
|
331
|
+
log(recipient.toReadableString());
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
program
|
|
337
|
+
.command('get-recipient')
|
|
338
|
+
.description('Gets a recipient given its Aztec address.')
|
|
339
|
+
.argument('<address>', 'The Aztec address to get recipient for')
|
|
340
|
+
.option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
|
|
341
|
+
.action(async (_address, options) => {
|
|
342
|
+
const client = createAztecRpcClient(options.rpcUrl);
|
|
343
|
+
const address = AztecAddress.fromString(_address);
|
|
344
|
+
const recipient = await client.getRecipient(address);
|
|
345
|
+
|
|
346
|
+
if (!recipient) {
|
|
347
|
+
log(`Unknown recipient ${_address}`);
|
|
348
|
+
} else {
|
|
349
|
+
log(recipient.toReadableString());
|
|
319
350
|
}
|
|
320
351
|
});
|
|
321
352
|
|
|
@@ -324,12 +355,11 @@ async function main() {
|
|
|
324
355
|
.description('Calls a function on an Aztec contract.')
|
|
325
356
|
.argument('<functionName>', 'Name of Function to view')
|
|
326
357
|
.option('-a, --args [functionArgs...]', 'Function arguments', [])
|
|
327
|
-
.
|
|
358
|
+
.requiredOption(
|
|
328
359
|
'-c, --contract-abi <fileLocation>',
|
|
329
360
|
"A compiled Noir contract's ABI in JSON format or name of a contract ABI exported by @aztec/noir-contracts",
|
|
330
|
-
undefined,
|
|
331
361
|
)
|
|
332
|
-
.
|
|
362
|
+
.requiredOption('-ca, --contract-address <address>', 'Aztec address of the contract.')
|
|
333
363
|
.option('-k, --private-key <string>', "The sender's private key.", PRIVATE_KEY)
|
|
334
364
|
.option('-u, --rpcUrl <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
|
|
335
365
|
|
|
@@ -349,22 +379,25 @@ async function main() {
|
|
|
349
379
|
);
|
|
350
380
|
}
|
|
351
381
|
|
|
382
|
+
const privateKey = new PrivateKey(Buffer.from(stripLeadingHex(options.privateKey), 'hex'));
|
|
383
|
+
|
|
352
384
|
const client = createAztecRpcClient(options.rpcUrl);
|
|
353
|
-
const wallet = await
|
|
385
|
+
const wallet = await getAccountWallets(
|
|
354
386
|
client,
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
387
|
+
SchnorrAccountContractAbi,
|
|
388
|
+
[privateKey],
|
|
389
|
+
[privateKey],
|
|
390
|
+
[accountCreationSalt],
|
|
358
391
|
);
|
|
359
|
-
const contract = await Contract.
|
|
392
|
+
const contract = await Contract.at(contractAddress, contractAbi, wallet);
|
|
360
393
|
const tx = contract.methods[functionName](...functionArgs).send();
|
|
361
394
|
await tx.isMined();
|
|
362
|
-
log('\
|
|
395
|
+
log('\nTransaction has been mined');
|
|
363
396
|
const receipt = await tx.getReceipt();
|
|
364
|
-
log(`
|
|
365
|
-
log(`
|
|
366
|
-
log(`Block
|
|
367
|
-
log(`
|
|
397
|
+
log(`Transaction hash: ${(await tx.getTxHash()).toString()}`);
|
|
398
|
+
log(`Status: ${receipt.status}\n`);
|
|
399
|
+
log(`Block number: ${receipt.blockNumber}`);
|
|
400
|
+
log(`Block hash: ${receipt.blockHash?.toString('hex')}`);
|
|
368
401
|
});
|
|
369
402
|
|
|
370
403
|
program
|
|
@@ -374,12 +407,11 @@ async function main() {
|
|
|
374
407
|
)
|
|
375
408
|
.argument('<functionName>', 'Name of Function to view')
|
|
376
409
|
.option('-a, --args [functionArgs...]', 'Function arguments', [])
|
|
377
|
-
.
|
|
410
|
+
.requiredOption(
|
|
378
411
|
'-c, --contract-abi <fileLocation>',
|
|
379
412
|
"A compiled Noir contract's ABI in JSON format or name of a contract ABI exported by @aztec/noir-contracts",
|
|
380
|
-
undefined,
|
|
381
413
|
)
|
|
382
|
-
.
|
|
414
|
+
.requiredOption('-ca, --contract-address <address>', 'Aztec address of the contract.')
|
|
383
415
|
.option('-f, --from <string>', 'Public key of the TX viewer. If empty, will try to find account in RPC.')
|
|
384
416
|
.option('-u, --rpcUrl <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
|
|
385
417
|
.action(async (functionName, options) => {
|
|
@@ -399,7 +431,7 @@ async function main() {
|
|
|
399
431
|
const client = createAztecRpcClient(options.rpcUrl);
|
|
400
432
|
const from = await getTxSender(client, options.from);
|
|
401
433
|
const result = await client.viewTx(functionName, functionArgs, contractAddress, from);
|
|
402
|
-
log('\nView
|
|
434
|
+
log('\nView result: ', JsonStringify(result, true), '\n');
|
|
403
435
|
});
|
|
404
436
|
|
|
405
437
|
// Helper for users to decode hex strings into structs if needed
|
|
@@ -407,12 +439,11 @@ async function main() {
|
|
|
407
439
|
.command('parse-parameter-struct')
|
|
408
440
|
.description("Helper for parsing an encoded string into a contract's parameter struct.")
|
|
409
441
|
.argument('<encodedString>', 'The encoded hex string')
|
|
410
|
-
.
|
|
442
|
+
.requiredOption(
|
|
411
443
|
'-c, --contract-abi <fileLocation>',
|
|
412
444
|
"A compiled Noir contract's ABI in JSON format or name of a contract ABI exported by @aztec/noir-contracts",
|
|
413
|
-
undefined,
|
|
414
445
|
)
|
|
415
|
-
.
|
|
446
|
+
.requiredOption('-p, --parameter <parameterName>', 'The name of the struct parameter to decode into')
|
|
416
447
|
.action(async (encodedString, options) => {
|
|
417
448
|
const contractAbi = await getContractAbi(options.contractAbi, log);
|
|
418
449
|
const parameterAbitype = contractAbi.functions
|
|
@@ -446,10 +477,7 @@ async function main() {
|
|
|
446
477
|
names.forEach(name => log(name));
|
|
447
478
|
});
|
|
448
479
|
|
|
449
|
-
|
|
450
|
-
}
|
|
480
|
+
compileContract(program, 'compile', log);
|
|
451
481
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
process.exit(1);
|
|
455
|
-
});
|
|
482
|
+
return program;
|
|
483
|
+
}
|
package/src/utils.ts
CHANGED
|
@@ -6,10 +6,10 @@ import { DebugLogger, LogFn } from '@aztec/foundation/log';
|
|
|
6
6
|
import fs from 'fs';
|
|
7
7
|
import { mnemonicToAccount, privateKeyToAccount } from 'viem/accounts';
|
|
8
8
|
|
|
9
|
-
import { encodeArgs } from './
|
|
9
|
+
import { encodeArgs } from './encoding.js';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* Helper type to dynamically import
|
|
12
|
+
* Helper type to dynamically import contracts.
|
|
13
13
|
*/
|
|
14
14
|
interface ArtifactsType {
|
|
15
15
|
[key: string]: ContractAbi;
|
|
@@ -105,9 +105,9 @@ export async function getTxSender(client: AztecRPC, _from?: string) {
|
|
|
105
105
|
} else {
|
|
106
106
|
const accounts = await client.getAccounts();
|
|
107
107
|
if (!accounts.length) {
|
|
108
|
-
throw new Error('No accounts found in Aztec RPC
|
|
108
|
+
throw new Error('No accounts found in Aztec RPC instance.');
|
|
109
109
|
}
|
|
110
|
-
from = accounts[0];
|
|
110
|
+
from = accounts[0].address;
|
|
111
111
|
}
|
|
112
112
|
return from;
|
|
113
113
|
}
|
package/tsconfig.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli_encoder.d.ts","sourceRoot":"","sources":["../src/cli_encoder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAW,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAE1E;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,OAcjE;AA8CD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,SAO7D"}
|
package/dest/cli_encoder.js
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { Fr } from '@aztec/aztec.js';
|
|
2
|
-
/**
|
|
3
|
-
* Parses a hex string into an ABI struct type.
|
|
4
|
-
* @param str - The encoded hex string.
|
|
5
|
-
* @param abiType - The ABI Struct type.
|
|
6
|
-
* @returns An object in the ABI struct type's format.
|
|
7
|
-
*/
|
|
8
|
-
export function parseStructString(str, abiType) {
|
|
9
|
-
// Assing string bytes to struct fields.
|
|
10
|
-
const buf = Buffer.from(str.replace(/^0x/i, ''), 'hex');
|
|
11
|
-
const struct = {};
|
|
12
|
-
let byteIndex = 0;
|
|
13
|
-
let argIndex = 0;
|
|
14
|
-
while (byteIndex < buf.length) {
|
|
15
|
-
const { name } = abiType.fields[argIndex];
|
|
16
|
-
struct[name] = Fr.fromBuffer(buf.subarray(byteIndex, byteIndex + 32));
|
|
17
|
-
byteIndex += 32;
|
|
18
|
-
argIndex += 1;
|
|
19
|
-
}
|
|
20
|
-
return struct;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Helper function to encode CLI string args to an appropriate JS type.
|
|
24
|
-
* @param arg - The CLI argument.
|
|
25
|
-
* @param abiType - The type as described by the contract's ABI.
|
|
26
|
-
* @returns The encoded argument.
|
|
27
|
-
*/
|
|
28
|
-
function encodeArg(arg, abiType) {
|
|
29
|
-
const { kind } = abiType;
|
|
30
|
-
if (kind === 'field' || kind === 'integer') {
|
|
31
|
-
return BigInt(arg);
|
|
32
|
-
}
|
|
33
|
-
else if (kind === 'boolean') {
|
|
34
|
-
if (arg === 'true')
|
|
35
|
-
return true;
|
|
36
|
-
if (arg === 'false')
|
|
37
|
-
return false;
|
|
38
|
-
}
|
|
39
|
-
else if (kind === 'array') {
|
|
40
|
-
let arr;
|
|
41
|
-
try {
|
|
42
|
-
arr = JSON.parse(arg);
|
|
43
|
-
if (!Array.isArray(arr))
|
|
44
|
-
throw Error();
|
|
45
|
-
for (let i = 0; i < abiType.length; i += 1) {
|
|
46
|
-
return encodeArg(arg[i], abiType.type);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
catch {
|
|
50
|
-
throw new Error(`Unable to parse arg ${arg} as array`);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
else if (kind === 'struct') {
|
|
54
|
-
// check if input is encoded long string
|
|
55
|
-
if (arg.startsWith('0x')) {
|
|
56
|
-
return parseStructString(arg, abiType);
|
|
57
|
-
}
|
|
58
|
-
let obj;
|
|
59
|
-
try {
|
|
60
|
-
obj = JSON.parse(arg);
|
|
61
|
-
if (Array.isArray(obj))
|
|
62
|
-
throw Error();
|
|
63
|
-
const res = [];
|
|
64
|
-
for (const field of abiType.fields) {
|
|
65
|
-
res.push(encodeArg(obj[field.name], field.type));
|
|
66
|
-
}
|
|
67
|
-
return res;
|
|
68
|
-
}
|
|
69
|
-
catch {
|
|
70
|
-
throw new Error(`Unable to parse arg ${arg} as struct`);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Tries to encode function args to their equivalent TS type.
|
|
76
|
-
* @param args - An array of function's / constructor's args.
|
|
77
|
-
* @returns The encoded array.
|
|
78
|
-
*/
|
|
79
|
-
export function encodeArgs(args, params) {
|
|
80
|
-
return args
|
|
81
|
-
.map((arg, index) => {
|
|
82
|
-
const paramType = params[index].type;
|
|
83
|
-
return encodeArg(arg, paramType);
|
|
84
|
-
})
|
|
85
|
-
.flat();
|
|
86
|
-
}
|
|
87
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpX2VuY29kZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY2xpX2VuY29kZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBR3JDOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUFDLEdBQVcsRUFBRSxPQUFtQjtJQUNoRSx3Q0FBd0M7SUFDeEMsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUN4RCxNQUFNLE1BQU0sR0FBUSxFQUFFLENBQUM7SUFDdkIsSUFBSSxTQUFTLEdBQUcsQ0FBQyxDQUFDO0lBQ2xCLElBQUksUUFBUSxHQUFHLENBQUMsQ0FBQztJQUNqQixPQUFPLFNBQVMsR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFO1FBQzdCLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFLFNBQVMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3RFLFNBQVMsSUFBSSxFQUFFLENBQUM7UUFDaEIsUUFBUSxJQUFJLENBQUMsQ0FBQztLQUNmO0lBRUQsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBUyxTQUFTLENBQUMsR0FBVyxFQUFFLE9BQWdCO0lBQzlDLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxPQUFPLENBQUM7SUFDekIsSUFBSSxJQUFJLEtBQUssT0FBTyxJQUFJLElBQUksS0FBSyxTQUFTLEVBQUU7UUFDMUMsT0FBTyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7S0FDcEI7U0FBTSxJQUFJLElBQUksS0FBSyxTQUFTLEVBQUU7UUFDN0IsSUFBSSxHQUFHLEtBQUssTUFBTTtZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQ2hDLElBQUksR0FBRyxLQUFLLE9BQU87WUFBRSxPQUFPLEtBQUssQ0FBQztLQUNuQztTQUFNLElBQUksSUFBSSxLQUFLLE9BQU8sRUFBRTtRQUMzQixJQUFJLEdBQUcsQ0FBQztRQUNSLElBQUk7WUFDRixHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN0QixJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUM7Z0JBQUUsTUFBTSxLQUFLLEVBQUUsQ0FBQztZQUN2QyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUMxQyxPQUFPLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQ3hDO1NBQ0Y7UUFBQyxNQUFNO1lBQ04sTUFBTSxJQUFJLEtBQUssQ0FBQyx1QkFBdUIsR0FBRyxXQUFXLENBQUMsQ0FBQztTQUN4RDtLQUNGO1NBQU0sSUFBSSxJQUFJLEtBQUssUUFBUSxFQUFFO1FBQzVCLHdDQUF3QztRQUN4QyxJQUFJLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDeEIsT0FBTyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUM7U0FDeEM7UUFDRCxJQUFJLEdBQUcsQ0FBQztRQUNSLElBQUk7WUFDRixHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN0QixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDO2dCQUFFLE1BQU0sS0FBSyxFQUFFLENBQUM7WUFDdEMsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDO1lBQ2YsS0FBSyxNQUFNLEtBQUssSUFBSSxPQUFPLENBQUMsTUFBTSxFQUFFO2dCQUNsQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO2FBQ2xEO1lBQ0QsT0FBTyxHQUFHLENBQUM7U0FDWjtRQUFDLE1BQU07WUFDTixNQUFNLElBQUksS0FBSyxDQUFDLHVCQUF1QixHQUFHLFlBQVksQ0FBQyxDQUFDO1NBQ3pEO0tBQ0Y7QUFDSCxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxVQUFVLENBQUMsSUFBVyxFQUFFLE1BQXNCO0lBQzVELE9BQU8sSUFBSTtTQUNSLEdBQUcsQ0FBQyxDQUFDLEdBQVEsRUFBRSxLQUFLLEVBQUUsRUFBRTtRQUN2QixNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ3JDLE9BQU8sU0FBUyxDQUFDLEdBQUcsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUNuQyxDQUFDLENBQUM7U0FDRCxJQUFJLEVBQUUsQ0FBQztBQUNaLENBQUMifQ==
|
|
File without changes
|