@aztec/cli 0.16.9 → 0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2

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.
Files changed (219) hide show
  1. package/README.md +9 -15
  2. package/dest/cmds/contracts/index.js +12 -0
  3. package/dest/cmds/contracts/inspect_contract.js +37 -0
  4. package/dest/cmds/contracts/parse_parameter_struct.js +13 -0
  5. package/dest/cmds/devnet/bootstrap_network.js +193 -0
  6. package/dest/cmds/devnet/faucet.js +26 -0
  7. package/dest/cmds/devnet/index.js +12 -0
  8. package/dest/cmds/infrastructure/index.js +22 -0
  9. package/dest/cmds/infrastructure/sequencers.js +93 -0
  10. package/dest/cmds/infrastructure/setup_protocol_contract.js +31 -0
  11. package/dest/cmds/l1/advance_epoch.js +10 -0
  12. package/dest/cmds/l1/assume_proven_through.js +12 -0
  13. package/dest/cmds/l1/bridge_erc20.js +31 -0
  14. package/dest/cmds/l1/create_l1_account.js +15 -0
  15. package/dest/cmds/l1/deploy_l1_contracts.js +25 -0
  16. package/dest/cmds/l1/deploy_l1_verifier.js +54 -0
  17. package/dest/cmds/l1/get_l1_balance.js +33 -0
  18. package/dest/cmds/l1/index.js +127 -0
  19. package/dest/cmds/l1/prover_stats.js +145 -0
  20. package/dest/cmds/l1/update_l1_validators.js +186 -0
  21. package/dest/cmds/misc/compute_selector.js +5 -0
  22. package/dest/cmds/misc/example_contracts.js +6 -0
  23. package/dest/cmds/misc/generate_p2p_private_key.js +7 -0
  24. package/dest/cmds/misc/generate_secret_and_hash.js +11 -0
  25. package/dest/cmds/misc/generate_secret_key.js +6 -0
  26. package/dest/cmds/misc/index.js +36 -0
  27. package/dest/cmds/misc/setup_contracts.js +25 -0
  28. package/dest/cmds/misc/update/common.js +3 -0
  29. package/dest/cmds/misc/update/github.js +3 -0
  30. package/dest/cmds/misc/update/noir.js +45 -0
  31. package/dest/cmds/misc/update/npm.js +127 -0
  32. package/dest/cmds/misc/update/utils.js +38 -0
  33. package/dest/cmds/misc/update.js +52 -0
  34. package/dest/cmds/pxe/add_contract.js +27 -0
  35. package/dest/cmds/pxe/block_number.js +10 -0
  36. package/dest/cmds/pxe/get_account.js +10 -0
  37. package/dest/cmds/pxe/get_accounts.js +25 -0
  38. package/dest/cmds/pxe/get_block.js +9 -0
  39. package/dest/cmds/pxe/get_contract_data.js +31 -0
  40. package/dest/cmds/pxe/get_current_base_fee.js +7 -0
  41. package/dest/cmds/pxe/get_l1_to_l2_message_witness.js +11 -0
  42. package/dest/cmds/pxe/get_logs.js +51 -0
  43. package/dest/cmds/pxe/get_node_info.js +61 -0
  44. package/dest/cmds/pxe/get_pxe_info.js +11 -0
  45. package/dest/cmds/pxe/index.js +55 -0
  46. package/dest/utils/aztec.js +162 -0
  47. package/dest/utils/commands.js +303 -0
  48. package/dest/utils/encoding.js +110 -0
  49. package/dest/utils/github.js +3 -0
  50. package/dest/utils/index.js +4 -0
  51. package/dest/utils/inspect.js +177 -0
  52. package/package.json +70 -21
  53. package/src/cmds/contracts/index.ts +34 -0
  54. package/src/cmds/contracts/inspect_contract.ts +51 -0
  55. package/src/cmds/contracts/parse_parameter_struct.ts +27 -0
  56. package/src/cmds/devnet/bootstrap_network.ts +306 -0
  57. package/src/cmds/devnet/faucet.ts +33 -0
  58. package/src/cmds/devnet/index.ts +52 -0
  59. package/src/cmds/infrastructure/index.ts +54 -0
  60. package/src/cmds/infrastructure/sequencers.ts +100 -0
  61. package/src/cmds/infrastructure/setup_protocol_contract.ts +36 -0
  62. package/src/cmds/l1/advance_epoch.ts +12 -0
  63. package/src/cmds/l1/assume_proven_through.ts +25 -0
  64. package/src/cmds/l1/bridge_erc20.ts +53 -0
  65. package/src/cmds/l1/create_l1_account.ts +17 -0
  66. package/src/cmds/l1/deploy_l1_contracts.ts +55 -0
  67. package/src/cmds/l1/deploy_l1_verifier.ts +105 -0
  68. package/src/cmds/l1/get_l1_balance.ts +41 -0
  69. package/src/cmds/l1/index.ts +415 -0
  70. package/src/cmds/l1/prover_stats.ts +192 -0
  71. package/src/cmds/l1/update_l1_validators.ts +238 -0
  72. package/src/cmds/misc/compute_selector.ts +7 -0
  73. package/src/cmds/misc/example_contracts.ts +12 -0
  74. package/src/cmds/misc/generate_p2p_private_key.ts +10 -0
  75. package/src/cmds/misc/generate_secret_and_hash.ts +15 -0
  76. package/src/cmds/misc/generate_secret_key.ts +5 -0
  77. package/src/cmds/misc/index.ts +70 -0
  78. package/src/cmds/misc/setup_contracts.ts +38 -0
  79. package/src/cmds/misc/update/common.ts +16 -0
  80. package/src/cmds/misc/update/github.ts +3 -0
  81. package/src/cmds/misc/update/noir.ts +57 -0
  82. package/src/cmds/misc/update/npm.ts +154 -0
  83. package/src/cmds/misc/update/utils.ts +50 -0
  84. package/src/cmds/misc/update.ts +78 -0
  85. package/src/cmds/pxe/add_contract.ts +39 -0
  86. package/src/cmds/pxe/block_number.ts +9 -0
  87. package/src/cmds/pxe/get_account.ts +16 -0
  88. package/src/cmds/pxe/get_accounts.ts +35 -0
  89. package/src/cmds/pxe/get_block.ts +10 -0
  90. package/src/cmds/pxe/get_contract_data.ts +49 -0
  91. package/src/cmds/pxe/get_current_base_fee.ts +9 -0
  92. package/src/cmds/pxe/get_l1_to_l2_message_witness.ts +25 -0
  93. package/src/cmds/pxe/get_logs.ts +66 -0
  94. package/src/cmds/pxe/get_node_info.ts +71 -0
  95. package/src/cmds/pxe/get_pxe_info.ts +13 -0
  96. package/src/cmds/pxe/index.ts +170 -0
  97. package/src/utils/aztec.ts +218 -0
  98. package/src/utils/commands.ts +384 -0
  99. package/src/utils/encoding.ts +123 -0
  100. package/src/utils/github.ts +3 -0
  101. package/src/utils/index.ts +4 -0
  102. package/src/utils/inspect.ts +207 -0
  103. package/dest/bin/index.d.ts +0 -3
  104. package/dest/bin/index.d.ts.map +0 -1
  105. package/dest/bin/index.js +0 -18
  106. package/dest/client.d.ts +0 -17
  107. package/dest/client.d.ts.map +0 -1
  108. package/dest/client.js +0 -60
  109. package/dest/cmds/add_contract.d.ts +0 -7
  110. package/dest/cmds/add_contract.d.ts.map +0 -1
  111. package/dest/cmds/add_contract.js +0 -15
  112. package/dest/cmds/add_note.d.ts +0 -8
  113. package/dest/cmds/add_note.d.ts.map +0 -1
  114. package/dest/cmds/add_note.js +0 -13
  115. package/dest/cmds/block_number.d.ts +0 -6
  116. package/dest/cmds/block_number.d.ts.map +0 -1
  117. package/dest/cmds/block_number.js +0 -10
  118. package/dest/cmds/call.d.ts +0 -7
  119. package/dest/cmds/call.d.ts.map +0 -1
  120. package/dest/cmds/call.js +0 -18
  121. package/dest/cmds/check_deploy.d.ts +0 -7
  122. package/dest/cmds/check_deploy.d.ts.map +0 -1
  123. package/dest/cmds/check_deploy.js +0 -16
  124. package/dest/cmds/compute_selector.d.ts +0 -6
  125. package/dest/cmds/compute_selector.d.ts.map +0 -1
  126. package/dest/cmds/compute_selector.js +0 -9
  127. package/dest/cmds/create_account.d.ts +0 -7
  128. package/dest/cmds/create_account.d.ts.map +0 -1
  129. package/dest/cmds/create_account.js +0 -30
  130. package/dest/cmds/deploy.d.ts +0 -7
  131. package/dest/cmds/deploy.d.ts.map +0 -1
  132. package/dest/cmds/deploy.js +0 -58
  133. package/dest/cmds/deploy_l1_contracts.d.ts +0 -6
  134. package/dest/cmds/deploy_l1_contracts.d.ts.map +0 -1
  135. package/dest/cmds/deploy_l1_contracts.js +0 -15
  136. package/dest/cmds/example_contracts.d.ts +0 -6
  137. package/dest/cmds/example_contracts.d.ts.map +0 -1
  138. package/dest/cmds/example_contracts.js +0 -10
  139. package/dest/cmds/generate_p2p_private_key.d.ts +0 -6
  140. package/dest/cmds/generate_p2p_private_key.d.ts.map +0 -1
  141. package/dest/cmds/generate_p2p_private_key.js +0 -11
  142. package/dest/cmds/generate_private_key.d.ts +0 -6
  143. package/dest/cmds/generate_private_key.d.ts.map +0 -1
  144. package/dest/cmds/generate_private_key.js +0 -22
  145. package/dest/cmds/get_account.d.ts +0 -7
  146. package/dest/cmds/get_account.d.ts.map +0 -1
  147. package/dest/cmds/get_account.js +0 -15
  148. package/dest/cmds/get_accounts.d.ts +0 -6
  149. package/dest/cmds/get_accounts.d.ts.map +0 -1
  150. package/dest/cmds/get_accounts.js +0 -18
  151. package/dest/cmds/get_contract_data.d.ts +0 -7
  152. package/dest/cmds/get_contract_data.d.ts.map +0 -1
  153. package/dest/cmds/get_contract_data.js +0 -28
  154. package/dest/cmds/get_logs.d.ts +0 -7
  155. package/dest/cmds/get_logs.d.ts.map +0 -1
  156. package/dest/cmds/get_logs.js +0 -54
  157. package/dest/cmds/get_node_info.d.ts +0 -6
  158. package/dest/cmds/get_node_info.d.ts.map +0 -1
  159. package/dest/cmds/get_node_info.js +0 -15
  160. package/dest/cmds/get_recipient.d.ts +0 -7
  161. package/dest/cmds/get_recipient.d.ts.map +0 -1
  162. package/dest/cmds/get_recipient.js +0 -15
  163. package/dest/cmds/get_recipients.d.ts +0 -6
  164. package/dest/cmds/get_recipients.d.ts.map +0 -1
  165. package/dest/cmds/get_recipients.js +0 -18
  166. package/dest/cmds/get_tx_receipt.d.ts +0 -7
  167. package/dest/cmds/get_tx_receipt.d.ts.map +0 -1
  168. package/dest/cmds/get_tx_receipt.js +0 -16
  169. package/dest/cmds/inspect_contract.d.ts +0 -6
  170. package/dest/cmds/inspect_contract.d.ts.map +0 -1
  171. package/dest/cmds/inspect_contract.js +0 -19
  172. package/dest/cmds/parse_parameter_struct.d.ts +0 -6
  173. package/dest/cmds/parse_parameter_struct.d.ts.map +0 -1
  174. package/dest/cmds/parse_parameter_struct.js +0 -20
  175. package/dest/cmds/register_account.d.ts +0 -7
  176. package/dest/cmds/register_account.d.ts.map +0 -1
  177. package/dest/cmds/register_account.js +0 -13
  178. package/dest/cmds/register_recipient.d.ts +0 -7
  179. package/dest/cmds/register_recipient.d.ts.map +0 -1
  180. package/dest/cmds/register_recipient.js +0 -11
  181. package/dest/cmds/send.d.ts +0 -7
  182. package/dest/cmds/send.d.ts.map +0 -1
  183. package/dest/cmds/send.js +0 -26
  184. package/dest/cmds/unbox.d.ts +0 -6
  185. package/dest/cmds/unbox.d.ts.map +0 -1
  186. package/dest/cmds/unbox.js +0 -9
  187. package/dest/encoding.d.ts +0 -15
  188. package/dest/encoding.d.ts.map +0 -1
  189. package/dest/encoding.js +0 -114
  190. package/dest/github.d.ts +0 -4
  191. package/dest/github.d.ts.map +0 -1
  192. package/dest/github.js +0 -4
  193. package/dest/index.d.ts +0 -10
  194. package/dest/index.d.ts.map +0 -1
  195. package/dest/index.js +0 -321
  196. package/dest/parse_args.d.ts +0 -105
  197. package/dest/parse_args.d.ts.map +0 -1
  198. package/dest/parse_args.js +0 -233
  199. package/dest/test/mocks.d.ts +0 -3
  200. package/dest/test/mocks.d.ts.map +0 -1
  201. package/dest/test/mocks.js +0 -65
  202. package/dest/unbox.d.ts +0 -14
  203. package/dest/unbox.d.ts.map +0 -1
  204. package/dest/unbox.js +0 -276
  205. package/dest/update/common.d.ts +0 -17
  206. package/dest/update/common.d.ts.map +0 -1
  207. package/dest/update/common.js +0 -2
  208. package/dest/update/noir.d.ts +0 -10
  209. package/dest/update/noir.d.ts.map +0 -1
  210. package/dest/update/noir.js +0 -63
  211. package/dest/update/npm.d.ts +0 -34
  212. package/dest/update/npm.d.ts.map +0 -1
  213. package/dest/update/npm.js +0 -125
  214. package/dest/update/update.d.ts +0 -3
  215. package/dest/update/update.d.ts.map +0 -1
  216. package/dest/update/update.js +0 -58
  217. package/dest/utils.d.ts +0 -70
  218. package/dest/utils.d.ts.map +0 -1
  219. package/dest/utils.js +0 -168
@@ -0,0 +1,162 @@
1
+ import { loadContractArtifact } from '@aztec/aztec.js/abi';
2
+ import { FunctionType } from '@aztec/foundation/abi';
3
+ import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
4
+ import { ProtocolContractAddress, protocolContractTreeRoot } from '@aztec/protocol-contracts';
5
+ import TOML from '@iarna/toml';
6
+ import { readFile } from 'fs/promises';
7
+ import { gtr, ltr, satisfies, valid } from 'semver';
8
+ import { getAddress, getContract, publicActions } from 'viem';
9
+ import { encodeArgs } from './encoding.js';
10
+ /**
11
+ * Helper to get an ABI function or throw error if it doesn't exist.
12
+ * @param artifact - Contract's build artifact in JSON format.
13
+ * @param fnName - Function name to be found.
14
+ * @returns The function's ABI.
15
+ */ export function getFunctionArtifact(artifact, fnName) {
16
+ const fn = artifact.functions.find(({ name })=>name === fnName);
17
+ if (!fn) {
18
+ throw Error(`Function ${fnName} not found in contract ABI.`);
19
+ }
20
+ return fn;
21
+ }
22
+ /**
23
+ * Function to execute the 'deployRollupContracts' command.
24
+ * @param rpcUrl - The RPC URL of the ethereum node.
25
+ * @param chainId - The chain ID of the L1 host.
26
+ * @param privateKey - The private key to be used in contract deployment.
27
+ * @param mnemonic - The mnemonic to be used in contract deployment.
28
+ */ export async function deployAztecContracts(rpcUrl, chainId, privateKey, mnemonic, mnemonicIndex, salt, initialValidators, config, debugLogger) {
29
+ const { createEthereumChain, deployL1Contracts } = await import('@aztec/ethereum');
30
+ const { mnemonicToAccount, privateKeyToAccount } = await import('viem/accounts');
31
+ const account = !privateKey ? mnemonicToAccount(mnemonic, {
32
+ addressIndex: mnemonicIndex
33
+ }) : privateKeyToAccount(`${privateKey.startsWith('0x') ? '' : '0x'}${privateKey}`);
34
+ const chain = createEthereumChain(rpcUrl, chainId);
35
+ const { getVKTreeRoot } = await import('@aztec/noir-protocol-circuits-types/vks');
36
+ return await deployL1Contracts(chain.rpcUrl, account, chain.chainInfo, debugLogger, {
37
+ l2FeeJuiceAddress: ProtocolContractAddress.FeeJuice,
38
+ vkTreeRoot: await getVKTreeRoot(),
39
+ protocolContractTreeRoot,
40
+ salt,
41
+ initialValidators,
42
+ ...config
43
+ });
44
+ }
45
+ /** Sets the assumed proven block number on the rollup contract on L1 */ export async function setAssumeProvenThrough(blockNumber, rollupAddress, walletClient) {
46
+ const rollup = getContract({
47
+ address: getAddress(rollupAddress.toString()),
48
+ abi: RollupAbi,
49
+ client: walletClient
50
+ });
51
+ const hash = await rollup.write.setAssumeProvenThroughBlockNumber([
52
+ BigInt(blockNumber)
53
+ ]);
54
+ await walletClient.extend(publicActions).waitForTransactionReceipt({
55
+ hash
56
+ });
57
+ }
58
+ /**
59
+ * Gets all contracts available in \@aztec/noir-contracts.js.
60
+ * @returns The contract names.
61
+ */ export async function getExampleContractNames() {
62
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
63
+ // @ts-ignore - Importing noir-contracts.js even in devDeps results in a circular dependency error. Need to ignore because this line doesn't cause an error in a dev environment
64
+ const { ContractNames } = await import('@aztec/noir-contracts.js');
65
+ return ContractNames;
66
+ }
67
+ /**
68
+ * Reads a file and converts it to an Aztec Contract ABI.
69
+ * @param fileDir - The directory of the compiled contract ABI.
70
+ * @returns The parsed contract artifact.
71
+ */ export async function getContractArtifact(fileDir, log) {
72
+ // first check if it's a noir-contracts example
73
+ const allNames = await getExampleContractNames();
74
+ const contractName = fileDir.replace(/Contract(Artifact)?$/, '');
75
+ if (allNames.includes(contractName)) {
76
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
77
+ // @ts-ignore - Importing noir-contracts.js even in devDeps results in a circular dependency error. Need to ignore because this line doesn't cause an error in a dev environment
78
+ const imported = await import(`@aztec/noir-contracts.js/${contractName}`);
79
+ const artifact = imported[`${contractName}ContractArtifact`];
80
+ if (!artifact) {
81
+ throw Error(`Could not import ${contractName}ContractArtifact from @aztec/noir-contracts.js/${contractName}`);
82
+ }
83
+ return artifact;
84
+ }
85
+ let contents;
86
+ try {
87
+ contents = await readFile(fileDir, 'utf8');
88
+ } catch {
89
+ throw Error(`Contract ${fileDir} not found`);
90
+ }
91
+ try {
92
+ return loadContractArtifact(JSON.parse(contents));
93
+ } catch (err) {
94
+ log('Invalid file used. Please try again.');
95
+ throw err;
96
+ }
97
+ }
98
+ /**
99
+ * Performs necessary checks, conversions & operations to call a contract fn from the CLI.
100
+ * @param contractFile - Directory of the compiled contract ABI.
101
+ * @param functionName - Name of the function to be called.
102
+ * @param _functionArgs - Arguments to call the function with.
103
+ * @param log - Logger instance that will output to the CLI
104
+ * @returns Formatted contract address, function arguments and caller's aztec address.
105
+ */ export async function prepTx(contractFile, functionName, _functionArgs, log) {
106
+ const contractArtifact = await getContractArtifact(contractFile, log);
107
+ const functionArtifact = getFunctionArtifact(contractArtifact, functionName);
108
+ const functionArgs = encodeArgs(_functionArgs, functionArtifact.parameters);
109
+ const isPrivate = functionArtifact.functionType === FunctionType.PRIVATE;
110
+ return {
111
+ functionArgs,
112
+ contractArtifact,
113
+ isPrivate
114
+ };
115
+ }
116
+ /**
117
+ * Removes the leading 0x from a hex string. If no leading 0x is found the string is returned unchanged.
118
+ * @param hex - A hex string
119
+ * @returns A new string with leading 0x removed
120
+ */ export const stripLeadingHex = (hex)=>{
121
+ if (hex.length > 2 && hex.startsWith('0x')) {
122
+ return hex.substring(2);
123
+ }
124
+ return hex;
125
+ };
126
+ /**
127
+ * Pretty prints Nargo.toml contents to a string
128
+ * @param config - Nargo.toml contents
129
+ * @returns The Nargo.toml contents as a string
130
+ */ export function prettyPrintNargoToml(config) {
131
+ const withoutDependencies = Object.fromEntries(Object.entries(config).filter(([key])=>key !== 'dependencies'));
132
+ const partialToml = TOML.stringify(withoutDependencies);
133
+ const dependenciesToml = Object.entries(config.dependencies).map(([name, dep])=>{
134
+ const depToml = TOML.stringify.value(dep);
135
+ return `${name} = ${depToml}`;
136
+ });
137
+ return partialToml + '\n[dependencies]\n' + dependenciesToml.join('\n') + '\n';
138
+ }
139
+ /** Mismatch between server and client versions. */ class VersionMismatchError extends Error {
140
+ }
141
+ /**
142
+ * Checks that Private eXecution Environment (PXE) version matches the expected one by this CLI. Throws if not.
143
+ * @param pxe - PXE client.
144
+ * @param expectedVersionRange - Expected version by CLI.
145
+ */ export async function checkServerVersion(pxe, expectedVersionRange) {
146
+ const serverName = 'Aztec Node';
147
+ const { nodeVersion } = await pxe.getNodeInfo();
148
+ if (!nodeVersion) {
149
+ throw new VersionMismatchError(`Couldn't determine ${serverName} version. You may run into issues.`);
150
+ }
151
+ if (!nodeVersion || !valid(nodeVersion)) {
152
+ throw new VersionMismatchError(`Missing or invalid version identifier for ${serverName} (${nodeVersion ?? 'empty'}).`);
153
+ } else if (!satisfies(nodeVersion, expectedVersionRange)) {
154
+ if (gtr(nodeVersion, expectedVersionRange)) {
155
+ throw new VersionMismatchError(`${serverName} is running version ${nodeVersion} which is newer than the expected by this CLI (${expectedVersionRange}). Consider upgrading your CLI to a newer version.`);
156
+ } else if (ltr(nodeVersion, expectedVersionRange)) {
157
+ throw new VersionMismatchError(`${serverName} is running version ${nodeVersion} which is older than the expected by this CLI (${expectedVersionRange}). Consider upgrading your ${serverName} to a newer version.`);
158
+ } else {
159
+ throw new VersionMismatchError(`${serverName} is running version ${nodeVersion} which does not match the expected by this CLI (${expectedVersionRange}).`);
160
+ }
161
+ }
162
+ }
@@ -0,0 +1,303 @@
1
+ import { FunctionSelector } from '@aztec/aztec.js/abi';
2
+ import { AztecAddress } from '@aztec/aztec.js/addresses';
3
+ import { EthAddress } from '@aztec/aztec.js/eth_address';
4
+ import { Fr } from '@aztec/aztec.js/fields';
5
+ import { LogId } from '@aztec/aztec.js/log_id';
6
+ import { TxHash } from '@aztec/aztec.js/tx_hash';
7
+ import { PublicKeys } from '@aztec/circuits.js/types';
8
+ import { CommanderError, InvalidArgumentError, Option } from 'commander';
9
+ import { lookup } from 'dns/promises';
10
+ import { rename, writeFile } from 'fs/promises';
11
+ /**
12
+ * If we can successfully resolve 'host.docker.internal', then we are running in a container, and we should treat
13
+ * localhost as being host.docker.internal.
14
+ */ export const getLocalhost = ()=>lookup('host.docker.internal').then(()=>'host.docker.internal').catch(()=>'localhost');
15
+ export const LOCALHOST = await getLocalhost();
16
+ export const { ETHEREUM_HOST = `http://${LOCALHOST}:8545`, PRIVATE_KEY, API_KEY, CLI_VERSION } = process.env;
17
+ export function addOptions(program, options) {
18
+ options.forEach((option)=>program.addOption(option));
19
+ return program;
20
+ }
21
+ export const makePxeOption = (mandatory)=>new Option('-u, --rpc-url <string>', 'URL of the PXE').env('PXE_URL').default(`http://${LOCALHOST}:8080`).conflicts('remote-pxe').makeOptionMandatory(mandatory);
22
+ export const pxeOption = makePxeOption(true);
23
+ export const l1ChainIdOption = new Option('-c, --l1-chain-id <number>', 'Chain ID of the ethereum host').env('L1_CHAIN_ID').default(31337).argParser((value)=>{
24
+ const parsedValue = Number(value);
25
+ if (isNaN(parsedValue)) {
26
+ throw new Error('Chain ID must be a number.');
27
+ }
28
+ return parsedValue;
29
+ });
30
+ export const createSecretKeyOption = (description, mandatory, argsParser)=>new Option('-sk, --secret-key <string>', description).env('SECRET_KEY').argParser(argsParser ?? parseSecretKey).makeOptionMandatory(mandatory);
31
+ export const logJson = (log)=>(obj)=>log(JSON.stringify(obj, null, 2));
32
+ /**
33
+ * Updates a file in place atomically.
34
+ * @param filePath - Path to file
35
+ * @param contents - New contents to write
36
+ */ export async function atomicUpdateFile(filePath, contents) {
37
+ const tmpFilepath = filePath + '.tmp';
38
+ try {
39
+ await writeFile(tmpFilepath, contents, {
40
+ // let's crash if the tmp file already exists
41
+ flag: 'wx'
42
+ });
43
+ await rename(tmpFilepath, filePath);
44
+ } catch (e) {
45
+ if (e instanceof Error && 'code' in e && e.code === 'EEXIST') {
46
+ const commanderError = new CommanderError(1, e.code, `Temporary file already exists: ${tmpFilepath}. Delete this file and try again.`);
47
+ commanderError.nestedError = e.message;
48
+ throw commanderError;
49
+ } else {
50
+ throw e;
51
+ }
52
+ }
53
+ }
54
+ /**
55
+ * Utility to select a TX sender either from user input
56
+ * or from the first account that is found in a PXE instance.
57
+ * @param pxe - The PXE instance that will be checked for an account.
58
+ * @param _from - The user input.
59
+ * @returns An Aztec address. Will throw if one can't be found in either options.
60
+ */ export async function getTxSender(pxe, _from) {
61
+ let from;
62
+ if (_from) {
63
+ try {
64
+ from = AztecAddress.fromString(_from);
65
+ } catch {
66
+ throw new InvalidArgumentError(`Invalid option 'from' passed: ${_from}`);
67
+ }
68
+ } else {
69
+ const accounts = await pxe.getRegisteredAccounts();
70
+ if (!accounts.length) {
71
+ throw new Error('No accounts found in PXE instance.');
72
+ }
73
+ from = accounts[0].address;
74
+ }
75
+ return from;
76
+ }
77
+ /**
78
+ * Removes the leading 0x from a hex string. If no leading 0x is found the string is returned unchanged.
79
+ * @param hex - A hex string
80
+ * @returns A new string with leading 0x removed
81
+ */ const stripLeadingHex = (hex)=>{
82
+ if (hex.length > 2 && hex.startsWith('0x')) {
83
+ return hex.substring(2);
84
+ }
85
+ return hex;
86
+ };
87
+ export function parseBigint(bigint) {
88
+ return bigint ? BigInt(bigint) : undefined;
89
+ }
90
+ /**
91
+ * Parses a hex encoded string to an Fr integer
92
+ * @param str - Hex encoded string
93
+ * @returns A integer
94
+ */ export function parseFieldFromHexString(str) {
95
+ const hex = stripLeadingHex(str);
96
+ // ensure it's a hex string
97
+ if (!hex.match(/^[0-9a-f]+$/i)) {
98
+ throw new InvalidArgumentError('Invalid hex string');
99
+ }
100
+ // pad it so that we may read it as a buffer.
101
+ // Buffer needs _exactly_ two hex characters per byte
102
+ const padded = hex.length % 2 === 1 ? '0' + hex : hex;
103
+ let buf = Buffer.from(padded, 'hex');
104
+ if (buf.length > Fr.SIZE_IN_BYTES) {
105
+ buf = buf.subarray(buf.length - Fr.SIZE_IN_BYTES);
106
+ }
107
+ const fr = Buffer.alloc(Fr.SIZE_IN_BYTES, 0);
108
+ fr.set(buf, Fr.SIZE_IN_BYTES - buf.length);
109
+ // finally, turn it into an integer
110
+ return Fr.fromBuffer(fr);
111
+ }
112
+ /**
113
+ * Parses an AztecAddress from a string.
114
+ * @param address - A serialized Aztec address
115
+ * @returns An Aztec address
116
+ * @throws InvalidArgumentError if the input string is not valid.
117
+ */ export function parseAztecAddress(address) {
118
+ try {
119
+ return AztecAddress.fromString(address);
120
+ } catch {
121
+ throw new InvalidArgumentError(`Invalid address: ${address}`);
122
+ }
123
+ }
124
+ /**
125
+ * Parses an Ethereum address from a string.
126
+ * @param address - A serialized Ethereum address
127
+ * @returns An Ethereum address
128
+ * @throws InvalidArgumentError if the input string is not valid.
129
+ */ export function parseEthereumAddress(address) {
130
+ try {
131
+ return EthAddress.fromString(address);
132
+ } catch {
133
+ throw new InvalidArgumentError(`Invalid address: ${address}`);
134
+ }
135
+ }
136
+ /**
137
+ * Parses an AztecAddress from a string.
138
+ * @param address - A serialized Aztec address
139
+ * @returns An Aztec address
140
+ * @throws InvalidArgumentError if the input string is not valid.
141
+ */ export function parseOptionalAztecAddress(address) {
142
+ if (!address) {
143
+ return undefined;
144
+ }
145
+ return parseAztecAddress(address);
146
+ }
147
+ /**
148
+ * Parses an optional log ID string into a LogId object.
149
+ *
150
+ * @param logId - The log ID string to parse.
151
+ * @returns The parsed LogId object, or undefined if the log ID is missing or empty.
152
+ */ export function parseOptionalLogId(logId) {
153
+ if (!logId) {
154
+ return undefined;
155
+ }
156
+ return LogId.fromString(logId);
157
+ }
158
+ /**
159
+ * Parses a selector from a string.
160
+ * @param selector - A serialized selector.
161
+ * @returns A selector.
162
+ * @throws InvalidArgumentError if the input string is not valid.
163
+ */ export function parseOptionalSelector(selector) {
164
+ if (!selector) {
165
+ return undefined;
166
+ }
167
+ try {
168
+ return FunctionSelector.fromString(selector);
169
+ } catch {
170
+ throw new InvalidArgumentError(`Invalid selector: ${selector}`);
171
+ }
172
+ }
173
+ /**
174
+ * Parses a string into an integer or returns undefined if the input is falsy.
175
+ *
176
+ * @param value - The string to parse into an integer.
177
+ * @returns The parsed integer, or undefined if the input string is falsy.
178
+ * @throws If the input is not a valid integer.
179
+ */ export function parseOptionalInteger(value) {
180
+ if (!value) {
181
+ return undefined;
182
+ }
183
+ const parsed = Number(value);
184
+ if (!Number.isInteger(parsed)) {
185
+ throw new InvalidArgumentError('Invalid integer.');
186
+ }
187
+ return parsed;
188
+ }
189
+ /**
190
+ * Parses a TxHash from a string.
191
+ * @param txHash - A transaction hash
192
+ * @returns A TxHash instance
193
+ * @throws InvalidArgumentError if the input string is not valid.
194
+ */ export function parseTxHash(txHash) {
195
+ try {
196
+ return TxHash.fromString(txHash);
197
+ } catch {
198
+ throw new InvalidArgumentError(`Invalid transaction hash: ${txHash}`);
199
+ }
200
+ }
201
+ /**
202
+ * Parses an optional TxHash from a string.
203
+ * Calls parseTxHash internally.
204
+ * @param txHash - A transaction hash
205
+ * @returns A TxHash instance, or undefined if the input string is falsy.
206
+ * @throws InvalidArgumentError if the input string is not valid.
207
+ */ export function parseOptionalTxHash(txHash) {
208
+ if (!txHash) {
209
+ return undefined;
210
+ }
211
+ return parseTxHash(txHash);
212
+ }
213
+ /**
214
+ * Parses a public key from a string.
215
+ * @param publicKey - A public keys object serialised as a string
216
+ * @returns A PublicKeys instance
217
+ * @throws InvalidArgumentError if the input string is not valid.
218
+ */ export function parsePublicKey(publicKey) {
219
+ if (!publicKey) {
220
+ return undefined;
221
+ }
222
+ try {
223
+ return PublicKeys.fromString(publicKey);
224
+ } catch (err) {
225
+ throw new InvalidArgumentError(`Invalid public key: ${publicKey}`);
226
+ }
227
+ }
228
+ /**
229
+ * Parses a partial address from a string.
230
+ * @param address - A partial address
231
+ * @returns A Fr instance
232
+ * @throws InvalidArgumentError if the input string is not valid.
233
+ */ export function parsePartialAddress(address) {
234
+ try {
235
+ return Fr.fromHexString(address);
236
+ } catch (err) {
237
+ throw new InvalidArgumentError(`Invalid partial address: ${address}`);
238
+ }
239
+ }
240
+ /**
241
+ * Parses a secret key from a string.
242
+ * @param privateKey - A string
243
+ * @returns A secret key
244
+ * @throws InvalidArgumentError if the input string is not valid.
245
+ */ export function parseSecretKey(secretKey) {
246
+ try {
247
+ return Fr.fromHexString(secretKey);
248
+ } catch (err) {
249
+ throw new InvalidArgumentError(`Invalid encryption secret key: ${secretKey}`);
250
+ }
251
+ }
252
+ /**
253
+ * Parses a field from a string.
254
+ * @param field - A string representing the field.
255
+ * @returns A field.
256
+ * @throws InvalidArgumentError if the input string is not valid.
257
+ */ export function parseField(field) {
258
+ try {
259
+ const isHex = field.startsWith('0x') || field.match(new RegExp(`^[0-9a-f]{${Fr.SIZE_IN_BYTES * 2}}$`, 'i'));
260
+ if (isHex) {
261
+ return Fr.fromHexString(field);
262
+ }
263
+ if ([
264
+ 'true',
265
+ 'false'
266
+ ].includes(field)) {
267
+ return new Fr(field === 'true');
268
+ }
269
+ const isNumber = +field || field === '0';
270
+ if (isNumber) {
271
+ return new Fr(BigInt(field));
272
+ }
273
+ const isBigInt = field.endsWith('n');
274
+ if (isBigInt) {
275
+ return new Fr(BigInt(field.replace(/n$/, '')));
276
+ }
277
+ return new Fr(BigInt(field));
278
+ } catch (err) {
279
+ throw new InvalidArgumentError(`Invalid field: ${field}`);
280
+ }
281
+ }
282
+ /**
283
+ * Parses an array of strings to Frs.
284
+ * @param fields - An array of strings representing the fields.
285
+ * @returns An array of Frs.
286
+ */ export function parseFields(fields) {
287
+ return fields.map(parseField);
288
+ }
289
+ /**
290
+ * Pretty prints an object as JSON
291
+ * @param data - The object to stringify
292
+ * @returns A JSON string
293
+ */ export function prettyPrintJSON(data) {
294
+ return JSON.stringify(data, (_key, val)=>{
295
+ if (typeof val === 'bigint') {
296
+ return String(val);
297
+ } else if (val && typeof val === 'object' && 'toBuffer' in val) {
298
+ return '0x' + val.toBuffer().toString('hex');
299
+ } else {
300
+ return val;
301
+ }
302
+ }, 2);
303
+ }
@@ -0,0 +1,110 @@
1
+ import { isU128Struct } from '@aztec/foundation/abi';
2
+ import { Fr } from '@aztec/foundation/fields';
3
+ /**
4
+ * Parses a hex string into an ABI struct type.
5
+ * @param str - The encoded hex string.
6
+ * @param abiType - The ABI Struct type.
7
+ * @returns An object in the ABI struct type's format.
8
+ */ export function parseStructString(str, abiType) {
9
+ // Assign string bytes to struct fields.
10
+ const buf = Buffer.from(str.replace(/^0x/i, ''), 'hex');
11
+ const struct = {};
12
+ let byteIndex = 0;
13
+ let argIndex = 0;
14
+ while(byteIndex < buf.length){
15
+ const { name } = abiType.fields[argIndex];
16
+ struct[name] = Fr.fromBuffer(buf.subarray(byteIndex, byteIndex + 32));
17
+ byteIndex += 32;
18
+ argIndex += 1;
19
+ }
20
+ return struct;
21
+ }
22
+ /**
23
+ * Helper function to encode CLI string args to an appropriate JS type.
24
+ * @param arg - The CLI argument.
25
+ * @param abiType - The type as described by the contract's ABI.
26
+ * @returns The encoded argument.
27
+ */ function encodeArg(arg, abiType, name) {
28
+ const { kind } = abiType;
29
+ if (kind === 'field' || kind === 'integer') {
30
+ let res;
31
+ try {
32
+ res = BigInt(arg);
33
+ } catch (err) {
34
+ throw new Error(`Invalid value passed for ${name}. Could not parse ${arg} as a${kind === 'integer' ? 'n' : ''} ${kind}.`);
35
+ }
36
+ return res;
37
+ } else if (kind === 'boolean') {
38
+ if (arg === 'true') {
39
+ return true;
40
+ }
41
+ if (arg === 'false') {
42
+ return false;
43
+ } else {
44
+ throw Error(`Invalid boolean value passed for ${name}: ${arg}.`);
45
+ }
46
+ } else if (kind === 'string') {
47
+ return arg;
48
+ } else if (kind === 'array') {
49
+ let arr;
50
+ const res = [];
51
+ try {
52
+ arr = JSON.parse(arg);
53
+ } catch {
54
+ throw new Error(`Unable to parse arg ${arg} as array for ${name} parameter`);
55
+ }
56
+ if (!Array.isArray(arr)) {
57
+ throw Error(`Invalid argument ${arg} passed for array parameter ${name}.`);
58
+ }
59
+ if (arr.length !== abiType.length) {
60
+ throw Error(`Invalid array length passed for ${name}. Expected ${abiType.length}, received ${arr.length}.`);
61
+ }
62
+ for(let i = 0; i < abiType.length; i += 1){
63
+ res.push(encodeArg(arr[i], abiType.type, name));
64
+ }
65
+ return res;
66
+ } else if (kind === 'struct') {
67
+ // check if input is encoded long string
68
+ if (arg.startsWith('0x')) {
69
+ return parseStructString(arg, abiType);
70
+ }
71
+ let obj;
72
+ try {
73
+ obj = JSON.parse(arg);
74
+ } catch {
75
+ throw new Error(`Unable to parse arg ${arg} as struct`);
76
+ }
77
+ if (Array.isArray(obj)) {
78
+ throw Error(`Array passed for arg ${name}. Expected a struct.`);
79
+ }
80
+ const res = {};
81
+ if (isU128Struct(abiType)) {
82
+ // When dealing with U128 we don't expect to receive limbs from the user but instead just a normal number.
83
+ // Also encoder.ts expects a normal number so we just return it as such.
84
+ return obj;
85
+ } else {
86
+ for (const field of abiType.fields){
87
+ // Remove field name from list as it's present
88
+ const arg = obj[field.name];
89
+ if (!arg) {
90
+ throw Error(`Expected field ${field.name} not found in struct ${name}.`);
91
+ }
92
+ res[field.name] = encodeArg(obj[field.name], field.type, field.name);
93
+ }
94
+ }
95
+ return res;
96
+ }
97
+ }
98
+ /**
99
+ * Tries to encode function args to their equivalent TS type.
100
+ * @param args - An array of function's / constructor's args.
101
+ * @returns The encoded array.
102
+ */ export function encodeArgs(args, params) {
103
+ if (args.length !== params.length) {
104
+ throw new Error(`Invalid args provided.\nExpected args: [${params.map((param)=>param.name + ': ' + param.type.kind).join(', ')}]\nReceived args: ${args.join(', ')}`);
105
+ }
106
+ return args.map((arg, index)=>{
107
+ const { type, name } = params[index];
108
+ return encodeArg(arg, type, name);
109
+ });
110
+ }
@@ -0,0 +1,3 @@
1
+ export const GITHUB_OWNER = 'AztecProtocol';
2
+ export const GITHUB_REPO = 'aztec-packages';
3
+ export const GITHUB_TAG_PREFIX = 'aztec-packages';
@@ -0,0 +1,4 @@
1
+ export * from './commands.js';
2
+ export * from './aztec.js';
3
+ export * from './encoding.js';
4
+ export * from './github.js';