@aztec/cli-wallet 0.0.1-commit.5daedc8 → 0.0.1-commit.6201a7b05

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 (70) hide show
  1. package/dest/bin/index.d.ts +1 -0
  2. package/dest/bin/index.js +1 -0
  3. package/dest/cmds/authorize_action.d.ts +2 -2
  4. package/dest/cmds/authorize_action.d.ts.map +1 -1
  5. package/dest/cmds/authorize_action.js +4 -2
  6. package/dest/cmds/bridge_fee_juice.d.ts +2 -2
  7. package/dest/cmds/bridge_fee_juice.d.ts.map +1 -1
  8. package/dest/cmds/bridge_fee_juice.js +3 -2
  9. package/dest/cmds/check_tx.d.ts +1 -1
  10. package/dest/cmds/check_tx.d.ts.map +1 -1
  11. package/dest/cmds/check_tx.js +45 -14
  12. package/dest/cmds/create_account.d.ts +7 -5
  13. package/dest/cmds/create_account.d.ts.map +1 -1
  14. package/dest/cmds/create_account.js +43 -26
  15. package/dest/cmds/create_authwit.d.ts +2 -2
  16. package/dest/cmds/create_authwit.d.ts.map +1 -1
  17. package/dest/cmds/deploy.d.ts +4 -3
  18. package/dest/cmds/deploy.d.ts.map +1 -1
  19. package/dest/cmds/deploy.js +56 -29
  20. package/dest/cmds/deploy_account.d.ts +4 -3
  21. package/dest/cmds/deploy_account.d.ts.map +1 -1
  22. package/dest/cmds/deploy_account.js +37 -20
  23. package/dest/cmds/get_fee_juice_balance.d.ts +5 -0
  24. package/dest/cmds/get_fee_juice_balance.d.ts.map +1 -0
  25. package/dest/cmds/get_fee_juice_balance.js +27 -0
  26. package/dest/cmds/index.d.ts +1 -1
  27. package/dest/cmds/index.d.ts.map +1 -1
  28. package/dest/cmds/index.js +31 -15
  29. package/dest/cmds/send.d.ts +5 -4
  30. package/dest/cmds/send.d.ts.map +1 -1
  31. package/dest/cmds/send.js +32 -16
  32. package/dest/cmds/simulate.d.ts +1 -1
  33. package/dest/cmds/simulate.d.ts.map +1 -1
  34. package/dest/cmds/simulate.js +3 -3
  35. package/dest/storage/wallet_db.d.ts +8 -3
  36. package/dest/storage/wallet_db.d.ts.map +1 -1
  37. package/dest/storage/wallet_db.js +61 -32
  38. package/dest/utils/constants.d.ts +4 -0
  39. package/dest/utils/constants.d.ts.map +1 -0
  40. package/dest/utils/constants.js +7 -0
  41. package/dest/utils/options/fees.d.ts +3 -2
  42. package/dest/utils/options/fees.d.ts.map +1 -1
  43. package/dest/utils/options/fees.js +34 -11
  44. package/dest/utils/options/options.d.ts +2 -2
  45. package/dest/utils/options/options.d.ts.map +1 -1
  46. package/dest/utils/options/options.js +1 -1
  47. package/dest/utils/profiling.d.ts +1 -1
  48. package/dest/utils/profiling.d.ts.map +1 -1
  49. package/dest/utils/profiling.js +9 -1
  50. package/dest/utils/wallet.d.ts +14 -9
  51. package/dest/utils/wallet.d.ts.map +1 -1
  52. package/dest/utils/wallet.js +93 -56
  53. package/package.json +17 -17
  54. package/src/bin/index.ts +1 -0
  55. package/src/cmds/authorize_action.ts +1 -1
  56. package/src/cmds/bridge_fee_juice.ts +3 -2
  57. package/src/cmds/check_tx.ts +50 -19
  58. package/src/cmds/create_account.ts +47 -26
  59. package/src/cmds/deploy.ts +55 -27
  60. package/src/cmds/deploy_account.ts +38 -19
  61. package/src/cmds/get_fee_juice_balance.ts +37 -0
  62. package/src/cmds/index.ts +59 -6
  63. package/src/cmds/send.ts +32 -12
  64. package/src/cmds/simulate.ts +4 -7
  65. package/src/storage/wallet_db.ts +65 -38
  66. package/src/utils/constants.ts +4 -0
  67. package/src/utils/options/fees.ts +41 -11
  68. package/src/utils/options/options.ts +1 -1
  69. package/src/utils/profiling.ts +15 -1
  70. package/src/utils/wallet.ts +103 -70
@@ -1,11 +1,14 @@
1
1
  import { EcdsaRAccountContract, EcdsaRSSHAccountContract } from '@aztec/accounts/ecdsa';
2
2
  import { SchnorrAccountContract } from '@aztec/accounts/schnorr';
3
- import { StubAccountContractArtifact, createStubAccount } from '@aztec/accounts/stub';
3
+ import { StubEcdsaAccountContractArtifact, createStubEcdsaAccount } from '@aztec/accounts/stub/ecdsa';
4
+ import { StubSchnorrAccountContractArtifact, createStubSchnorrAccount } from '@aztec/accounts/stub/schnorr';
4
5
  import { getIdentities } from '@aztec/accounts/utils';
5
- import { SignerlessAccount } from '@aztec/aztec.js/account';
6
+ import { NO_FROM } from '@aztec/aztec.js/account';
6
7
  import { getContractInstanceFromInstantiationParams, getGasLimits } from '@aztec/aztec.js/contracts';
7
8
  import { AccountManager } from '@aztec/aztec.js/wallet';
8
- import { Fr } from '@aztec/foundation/fields';
9
+ import { TxSimulationResultWithAppOffset } from '@aztec/aztec.js/wallet';
10
+ import { DefaultEntrypoint } from '@aztec/entrypoints/default';
11
+ import { Fr } from '@aztec/foundation/curves/bn254';
9
12
  import { createPXE, getPXEConfig } from '@aztec/pxe/server';
10
13
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
11
14
  import { deriveSigningKey } from '@aztec/stdlib/keys';
@@ -13,13 +16,6 @@ import { ExecutionPayload, mergeExecutionPayloads } from '@aztec/stdlib/tx';
13
16
  import { BaseWallet } from '@aztec/wallet-sdk/base-wallet';
14
17
  import { extractECDSAPublicKeyFromBase64String } from './ecdsa.js';
15
18
  import { printGasEstimates } from './options/fees.js';
16
- export const AccountTypes = [
17
- 'schnorr',
18
- 'ecdsasecp256r1',
19
- 'ecdsasecp256r1ssh',
20
- 'ecdsasecp256k1'
21
- ];
22
- export const BASE_FEE_PADDING = 0.5;
23
19
  export class CLIWallet extends BaseWallet {
24
20
  userLog;
25
21
  db;
@@ -35,33 +31,42 @@ export class CLIWallet extends BaseWallet {
35
31
  }
36
32
  async getAccounts() {
37
33
  const accounts = await this.db?.listAliases('accounts') ?? [];
38
- return Promise.resolve(accounts.map(({ key, value })=>({
39
- alias: value,
40
- item: AztecAddress.fromString(key)
41
- })));
34
+ return Promise.resolve(accounts.map(({ key, value })=>{
35
+ const alias = key.includes(':') ? key.slice(key.indexOf(':') + 1) : key;
36
+ return {
37
+ alias,
38
+ item: AztecAddress.fromString(value)
39
+ };
40
+ }));
42
41
  }
43
42
  async createCancellationTxExecutionRequest(from, txNonce, increasedFee) {
44
43
  const executionPayload = ExecutionPayload.empty();
45
- const feeOptions = await this.completeFeeOptions(from, executionPayload.feePayer, increasedFee.gasSettings);
44
+ const feeOptions = await this.completeFeeOptions({
45
+ from,
46
+ feePayer: executionPayload.feePayer,
47
+ gasSettings: increasedFee.gasSettings
48
+ });
46
49
  const feeExecutionPayload = await feeOptions.walletFeePaymentMethod?.getExecutionPayload();
47
50
  const fromAccount = await this.getAccountFromAddress(from);
51
+ const chainInfo = await this.getChainInfo();
48
52
  const executionOptions = {
49
53
  txNonce,
50
54
  cancellable: this.cancellableTransactions,
55
+ // If from is an address, feeOptions include the way the account contract should handle the fee payment
51
56
  feePaymentMethodOptions: feeOptions.accountFeePaymentMethodOptions
52
57
  };
53
- return await fromAccount.createTxExecutionRequest(feeExecutionPayload ?? executionPayload, feeOptions.gasSettings, executionOptions);
58
+ return await fromAccount.createTxExecutionRequest(feeExecutionPayload ?? executionPayload, feeOptions.gasSettings, chainInfo, executionOptions);
54
59
  }
55
60
  async proveCancellationTx(from, txNonce, increasedFee) {
56
61
  const cancellationTxRequest = await this.createCancellationTxExecutionRequest(from, txNonce, increasedFee);
57
- return await this.pxe.proveTx(cancellationTxRequest);
62
+ return await this.pxe.proveTx(cancellationTxRequest, {
63
+ scopes: this.scopesFrom(from),
64
+ senderForTags: from
65
+ });
58
66
  }
59
67
  async getAccountFromAddress(address) {
60
68
  let account;
61
- if (address.equals(AztecAddress.ZERO)) {
62
- const chainInfo = await this.getChainInfo();
63
- account = new SignerlessAccount(chainInfo);
64
- } else if (this.accountCache.has(address.toString())) {
69
+ if (this.accountCache.has(address.toString())) {
65
70
  return this.accountCache.get(address.toString());
66
71
  } else {
67
72
  const accountManager = await this.createOrRetrieveAccount(address);
@@ -125,62 +130,89 @@ export class CLIWallet extends BaseWallet {
125
130
  }
126
131
  return account;
127
132
  }
128
- async getFakeAccountDataFor(address) {
129
- const chainInfo = await this.getChainInfo();
133
+ /**
134
+ * Creates a stub account that impersonates the given address, allowing kernelless simulations
135
+ * to bypass the account's authorization mechanisms via contract overrides.
136
+ * @param address - The address of the account to impersonate
137
+ * @returns The stub account, contract instance, and artifact for simulation
138
+ */ async getFakeAccountDataFor(address) {
130
139
  const originalAccount = await this.getAccountFromAddress(address);
131
140
  const originalAddress = originalAccount.getCompleteAddress();
132
- const { contractInstance } = await this.pxe.getContractMetadata(originalAddress.address);
141
+ const contractInstance = await this.pxe.getContractInstance(originalAddress.address);
133
142
  if (!contractInstance) {
134
143
  throw new Error(`No contract instance found for address: ${originalAddress.address}`);
135
144
  }
136
- const stubAccount = createStubAccount(originalAddress, chainInfo);
137
- const instance = await getContractInstanceFromInstantiationParams(StubAccountContractArtifact, {
145
+ const { type } = await this.db.retrieveAccount(address);
146
+ const isSchnorr = type === 'schnorr';
147
+ const artifact = isSchnorr ? StubSchnorrAccountContractArtifact : StubEcdsaAccountContractArtifact;
148
+ const stubAccount = isSchnorr ? createStubSchnorrAccount(originalAddress) : createStubEcdsaAccount(originalAddress);
149
+ const instance = await getContractInstanceFromInstantiationParams(artifact, {
138
150
  salt: Fr.random()
139
151
  });
140
152
  return {
141
153
  account: stubAccount,
142
154
  instance,
143
- artifact: StubAccountContractArtifact
155
+ artifact
144
156
  };
145
157
  }
146
158
  async simulateTx(executionPayload, opts) {
147
- let simulationResults;
148
- const feeOptions = opts.fee?.estimateGas ? await this.completeFeeOptionsForEstimation(opts.from, executionPayload.feePayer, opts.fee?.gasSettings) : await this.completeFeeOptions(opts.from, executionPayload.feePayer, opts.fee?.gasSettings);
159
+ const simulationResults = await super.simulateTx(executionPayload, opts);
160
+ if (opts.fee?.estimateGas) {
161
+ const feeOptions = await this.completeFeeOptions({
162
+ from: opts.from,
163
+ feePayer: executionPayload.feePayer,
164
+ gasSettings: opts.fee?.gasSettings
165
+ });
166
+ const limits = getGasLimits(simulationResults, opts.fee?.estimatedGasPadding);
167
+ printGasEstimates(feeOptions, limits, this.userLog);
168
+ }
169
+ return simulationResults;
170
+ }
171
+ /**
172
+ * Uses a stub account for kernelless simulation, bypassing real account authorization.
173
+ * Uses DefaultEntrypoint directly for NO_FROM transactions.
174
+ */ async simulateViaEntrypoint(executionPayload, opts) {
175
+ const { from, feeOptions, additionalScopes, sendMessagesAs } = opts;
176
+ const scopes = this.scopesFrom(from, additionalScopes);
149
177
  const feeExecutionPayload = await feeOptions.walletFeePaymentMethod?.getExecutionPayload();
150
- const executionOptions = {
151
- txNonce: Fr.random(),
152
- cancellable: this.cancellableTransactions,
153
- feePaymentMethodOptions: feeOptions.accountFeePaymentMethodOptions
154
- };
155
178
  const finalExecutionPayload = feeExecutionPayload ? mergeExecutionPayloads([
156
179
  feeExecutionPayload,
157
180
  executionPayload
158
181
  ]) : executionPayload;
159
- // Kernelless simulations using the multicall entrypoints are not currently supported,
160
- // since we only override proper account contracts.
161
- // TODO: allow disabling kernels even when no overrides are necessary
162
- if (opts.from.equals(AztecAddress.ZERO)) {
163
- const fromAccount = await this.getAccountFromAddress(opts.from);
164
- const txRequest = await fromAccount.createTxExecutionRequest(finalExecutionPayload, feeOptions.gasSettings, executionOptions);
165
- simulationResults = await this.pxe.simulateTx(txRequest, true, opts?.skipTxValidation, opts?.skipFeeEnforcement ?? true);
182
+ const chainInfo = await this.getChainInfo();
183
+ let overrides;
184
+ let txRequest;
185
+ if (from === NO_FROM) {
186
+ const entrypoint = new DefaultEntrypoint();
187
+ txRequest = await entrypoint.createTxExecutionRequest(finalExecutionPayload, feeOptions.gasSettings, chainInfo);
166
188
  } else {
167
- const { account: fromAccount, instance, artifact } = await this.getFakeAccountDataFor(opts.from);
168
- const txRequest = await fromAccount.createTxExecutionRequest(finalExecutionPayload, feeOptions.gasSettings, executionOptions);
169
- const contractOverrides = {
170
- [opts.from.toString()]: {
171
- instance,
172
- artifact
189
+ const { account, instance, artifact } = await this.getFakeAccountDataFor(from);
190
+ overrides = {
191
+ contracts: {
192
+ [from.toString()]: {
193
+ instance,
194
+ artifact
195
+ }
173
196
  }
174
197
  };
175
- simulationResults = await this.pxe.simulateTx(txRequest, true, true, true, {
176
- contracts: contractOverrides
177
- });
178
- }
179
- if (opts.fee?.estimateGas) {
180
- const limits = getGasLimits(simulationResults, opts.fee?.estimatedGasPadding);
181
- printGasEstimates(feeOptions, limits, this.userLog);
198
+ const executionOptions = {
199
+ txNonce: Fr.random(),
200
+ cancellable: this.cancellableTransactions,
201
+ // If from is an address, feeOptions include the way the account contract should handle the fee payment
202
+ feePaymentMethodOptions: feeOptions.accountFeePaymentMethodOptions
203
+ };
204
+ txRequest = await account.createTxExecutionRequest(finalExecutionPayload, feeOptions.gasSettings, chainInfo, executionOptions);
182
205
  }
183
- return simulationResults;
206
+ const result = await this.pxe.simulateTx(txRequest, {
207
+ simulatePublic: true,
208
+ skipFeeEnforcement: true,
209
+ skipTxValidation: true,
210
+ overrides,
211
+ scopes,
212
+ senderForTags: this.senderForTagsFrom(from, sendMessagesAs)
213
+ });
214
+ const appCallOffset = await this.computeAppCallOffset(from, feeOptions);
215
+ return TxSimulationResultWithAppOffset.fromResultAndOffset(result, appCallOffset);
184
216
  }
185
217
  // Exposed because of the `aztec-wallet get-tx` command. It has been decided that it's fine to keep around because
186
218
  // this is just a CLI wallet.
@@ -190,6 +222,11 @@ export class CLIWallet extends BaseWallet {
190
222
  // Exposed because of the `aztec-wallet get-tx` command. It has been decided that it's fine to keep around because
191
223
  // this is just a CLI wallet.
192
224
  getNotes(filter) {
193
- return this.pxe.getNotes(filter);
225
+ return this.pxe.debug.getNotes(filter);
226
+ }
227
+ // Exposed because of the `aztec-wallet get-tx` command. It has been decided that it's fine to keep around because
228
+ // this is just a CLI wallet.
229
+ getContractArtifact(id) {
230
+ return this.pxe.getContractArtifact(id);
194
231
  }
195
232
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/cli-wallet",
3
- "version": "0.0.1-commit.5daedc8",
3
+ "version": "0.0.1-commit.6201a7b05",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/cmds/index.js",
@@ -20,8 +20,8 @@
20
20
  "start": "node --no-warnings ./dest/bin",
21
21
  "start:debug": "node --inspect=0.0.0.0:9221 --no-warnings ./dest/bin",
22
22
  "dev": "LOG_LEVEL=debug && node ./dest/bin",
23
- "build": "yarn clean && tsgo -b",
24
- "build:dev": "tsgo -b --watch",
23
+ "build": "yarn clean && ../scripts/tsc.sh",
24
+ "build:dev": "../scripts/tsc.sh --watch",
25
25
  "clean": "rm -rf ./dest .tsbuildinfo",
26
26
  "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}"
27
27
  },
@@ -67,19 +67,19 @@
67
67
  ]
68
68
  },
69
69
  "dependencies": {
70
- "@aztec/accounts": "0.0.1-commit.5daedc8",
71
- "@aztec/aztec.js": "0.0.1-commit.5daedc8",
72
- "@aztec/bb.js": "0.0.1-commit.5daedc8",
73
- "@aztec/cli": "0.0.1-commit.5daedc8",
74
- "@aztec/entrypoints": "0.0.1-commit.5daedc8",
75
- "@aztec/ethereum": "0.0.1-commit.5daedc8",
76
- "@aztec/foundation": "0.0.1-commit.5daedc8",
77
- "@aztec/kv-store": "0.0.1-commit.5daedc8",
78
- "@aztec/noir-contracts.js": "0.0.1-commit.5daedc8",
79
- "@aztec/noir-noirc_abi": "0.0.1-commit.5daedc8",
80
- "@aztec/pxe": "0.0.1-commit.5daedc8",
81
- "@aztec/stdlib": "0.0.1-commit.5daedc8",
82
- "@aztec/wallet-sdk": "0.0.1-commit.5daedc8",
70
+ "@aztec/accounts": "0.0.1-commit.6201a7b05",
71
+ "@aztec/aztec.js": "0.0.1-commit.6201a7b05",
72
+ "@aztec/bb.js": "0.0.1-commit.6201a7b05",
73
+ "@aztec/cli": "0.0.1-commit.6201a7b05",
74
+ "@aztec/entrypoints": "0.0.1-commit.6201a7b05",
75
+ "@aztec/ethereum": "0.0.1-commit.6201a7b05",
76
+ "@aztec/foundation": "0.0.1-commit.6201a7b05",
77
+ "@aztec/kv-store": "0.0.1-commit.6201a7b05",
78
+ "@aztec/noir-contracts.js": "0.0.1-commit.6201a7b05",
79
+ "@aztec/noir-noirc_abi": "0.0.1-commit.6201a7b05",
80
+ "@aztec/pxe": "0.0.1-commit.6201a7b05",
81
+ "@aztec/stdlib": "0.0.1-commit.6201a7b05",
82
+ "@aztec/wallet-sdk": "0.0.1-commit.6201a7b05",
83
83
  "commander": "^12.1.0",
84
84
  "inquirer": "^10.1.8",
85
85
  "source-map-support": "^0.5.21",
@@ -90,7 +90,7 @@
90
90
  "@types/jest": "^30.0.0",
91
91
  "@types/node": "^22.15.17",
92
92
  "@types/source-map-support": "^0.5.10",
93
- "@typescript/native-preview": "7.0.0-dev.20251126.1",
93
+ "@typescript/native-preview": "7.0.0-dev.20260113.1",
94
94
  "jest": "^30.0.0",
95
95
  "jest-mock-extended": "^4.0.0",
96
96
  "ts-jest": "^29.4.0",
package/src/bin/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env node
1
2
  import { computeSecretHash } from '@aztec/aztec.js/crypto';
2
3
  import { Fr } from '@aztec/aztec.js/fields';
3
4
  import { createAztecNodeClient } from '@aztec/aztec.js/node';
@@ -39,7 +39,7 @@ export async function authorizeAction(
39
39
  { caller, action },
40
40
  true,
41
41
  );
42
- const witness = await setAuthwitnessInteraction.send().wait({ timeout: DEFAULT_TX_TIMEOUT_S });
42
+ const witness = await setAuthwitnessInteraction.send({ wait: { timeout: DEFAULT_TX_TIMEOUT_S } });
43
43
 
44
44
  log(`Authorized action ${functionName} on contract ${contractAddress} for caller ${caller}`);
45
45
 
@@ -2,8 +2,9 @@ import { L1FeeJuicePortalManager } from '@aztec/aztec.js/ethereum';
2
2
  import type { AztecNode } from '@aztec/aztec.js/node';
3
3
  import { ProtocolContractAddress } from '@aztec/aztec.js/protocol';
4
4
  import { prettyPrintJSON } from '@aztec/cli/utils';
5
- import { createEthereumChain, createExtendedL1Client } from '@aztec/ethereum';
6
- import { Fr } from '@aztec/foundation/fields';
5
+ import { createEthereumChain } from '@aztec/ethereum/chain';
6
+ import { createExtendedL1Client } from '@aztec/ethereum/client';
7
+ import { Fr } from '@aztec/foundation/curves/bn254';
7
8
  import type { LogFn, Logger } from '@aztec/foundation/log';
8
9
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
9
10
  import { getNonNullifiedL1ToL2MessageWitness } from '@aztec/stdlib/messaging';
@@ -1,11 +1,15 @@
1
1
  import type { ContractArtifact } from '@aztec/aztec.js/abi';
2
- import type { AztecAddress } from '@aztec/aztec.js/addresses';
2
+ import { AztecAddress } from '@aztec/aztec.js/addresses';
3
3
  import { Fr } from '@aztec/aztec.js/fields';
4
4
  import type { AztecNode } from '@aztec/aztec.js/node';
5
5
  import { ProtocolContractAddress } from '@aztec/aztec.js/protocol';
6
6
  import type { TxHash } from '@aztec/aztec.js/tx';
7
7
  import type { LogFn } from '@aztec/foundation/log';
8
- import { siloNullifier } from '@aztec/stdlib/hash';
8
+ import {
9
+ computeSiloedPrivateInitializationNullifier,
10
+ computeSiloedPublicInitializationNullifier,
11
+ siloNullifier,
12
+ } from '@aztec/stdlib/hash';
9
13
  import { NoteDao } from '@aztec/stdlib/note';
10
14
 
11
15
  import type { CLIWallet } from '../utils/wallet.js';
@@ -32,7 +36,10 @@ async function inspectTx(wallet: CLIWallet, aztecNode: AztecNode, txHash: TxHash
32
36
  const [receipt, effectsInBlock] = await Promise.all([aztecNode.getTxReceipt(txHash), aztecNode.getTxEffect(txHash)]);
33
37
  // Base tx data
34
38
  log(`Tx ${txHash.toString()}`);
35
- log(` Status: ${receipt.status} ${effectsInBlock ? `(${effectsInBlock.data.revertCode.getDescription()})` : ''}`);
39
+ log(` Status: ${receipt.status}`);
40
+ if (receipt.executionResult) {
41
+ log(` Execution result: ${receipt.executionResult}`);
42
+ }
36
43
  if (receipt.error) {
37
44
  log(` Error: ${receipt.error}`);
38
45
  }
@@ -80,12 +87,13 @@ async function inspectTx(wallet: CLIWallet, aztecNode: AztecNode, txHash: TxHash
80
87
  // Nullifiers
81
88
  const nullifierCount = effects.nullifiers.length;
82
89
  const { deployNullifiers, initNullifiers, classNullifiers } = await getKnownNullifiers(wallet, artifactMap);
90
+ const accounts = (await wallet.getAccounts()).map(a => a.item);
83
91
  if (nullifierCount > 0) {
84
92
  log(' Nullifiers:');
85
93
  for (const nullifier of effects.nullifiers) {
86
94
  const deployed = deployNullifiers[nullifier.toString()];
87
95
  const note = deployed
88
- ? (await wallet.getNotes({ siloedNullifier: nullifier, contractAddress: deployed }))[0]
96
+ ? (await wallet.getNotes({ siloedNullifier: nullifier, contractAddress: deployed, scopes: accounts }))[0]
89
97
  : undefined;
90
98
  const initialized = initNullifiers[nullifier.toString()];
91
99
  const registered = classNullifiers[nullifier.toString()];
@@ -141,22 +149,49 @@ function toFriendlyAddress(address: AztecAddress, artifactMap: ArtifactMap) {
141
149
 
142
150
  async function getKnownNullifiers(wallet: CLIWallet, artifactMap: ArtifactMap) {
143
151
  const knownContracts = await wallet.getContracts();
144
- const deployerAddress = ProtocolContractAddress.ContractInstanceRegistry;
145
- const classRegistryAddress = ProtocolContractAddress.ContractClassRegistry;
152
+
153
+ const [contractResults, classResults] = await Promise.all([
154
+ Promise.all(knownContracts.map(contract => getContractNullifiers(wallet, contract))),
155
+ Promise.all(Object.values(artifactMap).map(artifact => getClassNullifier(artifact))),
156
+ ]);
157
+
146
158
  const initNullifiers: Record<string, AztecAddress> = {};
147
159
  const deployNullifiers: Record<string, AztecAddress> = {};
148
160
  const classNullifiers: Record<string, string> = {};
149
- for (const contract of knownContracts) {
150
- initNullifiers[(await siloNullifier(contract, contract.toField())).toString()] = contract;
151
- deployNullifiers[(await siloNullifier(deployerAddress, contract.toField())).toString()] = contract;
161
+
162
+ for (const { contract, deployNullifier, privateInitNullifier, publicInitNullifier } of contractResults) {
163
+ deployNullifiers[deployNullifier.toString()] = contract;
164
+ if (privateInitNullifier) {
165
+ initNullifiers[privateInitNullifier.toString()] = contract;
166
+ }
167
+ initNullifiers[publicInitNullifier.toString()] = contract;
152
168
  }
153
- for (const artifact of Object.values(artifactMap)) {
154
- classNullifiers[(await siloNullifier(classRegistryAddress, artifact.classId)).toString()] =
155
- `${artifact.name}Class<${artifact.classId}>`;
169
+ for (const { nullifier, label } of classResults) {
170
+ classNullifiers[nullifier.toString()] = label;
156
171
  }
172
+
157
173
  return { initNullifiers, deployNullifiers, classNullifiers };
158
174
  }
159
175
 
176
+ async function getContractNullifiers(wallet: CLIWallet, contract: AztecAddress) {
177
+ const deployerAddress = ProtocolContractAddress.ContractInstanceRegistry;
178
+ const deployNullifier = await siloNullifier(deployerAddress, contract.toField());
179
+
180
+ const metadata = await wallet.getContractMetadata(contract);
181
+ const privateInitNullifier = metadata.instance
182
+ ? await computeSiloedPrivateInitializationNullifier(contract, metadata.instance.initializationHash)
183
+ : undefined;
184
+ const publicInitNullifier = await computeSiloedPublicInitializationNullifier(contract);
185
+
186
+ return { contract, deployNullifier, privateInitNullifier, publicInitNullifier };
187
+ }
188
+
189
+ async function getClassNullifier(artifact: ContractArtifactWithClassId) {
190
+ const classRegistryAddress = ProtocolContractAddress.ContractClassRegistry;
191
+ const nullifier = await siloNullifier(classRegistryAddress, artifact.classId);
192
+ return { nullifier, label: `${artifact.name}Class<${artifact.classId}>` };
193
+ }
194
+
160
195
  type ArtifactMap = Record<string, ContractArtifactWithClassId>;
161
196
  type ContractArtifactWithClassId = ContractArtifact & { classId: Fr };
162
197
 
@@ -164,15 +199,11 @@ async function getKnownArtifacts(wallet: CLIWallet): Promise<ArtifactMap> {
164
199
  const knownContractAddresses = await wallet.getContracts();
165
200
  const knownContracts = (
166
201
  await Promise.all(knownContractAddresses.map(contractAddress => wallet.getContractMetadata(contractAddress)))
167
- ).map(contractMetadata => contractMetadata.contractInstance);
202
+ ).map(contractMetadata => contractMetadata.instance);
168
203
  const classIds = [...new Set(knownContracts.map(contract => contract?.currentContractClassId))];
169
204
  const knownArtifacts = (
170
- await Promise.all(classIds.map(classId => (classId ? wallet.getContractClassMetadata(classId) : undefined)))
171
- ).map(contractClassMetadata =>
172
- contractClassMetadata
173
- ? { ...contractClassMetadata.artifact, classId: contractClassMetadata.contractClass?.id }
174
- : undefined,
175
- );
205
+ await Promise.all(classIds.map(classId => (classId ? wallet.getContractArtifact(classId) : undefined)))
206
+ ).map((artifact, index) => (artifact ? { ...artifact, classId: classIds[index] } : undefined));
176
207
  const map: Record<string, ContractArtifactWithClassId> = {};
177
208
  for (const instance of knownContracts) {
178
209
  if (instance) {
@@ -1,20 +1,25 @@
1
+ import { NO_FROM } from '@aztec/aztec.js/account';
1
2
  import { AztecAddress } from '@aztec/aztec.js/addresses';
2
- import type { AztecNode } from '@aztec/aztec.js/node';
3
+ import { NO_WAIT } from '@aztec/aztec.js/contracts';
4
+ import { type AztecNode, waitForTx } from '@aztec/aztec.js/node';
3
5
  import type { DeployAccountOptions } from '@aztec/aztec.js/wallet';
4
6
  import { prettyPrintJSON } from '@aztec/cli/cli-utils';
5
- import { Fr } from '@aztec/foundation/fields';
7
+ import { Fr } from '@aztec/foundation/curves/bn254';
6
8
  import type { LogFn, Logger } from '@aztec/foundation/log';
9
+ import { type TxHash, type TxReceipt, TxStatus } from '@aztec/stdlib/tx';
7
10
 
8
11
  import { DEFAULT_TX_TIMEOUT_S } from '../utils/cli_wallet_and_node_wrapper.js';
12
+ import type { AccountType } from '../utils/constants.js';
9
13
  import { CLIFeeArgs } from '../utils/options/fees.js';
10
14
  import { printProfileResult } from '../utils/profiling.js';
11
- import { type AccountType, CLIWallet } from '../utils/wallet.js';
15
+ import { CLIWallet } from '../utils/wallet.js';
12
16
 
13
17
  export async function createAccount(
14
18
  wallet: CLIWallet,
15
19
  aztecNode: AztecNode,
16
20
  accountType: AccountType,
17
21
  secretKey: Fr | undefined,
22
+ salt: Fr | undefined,
18
23
  publicKey: string | undefined,
19
24
  alias: string | undefined,
20
25
  deployer: AztecAddress | undefined,
@@ -24,6 +29,7 @@ export async function createAccount(
24
29
  registerClass: boolean,
25
30
  wait: boolean,
26
31
  feeOpts: CLIFeeArgs,
32
+ waitForStatus: TxStatus,
27
33
  json: boolean,
28
34
  verbose: boolean,
29
35
  debugLogger: Logger,
@@ -35,10 +41,10 @@ export async function createAccount(
35
41
  undefined /* address, we don't have it yet */,
36
42
  secretKey,
37
43
  accountType,
38
- Fr.ZERO,
44
+ salt,
39
45
  publicKey,
40
46
  );
41
- const { salt } = account.getInstance();
47
+ const instanceSalt = account.getInstance().salt;
42
48
  const { address, publicKeys, partialAddress } = await account.getCompleteAddress();
43
49
 
44
50
  const out: Record<string, any> = {};
@@ -49,7 +55,7 @@ export async function createAccount(
49
55
  out.secretKey = secretKey;
50
56
  }
51
57
  out.partialAddress = partialAddress;
52
- out.salt = salt;
58
+ out.salt = instanceSalt;
53
59
  out.initHash = account.getInstance().initializationHash;
54
60
  } else {
55
61
  log(`\nNew account:\n`);
@@ -59,17 +65,17 @@ export async function createAccount(
59
65
  log(`Secret key: ${secretKey.toString()}`);
60
66
  }
61
67
  log(`Partial address: ${partialAddress.toString()}`);
62
- log(`Salt: ${salt.toString()}`);
68
+ log(`Salt: ${instanceSalt.toString()}`);
63
69
  log(`Init hash: ${account.getInstance().initializationHash.toString()}`);
64
70
  }
65
71
 
66
- let tx;
67
- let txReceipt;
72
+ let txHash: TxHash | undefined;
73
+ let txReceipt: TxReceipt | undefined;
68
74
  if (!registerOnly) {
69
75
  const { paymentMethod, gasSettings } = await feeOpts.toUserFeeOptions(aztecNode, wallet, address);
70
76
 
71
77
  const delegatedDeployment = deployer && !account.address.equals(deployer);
72
- const from = delegatedDeployment ? deployer : AztecAddress.ZERO;
78
+ const from = delegatedDeployment ? deployer : NO_FROM;
73
79
 
74
80
  const deployAccountOpts: DeployAccountOptions = {
75
81
  skipClassPublication: !registerClass,
@@ -79,11 +85,15 @@ export async function createAccount(
79
85
  fee: { paymentMethod, gasSettings },
80
86
  };
81
87
 
88
+ const localStart = performance.now();
82
89
  const deployMethod = await account.getDeployMethod();
83
- const { estimatedGas, stats } = await deployMethod.simulate({
90
+ const sim = await deployMethod.simulate({
84
91
  ...deployAccountOpts,
85
92
  fee: { ...deployAccountOpts.fee, estimateGas: true },
86
93
  });
94
+ // estimateGas: true guarantees these fields are present
95
+ const estimatedGas = sim.estimatedGas!;
96
+ const stats = sim.stats!;
87
97
 
88
98
  if (feeOpts.estimateOnly) {
89
99
  if (json) {
@@ -99,7 +109,14 @@ export async function createAccount(
99
109
  };
100
110
  }
101
111
  } else {
102
- tx = deployMethod.send({
112
+ if (verbose) {
113
+ printProfileResult(stats, log);
114
+ }
115
+
116
+ if (!json) {
117
+ log(`\nWaiting for account contract deployment...`);
118
+ }
119
+ const sendOpts = {
103
120
  ...deployAccountOpts,
104
121
  fee: deployAccountOpts.fee
105
122
  ? {
@@ -107,37 +124,41 @@ export async function createAccount(
107
124
  gasSettings: estimatedGas,
108
125
  }
109
126
  : undefined,
110
- });
111
- if (verbose) {
112
- printProfileResult(stats, log);
113
- }
127
+ };
128
+
129
+ ({ txHash } = await deployMethod.send({ ...sendOpts, wait: NO_WAIT }));
130
+ const localTimeMs = performance.now() - localStart;
114
131
 
115
- const txHash = await tx.getTxHash();
116
- debugLogger.debug(`Account contract tx sent with hash ${txHash.toString()}`);
117
- out.txHash = txHash;
118
132
  if (wait) {
119
- if (!json) {
120
- log(`\nWaiting for account contract deployment...`);
121
- }
122
- txReceipt = await tx.wait({ timeout: DEFAULT_TX_TIMEOUT_S });
133
+ const nodeStart = performance.now();
134
+ txReceipt = await waitForTx(aztecNode, txHash, { timeout: DEFAULT_TX_TIMEOUT_S, waitForStatus });
135
+ const nodeTimeMs = performance.now() - nodeStart;
136
+
123
137
  out.txReceipt = {
124
138
  status: txReceipt.status,
125
139
  transactionFee: txReceipt.transactionFee,
126
140
  };
141
+
142
+ if (!json) {
143
+ log(` Local processing time: ${(localTimeMs / 1000).toFixed(1)}s`);
144
+ log(` Node inclusion time: ${(nodeTimeMs / 1000).toFixed(1)}s`);
145
+ }
127
146
  }
147
+ debugLogger.debug(`Account contract tx sent with hash ${txHash.toString()}`);
148
+ out.txHash = txHash;
128
149
  }
129
150
  }
130
151
 
131
152
  if (json) {
132
153
  log(prettyPrintJSON(out));
133
154
  } else {
134
- if (tx) {
135
- log(`Deploy tx hash: ${(await tx.getTxHash()).toString()}`);
155
+ if (txHash) {
156
+ log(`Deploy tx hash: ${txHash.toString()}`);
136
157
  }
137
158
  if (txReceipt) {
138
159
  log(`Deploy tx fee: ${txReceipt.transactionFee}`);
139
160
  }
140
161
  }
141
162
 
142
- return { alias, address, secretKey, salt };
163
+ return { alias, address, secretKey, salt: instanceSalt };
143
164
  }