@aztec/wallets 0.0.1-commit.d1da697d6 → 0.0.1-commit.d58ff9d0
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/embedded/account-contract-providers/bundle.d.ts +6 -8
- package/dest/embedded/account-contract-providers/bundle.d.ts.map +1 -1
- package/dest/embedded/account-contract-providers/bundle.js +12 -10
- package/dest/embedded/account-contract-providers/lazy.d.ts +6 -8
- package/dest/embedded/account-contract-providers/lazy.d.ts.map +1 -1
- package/dest/embedded/account-contract-providers/lazy.js +20 -10
- package/dest/embedded/account-contract-providers/types.d.ts +6 -8
- package/dest/embedded/account-contract-providers/types.d.ts.map +1 -1
- package/dest/embedded/embedded_wallet.d.ts +32 -6
- package/dest/embedded/embedded_wallet.d.ts.map +1 -1
- package/dest/embedded/embedded_wallet.js +146 -41
- package/dest/embedded/entrypoints/browser.d.ts +1 -1
- package/dest/embedded/entrypoints/browser.d.ts.map +1 -1
- package/dest/embedded/entrypoints/browser.js +33 -13
- package/dest/embedded/entrypoints/node.d.ts +1 -1
- package/dest/embedded/entrypoints/node.d.ts.map +1 -1
- package/dest/embedded/entrypoints/node.js +36 -13
- package/dest/embedded/store_encryption.d.ts +74 -0
- package/dest/embedded/store_encryption.d.ts.map +1 -0
- package/dest/embedded/store_encryption.js +93 -0
- package/dest/embedded/wallet_db.d.ts +9 -6
- package/dest/embedded/wallet_db.d.ts.map +1 -1
- package/dest/embedded/wallet_db.js +13 -11
- package/dest/testing.d.ts +8 -4
- package/dest/testing.d.ts.map +1 -1
- package/dest/testing.js +8 -14
- package/package.json +12 -10
- package/src/embedded/account-contract-providers/bundle.ts +15 -12
- package/src/embedded/account-contract-providers/lazy.ts +23 -12
- package/src/embedded/account-contract-providers/types.ts +6 -4
- package/src/embedded/embedded_wallet.ts +175 -45
- package/src/embedded/entrypoints/browser.ts +32 -17
- package/src/embedded/entrypoints/node.ts +37 -21
- package/src/embedded/store_encryption.ts +146 -0
- package/src/embedded/wallet_db.ts +18 -12
- package/src/testing.ts +11 -17
|
@@ -1,30 +1,48 @@
|
|
|
1
1
|
import { type Account, NO_FROM } from '@aztec/aztec.js/account';
|
|
2
2
|
import { CallAuthorizationRequest } from '@aztec/aztec.js/authorization';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import {
|
|
4
|
+
ContractFunctionInteraction,
|
|
5
|
+
type InteractionWaitOptions,
|
|
6
|
+
NO_WAIT,
|
|
7
|
+
type SendReturn,
|
|
8
|
+
type WaitOpts,
|
|
9
|
+
} from '@aztec/aztec.js/contracts';
|
|
10
|
+
import type {
|
|
11
|
+
Aliased,
|
|
12
|
+
ExecuteUtilityOptions,
|
|
13
|
+
PrivateEvent,
|
|
14
|
+
PrivateEventFilter,
|
|
15
|
+
ProfileOptions,
|
|
16
|
+
SendOptions,
|
|
17
|
+
SimulateOptions,
|
|
18
|
+
} from '@aztec/aztec.js/wallet';
|
|
19
|
+
import { AccountManager, TxSimulationResultWithAppOffset } from '@aztec/aztec.js/wallet';
|
|
6
20
|
import type { DefaultAccountEntrypointOptions } from '@aztec/entrypoints/account';
|
|
7
21
|
import { DefaultEntrypoint } from '@aztec/entrypoints/default';
|
|
22
|
+
import { poseidon2Hash } from '@aztec/foundation/crypto/poseidon';
|
|
23
|
+
import { Schnorr } from '@aztec/foundation/crypto/schnorr';
|
|
8
24
|
import { Fq, Fr } from '@aztec/foundation/curves/bn254';
|
|
9
25
|
import type { Logger } from '@aztec/foundation/log';
|
|
26
|
+
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
10
27
|
import type { PXEConfig, PXECreationOptions } from '@aztec/pxe/client/lazy';
|
|
11
28
|
import type { PXE } from '@aztec/pxe/server';
|
|
29
|
+
import type { EventMetadataDefinition, FunctionCall } from '@aztec/stdlib/abi';
|
|
12
30
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
13
|
-
import {
|
|
31
|
+
import { getContractClassFromArtifact } from '@aztec/stdlib/contract';
|
|
14
32
|
import { GasSettings } from '@aztec/stdlib/gas';
|
|
15
33
|
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
16
|
-
import { deriveSigningKey } from '@aztec/stdlib/keys';
|
|
17
34
|
import {
|
|
18
35
|
type ContractOverrides,
|
|
19
36
|
ExecutionPayload,
|
|
20
37
|
SimulationOverrides,
|
|
21
38
|
type TxExecutionRequest,
|
|
22
|
-
type
|
|
39
|
+
type TxProfileResult,
|
|
23
40
|
TxStatus,
|
|
41
|
+
type UtilityExecutionResult,
|
|
24
42
|
collectOffchainEffects,
|
|
25
43
|
mergeExecutionPayloads,
|
|
26
44
|
} from '@aztec/stdlib/tx';
|
|
27
|
-
import { BaseWallet, type SimulateViaEntrypointOptions } from '@aztec/wallet-sdk/base-wallet';
|
|
45
|
+
import { BaseWallet, type SimulateViaEntrypointOptions, getGasLimits } from '@aztec/wallet-sdk/base-wallet';
|
|
28
46
|
|
|
29
47
|
import type { AccountContractsProvider } from './account-contract-providers/types.js';
|
|
30
48
|
import { type AccountType, WalletDB } from './wallet_db.js';
|
|
@@ -40,10 +58,20 @@ export function splitPxeOptions(pxe?: EmbeddedWalletPXEOptions): {
|
|
|
40
58
|
if (!pxe) {
|
|
41
59
|
return { config: {}, creation: {} };
|
|
42
60
|
}
|
|
43
|
-
const { loggers, loggerActorLabel, proverOrOptions, store, simulator, ...config } =
|
|
44
|
-
|
|
61
|
+
const { loggers, loggerActorLabel, proverOrOptions, store, simulator, hooks, preloadedContractsProvider, ...config } =
|
|
62
|
+
pxe;
|
|
63
|
+
return {
|
|
64
|
+
config,
|
|
65
|
+
creation: { loggers, loggerActorLabel, proverOrOptions, store, simulator, hooks, preloadedContractsProvider },
|
|
66
|
+
};
|
|
45
67
|
}
|
|
46
68
|
|
|
69
|
+
/** Options for the EmbeddedWallet's own DB (accounts, senders — distinct from PXE state). */
|
|
70
|
+
export type EmbeddedWalletDBOptions = {
|
|
71
|
+
/** Override the wallet DB backend. If omitted, an IndexedDB (browser) / LMDB (node) store is created. */
|
|
72
|
+
store?: AztecAsyncKVStore;
|
|
73
|
+
};
|
|
74
|
+
|
|
47
75
|
export type EmbeddedWalletOptions = {
|
|
48
76
|
/** Parent logger. Child loggers are derived via createChild() for each subsystem. */
|
|
49
77
|
logger?: Logger;
|
|
@@ -51,6 +79,8 @@ export type EmbeddedWalletOptions = {
|
|
|
51
79
|
ephemeral?: boolean;
|
|
52
80
|
/** PXE configuration and dependency overrides (custom store, prover, simulator). */
|
|
53
81
|
pxe?: EmbeddedWalletPXEOptions;
|
|
82
|
+
/** Wallet DB dependency overrides (custom store). */
|
|
83
|
+
walletDb?: EmbeddedWalletDBOptions;
|
|
54
84
|
/**
|
|
55
85
|
* Override PXE configuration.
|
|
56
86
|
* @deprecated Use `pxe` instead.
|
|
@@ -68,6 +98,10 @@ const DEFAULT_ESTIMATED_GAS_PADDING = 0.1;
|
|
|
68
98
|
export class EmbeddedWallet extends BaseWallet {
|
|
69
99
|
protected estimatedGasPadding = DEFAULT_ESTIMATED_GAS_PADDING;
|
|
70
100
|
|
|
101
|
+
// Stub class ids, populated on wallet startup
|
|
102
|
+
// to avoid redundant work per simulation
|
|
103
|
+
protected stubClassIds = new Map<AccountType, Fr>();
|
|
104
|
+
|
|
71
105
|
constructor(
|
|
72
106
|
pxe: PXE,
|
|
73
107
|
aztecNode: AztecNode,
|
|
@@ -96,15 +130,17 @@ export class EmbeddedWallet extends BaseWallet {
|
|
|
96
130
|
|
|
97
131
|
override async registerSender(address: AztecAddress, alias: string) {
|
|
98
132
|
await this.walletDB.storeSender(address, alias);
|
|
99
|
-
|
|
133
|
+
await this.pxe.registerTaggingSecretSource({ kind: 'address-derived', sender: address });
|
|
134
|
+
return address;
|
|
100
135
|
}
|
|
101
136
|
|
|
102
137
|
override async getAddressBook(): Promise<Aliased<AztecAddress>[]> {
|
|
103
|
-
const
|
|
138
|
+
const sources = await this.pxe.getTaggingSecretSources({ kind: 'address-derived' });
|
|
139
|
+
const senders = sources.map(source => source.sender);
|
|
104
140
|
const storedSenders = await this.walletDB.listSenders();
|
|
105
141
|
for (const storedSender of storedSenders) {
|
|
106
142
|
if (senders.findIndex(sender => sender.equals(storedSender.item)) === -1) {
|
|
107
|
-
await this.pxe.
|
|
143
|
+
await this.pxe.registerTaggingSecretSource({ kind: 'address-derived', sender: storedSender.item });
|
|
108
144
|
}
|
|
109
145
|
}
|
|
110
146
|
return storedSenders;
|
|
@@ -119,6 +155,9 @@ export class EmbeddedWallet extends BaseWallet {
|
|
|
119
155
|
executionPayload: ExecutionPayload,
|
|
120
156
|
opts: SendOptions<W>,
|
|
121
157
|
): Promise<SendReturn<W>> {
|
|
158
|
+
// PXE has autoSync disabled by the embedded wallet entrypoints, so we sync once here to cover
|
|
159
|
+
// both the inner simulateTx (via simulateViaEntrypoint) and the proveTx that super.sendTx
|
|
160
|
+
await this.pxe.sync();
|
|
122
161
|
const feeOptions = await this.completeFeeOptions({
|
|
123
162
|
from: opts.from,
|
|
124
163
|
feePayer: executionPayload.feePayer,
|
|
@@ -131,8 +170,9 @@ export class EmbeddedWallet extends BaseWallet {
|
|
|
131
170
|
const simulationResult = await this.simulateViaEntrypoint(executionPayload, {
|
|
132
171
|
from: opts.from,
|
|
133
172
|
feeOptions,
|
|
134
|
-
|
|
173
|
+
additionalScopes: opts.additionalScopes,
|
|
135
174
|
skipTxValidation: true,
|
|
175
|
+
sendMessagesAs: opts.sendMessagesAs,
|
|
136
176
|
});
|
|
137
177
|
|
|
138
178
|
const offchainEffects = collectOffchainEffects(simulationResult.privateExecutionResult);
|
|
@@ -154,7 +194,8 @@ export class EmbeddedWallet extends BaseWallet {
|
|
|
154
194
|
executionPayload.authWitnesses.push(authwit);
|
|
155
195
|
}
|
|
156
196
|
}
|
|
157
|
-
const
|
|
197
|
+
const maxTxGasLimits = await this.getMaxTxGasLimits();
|
|
198
|
+
const estimated = getGasLimits(simulationResult.gasUsed, maxTxGasLimits, this.estimatedGasPadding);
|
|
158
199
|
this.log.verbose(
|
|
159
200
|
`Estimated gas limits for tx: DA=${estimated.gasLimits.daGas} L2=${estimated.gasLimits.l2Gas} teardownDA=${estimated.teardownGasLimits.daGas} teardownL2=${estimated.teardownGasLimits.l2Gas}`,
|
|
160
201
|
);
|
|
@@ -165,37 +206,102 @@ export class EmbeddedWallet extends BaseWallet {
|
|
|
165
206
|
gasLimits: opts.fee?.gasSettings?.gasLimits ?? estimated.gasLimits,
|
|
166
207
|
teardownGasLimits: opts.fee?.gasSettings?.teardownGasLimits ?? estimated.teardownGasLimits,
|
|
167
208
|
});
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
209
|
+
let wait: InteractionWaitOptions = opts.wait;
|
|
210
|
+
if (wait !== NO_WAIT) {
|
|
211
|
+
const callerWaitOpts: WaitOpts = typeof wait === 'object' ? wait : {};
|
|
212
|
+
wait = {
|
|
213
|
+
...callerWaitOpts,
|
|
214
|
+
// Default to PROPOSED so the wait returns as soon as the tx lands in a proposed L2 block,
|
|
215
|
+
// rather than waiting until the end of the slot for the checkpoint to be published to L1.
|
|
216
|
+
// This is what makes MBPS (Multiple Blocks Per Slot) actually improve UX: with CHECKPOINTED
|
|
217
|
+
// we'd block until L1 inclusion regardless of how early in the slot the tx was sequenced.
|
|
218
|
+
// The tradeoff is a weaker guarantee — a proposed block only becomes canonical once it (or
|
|
219
|
+
// a later block in the same slot) is checkpointed, so a tx could be re-orged out if the
|
|
220
|
+
// proposer fails to publish to L1 (which should be rare, since they'd get slashed for it).
|
|
221
|
+
waitForStatus: callerWaitOpts.waitForStatus ?? TxStatus.PROPOSED,
|
|
222
|
+
};
|
|
179
223
|
}
|
|
180
224
|
return super.sendTx(executionPayload, {
|
|
181
225
|
...opts,
|
|
226
|
+
wait: wait as W,
|
|
182
227
|
fee: { ...opts.fee, gasSettings },
|
|
183
228
|
});
|
|
184
229
|
}
|
|
185
230
|
|
|
231
|
+
/**
|
|
232
|
+
* Overrides the base simulateTx to drive PXE syncing explicitly. The PXE created by the embedded
|
|
233
|
+
* wallet has autoSync disabled (so we can share one sync across simulate+send in sendTx); for
|
|
234
|
+
* standalone simulations we still need a fresh anchor block, which we provide here.
|
|
235
|
+
*/
|
|
236
|
+
public override async simulateTx(
|
|
237
|
+
executionPayload: ExecutionPayload,
|
|
238
|
+
opts: SimulateOptions,
|
|
239
|
+
): Promise<TxSimulationResultWithAppOffset> {
|
|
240
|
+
await this.pxe.sync();
|
|
241
|
+
return super.simulateTx(executionPayload, opts);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
public override async profileTx(executionPayload: ExecutionPayload, opts: ProfileOptions): Promise<TxProfileResult> {
|
|
245
|
+
await this.pxe.sync();
|
|
246
|
+
return super.profileTx(executionPayload, opts);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
public override async executeUtility(
|
|
250
|
+
call: FunctionCall,
|
|
251
|
+
opts: ExecuteUtilityOptions,
|
|
252
|
+
): Promise<UtilityExecutionResult> {
|
|
253
|
+
await this.pxe.sync();
|
|
254
|
+
return super.executeUtility(call, opts);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
public override async getPrivateEvents<T>(
|
|
258
|
+
eventDef: EventMetadataDefinition,
|
|
259
|
+
eventFilter: PrivateEventFilter,
|
|
260
|
+
): Promise<PrivateEvent<T>[]> {
|
|
261
|
+
await this.pxe.sync();
|
|
262
|
+
return super.getPrivateEvents<T>(eventDef, eventFilter);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Hashes and registers the stub class for every supported account type with PXE, populating
|
|
267
|
+
* stubClassIds. Called on wallet initialization.
|
|
268
|
+
*/
|
|
269
|
+
async initStubClasses(): Promise<void> {
|
|
270
|
+
const schnorrArtifact = await this.accountContracts.getStubAccountContractArtifact('schnorr');
|
|
271
|
+
const { id: schnorrClassId } = await getContractClassFromArtifact(schnorrArtifact);
|
|
272
|
+
await this.pxe.registerContractClass(schnorrArtifact);
|
|
273
|
+
|
|
274
|
+
// ecdsa stubs share the same class id
|
|
275
|
+
const ecdsaArtifact = await this.accountContracts.getStubAccountContractArtifact('ecdsasecp256r1');
|
|
276
|
+
const { id: ecdsaClassId } = await getContractClassFromArtifact(ecdsaArtifact);
|
|
277
|
+
await this.pxe.registerContractClass(ecdsaArtifact);
|
|
278
|
+
|
|
279
|
+
this.stubClassIds.set('schnorr', schnorrClassId);
|
|
280
|
+
this.stubClassIds.set('schnorr_initializerless', schnorrClassId);
|
|
281
|
+
this.stubClassIds.set('ecdsasecp256k1', ecdsaClassId);
|
|
282
|
+
this.stubClassIds.set('ecdsasecp256r1', ecdsaClassId);
|
|
283
|
+
}
|
|
284
|
+
|
|
186
285
|
/**
|
|
187
286
|
* Builds contract overrides for all provided addresses by replacing their account contracts with stub implementations.
|
|
287
|
+
* Uses a type-specific stub artifact so that the stub's constructor selector matches the real account's constructor.
|
|
188
288
|
*/
|
|
189
289
|
protected async buildAccountOverrides(addresses: AztecAddress[]): Promise<ContractOverrides> {
|
|
190
290
|
const accounts = await this.getAccounts();
|
|
191
291
|
const contracts: ContractOverrides = {};
|
|
192
292
|
|
|
193
|
-
const stubArtifact = await this.accountContracts.getStubAccountContractArtifact();
|
|
194
|
-
|
|
195
293
|
const filtered = accounts.filter(acc => addresses.some(addr => addr.equals(acc.item)));
|
|
196
294
|
|
|
197
295
|
for (const account of filtered) {
|
|
198
296
|
const address = account.item;
|
|
297
|
+
const { type } = await this.walletDB.retrieveAccount(address);
|
|
298
|
+
const stubClassId = this.stubClassIds.get(type);
|
|
299
|
+
if (!stubClassId) {
|
|
300
|
+
throw new Error(
|
|
301
|
+
`Stub class for account type '${type}' was not registered at wallet init. This is a bug — initStubClasses should cover every supported AccountType.`,
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
|
|
199
305
|
const originalAccount = await this.getAccountFromAddress(address);
|
|
200
306
|
const completeAddress = originalAccount.getCompleteAddress();
|
|
201
307
|
const contractInstance = await this.pxe.getContractInstance(completeAddress.address);
|
|
@@ -205,13 +311,8 @@ export class EmbeddedWallet extends BaseWallet {
|
|
|
205
311
|
);
|
|
206
312
|
}
|
|
207
313
|
|
|
208
|
-
const stubInstance = await getContractInstanceFromInstantiationParams(stubArtifact, {
|
|
209
|
-
salt: Fr.random(),
|
|
210
|
-
});
|
|
211
|
-
|
|
212
314
|
contracts[address.toString()] = {
|
|
213
|
-
instance:
|
|
214
|
-
artifact: stubArtifact,
|
|
315
|
+
instance: { ...contractInstance, currentContractClassId: stubClassId },
|
|
215
316
|
};
|
|
216
317
|
}
|
|
217
318
|
|
|
@@ -226,8 +327,9 @@ export class EmbeddedWallet extends BaseWallet {
|
|
|
226
327
|
protected override async simulateViaEntrypoint(
|
|
227
328
|
executionPayload: ExecutionPayload,
|
|
228
329
|
opts: SimulateViaEntrypointOptions,
|
|
229
|
-
): Promise<
|
|
230
|
-
const { from, feeOptions,
|
|
330
|
+
): Promise<TxSimulationResultWithAppOffset> {
|
|
331
|
+
const { from, feeOptions, additionalScopes, skipTxValidation, skipFeeEnforcement, sendMessagesAs } = opts;
|
|
332
|
+
const scopes = this.scopesFrom(from, additionalScopes ?? [], sendMessagesAs);
|
|
231
333
|
|
|
232
334
|
const feeExecutionPayload = await feeOptions.walletFeePaymentMethod?.getExecutionPayload();
|
|
233
335
|
const finalExecutionPayload = feeExecutionPayload
|
|
@@ -235,17 +337,18 @@ export class EmbeddedWallet extends BaseWallet {
|
|
|
235
337
|
: executionPayload;
|
|
236
338
|
const chainInfo = await this.getChainInfo();
|
|
237
339
|
|
|
238
|
-
const accountOverrides = await this.buildAccountOverrides(
|
|
239
|
-
const overrides = new SimulationOverrides(accountOverrides);
|
|
340
|
+
const accountOverrides = await this.buildAccountOverrides(scopes);
|
|
341
|
+
const overrides = new SimulationOverrides({ contracts: accountOverrides });
|
|
240
342
|
|
|
241
343
|
let txRequest: TxExecutionRequest;
|
|
242
344
|
if (from === NO_FROM) {
|
|
243
345
|
const entrypoint = new DefaultEntrypoint();
|
|
244
346
|
txRequest = await entrypoint.createTxExecutionRequest(finalExecutionPayload, feeOptions.gasSettings, chainInfo);
|
|
245
347
|
} else {
|
|
348
|
+
const { type } = await this.walletDB.retrieveAccount(from);
|
|
246
349
|
const originalAccount = await this.getAccountFromAddress(from);
|
|
247
350
|
const completeAddress = originalAccount.getCompleteAddress();
|
|
248
|
-
const account = await this.accountContracts.createStubAccount(completeAddress);
|
|
351
|
+
const account = await this.accountContracts.createStubAccount(completeAddress, type);
|
|
249
352
|
const executionOptions: DefaultAccountEntrypointOptions = {
|
|
250
353
|
txNonce: Fr.random(),
|
|
251
354
|
cancellable: this.cancellableTransactions,
|
|
@@ -260,13 +363,16 @@ export class EmbeddedWallet extends BaseWallet {
|
|
|
260
363
|
);
|
|
261
364
|
}
|
|
262
365
|
|
|
263
|
-
|
|
366
|
+
const result = await this.pxe.simulateTx(txRequest, {
|
|
264
367
|
simulatePublic: true,
|
|
265
368
|
skipFeeEnforcement,
|
|
266
369
|
skipTxValidation,
|
|
267
370
|
overrides,
|
|
268
371
|
scopes,
|
|
372
|
+
senderForTags: this.senderForTagsFrom(from, sendMessagesAs),
|
|
269
373
|
});
|
|
374
|
+
const appCallOffset = await this.computeAppCallOffset(from, feeOptions);
|
|
375
|
+
return TxSimulationResultWithAppOffset.fromResultAndOffset(result, appCallOffset);
|
|
270
376
|
}
|
|
271
377
|
|
|
272
378
|
protected async createAccountInternal(
|
|
@@ -276,11 +382,19 @@ export class EmbeddedWallet extends BaseWallet {
|
|
|
276
382
|
signingKey: Buffer,
|
|
277
383
|
): Promise<AccountManager> {
|
|
278
384
|
let contract;
|
|
385
|
+
let immutablesHash;
|
|
386
|
+
let publicKey;
|
|
279
387
|
switch (type) {
|
|
280
388
|
case 'schnorr': {
|
|
281
389
|
contract = await this.accountContracts.getSchnorrAccountContract(Fq.fromBuffer(signingKey));
|
|
282
390
|
break;
|
|
283
391
|
}
|
|
392
|
+
case 'schnorr_initializerless': {
|
|
393
|
+
contract = await this.accountContracts.getSchnorrInitializerlessAccountContract(Fq.fromBuffer(signingKey));
|
|
394
|
+
publicKey = await new Schnorr().computePublicKey(Fq.fromBuffer(signingKey));
|
|
395
|
+
immutablesHash = await poseidon2Hash([publicKey.x, publicKey.y]);
|
|
396
|
+
break;
|
|
397
|
+
}
|
|
284
398
|
case 'ecdsasecp256k1': {
|
|
285
399
|
contract = await this.accountContracts.getEcdsaKAccountContract(signingKey);
|
|
286
400
|
break;
|
|
@@ -294,17 +408,29 @@ export class EmbeddedWallet extends BaseWallet {
|
|
|
294
408
|
}
|
|
295
409
|
}
|
|
296
410
|
|
|
297
|
-
const accountManager = await AccountManager.create(this, secret, contract, salt);
|
|
411
|
+
const accountManager = await AccountManager.create(this, secret, contract, { salt, immutablesHash });
|
|
298
412
|
|
|
299
413
|
const instance = accountManager.getInstance();
|
|
300
414
|
const existingInstance = await this.pxe.getContractInstance(instance.address);
|
|
301
415
|
if (!existingInstance) {
|
|
302
416
|
const existingArtifact = await this.pxe.getContractArtifact(instance.currentContractClassId);
|
|
417
|
+
const artifact = existingArtifact ?? (await accountManager.getAccountContract().getContractArtifact());
|
|
303
418
|
await this.registerContract(
|
|
304
419
|
instance,
|
|
305
420
|
!existingArtifact ? await accountManager.getAccountContract().getContractArtifact() : undefined,
|
|
306
421
|
accountManager.getSecretKey(),
|
|
307
422
|
);
|
|
423
|
+
if (type === 'schnorr_initializerless') {
|
|
424
|
+
const constructor = artifact.functions.find(f => f.name === 'constructor');
|
|
425
|
+
if (!constructor) {
|
|
426
|
+
throw new Error('Could not create SchnorrInitializerlessAccountContract: constructor ABI not found');
|
|
427
|
+
}
|
|
428
|
+
const storeCall = new ContractFunctionInteraction(this, instance.address, constructor, [
|
|
429
|
+
publicKey!.x,
|
|
430
|
+
publicKey!.y,
|
|
431
|
+
]);
|
|
432
|
+
await storeCall.simulate({ from: instance.address });
|
|
433
|
+
}
|
|
308
434
|
}
|
|
309
435
|
return accountManager;
|
|
310
436
|
}
|
|
@@ -321,9 +447,12 @@ export class EmbeddedWallet extends BaseWallet {
|
|
|
321
447
|
return accountManager;
|
|
322
448
|
}
|
|
323
449
|
|
|
324
|
-
createSchnorrAccount(secret: Fr, salt: Fr, signingKey
|
|
325
|
-
|
|
326
|
-
|
|
450
|
+
createSchnorrAccount(secret: Fr, salt: Fr, signingKey: Fq, alias?: string): Promise<AccountManager> {
|
|
451
|
+
return this.createAndStoreAccount(alias ?? '', 'schnorr', secret, salt, signingKey.toBuffer());
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
createSchnorrInitializerlessAccount(secret: Fr, salt: Fr, signingKey: Fq, alias?: string): Promise<AccountManager> {
|
|
455
|
+
return this.createAndStoreAccount(alias ?? '', 'schnorr_initializerless', secret, salt, signingKey.toBuffer());
|
|
327
456
|
}
|
|
328
457
|
|
|
329
458
|
createECDSARAccount(secret: Fr, salt: Fr, signingKey: Buffer, alias?: string): Promise<AccountManager> {
|
|
@@ -342,7 +471,8 @@ export class EmbeddedWallet extends BaseWallet {
|
|
|
342
471
|
this.estimatedGasPadding = value ?? DEFAULT_ESTIMATED_GAS_PADDING;
|
|
343
472
|
}
|
|
344
473
|
|
|
345
|
-
stop() {
|
|
346
|
-
|
|
474
|
+
async stop(): Promise<void> {
|
|
475
|
+
await this.pxe.stop();
|
|
476
|
+
await this.walletDB.close();
|
|
347
477
|
}
|
|
348
478
|
}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { type AztecNode, createAztecNodeClient } from '@aztec/aztec.js/node';
|
|
2
2
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
3
|
-
import {
|
|
4
|
-
import { type PXE, type PXECreationOptions, createPXE } from '@aztec/pxe/client/lazy';
|
|
3
|
+
import { openTmpStore } from '@aztec/kv-store/sqlite-opfs';
|
|
4
|
+
import { type PXE, type PXECreationOptions, createPXE, openBrowserStore } from '@aztec/pxe/client/lazy';
|
|
5
5
|
import { type PXEConfig, getPXEConfig } from '@aztec/pxe/config';
|
|
6
|
+
import { getStandardAuthRegistry } from '@aztec/standard-contracts/auth-registry/lazy';
|
|
7
|
+
import { getStandardHandshakeRegistry } from '@aztec/standard-contracts/handshake-registry/lazy';
|
|
8
|
+
import { getStandardMultiCallEntrypoint } from '@aztec/standard-contracts/multi-call-entrypoint/lazy';
|
|
6
9
|
|
|
7
10
|
import { LazyAccountContractsProvider } from '../account-contract-providers/lazy.js';
|
|
8
11
|
import type { AccountContractsProvider } from '../account-contract-providers/types.js';
|
|
9
12
|
import { EmbeddedWallet, type EmbeddedWalletOptions, splitPxeOptions } from '../embedded_wallet.js';
|
|
10
|
-
import { WalletDB } from '../wallet_db.js';
|
|
13
|
+
import { WALLET_DATA_SCHEMA_VERSION, WalletDB } from '../wallet_db.js';
|
|
11
14
|
|
|
12
15
|
export class BrowserEmbeddedWallet extends EmbeddedWallet {
|
|
13
16
|
static async create<T extends BrowserEmbeddedWallet = BrowserEmbeddedWallet>(
|
|
@@ -24,7 +27,6 @@ export class BrowserEmbeddedWallet extends EmbeddedWallet {
|
|
|
24
27
|
const rootLogger = options.logger ?? createLogger('embedded-wallet');
|
|
25
28
|
|
|
26
29
|
const aztecNode = typeof nodeOrUrl === 'string' ? createAztecNodeClient(nodeOrUrl) : nodeOrUrl;
|
|
27
|
-
const l1Contracts = await aztecNode.getL1ContractAddresses();
|
|
28
30
|
|
|
29
31
|
// Support both the new unified `pxe` option and the deprecated `pxeConfig`/`pxeOptions`.
|
|
30
32
|
const { config: pxeConfigFromPxe, creation: pxeCreationFromPxe } = splitPxeOptions(options.pxe);
|
|
@@ -32,8 +34,10 @@ export class BrowserEmbeddedWallet extends EmbeddedWallet {
|
|
|
32
34
|
const mergedCreationOverrides: PXECreationOptions = { ...options.pxeOptions, ...pxeCreationFromPxe };
|
|
33
35
|
|
|
34
36
|
const pxeConfig: PXEConfig = Object.assign(getPXEConfig(), {
|
|
35
|
-
proverEnabled: mergedConfigOverrides.proverEnabled
|
|
36
|
-
|
|
37
|
+
proverEnabled: mergedConfigOverrides.proverEnabled,
|
|
38
|
+
// Unused in the browser: sqlite-opfs keys stores by name, not directory.
|
|
39
|
+
dataDirectory: 'pxe_data',
|
|
40
|
+
autoSync: false,
|
|
37
41
|
...mergedConfigOverrides,
|
|
38
42
|
});
|
|
39
43
|
|
|
@@ -43,6 +47,13 @@ export class BrowserEmbeddedWallet extends EmbeddedWallet {
|
|
|
43
47
|
|
|
44
48
|
const pxeOptions: PXECreationOptions = {
|
|
45
49
|
...mergedCreationOverrides,
|
|
50
|
+
preloadedContractsProvider: mergedCreationOverrides.preloadedContractsProvider ?? {
|
|
51
|
+
getPreloadedContracts: async () => [
|
|
52
|
+
await getStandardMultiCallEntrypoint(),
|
|
53
|
+
await getStandardAuthRegistry(),
|
|
54
|
+
await getStandardHandshakeRegistry(),
|
|
55
|
+
],
|
|
56
|
+
},
|
|
46
57
|
loggers: {
|
|
47
58
|
store: rootLogger.createChild('pxe:data'),
|
|
48
59
|
pxe: rootLogger.createChild('pxe:service'),
|
|
@@ -53,21 +64,25 @@ export class BrowserEmbeddedWallet extends EmbeddedWallet {
|
|
|
53
64
|
|
|
54
65
|
const pxe = await createPXE(aztecNode, pxeConfig, pxeOptions);
|
|
55
66
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
67
|
+
let walletDBStore = options.walletDb?.store;
|
|
68
|
+
if (!walletDBStore) {
|
|
69
|
+
if (options.ephemeral) {
|
|
70
|
+
walletDBStore = await openTmpStore(true);
|
|
71
|
+
} else {
|
|
72
|
+
const { l1ChainId, l1ContractAddresses } = await aztecNode.getNodeInfo();
|
|
73
|
+
walletDBStore = await openBrowserStore(
|
|
59
74
|
'wallet_data',
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
dataStoreMapSizeKb: pxeConfig.dataStoreMapSizeKb,
|
|
63
|
-
l1Contracts,
|
|
64
|
-
},
|
|
65
|
-
1,
|
|
75
|
+
WALLET_DATA_SCHEMA_VERSION,
|
|
76
|
+
{ l1ChainId, rollupAddress: l1ContractAddresses.rollupAddress },
|
|
66
77
|
rootLogger.createChild('wallet:data'),
|
|
67
78
|
);
|
|
68
|
-
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const walletDB = new WalletDB(walletDBStore, rootLogger.createChild('wallet:db').info);
|
|
69
82
|
|
|
70
|
-
|
|
83
|
+
const wallet = new this(pxe, aztecNode, walletDB, new LazyAccountContractsProvider(), rootLogger) as T;
|
|
84
|
+
await wallet.initStubClasses();
|
|
85
|
+
return wallet;
|
|
71
86
|
}
|
|
72
87
|
}
|
|
73
88
|
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { createAztecNodeClient } from '@aztec/aztec.js/node';
|
|
2
2
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
3
|
-
import {
|
|
3
|
+
import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
|
|
4
4
|
import { type PXEConfig, getPXEConfig } from '@aztec/pxe/config';
|
|
5
|
-
import { type PXE, type PXECreationOptions, createPXE } from '@aztec/pxe/server';
|
|
5
|
+
import { type PXE, type PXECreationOptions, createPXE, openStore } from '@aztec/pxe/server';
|
|
6
|
+
import { getStandardAuthRegistry } from '@aztec/standard-contracts/auth-registry';
|
|
7
|
+
import { getStandardHandshakeRegistry } from '@aztec/standard-contracts/handshake-registry';
|
|
8
|
+
import { getStandardMultiCallEntrypoint } from '@aztec/standard-contracts/multi-call-entrypoint';
|
|
6
9
|
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
7
10
|
|
|
8
11
|
import { BundleAccountContractsProvider } from '../account-contract-providers/bundle.js';
|
|
9
12
|
import type { AccountContractsProvider } from '../account-contract-providers/types.js';
|
|
10
13
|
import { EmbeddedWallet, type EmbeddedWalletOptions, splitPxeOptions } from '../embedded_wallet.js';
|
|
11
|
-
import { WalletDB } from '../wallet_db.js';
|
|
14
|
+
import { WALLET_DATA_SCHEMA_VERSION, WalletDB } from '../wallet_db.js';
|
|
15
|
+
|
|
16
|
+
const DEFAULT_WALLET_DATA_DIRECTORY = 'aztec-wallet-data';
|
|
12
17
|
|
|
13
18
|
export class NodeEmbeddedWallet extends EmbeddedWallet {
|
|
14
19
|
static async create<T extends NodeEmbeddedWallet = NodeEmbeddedWallet>(
|
|
@@ -25,7 +30,6 @@ export class NodeEmbeddedWallet extends EmbeddedWallet {
|
|
|
25
30
|
const rootLogger = options.logger ?? createLogger('embedded-wallet');
|
|
26
31
|
|
|
27
32
|
const aztecNode = typeof nodeOrUrl === 'string' ? createAztecNodeClient(nodeOrUrl) : nodeOrUrl;
|
|
28
|
-
const l1Contracts = await aztecNode.getL1ContractAddresses();
|
|
29
33
|
|
|
30
34
|
// Support both the new unified `pxe` option and the deprecated `pxeConfig`/`pxeOptions`.
|
|
31
35
|
const { config: pxeConfigFromPxe, creation: pxeCreationFromPxe } = splitPxeOptions(options.pxe);
|
|
@@ -33,8 +37,9 @@ export class NodeEmbeddedWallet extends EmbeddedWallet {
|
|
|
33
37
|
const mergedCreationOverrides: PXECreationOptions = { ...options.pxeOptions, ...pxeCreationFromPxe };
|
|
34
38
|
|
|
35
39
|
const pxeConfig: PXEConfig = Object.assign(getPXEConfig(), {
|
|
36
|
-
proverEnabled: mergedConfigOverrides.proverEnabled
|
|
37
|
-
dataDirectory:
|
|
40
|
+
proverEnabled: mergedConfigOverrides.proverEnabled,
|
|
41
|
+
dataDirectory: DEFAULT_WALLET_DATA_DIRECTORY,
|
|
42
|
+
autoSync: false,
|
|
38
43
|
...mergedConfigOverrides,
|
|
39
44
|
});
|
|
40
45
|
|
|
@@ -44,6 +49,13 @@ export class NodeEmbeddedWallet extends EmbeddedWallet {
|
|
|
44
49
|
|
|
45
50
|
const pxeOptions: PXECreationOptions = {
|
|
46
51
|
...mergedCreationOverrides,
|
|
52
|
+
preloadedContractsProvider: mergedCreationOverrides.preloadedContractsProvider ?? {
|
|
53
|
+
getPreloadedContracts: async () => [
|
|
54
|
+
await getStandardMultiCallEntrypoint(),
|
|
55
|
+
await getStandardAuthRegistry(),
|
|
56
|
+
await getStandardHandshakeRegistry(),
|
|
57
|
+
],
|
|
58
|
+
},
|
|
47
59
|
loggers: {
|
|
48
60
|
store: rootLogger.createChild('pxe:data'),
|
|
49
61
|
pxe: rootLogger.createChild('pxe:service'),
|
|
@@ -54,27 +66,31 @@ export class NodeEmbeddedWallet extends EmbeddedWallet {
|
|
|
54
66
|
|
|
55
67
|
const pxe = await createPXE(aztecNode, pxeConfig, pxeOptions);
|
|
56
68
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
: await createStore(
|
|
69
|
+
let walletDBStore = options.walletDb?.store;
|
|
70
|
+
if (!walletDBStore) {
|
|
71
|
+
const bindings = rootLogger.createChild('wallet:data').getBindings();
|
|
72
|
+
if (options.ephemeral) {
|
|
73
|
+
walletDBStore = await openTmpStore('wallet_data', true, undefined, undefined, bindings);
|
|
74
|
+
} else {
|
|
75
|
+
const { l1ChainId, l1ContractAddresses } = await aztecNode.getNodeInfo();
|
|
76
|
+
walletDBStore = await openStore(
|
|
66
77
|
'wallet_data',
|
|
67
|
-
|
|
78
|
+
WALLET_DATA_SCHEMA_VERSION,
|
|
68
79
|
{
|
|
69
|
-
dataDirectory:
|
|
80
|
+
dataDirectory: pxeConfig.dataDirectory ?? DEFAULT_WALLET_DATA_DIRECTORY,
|
|
70
81
|
dataStoreMapSizeKb: pxeConfig.dataStoreMapSizeKb,
|
|
71
|
-
|
|
82
|
+
l1ChainId,
|
|
83
|
+
rollupAddress: l1ContractAddresses.rollupAddress,
|
|
72
84
|
},
|
|
73
|
-
|
|
85
|
+
bindings,
|
|
74
86
|
);
|
|
75
|
-
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const walletDB = new WalletDB(walletDBStore, rootLogger.createChild('wallet:db').info);
|
|
76
90
|
|
|
77
|
-
|
|
91
|
+
const wallet = new this(pxe, aztecNode, walletDB, new BundleAccountContractsProvider(), rootLogger) as T;
|
|
92
|
+
await wallet.initStubClasses();
|
|
93
|
+
return wallet;
|
|
78
94
|
}
|
|
79
95
|
}
|
|
80
96
|
|