@metamask-previews/eth-snap-keyring 20.0.0-018fb62 → 20.0.0-d23a1b9
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/CHANGELOG.md +2 -2
- package/dist/SnapKeyring.cjs +96 -141
- package/dist/SnapKeyring.cjs.map +1 -1
- package/dist/SnapKeyring.d.cts +5 -9
- package/dist/SnapKeyring.d.cts.map +1 -1
- package/dist/SnapKeyring.d.mts +5 -9
- package/dist/SnapKeyring.d.mts.map +1 -1
- package/dist/SnapKeyring.mjs +90 -135
- package/dist/SnapKeyring.mjs.map +1 -1
- package/dist/SnapKeyringV2.cjs +205 -8
- package/dist/SnapKeyringV2.cjs.map +1 -1
- package/dist/SnapKeyringV2.d.cts +144 -6
- package/dist/SnapKeyringV2.d.cts.map +1 -1
- package/dist/SnapKeyringV2.d.mts +144 -6
- package/dist/SnapKeyringV2.d.mts.map +1 -1
- package/dist/SnapKeyringV2.mjs +205 -8
- package/dist/SnapKeyringV2.mjs.map +1 -1
- package/dist/util.cjs +16 -0
- package/dist/util.cjs.map +1 -1
- package/dist/util.d.cts +11 -0
- package/dist/util.d.cts.map +1 -1
- package/dist/util.d.mts +11 -0
- package/dist/util.d.mts.map +1 -1
- package/dist/util.mjs +15 -0
- package/dist/util.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,12 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
### Added
|
|
11
11
|
|
|
12
|
-
- Add `SnapKeyringV2` class, a per-snap keyring wrapper with
|
|
12
|
+
- Add `SnapKeyringV2` class, a per-snap keyring wrapper that implements `KeyringV2` with `createAccount`, `createAccounts`, `deleteAccount`, `submitRequest`, `getAccount`, and `getAccounts` ([#501](https://github.com/MetaMask/accounts/pull/501))
|
|
13
|
+
- Add `@metamask/keyring-sdk` `^1.1.0` as a new dependency ([#501](https://github.com/MetaMask/accounts/pull/501))
|
|
13
14
|
|
|
14
15
|
### Changed
|
|
15
16
|
|
|
16
17
|
- Refactor `SnapKeyring` to store accounts in per-snap `SnapKeyringV2` wrappers instead of a single flat map ([#501](https://github.com/MetaMask/accounts/pull/501))
|
|
17
|
-
- Bump `@metamask/keyring-sdk` from none to `^1.1.0`
|
|
18
18
|
- Bump `@metamask/messenger` from `^0.3.0` to `^1.1.1` ([#489](https://github.com/MetaMask/accounts/pull/489), [#500](https://github.com/MetaMask/accounts/pull/500))
|
|
19
19
|
- Bump `@metamask/snaps-controllers` from `^19.0.0` to `^19.0.1` ([#500](https://github.com/MetaMask/accounts/pull/500))
|
|
20
20
|
- Bump `@metamask/snaps-utils` from `^12.1.2` to `^12.1.3` ([#500](https://github.com/MetaMask/accounts/pull/500))
|
package/dist/SnapKeyring.cjs
CHANGED
|
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _SnapKeyring_instances, _SnapKeyring_messenger, _SnapKeyring_snapClient, _SnapKeyring_snapKeyrings, _SnapKeyring_accountIndex, _SnapKeyring_selectedAccounts, _SnapKeyring_requests, _SnapKeyring_options, _SnapKeyring_callbacks, _SnapKeyring_isAnyAccountTypeAllowed, _SnapKeyring_lock, _SnapKeyring_withLock, _SnapKeyring_getOrCreateKeyringV2, _SnapKeyring_isMinimumPlatformVersion, _SnapKeyring_assertAccountCanBeUsed, _SnapKeyring_getExistingAccount, _SnapKeyring_getInternalOptions, _SnapKeyring_handleAccountCreated, _SnapKeyring_handleAccountUpdated, _SnapKeyring_handleAccountDeleted, _SnapKeyring_handleGetSelectedAccounts, _SnapKeyring_handleRequestApproved, _SnapKeyring_handleRequestRejected, _SnapKeyring_rePublishAccountEvent, _SnapKeyring_handleAccountBalancesUpdated, _SnapKeyring_handleAccountAssetListUpdated, _SnapKeyring_handleAccountTransactionsUpdated, _SnapKeyring_getAccount, _SnapKeyring_submitRequest, _SnapKeyring_submitSnapRequest, _SnapKeyring_hasMethod, _SnapKeyring_createRequestPromise, _SnapKeyring_clearRequestPromise, _SnapKeyring_handleSyncResponse, _SnapKeyring_handleAsyncResponse, _SnapKeyring_sanitizeRedirectUrl, _SnapKeyring_validateRedirectUrl, _SnapKeyring_deleteAccount, _SnapKeyring_resolveAddress, _SnapKeyring_updateSelectedAccountsMap, _SnapKeyring_getSnap, _SnapKeyring_getSnapMetadata, _SnapKeyring_getSnapAllowedOrigins, _SnapKeyring_transformToInternalAccount;
|
|
13
|
+
var _SnapKeyring_instances, _SnapKeyring_messenger, _SnapKeyring_snapClient, _SnapKeyring_snapKeyrings, _SnapKeyring_accountIndex, _SnapKeyring_selectedAccounts, _SnapKeyring_requests, _SnapKeyring_options, _SnapKeyring_callbacks, _SnapKeyring_isAnyAccountTypeAllowed, _SnapKeyring_lock, _SnapKeyring_withLock, _SnapKeyring_getOrCreateKeyringV2, _SnapKeyring_isMinimumPlatformVersion, _SnapKeyring_assertAccountCanBeUsed, _SnapKeyring_getExistingAccount, _SnapKeyring_getInternalOptions, _SnapKeyring_handleAccountCreated, _SnapKeyring_handleAccountUpdated, _SnapKeyring_handleAccountDeleted, _SnapKeyring_handleGetSelectedAccounts, _SnapKeyring_handleRequestApproved, _SnapKeyring_handleRequestRejected, _SnapKeyring_rePublishAccountEvent, _SnapKeyring_handleAccountBalancesUpdated, _SnapKeyring_handleAccountAssetListUpdated, _SnapKeyring_handleAccountTransactionsUpdated, _SnapKeyring_getAccount, _SnapKeyring_createSnapAccount, _SnapKeyring_submitRequest, _SnapKeyring_submitSnapRequest, _SnapKeyring_hasMethod, _SnapKeyring_createRequestPromise, _SnapKeyring_clearRequestPromise, _SnapKeyring_handleSyncResponse, _SnapKeyring_handleAsyncResponse, _SnapKeyring_sanitizeRedirectUrl, _SnapKeyring_validateRedirectUrl, _SnapKeyring_deleteAccount, _SnapKeyring_resolveAddress, _SnapKeyring_updateSelectedAccountsMap, _SnapKeyring_getSnap, _SnapKeyring_getSnapMetadata, _SnapKeyring_getSnapAllowedOrigins, _SnapKeyring_transformToInternalAccount;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.SnapKeyring = exports.SNAP_KEYRING_TYPE = void 0;
|
|
16
16
|
const tx_1 = require("@ethereumjs/tx");
|
|
@@ -36,20 +36,6 @@ const SnapKeyringV2_1 = require("./SnapKeyringV2.cjs");
|
|
|
36
36
|
const types_1 = require("./types.cjs");
|
|
37
37
|
const util_1 = require("./util.cjs");
|
|
38
38
|
exports.SNAP_KEYRING_TYPE = 'Snap Keyring';
|
|
39
|
-
/**
|
|
40
|
-
* Normalize account's address.
|
|
41
|
-
*
|
|
42
|
-
* @param account - The account.
|
|
43
|
-
* @returns The normalized account address.
|
|
44
|
-
*/
|
|
45
|
-
function normalizeAccountAddress(account) {
|
|
46
|
-
// FIXME: Is it required to lowercase the address here? For now we'll keep this behavior
|
|
47
|
-
// only for Ethereum addresses and use the original address for other non-EVM accounts.
|
|
48
|
-
// For example, Solana addresses are case-sensitives.
|
|
49
|
-
return (0, keyring_api_1.isEvmAccountType)(account.type)
|
|
50
|
-
? account.address.toLowerCase()
|
|
51
|
-
: account.address;
|
|
52
|
-
}
|
|
53
39
|
/**
|
|
54
40
|
* Keyring bridge implementation to support Snaps.
|
|
55
41
|
*/
|
|
@@ -218,7 +204,7 @@ class SnapKeyring {
|
|
|
218
204
|
// Rebuild per-snap wrappers. Migrations run inside wrapper.deserialize().
|
|
219
205
|
for (const [snapId, accounts] of bySnap) {
|
|
220
206
|
const wrapper = __classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_getOrCreateKeyringV2).call(this, snapId);
|
|
221
|
-
wrapper.deserialize({ snapId, accounts });
|
|
207
|
+
await wrapper.deserialize({ snapId, accounts });
|
|
222
208
|
// onRegister callbacks fired above have repopulated #accountIndex.
|
|
223
209
|
}
|
|
224
210
|
}
|
|
@@ -231,7 +217,7 @@ class SnapKeyring {
|
|
|
231
217
|
const addresses = [];
|
|
232
218
|
for (const wrapper of __classPrivateFieldGet(this, _SnapKeyring_snapKeyrings, "f").values()) {
|
|
233
219
|
for (const account of wrapper.accounts()) {
|
|
234
|
-
addresses.push(normalizeAccountAddress(account));
|
|
220
|
+
addresses.push((0, util_1.normalizeAccountAddress)(account));
|
|
235
221
|
}
|
|
236
222
|
}
|
|
237
223
|
return (0, util_1.unique)(addresses);
|
|
@@ -243,10 +229,12 @@ class SnapKeyring {
|
|
|
243
229
|
* @returns The addresses of the accounts associated with the given Snap.
|
|
244
230
|
*/
|
|
245
231
|
async getAccountsBySnapId(snapId) {
|
|
246
|
-
return (0, util_1.unique)((__classPrivateFieldGet(this, _SnapKeyring_snapKeyrings, "f").get(snapId)?.accounts() ?? []).map(normalizeAccountAddress));
|
|
232
|
+
return (0, util_1.unique)((__classPrivateFieldGet(this, _SnapKeyring_snapKeyrings, "f").get(snapId)?.accounts() ?? []).map(util_1.normalizeAccountAddress));
|
|
247
233
|
}
|
|
248
234
|
/**
|
|
249
|
-
* Create an account.
|
|
235
|
+
* Create an account (v1 event-driven flow).
|
|
236
|
+
*
|
|
237
|
+
* Delegates to the per-snap `SnapKeyringV2` wrapper.
|
|
250
238
|
*
|
|
251
239
|
* @param snapId - Snap ID to create the account for.
|
|
252
240
|
* @param options - Account creation options. Differs between keyrings.
|
|
@@ -254,120 +242,20 @@ class SnapKeyring {
|
|
|
254
242
|
* @returns The account object.
|
|
255
243
|
*/
|
|
256
244
|
async createAccount(snapId, options, internalOptions) {
|
|
257
|
-
|
|
258
|
-
messenger: __classPrivateFieldGet(this, _SnapKeyring_messenger, "f"),
|
|
259
|
-
snapId,
|
|
260
|
-
});
|
|
261
|
-
// The 'metamask' field is reserved, so we have to prevent use of it on
|
|
262
|
-
// the "normal options".
|
|
263
|
-
const reserved = 'metamask';
|
|
264
|
-
if ((0, utils_1.hasProperty)(options, reserved)) {
|
|
265
|
-
throw new Error(`The '${reserved}' property is reserved for internal use`);
|
|
266
|
-
}
|
|
267
|
-
// Those internal options are optional. If not set, we avoid registering anything
|
|
268
|
-
// to internal map (to avoid holding resources for nothing). In this case, it's
|
|
269
|
-
// just a normal `keyring_createAccount`.
|
|
270
|
-
if (!internalOptions) {
|
|
271
|
-
return await client.createAccount(options);
|
|
272
|
-
}
|
|
273
|
-
// A unique ID to identify this execution flow which allows to associate the
|
|
274
|
-
// internal options and the current `keyring_createAccount` flow for that Snap.
|
|
275
|
-
const correlationId = (0, uuid_1.v4)();
|
|
276
|
-
// Register those internal options to use them during the `keyring_createAccount`
|
|
277
|
-
// flow.
|
|
278
|
-
__classPrivateFieldGet(this, _SnapKeyring_options, "f").set(correlationId, {
|
|
279
|
-
snapId,
|
|
280
|
-
options: internalOptions,
|
|
281
|
-
});
|
|
282
|
-
return await client.createAccount({
|
|
283
|
-
...options,
|
|
284
|
-
// Create internal options context.
|
|
285
|
-
// NOTE: Those options HAVE TO be re-emitted during the `notify:accountCreated` event.
|
|
286
|
-
...{
|
|
287
|
-
metamask: {
|
|
288
|
-
correlationId,
|
|
289
|
-
},
|
|
290
|
-
},
|
|
291
|
-
});
|
|
245
|
+
return __classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_getOrCreateKeyringV2).call(this, snapId).createAccount(options, internalOptions);
|
|
292
246
|
}
|
|
293
247
|
/**
|
|
294
248
|
* Creates one or more new accounts according to the provided options.
|
|
295
249
|
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
298
|
-
* options should always return the same accounts, even if the accounts
|
|
299
|
-
* already exist in the keyring.
|
|
300
|
-
*
|
|
301
|
-
* NOTE: If some accounts are not allowed (non-unique address, unsupported
|
|
302
|
-
* generic account), this method will skip their creation and ask the Snap
|
|
303
|
-
* to remove them from its state.
|
|
250
|
+
* Delegates to the per-snap `SnapKeyringV2` wrapper which handles
|
|
251
|
+
* idempotency, validation, batch tracking, state persistence, and rollback.
|
|
304
252
|
*
|
|
305
253
|
* @param snapId - Snap ID to create the account(s) for.
|
|
306
254
|
* @param options - Options describing how to create the account(s).
|
|
307
255
|
* @returns An array of the created account objects.
|
|
308
256
|
*/
|
|
309
257
|
async createAccounts(snapId, options) {
|
|
310
|
-
return __classPrivateFieldGet(this, _SnapKeyring_instances, "m",
|
|
311
|
-
const client = new keyring_internal_snap_client_1.KeyringInternalSnapClient({
|
|
312
|
-
messenger: __classPrivateFieldGet(this, _SnapKeyring_messenger, "f"),
|
|
313
|
-
snapId,
|
|
314
|
-
});
|
|
315
|
-
// Keep track of address/account ID part of this batch, to avoid having duplicates.
|
|
316
|
-
const accountAddresses = new Set();
|
|
317
|
-
const accountIds = new Set();
|
|
318
|
-
const accounts = [];
|
|
319
|
-
const newAccounts = [];
|
|
320
|
-
const snapAccounts = await client.createAccounts(options);
|
|
321
|
-
try {
|
|
322
|
-
for (const snapAccount of snapAccounts) {
|
|
323
|
-
let account = (0, account_1.transformAccount)(snapAccount);
|
|
324
|
-
const address = normalizeAccountAddress(account);
|
|
325
|
-
// Check for idempotency.
|
|
326
|
-
const existingAccount = __classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_getExistingAccount).call(this, snapId, account);
|
|
327
|
-
if (existingAccount) {
|
|
328
|
-
// NOTE: We re-use the account from the internal state to avoid having the Snap
|
|
329
|
-
// mutating the account object without updating the map.
|
|
330
|
-
account = existingAccount;
|
|
331
|
-
}
|
|
332
|
-
else {
|
|
333
|
-
await __classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_assertAccountCanBeUsed).call(this, account);
|
|
334
|
-
// Also check for transient accounts that are not yet part of the keyring
|
|
335
|
-
// state.
|
|
336
|
-
if (accountAddresses.has(address) || accountIds.has(account.id)) {
|
|
337
|
-
throw new Error(`Account '${account.id}' is already part of this batch (same address or account ID)`);
|
|
338
|
-
}
|
|
339
|
-
accountAddresses.add(address);
|
|
340
|
-
accountIds.add(account.id);
|
|
341
|
-
// NOTE: This method does not rely on the `AccountCreated` event to add
|
|
342
|
-
// accounts to the keyring, so we have to add them to the state manually.
|
|
343
|
-
newAccounts.push(account);
|
|
344
|
-
}
|
|
345
|
-
// New AND existing accounts are returned to the caller no matter what.
|
|
346
|
-
accounts.push(account);
|
|
347
|
-
}
|
|
348
|
-
// We update the keyring state only if needed.
|
|
349
|
-
if (newAccounts.length > 0) {
|
|
350
|
-
const wrapper = __classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_getOrCreateKeyringV2).call(this, snapId);
|
|
351
|
-
for (const account of newAccounts) {
|
|
352
|
-
wrapper.setAccount(account);
|
|
353
|
-
}
|
|
354
|
-
// NOTE: We assume this will never fail, thus, we don't need to rollback the
|
|
355
|
-
// keyring state if anything goes wrong here.
|
|
356
|
-
await __classPrivateFieldGet(this, _SnapKeyring_callbacks, "f").saveState();
|
|
357
|
-
}
|
|
358
|
-
return accounts;
|
|
359
|
-
}
|
|
360
|
-
catch (error) {
|
|
361
|
-
// Rollback Snap state.
|
|
362
|
-
for (const account of snapAccounts) {
|
|
363
|
-
// Make sure to only delete accounts that were not part of the keyring state.
|
|
364
|
-
if (!__classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_getExistingAccount).call(this, snapId, account)) {
|
|
365
|
-
await __classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_deleteAccount).call(this, snapId, account);
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
throw error;
|
|
369
|
-
}
|
|
370
|
-
});
|
|
258
|
+
return __classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_getOrCreateKeyringV2).call(this, snapId).createAccounts(options);
|
|
371
259
|
}
|
|
372
260
|
/**
|
|
373
261
|
* Checks if a Snap ID is known from the keyring.
|
|
@@ -670,6 +558,10 @@ async function _SnapKeyring_withLock(callback) {
|
|
|
670
558
|
}, _SnapKeyring_getOrCreateKeyringV2 = function _SnapKeyring_getOrCreateKeyringV2(snapId) {
|
|
671
559
|
let keyring = __classPrivateFieldGet(this, _SnapKeyring_snapKeyrings, "f").get(snapId);
|
|
672
560
|
if (!keyring) {
|
|
561
|
+
const client = new keyring_internal_snap_client_1.KeyringInternalSnapClient({
|
|
562
|
+
messenger: __classPrivateFieldGet(this, _SnapKeyring_messenger, "f"),
|
|
563
|
+
snapId,
|
|
564
|
+
});
|
|
673
565
|
keyring = new SnapKeyringV2_1.SnapKeyringV2({
|
|
674
566
|
snapId,
|
|
675
567
|
onRegister: (id) => {
|
|
@@ -678,6 +570,30 @@ async function _SnapKeyring_withLock(callback) {
|
|
|
678
570
|
onUnregister: (id) => {
|
|
679
571
|
__classPrivateFieldGet(this, _SnapKeyring_accountIndex, "f").delete(id);
|
|
680
572
|
},
|
|
573
|
+
callbacks: {
|
|
574
|
+
createSnapAccount: async (options, internalOptions) => __classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_createSnapAccount).call(this, snapId, client, options, internalOptions),
|
|
575
|
+
createSnapAccounts: async (options) => client.createAccounts(options),
|
|
576
|
+
deleteSnapAccount: async (id) => client.deleteAccount(id),
|
|
577
|
+
// This callback is only invoked via SnapKeyringV2.submitRequest,
|
|
578
|
+
// which is not called through SnapKeyring's public API today.
|
|
579
|
+
// SnapKeyring.submitRequest routes through #submitSnapRequest directly.
|
|
580
|
+
// Coverage is excluded until consumers interact with SnapKeyringV2 directly.
|
|
581
|
+
submitSnapRequest: /* istanbul ignore next */ async (request) => __classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_submitSnapRequest).call(this, {
|
|
582
|
+
origin: request.origin,
|
|
583
|
+
snapId,
|
|
584
|
+
account: __classPrivateFieldGet(this, _SnapKeyring_snapKeyrings, "f")
|
|
585
|
+
.get(snapId)
|
|
586
|
+
?.lookupAccount(request.account) ??
|
|
587
|
+
(0, util_1.throwError)(`Account '${request.account}' not found for snap '${snapId}'`),
|
|
588
|
+
method: request.request.method,
|
|
589
|
+
params: request.request.params,
|
|
590
|
+
scope: request.scope,
|
|
591
|
+
noPending: false,
|
|
592
|
+
}),
|
|
593
|
+
assertAccountCanBeUsed: async (account) => __classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_assertAccountCanBeUsed).call(this, account),
|
|
594
|
+
saveState: async () => __classPrivateFieldGet(this, _SnapKeyring_callbacks, "f").saveState(),
|
|
595
|
+
withLock: async (callback) => __classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_withLock).call(this, callback),
|
|
596
|
+
},
|
|
681
597
|
});
|
|
682
598
|
__classPrivateFieldGet(this, _SnapKeyring_snapKeyrings, "f").set(snapId, keyring);
|
|
683
599
|
}
|
|
@@ -693,7 +609,7 @@ async function _SnapKeyring_withLock(callback) {
|
|
|
693
609
|
* @throws If the account cannot be used.
|
|
694
610
|
*/
|
|
695
611
|
async function _SnapKeyring_assertAccountCanBeUsed(account) {
|
|
696
|
-
const address = normalizeAccountAddress(account);
|
|
612
|
+
const address = (0, util_1.normalizeAccountAddress)(account);
|
|
697
613
|
// The `AnyAccountType.Account` generic account type is allowed only during
|
|
698
614
|
// development, so we check whether it's allowed before continuing.
|
|
699
615
|
if (!__classPrivateFieldGet(this, _SnapKeyring_isAnyAccountTypeAllowed, "f") &&
|
|
@@ -713,7 +629,7 @@ async function _SnapKeyring_assertAccountCanBeUsed(account) {
|
|
|
713
629
|
throw new Error(`Account address '${address}' already exists`);
|
|
714
630
|
}
|
|
715
631
|
}, _SnapKeyring_getExistingAccount = function _SnapKeyring_getExistingAccount(snapId, account) {
|
|
716
|
-
const address = normalizeAccountAddress(account);
|
|
632
|
+
const address = (0, util_1.normalizeAccountAddress)(account);
|
|
717
633
|
// Account creation is idempotent, so we need to check whether the account
|
|
718
634
|
// already exists and that the right Snap is trying to "create" it again.
|
|
719
635
|
// NOTE: We are not checking account object equality here. If a Snap
|
|
@@ -721,7 +637,7 @@ async function _SnapKeyring_assertAccountCanBeUsed(account) {
|
|
|
721
637
|
const wrapper = __classPrivateFieldGet(this, _SnapKeyring_snapKeyrings, "f").get(snapId);
|
|
722
638
|
const existing = wrapper?.lookupAccount(account.id);
|
|
723
639
|
if (existing !== undefined &&
|
|
724
|
-
normalizeAccountAddress(existing) === address) {
|
|
640
|
+
(0, util_1.normalizeAccountAddress)(existing) === address) {
|
|
725
641
|
return existing;
|
|
726
642
|
}
|
|
727
643
|
return undefined; // Not a known account.
|
|
@@ -759,7 +675,7 @@ async function _SnapKeyring_handleAccountCreated(snapId, message) {
|
|
|
759
675
|
// first create the account data and then fire the "AccountCreated" event.
|
|
760
676
|
// Potentially migrate the account.
|
|
761
677
|
const account = (0, account_1.transformAccount)(newAccountFromEvent);
|
|
762
|
-
const address = normalizeAccountAddress(account);
|
|
678
|
+
const address = (0, util_1.normalizeAccountAddress)(account);
|
|
763
679
|
if (__classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_getExistingAccount).call(this, snapId, account)) {
|
|
764
680
|
// If the account already exists, we skip it.
|
|
765
681
|
return null;
|
|
@@ -879,7 +795,7 @@ async function _SnapKeyring_handleAccountDeleted(snapId, message) {
|
|
|
879
795
|
if (account === undefined) {
|
|
880
796
|
return null;
|
|
881
797
|
}
|
|
882
|
-
await __classPrivateFieldGet(this, _SnapKeyring_callbacks, "f").removeAccount(normalizeAccountAddress(account), snapId, async (accepted) => {
|
|
798
|
+
await __classPrivateFieldGet(this, _SnapKeyring_callbacks, "f").removeAccount((0, util_1.normalizeAccountAddress)(account), snapId, async (accepted) => {
|
|
883
799
|
if (accepted) {
|
|
884
800
|
await __classPrivateFieldGet(this, _SnapKeyring_callbacks, "f").saveState();
|
|
885
801
|
}
|
|
@@ -1009,6 +925,53 @@ async function _SnapKeyring_handleAccountTransactionsUpdated(snapId, message) {
|
|
|
1009
925
|
throw new Error(`Unable to get account: unknown account ID: '${id}'`);
|
|
1010
926
|
}
|
|
1011
927
|
return { account, snapId };
|
|
928
|
+
}, _SnapKeyring_createSnapAccount =
|
|
929
|
+
/**
|
|
930
|
+
* Core logic for the v1 `createAccount` flow. Called via the injected
|
|
931
|
+
* callback in each `SnapKeyringV2` wrapper.
|
|
932
|
+
*
|
|
933
|
+
* Handles the reserved 'metamask' field, correlation IDs, and internal
|
|
934
|
+
* options registration. The account is ultimately added to the wrapper
|
|
935
|
+
* via the `AccountCreated` event handler, not the return value.
|
|
936
|
+
*
|
|
937
|
+
* @param snapId - Snap ID.
|
|
938
|
+
* @param client - Snap client for this snap.
|
|
939
|
+
* @param options - Account creation options.
|
|
940
|
+
* @param internalOptions - Internal Snap keyring options.
|
|
941
|
+
* @returns The account object returned by the snap.
|
|
942
|
+
*/
|
|
943
|
+
async function _SnapKeyring_createSnapAccount(snapId, client, options, internalOptions) {
|
|
944
|
+
// The 'metamask' field is reserved, so we have to prevent use of it on
|
|
945
|
+
// the "normal options".
|
|
946
|
+
const reserved = 'metamask';
|
|
947
|
+
if ((0, utils_1.hasProperty)(options, reserved)) {
|
|
948
|
+
throw new Error(`The '${reserved}' property is reserved for internal use`);
|
|
949
|
+
}
|
|
950
|
+
// Those internal options are optional. If not set, we avoid registering anything
|
|
951
|
+
// to internal map (to avoid holding resources for nothing). In this case, it's
|
|
952
|
+
// just a normal `keyring_createAccount`.
|
|
953
|
+
if (!internalOptions) {
|
|
954
|
+
return await client.createAccount(options);
|
|
955
|
+
}
|
|
956
|
+
// A unique ID to identify this execution flow which allows to associate the
|
|
957
|
+
// internal options and the current `keyring_createAccount` flow for that Snap.
|
|
958
|
+
const correlationId = (0, uuid_1.v4)();
|
|
959
|
+
// Register those internal options to use them during the `keyring_createAccount`
|
|
960
|
+
// flow.
|
|
961
|
+
__classPrivateFieldGet(this, _SnapKeyring_options, "f").set(correlationId, {
|
|
962
|
+
snapId,
|
|
963
|
+
options: internalOptions,
|
|
964
|
+
});
|
|
965
|
+
return await client.createAccount({
|
|
966
|
+
...options,
|
|
967
|
+
// Create internal options context.
|
|
968
|
+
// NOTE: Those options HAVE TO be re-emitted during the `notify:accountCreated` event.
|
|
969
|
+
...{
|
|
970
|
+
metamask: {
|
|
971
|
+
correlationId,
|
|
972
|
+
},
|
|
973
|
+
},
|
|
974
|
+
});
|
|
1012
975
|
}, _SnapKeyring_submitRequest =
|
|
1013
976
|
/**
|
|
1014
977
|
* Submit a request to a Snap from an account address.
|
|
@@ -1158,22 +1121,14 @@ async function _SnapKeyring_handleAsyncResponse(redirect, snapId) {
|
|
|
1158
1121
|
/**
|
|
1159
1122
|
* Removes an account.
|
|
1160
1123
|
*
|
|
1124
|
+
* Delegates to the per-snap `SnapKeyringV2` wrapper which handles
|
|
1125
|
+
* registry removal, index cleanup, and snap communication.
|
|
1126
|
+
*
|
|
1161
1127
|
* @param snapId - Snap ID.
|
|
1162
1128
|
* @param account - Account to delete.
|
|
1163
1129
|
*/
|
|
1164
1130
|
async function _SnapKeyring_deleteAccount(snapId, account) {
|
|
1165
|
-
|
|
1166
|
-
// fail to delete it. removeAccount fires onUnregister to clean #accountIndex.
|
|
1167
|
-
__classPrivateFieldGet(this, _SnapKeyring_snapKeyrings, "f").get(snapId)?.removeAccount(account.id);
|
|
1168
|
-
try {
|
|
1169
|
-
await __classPrivateFieldGet(this, _SnapKeyring_snapClient, "f").withSnapId(snapId).deleteAccount(account.id);
|
|
1170
|
-
}
|
|
1171
|
-
catch (error) {
|
|
1172
|
-
// If the Snap failed to delete the account, log the error and continue
|
|
1173
|
-
// with the account deletion, otherwise the account will be stuck in the
|
|
1174
|
-
// keyring.
|
|
1175
|
-
console.error(`Account '${account.address}' may not have been removed from snap '${snapId}':`, error);
|
|
1176
|
-
}
|
|
1131
|
+
await __classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_getOrCreateKeyringV2).call(this, snapId).deleteAccount(account.id);
|
|
1177
1132
|
}, _SnapKeyring_resolveAddress = function _SnapKeyring_resolveAddress(address) {
|
|
1178
1133
|
for (const wrapper of __classPrivateFieldGet(this, _SnapKeyring_snapKeyrings, "f").values()) {
|
|
1179
1134
|
const account = wrapper.lookupByAddress(address);
|
|
@@ -1217,7 +1172,7 @@ async function _SnapKeyring_deleteAccount(snapId, account) {
|
|
|
1217
1172
|
//
|
|
1218
1173
|
// NOTE: We convert the address only for EVM accounts, see
|
|
1219
1174
|
// `normalizeAccountAddress`.
|
|
1220
|
-
address: normalizeAccountAddress(account),
|
|
1175
|
+
address: (0, util_1.normalizeAccountAddress)(account),
|
|
1221
1176
|
metadata: {
|
|
1222
1177
|
name: '',
|
|
1223
1178
|
importTime: 0,
|