@aztec/cli 0.7.10 → 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -19
- package/dest/bin/index.js +0 -0
- package/dest/client.d.ts +9 -15
- package/dest/client.d.ts.map +1 -1
- package/dest/client.js +14 -22
- package/dest/encoding.d.ts.map +1 -1
- package/dest/encoding.js +4 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +134 -106
- package/dest/unbox.d.ts.map +1 -1
- package/dest/unbox.js +40 -11
- package/dest/utils.d.ts +61 -8
- package/dest/utils.d.ts.map +1 -1
- package/dest/utils.js +169 -19
- package/package.json +61 -10
- package/src/client.ts +13 -22
- package/src/encoding.ts +3 -1
- package/src/index.ts +167 -136
- package/src/unbox.ts +45 -10
- package/src/utils.ts +192 -25
- package/.eslintrc.cjs +0 -1
- package/.tsbuildinfo +0 -1
- package/dest/client.test.d.ts +0 -2
- package/dest/client.test.d.ts.map +0 -1
- package/dest/client.test.js +0 -23
- package/dest/test/utils.test.d.ts +0 -2
- package/dest/test/utils.test.d.ts.map +0 -1
- package/dest/test/utils.test.js +0 -104
- package/src/client.test.ts +0 -34
- package/src/test/utils.test.ts +0 -133
- package/tsconfig.json +0 -30
package/src/client.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PXE, createPXEClient } from '@aztec/aztec.js';
|
|
2
2
|
import { DebugLogger } from '@aztec/foundation/log';
|
|
3
3
|
import { fileURLToPath } from '@aztec/foundation/url';
|
|
4
4
|
|
|
@@ -7,51 +7,42 @@ import { dirname, resolve } from 'path';
|
|
|
7
7
|
import { gtr, ltr, satisfies, valid } from 'semver';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* Creates
|
|
11
|
-
*
|
|
12
|
-
* @
|
|
13
|
-
*/
|
|
14
|
-
export function createClient(rpcUrl: string) {
|
|
15
|
-
return createAztecRpcClient(rpcUrl);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Creates an Aztec RPC client with a given set of retries on non-server errors.
|
|
20
|
-
* Checks that the RPC server matches the expected version, and warns if not.
|
|
21
|
-
* @param rpcUrl - URL of the RPC server.
|
|
10
|
+
* Creates a PXE client with a given set of retries on non-server errors.
|
|
11
|
+
* Checks that PXE matches the expected version, and warns if not.
|
|
12
|
+
* @param rpcUrl - URL of the RPC server wrapping the PXE.
|
|
22
13
|
* @param logger - Debug logger to warn version incompatibilities.
|
|
23
|
-
* @returns
|
|
14
|
+
* @returns A PXE client.
|
|
24
15
|
*/
|
|
25
16
|
export async function createCompatibleClient(rpcUrl: string, logger: DebugLogger) {
|
|
26
|
-
const
|
|
17
|
+
const pxe = createPXEClient(rpcUrl);
|
|
27
18
|
const packageJsonPath = resolve(dirname(fileURLToPath(import.meta.url)), '../package.json');
|
|
28
19
|
const packageJsonContents = JSON.parse(readFileSync(packageJsonPath).toString());
|
|
29
20
|
const expectedVersionRange = packageJsonContents.version; // During sandbox, we'll expect exact matches
|
|
30
21
|
|
|
31
22
|
try {
|
|
32
|
-
await checkServerVersion(
|
|
23
|
+
await checkServerVersion(pxe, expectedVersionRange);
|
|
33
24
|
} catch (err) {
|
|
34
25
|
if (err instanceof VersionMismatchError) {
|
|
35
|
-
logger.
|
|
26
|
+
logger.warn(err.message);
|
|
36
27
|
} else {
|
|
37
28
|
throw err;
|
|
38
29
|
}
|
|
39
30
|
}
|
|
40
31
|
|
|
41
|
-
return
|
|
32
|
+
return pxe;
|
|
42
33
|
}
|
|
43
34
|
|
|
44
35
|
/** Mismatch between server and client versions. */
|
|
45
36
|
class VersionMismatchError extends Error {}
|
|
46
37
|
|
|
47
38
|
/**
|
|
48
|
-
* Checks that
|
|
49
|
-
* @param
|
|
39
|
+
* Checks that Private eXecution Environment (PXE) version matches the expected one by this CLI. Throws if not.
|
|
40
|
+
* @param pxe - PXE client.
|
|
50
41
|
* @param expectedVersionRange - Expected version by CLI.
|
|
51
42
|
*/
|
|
52
|
-
export async function checkServerVersion(
|
|
43
|
+
export async function checkServerVersion(pxe: PXE, expectedVersionRange: string) {
|
|
53
44
|
const serverName = 'Aztec Sandbox';
|
|
54
|
-
const { sandboxVersion } = await
|
|
45
|
+
const { sandboxVersion } = await pxe.getNodeInfo();
|
|
55
46
|
if (!sandboxVersion) {
|
|
56
47
|
throw new VersionMismatchError(`Couldn't determine ${serverName} version. You may run into issues.`);
|
|
57
48
|
}
|
package/src/encoding.ts
CHANGED
|
@@ -91,7 +91,9 @@ function encodeArg(arg: string, abiType: ABIType, name: string): any {
|
|
|
91
91
|
export function encodeArgs(args: any[], params: ABIParameter[]) {
|
|
92
92
|
if (args.length !== params.length) {
|
|
93
93
|
throw new Error(
|
|
94
|
-
`Invalid
|
|
94
|
+
`Invalid args provided.\nExpected args: [${params
|
|
95
|
+
.map(param => param.name + ': ' + param.type.kind)
|
|
96
|
+
.join(', ')}]\nReceived args: ${args.join(', ')}`,
|
|
95
97
|
);
|
|
96
98
|
}
|
|
97
99
|
return args.map((arg: any, index) => {
|
package/src/index.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
-
AztecAddress,
|
|
3
2
|
Contract,
|
|
4
3
|
ContractDeployer,
|
|
5
4
|
Fr,
|
|
6
5
|
GrumpkinScalar,
|
|
7
|
-
|
|
6
|
+
NotePreimage,
|
|
8
7
|
generatePublicKey,
|
|
9
8
|
getSchnorrAccount,
|
|
10
9
|
isContractDeployed,
|
|
@@ -14,12 +13,13 @@ import { JsonStringify } from '@aztec/foundation/json-rpc';
|
|
|
14
13
|
import { DebugLogger, LogFn } from '@aztec/foundation/log';
|
|
15
14
|
import { fileURLToPath } from '@aztec/foundation/url';
|
|
16
15
|
import { compileContract, generateNoirInterface, generateTypescriptInterface } from '@aztec/noir-compiler/cli';
|
|
17
|
-
import { CompleteAddress, ContractData, L2BlockL2Logs
|
|
16
|
+
import { CompleteAddress, ContractData, L2BlockL2Logs } from '@aztec/types';
|
|
18
17
|
|
|
19
|
-
import {
|
|
18
|
+
import { createSecp256k1PeerId } from '@libp2p/peer-id-factory';
|
|
19
|
+
import { Command, Option } from 'commander';
|
|
20
20
|
import { readFileSync } from 'fs';
|
|
21
|
-
import startCase from 'lodash.startcase';
|
|
22
21
|
import { dirname, resolve } from 'path';
|
|
22
|
+
import { format } from 'util';
|
|
23
23
|
import { mnemonicToAccount } from 'viem/accounts';
|
|
24
24
|
|
|
25
25
|
import { createCompatibleClient } from './client.js';
|
|
@@ -31,19 +31,20 @@ import {
|
|
|
31
31
|
getContractAbi,
|
|
32
32
|
getExampleContractArtifacts,
|
|
33
33
|
getTxSender,
|
|
34
|
+
parseAztecAddress,
|
|
35
|
+
parseField,
|
|
36
|
+
parseFields,
|
|
37
|
+
parsePartialAddress,
|
|
38
|
+
parsePrivateKey,
|
|
39
|
+
parsePublicKey,
|
|
40
|
+
parseSaltFromHexString,
|
|
41
|
+
parseTxHash,
|
|
34
42
|
prepTx,
|
|
35
43
|
} from './utils.js';
|
|
36
44
|
|
|
37
45
|
const accountCreationSalt = Fr.ZERO;
|
|
38
46
|
|
|
39
|
-
const
|
|
40
|
-
if (hex.length > 2 && hex.startsWith('0x')) {
|
|
41
|
-
return hex.substring(2);
|
|
42
|
-
}
|
|
43
|
-
return hex;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const { ETHEREUM_HOST, AZTEC_RPC_HOST, PRIVATE_KEY, API_KEY } = process.env;
|
|
47
|
+
const { ETHEREUM_HOST = 'http://localhost:8545', PRIVATE_KEY, API_KEY } = process.env;
|
|
47
48
|
|
|
48
49
|
/**
|
|
49
50
|
* Returns commander program that defines the CLI.
|
|
@@ -59,36 +60,46 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
|
|
|
59
60
|
|
|
60
61
|
program.name('aztec-cli').description('CLI for interacting with Aztec.').version(version);
|
|
61
62
|
|
|
63
|
+
const pxeOption = new Option('-u, --rpc-url <string>', 'URL of the PXE')
|
|
64
|
+
.env('PXE_URL')
|
|
65
|
+
.default('http://localhost:8080')
|
|
66
|
+
.makeOptionMandatory(true);
|
|
67
|
+
|
|
68
|
+
const createPrivateKeyOption = (description: string, mandatory: boolean) =>
|
|
69
|
+
new Option('-k, --private-key <string>', description)
|
|
70
|
+
.env('PRIVATE_KEY')
|
|
71
|
+
.argParser(parsePrivateKey)
|
|
72
|
+
.makeOptionMandatory(mandatory);
|
|
73
|
+
|
|
62
74
|
program
|
|
63
75
|
.command('deploy-l1-contracts')
|
|
64
76
|
.description('Deploys all necessary Ethereum contracts for Aztec.')
|
|
65
|
-
.
|
|
77
|
+
.requiredOption(
|
|
66
78
|
'-u, --rpc-url <string>',
|
|
67
79
|
'Url of the ethereum host. Chain identifiers localhost and testnet can be used',
|
|
68
|
-
ETHEREUM_HOST
|
|
80
|
+
ETHEREUM_HOST,
|
|
69
81
|
)
|
|
70
82
|
.option('-a, --api-key <string>', 'Api key for the ethereum host', API_KEY)
|
|
71
|
-
.
|
|
83
|
+
.requiredOption('-p, --private-key <string>', 'The private key to use for deployment', PRIVATE_KEY)
|
|
72
84
|
.option(
|
|
73
85
|
'-m, --mnemonic <string>',
|
|
74
86
|
'The mnemonic to use in deployment',
|
|
75
87
|
'test test test test test test test test test test test junk',
|
|
76
88
|
)
|
|
77
89
|
.action(async options => {
|
|
78
|
-
const {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
);
|
|
90
|
+
const { l1ContractAddresses } = await deployAztecContracts(
|
|
91
|
+
options.rpcUrl,
|
|
92
|
+
options.apiKey ?? '',
|
|
93
|
+
options.privateKey,
|
|
94
|
+
options.mnemonic,
|
|
95
|
+
debugLogger,
|
|
96
|
+
);
|
|
86
97
|
log('\n');
|
|
87
|
-
log(`Rollup Address: ${rollupAddress.toString()}`);
|
|
88
|
-
log(`Registry Address: ${registryAddress.toString()}`);
|
|
89
|
-
log(`L1 -> L2 Inbox Address: ${inboxAddress.toString()}`);
|
|
90
|
-
log(`L2 -> L1 Outbox address: ${outboxAddress.toString()}`);
|
|
91
|
-
log(`Contract Deployment Emitter Address: ${contractDeploymentEmitterAddress.toString()}`);
|
|
98
|
+
log(`Rollup Address: ${l1ContractAddresses.rollupAddress.toString()}`);
|
|
99
|
+
log(`Registry Address: ${l1ContractAddresses.registryAddress.toString()}`);
|
|
100
|
+
log(`L1 -> L2 Inbox Address: ${l1ContractAddresses.inboxAddress.toString()}`);
|
|
101
|
+
log(`L2 -> L1 Outbox address: ${l1ContractAddresses.outboxAddress.toString()}`);
|
|
102
|
+
log(`Contract Deployment Emitter Address: ${l1ContractAddresses.contractDeploymentEmitterAddress.toString()}`);
|
|
92
103
|
log('\n');
|
|
93
104
|
});
|
|
94
105
|
|
|
@@ -118,23 +129,30 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
|
|
|
118
129
|
log(`\nPrivate Key: ${privKey}\nPublic Key: ${publicKey.toString()}\n`);
|
|
119
130
|
});
|
|
120
131
|
|
|
132
|
+
program
|
|
133
|
+
.command('generate-p2p-private-key')
|
|
134
|
+
.summary('Generates a LibP2P peer private key.')
|
|
135
|
+
.description('Generates a private key that can be used for running a node on a LibP2P network.')
|
|
136
|
+
.action(async () => {
|
|
137
|
+
const peerId = await createSecp256k1PeerId();
|
|
138
|
+
const exportedPeerId = Buffer.from(peerId.privateKey!).toString('hex');
|
|
139
|
+
log(`Private key: ${exportedPeerId}`);
|
|
140
|
+
log(`Peer Id: ${peerId}`);
|
|
141
|
+
});
|
|
142
|
+
|
|
121
143
|
program
|
|
122
144
|
.command('create-account')
|
|
123
145
|
.description(
|
|
124
|
-
'Creates an aztec account that can be used for sending transactions. Registers the account on the
|
|
146
|
+
'Creates an aztec account that can be used for sending transactions. Registers the account on the PXE 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).',
|
|
125
147
|
)
|
|
126
148
|
.summary('Creates an aztec account that can be used for sending transactions.')
|
|
127
|
-
.
|
|
128
|
-
'
|
|
129
|
-
'Private key for note encryption and transaction signing. Uses random by default.',
|
|
130
|
-
PRIVATE_KEY,
|
|
149
|
+
.addOption(
|
|
150
|
+
createPrivateKeyOption('Private key for note encryption and transaction signing. Uses random by default.', false),
|
|
131
151
|
)
|
|
132
|
-
.
|
|
152
|
+
.addOption(pxeOption)
|
|
133
153
|
.action(async options => {
|
|
134
154
|
const client = await createCompatibleClient(options.rpcUrl, debugLogger);
|
|
135
|
-
const privateKey = options.privateKey
|
|
136
|
-
? GrumpkinScalar.fromString(stripLeadingHex(options.privateKey))
|
|
137
|
-
: GrumpkinScalar.random();
|
|
155
|
+
const privateKey = options.privateKey ?? GrumpkinScalar.random();
|
|
138
156
|
|
|
139
157
|
const account = getSchnorrAccount(client, privateKey, privateKey, accountCreationSalt);
|
|
140
158
|
const wallet = await account.waitDeploy();
|
|
@@ -155,46 +173,57 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
|
|
|
155
173
|
"A compiled Aztec.nr contract's ABI in JSON format or name of a contract ABI exported by @aztec/noir-contracts",
|
|
156
174
|
)
|
|
157
175
|
.option('-a, --args <constructorArgs...>', 'Contract constructor arguments', [])
|
|
158
|
-
.
|
|
176
|
+
.addOption(pxeOption)
|
|
159
177
|
.option(
|
|
160
178
|
'-k, --public-key <string>',
|
|
161
179
|
'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.',
|
|
180
|
+
parsePublicKey,
|
|
162
181
|
)
|
|
163
|
-
.option(
|
|
164
|
-
|
|
182
|
+
.option(
|
|
183
|
+
'-s, --salt <hex string>',
|
|
184
|
+
'Optional deployment salt as a hex string for generating the deployment address.',
|
|
185
|
+
parseSaltFromHexString,
|
|
186
|
+
)
|
|
187
|
+
// `options.wait` is default true. Passing `--no-wait` will set it to false.
|
|
188
|
+
// https://github.com/tj/commander.js#other-option-types-negatable-boolean-and-booleanvalue
|
|
189
|
+
.option('--no-wait', 'Skip waiting for the contract to be deployed. Print the hash of deployment transaction')
|
|
190
|
+
.action(async (abiPath, { rpcUrl, publicKey, args: rawArgs, salt, wait }) => {
|
|
165
191
|
const contractAbi = await getContractAbi(abiPath, log);
|
|
166
192
|
const constructorAbi = contractAbi.functions.find(({ name }) => name === 'constructor');
|
|
167
193
|
|
|
168
|
-
const client = await createCompatibleClient(
|
|
169
|
-
const publicKey = options.publicKey ? Point.fromString(options.publicKey) : undefined;
|
|
170
|
-
const salt = options.salt ? Fr.fromBuffer(Buffer.from(stripLeadingHex(options.salt), 'hex')) : undefined;
|
|
194
|
+
const client = await createCompatibleClient(rpcUrl, debugLogger);
|
|
171
195
|
const deployer = new ContractDeployer(contractAbi, client, publicKey);
|
|
172
196
|
|
|
173
197
|
const constructor = getAbiFunction(contractAbi, 'constructor');
|
|
174
198
|
if (!constructor) throw new Error(`Constructor not found in contract ABI`);
|
|
175
|
-
if (constructor.parameters.length !== options.args.length) {
|
|
176
|
-
throw new Error(
|
|
177
|
-
`Invalid number of args passed (expected ${constructor.parameters.length} but got ${options.args.length})`,
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
199
|
|
|
181
|
-
debugLogger(`Input arguments: ${
|
|
182
|
-
const args = encodeArgs(
|
|
200
|
+
debugLogger(`Input arguments: ${rawArgs.map((x: any) => `"${x}"`).join(', ')}`);
|
|
201
|
+
const args = encodeArgs(rawArgs, constructorAbi!.parameters);
|
|
183
202
|
debugLogger(`Encoded arguments: ${args.join(', ')}`);
|
|
203
|
+
|
|
184
204
|
const tx = deployer.deploy(...args).send({ contractAddressSalt: salt });
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
205
|
+
const txHash = await tx.getTxHash();
|
|
206
|
+
debugLogger(`Deploy tx sent with hash ${txHash}`);
|
|
207
|
+
if (wait) {
|
|
208
|
+
const deployed = await tx.wait();
|
|
209
|
+
log(`\nContract deployed at ${deployed.contractAddress!.toString()}\n`);
|
|
210
|
+
} else {
|
|
211
|
+
log(`\nDeployment transaction hash: ${txHash}\n`);
|
|
212
|
+
}
|
|
188
213
|
});
|
|
189
214
|
|
|
190
215
|
program
|
|
191
216
|
.command('check-deploy')
|
|
192
217
|
.description('Checks if a contract is deployed to the specified Aztec address.')
|
|
193
|
-
.requiredOption(
|
|
194
|
-
|
|
218
|
+
.requiredOption(
|
|
219
|
+
'-ca, --contract-address <address>',
|
|
220
|
+
'An Aztec address to check if contract has been deployed to.',
|
|
221
|
+
parseAztecAddress,
|
|
222
|
+
)
|
|
223
|
+
.addOption(pxeOption)
|
|
195
224
|
.action(async options => {
|
|
196
225
|
const client = await createCompatibleClient(options.rpcUrl, debugLogger);
|
|
197
|
-
const address =
|
|
226
|
+
const address = options.contractAddress;
|
|
198
227
|
const isDeployed = await isContractDeployed(client, address);
|
|
199
228
|
if (isDeployed) log(`\nContract found at ${address.toString()}\n`);
|
|
200
229
|
else log(`\nNo contract found at ${address.toString()}\n`);
|
|
@@ -203,14 +232,13 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
|
|
|
203
232
|
program
|
|
204
233
|
.command('get-tx-receipt')
|
|
205
234
|
.description('Gets the receipt for the specified transaction hash.')
|
|
206
|
-
.argument('<txHash>', 'A transaction hash to get the receipt for.')
|
|
207
|
-
.
|
|
208
|
-
.action(async (
|
|
235
|
+
.argument('<txHash>', 'A transaction hash to get the receipt for.', parseTxHash)
|
|
236
|
+
.addOption(pxeOption)
|
|
237
|
+
.action(async (txHash, options) => {
|
|
209
238
|
const client = await createCompatibleClient(options.rpcUrl, debugLogger);
|
|
210
|
-
const txHash = TxHash.fromString(_txHash);
|
|
211
239
|
const receipt = await client.getTxReceipt(txHash);
|
|
212
240
|
if (!receipt) {
|
|
213
|
-
log(`No receipt found for transaction hash ${
|
|
241
|
+
log(`No receipt found for transaction hash ${txHash.toString()}`);
|
|
214
242
|
} else {
|
|
215
243
|
log(`\nTransaction receipt: \n${JsonStringify(receipt, true)}\n`);
|
|
216
244
|
}
|
|
@@ -219,15 +247,14 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
|
|
|
219
247
|
program
|
|
220
248
|
.command('get-contract-data')
|
|
221
249
|
.description('Gets information about the Aztec contract deployed at the specified address.')
|
|
222
|
-
.argument('<contractAddress>', 'Aztec address of the contract.')
|
|
223
|
-
.
|
|
250
|
+
.argument('<contractAddress>', 'Aztec address of the contract.', parseAztecAddress)
|
|
251
|
+
.addOption(pxeOption)
|
|
224
252
|
.option('-b, --include-bytecode <boolean>', "Include the contract's public function bytecode, if any.", false)
|
|
225
253
|
.action(async (contractAddress, options) => {
|
|
226
254
|
const client = await createCompatibleClient(options.rpcUrl, debugLogger);
|
|
227
|
-
const address = AztecAddress.fromString(contractAddress);
|
|
228
255
|
const contractDataWithOrWithoutBytecode = options.includeBytecode
|
|
229
|
-
? await client.getExtendedContractData(
|
|
230
|
-
: await client.getContractData(
|
|
256
|
+
? await client.getExtendedContractData(contractAddress)
|
|
257
|
+
: await client.getContractData(contractAddress);
|
|
231
258
|
|
|
232
259
|
if (!contractDataWithOrWithoutBytecode) {
|
|
233
260
|
log(`No contract data found at ${contractAddress}`);
|
|
@@ -253,7 +280,7 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
|
|
|
253
280
|
.description('Gets all the unencrypted logs from L2 blocks in the range specified.')
|
|
254
281
|
.option('-f, --from <blockNum>', 'Initial block number for getting logs (defaults to 1).')
|
|
255
282
|
.option('-l, --limit <blockCount>', 'How many blocks to fetch (defaults to 100).')
|
|
256
|
-
.
|
|
283
|
+
.addOption(pxeOption)
|
|
257
284
|
.action(async options => {
|
|
258
285
|
const { from, limit } = options;
|
|
259
286
|
const fromBlock = from ? parseInt(from) : 1;
|
|
@@ -271,25 +298,25 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
|
|
|
271
298
|
|
|
272
299
|
program
|
|
273
300
|
.command('register-recipient')
|
|
274
|
-
.description('Register a recipient in the
|
|
275
|
-
.requiredOption('-a, --address <aztecAddress>', "The account's Aztec address.")
|
|
276
|
-
.requiredOption('-p, --public-key <publicKey>', 'The account public key.')
|
|
277
|
-
.requiredOption(
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
301
|
+
.description('Register a recipient in the PXE.')
|
|
302
|
+
.requiredOption('-a, --address <aztecAddress>', "The account's Aztec address.", parseAztecAddress)
|
|
303
|
+
.requiredOption('-p, --public-key <publicKey>', 'The account public key.', parsePublicKey)
|
|
304
|
+
.requiredOption(
|
|
305
|
+
'-pa, --partial-address <partialAddress>',
|
|
306
|
+
'The partially computed address of the account contract.',
|
|
307
|
+
parsePartialAddress,
|
|
308
|
+
)
|
|
309
|
+
.addOption(pxeOption)
|
|
310
|
+
.action(async ({ address, publicKey, partialAddress, rpcUrl }) => {
|
|
311
|
+
const client = await createCompatibleClient(rpcUrl, debugLogger);
|
|
285
312
|
await client.registerRecipient(await CompleteAddress.create(address, publicKey, partialAddress));
|
|
286
|
-
log(`\nRegistered details for account with address: ${
|
|
313
|
+
log(`\nRegistered details for account with address: ${address}\n`);
|
|
287
314
|
});
|
|
288
315
|
|
|
289
316
|
program
|
|
290
317
|
.command('get-accounts')
|
|
291
|
-
.description('Gets all the Aztec accounts stored in the
|
|
292
|
-
.
|
|
318
|
+
.description('Gets all the Aztec accounts stored in the PXE.')
|
|
319
|
+
.addOption(pxeOption)
|
|
293
320
|
.action(async (options: any) => {
|
|
294
321
|
const client = await createCompatibleClient(options.rpcUrl, debugLogger);
|
|
295
322
|
const accounts = await client.getRegisteredAccounts();
|
|
@@ -306,15 +333,14 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
|
|
|
306
333
|
program
|
|
307
334
|
.command('get-account')
|
|
308
335
|
.description('Gets an account given its Aztec address.')
|
|
309
|
-
.argument('<address>', 'The Aztec address to get account for')
|
|
310
|
-
.
|
|
311
|
-
.action(async (
|
|
336
|
+
.argument('<address>', 'The Aztec address to get account for', parseAztecAddress)
|
|
337
|
+
.addOption(pxeOption)
|
|
338
|
+
.action(async (address, options) => {
|
|
312
339
|
const client = await createCompatibleClient(options.rpcUrl, debugLogger);
|
|
313
|
-
const address = AztecAddress.fromString(_address);
|
|
314
340
|
const account = await client.getRegisteredAccount(address);
|
|
315
341
|
|
|
316
342
|
if (!account) {
|
|
317
|
-
log(`Unknown account ${
|
|
343
|
+
log(`Unknown account ${address.toString()}`);
|
|
318
344
|
} else {
|
|
319
345
|
log(account.toReadableString());
|
|
320
346
|
}
|
|
@@ -322,8 +348,8 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
|
|
|
322
348
|
|
|
323
349
|
program
|
|
324
350
|
.command('get-recipients')
|
|
325
|
-
.description('Gets all the recipients stored in the
|
|
326
|
-
.
|
|
351
|
+
.description('Gets all the recipients stored in the PXE.')
|
|
352
|
+
.addOption(pxeOption)
|
|
327
353
|
.action(async (options: any) => {
|
|
328
354
|
const client = await createCompatibleClient(options.rpcUrl, debugLogger);
|
|
329
355
|
const recipients = await client.getRecipients();
|
|
@@ -340,15 +366,14 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
|
|
|
340
366
|
program
|
|
341
367
|
.command('get-recipient')
|
|
342
368
|
.description('Gets a recipient given its Aztec address.')
|
|
343
|
-
.argument('<address>', 'The Aztec address to get recipient for')
|
|
344
|
-
.
|
|
345
|
-
.action(async (
|
|
369
|
+
.argument('<address>', 'The Aztec address to get recipient for', parseAztecAddress)
|
|
370
|
+
.addOption(pxeOption)
|
|
371
|
+
.action(async (address, options) => {
|
|
346
372
|
const client = await createCompatibleClient(options.rpcUrl, debugLogger);
|
|
347
|
-
const address = AztecAddress.fromString(_address);
|
|
348
373
|
const recipient = await client.getRecipient(address);
|
|
349
374
|
|
|
350
375
|
if (!recipient) {
|
|
351
|
-
log(`Unknown recipient ${
|
|
376
|
+
log(`Unknown recipient ${address.toString()}`);
|
|
352
377
|
} else {
|
|
353
378
|
log(recipient.toReadableString());
|
|
354
379
|
}
|
|
@@ -357,45 +382,37 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
|
|
|
357
382
|
program
|
|
358
383
|
.command('send')
|
|
359
384
|
.description('Calls a function on an Aztec contract.')
|
|
360
|
-
.argument('<functionName>', 'Name of
|
|
385
|
+
.argument('<functionName>', 'Name of function to execute')
|
|
361
386
|
.option('-a, --args [functionArgs...]', 'Function arguments', [])
|
|
362
387
|
.requiredOption(
|
|
363
388
|
'-c, --contract-abi <fileLocation>',
|
|
364
389
|
"A compiled Aztec.nr contract's ABI in JSON format or name of a contract ABI exported by @aztec/noir-contracts",
|
|
365
390
|
)
|
|
366
|
-
.requiredOption('-ca, --contract-address <address>', 'Aztec address of the contract.')
|
|
367
|
-
.
|
|
368
|
-
.
|
|
369
|
-
|
|
391
|
+
.requiredOption('-ca, --contract-address <address>', 'Aztec address of the contract.', parseAztecAddress)
|
|
392
|
+
.addOption(createPrivateKeyOption("The sender's private key.", true))
|
|
393
|
+
.addOption(pxeOption)
|
|
394
|
+
.option('--no-wait', 'Print transaction hash without waiting for it to be mined')
|
|
370
395
|
.action(async (functionName, options) => {
|
|
371
|
-
const {
|
|
372
|
-
|
|
373
|
-
options.contractAddress,
|
|
374
|
-
functionName,
|
|
375
|
-
options.args,
|
|
376
|
-
log,
|
|
377
|
-
);
|
|
378
|
-
|
|
379
|
-
const fnAbi = getAbiFunction(contractAbi, functionName);
|
|
380
|
-
if (fnAbi.parameters.length !== options.args.length) {
|
|
381
|
-
throw Error(
|
|
382
|
-
`Invalid number of args passed. Expected ${fnAbi.parameters.length}; Received: ${options.args.length}`,
|
|
383
|
-
);
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
const privateKey = GrumpkinScalar.fromString(stripLeadingHex(options.privateKey));
|
|
396
|
+
const { functionArgs, contractAbi } = await prepTx(options.contractAbi, functionName, options.args, log);
|
|
397
|
+
const { contractAddress, privateKey } = options;
|
|
387
398
|
|
|
388
399
|
const client = await createCompatibleClient(options.rpcUrl, debugLogger);
|
|
389
400
|
const wallet = await getSchnorrAccount(client, privateKey, privateKey, accountCreationSalt).getWallet();
|
|
390
401
|
const contract = await Contract.at(contractAddress, contractAbi, wallet);
|
|
391
402
|
const tx = contract.methods[functionName](...functionArgs).send();
|
|
392
|
-
await tx.wait();
|
|
393
|
-
log('\nTransaction has been mined');
|
|
394
|
-
const receipt = await tx.getReceipt();
|
|
395
403
|
log(`Transaction hash: ${(await tx.getTxHash()).toString()}`);
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
404
|
+
if (options.wait) {
|
|
405
|
+
await tx.wait();
|
|
406
|
+
|
|
407
|
+
log('Transaction has been mined');
|
|
408
|
+
|
|
409
|
+
const receipt = await tx.getReceipt();
|
|
410
|
+
log(`Status: ${receipt.status}\n`);
|
|
411
|
+
log(`Block number: ${receipt.blockNumber}`);
|
|
412
|
+
log(`Block hash: ${receipt.blockHash?.toString('hex')}`);
|
|
413
|
+
} else {
|
|
414
|
+
log('\nTransaction pending. Check status with get-tx-receipt');
|
|
415
|
+
}
|
|
399
416
|
});
|
|
400
417
|
|
|
401
418
|
program
|
|
@@ -403,23 +420,18 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
|
|
|
403
420
|
.description(
|
|
404
421
|
'Simulates the execution of a view (read-only) function on a deployed contract, without modifying state.',
|
|
405
422
|
)
|
|
406
|
-
.argument('<functionName>', 'Name of
|
|
423
|
+
.argument('<functionName>', 'Name of function to call')
|
|
407
424
|
.option('-a, --args [functionArgs...]', 'Function arguments', [])
|
|
408
425
|
.requiredOption(
|
|
409
426
|
'-c, --contract-abi <fileLocation>',
|
|
410
427
|
"A compiled Aztec.nr contract's ABI in JSON format or name of a contract ABI exported by @aztec/noir-contracts",
|
|
411
428
|
)
|
|
412
|
-
.requiredOption('-ca, --contract-address <address>', 'Aztec address of the contract.')
|
|
429
|
+
.requiredOption('-ca, --contract-address <address>', 'Aztec address of the contract.', parseAztecAddress)
|
|
413
430
|
.option('-f, --from <string>', 'Aztec address of the caller. If empty, will use the first account from RPC.')
|
|
414
|
-
.
|
|
431
|
+
.addOption(pxeOption)
|
|
415
432
|
.action(async (functionName, options) => {
|
|
416
|
-
const {
|
|
417
|
-
|
|
418
|
-
options.contractAddress,
|
|
419
|
-
functionName,
|
|
420
|
-
options.args,
|
|
421
|
-
log,
|
|
422
|
-
);
|
|
433
|
+
const { functionArgs, contractAbi } = await prepTx(options.contractAbi, functionName, options.args, log);
|
|
434
|
+
|
|
423
435
|
const fnAbi = getAbiFunction(contractAbi, functionName);
|
|
424
436
|
if (fnAbi.parameters.length !== options.args.length) {
|
|
425
437
|
throw Error(
|
|
@@ -428,8 +440,23 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
|
|
|
428
440
|
}
|
|
429
441
|
const client = await createCompatibleClient(options.rpcUrl, debugLogger);
|
|
430
442
|
const from = await getTxSender(client, options.from);
|
|
431
|
-
const result = await client.viewTx(functionName, functionArgs, contractAddress, from);
|
|
432
|
-
log('\nView result: ', result, '\n');
|
|
443
|
+
const result = await client.viewTx(functionName, functionArgs, options.contractAddress, from);
|
|
444
|
+
log(format('\nView result: ', result, '\n'));
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
program
|
|
448
|
+
.command('add-note')
|
|
449
|
+
.description('Adds a note to the database in the PXE.')
|
|
450
|
+
.argument('<address>', 'The Aztec address of the note owner.', parseAztecAddress)
|
|
451
|
+
.argument('<contractAddress>', 'Aztec address of the contract.', parseAztecAddress)
|
|
452
|
+
.argument('<storageSlot>', 'The storage slot of the note.', parseField)
|
|
453
|
+
.argument('<txHash>', 'The tx hash of the tx containing the note.', parseTxHash)
|
|
454
|
+
.requiredOption('-p, --preimage [notePreimage...]', 'Note preimage.', [])
|
|
455
|
+
.addOption(pxeOption)
|
|
456
|
+
.action(async (address, contractAddress, storageSlot, txHash, options) => {
|
|
457
|
+
const preimage = new NotePreimage(parseFields(options.preimage));
|
|
458
|
+
const client = await createCompatibleClient(options.rpcUrl, debugLogger);
|
|
459
|
+
await client.addNote(address, contractAddress, storageSlot, preimage, txHash);
|
|
433
460
|
});
|
|
434
461
|
|
|
435
462
|
// Helper for users to decode hex strings into structs if needed.
|
|
@@ -459,7 +486,7 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
|
|
|
459
486
|
program
|
|
460
487
|
.command('block-number')
|
|
461
488
|
.description('Gets the current Aztec L2 block number.')
|
|
462
|
-
.
|
|
489
|
+
.addOption(pxeOption)
|
|
463
490
|
.action(async (options: any) => {
|
|
464
491
|
const client = await createCompatibleClient(options.rpcUrl, debugLogger);
|
|
465
492
|
const num = await client.getBlockNumber();
|
|
@@ -490,12 +517,16 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
|
|
|
490
517
|
program
|
|
491
518
|
.command('get-node-info')
|
|
492
519
|
.description('Gets the information of an aztec node at a URL.')
|
|
493
|
-
.
|
|
520
|
+
.addOption(pxeOption)
|
|
494
521
|
.action(async options => {
|
|
495
522
|
const client = await createCompatibleClient(options.rpcUrl, debugLogger);
|
|
496
523
|
const info = await client.getNodeInfo();
|
|
497
524
|
log(`\nNode Info:\n`);
|
|
498
|
-
|
|
525
|
+
log(`Sandbox Version: ${info.sandboxVersion}\n`);
|
|
526
|
+
log(`Compatible Nargo Version: ${info.compatibleNargoVersion}\n`);
|
|
527
|
+
log(`Chain Id: ${info.chainId}\n`);
|
|
528
|
+
log(`Protocol Version: ${info.protocolVersion}\n`);
|
|
529
|
+
log(`Rollup Address: ${info.l1ContractAddresses.rollupAddress.toString()}`);
|
|
499
530
|
});
|
|
500
531
|
|
|
501
532
|
program
|