@aztec/cli 0.1.0-alpha47 → 0.1.0-alpha48

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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=utils.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.test.d.ts","sourceRoot":"","sources":["../../src/test/utils.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,104 @@
1
+ import { AztecAddress, Fr } from '@aztec/aztec.js';
2
+ import { CompleteAddress } from '@aztec/types';
3
+ import { mock } from 'jest-mock-extended';
4
+ import { encodeArgs } from '../encoding.js';
5
+ import { getTxSender } from '../utils.js';
6
+ import { mockContractAbi } from './mocks.js';
7
+ describe('CLI Utils', () => {
8
+ let client;
9
+ // test values
10
+ const addr1 = AztecAddress.random();
11
+ const addr2 = AztecAddress.random();
12
+ const addr3 = AztecAddress.random();
13
+ const fieldArray = [addr1.toString(), addr2.toString(), addr3.toString()];
14
+ const num = 33;
15
+ const field = Fr.random();
16
+ const struct = {
17
+ subField1: field.toString(),
18
+ subField2: 'true',
19
+ };
20
+ beforeEach(() => {
21
+ client = mock();
22
+ });
23
+ it('Gets a txSender correctly or throw error', async () => {
24
+ // returns a parsed Aztec Address
25
+ const aztecAddress = AztecAddress.random();
26
+ const result = await getTxSender(client, aztecAddress.toString());
27
+ expect(client.getAccounts).toHaveBeenCalledTimes(0);
28
+ expect(result).toEqual(aztecAddress);
29
+ // returns an address found in the aztec client
30
+ const completeAddress = await CompleteAddress.random();
31
+ client.getAccounts.mockResolvedValueOnce([completeAddress]);
32
+ const resultWithoutString = await getTxSender(client);
33
+ expect(client.getAccounts).toHaveBeenCalled();
34
+ expect(resultWithoutString).toEqual(completeAddress.address);
35
+ // throws when invalid parameter passed
36
+ const errorAddr = 'foo';
37
+ await expect((async () => {
38
+ await getTxSender(client, errorAddr);
39
+ })()).rejects.toThrow(`Invalid option 'from' passed: ${errorAddr}`);
40
+ // Throws error when no string is passed & no accounts found in RPC
41
+ client.getAccounts.mockResolvedValueOnce([]);
42
+ await expect((async () => {
43
+ await getTxSender(client);
44
+ })()).rejects.toThrow('No accounts found in Aztec RPC instance.');
45
+ });
46
+ it('Encodes args correctly', () => {
47
+ const args = [addr1.toString(), 'false', num.toString(), `${JSON.stringify(fieldArray)}`, JSON.stringify(struct)];
48
+ const result = encodeArgs(args, mockContractAbi.functions[1].parameters);
49
+ const exp = [
50
+ addr1.toBigInt(),
51
+ false,
52
+ 33n,
53
+ addr1.toBigInt(),
54
+ addr2.toBigInt(),
55
+ addr3.toBigInt(),
56
+ field.toBigInt(),
57
+ true,
58
+ ];
59
+ expect(result).toEqual(exp);
60
+ });
61
+ it('Errors on invalid inputs', () => {
62
+ // invalid number of args
63
+ const args1 = [field.toString(), 'false'];
64
+ expect(() => encodeArgs(args1, mockContractAbi.functions[1].parameters)).toThrow('Invalid number of args provided. Expected: 5, received: 2');
65
+ // invalid array length
66
+ const invalidArray = fieldArray.concat([Fr.random().toString()]);
67
+ const args2 = [
68
+ addr1.toString(),
69
+ 'false',
70
+ num.toString(),
71
+ `${JSON.stringify(invalidArray)}`,
72
+ JSON.stringify(struct),
73
+ ];
74
+ expect(() => encodeArgs(args2, mockContractAbi.functions[1].parameters)).toThrow('Invalid array length passed for arrayParam. Expected 3, received 4.');
75
+ // invalid struct
76
+ const invalidStruct = {
77
+ subField1: Fr.random().toString(),
78
+ };
79
+ const args3 = [
80
+ addr1.toString(),
81
+ 'false',
82
+ num.toString(),
83
+ `${JSON.stringify(fieldArray)}`,
84
+ JSON.stringify(invalidStruct),
85
+ ];
86
+ expect(() => encodeArgs(args3, mockContractAbi.functions[1].parameters)).toThrow('Expected field subField2 not found in struct structParam.');
87
+ // invalid bool
88
+ const args4 = [
89
+ addr1.toString(),
90
+ 'foo',
91
+ num.toString(),
92
+ `${JSON.stringify(fieldArray)}`,
93
+ JSON.stringify(invalidStruct),
94
+ ];
95
+ expect(() => encodeArgs(args4, mockContractAbi.functions[1].parameters)).toThrow('Invalid boolean value passed for boolParam: foo.');
96
+ // invalid field
97
+ const args5 = ['foo', 'false', num.toString(), `${JSON.stringify(fieldArray)}`, JSON.stringify(invalidStruct)];
98
+ expect(() => encodeArgs(args5, mockContractAbi.functions[1].parameters)).toThrow('Invalid value passed for fieldParam. Could not parse foo as a field.');
99
+ // invalid int
100
+ const args6 = [addr1.toString(), 'false', 'foo', `${JSON.stringify(fieldArray)}`, JSON.stringify(invalidStruct)];
101
+ expect(() => encodeArgs(args6, mockContractAbi.functions[1].parameters)).toThrow('Invalid value passed for integerParam. Could not parse foo as an integer.');
102
+ });
103
+ });
104
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXN0L3V0aWxzLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNuRCxPQUFPLEVBQVksZUFBZSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRXpELE9BQU8sRUFBYSxJQUFJLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVyRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDNUMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUMxQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRTdDLFFBQVEsQ0FBQyxXQUFXLEVBQUUsR0FBRyxFQUFFO0lBQ3pCLElBQUksTUFBMkIsQ0FBQztJQUVoQyxjQUFjO0lBQ2QsTUFBTSxLQUFLLEdBQUcsWUFBWSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ3BDLE1BQU0sS0FBSyxHQUFHLFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUNwQyxNQUFNLEtBQUssR0FBRyxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDcEMsTUFBTSxVQUFVLEdBQUcsQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLEVBQUUsS0FBSyxDQUFDLFFBQVEsRUFBRSxFQUFFLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBQzFFLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQztJQUNmLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUMxQixNQUFNLE1BQU0sR0FBRztRQUNiLFNBQVMsRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFO1FBQzNCLFNBQVMsRUFBRSxNQUFNO0tBQ2xCLENBQUM7SUFDRixVQUFVLENBQUMsR0FBRyxFQUFFO1FBQ2QsTUFBTSxHQUFHLElBQUks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
package/dest/utils.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { AztecAddress, AztecRPC } from '@aztec/aztec.js';
2
2
  import { ContractAbi } from '@aztec/foundation/abi';
3
3
  import { DebugLogger, LogFn } from '@aztec/foundation/log';
4
+ export { createClient } from './client.js';
4
5
  /**
5
6
  * Helper type to dynamically import contracts.
6
7
  */
@@ -55,5 +56,4 @@ export declare function prepTx(contractFile: string, _contractAddress: string, f
55
56
  functionArgs: any[];
56
57
  contractAbi: ContractAbi;
57
58
  }>;
58
- export {};
59
59
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAO3D;;GAEG;AACH,UAAU,aAAa;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,+CAM9D;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,WAAW,wDAKzB;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,2BAGhD;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,wBAuB/D;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,MAAM,yBAgBjE;AAED;;;;;;;;GAQG;AACH,wBAAsB,MAAM,CAC1B,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,MAAM,EACxB,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EAAE,EACvB,GAAG,EAAE,KAAK;;;;GAaX"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAO3D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C;;GAEG;AACH,UAAU,aAAa;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,+CAM9D;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,WAAW,wDAKzB;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,2BAGhD;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,wBAuB/D;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,MAAM,yBAgBjE;AAED;;;;;;;;GAQG;AACH,wBAAsB,MAAM,CAC1B,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,MAAM,EACxB,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EAAE,EACvB,GAAG,EAAE,KAAK;;;;GAaX"}
package/dest/utils.js CHANGED
@@ -3,6 +3,7 @@ import { createEthereumChain, deployL1Contracts } from '@aztec/ethereum';
3
3
  import fs from 'fs';
4
4
  import { mnemonicToAccount, privateKeyToAccount } from 'viem/accounts';
5
5
  import { encodeArgs } from './encoding.js';
6
+ export { createClient } from './client.js';
6
7
  /**
7
8
  * Helper to get an ABI function or throw error if it doesn't exist.
8
9
  * @param abi - Contract's ABI in JSON format.
@@ -113,4 +114,4 @@ export async function prepTx(contractFile, _contractAddress, functionName, _func
113
114
  const functionArgs = encodeArgs(_functionArgs, functionAbi.parameters);
114
115
  return { contractAddress, functionArgs, contractAbi };
115
116
  }
116
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBWSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBSXpFLE9BQU8sRUFBRSxNQUFNLElBQUksQ0FBQztBQUNwQixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFdkUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQVMzQzs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxjQUFjLENBQUMsR0FBZ0IsRUFBRSxNQUFjO0lBQzdELE1BQU0sRUFBRSxHQUFHLEdBQUcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsSUFBSSxLQUFLLE1BQU0sQ0FBQyxDQUFDO0lBQzdELElBQUksQ0FBQyxFQUFFLEVBQUU7UUFDUCxNQUFNLEtBQUssQ0FBQyxZQUFZLE1BQU0sNkJBQTZCLENBQUMsQ0FBQztLQUM5RDtJQUNELE9BQU8sRUFBRSxDQUFDO0FBQ1osQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsb0JBQW9CLENBQ3hDLE1BQWMsRUFDZCxNQUFjLEVBQ2QsVUFBa0IsRUFDbEIsUUFBZ0IsRUFDaEIsV0FBd0I7SUFFeEIsTUFBTSxPQUFPLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLFFBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLFVBQVUsRUFBRSxDQUFDLENBQUM7SUFDcEcsTUFBTSxLQUFLLEdBQUcsbUJBQW1CLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ2xELE9BQU8sTUFBTSxp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
117
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBWSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBSXpFLE9BQU8sRUFBRSxNQUFNLElBQUksQ0FBQztBQUNwQixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFdkUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUzQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBUTNDOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FBQyxHQUFnQixFQUFFLE1BQWM7SUFDN0QsTUFBTSxFQUFFLEdBQUcsR0FBRyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUFDLENBQUM7SUFDN0QsSUFBSSxDQUFDLEVBQUUsRUFBRTtRQUNQLE1BQU0sS0FBSyxDQUFDLFlBQVksTUFBTSw2QkFBNkIsQ0FBQyxDQUFDO0tBQzlEO0lBQ0QsT0FBTyxFQUFFLENBQUM7QUFDWixDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxvQkFBb0IsQ0FDeEMsTUFBYyxFQUNkLE1BQWMsRUFDZCxVQUFrQixFQUNsQixRQUFnQixFQUNoQixXQUF3QjtJQUV4QixNQUFNLE9BQU8sR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsUUFBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLEtBQUssVUFBVSxFQUFFLENBQUMsQ0FBQztJQUNwRyxNQUFNLEtBQUssR0FBRyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDbEQsT0FBTyxNQUFNLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLEtBQUssQ0FBQyxTQUFTLEVBQUUsV0FBVyxDQUFDLENBQUM7QUFDdEYsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsMkJBQTJCO0lBQy9DLE1BQU0sU0FBUyxHQUFrQixNQUFNLE1BQU0sQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO0lBQ2pGLE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxjQUFjLENBQUMsT0FBZSxFQUFFLEdBQVU7SUFDOUQsK0NBQStDO0lBQy9DLElBQUksUUFBZ0IsQ0FBQztJQUNyQixNQUFNLFNBQVMsR0FBRyxNQUFNLDJCQUEyQixFQUFFLENBQUM7SUFDdEQsSUFBSSxTQUFTLENBQUMsT0FBTyxDQUFDLEVBQUU7UUFDdEIsT0FBTyxTQUFTLENBQUMsT0FBTyxDQUFnQixDQUFDO0tBQzFDO0lBRUQsSUFBSTtRQUNGLFFBQVEsR0FBRyxFQUFFLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztLQUM3QztJQUFDLE1BQU07UUFDTixNQUFNLEtBQUssQ0FBQyxZQUFZLE9BQU8sWUFBWSxDQUFDLENBQUM7S0FDOUM7SUFFRCw2Q0FBNkM7SUFDN0MsSUFBSSxXQUF3QixDQUFDO0lBQzdCLElBQUk7UUFDRixXQUFXLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQWdCLENBQUM7S0FDbkQ7SUFBQyxPQUFPLEdBQUcsRUFBRTtRQUNaLEdBQUcsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQzVDLE1BQU0sR0FBRyxDQUFDO0tBQ1g7SUFDRCxPQUFPLFdBQVcsQ0FBQztBQUNyQixDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxXQUFXLENBQUMsTUFBZ0IsRUFBRSxLQUFjO0lBQ2hFLElBQUksSUFBa0IsQ0FBQztJQUN2QixJQUFJLEtBQUssRUFBRTtRQUNULElBQUk7WUFDRixJQUFJLEdBQUcsWUFBWSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUN2QztRQUFDLE1BQU07WUFDTixNQUFNLElBQUksS0FBSyxDQUFDLGlDQUFpQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1NBQzNEO0tBQ0Y7U0FBTTtRQUNMLE1BQU0sUUFBUSxHQUFHLE1BQU0sTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzVDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFO1lBQ3BCLE1BQU0sSUFBSSxLQUFLLENBQUMsMENBQTBDLENBQUMsQ0FBQztTQUM3RDtRQUNELElBQUksR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO0tBQzVCO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLE1BQU0sQ0FDMUIsWUFBb0IsRUFDcEIsZ0JBQXdCLEVBQ3hCLFlBQW9CLEVBQ3BCLGFBQXVCLEVBQ3ZCLEdBQVU7SUFFVixJQUFJLGVBQWUsQ0FBQztJQUNwQixJQUFJO1FBQ0YsZUFBZSxHQUFHLFlBQVksQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztLQUM3RDtJQUFDLE1BQU07UUFDTixNQUFNLElBQUksS0FBSyxDQUFDLG9DQUFvQyxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7S0FDMUU7SUFDRCxNQUFNLFdBQVcsR0FBRyxNQUFNLGNBQWMsQ0FBQyxZQUFZLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDNUQsTUFBTSxXQUFXLEdBQUcsY0FBYyxDQUFDLFdBQVcsRUFBRSxZQUFZLENBQUMsQ0FBQztJQUM5RCxNQUFNLFlBQVksR0FBRyxVQUFVLENBQUMsYUFBYSxFQUFFLFdBQVcsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUV2RSxPQUFPLEVBQUUsZUFBZSxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsQ0FBQztBQUN4RCxDQUFDIn0=
package/package.json CHANGED
@@ -1,16 +1,17 @@
1
1
  {
2
2
  "name": "@aztec/cli",
3
- "version": "0.1.0-alpha47",
3
+ "version": "0.1.0-alpha48",
4
4
  "main": "./dest/index.js",
5
5
  "type": "module",
6
6
  "dependencies": {
7
- "@aztec/aztec.js": "0.1.0-alpha47",
8
- "@aztec/ethereum": "0.1.0-alpha47",
9
- "@aztec/foundation": "0.1.0-alpha47",
10
- "@aztec/noir-compiler": "0.1.0-alpha47",
11
- "@aztec/noir-contracts": "0.1.0-alpha47",
12
- "@aztec/types": "0.1.0-alpha47",
7
+ "@aztec/aztec.js": "0.1.0-alpha48",
8
+ "@aztec/ethereum": "0.1.0-alpha48",
9
+ "@aztec/foundation": "0.1.0-alpha48",
10
+ "@aztec/noir-compiler": "0.1.0-alpha48",
11
+ "@aztec/noir-contracts": "0.1.0-alpha48",
12
+ "@aztec/types": "0.1.0-alpha48",
13
13
  "commander": "^9.0.0",
14
+ "semver": "^7.5.4",
14
15
  "tslib": "^2.4.0",
15
16
  "viem": "^1.2.5"
16
17
  },
@@ -0,0 +1,34 @@
1
+ import { AztecRPC, NodeInfo } from '@aztec/types';
2
+
3
+ import { MockProxy, mock } from 'jest-mock-extended';
4
+
5
+ import { checkServerVersion } from './client.js';
6
+
7
+ describe('client', () => {
8
+ describe('checkServerVersion', () => {
9
+ let rpc: MockProxy<AztecRPC>;
10
+
11
+ beforeEach(() => {
12
+ rpc = mock<AztecRPC>();
13
+ });
14
+
15
+ it('checks versions match', async () => {
16
+ rpc.getNodeInfo.mockResolvedValue({ client: 'rpc@0.1.0-alpha47' } as NodeInfo);
17
+ await checkServerVersion(rpc, '0.1.0-alpha47');
18
+ });
19
+
20
+ it('reports mismatch on older rpc version', async () => {
21
+ rpc.getNodeInfo.mockResolvedValue({ client: 'rpc@0.1.0-alpha47' } as NodeInfo);
22
+ await expect(checkServerVersion(rpc, '0.1.0-alpha48')).rejects.toThrowError(
23
+ /is older than the expected by this CLI/,
24
+ );
25
+ });
26
+
27
+ it('reports mismatch on newer rpc version', async () => {
28
+ rpc.getNodeInfo.mockResolvedValue({ client: 'rpc@0.1.0-alpha48' } as NodeInfo);
29
+ await expect(checkServerVersion(rpc, '0.1.0-alpha47')).rejects.toThrowError(
30
+ /is newer than the expected by this CLI/,
31
+ );
32
+ });
33
+ });
34
+ });
package/src/client.ts CHANGED
@@ -1,5 +1,11 @@
1
- import { createAztecRpcClient } from '@aztec/aztec.js';
1
+ import { AztecRPC, createAztecRpcClient } from '@aztec/aztec.js';
2
2
  import { makeFetch } from '@aztec/foundation/json-rpc/client';
3
+ import { DebugLogger } from '@aztec/foundation/log';
4
+
5
+ import { readFileSync } from 'fs';
6
+ import { dirname, resolve } from 'path';
7
+ import { gtr, ltr, satisfies, valid } from 'semver';
8
+ import { fileURLToPath } from 'url';
3
9
 
4
10
  const retries = [1, 1, 2];
5
11
 
@@ -12,3 +18,61 @@ export function createClient(rpcUrl: string) {
12
18
  const fetch = makeFetch(retries, true);
13
19
  return createAztecRpcClient(rpcUrl, fetch);
14
20
  }
21
+
22
+ /**
23
+ * Creates an Aztec RPC client with a given set of retries on non-server errors.
24
+ * Checks that the RPC server matches the expected version, and warns if not.
25
+ * @param rpcUrl - URL of the RPC server.
26
+ * @param logger - Debug logger to warn version incompatibilities.
27
+ * @returns An RPC client.
28
+ */
29
+ export async function createCompatibleClient(rpcUrl: string, logger: DebugLogger) {
30
+ const client = createClient(rpcUrl);
31
+ const packageJsonPath = resolve(dirname(fileURLToPath(import.meta.url)), '../package.json');
32
+ const packageJsonContents = JSON.parse(readFileSync(packageJsonPath).toString());
33
+ const expectedVersionRange = packageJsonContents.version; // During sandbox, we'll expect exact matches
34
+
35
+ try {
36
+ await checkServerVersion(client, expectedVersionRange, logger);
37
+ } catch (err) {
38
+ if (err instanceof VersionMismatchError) {
39
+ logger.warn(err.message);
40
+ } else {
41
+ throw err;
42
+ }
43
+ }
44
+
45
+ return client;
46
+ }
47
+
48
+ /** Mismatch between server and client versions. */
49
+ class VersionMismatchError extends Error {}
50
+
51
+ /**
52
+ * Checks that the RPC server version matches the expected one by this CLI. Throws if not.
53
+ * @param rpc - RPC server connection.
54
+ * @param expectedVersionRange - Expected version by CLI.
55
+ */
56
+ export async function checkServerVersion(rpc: AztecRPC, expectedVersionRange: string, logger?: DebugLogger) {
57
+ const serverName = 'Aztec Sandbox';
58
+ const { client } = await rpc.getNodeInfo();
59
+ const version = client.split('@')[1];
60
+ logger?.debug(`Comparing server version ${version} against CLI expected ${expectedVersionRange}`);
61
+ if (!version || !valid(version)) {
62
+ throw new VersionMismatchError(`Missing or invalid version identifier for ${serverName} (${version ?? 'empty'}).`);
63
+ } else if (!satisfies(version, expectedVersionRange)) {
64
+ if (gtr(version, expectedVersionRange)) {
65
+ throw new VersionMismatchError(
66
+ `${serverName} is running version ${version} which is newer than the expected by this CLI (${expectedVersionRange}). Consider upgrading your CLI to a newer version.`,
67
+ );
68
+ } else if (ltr(version, expectedVersionRange)) {
69
+ throw new VersionMismatchError(
70
+ `${serverName} is running version ${version} which is older than the expected by this CLI (${expectedVersionRange}). Consider upgrading your ${serverName} to a newer version.`,
71
+ );
72
+ } else {
73
+ throw new VersionMismatchError(
74
+ `${serverName} is running version ${version} which does not match the expected by this CLI (${expectedVersionRange}).`,
75
+ );
76
+ }
77
+ }
78
+ }
package/src/encoding.ts CHANGED
@@ -29,24 +29,37 @@ export function parseStructString(str: string, abiType: StructType) {
29
29
  * @param abiType - The type as described by the contract's ABI.
30
30
  * @returns The encoded argument.
31
31
  */
32
- function encodeArg(arg: string, abiType: ABIType): any {
32
+ function encodeArg(arg: string, abiType: ABIType, name: string): any {
33
33
  const { kind } = abiType;
34
34
  if (kind === 'field' || kind === 'integer') {
35
- return BigInt(arg);
35
+ let res: bigint;
36
+ try {
37
+ res = BigInt(arg);
38
+ } catch (err) {
39
+ throw new Error(
40
+ `Invalid value passed for ${name}. Could not parse ${arg} as a${kind === 'integer' ? 'n' : ''} ${kind}.`,
41
+ );
42
+ }
43
+ return res;
36
44
  } else if (kind === 'boolean') {
37
45
  if (arg === 'true') return true;
38
46
  if (arg === 'false') return false;
47
+ else throw Error(`Invalid boolean value passed for ${name}: ${arg}.`);
39
48
  } else if (kind === 'array') {
40
49
  let arr;
50
+ const res = [];
41
51
  try {
42
52
  arr = JSON.parse(arg);
43
- if (!Array.isArray(arr)) throw Error();
44
- for (let i = 0; i < abiType.length; i += 1) {
45
- return encodeArg(arg[i], abiType.type);
46
- }
47
53
  } catch {
48
- throw new Error(`Unable to parse arg ${arg} as array`);
54
+ throw new Error(`Unable to parse arg ${arg} as array for ${name} parameter`);
55
+ }
56
+ if (!Array.isArray(arr)) throw Error(`Invalid argument ${arg} passed for array parameter ${name}.`);
57
+ if (arr.length !== abiType.length)
58
+ throw Error(`Invalid array length passed for ${name}. Expected ${abiType.length}, received ${arr.length}.`);
59
+ for (let i = 0; i < abiType.length; i += 1) {
60
+ res.push(encodeArg(arr[i], abiType.type, name));
49
61
  }
62
+ return res;
50
63
  } else if (kind === 'struct') {
51
64
  // check if input is encoded long string
52
65
  if (arg.startsWith('0x')) {
@@ -55,15 +68,18 @@ function encodeArg(arg: string, abiType: ABIType): any {
55
68
  let obj;
56
69
  try {
57
70
  obj = JSON.parse(arg);
58
- if (Array.isArray(obj)) throw Error();
59
- const res = [];
60
- for (const field of abiType.fields) {
61
- res.push(encodeArg(obj[field.name], field.type));
62
- }
63
- return res;
64
71
  } catch {
65
72
  throw new Error(`Unable to parse arg ${arg} as struct`);
66
73
  }
74
+ if (Array.isArray(obj)) throw Error(`Array passed for arg ${name}. Expected a struct.`);
75
+ const res = [];
76
+ for (const field of abiType.fields) {
77
+ // Remove field name from list as it's present
78
+ const arg = obj[field.name];
79
+ if (!arg) throw Error(`Expected field ${field.name} not found in struct ${name}.`);
80
+ res.push(encodeArg(obj[field.name], field.type, field.name));
81
+ }
82
+ return res;
67
83
  }
68
84
  }
69
85
 
@@ -73,10 +89,13 @@ function encodeArg(arg: string, abiType: ABIType): any {
73
89
  * @returns The encoded array.
74
90
  */
75
91
  export function encodeArgs(args: any[], params: ABIParameter[]) {
92
+ if (args.length !== params.length) {
93
+ throw new Error(`Invalid number of args provided. Expected: ${params.length}, received: ${args.length}`);
94
+ }
76
95
  return args
77
96
  .map((arg: any, index) => {
78
- const paramType = params[index].type;
79
- return encodeArg(arg, paramType);
97
+ const { type, name } = params[index];
98
+ return encodeArg(arg, type, name);
80
99
  })
81
100
  .flat();
82
101
  }
package/src/index.ts CHANGED
@@ -22,7 +22,7 @@ import { dirname, resolve } from 'path';
22
22
  import { fileURLToPath } from 'url';
23
23
  import { mnemonicToAccount } from 'viem/accounts';
24
24
 
25
- import { createClient } from './client.js';
25
+ import { createCompatibleClient } from './client.js';
26
26
  import { encodeArgs, parseStructString } from './encoding.js';
27
27
  import {
28
28
  deployAztecContracts,
@@ -127,9 +127,9 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
127
127
  )
128
128
  .option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
129
129
  .action(async options => {
130
- const client = createClient(options.rpcUrl);
130
+ const client = await createCompatibleClient(options.rpcUrl, debugLogger);
131
131
  const privateKey = options.privateKey
132
- ? new PrivateKey(Buffer.from(stripLeadingHex(options.privateKey), 'hex'))
132
+ ? PrivateKey.fromString(stripLeadingHex(options.privateKey))
133
133
  : PrivateKey.random();
134
134
 
135
135
  const account = getSchnorrAccount(client, privateKey, privateKey, accountCreationSalt);
@@ -161,7 +161,7 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
161
161
  const contractAbi = await getContractAbi(abiPath, log);
162
162
  const constructorAbi = contractAbi.functions.find(({ name }) => name === 'constructor');
163
163
 
164
- const client = createClient(options.rpcUrl);
164
+ const client = await createCompatibleClient(options.rpcUrl, debugLogger);
165
165
  const publicKey = options.publicKey ? Point.fromString(options.publicKey) : undefined;
166
166
  const salt = options.salt ? Fr.fromBuffer(Buffer.from(stripLeadingHex(options.salt), 'hex')) : undefined;
167
167
  const deployer = new ContractDeployer(contractAbi, client, publicKey);
@@ -189,7 +189,7 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
189
189
  .requiredOption('-ca, --contract-address <address>', 'An Aztec address to check if contract has been deployed to.')
190
190
  .option('-u, --rpc-url <url>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
191
191
  .action(async options => {
192
- const client = createClient(options.rpcUrl);
192
+ const client = await createCompatibleClient(options.rpcUrl, debugLogger);
193
193
  const address = AztecAddress.fromString(options.contractAddress);
194
194
  const isDeployed = await isContractDeployed(client, address);
195
195
  if (isDeployed) log(`\nContract found at ${address.toString()}\n`);
@@ -198,11 +198,11 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
198
198
 
199
199
  program
200
200
  .command('get-tx-receipt')
201
- .argument('<txHash>', 'A transaction hash to get the receipt for.')
202
201
  .description('Gets the receipt for the specified transaction hash.')
202
+ .argument('<txHash>', 'A transaction hash to get the receipt for.')
203
203
  .option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
204
204
  .action(async (_txHash, options) => {
205
- const client = createClient(options.rpcUrl);
205
+ const client = await createCompatibleClient(options.rpcUrl, debugLogger);
206
206
  const txHash = TxHash.fromString(_txHash);
207
207
  const receipt = await client.getTxReceipt(txHash);
208
208
  if (!receipt) {
@@ -219,10 +219,10 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
219
219
  .option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
220
220
  .option('-b, --include-bytecode <boolean>', "Include the contract's public function bytecode, if any.", false)
221
221
  .action(async (contractAddress, options) => {
222
- const client = createClient(options.rpcUrl);
222
+ const client = await createCompatibleClient(options.rpcUrl, debugLogger);
223
223
  const address = AztecAddress.fromString(contractAddress);
224
224
  const contractDataWithOrWithoutBytecode = options.includeBytecode
225
- ? await client.getContractDataAndBytecode(address)
225
+ ? await client.getExtendedContractData(address)
226
226
  : await client.getContractData(address);
227
227
 
228
228
  if (!contractDataWithOrWithoutBytecode) {
@@ -255,7 +255,7 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
255
255
  const fromBlock = from ? parseInt(from) : 1;
256
256
  const limitCount = limit ? parseInt(limit) : 100;
257
257
 
258
- const client = createClient(options.rpcUrl);
258
+ const client = await createCompatibleClient(options.rpcUrl, debugLogger);
259
259
  const logs = await client.getUnencryptedLogs(fromBlock, limitCount);
260
260
  if (!logs.length) {
261
261
  log(`No logs found in blocks ${fromBlock} to ${fromBlock + limitCount}`);
@@ -273,7 +273,7 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
273
273
  .requiredOption('-pa, --partial-address <partialAddress', 'The partially computed address of the account contract.')
274
274
  .option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
275
275
  .action(async options => {
276
- const client = createClient(options.rpcUrl);
276
+ const client = await createCompatibleClient(options.rpcUrl, debugLogger);
277
277
  const address = AztecAddress.fromString(options.address);
278
278
  const publicKey = Point.fromString(options.publicKey);
279
279
  const partialAddress = Fr.fromString(options.partialAddress);
@@ -287,7 +287,7 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
287
287
  .description('Gets all the Aztec accounts stored in the Aztec RPC.')
288
288
  .option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
289
289
  .action(async (options: any) => {
290
- const client = createClient(options.rpcUrl);
290
+ const client = await createCompatibleClient(options.rpcUrl, debugLogger);
291
291
  const accounts = await client.getAccounts();
292
292
  if (!accounts.length) {
293
293
  log('No accounts found.');
@@ -305,7 +305,7 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
305
305
  .argument('<address>', 'The Aztec address to get account for')
306
306
  .option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
307
307
  .action(async (_address, options) => {
308
- const client = createClient(options.rpcUrl);
308
+ const client = await createCompatibleClient(options.rpcUrl, debugLogger);
309
309
  const address = AztecAddress.fromString(_address);
310
310
  const account = await client.getAccount(address);
311
311
 
@@ -321,7 +321,7 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
321
321
  .description('Gets all the recipients stored in the Aztec RPC.')
322
322
  .option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
323
323
  .action(async (options: any) => {
324
- const client = createClient(options.rpcUrl);
324
+ const client = await createCompatibleClient(options.rpcUrl, debugLogger);
325
325
  const recipients = await client.getRecipients();
326
326
  if (!recipients.length) {
327
327
  log('No recipients found.');
@@ -339,7 +339,7 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
339
339
  .argument('<address>', 'The Aztec address to get recipient for')
340
340
  .option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
341
341
  .action(async (_address, options) => {
342
- const client = createClient(options.rpcUrl);
342
+ const client = await createCompatibleClient(options.rpcUrl, debugLogger);
343
343
  const address = AztecAddress.fromString(_address);
344
344
  const recipient = await client.getRecipient(address);
345
345
 
@@ -361,7 +361,7 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
361
361
  )
362
362
  .requiredOption('-ca, --contract-address <address>', 'Aztec address of the contract.')
363
363
  .option('-k, --private-key <string>', "The sender's private key.", PRIVATE_KEY)
364
- .option('-u, --rpcUrl <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
364
+ .option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
365
365
 
366
366
  .action(async (functionName, options) => {
367
367
  const { contractAddress, functionArgs, contractAbi } = await prepTx(
@@ -379,9 +379,9 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
379
379
  );
380
380
  }
381
381
 
382
- const privateKey = new PrivateKey(Buffer.from(stripLeadingHex(options.privateKey), 'hex'));
382
+ const privateKey = PrivateKey.fromString(stripLeadingHex(options.privateKey));
383
383
 
384
- const client = createClient(options.rpcUrl);
384
+ const client = await createCompatibleClient(options.rpcUrl, debugLogger);
385
385
  const wallet = await getAccountWallets(
386
386
  client,
387
387
  SchnorrAccountContractAbi,
@@ -391,7 +391,7 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
391
391
  );
392
392
  const contract = await Contract.at(contractAddress, contractAbi, wallet);
393
393
  const tx = contract.methods[functionName](...functionArgs).send();
394
- await tx.isMined();
394
+ await tx.wait();
395
395
  log('\nTransaction has been mined');
396
396
  const receipt = await tx.getReceipt();
397
397
  log(`Transaction hash: ${(await tx.getTxHash()).toString()}`);
@@ -413,7 +413,7 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
413
413
  )
414
414
  .requiredOption('-ca, --contract-address <address>', 'Aztec address of the contract.')
415
415
  .option('-f, --from <string>', 'Public key of the TX viewer. If empty, will try to find account in RPC.')
416
- .option('-u, --rpcUrl <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
416
+ .option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
417
417
  .action(async (functionName, options) => {
418
418
  const { contractAddress, functionArgs, contractAbi } = await prepTx(
419
419
  options.contractAbi,
@@ -428,10 +428,10 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
428
428
  `Invalid number of args passed. Expected ${fnAbi.parameters.length}; Received: ${options.args.length}`,
429
429
  );
430
430
  }
431
- const client = createClient(options.rpcUrl);
431
+ const client = await createCompatibleClient(options.rpcUrl, debugLogger);
432
432
  const from = await getTxSender(client, options.from);
433
433
  const result = await client.viewTx(functionName, functionArgs, contractAddress, from);
434
- log('\nView result: ', JsonStringify(result, true), '\n');
434
+ log('\nView result: ', result, '\n');
435
435
  });
436
436
 
437
437
  // Helper for users to decode hex strings into structs if needed
@@ -461,9 +461,9 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command {
461
461
  program
462
462
  .command('block-number')
463
463
  .description('Gets the current Aztec L2 block number.')
464
- .option('-u, --rpcUrl <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
464
+ .option('-u, --rpc-url <string>', 'URL of the Aztec RPC', AZTEC_RPC_HOST || 'http://localhost:8080')
465
465
  .action(async (options: any) => {
466
- const client = createClient(options.rpcUrl);
466
+ const client = await createCompatibleClient(options.rpcUrl, debugLogger);
467
467
  const num = await client.getBlockNumber();
468
468
  log(`${num}\n`);
469
469
  });
@@ -0,0 +1,63 @@
1
+ import { ABIParameterVisibility, ContractAbi, FunctionType } from '@aztec/foundation/abi';
2
+
3
+ export const mockContractAbi: ContractAbi = {
4
+ name: 'MockContract',
5
+ functions: [
6
+ {
7
+ name: 'constructor',
8
+ functionType: FunctionType.SECRET,
9
+ isInternal: false,
10
+ parameters: [
11
+ {
12
+ name: 'constructorParam1',
13
+ type: {
14
+ kind: 'field',
15
+ },
16
+ visibility: ABIParameterVisibility.SECRET,
17
+ },
18
+ ],
19
+ returnTypes: [],
20
+ bytecode: 'constructorBytecode',
21
+ },
22
+ {
23
+ name: 'mockFunction',
24
+ functionType: FunctionType.SECRET,
25
+ isInternal: false,
26
+ parameters: [
27
+ {
28
+ name: 'fieldParam',
29
+ type: { kind: 'field' },
30
+ visibility: ABIParameterVisibility.SECRET,
31
+ },
32
+ {
33
+ name: 'boolParam',
34
+ type: { kind: 'boolean' },
35
+ visibility: ABIParameterVisibility.SECRET,
36
+ },
37
+ {
38
+ name: 'integerParam',
39
+ type: { kind: 'integer', sign: 'signed', width: 32 },
40
+ visibility: ABIParameterVisibility.SECRET,
41
+ },
42
+ {
43
+ name: 'arrayParam',
44
+ type: { kind: 'array', length: 3, type: { kind: 'field' } },
45
+ visibility: ABIParameterVisibility.SECRET,
46
+ },
47
+ {
48
+ name: 'structParam',
49
+ type: {
50
+ kind: 'struct',
51
+ fields: [
52
+ { name: 'subField1', type: { kind: 'field' } },
53
+ { name: 'subField2', type: { kind: 'boolean' } },
54
+ ],
55
+ },
56
+ visibility: ABIParameterVisibility.SECRET,
57
+ },
58
+ ],
59
+ returnTypes: [{ kind: 'boolean' }],
60
+ bytecode: 'mockBytecode',
61
+ },
62
+ ],
63
+ };