@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.
- package/.tsbuildinfo +1 -1
- package/README.md +2 -2
- package/dest/client.d.ts +17 -1
- package/dest/client.d.ts.map +1 -1
- package/dest/client.js +58 -1
- package/dest/client.test.d.ts +2 -0
- package/dest/client.test.d.ts.map +1 -0
- package/dest/client.test.js +23 -0
- package/dest/encoding.d.ts.map +1 -1
- package/dest/encoding.js +38 -18
- package/dest/index.js +25 -25
- package/dest/test/mocks.d.ts +3 -0
- package/dest/test/mocks.d.ts.map +1 -0
- package/dest/test/mocks.js +63 -0
- package/dest/test/utils.test.d.ts +2 -0
- package/dest/test/utils.test.d.ts.map +1 -0
- package/dest/test/utils.test.js +104 -0
- package/dest/utils.d.ts +1 -1
- package/dest/utils.d.ts.map +1 -1
- package/dest/utils.js +2 -1
- package/package.json +8 -7
- package/src/client.test.ts +34 -0
- package/src/client.ts +65 -1
- package/src/encoding.ts +34 -15
- package/src/index.ts +24 -24
- package/src/test/mocks.ts +63 -0
- package/src/test/utils.test.ts +133 -0
- package/src/utils.ts +1 -0
|
@@ -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
|
package/dest/utils.d.ts.map
CHANGED
|
@@ -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,
|
|
117
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBWSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBSXpFLE9BQU8sRUFBRSxNQUFNLElBQUksQ0FBQztBQUNwQixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFdkUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUzQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBUTNDOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FBQyxHQUFnQixFQUFFLE1BQWM7SUFDN0QsTUFBTSxFQUFFLEdBQUcsR0FBRyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUFDLENBQUM7SUFDN0QsSUFBSSxDQUFDLEVBQUUsRUFBRTtRQUNQLE1BQU0sS0FBSyxDQUFDLFlBQVksTUFBTSw2QkFBNkIsQ0FBQyxDQUFDO0tBQzlEO0lBQ0QsT0FBTyxFQUFFLENBQUM7QUFDWixDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxvQkFBb0IsQ0FDeEMsTUFBYyxFQUNkLE1BQWMsRUFDZCxVQUFrQixFQUNsQixRQUFnQixFQUNoQixXQUF3QjtJQUV4QixNQUFNLE9BQU8sR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsUUFBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLEtBQUssVUFBVSxFQUFFLENBQUMsQ0FBQztJQUNwRyxNQUFNLEtBQUssR0FBRyxtQkFBbUIsQ0FBQyxN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
|
package/package.json
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/cli",
|
|
3
|
-
"version": "0.1.0-
|
|
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-
|
|
8
|
-
"@aztec/ethereum": "0.1.0-
|
|
9
|
-
"@aztec/foundation": "0.1.0-
|
|
10
|
-
"@aztec/noir-compiler": "0.1.0-
|
|
11
|
-
"@aztec/noir-contracts": "0.1.0-
|
|
12
|
-
"@aztec/types": "0.1.0-
|
|
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
|
-
|
|
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
|
|
79
|
-
return encodeArg(arg,
|
|
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 {
|
|
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 =
|
|
130
|
+
const client = await createCompatibleClient(options.rpcUrl, debugLogger);
|
|
131
131
|
const privateKey = options.privateKey
|
|
132
|
-
?
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
222
|
+
const client = await createCompatibleClient(options.rpcUrl, debugLogger);
|
|
223
223
|
const address = AztecAddress.fromString(contractAddress);
|
|
224
224
|
const contractDataWithOrWithoutBytecode = options.includeBytecode
|
|
225
|
-
? await client.
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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, --
|
|
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 =
|
|
382
|
+
const privateKey = PrivateKey.fromString(stripLeadingHex(options.privateKey));
|
|
383
383
|
|
|
384
|
-
const client =
|
|
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.
|
|
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, --
|
|
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 =
|
|
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: ',
|
|
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, --
|
|
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 =
|
|
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
|
+
};
|