@aztec/cli-wallet 0.0.1-commit.fffb133c → 0.0.1-dev
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/check_tx.d.ts +1 -1
- package/dest/cmds/check_tx.d.ts.map +1 -1
- package/dest/cmds/check_tx.js +37 -9
- package/dest/cmds/create_account.d.ts +4 -3
- package/dest/cmds/create_account.d.ts.map +1 -1
- package/dest/cmds/create_account.js +32 -21
- package/dest/cmds/deploy.d.ts +4 -3
- package/dest/cmds/deploy.d.ts.map +1 -1
- package/dest/cmds/deploy.js +40 -34
- 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 +27 -16
- 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 +30 -14
- package/dest/cmds/send.d.ts +4 -3
- package/dest/cmds/send.d.ts.map +1 -1
- package/dest/cmds/send.js +27 -23
- package/dest/storage/wallet_db.d.ts +6 -1
- package/dest/storage/wallet_db.d.ts.map +1 -1
- package/dest/storage/wallet_db.js +60 -31
- package/dest/utils/options/fees.d.ts +2 -2
- package/dest/utils/options/fees.d.ts.map +1 -1
- package/dest/utils/options/fees.js +10 -7
- package/dest/utils/wallet.d.ts +11 -5
- package/dest/utils/wallet.d.ts.map +1 -1
- package/dest/utils/wallet.js +77 -49
- package/package.json +14 -14
- package/src/bin/index.ts +1 -1
- package/src/cmds/check_tx.ts +43 -11
- package/src/cmds/create_account.ts +32 -18
- package/src/cmds/deploy.ts +34 -31
- package/src/cmds/deploy_account.ts +26 -13
- package/src/cmds/get_fee_juice_balance.ts +37 -0
- package/src/cmds/index.ts +57 -4
- package/src/cmds/send.ts +24 -16
- package/src/cmds/simulate.ts +1 -1
- package/src/storage/wallet_db.ts +63 -36
- package/src/utils/options/fees.ts +15 -7
- package/src/utils/wallet.ts +85 -69
package/dest/utils/wallet.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
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 { 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';
|
|
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';
|
|
10
13
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
@@ -28,33 +31,42 @@ export class CLIWallet extends BaseWallet {
|
|
|
28
31
|
}
|
|
29
32
|
async getAccounts() {
|
|
30
33
|
const accounts = await this.db?.listAliases('accounts') ?? [];
|
|
31
|
-
return Promise.resolve(accounts.map(({ key, value })=>
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
+
}));
|
|
35
41
|
}
|
|
36
42
|
async createCancellationTxExecutionRequest(from, txNonce, increasedFee) {
|
|
37
43
|
const executionPayload = ExecutionPayload.empty();
|
|
38
|
-
const feeOptions = await this.completeFeeOptions(
|
|
44
|
+
const feeOptions = await this.completeFeeOptions({
|
|
45
|
+
from,
|
|
46
|
+
feePayer: executionPayload.feePayer,
|
|
47
|
+
gasSettings: increasedFee.gasSettings
|
|
48
|
+
});
|
|
39
49
|
const feeExecutionPayload = await feeOptions.walletFeePaymentMethod?.getExecutionPayload();
|
|
40
50
|
const fromAccount = await this.getAccountFromAddress(from);
|
|
41
51
|
const chainInfo = await this.getChainInfo();
|
|
42
52
|
const executionOptions = {
|
|
43
53
|
txNonce,
|
|
44
54
|
cancellable: this.cancellableTransactions,
|
|
55
|
+
// If from is an address, feeOptions include the way the account contract should handle the fee payment
|
|
45
56
|
feePaymentMethodOptions: feeOptions.accountFeePaymentMethodOptions
|
|
46
57
|
};
|
|
47
58
|
return await fromAccount.createTxExecutionRequest(feeExecutionPayload ?? executionPayload, feeOptions.gasSettings, chainInfo, executionOptions);
|
|
48
59
|
}
|
|
49
60
|
async proveCancellationTx(from, txNonce, increasedFee) {
|
|
50
61
|
const cancellationTxRequest = await this.createCancellationTxExecutionRequest(from, txNonce, increasedFee);
|
|
51
|
-
return await this.pxe.proveTx(cancellationTxRequest
|
|
62
|
+
return await this.pxe.proveTx(cancellationTxRequest, {
|
|
63
|
+
scopes: this.scopesFrom(from),
|
|
64
|
+
senderForTags: from
|
|
65
|
+
});
|
|
52
66
|
}
|
|
53
67
|
async getAccountFromAddress(address) {
|
|
54
68
|
let account;
|
|
55
|
-
if (address.
|
|
56
|
-
account = new SignerlessAccount();
|
|
57
|
-
} else if (this.accountCache.has(address.toString())) {
|
|
69
|
+
if (this.accountCache.has(address.toString())) {
|
|
58
70
|
return this.accountCache.get(address.toString());
|
|
59
71
|
} else {
|
|
60
72
|
const accountManager = await this.createOrRetrieveAccount(address);
|
|
@@ -125,66 +137,82 @@ export class CLIWallet extends BaseWallet {
|
|
|
125
137
|
* @returns The stub account, contract instance, and artifact for simulation
|
|
126
138
|
*/ async getFakeAccountDataFor(address) {
|
|
127
139
|
const originalAccount = await this.getAccountFromAddress(address);
|
|
128
|
-
// Account contracts can only be overridden if they have an associated address
|
|
129
|
-
// Overwriting SignerlessAccount is not supported, and does not really make sense
|
|
130
|
-
// since it has no authorization mechanism.
|
|
131
|
-
if (originalAccount instanceof SignerlessAccount) {
|
|
132
|
-
throw new Error(`Cannot create fake account data for SignerlessAccount at address: ${address}`);
|
|
133
|
-
}
|
|
134
140
|
const originalAddress = originalAccount.getCompleteAddress();
|
|
135
141
|
const contractInstance = await this.pxe.getContractInstance(originalAddress.address);
|
|
136
142
|
if (!contractInstance) {
|
|
137
143
|
throw new Error(`No contract instance found for address: ${originalAddress.address}`);
|
|
138
144
|
}
|
|
139
|
-
const
|
|
140
|
-
const
|
|
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, {
|
|
141
150
|
salt: Fr.random()
|
|
142
151
|
});
|
|
143
152
|
return {
|
|
144
153
|
account: stubAccount,
|
|
145
154
|
instance,
|
|
146
|
-
artifact
|
|
155
|
+
artifact
|
|
147
156
|
};
|
|
148
157
|
}
|
|
149
158
|
async simulateTx(executionPayload, opts) {
|
|
150
|
-
|
|
151
|
-
|
|
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);
|
|
152
177
|
const feeExecutionPayload = await feeOptions.walletFeePaymentMethod?.getExecutionPayload();
|
|
153
|
-
const chainInfo = await this.getChainInfo();
|
|
154
|
-
const executionOptions = {
|
|
155
|
-
txNonce: Fr.random(),
|
|
156
|
-
cancellable: this.cancellableTransactions,
|
|
157
|
-
feePaymentMethodOptions: feeOptions.accountFeePaymentMethodOptions
|
|
158
|
-
};
|
|
159
178
|
const finalExecutionPayload = feeExecutionPayload ? mergeExecutionPayloads([
|
|
160
179
|
feeExecutionPayload,
|
|
161
180
|
executionPayload
|
|
162
181
|
]) : executionPayload;
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
if (
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
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);
|
|
170
188
|
} else {
|
|
171
|
-
const { account
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
189
|
+
const { account, instance, artifact } = await this.getFakeAccountDataFor(from);
|
|
190
|
+
overrides = {
|
|
191
|
+
contracts: {
|
|
192
|
+
[from.toString()]: {
|
|
193
|
+
instance,
|
|
194
|
+
artifact
|
|
195
|
+
}
|
|
177
196
|
}
|
|
178
197
|
};
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
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);
|
|
186
205
|
}
|
|
187
|
-
|
|
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);
|
|
188
216
|
}
|
|
189
217
|
// Exposed because of the `aztec-wallet get-tx` command. It has been decided that it's fine to keep around because
|
|
190
218
|
// this is just a CLI wallet.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/cli-wallet",
|
|
3
|
-
"version": "0.0.1-
|
|
3
|
+
"version": "0.0.1-dev",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/cmds/index.js",
|
|
@@ -67,19 +67,19 @@
|
|
|
67
67
|
]
|
|
68
68
|
},
|
|
69
69
|
"dependencies": {
|
|
70
|
-
"@aztec/accounts": "0.0.1-
|
|
71
|
-
"@aztec/aztec.js": "0.0.1-
|
|
72
|
-
"@aztec/bb.js": "0.0.1-
|
|
73
|
-
"@aztec/cli": "0.0.1-
|
|
74
|
-
"@aztec/entrypoints": "0.0.1-
|
|
75
|
-
"@aztec/ethereum": "0.0.1-
|
|
76
|
-
"@aztec/foundation": "0.0.1-
|
|
77
|
-
"@aztec/kv-store": "0.0.1-
|
|
78
|
-
"@aztec/noir-contracts.js": "0.0.1-
|
|
79
|
-
"@aztec/noir-noirc_abi": "0.0.1-
|
|
80
|
-
"@aztec/pxe": "0.0.1-
|
|
81
|
-
"@aztec/stdlib": "0.0.1-
|
|
82
|
-
"@aztec/wallet-sdk": "0.0.1-
|
|
70
|
+
"@aztec/accounts": "0.0.1-dev",
|
|
71
|
+
"@aztec/aztec.js": "0.0.1-dev",
|
|
72
|
+
"@aztec/bb.js": "0.0.1-dev",
|
|
73
|
+
"@aztec/cli": "0.0.1-dev",
|
|
74
|
+
"@aztec/entrypoints": "0.0.1-dev",
|
|
75
|
+
"@aztec/ethereum": "0.0.1-dev",
|
|
76
|
+
"@aztec/foundation": "0.0.1-dev",
|
|
77
|
+
"@aztec/kv-store": "0.0.1-dev",
|
|
78
|
+
"@aztec/noir-contracts.js": "0.0.1-dev",
|
|
79
|
+
"@aztec/noir-noirc_abi": "0.0.1-dev",
|
|
80
|
+
"@aztec/pxe": "0.0.1-dev",
|
|
81
|
+
"@aztec/stdlib": "0.0.1-dev",
|
|
82
|
+
"@aztec/wallet-sdk": "0.0.1-dev",
|
|
83
83
|
"commander": "^12.1.0",
|
|
84
84
|
"inquirer": "^10.1.8",
|
|
85
85
|
"source-map-support": "^0.5.21",
|
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();
|
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';
|
|
@@ -83,12 +87,13 @@ async function inspectTx(wallet: CLIWallet, aztecNode: AztecNode, txHash: TxHash
|
|
|
83
87
|
// Nullifiers
|
|
84
88
|
const nullifierCount = effects.nullifiers.length;
|
|
85
89
|
const { deployNullifiers, initNullifiers, classNullifiers } = await getKnownNullifiers(wallet, artifactMap);
|
|
90
|
+
const accounts = (await wallet.getAccounts()).map(a => a.item);
|
|
86
91
|
if (nullifierCount > 0) {
|
|
87
92
|
log(' Nullifiers:');
|
|
88
93
|
for (const nullifier of effects.nullifiers) {
|
|
89
94
|
const deployed = deployNullifiers[nullifier.toString()];
|
|
90
95
|
const note = deployed
|
|
91
|
-
? (await wallet.getNotes({ siloedNullifier: nullifier, contractAddress: deployed }))[0]
|
|
96
|
+
? (await wallet.getNotes({ siloedNullifier: nullifier, contractAddress: deployed, scopes: accounts }))[0]
|
|
92
97
|
: undefined;
|
|
93
98
|
const initialized = initNullifiers[nullifier.toString()];
|
|
94
99
|
const registered = classNullifiers[nullifier.toString()];
|
|
@@ -144,22 +149,49 @@ function toFriendlyAddress(address: AztecAddress, artifactMap: ArtifactMap) {
|
|
|
144
149
|
|
|
145
150
|
async function getKnownNullifiers(wallet: CLIWallet, artifactMap: ArtifactMap) {
|
|
146
151
|
const knownContracts = await wallet.getContracts();
|
|
147
|
-
|
|
148
|
-
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
|
+
|
|
149
158
|
const initNullifiers: Record<string, AztecAddress> = {};
|
|
150
159
|
const deployNullifiers: Record<string, AztecAddress> = {};
|
|
151
160
|
const classNullifiers: Record<string, string> = {};
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
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;
|
|
155
168
|
}
|
|
156
|
-
for (const
|
|
157
|
-
classNullifiers[
|
|
158
|
-
`${artifact.name}Class<${artifact.classId}>`;
|
|
169
|
+
for (const { nullifier, label } of classResults) {
|
|
170
|
+
classNullifiers[nullifier.toString()] = label;
|
|
159
171
|
}
|
|
172
|
+
|
|
160
173
|
return { initNullifiers, deployNullifiers, classNullifiers };
|
|
161
174
|
}
|
|
162
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
|
+
|
|
163
195
|
type ArtifactMap = Record<string, ContractArtifactWithClassId>;
|
|
164
196
|
type ContractArtifactWithClassId = ContractArtifact & { classId: Fr };
|
|
165
197
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import { NO_FROM } from '@aztec/aztec.js/account';
|
|
1
2
|
import { AztecAddress } from '@aztec/aztec.js/addresses';
|
|
2
3
|
import { NO_WAIT } from '@aztec/aztec.js/contracts';
|
|
3
|
-
import type
|
|
4
|
+
import { type AztecNode, waitForTx } from '@aztec/aztec.js/node';
|
|
4
5
|
import type { DeployAccountOptions } from '@aztec/aztec.js/wallet';
|
|
5
6
|
import { prettyPrintJSON } from '@aztec/cli/cli-utils';
|
|
6
7
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
7
8
|
import type { LogFn, Logger } from '@aztec/foundation/log';
|
|
8
|
-
import type
|
|
9
|
+
import { type TxHash, type TxReceipt, TxStatus } from '@aztec/stdlib/tx';
|
|
9
10
|
|
|
10
11
|
import { DEFAULT_TX_TIMEOUT_S } from '../utils/cli_wallet_and_node_wrapper.js';
|
|
11
12
|
import type { AccountType } from '../utils/constants.js';
|
|
@@ -18,6 +19,7 @@ export async function createAccount(
|
|
|
18
19
|
aztecNode: AztecNode,
|
|
19
20
|
accountType: AccountType,
|
|
20
21
|
secretKey: Fr | undefined,
|
|
22
|
+
salt: Fr | undefined,
|
|
21
23
|
publicKey: string | undefined,
|
|
22
24
|
alias: string | undefined,
|
|
23
25
|
deployer: AztecAddress | undefined,
|
|
@@ -27,6 +29,7 @@ export async function createAccount(
|
|
|
27
29
|
registerClass: boolean,
|
|
28
30
|
wait: boolean,
|
|
29
31
|
feeOpts: CLIFeeArgs,
|
|
32
|
+
waitForStatus: TxStatus,
|
|
30
33
|
json: boolean,
|
|
31
34
|
verbose: boolean,
|
|
32
35
|
debugLogger: Logger,
|
|
@@ -38,10 +41,10 @@ export async function createAccount(
|
|
|
38
41
|
undefined /* address, we don't have it yet */,
|
|
39
42
|
secretKey,
|
|
40
43
|
accountType,
|
|
41
|
-
|
|
44
|
+
salt,
|
|
42
45
|
publicKey,
|
|
43
46
|
);
|
|
44
|
-
const
|
|
47
|
+
const instanceSalt = account.getInstance().salt;
|
|
45
48
|
const { address, publicKeys, partialAddress } = await account.getCompleteAddress();
|
|
46
49
|
|
|
47
50
|
const out: Record<string, any> = {};
|
|
@@ -52,7 +55,7 @@ export async function createAccount(
|
|
|
52
55
|
out.secretKey = secretKey;
|
|
53
56
|
}
|
|
54
57
|
out.partialAddress = partialAddress;
|
|
55
|
-
out.salt =
|
|
58
|
+
out.salt = instanceSalt;
|
|
56
59
|
out.initHash = account.getInstance().initializationHash;
|
|
57
60
|
} else {
|
|
58
61
|
log(`\nNew account:\n`);
|
|
@@ -62,7 +65,7 @@ export async function createAccount(
|
|
|
62
65
|
log(`Secret key: ${secretKey.toString()}`);
|
|
63
66
|
}
|
|
64
67
|
log(`Partial address: ${partialAddress.toString()}`);
|
|
65
|
-
log(`Salt: ${
|
|
68
|
+
log(`Salt: ${instanceSalt.toString()}`);
|
|
66
69
|
log(`Init hash: ${account.getInstance().initializationHash.toString()}`);
|
|
67
70
|
}
|
|
68
71
|
|
|
@@ -72,7 +75,7 @@ export async function createAccount(
|
|
|
72
75
|
const { paymentMethod, gasSettings } = await feeOpts.toUserFeeOptions(aztecNode, wallet, address);
|
|
73
76
|
|
|
74
77
|
const delegatedDeployment = deployer && !account.address.equals(deployer);
|
|
75
|
-
const from = delegatedDeployment ? deployer :
|
|
78
|
+
const from = delegatedDeployment ? deployer : NO_FROM;
|
|
76
79
|
|
|
77
80
|
const deployAccountOpts: DeployAccountOptions = {
|
|
78
81
|
skipClassPublication: !registerClass,
|
|
@@ -82,11 +85,15 @@ export async function createAccount(
|
|
|
82
85
|
fee: { paymentMethod, gasSettings },
|
|
83
86
|
};
|
|
84
87
|
|
|
88
|
+
const localStart = performance.now();
|
|
85
89
|
const deployMethod = await account.getDeployMethod();
|
|
86
|
-
const
|
|
90
|
+
const sim = await deployMethod.simulate({
|
|
87
91
|
...deployAccountOpts,
|
|
88
92
|
fee: { ...deployAccountOpts.fee, estimateGas: true },
|
|
89
93
|
});
|
|
94
|
+
// estimateGas: true guarantees these fields are present
|
|
95
|
+
const estimatedGas = sim.estimatedGas!;
|
|
96
|
+
const stats = sim.stats!;
|
|
90
97
|
|
|
91
98
|
if (feeOpts.estimateOnly) {
|
|
92
99
|
if (json) {
|
|
@@ -109,7 +116,7 @@ export async function createAccount(
|
|
|
109
116
|
if (!json) {
|
|
110
117
|
log(`\nWaiting for account contract deployment...`);
|
|
111
118
|
}
|
|
112
|
-
const
|
|
119
|
+
const sendOpts = {
|
|
113
120
|
...deployAccountOpts,
|
|
114
121
|
fee: deployAccountOpts.fee
|
|
115
122
|
? {
|
|
@@ -117,18 +124,25 @@ export async function createAccount(
|
|
|
117
124
|
gasSettings: estimatedGas,
|
|
118
125
|
}
|
|
119
126
|
: undefined,
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
({ txHash } = await deployMethod.send({ ...sendOpts, wait: NO_WAIT }));
|
|
130
|
+
const localTimeMs = performance.now() - localStart;
|
|
131
|
+
|
|
132
|
+
if (wait) {
|
|
133
|
+
const nodeStart = performance.now();
|
|
134
|
+
txReceipt = await waitForTx(aztecNode, txHash, { timeout: DEFAULT_TX_TIMEOUT_S, waitForStatus });
|
|
135
|
+
const nodeTimeMs = performance.now() - nodeStart;
|
|
136
|
+
|
|
126
137
|
out.txReceipt = {
|
|
127
138
|
status: txReceipt.status,
|
|
128
139
|
transactionFee: txReceipt.transactionFee,
|
|
129
140
|
};
|
|
130
|
-
|
|
131
|
-
|
|
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
|
+
}
|
|
132
146
|
}
|
|
133
147
|
debugLogger.debug(`Account contract tx sent with hash ${txHash.toString()}`);
|
|
134
148
|
out.txHash = txHash;
|
|
@@ -146,5 +160,5 @@ export async function createAccount(
|
|
|
146
160
|
}
|
|
147
161
|
}
|
|
148
162
|
|
|
149
|
-
return { alias, address, secretKey, salt };
|
|
163
|
+
return { alias, address, secretKey, salt: instanceSalt };
|
|
150
164
|
}
|
package/src/cmds/deploy.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
+
import { NO_FROM } from '@aztec/aztec.js/account';
|
|
1
2
|
import { AztecAddress } from '@aztec/aztec.js/addresses';
|
|
2
3
|
import type { DeployOptions } from '@aztec/aztec.js/contracts';
|
|
3
4
|
import { NO_WAIT } from '@aztec/aztec.js/contracts';
|
|
4
5
|
import { ContractDeployer } from '@aztec/aztec.js/deployment';
|
|
5
6
|
import { Fr } from '@aztec/aztec.js/fields';
|
|
6
|
-
import type
|
|
7
|
+
import { type AztecNode, waitForTx } from '@aztec/aztec.js/node';
|
|
7
8
|
import { encodeArgs, getContractArtifact, prettyPrintJSON } from '@aztec/cli/utils';
|
|
8
9
|
import type { LogFn, Logger } from '@aztec/foundation/log';
|
|
9
10
|
import { getAllFunctionAbis, getInitializer } from '@aztec/stdlib/abi';
|
|
10
11
|
import { PublicKeys } from '@aztec/stdlib/keys';
|
|
12
|
+
import type { TxStatus } from '@aztec/stdlib/tx';
|
|
11
13
|
|
|
12
14
|
import { DEFAULT_TX_TIMEOUT_S } from '../utils/cli_wallet_and_node_wrapper.js';
|
|
13
15
|
import { CLIFeeArgs } from '../utils/options/fees.js';
|
|
@@ -29,6 +31,7 @@ export async function deploy(
|
|
|
29
31
|
skipInitialization: boolean | undefined,
|
|
30
32
|
wait: boolean,
|
|
31
33
|
feeOpts: CLIFeeArgs,
|
|
34
|
+
waitForStatus: TxStatus,
|
|
32
35
|
verbose: boolean,
|
|
33
36
|
timeout: number = DEFAULT_TX_TIMEOUT_S,
|
|
34
37
|
debugLogger: Logger,
|
|
@@ -42,12 +45,7 @@ export async function deploy(
|
|
|
42
45
|
|
|
43
46
|
// TODO(#12081): Add contractArtifact.noirVersion and check here (via Noir.lock)?
|
|
44
47
|
|
|
45
|
-
const contractDeployer = new ContractDeployer(
|
|
46
|
-
contractArtifact,
|
|
47
|
-
wallet,
|
|
48
|
-
publicKeys ?? PublicKeys.default(),
|
|
49
|
-
initializer,
|
|
50
|
-
);
|
|
48
|
+
const contractDeployer = new ContractDeployer(contractArtifact, wallet, initializer);
|
|
51
49
|
|
|
52
50
|
let args = [];
|
|
53
51
|
if (rawArgs.length > 0) {
|
|
@@ -59,22 +57,24 @@ export async function deploy(
|
|
|
59
57
|
debugLogger.debug(`Encoded arguments: ${args.join(', ')}`);
|
|
60
58
|
}
|
|
61
59
|
|
|
62
|
-
const
|
|
60
|
+
const deployInteraction = contractDeployer.deploy(args, { salt, publicKeys: publicKeys ?? PublicKeys.default() });
|
|
63
61
|
const { paymentMethod, gasSettings } = await feeOpts.toUserFeeOptions(node, wallet, deployer);
|
|
64
62
|
const deployOpts: DeployOptions = {
|
|
65
63
|
fee: { gasSettings, paymentMethod },
|
|
66
|
-
from: deployer ??
|
|
67
|
-
contractAddressSalt: salt,
|
|
68
|
-
universalDeploy: !deployer,
|
|
64
|
+
from: deployer ?? NO_FROM,
|
|
69
65
|
skipClassPublication,
|
|
70
66
|
skipInitialization,
|
|
71
67
|
skipInstancePublication,
|
|
72
68
|
};
|
|
73
69
|
|
|
74
|
-
const
|
|
70
|
+
const localStart = performance.now();
|
|
71
|
+
const sim = await deployInteraction.simulate({
|
|
75
72
|
...deployOpts,
|
|
76
73
|
fee: { ...deployOpts.fee, estimateGas: true },
|
|
77
74
|
});
|
|
75
|
+
// estimateGas: true guarantees these fields are present
|
|
76
|
+
const estimatedGas = sim.estimatedGas!;
|
|
77
|
+
const stats = sim.stats!;
|
|
78
78
|
|
|
79
79
|
if (feeOpts.estimateOnly) {
|
|
80
80
|
if (json) {
|
|
@@ -94,48 +94,51 @@ export async function deploy(
|
|
|
94
94
|
printProfileResult(stats, log);
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
const
|
|
98
|
-
const
|
|
97
|
+
const instance = await deployInteraction.getInstance();
|
|
98
|
+
const address = instance.address;
|
|
99
|
+
const partialAddress = await deployInteraction.getPartialAddress();
|
|
100
|
+
|
|
101
|
+
const { txHash } = await deployInteraction.send({ ...deployOpts, wait: NO_WAIT });
|
|
102
|
+
const localTimeMs = performance.now() - localStart;
|
|
103
|
+
debugLogger.debug(`Deploy tx sent with hash ${txHash.toString()}`);
|
|
104
|
+
out.hash = txHash;
|
|
99
105
|
|
|
100
106
|
if (wait) {
|
|
101
|
-
const
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
out.hash = txHash;
|
|
107
|
+
const nodeStart = performance.now();
|
|
108
|
+
const receipt = await waitForTx(node, txHash, { timeout, waitForStatus });
|
|
109
|
+
const nodeTimeMs = performance.now() - nodeStart;
|
|
105
110
|
|
|
106
111
|
if (!json) {
|
|
107
|
-
log(`Contract deployed at ${address
|
|
108
|
-
log(`Contract partial address ${
|
|
112
|
+
log(`Contract deployed at ${address.toString()}`);
|
|
113
|
+
log(`Contract partial address ${partialAddress.toString()}`);
|
|
109
114
|
log(`Contract init hash ${instance.initializationHash.toString()}`);
|
|
110
115
|
log(`Deployment tx hash: ${txHash.toString()}`);
|
|
111
116
|
log(`Deployment salt: ${salt.toString()}`);
|
|
112
117
|
log(`Deployer: ${instance.deployer.toString()}`);
|
|
113
118
|
log(`Transaction fee: ${receipt.transactionFee?.toString()}`);
|
|
119
|
+
log(` Local processing time: ${(localTimeMs / 1000).toFixed(1)}s`);
|
|
120
|
+
log(` Node inclusion time: ${(nodeTimeMs / 1000).toFixed(1)}s`);
|
|
114
121
|
} else {
|
|
115
122
|
out.contract = {
|
|
116
|
-
address: address
|
|
117
|
-
partialAddress:
|
|
123
|
+
address: address.toString(),
|
|
124
|
+
partialAddress: partialAddress.toString(),
|
|
118
125
|
initializationHash: instance.initializationHash.toString(),
|
|
119
126
|
salt: salt.toString(),
|
|
120
127
|
transactionFee: receipt.transactionFee?.toString(),
|
|
121
128
|
};
|
|
122
129
|
}
|
|
123
130
|
} else {
|
|
124
|
-
const txHash = await deploy.send({ ...deployOpts, wait: NO_WAIT });
|
|
125
|
-
debugLogger.debug(`Deploy tx sent with hash ${txHash.toString()}`);
|
|
126
|
-
out.hash = txHash;
|
|
127
|
-
|
|
128
131
|
if (!json) {
|
|
129
|
-
log(`Contract deployed at ${address
|
|
130
|
-
log(`Contract partial address ${
|
|
132
|
+
log(`Contract deployed at ${address.toString()}`);
|
|
133
|
+
log(`Contract partial address ${partialAddress.toString()}`);
|
|
131
134
|
log(`Contract init hash ${instance.initializationHash.toString()}`);
|
|
132
135
|
log(`Deployment tx hash: ${txHash.toString()}`);
|
|
133
136
|
log(`Deployment salt: ${salt.toString()}`);
|
|
134
137
|
log(`Deployer: ${instance.deployer.toString()}`);
|
|
135
138
|
} else {
|
|
136
139
|
out.contract = {
|
|
137
|
-
address: address
|
|
138
|
-
partialAddress:
|
|
140
|
+
address: address.toString(),
|
|
141
|
+
partialAddress: partialAddress.toString(),
|
|
139
142
|
initializationHash: instance.initializationHash.toString(),
|
|
140
143
|
salt: salt.toString(),
|
|
141
144
|
};
|
|
@@ -145,5 +148,5 @@ export async function deploy(
|
|
|
145
148
|
if (json) {
|
|
146
149
|
log(prettyPrintJSON(out));
|
|
147
150
|
}
|
|
148
|
-
return
|
|
151
|
+
return await deployInteraction.getAddress();
|
|
149
152
|
}
|