@aztec/cli 0.1.0-alpha49 → 0.1.0-alpha57

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.
@@ -0,0 +1,175 @@
1
+ import { AztecAddress } from '@aztec/aztec.js';
2
+ import { DebugLogger } from '@aztec/foundation/log';
3
+ import { AztecRPC, CompleteAddress } from '@aztec/types';
4
+
5
+ import stringArgv from 'string-argv';
6
+ import { format } from 'util';
7
+
8
+ import { getProgram } from '../index.js';
9
+
10
+ const INITIAL_BALANCE = 33000;
11
+ const TRANSFER_BALANCE = 3000;
12
+
13
+ export const cliTestSuite = (
14
+ testName: string,
15
+ aztecRpcSetup: () => Promise<AztecRPC>,
16
+ cleanup: () => Promise<void>,
17
+ rpcUrl: string,
18
+ debug: DebugLogger,
19
+ ) => {
20
+ return describe(testName, () => {
21
+ let cli: ReturnType<typeof getProgram>;
22
+ let aztecRpcClient: AztecRPC;
23
+ let existingAccounts: CompleteAddress[];
24
+ let contractAddress: AztecAddress;
25
+ let log: (...args: any[]) => void;
26
+
27
+ // All logs emitted by the cli will be collected here, and reset between tests
28
+ const logs: string[] = [];
29
+
30
+ beforeAll(async () => {
31
+ aztecRpcClient = await aztecRpcSetup();
32
+ log = (...args: any[]) => {
33
+ logs.push(format(...args));
34
+ debug(...args);
35
+ };
36
+ });
37
+
38
+ afterAll(async () => {
39
+ await cleanup();
40
+ });
41
+
42
+ // in order to run the same command twice, we need to create a new CLI instance
43
+ const resetCli = () => {
44
+ cli = getProgram(log, debug);
45
+ };
46
+
47
+ beforeEach(() => {
48
+ logs.splice(0);
49
+ resetCli();
50
+ });
51
+
52
+ // Run a command on the CLI
53
+ const run = (cmd: string, addRpcUrl = true) => {
54
+ const args = stringArgv(cmd, 'node', 'dest/bin/index.js');
55
+ if (addRpcUrl) {
56
+ args.push('--rpc-url', rpcUrl);
57
+ }
58
+ return cli.parseAsync(args);
59
+ };
60
+
61
+ // Returns first match across all logs collected so far
62
+ const findInLogs = (regex: RegExp) => {
63
+ for (const log of logs) {
64
+ const match = regex.exec(log);
65
+ if (match) return match;
66
+ }
67
+ };
68
+
69
+ const findMultipleInLogs = (regex: RegExp) => {
70
+ const matches = [];
71
+ for (const log of logs) {
72
+ const match = regex.exec(log);
73
+ if (match) matches.push(match);
74
+ }
75
+ return matches;
76
+ };
77
+
78
+ const clearLogs = () => {
79
+ logs.splice(0);
80
+ };
81
+
82
+ it('creates & retrieves an account', async () => {
83
+ existingAccounts = await aztecRpcClient.getAccounts();
84
+ debug('Create an account');
85
+ await run(`create-account`);
86
+ const foundAddress = findInLogs(/Address:\s+(?<address>0x[a-fA-F0-9]+)/)?.groups?.address;
87
+ expect(foundAddress).toBeDefined();
88
+ const newAddress = AztecAddress.fromString(foundAddress!);
89
+
90
+ const accountsAfter = await aztecRpcClient.getAccounts();
91
+ const expectedAccounts = [...existingAccounts.map(a => a.address), newAddress];
92
+ expect(accountsAfter.map(a => a.address)).toEqual(expectedAccounts);
93
+ const newCompleteAddress = accountsAfter[accountsAfter.length - 1];
94
+
95
+ // Test get-accounts
96
+ debug('Check that account was added to the list of accs in RPC');
97
+ await run('get-accounts');
98
+ const fetchedAddresses = findMultipleInLogs(/Address:\s+(?<address>0x[a-fA-F0-9]+)/);
99
+ const foundFetchedAddress = fetchedAddresses.find(match => match.groups?.address === newAddress.toString());
100
+ expect(foundFetchedAddress).toBeDefined();
101
+
102
+ // Test get-account
103
+ debug('Check we can retrieve the specific account');
104
+ clearLogs();
105
+ await run(`get-account ${newAddress.toString()}`);
106
+ const fetchedAddress = findInLogs(/Public Key:\s+(?<address>0x[a-fA-F0-9]+)/)?.groups?.address;
107
+ expect(fetchedAddress).toEqual(newCompleteAddress.publicKey.toString());
108
+ });
109
+
110
+ it('deploys a contract & sends transactions', async () => {
111
+ // generate a private key
112
+ debug('Create an account using a private key');
113
+ await run('generate-private-key', false);
114
+ const privKey = findInLogs(/Private\sKey:\s+(?<privKey>[a-fA-F0-9]+)/)?.groups?.privKey;
115
+ expect(privKey).toHaveLength(64);
116
+ await run(`create-account --private-key ${privKey}`);
117
+ const foundAddress = findInLogs(/Address:\s+(?<address>0x[a-fA-F0-9]+)/)?.groups?.address;
118
+ expect(foundAddress).toBeDefined();
119
+ const ownerAddress = AztecAddress.fromString(foundAddress!);
120
+
121
+ debug('Deploy Private Token Contract using created account.');
122
+ await run(`deploy PrivateTokenContractAbi --args ${INITIAL_BALANCE} ${ownerAddress} --salt 0`);
123
+ const loggedAddress = findInLogs(/Contract\sdeployed\sat\s+(?<address>0x[a-fA-F0-9]+)/)?.groups?.address;
124
+ expect(loggedAddress).toBeDefined();
125
+ contractAddress = AztecAddress.fromString(loggedAddress!);
126
+
127
+ const deployedContract = await aztecRpcClient.getContractData(contractAddress);
128
+ expect(deployedContract?.contractAddress).toEqual(contractAddress);
129
+
130
+ debug('Check contract can be found in returned address');
131
+ await run(`check-deploy -ca ${loggedAddress}`);
132
+ const checkResult = findInLogs(/Contract\sfound\sat\s+(?<address>0x[a-fA-F0-9]+)/)?.groups?.address;
133
+ expect(checkResult).toEqual(deployedContract?.contractAddress.toString());
134
+
135
+ // clear logs
136
+ clearLogs();
137
+ await run(`get-contract-data ${loggedAddress}`);
138
+ const contractDataAddress = findInLogs(/Address:\s+(?<address>0x[a-fA-F0-9]+)/)?.groups?.address;
139
+ expect(contractDataAddress).toEqual(deployedContract?.contractAddress.toString());
140
+
141
+ debug("Check owner's balance");
142
+ await run(
143
+ `call getBalance --args ${ownerAddress} --contract-abi PrivateTokenContractAbi --contract-address ${contractAddress.toString()}`,
144
+ );
145
+ const balance = findInLogs(/View\sresult:\s+(?<data>\S+)/)?.groups?.data;
146
+ expect(balance!).toEqual(`${BigInt(INITIAL_BALANCE).toString()}n`);
147
+
148
+ debug('Transfer some tokens');
149
+ const existingAccounts = await aztecRpcClient.getAccounts();
150
+ // ensure we pick a different acc
151
+ const receiver = existingAccounts.find(acc => acc.address.toString() !== ownerAddress.toString());
152
+
153
+ await run(
154
+ `send transfer --args ${TRANSFER_BALANCE} ${receiver?.address.toString()} --contract-address ${contractAddress.toString()} --contract-abi PrivateTokenContractAbi --private-key ${privKey}`,
155
+ );
156
+ const txHash = findInLogs(/Transaction\shash:\s+(?<txHash>\S+)/)?.groups?.txHash;
157
+
158
+ debug('Check the transfer receipt');
159
+ await run(`get-tx-receipt ${txHash}`);
160
+ const txResult = findInLogs(/Transaction receipt:\s*(?<txHash>[\s\S]*?\})/)?.groups?.txHash;
161
+ const parsedResult = JSON.parse(txResult!);
162
+ expect(parsedResult.txHash).toEqual(txHash);
163
+ expect(parsedResult.status).toEqual('mined');
164
+ debug("Check Receiver's balance");
165
+ // Reset CLI as we're calling getBalance again
166
+ resetCli();
167
+ clearLogs();
168
+ await run(
169
+ `call getBalance --args ${receiver?.address.toString()} --contract-abi PrivateTokenContractAbi --contract-address ${contractAddress.toString()}`,
170
+ );
171
+ const receiverBalance = findInLogs(/View\sresult:\s+(?<data>\S+)/)?.groups?.data;
172
+ expect(receiverBalance).toEqual(`${BigInt(TRANSFER_BALANCE).toString()}n`);
173
+ });
174
+ });
175
+ };