@aztec/cli-wallet 0.0.0-test.0 → 0.0.1-commit.001888fc

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 (111) hide show
  1. package/README.md +30 -0
  2. package/dest/bin/index.d.ts +2 -1
  3. package/dest/bin/index.js +58 -26
  4. package/dest/cmds/authorize_action.d.ts +4 -3
  5. package/dest/cmds/authorize_action.d.ts.map +1 -1
  6. package/dest/cmds/authorize_action.js +11 -5
  7. package/dest/cmds/bridge_fee_juice.d.ts +4 -4
  8. package/dest/cmds/bridge_fee_juice.d.ts.map +1 -1
  9. package/dest/cmds/bridge_fee_juice.js +10 -8
  10. package/dest/cmds/check_tx.d.ts +5 -3
  11. package/dest/cmds/check_tx.d.ts.map +1 -1
  12. package/dest/cmds/check_tx.js +148 -6
  13. package/dest/cmds/create_account.d.ts +9 -7
  14. package/dest/cmds/create_account.d.ts.map +1 -1
  15. package/dest/cmds/create_account.js +68 -35
  16. package/dest/cmds/create_authwit.d.ts +4 -3
  17. package/dest/cmds/create_authwit.d.ts.map +1 -1
  18. package/dest/cmds/create_authwit.js +6 -6
  19. package/dest/cmds/deploy.d.ts +7 -4
  20. package/dest/cmds/deploy.d.ts.map +1 -1
  21. package/dest/cmds/deploy.js +101 -58
  22. package/dest/cmds/deploy_account.d.ts +6 -8
  23. package/dest/cmds/deploy_account.d.ts.map +1 -1
  24. package/dest/cmds/deploy_account.js +67 -36
  25. package/dest/cmds/import_test_accounts.d.ts +3 -3
  26. package/dest/cmds/import_test_accounts.d.ts.map +1 -1
  27. package/dest/cmds/import_test_accounts.js +6 -9
  28. package/dest/cmds/index.d.ts +3 -3
  29. package/dest/cmds/index.d.ts.map +1 -1
  30. package/dest/cmds/index.js +83 -115
  31. package/dest/cmds/profile.d.ts +8 -0
  32. package/dest/cmds/profile.d.ts.map +1 -0
  33. package/dest/cmds/profile.js +28 -0
  34. package/dest/cmds/register_contract.d.ts +7 -3
  35. package/dest/cmds/register_contract.d.ts.map +1 -1
  36. package/dest/cmds/register_contract.js +20 -7
  37. package/dest/cmds/register_sender.d.ts +4 -3
  38. package/dest/cmds/register_sender.d.ts.map +1 -1
  39. package/dest/cmds/send.d.ts +8 -9
  40. package/dest/cmds/send.d.ts.map +1 -1
  41. package/dest/cmds/send.js +54 -28
  42. package/dest/cmds/simulate.d.ts +7 -3
  43. package/dest/cmds/simulate.d.ts.map +1 -1
  44. package/dest/cmds/simulate.js +26 -20
  45. package/dest/storage/wallet_db.d.ts +7 -19
  46. package/dest/storage/wallet_db.d.ts.map +1 -1
  47. package/dest/storage/wallet_db.js +49 -55
  48. package/dest/utils/authorizations.d.ts +6 -0
  49. package/dest/utils/authorizations.d.ts.map +1 -0
  50. package/dest/utils/authorizations.js +28 -0
  51. package/dest/utils/cli_wallet_and_node_wrapper.d.ts +12 -0
  52. package/dest/utils/cli_wallet_and_node_wrapper.d.ts.map +1 -0
  53. package/dest/utils/cli_wallet_and_node_wrapper.js +25 -0
  54. package/dest/utils/constants.d.ts +4 -0
  55. package/dest/utils/constants.d.ts.map +1 -0
  56. package/dest/utils/constants.js +7 -0
  57. package/dest/utils/ecdsa.d.ts +1 -3
  58. package/dest/utils/ecdsa.d.ts.map +1 -1
  59. package/dest/utils/options/fees.d.ts +22 -28
  60. package/dest/utils/options/fees.d.ts.map +1 -1
  61. package/dest/utils/options/fees.js +88 -145
  62. package/dest/utils/options/index.d.ts +1 -1
  63. package/dest/utils/options/options.d.ts +9 -5
  64. package/dest/utils/options/options.d.ts.map +1 -1
  65. package/dest/utils/options/options.js +26 -14
  66. package/dest/utils/profiling.d.ts +5 -0
  67. package/dest/utils/profiling.d.ts.map +1 -0
  68. package/dest/utils/profiling.js +68 -0
  69. package/dest/utils/wallet.d.ts +40 -0
  70. package/dest/utils/wallet.d.ts.map +1 -0
  71. package/dest/utils/wallet.js +208 -0
  72. package/package.json +29 -22
  73. package/src/bin/index.ts +63 -33
  74. package/src/cmds/authorize_action.ts +16 -5
  75. package/src/cmds/bridge_fee_juice.ts +16 -12
  76. package/src/cmds/check_tx.ts +180 -5
  77. package/src/cmds/create_account.ts +76 -41
  78. package/src/cmds/create_authwit.ts +9 -5
  79. package/src/cmds/deploy.ts +106 -67
  80. package/src/cmds/deploy_account.ts +76 -36
  81. package/src/cmds/import_test_accounts.ts +7 -11
  82. package/src/cmds/index.ts +257 -221
  83. package/src/cmds/profile.ts +48 -0
  84. package/src/cmds/register_contract.ts +28 -5
  85. package/src/cmds/register_sender.ts +3 -2
  86. package/src/cmds/send.ts +54 -25
  87. package/src/cmds/simulate.ts +37 -24
  88. package/src/storage/wallet_db.ts +53 -68
  89. package/src/utils/authorizations.ts +51 -0
  90. package/src/utils/cli_wallet_and_node_wrapper.ts +35 -0
  91. package/src/utils/constants.ts +4 -0
  92. package/src/utils/options/fees.ts +142 -207
  93. package/src/utils/options/options.ts +41 -19
  94. package/src/utils/profiling.ts +172 -0
  95. package/src/utils/wallet.ts +290 -0
  96. package/dest/cmds/add_authwit.d.ts +0 -4
  97. package/dest/cmds/add_authwit.d.ts.map +0 -1
  98. package/dest/cmds/add_authwit.js +0 -4
  99. package/dest/cmds/cancel_tx.d.ts +0 -11
  100. package/dest/cmds/cancel_tx.d.ts.map +0 -1
  101. package/dest/cmds/cancel_tx.js +0 -38
  102. package/dest/utils/accounts.d.ts +0 -11
  103. package/dest/utils/accounts.d.ts.map +0 -1
  104. package/dest/utils/accounts.js +0 -87
  105. package/dest/utils/pxe_wrapper.d.ts +0 -10
  106. package/dest/utils/pxe_wrapper.d.ts.map +0 -1
  107. package/dest/utils/pxe_wrapper.js +0 -21
  108. package/src/cmds/add_authwit.ts +0 -13
  109. package/src/cmds/cancel_tx.ts +0 -62
  110. package/src/utils/accounts.ts +0 -102
  111. package/src/utils/pxe_wrapper.ts +0 -26
@@ -1,12 +1,187 @@
1
- import type { PXE, TxHash } from '@aztec/aztec.js';
2
- import { inspectTx } from '@aztec/cli/inspect';
1
+ import type { ContractArtifact } from '@aztec/aztec.js/abi';
2
+ import type { AztecAddress } from '@aztec/aztec.js/addresses';
3
+ import { Fr } from '@aztec/aztec.js/fields';
4
+ import type { AztecNode } from '@aztec/aztec.js/node';
5
+ import { ProtocolContractAddress } from '@aztec/aztec.js/protocol';
6
+ import type { TxHash } from '@aztec/aztec.js/tx';
3
7
  import type { LogFn } from '@aztec/foundation/log';
8
+ import { siloNullifier } from '@aztec/stdlib/hash';
9
+ import { NoteDao } from '@aztec/stdlib/note';
4
10
 
5
- export async function checkTx(client: PXE, txHash: TxHash, statusOnly: boolean, log: LogFn) {
11
+ import type { CLIWallet } from '../utils/wallet.js';
12
+
13
+ export async function checkTx(
14
+ wallet: CLIWallet,
15
+ aztecNode: AztecNode,
16
+ txHash: TxHash,
17
+ statusOnly: boolean,
18
+ log: LogFn,
19
+ ) {
6
20
  if (statusOnly) {
7
- const receipt = await client.getTxReceipt(txHash);
21
+ const receipt = await aztecNode.getTxReceipt(txHash);
8
22
  return receipt.status;
9
23
  } else {
10
- await inspectTx(client, txHash, log, { includeBlockInfo: true });
24
+ await inspectTx(wallet, aztecNode, txHash, log);
25
+ }
26
+ }
27
+
28
+ // The rest of the code here was copied over here from CLI because in CLI I needed to prune the inspect function of the PXE
29
+ // dependency when dropping PXE JSON RPC Server.
30
+
31
+ async function inspectTx(wallet: CLIWallet, aztecNode: AztecNode, txHash: TxHash, log: LogFn) {
32
+ const [receipt, effectsInBlock] = await Promise.all([aztecNode.getTxReceipt(txHash), aztecNode.getTxEffect(txHash)]);
33
+ // Base tx data
34
+ log(`Tx ${txHash.toString()}`);
35
+ log(` Status: ${receipt.status}`);
36
+ if (receipt.executionResult) {
37
+ log(` Execution result: ${receipt.executionResult}`);
38
+ }
39
+ if (receipt.error) {
40
+ log(` Error: ${receipt.error}`);
41
+ }
42
+
43
+ if (!effectsInBlock) {
44
+ return;
45
+ }
46
+
47
+ const effects = effectsInBlock.data;
48
+ const artifactMap = await getKnownArtifacts(wallet);
49
+
50
+ log(` Block: ${receipt.blockNumber} (${receipt.blockHash?.toString()})`);
51
+ if (receipt.transactionFee) {
52
+ log(` Fee: ${receipt.transactionFee.toString()}`);
53
+ }
54
+
55
+ // Public logs
56
+ const publicLogs = effects.publicLogs;
57
+ if (publicLogs.length > 0) {
58
+ log(' Logs:');
59
+ for (const publicLog of publicLogs) {
60
+ log(` ${publicLog.toHumanReadable()}`);
61
+ }
62
+ }
63
+
64
+ // Public data writes
65
+ const writes = effects.publicDataWrites;
66
+ if (writes.length > 0) {
67
+ log(' Public data writes:');
68
+ for (const write of writes) {
69
+ log(` Leaf ${write.leafSlot.toString()} = ${write.value.toString()}`);
70
+ }
71
+ }
72
+
73
+ // Created notes
74
+ const notes = effects.noteHashes;
75
+ if (notes.length > 0) {
76
+ log(' Created notes:');
77
+ log(` Total: ${notes.length}`);
78
+ for (const note of notes) {
79
+ log(` Note hash: ${note.toShortString()}`);
80
+ }
81
+ }
82
+
83
+ // Nullifiers
84
+ const nullifierCount = effects.nullifiers.length;
85
+ const { deployNullifiers, initNullifiers, classNullifiers } = await getKnownNullifiers(wallet, artifactMap);
86
+ if (nullifierCount > 0) {
87
+ log(' Nullifiers:');
88
+ for (const nullifier of effects.nullifiers) {
89
+ const deployed = deployNullifiers[nullifier.toString()];
90
+ const note = deployed
91
+ ? (await wallet.getNotes({ siloedNullifier: nullifier, contractAddress: deployed, scopes: 'ALL_SCOPES' }))[0]
92
+ : undefined;
93
+ const initialized = initNullifiers[nullifier.toString()];
94
+ const registered = classNullifiers[nullifier.toString()];
95
+ if (nullifier.toBuffer().equals(txHash.toBuffer())) {
96
+ log(` Transaction hash nullifier ${nullifier.toShortString()}`);
97
+ } else if (note) {
98
+ inspectNote(note, artifactMap, log, `Nullifier ${nullifier.toShortString()} for note`);
99
+ } else if (deployed) {
100
+ log(
101
+ ` Contract ${toFriendlyAddress(deployed, artifactMap)} deployed via nullifier ${nullifier.toShortString()}`,
102
+ );
103
+ } else if (initialized) {
104
+ log(
105
+ ` Contract ${toFriendlyAddress(
106
+ initialized,
107
+ artifactMap,
108
+ )} initialized via nullifier ${nullifier.toShortString()}`,
109
+ );
110
+ } else if (registered) {
111
+ log(` Class ${registered} registered via nullifier ${nullifier.toShortString()}`);
112
+ } else {
113
+ log(` Unknown nullifier ${nullifier.toString()}`);
114
+ }
115
+ }
116
+ }
117
+
118
+ // L2 to L1 messages
119
+ if (effects.l2ToL1Msgs.length > 0) {
120
+ log(` L2 to L1 messages:`);
121
+ for (const msg of effects.l2ToL1Msgs) {
122
+ log(` ${msg.toString()}`);
123
+ }
124
+ }
125
+ }
126
+
127
+ function inspectNote(note: NoteDao, artifactMap: ArtifactMap, log: LogFn, text = 'Note') {
128
+ const artifact = artifactMap[note.contractAddress.toString()];
129
+ const contract = artifact?.name ?? note.contractAddress.toString();
130
+ log(` ${text} at ${contract}`);
131
+ for (const field of note.note.items) {
132
+ log(` ${field.toString()}`);
133
+ }
134
+ }
135
+
136
+ function toFriendlyAddress(address: AztecAddress, artifactMap: ArtifactMap) {
137
+ const artifact = artifactMap[address.toString()];
138
+ if (!artifact) {
139
+ return address.toString();
140
+ }
141
+
142
+ return `${artifact.name}<${address.toString()}>`;
143
+ }
144
+
145
+ async function getKnownNullifiers(wallet: CLIWallet, artifactMap: ArtifactMap) {
146
+ const knownContracts = await wallet.getContracts();
147
+ const deployerAddress = ProtocolContractAddress.ContractInstanceRegistry;
148
+ const classRegistryAddress = ProtocolContractAddress.ContractClassRegistry;
149
+ const initNullifiers: Record<string, AztecAddress> = {};
150
+ const deployNullifiers: Record<string, AztecAddress> = {};
151
+ const classNullifiers: Record<string, string> = {};
152
+ for (const contract of knownContracts) {
153
+ initNullifiers[(await siloNullifier(contract, contract.toField())).toString()] = contract;
154
+ deployNullifiers[(await siloNullifier(deployerAddress, contract.toField())).toString()] = contract;
155
+ }
156
+ for (const artifact of Object.values(artifactMap)) {
157
+ classNullifiers[(await siloNullifier(classRegistryAddress, artifact.classId)).toString()] =
158
+ `${artifact.name}Class<${artifact.classId}>`;
159
+ }
160
+ return { initNullifiers, deployNullifiers, classNullifiers };
161
+ }
162
+
163
+ type ArtifactMap = Record<string, ContractArtifactWithClassId>;
164
+ type ContractArtifactWithClassId = ContractArtifact & { classId: Fr };
165
+
166
+ async function getKnownArtifacts(wallet: CLIWallet): Promise<ArtifactMap> {
167
+ const knownContractAddresses = await wallet.getContracts();
168
+ const knownContracts = (
169
+ await Promise.all(knownContractAddresses.map(contractAddress => wallet.getContractMetadata(contractAddress)))
170
+ ).map(contractMetadata => contractMetadata.instance);
171
+ const classIds = [...new Set(knownContracts.map(contract => contract?.currentContractClassId))];
172
+ const knownArtifacts = (
173
+ await Promise.all(classIds.map(classId => (classId ? wallet.getContractArtifact(classId) : undefined)))
174
+ ).map((artifact, index) => (artifact ? { ...artifact, classId: classIds[index] } : undefined));
175
+ const map: Record<string, ContractArtifactWithClassId> = {};
176
+ for (const instance of knownContracts) {
177
+ if (instance) {
178
+ const artifact = knownArtifacts.find(a =>
179
+ a?.classId?.equals(instance.currentContractClassId),
180
+ ) as ContractArtifactWithClassId;
181
+ if (artifact) {
182
+ map[instance.address.toString()] = artifact;
183
+ }
184
+ }
11
185
  }
186
+ return map;
12
187
  }
@@ -1,38 +1,47 @@
1
- import type { DeployAccountOptions, PXE } from '@aztec/aztec.js';
1
+ import { AztecAddress } from '@aztec/aztec.js/addresses';
2
+ import { NO_WAIT } from '@aztec/aztec.js/contracts';
3
+ import type { AztecNode } from '@aztec/aztec.js/node';
4
+ import type { DeployAccountOptions } from '@aztec/aztec.js/wallet';
2
5
  import { prettyPrintJSON } from '@aztec/cli/cli-utils';
3
- import { Fr } from '@aztec/foundation/fields';
6
+ import { Fr } from '@aztec/foundation/curves/bn254';
4
7
  import type { LogFn, Logger } from '@aztec/foundation/log';
8
+ import type { TxHash, TxReceipt } from '@aztec/stdlib/tx';
5
9
 
6
- import { type AccountType, createOrRetrieveAccount } from '../utils/accounts.js';
7
- import { type IFeeOpts, printGasEstimates } from '../utils/options/fees.js';
10
+ import { DEFAULT_TX_TIMEOUT_S } from '../utils/cli_wallet_and_node_wrapper.js';
11
+ import type { AccountType } from '../utils/constants.js';
12
+ import { CLIFeeArgs } from '../utils/options/fees.js';
13
+ import { printProfileResult } from '../utils/profiling.js';
14
+ import { CLIWallet } from '../utils/wallet.js';
8
15
 
9
16
  export async function createAccount(
10
- client: PXE,
17
+ wallet: CLIWallet,
18
+ aztecNode: AztecNode,
11
19
  accountType: AccountType,
12
20
  secretKey: Fr | undefined,
13
21
  publicKey: string | undefined,
14
22
  alias: string | undefined,
23
+ deployer: AztecAddress | undefined,
15
24
  registerOnly: boolean,
16
- publicDeploy: boolean,
17
25
  skipInitialization: boolean,
26
+ publicDeploy: boolean,
27
+ registerClass: boolean,
18
28
  wait: boolean,
19
- feeOpts: IFeeOpts,
29
+ feeOpts: CLIFeeArgs,
20
30
  json: boolean,
31
+ verbose: boolean,
21
32
  debugLogger: Logger,
22
33
  log: LogFn,
23
34
  ) {
24
35
  secretKey ??= Fr.random();
25
36
 
26
- const account = await createOrRetrieveAccount(
27
- client,
37
+ const account = await wallet.createOrRetrieveAccount(
28
38
  undefined /* address, we don't have it yet */,
29
- undefined /* db, as we want to create from scratch */,
30
39
  secretKey,
31
40
  accountType,
32
41
  Fr.ZERO,
33
42
  publicKey,
34
43
  );
35
- const salt = account.getInstance().salt;
44
+ const { salt } = account.getInstance();
36
45
  const { address, publicKeys, partialAddress } = await account.getCompleteAddress();
37
46
 
38
47
  const out: Record<string, any> = {};
@@ -45,7 +54,6 @@ export async function createAccount(
45
54
  out.partialAddress = partialAddress;
46
55
  out.salt = salt;
47
56
  out.initHash = account.getInstance().initializationHash;
48
- out.deployer = account.getInstance().deployer;
49
57
  } else {
50
58
  log(`\nNew account:\n`);
51
59
  log(`Address: ${address.toString()}`);
@@ -56,60 +64,87 @@ export async function createAccount(
56
64
  log(`Partial address: ${partialAddress.toString()}`);
57
65
  log(`Salt: ${salt.toString()}`);
58
66
  log(`Init hash: ${account.getInstance().initializationHash.toString()}`);
59
- log(`Deployer: ${account.getInstance().deployer.toString()}`);
60
67
  }
61
68
 
62
- let tx;
63
- let txReceipt;
64
- if (registerOnly) {
65
- await account.register();
66
- } else {
67
- const wallet = await account.getWallet();
68
- const deployOpts: DeployAccountOptions = {
69
- skipClassRegistration: !publicDeploy,
70
- skipPublicDeployment: !publicDeploy,
71
- skipInitialization: skipInitialization,
72
- ...(await feeOpts.toDeployAccountOpts(wallet)),
69
+ let txHash: TxHash | undefined;
70
+ let txReceipt: TxReceipt | undefined;
71
+ if (!registerOnly) {
72
+ const { paymentMethod, gasSettings } = await feeOpts.toUserFeeOptions(aztecNode, wallet, address);
73
+
74
+ const delegatedDeployment = deployer && !account.address.equals(deployer);
75
+ const from = delegatedDeployment ? deployer : AztecAddress.ZERO;
76
+
77
+ const deployAccountOpts: DeployAccountOptions = {
78
+ skipClassPublication: !registerClass,
79
+ skipInstancePublication: !publicDeploy,
80
+ skipInitialization,
81
+ from,
82
+ fee: { paymentMethod, gasSettings },
73
83
  };
84
+
85
+ const deployMethod = await account.getDeployMethod();
86
+ const sim = await deployMethod.simulate({
87
+ ...deployAccountOpts,
88
+ fee: { ...deployAccountOpts.fee, estimateGas: true },
89
+ });
90
+ // estimateGas: true guarantees these fields are present
91
+ const estimatedGas = sim.estimatedGas!;
92
+ const stats = sim.stats!;
93
+
74
94
  if (feeOpts.estimateOnly) {
75
- const gas = await (await account.getDeployMethod(deployOpts.deployWallet)).estimateGas(deployOpts);
76
95
  if (json) {
77
96
  out.fee = {
78
97
  gasLimits: {
79
- da: gas.gasLimits.daGas,
80
- l2: gas.gasLimits.l2Gas,
98
+ da: estimatedGas.gasLimits.daGas,
99
+ l2: estimatedGas.gasLimits.l2Gas,
81
100
  },
82
101
  teardownGasLimits: {
83
- da: gas.teardownGasLimits.daGas,
84
- l2: gas.teardownGasLimits,
102
+ da: estimatedGas.teardownGasLimits.daGas,
103
+ l2: estimatedGas.teardownGasLimits,
85
104
  },
86
105
  };
87
- } else {
88
- printGasEstimates(feeOpts, gas, log);
89
106
  }
90
107
  } else {
91
- tx = account.deploy(deployOpts);
92
- const txHash = await tx.getTxHash();
93
- debugLogger.debug(`Account contract tx sent with hash ${txHash}`);
94
- out.txHash = txHash;
108
+ if (verbose) {
109
+ printProfileResult(stats, log);
110
+ }
111
+
112
+ if (!json) {
113
+ log(`\nWaiting for account contract deployment...`);
114
+ }
115
+ const sendOpts = {
116
+ ...deployAccountOpts,
117
+ fee: deployAccountOpts.fee
118
+ ? {
119
+ ...deployAccountOpts.fee,
120
+ gasSettings: estimatedGas,
121
+ }
122
+ : undefined,
123
+ };
95
124
  if (wait) {
96
- if (!json) {
97
- log(`\nWaiting for account contract deployment...`);
98
- }
99
- txReceipt = await tx.wait();
125
+ const { receipt } = await deployMethod.send({
126
+ ...sendOpts,
127
+ wait: { timeout: DEFAULT_TX_TIMEOUT_S, returnReceipt: true },
128
+ });
129
+ txReceipt = receipt;
130
+ txHash = receipt.txHash;
100
131
  out.txReceipt = {
101
132
  status: txReceipt.status,
102
133
  transactionFee: txReceipt.transactionFee,
103
134
  };
135
+ } else {
136
+ ({ txHash } = await deployMethod.send({ ...sendOpts, wait: NO_WAIT }));
104
137
  }
138
+ debugLogger.debug(`Account contract tx sent with hash ${txHash.toString()}`);
139
+ out.txHash = txHash;
105
140
  }
106
141
  }
107
142
 
108
143
  if (json) {
109
144
  log(prettyPrintJSON(out));
110
145
  } else {
111
- if (tx) {
112
- log(`Deploy tx hash: ${await tx.getTxHash()}`);
146
+ if (txHash) {
147
+ log(`Deploy tx hash: ${txHash.toString()}`);
113
148
  }
114
149
  if (txReceipt) {
115
150
  log(`Deploy tx fee: ${txReceipt.transactionFee}`);
@@ -1,9 +1,13 @@
1
- import { type AccountWalletWithSecretKey, type AztecAddress, Contract } from '@aztec/aztec.js';
1
+ import type { AztecAddress } from '@aztec/aztec.js/addresses';
2
+ import { Contract } from '@aztec/aztec.js/contracts';
2
3
  import { prepTx } from '@aztec/cli/utils';
3
4
  import type { LogFn } from '@aztec/foundation/log';
4
5
 
6
+ import type { CLIWallet } from '../utils/wallet.js';
7
+
5
8
  export async function createAuthwit(
6
- wallet: AccountWalletWithSecretKey,
9
+ wallet: CLIWallet,
10
+ from: AztecAddress,
7
11
  functionName: string,
8
12
  caller: AztecAddress,
9
13
  functionArgsIn: any[],
@@ -24,10 +28,10 @@ export async function createAuthwit(
24
28
  );
25
29
  }
26
30
 
27
- const contract = await Contract.at(contractAddress, contractArtifact, wallet);
28
- const action = contract.methods[functionName](...functionArgs);
31
+ const contract = Contract.at(contractAddress, contractArtifact, wallet);
32
+ const call = await contract.methods[functionName](...functionArgs).getFunctionCall();
29
33
 
30
- const witness = await wallet.createAuthWit({ caller, action });
34
+ const witness = await wallet.createAuthWit(from, { caller, call });
31
35
 
32
36
  log(`Created authorization witness for action ${functionName} on contract ${contractAddress} for caller ${caller}`);
33
37
 
@@ -1,43 +1,53 @@
1
- import { type AccountWalletWithSecretKey, ContractDeployer, type DeployMethod, Fr, type PXE } from '@aztec/aztec.js';
2
- import { GITHUB_TAG_PREFIX, encodeArgs, getContractArtifact } from '@aztec/cli/utils';
1
+ import { AztecAddress } from '@aztec/aztec.js/addresses';
2
+ import type { DeployOptions } from '@aztec/aztec.js/contracts';
3
+ import { NO_WAIT } from '@aztec/aztec.js/contracts';
4
+ import { ContractDeployer } from '@aztec/aztec.js/deployment';
5
+ import { Fr } from '@aztec/aztec.js/fields';
6
+ import type { AztecNode } from '@aztec/aztec.js/node';
7
+ import { encodeArgs, getContractArtifact, prettyPrintJSON } from '@aztec/cli/utils';
3
8
  import type { LogFn, Logger } from '@aztec/foundation/log';
4
- import { getInitializer } from '@aztec/stdlib/abi';
9
+ import { getAllFunctionAbis, getInitializer } from '@aztec/stdlib/abi';
5
10
  import { PublicKeys } from '@aztec/stdlib/keys';
6
11
 
7
- import { type IFeeOpts, printGasEstimates } from '../utils/options/fees.js';
12
+ import { DEFAULT_TX_TIMEOUT_S } from '../utils/cli_wallet_and_node_wrapper.js';
13
+ import { CLIFeeArgs } from '../utils/options/fees.js';
14
+ import { printProfileResult } from '../utils/profiling.js';
15
+ import type { CLIWallet } from '../utils/wallet.js';
8
16
 
9
17
  export async function deploy(
10
- client: PXE,
11
- wallet: AccountWalletWithSecretKey,
18
+ wallet: CLIWallet,
19
+ node: AztecNode,
20
+ deployer: AztecAddress,
12
21
  artifactPath: string,
13
22
  json: boolean,
14
23
  publicKeys: PublicKeys | undefined,
15
24
  rawArgs: any[],
16
25
  salt: Fr | undefined,
17
26
  initializer: string | undefined,
18
- skipPublicDeployment: boolean,
19
- skipClassRegistration: boolean,
27
+ skipInstancePublication: boolean,
28
+ skipClassPublication: boolean,
20
29
  skipInitialization: boolean | undefined,
21
- universalDeploy: boolean | undefined,
22
30
  wait: boolean,
23
- feeOpts: IFeeOpts,
31
+ feeOpts: CLIFeeArgs,
32
+ verbose: boolean,
33
+ timeout: number = DEFAULT_TX_TIMEOUT_S,
24
34
  debugLogger: Logger,
25
35
  log: LogFn,
26
- logJson: (output: any) => void,
27
36
  ) {
37
+ const out: Record<string, any> = {};
28
38
  salt ??= Fr.random();
29
39
  const contractArtifact = await getContractArtifact(artifactPath, log);
30
- const constructorArtifact = getInitializer(contractArtifact, initializer);
40
+ const hasInitializer = getAllFunctionAbis(contractArtifact).some(fn => fn.isInitializer);
41
+ const constructorArtifact = hasInitializer ? getInitializer(contractArtifact, initializer) : undefined;
31
42
 
32
- const nodeInfo = await client.getNodeInfo();
33
- const expectedAztecNrVersion = `${GITHUB_TAG_PREFIX}-v${nodeInfo.nodeVersion}`;
34
- if (contractArtifact.aztecNrVersion && contractArtifact.aztecNrVersion !== expectedAztecNrVersion) {
35
- log(
36
- `\nWarning: Contract was compiled with a different version of Aztec.nr: ${contractArtifact.aztecNrVersion}. Consider updating Aztec.nr to ${expectedAztecNrVersion}\n`,
37
- );
38
- }
43
+ // TODO(#12081): Add contractArtifact.noirVersion and check here (via Noir.lock)?
39
44
 
40
- const deployer = new ContractDeployer(contractArtifact, wallet, publicKeys ?? PublicKeys.default(), initializer);
45
+ const contractDeployer = new ContractDeployer(
46
+ contractArtifact,
47
+ wallet,
48
+ publicKeys ?? PublicKeys.default(),
49
+ initializer,
50
+ );
41
51
 
42
52
  let args = [];
43
53
  if (rawArgs.length > 0) {
@@ -49,65 +59,94 @@ export async function deploy(
49
59
  debugLogger.debug(`Encoded arguments: ${args.join(', ')}`);
50
60
  }
51
61
 
52
- const deploy = deployer.deploy(...args);
53
- const deployOpts: Parameters<DeployMethod['send']>[0] = {
54
- ...(await feeOpts.toSendOpts(wallet)),
62
+ const deploy = contractDeployer.deploy(...args);
63
+ const { paymentMethod, gasSettings } = await feeOpts.toUserFeeOptions(node, wallet, deployer);
64
+ const deployOpts: DeployOptions = {
65
+ fee: { gasSettings, paymentMethod },
66
+ from: deployer ?? AztecAddress.ZERO,
55
67
  contractAddressSalt: salt,
56
- universalDeploy,
57
- skipClassRegistration,
68
+ universalDeploy: !deployer,
69
+ skipClassPublication,
58
70
  skipInitialization,
59
- skipPublicDeployment,
71
+ skipInstancePublication,
60
72
  };
61
73
 
62
- if (feeOpts.estimateOnly) {
63
- const gas = await deploy.estimateGas(deployOpts);
64
- printGasEstimates(feeOpts, gas, log);
65
- return;
66
- }
67
-
68
- const tx = deploy.send(deployOpts);
74
+ const sim = await deploy.simulate({
75
+ ...deployOpts,
76
+ fee: { ...deployOpts.fee, estimateGas: true },
77
+ });
78
+ // estimateGas: true guarantees these fields are present
79
+ const estimatedGas = sim.estimatedGas!;
80
+ const stats = sim.stats!;
69
81
 
70
- const txHash = await tx.getTxHash();
71
- debugLogger.debug(`Deploy tx sent with hash ${txHash}`);
72
- if (wait) {
73
- const deployed = await tx.wait();
74
- const { address, partialAddress, instance } = deployed.contract;
82
+ if (feeOpts.estimateOnly) {
75
83
  if (json) {
76
- logJson({
77
- address: address.toString(),
78
- partialAddress: (await partialAddress).toString(),
79
- initializationHash: instance.initializationHash.toString(),
80
- salt: salt.toString(),
81
- transactionFee: deployed.transactionFee?.toString(),
82
- });
83
- } else {
84
- log(`Contract deployed at ${address.toString()}`);
85
- log(`Contract partial address ${(await partialAddress).toString()}`);
86
- log(`Contract init hash ${instance.initializationHash.toString()}`);
87
- log(`Deployment tx hash: ${txHash.toString()}`);
88
- log(`Deployment salt: ${salt.toString()}`);
89
- log(`Deployment fee: ${deployed.transactionFee}`);
84
+ out.fee = {
85
+ gasLimits: {
86
+ da: estimatedGas.gasLimits.daGas,
87
+ l2: estimatedGas.gasLimits.l2Gas,
88
+ },
89
+ teardownGasLimits: {
90
+ da: estimatedGas.teardownGasLimits.daGas,
91
+ l2: estimatedGas.teardownGasLimits,
92
+ },
93
+ };
90
94
  }
91
95
  } else {
96
+ if (verbose) {
97
+ printProfileResult(stats, log);
98
+ }
99
+
92
100
  const { address, partialAddress } = deploy;
93
101
  const instance = await deploy.getInstance();
94
- if (json) {
95
- logJson({
96
- address: address?.toString() ?? 'N/A',
97
- partialAddress: (await partialAddress)?.toString() ?? 'N/A',
98
- txHash: txHash.toString(),
99
- initializationHash: instance.initializationHash.toString(),
100
- salt: salt.toString(),
101
- deployer: instance.deployer.toString(),
102
- });
102
+
103
+ if (wait) {
104
+ const { receipt } = await deploy.send({ ...deployOpts, wait: { timeout, returnReceipt: true } });
105
+ const txHash = receipt.txHash;
106
+ debugLogger.debug(`Deploy tx sent with hash ${txHash.toString()}`);
107
+ out.hash = txHash;
108
+
109
+ if (!json) {
110
+ log(`Contract deployed at ${address?.toString()}`);
111
+ log(`Contract partial address ${(await partialAddress)?.toString()}`);
112
+ log(`Contract init hash ${instance.initializationHash.toString()}`);
113
+ log(`Deployment tx hash: ${txHash.toString()}`);
114
+ log(`Deployment salt: ${salt.toString()}`);
115
+ log(`Deployer: ${instance.deployer.toString()}`);
116
+ log(`Transaction fee: ${receipt.transactionFee?.toString()}`);
117
+ } else {
118
+ out.contract = {
119
+ address: address?.toString(),
120
+ partialAddress: (await partialAddress)?.toString(),
121
+ initializationHash: instance.initializationHash.toString(),
122
+ salt: salt.toString(),
123
+ transactionFee: receipt.transactionFee?.toString(),
124
+ };
125
+ }
103
126
  } else {
104
- log(`Contract deployed at ${address?.toString()}`);
105
- log(`Contract partial address ${(await partialAddress)?.toString()}`);
106
- log(`Contract init hash ${instance.initializationHash.toString()}`);
107
- log(`Deployment tx hash: ${txHash.toString()}`);
108
- log(`Deployment salt: ${salt.toString()}`);
109
- log(`Deployer: ${instance.deployer.toString()}`);
127
+ const { txHash } = await deploy.send({ ...deployOpts, wait: NO_WAIT });
128
+ debugLogger.debug(`Deploy tx sent with hash ${txHash.toString()}`);
129
+ out.hash = txHash;
130
+
131
+ if (!json) {
132
+ log(`Contract deployed at ${address?.toString()}`);
133
+ log(`Contract partial address ${(await partialAddress)?.toString()}`);
134
+ log(`Contract init hash ${instance.initializationHash.toString()}`);
135
+ log(`Deployment tx hash: ${txHash.toString()}`);
136
+ log(`Deployment salt: ${salt.toString()}`);
137
+ log(`Deployer: ${instance.deployer.toString()}`);
138
+ } else {
139
+ out.contract = {
140
+ address: address?.toString(),
141
+ partialAddress: (await partialAddress)?.toString(),
142
+ initializationHash: instance.initializationHash.toString(),
143
+ salt: salt.toString(),
144
+ };
145
+ }
110
146
  }
111
147
  }
148
+ if (json) {
149
+ log(prettyPrintJSON(out));
150
+ }
112
151
  return deploy.address;
113
152
  }