@aztec/cli-wallet 0.0.1-commit.03f7ef2 → 0.0.1-commit.04d373f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/bin/index.js +1 -1
- package/dest/cmds/authorize_action.d.ts +2 -2
- package/dest/cmds/authorize_action.d.ts.map +1 -1
- package/dest/cmds/authorize_action.js +4 -2
- package/dest/cmds/check_tx.d.ts +1 -1
- package/dest/cmds/check_tx.d.ts.map +1 -1
- package/dest/cmds/check_tx.js +45 -14
- package/dest/cmds/create_account.d.ts +6 -4
- package/dest/cmds/create_account.d.ts.map +1 -1
- package/dest/cmds/create_account.js +42 -25
- package/dest/cmds/create_authwit.d.ts +2 -2
- package/dest/cmds/create_authwit.d.ts.map +1 -1
- package/dest/cmds/deploy.d.ts +5 -4
- package/dest/cmds/deploy.d.ts.map +1 -1
- package/dest/cmds/deploy.js +64 -32
- package/dest/cmds/deploy_account.d.ts +4 -3
- package/dest/cmds/deploy_account.d.ts.map +1 -1
- package/dest/cmds/deploy_account.js +37 -20
- package/dest/cmds/get_fee_juice_balance.d.ts +5 -0
- package/dest/cmds/get_fee_juice_balance.d.ts.map +1 -0
- package/dest/cmds/get_fee_juice_balance.js +27 -0
- package/dest/cmds/index.d.ts +1 -1
- package/dest/cmds/index.d.ts.map +1 -1
- package/dest/cmds/index.js +31 -15
- package/dest/cmds/send.d.ts +5 -4
- package/dest/cmds/send.d.ts.map +1 -1
- package/dest/cmds/send.js +32 -16
- package/dest/cmds/simulate.d.ts +1 -1
- package/dest/cmds/simulate.d.ts.map +1 -1
- package/dest/cmds/simulate.js +3 -3
- package/dest/storage/wallet_db.d.ts +7 -2
- package/dest/storage/wallet_db.d.ts.map +1 -1
- package/dest/storage/wallet_db.js +60 -31
- package/dest/utils/constants.d.ts +4 -0
- package/dest/utils/constants.d.ts.map +1 -0
- package/dest/utils/constants.js +7 -0
- package/dest/utils/options/fees.d.ts +3 -2
- package/dest/utils/options/fees.d.ts.map +1 -1
- package/dest/utils/options/fees.js +33 -10
- package/dest/utils/options/options.d.ts +2 -2
- package/dest/utils/options/options.d.ts.map +1 -1
- package/dest/utils/options/options.js +1 -1
- package/dest/utils/profiling.d.ts +1 -1
- package/dest/utils/profiling.d.ts.map +1 -1
- package/dest/utils/profiling.js +9 -1
- package/dest/utils/wallet.d.ts +16 -8
- package/dest/utils/wallet.d.ts.map +1 -1
- package/dest/utils/wallet.js +129 -61
- package/package.json +17 -16
- package/src/bin/index.ts +1 -1
- package/src/cmds/authorize_action.ts +1 -1
- package/src/cmds/check_tx.ts +50 -19
- package/src/cmds/create_account.ts +46 -25
- package/src/cmds/deploy.ts +63 -36
- package/src/cmds/deploy_account.ts +38 -19
- package/src/cmds/get_fee_juice_balance.ts +37 -0
- package/src/cmds/index.ts +61 -7
- package/src/cmds/send.ts +32 -12
- package/src/cmds/simulate.ts +4 -7
- package/src/storage/wallet_db.ts +64 -37
- package/src/utils/constants.ts +4 -0
- package/src/utils/options/fees.ts +40 -10
- package/src/utils/options/options.ts +1 -1
- package/src/utils/profiling.ts +15 -1
- package/src/utils/wallet.ts +139 -75
package/dest/utils/wallet.js
CHANGED
|
@@ -1,67 +1,100 @@
|
|
|
1
1
|
import { EcdsaRAccountContract, EcdsaRSSHAccountContract } from '@aztec/accounts/ecdsa';
|
|
2
2
|
import { SchnorrAccountContract } from '@aztec/accounts/schnorr';
|
|
3
|
-
import {
|
|
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 {
|
|
6
|
-
import {
|
|
6
|
+
import { NO_FROM } from '@aztec/aztec.js/account';
|
|
7
|
+
import { getContractClassFromArtifact, getGasLimits } from '@aztec/aztec.js/contracts';
|
|
7
8
|
import { AccountManager } from '@aztec/aztec.js/wallet';
|
|
9
|
+
import { TxSimulationResultWithAppOffset } from '@aztec/aztec.js/wallet';
|
|
10
|
+
import { DefaultEntrypoint } from '@aztec/entrypoints/default';
|
|
8
11
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
9
12
|
import { createPXE, getPXEConfig } from '@aztec/pxe/server';
|
|
13
|
+
import { getStandardAuthRegistry } from '@aztec/standard-contracts/auth-registry';
|
|
10
14
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
11
15
|
import { deriveSigningKey } from '@aztec/stdlib/keys';
|
|
12
16
|
import { ExecutionPayload, mergeExecutionPayloads } from '@aztec/stdlib/tx';
|
|
13
17
|
import { BaseWallet } from '@aztec/wallet-sdk/base-wallet';
|
|
14
18
|
import { extractECDSAPublicKeyFromBase64String } from './ecdsa.js';
|
|
15
19
|
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
20
|
export class CLIWallet extends BaseWallet {
|
|
24
21
|
userLog;
|
|
25
22
|
db;
|
|
26
23
|
accountCache;
|
|
24
|
+
// Stub class ids, populated on wallet startup
|
|
25
|
+
// to avoid redundant work per simulation
|
|
26
|
+
stubClassIds;
|
|
27
27
|
constructor(pxe, node, userLog, db){
|
|
28
|
-
super(pxe, node), this.userLog = userLog, this.db = db, this.accountCache = new Map();
|
|
28
|
+
super(pxe, node), this.userLog = userLog, this.db = db, this.accountCache = new Map(), this.stubClassIds = new Map();
|
|
29
29
|
this.cancellableTransactions = true;
|
|
30
30
|
}
|
|
31
31
|
static async create(node, log, db, overridePXEConfig) {
|
|
32
32
|
const pxeConfig = Object.assign(getPXEConfig(), overridePXEConfig);
|
|
33
33
|
const pxe = await createPXE(node, pxeConfig);
|
|
34
|
-
|
|
34
|
+
const wallet = new CLIWallet(pxe, node, log, db);
|
|
35
|
+
await wallet.initStubClasses();
|
|
36
|
+
await wallet.registerAuthRegistry();
|
|
37
|
+
return wallet;
|
|
38
|
+
}
|
|
39
|
+
async registerAuthRegistry() {
|
|
40
|
+
const { instance, artifact } = await getStandardAuthRegistry();
|
|
41
|
+
await this.pxe.registerContract({
|
|
42
|
+
instance,
|
|
43
|
+
artifact
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Hashes and registers the stub class for every supported account type with PXE, populating
|
|
48
|
+
* stubClassIds. Called on wallet initialization.
|
|
49
|
+
*/ async initStubClasses() {
|
|
50
|
+
const { id: schnorrClassId } = await getContractClassFromArtifact(StubSchnorrAccountContractArtifact);
|
|
51
|
+
await this.pxe.registerContractClass(StubSchnorrAccountContractArtifact);
|
|
52
|
+
// ecdsa stubs share the same class id
|
|
53
|
+
const { id: ecdsaClassId } = await getContractClassFromArtifact(StubEcdsaAccountContractArtifact);
|
|
54
|
+
await this.pxe.registerContractClass(StubEcdsaAccountContractArtifact);
|
|
55
|
+
this.stubClassIds.set('schnorr', schnorrClassId);
|
|
56
|
+
this.stubClassIds.set('ecdsasecp256k1', ecdsaClassId);
|
|
57
|
+
this.stubClassIds.set('ecdsasecp256r1', ecdsaClassId);
|
|
58
|
+
this.stubClassIds.set('ecdsasecp256r1ssh', ecdsaClassId);
|
|
35
59
|
}
|
|
36
60
|
async getAccounts() {
|
|
37
61
|
const accounts = await this.db?.listAliases('accounts') ?? [];
|
|
38
|
-
return Promise.resolve(accounts.map(({ key, value })=>
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
62
|
+
return Promise.resolve(accounts.map(({ key, value })=>{
|
|
63
|
+
const alias = key.includes(':') ? key.slice(key.indexOf(':') + 1) : key;
|
|
64
|
+
return {
|
|
65
|
+
alias,
|
|
66
|
+
item: AztecAddress.fromString(value)
|
|
67
|
+
};
|
|
68
|
+
}));
|
|
42
69
|
}
|
|
43
70
|
async createCancellationTxExecutionRequest(from, txNonce, increasedFee) {
|
|
44
71
|
const executionPayload = ExecutionPayload.empty();
|
|
45
|
-
const feeOptions = await this.completeFeeOptions(
|
|
72
|
+
const feeOptions = await this.completeFeeOptions({
|
|
73
|
+
from,
|
|
74
|
+
feePayer: executionPayload.feePayer,
|
|
75
|
+
gasSettings: increasedFee.gasSettings
|
|
76
|
+
});
|
|
46
77
|
const feeExecutionPayload = await feeOptions.walletFeePaymentMethod?.getExecutionPayload();
|
|
47
78
|
const fromAccount = await this.getAccountFromAddress(from);
|
|
79
|
+
const chainInfo = await this.getChainInfo();
|
|
48
80
|
const executionOptions = {
|
|
49
81
|
txNonce,
|
|
50
82
|
cancellable: this.cancellableTransactions,
|
|
83
|
+
// If from is an address, feeOptions include the way the account contract should handle the fee payment
|
|
51
84
|
feePaymentMethodOptions: feeOptions.accountFeePaymentMethodOptions
|
|
52
85
|
};
|
|
53
|
-
return await fromAccount.createTxExecutionRequest(feeExecutionPayload ?? executionPayload, feeOptions.gasSettings, executionOptions);
|
|
86
|
+
return await fromAccount.createTxExecutionRequest(feeExecutionPayload ?? executionPayload, feeOptions.gasSettings, chainInfo, executionOptions);
|
|
54
87
|
}
|
|
55
88
|
async proveCancellationTx(from, txNonce, increasedFee) {
|
|
56
89
|
const cancellationTxRequest = await this.createCancellationTxExecutionRequest(from, txNonce, increasedFee);
|
|
57
|
-
return await this.pxe.proveTx(cancellationTxRequest
|
|
90
|
+
return await this.pxe.proveTx(cancellationTxRequest, {
|
|
91
|
+
scopes: this.scopesFrom(from),
|
|
92
|
+
senderForTags: from
|
|
93
|
+
});
|
|
58
94
|
}
|
|
59
95
|
async getAccountFromAddress(address) {
|
|
60
96
|
let account;
|
|
61
|
-
if (address.
|
|
62
|
-
const chainInfo = await this.getChainInfo();
|
|
63
|
-
account = new SignerlessAccount(chainInfo);
|
|
64
|
-
} else if (this.accountCache.has(address.toString())) {
|
|
97
|
+
if (this.accountCache.has(address.toString())) {
|
|
65
98
|
return this.accountCache.get(address.toString());
|
|
66
99
|
} else {
|
|
67
100
|
const accountManager = await this.createOrRetrieveAccount(address);
|
|
@@ -73,7 +106,9 @@ export class CLIWallet extends BaseWallet {
|
|
|
73
106
|
return account;
|
|
74
107
|
}
|
|
75
108
|
async createAccount(secret, salt, contract) {
|
|
76
|
-
const accountManager = await AccountManager.create(this, secret, contract,
|
|
109
|
+
const accountManager = await AccountManager.create(this, secret, contract, {
|
|
110
|
+
salt
|
|
111
|
+
});
|
|
77
112
|
const instance = accountManager.getInstance();
|
|
78
113
|
const artifact = await contract.getContractArtifact();
|
|
79
114
|
await this.registerContract(instance, artifact, secret);
|
|
@@ -125,62 +160,90 @@ export class CLIWallet extends BaseWallet {
|
|
|
125
160
|
}
|
|
126
161
|
return account;
|
|
127
162
|
}
|
|
128
|
-
|
|
129
|
-
|
|
163
|
+
/**
|
|
164
|
+
* Creates a stub account that impersonates the given address, allowing kernelless simulations
|
|
165
|
+
* to bypass the account's authorization mechanisms via contract overrides.
|
|
166
|
+
* @param address - The address of the account to impersonate
|
|
167
|
+
* @returns The stub account, contract instance, and artifact for simulation
|
|
168
|
+
*/ async getFakeAccountDataFor(address) {
|
|
130
169
|
const originalAccount = await this.getAccountFromAddress(address);
|
|
131
170
|
const originalAddress = originalAccount.getCompleteAddress();
|
|
132
|
-
const
|
|
171
|
+
const contractInstance = await this.pxe.getContractInstance(originalAddress.address);
|
|
133
172
|
if (!contractInstance) {
|
|
134
173
|
throw new Error(`No contract instance found for address: ${originalAddress.address}`);
|
|
135
174
|
}
|
|
136
|
-
const
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
175
|
+
const { type } = await this.db.retrieveAccount(address);
|
|
176
|
+
const stubAccount = type === 'schnorr' ? createStubSchnorrAccount(originalAddress) : createStubEcdsaAccount(originalAddress);
|
|
177
|
+
const stubClassId = this.stubClassIds.get(type);
|
|
178
|
+
if (!stubClassId) {
|
|
179
|
+
throw new Error(`Stub class for account type '${type}' was not registered at wallet init. This is a bug — initStubClasses should cover every supported AccountType.`);
|
|
180
|
+
}
|
|
181
|
+
const instance = {
|
|
182
|
+
...contractInstance,
|
|
183
|
+
currentContractClassId: stubClassId
|
|
184
|
+
};
|
|
140
185
|
return {
|
|
141
186
|
account: stubAccount,
|
|
142
|
-
instance
|
|
143
|
-
artifact: StubAccountContractArtifact
|
|
187
|
+
instance
|
|
144
188
|
};
|
|
145
189
|
}
|
|
146
190
|
async simulateTx(executionPayload, opts) {
|
|
147
|
-
|
|
148
|
-
|
|
191
|
+
const simulationResults = await super.simulateTx(executionPayload, opts);
|
|
192
|
+
if (opts.fee?.estimateGas) {
|
|
193
|
+
const feeOptions = await this.completeFeeOptions({
|
|
194
|
+
from: opts.from,
|
|
195
|
+
feePayer: executionPayload.feePayer,
|
|
196
|
+
gasSettings: opts.fee?.gasSettings
|
|
197
|
+
});
|
|
198
|
+
const limits = getGasLimits(simulationResults, opts.fee?.estimatedGasPadding);
|
|
199
|
+
printGasEstimates(feeOptions, limits, this.userLog);
|
|
200
|
+
}
|
|
201
|
+
return simulationResults;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Uses a stub account for kernelless simulation, bypassing real account authorization.
|
|
205
|
+
* Uses DefaultEntrypoint directly for NO_FROM transactions.
|
|
206
|
+
*/ async simulateViaEntrypoint(executionPayload, opts) {
|
|
207
|
+
const { from, feeOptions, additionalScopes, sendMessagesAs } = opts;
|
|
208
|
+
const scopes = this.scopesFrom(from, additionalScopes);
|
|
149
209
|
const feeExecutionPayload = await feeOptions.walletFeePaymentMethod?.getExecutionPayload();
|
|
150
|
-
const executionOptions = {
|
|
151
|
-
txNonce: Fr.random(),
|
|
152
|
-
cancellable: this.cancellableTransactions,
|
|
153
|
-
feePaymentMethodOptions: feeOptions.accountFeePaymentMethodOptions
|
|
154
|
-
};
|
|
155
210
|
const finalExecutionPayload = feeExecutionPayload ? mergeExecutionPayloads([
|
|
156
211
|
feeExecutionPayload,
|
|
157
212
|
executionPayload
|
|
158
213
|
]) : executionPayload;
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
if (
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
simulationResults = await this.pxe.simulateTx(txRequest, true, opts?.skipTxValidation, opts?.skipFeeEnforcement ?? true);
|
|
214
|
+
const chainInfo = await this.getChainInfo();
|
|
215
|
+
let overrides;
|
|
216
|
+
let txRequest;
|
|
217
|
+
if (from === NO_FROM) {
|
|
218
|
+
const entrypoint = new DefaultEntrypoint();
|
|
219
|
+
txRequest = await entrypoint.createTxExecutionRequest(finalExecutionPayload, feeOptions.gasSettings, chainInfo);
|
|
166
220
|
} else {
|
|
167
|
-
const { account
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
221
|
+
const { account, instance } = await this.getFakeAccountDataFor(from);
|
|
222
|
+
overrides = {
|
|
223
|
+
contracts: {
|
|
224
|
+
[from.toString()]: {
|
|
225
|
+
instance
|
|
226
|
+
}
|
|
173
227
|
}
|
|
174
228
|
};
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
229
|
+
const executionOptions = {
|
|
230
|
+
txNonce: Fr.random(),
|
|
231
|
+
cancellable: this.cancellableTransactions,
|
|
232
|
+
// If from is an address, feeOptions include the way the account contract should handle the fee payment
|
|
233
|
+
feePaymentMethodOptions: feeOptions.accountFeePaymentMethodOptions
|
|
234
|
+
};
|
|
235
|
+
txRequest = await account.createTxExecutionRequest(finalExecutionPayload, feeOptions.gasSettings, chainInfo, executionOptions);
|
|
182
236
|
}
|
|
183
|
-
|
|
237
|
+
const result = await this.pxe.simulateTx(txRequest, {
|
|
238
|
+
simulatePublic: true,
|
|
239
|
+
skipFeeEnforcement: true,
|
|
240
|
+
skipTxValidation: true,
|
|
241
|
+
overrides,
|
|
242
|
+
scopes,
|
|
243
|
+
senderForTags: this.senderForTagsFrom(from, sendMessagesAs)
|
|
244
|
+
});
|
|
245
|
+
const appCallOffset = await this.computeAppCallOffset(from, feeOptions);
|
|
246
|
+
return TxSimulationResultWithAppOffset.fromResultAndOffset(result, appCallOffset);
|
|
184
247
|
}
|
|
185
248
|
// Exposed because of the `aztec-wallet get-tx` command. It has been decided that it's fine to keep around because
|
|
186
249
|
// this is just a CLI wallet.
|
|
@@ -192,4 +255,9 @@ export class CLIWallet extends BaseWallet {
|
|
|
192
255
|
getNotes(filter) {
|
|
193
256
|
return this.pxe.debug.getNotes(filter);
|
|
194
257
|
}
|
|
258
|
+
// Exposed because of the `aztec-wallet get-tx` command. It has been decided that it's fine to keep around because
|
|
259
|
+
// this is just a CLI wallet.
|
|
260
|
+
getContractArtifact(id) {
|
|
261
|
+
return this.pxe.getContractArtifact(id);
|
|
262
|
+
}
|
|
195
263
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/cli-wallet",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.04d373f",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/cmds/index.js",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"scripts": {
|
|
20
20
|
"start": "node --no-warnings ./dest/bin",
|
|
21
21
|
"start:debug": "node --inspect=0.0.0.0:9221 --no-warnings ./dest/bin",
|
|
22
|
-
"dev": "LOG_LEVEL
|
|
22
|
+
"dev": "LOG_LEVEL=\"debug; info: json-rpc, simulator\" node ./dest/bin",
|
|
23
23
|
"build": "yarn clean && ../scripts/tsc.sh",
|
|
24
24
|
"build:dev": "../scripts/tsc.sh --watch",
|
|
25
25
|
"clean": "rm -rf ./dest .tsbuildinfo",
|
|
@@ -67,19 +67,20 @@
|
|
|
67
67
|
]
|
|
68
68
|
},
|
|
69
69
|
"dependencies": {
|
|
70
|
-
"@aztec/accounts": "0.0.1-commit.
|
|
71
|
-
"@aztec/aztec.js": "0.0.1-commit.
|
|
72
|
-
"@aztec/bb.js": "0.0.1-commit.
|
|
73
|
-
"@aztec/cli": "0.0.1-commit.
|
|
74
|
-
"@aztec/entrypoints": "0.0.1-commit.
|
|
75
|
-
"@aztec/ethereum": "0.0.1-commit.
|
|
76
|
-
"@aztec/foundation": "0.0.1-commit.
|
|
77
|
-
"@aztec/kv-store": "0.0.1-commit.
|
|
78
|
-
"@aztec/noir-contracts.js": "0.0.1-commit.
|
|
79
|
-
"@aztec/noir-noirc_abi": "0.0.1-commit.
|
|
80
|
-
"@aztec/pxe": "0.0.1-commit.
|
|
81
|
-
"@aztec/
|
|
82
|
-
"@aztec/
|
|
70
|
+
"@aztec/accounts": "0.0.1-commit.04d373f",
|
|
71
|
+
"@aztec/aztec.js": "0.0.1-commit.04d373f",
|
|
72
|
+
"@aztec/bb.js": "0.0.1-commit.04d373f",
|
|
73
|
+
"@aztec/cli": "0.0.1-commit.04d373f",
|
|
74
|
+
"@aztec/entrypoints": "0.0.1-commit.04d373f",
|
|
75
|
+
"@aztec/ethereum": "0.0.1-commit.04d373f",
|
|
76
|
+
"@aztec/foundation": "0.0.1-commit.04d373f",
|
|
77
|
+
"@aztec/kv-store": "0.0.1-commit.04d373f",
|
|
78
|
+
"@aztec/noir-contracts.js": "0.0.1-commit.04d373f",
|
|
79
|
+
"@aztec/noir-noirc_abi": "0.0.1-commit.04d373f",
|
|
80
|
+
"@aztec/pxe": "0.0.1-commit.04d373f",
|
|
81
|
+
"@aztec/standard-contracts": "0.0.1-commit.04d373f",
|
|
82
|
+
"@aztec/stdlib": "0.0.1-commit.04d373f",
|
|
83
|
+
"@aztec/wallet-sdk": "0.0.1-commit.04d373f",
|
|
83
84
|
"commander": "^12.1.0",
|
|
84
85
|
"inquirer": "^10.1.8",
|
|
85
86
|
"source-map-support": "^0.5.21",
|
|
@@ -90,7 +91,7 @@
|
|
|
90
91
|
"@types/jest": "^30.0.0",
|
|
91
92
|
"@types/node": "^22.15.17",
|
|
92
93
|
"@types/source-map-support": "^0.5.10",
|
|
93
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
94
|
+
"@typescript/native-preview": "7.0.0-dev.20260113.1",
|
|
94
95
|
"jest": "^30.0.0",
|
|
95
96
|
"jest-mock-extended": "^4.0.0",
|
|
96
97
|
"ts-jest": "^29.4.0",
|
package/src/bin/index.ts
CHANGED
|
@@ -73,7 +73,7 @@ function injectInternalCommands(program: Command, log: LogFn, db: WalletDB) {
|
|
|
73
73
|
|
|
74
74
|
/** CLI wallet main entrypoint */
|
|
75
75
|
async function main() {
|
|
76
|
-
const walletVersion = getPackageVersion()
|
|
76
|
+
const walletVersion = getPackageVersion();
|
|
77
77
|
|
|
78
78
|
const db = WalletDB.getInstance();
|
|
79
79
|
const walletAndNodeWrapper = new CliWalletAndNodeWrapper();
|
|
@@ -39,7 +39,7 @@ export async function authorizeAction(
|
|
|
39
39
|
{ caller, action },
|
|
40
40
|
true,
|
|
41
41
|
);
|
|
42
|
-
const witness = await setAuthwitnessInteraction.send(
|
|
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
|
|
package/src/cmds/check_tx.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import type { ContractArtifact } from '@aztec/aztec.js/abi';
|
|
2
|
-
import
|
|
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 {
|
|
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}
|
|
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
|
-
|
|
145
|
-
const
|
|
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
|
-
|
|
150
|
-
|
|
151
|
-
deployNullifiers[
|
|
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
|
|
154
|
-
classNullifiers[
|
|
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.
|
|
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.
|
|
171
|
-
).map(
|
|
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
|
|
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
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 {
|
|
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
|
-
|
|
44
|
+
salt,
|
|
39
45
|
publicKey,
|
|
40
46
|
);
|
|
41
|
-
const
|
|
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 =
|
|
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: ${
|
|
68
|
+
log(`Salt: ${instanceSalt.toString()}`);
|
|
63
69
|
log(`Init hash: ${account.getInstance().initializationHash.toString()}`);
|
|
64
70
|
}
|
|
65
71
|
|
|
66
|
-
let
|
|
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 :
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
112
|
-
|
|
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
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
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 (
|
|
135
|
-
log(`Deploy tx hash: ${
|
|
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
|
}
|