@metamask-previews/eth-snap-keyring 17.2.0-45ee2b8 → 17.2.0-50e2da5

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.
@@ -13,7 +13,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
13
13
  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");
14
14
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
15
15
  };
16
- var _SnapKeyring_instances, _SnapKeyring_messenger, _SnapKeyring_snapClient, _SnapKeyring_accounts, _SnapKeyring_requests, _SnapKeyring_options, _SnapKeyring_callbacks, _SnapKeyring_isAnyAccountTypeAllowed, _SnapKeyring_getKeyringVersion, _SnapKeyring_getInternalOptions, _SnapKeyring_handleAccountCreated, _SnapKeyring_handleAccountUpdated, _SnapKeyring_handleAccountDeleted, _SnapKeyring_handleRequestApproved, _SnapKeyring_handleRequestRejected, _SnapKeyring_rePublishAccountEvent, _SnapKeyring_handleAccountBalancesUpdated, _SnapKeyring_handleAccountAssetListUpdated, _SnapKeyring_handleAccountTransactionsUpdated, _SnapKeyring_getAccount, _SnapKeyring_submitRequest, _SnapKeyring_submitSnapRequestForVersion, _SnapKeyring_submitSnapRequest, _SnapKeyring_hasMethod, _SnapKeyring_createRequestPromise, _SnapKeyring_clearRequestPromise, _SnapKeyring_handleSyncResponse, _SnapKeyring_handleAsyncResponse, _SnapKeyring_sanitizeRedirectUrl, _SnapKeyring_validateRedirectUrl, _SnapKeyring_deleteAccount, _SnapKeyring_resolveAddress, _SnapKeyring_getSnap, _SnapKeyring_getSnapMetadata, _SnapKeyring_getSnapAllowedOrigins;
16
+ var _SnapKeyring_instances, _SnapKeyring_messenger, _SnapKeyring_snapClient, _SnapKeyring_accounts, _SnapKeyring_requests, _SnapKeyring_options, _SnapKeyring_callbacks, _SnapKeyring_isAnyAccountTypeAllowed, _SnapKeyring_getKeyringVersion, _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_submitSnapRequestForVersion, _SnapKeyring_submitSnapRequest, _SnapKeyring_hasMethod, _SnapKeyring_createRequestPromise, _SnapKeyring_clearRequestPromise, _SnapKeyring_handleSyncResponse, _SnapKeyring_handleAsyncResponse, _SnapKeyring_sanitizeRedirectUrl, _SnapKeyring_validateRedirectUrl, _SnapKeyring_deleteAccount, _SnapKeyring_resolveAddress, _SnapKeyring_getSnap, _SnapKeyring_getSnapMetadata, _SnapKeyring_getSnapAllowedOrigins;
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.SnapKeyring = exports.SNAP_KEYRING_TYPE = void 0;
19
19
  const tx_1 = require("@ethereumjs/tx");
@@ -144,6 +144,9 @@ class SnapKeyring {
144
144
  case `${keyring_api_1.KeyringEvent.AccountTransactionsUpdated}`: {
145
145
  return __classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_handleAccountTransactionsUpdated).call(this, snapId, message);
146
146
  }
147
+ case `${keyring_api_1.KeyringMethod.GetSelectedAccounts}`: {
148
+ return __classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_handleGetSelectedAccounts).call(this, snapId, message);
149
+ }
147
150
  default:
148
151
  throw new Error(`Method not supported: ${message.method}`);
149
152
  }
@@ -490,6 +493,16 @@ class SnapKeyring {
490
493
  const { account, snapId } = __classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_resolveAddress).call(this, address);
491
494
  await __classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_deleteAccount).call(this, snapId, account);
492
495
  }
496
+ /**
497
+ * Set the selected accounts.
498
+ *
499
+ * @param accounts - The accounts to set as selected.
500
+ */
501
+ async setSelectedAccounts(accounts) {
502
+ for (const [snapId, accountIds] of Object.entries(accounts)) {
503
+ await __classPrivateFieldGet(this, _SnapKeyring_snapClient, "f").withSnapId(snapId).setSelectedAccounts(accountIds);
504
+ }
505
+ }
493
506
  /**
494
507
  * Return an internal account object for a given address.
495
508
  *
@@ -710,6 +723,17 @@ async function _SnapKeyring_handleAccountDeleted(snapId, message) {
710
723
  }
711
724
  });
712
725
  return null;
726
+ }, _SnapKeyring_handleGetSelectedAccounts =
727
+ /**
728
+ * Handle an Get Selected Accounts method call from a Snap.
729
+ *
730
+ * @param snapId - Snap ID.
731
+ * @param message - Method call message.
732
+ * @returns The selected accounts.
733
+ */
734
+ async function _SnapKeyring_handleGetSelectedAccounts(snapId, message) {
735
+ (0, superstruct_1.assert)(message, keyring_api_1.GetSelectedAccountsRequestStruct);
736
+ return __classPrivateFieldGet(this, _SnapKeyring_callbacks, "f").getSelectedAccounts(snapId);
713
737
  }, _SnapKeyring_handleRequestApproved =
714
738
  /**
715
739
  * Handle an Request Approved event from a Snap.
@@ -1 +1 @@
1
- {"version":3,"file":"SnapKeyring.cjs","sourceRoot":"","sources":["../src/SnapKeyring.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-redundant-type-constituents */\n// This rule seems to be triggering a false positive. Possibly eslint is not\n// inferring the `EthMethod`, `BtcMethod`, and `InternalAccount` types correctly.\n\nimport type { TypedTransaction } from '@ethereumjs/tx';\nimport { TransactionFactory } from '@ethereumjs/tx';\nimport type { ExtractEventPayload } from '@metamask/base-controller';\nimport type { TypedDataV1, TypedMessage } from '@metamask/eth-sig-util';\nimport { SignTypedDataVersion } from '@metamask/eth-sig-util';\nimport type {\n KeyringAccount,\n KeyringExecutionContext,\n BtcMethod,\n EthBaseTransaction,\n EthBaseUserOperation,\n EthUserOperation,\n EthUserOperationPatch,\n ResolvedAccountAddress,\n CaipChainId,\n MetaMaskOptions,\n KeyringRequest,\n KeyringResponse,\n} from '@metamask/keyring-api';\nimport {\n EthBytesStruct,\n EthMethod,\n EthBaseUserOperationStruct,\n EthUserOperationPatchStruct,\n isEvmAccountType,\n KeyringEvent,\n AccountAssetListUpdatedEventStruct,\n AccountBalancesUpdatedEventStruct,\n AccountTransactionsUpdatedEventStruct,\n AnyAccountType,\n} from '@metamask/keyring-api';\nimport {\n KeyringVersion,\n toKeyringRequestV1,\n type InternalAccount,\n} from '@metamask/keyring-internal-api';\nimport { KeyringInternalSnapClient } from '@metamask/keyring-internal-snap-client';\nimport type { AccountId, JsonRpcRequest } from '@metamask/keyring-utils';\nimport { strictMask } from '@metamask/keyring-utils';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { type Snap } from '@metamask/snaps-utils';\nimport { assert, mask, object, string } from '@metamask/superstruct';\nimport type { Hex, Json, SemVerVersion } from '@metamask/utils';\nimport {\n bigIntToHex,\n hasProperty,\n KnownCaipNamespace,\n toCaipChainId,\n} from '@metamask/utils';\nimport { v4 as uuid } from 'uuid';\n\nimport { transformAccount } from './account';\nimport { DeferredPromise } from './DeferredPromise';\nimport {\n AccountCreatedEventStruct,\n AccountUpdatedEventStruct,\n AccountDeletedEventStruct,\n RequestApprovedEventStruct,\n RequestRejectedEventStruct,\n} from './events';\nimport { projectLogger as log } from './logger';\nimport { isAccountV1, migrateAccountV1 } from './migrations';\nimport {\n getInternalOptionsOf,\n type SnapKeyringInternalOptions,\n} from './options';\nimport { SnapIdMap } from './SnapIdMap';\nimport type {\n SnapKeyringEvents,\n SnapKeyringMessenger,\n} from './SnapKeyringMessenger';\nimport { SNAP_KEYRING_NAME } from './SnapKeyringMessenger';\nimport type { SnapMessage } from './types';\nimport { SnapMessageStruct } from './types';\nimport {\n equalsIgnoreCase,\n sanitizeUrl,\n throwError,\n toJson,\n unique,\n} from './util';\nimport { getKeyringVersionFromPlatform } from './versions';\n\nexport const SNAP_KEYRING_TYPE = 'Snap Keyring';\n\n// TODO: to be removed when this is added to the keyring-api\n\ntype AccountMethod = EthMethod | BtcMethod;\n\n/**\n * Snap keyring state.\n *\n * This state is persisted by the keyring controller and passed to the Snap\n * keyring when it's created.\n */\nexport type KeyringState = {\n accounts: Record<string, { account: KeyringAccount; snapId: SnapId }>;\n};\n\n/**\n * Snap keyring callbacks.\n *\n * These callbacks are used to interact with other components.\n */\nexport type SnapKeyringCallbacks = {\n saveState: () => Promise<void>;\n\n addressExists(address: string): Promise<boolean>;\n\n addAccount(\n address: string,\n snapId: SnapId,\n handleUserInput: (accepted: boolean) => Promise<void>,\n onceSaved: Promise<AccountId>,\n accountNameSuggestion?: string,\n internalOptions?: SnapKeyringInternalOptions,\n ): Promise<void>;\n\n removeAccount(\n address: string,\n snapId: SnapId,\n handleUserInput: (accepted: boolean) => Promise<void>,\n ): Promise<void>;\n\n redirectUser(snapId: SnapId, url: string, message: string): Promise<void>;\n};\n\n/**\n * Callback type to filter unknown account ID from a mapping account ID mapping.\n */\ntype FilterAccountIdFunction = <Entry>(\n accountMapping: Record<AccountId, Entry>,\n) => Record<AccountId, Entry>;\n\n/**\n * Normalize account's address.\n *\n * @param account - The account.\n * @returns The normalized account address.\n */\nfunction normalizeAccountAddress(account: KeyringAccount): string {\n // FIXME: Is it required to lowercase the address here? For now we'll keep this behavior\n // only for Ethereum addresses and use the original address for other non-EVM accounts.\n // For example, Solana addresses are case-sensitives.\n return isEvmAccountType(account.type)\n ? account.address.toLowerCase()\n : account.address;\n}\n\n/**\n * Keyring bridge implementation to support Snaps.\n */\nexport class SnapKeyring {\n static type: string = SNAP_KEYRING_TYPE;\n\n type: string;\n\n // Name and state are required for modular initialisation.\n name: typeof SNAP_KEYRING_NAME = SNAP_KEYRING_NAME;\n\n state = null;\n\n /**\n * Messenger to dispatch requests to the Snaps controller.\n */\n readonly #messenger: SnapKeyringMessenger;\n\n /**\n * Client used to call the Snap keyring.\n */\n readonly #snapClient: KeyringInternalSnapClient;\n\n /**\n * Mapping between account IDs and an object that contains the associated\n * account object and Snap ID.\n */\n #accounts: SnapIdMap<{\n account: KeyringAccount;\n snapId: SnapId;\n }>;\n\n /**\n * Mapping between request IDs and their deferred promises.\n */\n readonly #requests: SnapIdMap<{\n promise: DeferredPromise<any>;\n snapId: SnapId;\n }>;\n\n /**\n * Mapping between internal options, a correlation ID and a Snap ID.\n */\n readonly #options: SnapIdMap<{\n options: SnapKeyringInternalOptions;\n snapId: SnapId;\n // TODO: Add TTL to avoid having too many \"leaking\" internal options.\n }>;\n\n /**\n * Callbacks used to interact with other components.\n */\n readonly #callbacks: SnapKeyringCallbacks;\n\n /**\n * Whether to allow the creation and update of generic accounts.\n *\n * Account deletion is not affected by this flag and is always allowed.\n */\n readonly #isAnyAccountTypeAllowed: boolean;\n\n /**\n * Create a new Snap keyring.\n *\n * @param options - Constructor options.\n * @param options.messenger - Snap keyring messenger.\n * @param options.callbacks - Callbacks used to interact with other components.\n * @param options.isAnyAccountTypeAllowed - Whether to allow the `AnyAccountType` generic account type.\n * @returns A new Snap keyring.\n */\n constructor({\n messenger,\n callbacks,\n isAnyAccountTypeAllowed = false,\n }: {\n messenger: SnapKeyringMessenger;\n callbacks: SnapKeyringCallbacks;\n isAnyAccountTypeAllowed?: boolean;\n }) {\n this.type = SnapKeyring.type;\n this.#messenger = messenger;\n this.#snapClient = new KeyringInternalSnapClient({ messenger });\n this.#requests = new SnapIdMap();\n this.#accounts = new SnapIdMap();\n this.#options = new SnapIdMap();\n this.#callbacks = callbacks;\n this.#isAnyAccountTypeAllowed = isAnyAccountTypeAllowed;\n }\n\n /**\n * Gets keyring's version for a given Snap.\n *\n * @param snapId - The Snap ID.\n * @returns The Snap's keyring version.\n */\n #getKeyringVersion(snapId: SnapId): KeyringVersion {\n return getKeyringVersionFromPlatform((version: SemVerVersion) => {\n return this.#messenger.call(\n 'SnapController:isMinimumPlatformVersion',\n snapId,\n version,\n );\n });\n }\n\n /**\n * Get internal options given a correlation ID.\n *\n * NOTE: The associated options will be deleted automatically.\n *\n * @param snapId - Snap ID\n * @param correlationId - Correlation ID associated with the internal options.\n * @returns Internal options if found, `undefined` otherwise.\n */\n #getInternalOptions(\n snapId: SnapId,\n correlationId: string | undefined,\n ): SnapKeyringInternalOptions | undefined {\n if (correlationId) {\n // We still need to check if the correlation ID is valid and associated to\n // some internal options.\n //\n // NOTE: `found` will be `undefined` if a Snap tried to use a correlation ID that\n // belongs to another Snap ID. However, if a Snap starts 2 parallel flow (which\n // will results in 2 different correlation IDs), we won't be able to prevent\n // the Snap from swapping/mixing up those correlation IDs he owns.\n const found = this.#options.pop(snapId, correlationId);\n\n if (found) {\n return found.options;\n }\n\n console.warn(\n `SnapKeyring - Received unmapped correlation ID: \"${correlationId}\"`,\n );\n }\n\n return undefined;\n }\n\n /**\n * Handle an Account Created event from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountCreated(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountCreatedEventStruct);\n const {\n metamask, // Used for internal options.\n account: newAccountFromEvent,\n accountNameSuggestion,\n displayAccountNameSuggestion,\n displayConfirmation,\n } = message.params;\n\n // READ THIS CAREFULLY:\n // ------------------------------------------------------------------------\n // The account creation flow is now asynchronous. We expect the Snap to\n // first create the account data and then fire the \"AccountCreated\" event.\n\n // Potentially migrate the account.\n const account = transformAccount(newAccountFromEvent);\n\n // The `AnyAccountType.Account` generic account type is allowed only during\n // development, so we check whether it's allowed before continuing.\n if (\n !this.#isAnyAccountTypeAllowed &&\n account.type === AnyAccountType.Account\n ) {\n throw new Error(`Cannot create generic account '${account.id}'`);\n }\n\n // The UI still uses the account address to identify accounts, so we need\n // to block the creation of duplicate accounts for now to prevent accounts\n // from being overwritten.\n const address = normalizeAccountAddress(account);\n if (await this.#callbacks.addressExists(address)) {\n throw new Error(`Account address '${address}' already exists`);\n }\n\n // A Snap could try to create an account with a different address but with\n // an existing ID, so the above test only is not enough.\n if (this.#accounts.has(snapId, account.id)) {\n throw new Error(`Account '${account.id}' already exists`);\n }\n\n // A deferred promise that will be resolved once the Snap keyring has saved\n // its internal state.\n // This part of the flow is run asynchronously, so we have no other way of\n // letting the MetaMask client that this \"save\" has been run.\n // NOTE: Another way of fixing that could be to rely on events through the\n // messenger maybe?\n const onceSaved = new DeferredPromise<AccountId>();\n\n // Add the account to the keyring, but wait for the MetaMask client to\n // approve the account creation first.\n await this.#callbacks.addAccount(\n address,\n snapId,\n // This callback is passed to the MetaMask client, it will be called whenever\n // the end user will accept or not the account creation.\n async (accepted: boolean) => {\n if (accepted) {\n // We consider the account to be created on the Snap keyring only if\n // the user accepted it. Meaning that the Snap MIGHT HAVE created the\n // account on its own state, but the Snap keyring MIGHT NOT HAVE it yet.\n //\n // e.g The account creation dialog crashed on MetaMask, this callback\n // will never be called, but the Snap still has the account.\n this.#accounts.set(account.id, { account, snapId });\n\n // This is the \"true async part\". We do not `await` for this call, mainly\n // because this callback will persist the account on the client side\n // (through the `AccountsController`).\n //\n // Since this will happen after the Snap account creation and Snap\n // event, if anything goes wrong, we will delete the account by\n // calling `deleteAccount` on the Snap.\n // eslint-disable-next-line no-void\n void this.#callbacks\n .saveState()\n .then(() => {\n // This allows the MetaMask client to be \"notified\" when then\n // Snap keyring has truly persisted its state. From there, we should\n // be able to use the account (e.g. to display account creation\n // confirmation dialogs).\n onceSaved.resolve(account.id);\n })\n .catch(async (error) => {\n // FIXME: There's a potential race condition here, if the Snap did\n // not persist the account yet (this should mostly be for older Snaps).\n await this.#deleteAccount(snapId, account);\n\n // This allows the MetaMask client to be \"notified\" that something went\n // wrong with the Snap keyring. (e.g. useful to display account creation\n // error dialogs).\n onceSaved.reject(error);\n });\n }\n },\n onceSaved.promise,\n accountNameSuggestion,\n getInternalOptionsOf([\n // 1. We use the internal options from the Snap keyring.\n this.#getInternalOptions(snapId, metamask?.correlationId) ?? {},\n // 2. We use the ones coming from the Snap.\n {\n displayConfirmation,\n displayAccountNameSuggestion,\n },\n ]),\n );\n\n return null;\n }\n\n /**\n * Handle an Account Updated event from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountUpdated(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountUpdatedEventStruct);\n const { account: newAccountFromEvent } = message.params;\n const { account: oldAccount } =\n this.#accounts.get(snapId, newAccountFromEvent.id) ??\n throwError(`Account '${newAccountFromEvent.id}' not found`);\n\n // Potentially migrate the account.\n const newAccount = transformAccount(newAccountFromEvent);\n\n // The `AnyAccountType.Account` generic account type is allowed only during\n // development, so we check whether it's allowed before continuing.\n //\n // An account cannot be updated if the `isAnyAccountTypeAllowed` flag is\n // set to `false` and the new or old account is a generic account.\n const isGenericAccountInvolved =\n newAccount.type === AnyAccountType.Account ||\n oldAccount.type === AnyAccountType.Account;\n\n if (!this.#isAnyAccountTypeAllowed && isGenericAccountInvolved) {\n throw new Error(`Cannot update generic account '${newAccount.id}'`);\n }\n\n // The address of the account cannot be changed. In the future, we will\n // support changing the address of an account since it will be required to\n // support UTXO-based chains.\n if (!equalsIgnoreCase(oldAccount.address, newAccount.address)) {\n throw new Error(`Cannot change address of account '${newAccount.id}'`);\n }\n\n this.#accounts.set(newAccount.id, { account: newAccount, snapId });\n await this.#callbacks.saveState();\n return null;\n }\n\n /**\n * Handle an Account Deleted event from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountDeleted(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountDeletedEventStruct);\n const { id } = message.params;\n const entry = this.#accounts.get(snapId, id);\n\n // We can ignore the case where the account was already removed from the\n // keyring, making the deletion idempotent.\n //\n // This happens when the keyring calls the Snap to delete an account, and\n // the Snap calls the keyring back with an `AccountDeleted` event.\n if (entry === undefined) {\n return null;\n }\n\n // At this point we know that the account exists, so we can safely\n // destructure it.\n const { account } = entry;\n\n await this.#callbacks.removeAccount(\n normalizeAccountAddress(account),\n snapId,\n async (accepted) => {\n if (accepted) {\n await this.#callbacks.saveState();\n }\n },\n );\n return null;\n }\n\n /**\n * Handle an Request Approved event from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleRequestApproved(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, RequestApprovedEventStruct);\n const { id, result } = message.params;\n const { promise } =\n this.#requests.get(snapId, id) ?? throwError(`Request '${id}' not found`);\n\n this.#requests.delete(snapId, id);\n promise.resolve(result);\n return null;\n }\n\n /**\n * Handle an Request Rejected event from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleRequestRejected(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, RequestRejectedEventStruct);\n const { id } = message.params;\n const { promise } =\n this.#requests.get(snapId, id) ?? throwError(`Request '${id}' not found`);\n\n this.#requests.delete(snapId, id);\n promise.reject(new Error(`Request rejected by user or snap.`));\n return null;\n }\n\n /**\n * Re-publish an account event.\n *\n * @param snapId - Snap ID.\n * @param event - The event type. This is a unique identifier for this event.\n * @param filteredEventCallback - A callback that returns the event to re-publish. This callback takes a filtering\n * function as parameter that can be used to filter out account ID that do not belong to this Snap ID.\n * @template EventType - A Snap keyring event type.\n * @returns `null`.\n */\n async #rePublishAccountEvent<EventType extends SnapKeyringEvents['type']>(\n snapId: SnapId,\n event: EventType,\n filteredEventCallback: (\n filter: FilterAccountIdFunction,\n ) => ExtractEventPayload<SnapKeyringEvents, EventType>,\n ): Promise<null> {\n // This callback can be used to filter out the accounts that no longer exists on the Snap (fail-safe) or to\n // prevent other Snaps from updating accounts they do not own.\n const filter: FilterAccountIdFunction = <Entry>(\n accountMapping: Record<AccountId, Entry>,\n ): Record<AccountId, Entry> => {\n return Object.entries(accountMapping).reduce<Record<AccountId, Entry>>(\n (filtered, [accountId, entry]) => {\n if (this.#accounts.has(snapId, accountId)) {\n // If the Snap owns this account, we can use it.\n filtered[accountId] = entry;\n } else {\n // Otherwise, we just filter it out and log it (for debugging/tracking purposes).\n console.warn(\n `SnapKeyring - ${event} - Found an unknown account ID \"${accountId}\" for Snap ID \"${snapId}\". Skipping.`,\n );\n }\n\n return filtered;\n },\n {},\n );\n };\n\n this.#messenger.publish(event, ...filteredEventCallback(filter));\n return null;\n }\n\n /**\n * Handle a balances updated event from a Snap.\n *\n * @param snapId - ID of the Snap.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountBalancesUpdated(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountBalancesUpdatedEventStruct);\n\n const event = message.params;\n return this.#rePublishAccountEvent(\n snapId,\n 'SnapKeyring:accountBalancesUpdated',\n (filter) => {\n event.balances = filter(event.balances);\n return [event];\n },\n );\n }\n\n /**\n * Handle a asset list updated event from a Snap.\n *\n * @param snapId - ID of the Snap.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountAssetListUpdated(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountAssetListUpdatedEventStruct);\n\n const event = message.params;\n return this.#rePublishAccountEvent(\n snapId,\n 'SnapKeyring:accountAssetListUpdated',\n (filter) => {\n event.assets = filter(event.assets);\n return [event];\n },\n );\n }\n\n /**\n * Handle a transactions updated event from a Snap.\n *\n * @param snapId - ID of the Snap.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountTransactionsUpdated(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountTransactionsUpdatedEventStruct);\n\n const event = message.params;\n return this.#rePublishAccountEvent(\n snapId,\n 'SnapKeyring:accountTransactionsUpdated',\n (filter) => {\n event.transactions = filter(event.transactions);\n return [event];\n },\n );\n }\n\n /**\n * Handle a message from a Snap.\n *\n * @param snapId - ID of the Snap.\n * @param message - Message sent by the Snap.\n * @returns The execution result.\n */\n async handleKeyringSnapMessage(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<Json> {\n assert(message, SnapMessageStruct);\n switch (message.method) {\n case `${KeyringEvent.AccountCreated}`: {\n return this.#handleAccountCreated(snapId, message);\n }\n\n case `${KeyringEvent.AccountUpdated}`: {\n return this.#handleAccountUpdated(snapId, message);\n }\n\n case `${KeyringEvent.AccountDeleted}`: {\n return this.#handleAccountDeleted(snapId, message);\n }\n\n case `${KeyringEvent.RequestApproved}`: {\n return this.#handleRequestApproved(snapId, message);\n }\n\n case `${KeyringEvent.RequestRejected}`: {\n return this.#handleRequestRejected(snapId, message);\n }\n\n // Assets related events:\n case `${KeyringEvent.AccountBalancesUpdated}`: {\n return this.#handleAccountBalancesUpdated(snapId, message);\n }\n\n case `${KeyringEvent.AccountAssetListUpdated}`: {\n return this.#handleAccountAssetListUpdated(snapId, message);\n }\n\n case `${KeyringEvent.AccountTransactionsUpdated}`: {\n return this.#handleAccountTransactionsUpdated(snapId, message);\n }\n\n default:\n throw new Error(`Method not supported: ${message.method}`);\n }\n }\n\n /**\n * Serialize the keyring state.\n *\n * @returns Serialized keyring state.\n */\n async serialize(): Promise<KeyringState> {\n return {\n accounts: this.#accounts.toObject(),\n };\n }\n\n /**\n * Deserialize the keyring state into this keyring.\n *\n * @param state - Serialized keyring state.\n */\n async deserialize(state: KeyringState | undefined): Promise<void> {\n // If the state is undefined, it means that this is a new keyring, so we\n // don't need to do anything.\n if (state === undefined) {\n return;\n }\n\n // Running Snap keyring migrations. We might have some accounts that have a\n // different \"version\" than the one we expect.\n //\n // In this case, we \"transform\" then directly when deserializing to convert\n // them in the final account version.\n const accounts: KeyringState['accounts'] = {};\n for (const [snapId, entry] of Object.entries(state.accounts)) {\n // V1 accounts are missing the scopes.\n if (isAccountV1(entry.account)) {\n console.info(\n `SnapKeyring - Found a KeyringAccountV1, migrating to V2: ${entry.account.id}`,\n );\n accounts[snapId] = {\n ...entry,\n account: migrateAccountV1(entry.account),\n };\n } else {\n accounts[snapId] = entry;\n }\n }\n\n this.#accounts = SnapIdMap.fromObject(accounts);\n }\n\n /**\n * Get an account and its associated Snap ID from its ID.\n *\n * @param id - Account ID.\n * @throws An error if the account could not be found.\n * @returns The account associated with the given account ID in this keyring.\n */\n #getAccount(id: string): { account: KeyringAccount; snapId: SnapId } {\n const found = [...this.#accounts.values()].find(\n (entry) => entry.account.id === id,\n );\n\n if (!found) {\n throw new Error(`Unable to get account: unknown account ID: '${id}'`);\n }\n return found;\n }\n\n /**\n * Get the addresses of the accounts in this keyring.\n *\n * @returns The addresses of the accounts in this keyring.\n */\n async getAccounts(): Promise<string[]> {\n return unique(\n [...this.#accounts.values()].map(({ account }) =>\n normalizeAccountAddress(account),\n ),\n );\n }\n\n /**\n * Get the addresses of the accounts associated with a given Snap.\n *\n * @param snapId - Snap ID to filter by.\n * @returns The addresses of the accounts associated with the given Snap.\n */\n async getAccountsBySnapId(snapId: SnapId): Promise<string[]> {\n return unique(\n [...this.#accounts.values()]\n .filter(({ snapId: accountSnapId }) => accountSnapId === snapId)\n .map(({ account }) => normalizeAccountAddress(account)),\n );\n }\n\n /**\n * Create an account.\n *\n * @param snapId - Snap ID to create the account for.\n * @param options - Account creation options. Differs between keyrings.\n * @param internalOptions - Internal Snap keyring options.\n * @returns The account object.\n */\n async createAccount(\n snapId: SnapId,\n options: Record<string, Json>,\n internalOptions?: SnapKeyringInternalOptions,\n ): Promise<KeyringAccount> {\n const client = new KeyringInternalSnapClient({\n messenger: this.#messenger,\n snapId,\n });\n\n // The 'metamask' field is reserved, so we have to prevent use of it on\n // the \"normal options\".\n const reserved = 'metamask';\n if (hasProperty(options, reserved)) {\n throw new Error(\n `The '${reserved}' property is reserved for internal use`,\n );\n }\n\n // Those internal options are optional. If not set, we avoid registering anything\n // to internal map (to avoid holding resources for nothing). In this case, it's\n // just a normal `keyring_createAccount`.\n if (!internalOptions) {\n return await client.createAccount(options);\n }\n\n // A unique ID to identify this execution flow which allows to associate the\n // internal options and the current `keyring_createAccount` flow for that Snap.\n const correlationId = uuid();\n\n // Register those internal options to use them during the `keyring_createAccount`\n // flow.\n this.#options.set(correlationId, {\n snapId,\n options: internalOptions,\n });\n\n return await client.createAccount({\n ...options,\n // Create internal options context.\n // NOTE: Those options HAVE TO be re-emitted during the `notify:accountCreated` event.\n ...({\n metamask: {\n correlationId,\n },\n } as MetaMaskOptions),\n });\n }\n\n /**\n * Checks if a Snap ID is known from the keyring.\n *\n * @param snapId - Snap ID.\n * @returns `true` if the Snap ID is known, `false` otherwise.\n */\n hasSnapId(snapId: SnapId): boolean {\n return this.#accounts.hasSnapId(snapId);\n }\n\n /**\n * Resolve the Snap account's address associated from a signing request.\n *\n * @param snapId - Snap ID.\n * @param scope - CAIP-2 chain ID.\n * @param request - Signing request object.\n * @throws An error if the Snap ID is not known from the keyring.\n * @returns The resolved address if found, `null` otherwise.\n */\n async resolveAccountAddress(\n snapId: SnapId,\n scope: CaipChainId,\n request: JsonRpcRequest,\n ): Promise<ResolvedAccountAddress | null> {\n // We do check that the incoming Snap ID is known by the keyring.\n if (!this.hasSnapId(snapId)) {\n throw new Error(\n `Unable to resolve account address: unknown Snap ID: ${snapId}`,\n );\n }\n\n return await this.#snapClient\n .withSnapId(snapId)\n .resolveAccountAddress(scope, request);\n }\n\n /**\n * Submit a request to a Snap from an account ID.\n *\n * This request cannot be an asynchronous keyring request.\n *\n * @param opts - Request options.\n * @param opts.origin - Send origin.\n * @param opts.account - Account ID.\n * @param opts.method - Method to call.\n * @param opts.params - Method parameters.\n * @param opts.scope - Selected chain ID (CAIP-2).\n * @returns Promise that resolves to the result of the method call.\n */\n async submitRequest({\n origin,\n account: accountId,\n method,\n params,\n scope,\n }: {\n origin: string;\n // NOTE: We use `account` here rather than `id` to avoid ambiguity with a \"request ID\".\n // We already use this same field name for `KeyringAccount`s.\n account: string;\n method: string;\n params?: Json[] | Record<string, Json>;\n scope: string;\n }): Promise<Json> {\n const { account, snapId } = this.#getAccount(accountId);\n\n return await this.#submitSnapRequest({\n origin,\n snapId,\n account,\n method: method as AccountMethod,\n params,\n scope,\n // For non-EVM (in the context of the multichain API and SIP-26), we enforce responses\n // to be synchronous.\n noPending: true,\n });\n }\n\n /**\n * Submit a request to a Snap from an account address.\n *\n * @param opts - Request options.\n * @param opts.origin - Sender origin.\n * @param opts.address - Account address.\n * @param opts.method - Method to call.\n * @param opts.params - Method parameters.\n * @param opts.scope - Selected chain ID (CAIP-2).\n * @param opts.noPending - Whether the response is allowed to be pending.\n * @returns Promise that resolves to the result of the method call.\n */\n async #submitRequest<Response extends Json>({\n origin,\n address,\n method,\n params,\n scope = '',\n noPending = false,\n }: {\n origin: string;\n address: string;\n method: string;\n params?: Json[] | Record<string, Json>;\n scope?: string;\n noPending?: boolean;\n }): Promise<Response> {\n const { account, snapId } = this.#resolveAddress(address);\n\n return await this.#submitSnapRequest<Response>({\n origin,\n snapId,\n account,\n method: method as AccountMethod,\n params,\n scope,\n noPending,\n });\n }\n\n /**\n * Submits a request to a Snap and fix-up the payload depending on the version currently supported.\n *\n * @param options - The options for the Snap request.\n * @param options.version - The supported keyring version for the Snap.\n * @param options.snapId - The Snap ID to submit the request to.\n * @param options.request - The Snap request.\n * @returns A promise that resolves to the keyring response from the Snap.\n */\n async #submitSnapRequestForVersion({\n snapId,\n version,\n request,\n }: {\n snapId: SnapId;\n version: KeyringVersion;\n request: KeyringRequest;\n }): Promise<KeyringResponse> {\n // Get specific client for that Snap.\n const client = this.#snapClient.withSnapId(snapId);\n\n if (version === KeyringVersion.V1) {\n return await client.submitRequestV1(toKeyringRequestV1(request));\n }\n\n return await client.submitRequest(request);\n }\n\n /**\n * Submits a request to a Snap.\n *\n * @param options - The options for the Snap request.\n * @param options.origin - The sender origin.\n * @param options.snapId - The Snap ID to submit the request to.\n * @param options.account - The account to use for the request.\n * @param options.method - The Ethereum method to call.\n * @param options.params - The parameters to pass to the method, can be undefined.\n * @param options.scope - The chain ID to use for the request, can be an empty string.\n * @param options.noPending - Whether the response is allowed to be pending.\n * @returns A promise that resolves to the keyring response from the Snap.\n * @throws An error if the Snap fails to respond or if there's an issue with the request submission.\n */\n async #submitSnapRequest<Response extends Json>({\n origin,\n snapId,\n account,\n method,\n params,\n scope,\n noPending,\n }: {\n origin: string;\n snapId: SnapId;\n account: KeyringAccount;\n method: AccountMethod;\n params?: Json[] | Record<string, Json> | undefined;\n scope: string;\n noPending: boolean;\n }): Promise<Response> {\n if (!this.#hasMethod(account, method)) {\n throw new Error(\n `Method '${method}' not supported for account ${account.address}`,\n );\n }\n\n // Will both catch `undefined` and \"empty\" origins.\n if (!origin?.trim()) {\n throw new Error('An `origin` is required');\n }\n\n // Generate a new random request ID to keep track of the request execution flow.\n const requestId = uuid();\n\n // Create the promise before calling the Snap to prevent a race condition\n // where the Snap responds before we have a chance to create it.\n const requestPromise = this.#createRequestPromise<Response>(\n requestId,\n snapId,\n );\n\n try {\n const version = this.#getKeyringVersion(snapId);\n\n const request = {\n id: requestId,\n origin,\n scope,\n account: account.id,\n request: {\n method,\n ...(params !== undefined && { params }),\n },\n };\n\n log('Submit Snap request: ', request);\n\n const response = await this.#submitSnapRequestForVersion({\n version,\n snapId,\n request,\n });\n\n // Some methods, like the ones used to prepare and patch user operations,\n // require the Snap to answer synchronously in order to work with the\n // confirmation flow. This check lets the caller enforce this behavior.\n if (noPending && response.pending) {\n throw new Error(\n `Request '${requestId}' to Snap '${snapId}' is pending and noPending is true.`,\n );\n }\n\n // If the Snap answers synchronously, the promise must be removed from the\n // map to prevent a leak.\n if (!response.pending) {\n return this.#handleSyncResponse<Response>(response, requestId, snapId);\n }\n\n // If the Snap answers asynchronously, we will inform the user with a redirect\n if (response.redirect?.message || response.redirect?.url) {\n await this.#handleAsyncResponse(response.redirect, snapId);\n }\n\n return requestPromise.promise;\n } catch (error) {\n log('Snap Request failed: ', { requestId });\n\n // If the Snap failed to respond, delete the promise to prevent a leak.\n this.#clearRequestPromise(requestId, snapId);\n throw error;\n }\n }\n\n /**\n * Check if an account supports the given method.\n *\n * @param account - The account object to check for method support.\n * @param method - The Ethereum method to validate.\n * @returns `true` if the method is supported, `false` otherwise.\n */\n #hasMethod(account: KeyringAccount, method: AccountMethod): boolean {\n return (account.methods as AccountMethod[]).includes(method);\n }\n\n /**\n * Creates a promise for a request and adds it to the map of requests.\n *\n * @param requestId - The unique identifier for the request.\n * @param snapId - The Snap ID associated with the request.\n * @returns A DeferredPromise instance.\n */\n #createRequestPromise<Response>(\n requestId: string,\n snapId: SnapId,\n ): DeferredPromise<Response> {\n const promise = new DeferredPromise<Response>();\n this.#requests.set(requestId, { promise, snapId });\n return promise;\n }\n\n /**\n * Clear a promise for a request and delete it from the map of requests.\n *\n * @param requestId - The unique identifier for the request.\n * @param snapId - The Snap ID associated with the request.\n */\n #clearRequestPromise(requestId: string, snapId: SnapId): void {\n this.#requests.delete(snapId, requestId);\n }\n\n /**\n * Handles the synchronous response from a Snap. If the response indicates the request is not pending, it removes the request from the map.\n *\n * @param response - The response from the Snap.\n * @param response.pending - A boolean indicating if the request is pending should always be false in this context.\n * @param response.result - The result data from the Snap response.\n * @param requestId - The unique identifier for the request.\n * @param snapId - The Snap ID associated with the request.\n * @returns The result from the Snap response.\n */\n #handleSyncResponse<Response extends Json>(\n response: { pending: false; result: Json },\n requestId: string,\n snapId: SnapId,\n ): Response {\n this.#requests.delete(snapId, requestId);\n // We consider `Response` to be compatible with `result` here.\n return response.result as Response;\n }\n\n /**\n * Handles the async redirect and response from a Snap. Validates the redirect URL and informs the user with a message and URL if provided.\n *\n * @param redirect - The redirect information including message and URL.\n * @param redirect.message - The message to show to the user if provided.\n * @param redirect.url - The URL to redirect the user to if provided.\n * @param snapId - The Snap ID associated with the request.\n * @throws An error if the redirect URL is not an allowed origin for the Snap.\n */\n async #handleAsyncResponse(\n redirect: { message?: string; url?: string },\n snapId: SnapId,\n ): Promise<void> {\n const { message = '', url: redirectUrl = '' } = redirect;\n const url = this.#sanitizeRedirectUrl(redirectUrl);\n if (url) {\n this.#validateRedirectUrl(url, snapId);\n }\n await this.#callbacks.redirectUser(snapId, url, message);\n }\n\n /**\n * Sanitize a redirect URL.\n *\n * @param url - The URL to sanitize.\n * @returns The new sanitized redirect URL.\n */\n #sanitizeRedirectUrl(url: string): string {\n // We do check if the URL is empty or not since the Snap might not returns any URL at all.\n return url ? sanitizeUrl(url) : url;\n }\n\n /**\n * Validates if the redirect URL is in the Snap's allowed origins.\n *\n * @param url - The URL to validate.\n * @param snapId - The Snap ID to check allowed origins for.\n * @throws An error if the URL's origin is not in the Snap's allowed origins.\n */\n #validateRedirectUrl(url: string, snapId: SnapId): void {\n const { origin } = new URL(url);\n const snap = this.#getSnap(snapId);\n if (!snap) {\n throw new Error(`Snap '${snapId}' not found.`);\n }\n const allowedOrigins = this.#getSnapAllowedOrigins(snap);\n if (!allowedOrigins.includes(origin)) {\n throw new Error(\n `Redirect URL domain '${origin}' is not an allowed origin by snap '${snapId}'`,\n );\n }\n }\n\n /**\n * Sign a transaction.\n *\n * @param address - Sender's address.\n * @param transaction - Transaction.\n * @param _opts - Transaction options (not used).\n * @returns A promise that resolves to the signed transaction.\n */\n async signTransaction(\n address: string,\n transaction: TypedTransaction,\n _opts = {},\n ): Promise<Json | TypedTransaction> {\n const chainId = transaction.common.chainId();\n const tx = toJson({\n ...transaction.toJSON(),\n from: address,\n type: `0x${transaction.type.toString(16)}`,\n chainId: bigIntToHex(chainId),\n });\n\n const signedTx = await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.SignTransaction,\n params: [tx],\n scope: toCaipChainId(KnownCaipNamespace.Eip155, `${chainId}`),\n });\n\n // ! It's *** CRITICAL *** that we mask the signature here, otherwise the\n // ! Snap could overwrite the transaction.\n const signature = mask(\n signedTx,\n object({\n r: string(),\n s: string(),\n v: string(),\n }),\n );\n\n return TransactionFactory.fromTxData({\n ...(tx as Record<string, Json>),\n r: signature.r as Hex,\n s: signature.s as Hex,\n v: signature.v as Hex,\n });\n }\n\n /**\n * Sign a typed data message.\n *\n * @param address - Signer's address.\n * @param data - Data to sign.\n * @param opts - Signing options.\n * @returns The signature.\n */\n async signTypedData(\n address: string,\n data: Record<string, unknown>[] | TypedDataV1 | TypedMessage<any>,\n opts = { version: SignTypedDataVersion.V1 },\n ): Promise<string> {\n const methods = {\n [SignTypedDataVersion.V1]: EthMethod.SignTypedDataV1,\n [SignTypedDataVersion.V3]: EthMethod.SignTypedDataV3,\n [SignTypedDataVersion.V4]: EthMethod.SignTypedDataV4,\n };\n\n // Use 'V1' by default to match other keyring implementations. V1 will be\n // used if the version is not specified or not supported.\n const method = methods[opts.version] || EthMethod.SignTypedDataV1;\n\n // Extract chain ID as if it was a typed message (as defined by EIP-712), if\n // input is not a typed message, then chain ID will be undefined!\n const chainId = (data as TypedMessage<any>).domain?.chainId;\n\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method,\n params: toJson<Json[]>([address, data]),\n ...(chainId === undefined\n ? {}\n : {\n scope: toCaipChainId(KnownCaipNamespace.Eip155, `${chainId}`),\n }),\n }),\n EthBytesStruct,\n );\n }\n\n /**\n * Sign a message.\n *\n * @param address - Signer's address.\n * @param hash - Data to sign.\n * @returns The signature.\n */\n async signMessage(address: string, hash: any): Promise<string> {\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.Sign,\n params: toJson<Json[]>([address, hash]),\n }),\n EthBytesStruct,\n );\n }\n\n /**\n * Sign a personal message.\n *\n * Note: KeyringController says this should return a Buffer but it actually\n * expects a string.\n *\n * @param address - Signer's address.\n * @param data - Data to sign.\n * @returns Promise of the signature.\n */\n async signPersonalMessage(address: string, data: any): Promise<string> {\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.PersonalSign,\n params: toJson<Json[]>([data, address]),\n }),\n EthBytesStruct,\n );\n }\n\n /**\n * Convert a base transaction to a base UserOperation.\n *\n * @param address - Address of the sender.\n * @param transactions - Base transactions to include in the UserOperation.\n * @param context - Keyring execution context.\n * @returns A pseudo-UserOperation that can be used to construct a real.\n */\n async prepareUserOperation(\n address: string,\n transactions: EthBaseTransaction[],\n context: KeyringExecutionContext,\n ): Promise<EthBaseUserOperation> {\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.PrepareUserOperation,\n params: toJson<Json[]>(transactions),\n noPending: true,\n // We assume the chain ID is already well formatted\n scope: toCaipChainId(KnownCaipNamespace.Eip155, context.chainId),\n }),\n EthBaseUserOperationStruct,\n );\n }\n\n /**\n * Patches properties of a UserOperation. Currently, only the\n * `paymasterAndData` can be patched.\n *\n * @param address - Address of the sender.\n * @param userOp - UserOperation to patch.\n * @param context - Keyring execution context.\n * @returns A patch to apply to the UserOperation.\n */\n async patchUserOperation(\n address: string,\n userOp: EthUserOperation,\n context: KeyringExecutionContext,\n ): Promise<EthUserOperationPatch> {\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.PatchUserOperation,\n params: toJson<Json[]>([userOp]),\n noPending: true,\n // We assume the chain ID is already well formatted\n scope: toCaipChainId(KnownCaipNamespace.Eip155, context.chainId),\n }),\n EthUserOperationPatchStruct,\n );\n }\n\n /**\n * Signs an UserOperation.\n *\n * @param address - Address of the sender.\n * @param userOp - UserOperation to sign.\n * @param context - Leyring execution context.\n * @returns The signature of the UserOperation.\n */\n async signUserOperation(\n address: string,\n userOp: EthUserOperation,\n context: KeyringExecutionContext,\n ): Promise<string> {\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.SignUserOperation,\n params: toJson<Json[]>([userOp]),\n // We assume the chain ID is already well formatted\n scope: toCaipChainId(KnownCaipNamespace.Eip155, context.chainId),\n }),\n EthBytesStruct,\n );\n }\n\n /**\n * Gets the private data associated with the given address so\n * that it may be exported.\n *\n * If this keyring contains duplicate public keys the first\n * matching address is exported.\n *\n * Used by the UI to export an account.\n *\n * @param _address - Address of the account to export.\n */\n exportAccount(_address: string): [Uint8Array, Json] | undefined {\n throw new Error('Exporting accounts from snaps is not supported.');\n }\n\n /**\n * Removes the account matching the given address.\n *\n * @param address - Address of the account to remove.\n */\n async removeAccount(address: string): Promise<void> {\n const { account, snapId } = this.#resolveAddress(address);\n\n await this.#deleteAccount(snapId, account);\n }\n\n /**\n * Removes an account.\n *\n * @param snapId - Snap ID.\n * @param account - Account to delete.\n */\n async #deleteAccount(snapId: SnapId, account: KeyringAccount): Promise<void> {\n // Always remove the account from the maps, even if the Snap is going to\n // fail to delete it.\n this.#accounts.delete(snapId, account.id);\n\n try {\n await this.#snapClient.withSnapId(snapId).deleteAccount(account.id);\n } catch (error) {\n // If the Snap failed to delete the account, log the error and continue\n // with the account deletion, otherwise the account will be stuck in the\n // keyring.\n console.error(\n `Account '${account.address}' may not have been removed from snap '${snapId}':`,\n error,\n );\n }\n }\n\n /**\n * Resolve an address to an account and Snap ID.\n *\n * @param address - Address of the account to resolve.\n * @returns Account and Snap ID. Throws if the account or Snap ID is not\n * found.\n */\n #resolveAddress(address: string): {\n account: KeyringAccount;\n snapId: SnapId;\n } {\n return (\n [...this.#accounts.values()].find(({ account }) =>\n equalsIgnoreCase(account.address, address),\n ) ?? throwError(`Account '${address}' not found`)\n );\n }\n\n /**\n * Get the Snap associated with the given Snap ID.\n *\n * @param snapId - Snap ID.\n * @returns The Snap or undefined if the Snap cannot be found.\n */\n #getSnap(snapId: SnapId): Snap | undefined {\n return this.#messenger.call('SnapController:get', snapId);\n }\n\n /**\n * Get the metadata of a Snap keyring account.\n *\n * @param snapId - Snap ID.\n * @returns The Snap metadata or undefined if the Snap cannot be found.\n */\n #getSnapMetadata(\n snapId: SnapId,\n ): InternalAccount['metadata']['snap'] | undefined {\n const snap = this.#getSnap(snapId);\n return snap\n ? { id: snapId, name: snap.manifest.proposedName, enabled: snap.enabled }\n : undefined;\n }\n\n /**\n * Get the allowed origins of a Snap.\n *\n * @param snap - Snap.\n * @returns The allowed origins of the Snap.\n */\n #getSnapAllowedOrigins(snap: Snap): string[] {\n return (\n snap.manifest.initialPermissions['endowment:keyring']?.allowedOrigins ??\n []\n );\n }\n\n /**\n * Return an internal account object for a given address.\n *\n * @param address - Address of the account to return.\n * @returns An internal account object for the given address.\n */\n getAccountByAddress(address: string): InternalAccount | undefined {\n const accounts = this.listAccounts();\n return accounts.find(({ address: accountAddress }) =>\n equalsIgnoreCase(accountAddress, address),\n );\n }\n\n /**\n * List all Snap keyring accounts.\n *\n * @returns An array containing all Snap keyring accounts.\n */\n listAccounts(): InternalAccount[] {\n return [...this.#accounts.values()].map(({ account, snapId }) => {\n const snap = this.#getSnapMetadata(snapId);\n return {\n ...account,\n // TODO: Do not convert the address to lowercase.\n //\n // This is a workaround to support the current UI which expects the\n // account address to be lowercase. This workaround should be removed\n // once we migrated the UI to use the account ID instead of the account\n // address.\n //\n // NOTE: We convert the address only for EVM accounts, see\n // `normalizeAccountAddress`.\n address: normalizeAccountAddress(account),\n metadata: {\n name: '',\n importTime: 0,\n keyring: {\n type: this.type,\n },\n ...(snap !== undefined && { snap }),\n },\n };\n });\n }\n}\n"]}
1
+ {"version":3,"file":"SnapKeyring.cjs","sourceRoot":"","sources":["../src/SnapKeyring.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-redundant-type-constituents */\n// This rule seems to be triggering a false positive. Possibly eslint is not\n// inferring the `EthMethod`, `BtcMethod`, and `InternalAccount` types correctly.\n\nimport type { TypedTransaction } from '@ethereumjs/tx';\nimport { TransactionFactory } from '@ethereumjs/tx';\nimport type { ExtractEventPayload } from '@metamask/base-controller';\nimport type { TypedDataV1, TypedMessage } from '@metamask/eth-sig-util';\nimport { SignTypedDataVersion } from '@metamask/eth-sig-util';\nimport type {\n KeyringAccount,\n KeyringExecutionContext,\n BtcMethod,\n EthBaseTransaction,\n EthBaseUserOperation,\n EthUserOperation,\n EthUserOperationPatch,\n ResolvedAccountAddress,\n CaipChainId,\n MetaMaskOptions,\n KeyringRequest,\n KeyringResponse,\n GetSelectedAccountsResponse,\n} from '@metamask/keyring-api';\nimport {\n EthBytesStruct,\n EthMethod,\n EthBaseUserOperationStruct,\n EthUserOperationPatchStruct,\n isEvmAccountType,\n KeyringEvent,\n AccountAssetListUpdatedEventStruct,\n AccountBalancesUpdatedEventStruct,\n AccountTransactionsUpdatedEventStruct,\n AnyAccountType,\n KeyringMethod,\n GetSelectedAccountsRequestStruct,\n} from '@metamask/keyring-api';\nimport {\n KeyringVersion,\n toKeyringRequestV1,\n type InternalAccount,\n} from '@metamask/keyring-internal-api';\nimport { KeyringInternalSnapClient } from '@metamask/keyring-internal-snap-client';\nimport type { AccountId, JsonRpcRequest } from '@metamask/keyring-utils';\nimport { strictMask } from '@metamask/keyring-utils';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { type Snap } from '@metamask/snaps-utils';\nimport { assert, mask, object, string } from '@metamask/superstruct';\nimport type { Hex, Json, SemVerVersion } from '@metamask/utils';\nimport {\n bigIntToHex,\n hasProperty,\n KnownCaipNamespace,\n toCaipChainId,\n} from '@metamask/utils';\nimport { v4 as uuid } from 'uuid';\n\nimport { transformAccount } from './account';\nimport { DeferredPromise } from './DeferredPromise';\nimport {\n AccountCreatedEventStruct,\n AccountUpdatedEventStruct,\n AccountDeletedEventStruct,\n RequestApprovedEventStruct,\n RequestRejectedEventStruct,\n} from './events';\nimport { projectLogger as log } from './logger';\nimport { isAccountV1, migrateAccountV1 } from './migrations';\nimport {\n getInternalOptionsOf,\n type SnapKeyringInternalOptions,\n} from './options';\nimport { SnapIdMap } from './SnapIdMap';\nimport type {\n SnapKeyringEvents,\n SnapKeyringMessenger,\n} from './SnapKeyringMessenger';\nimport { SNAP_KEYRING_NAME } from './SnapKeyringMessenger';\nimport type { SnapMessage } from './types';\nimport { SnapMessageStruct } from './types';\nimport {\n equalsIgnoreCase,\n sanitizeUrl,\n throwError,\n toJson,\n unique,\n} from './util';\nimport { getKeyringVersionFromPlatform } from './versions';\n\nexport const SNAP_KEYRING_TYPE = 'Snap Keyring';\n\n// TODO: to be removed when this is added to the keyring-api\n\ntype AccountMethod = EthMethod | BtcMethod;\n\n/**\n * Snap keyring state.\n *\n * This state is persisted by the keyring controller and passed to the Snap\n * keyring when it's created.\n */\nexport type KeyringState = {\n accounts: Record<string, { account: KeyringAccount; snapId: SnapId }>;\n};\n\n/**\n * Snap keyring callbacks.\n *\n * These callbacks are used to interact with other components.\n */\nexport type SnapKeyringCallbacks = {\n saveState: () => Promise<void>;\n\n addressExists(address: string): Promise<boolean>;\n\n addAccount(\n address: string,\n snapId: SnapId,\n handleUserInput: (accepted: boolean) => Promise<void>,\n onceSaved: Promise<AccountId>,\n accountNameSuggestion?: string,\n internalOptions?: SnapKeyringInternalOptions,\n ): Promise<void>;\n\n removeAccount(\n address: string,\n snapId: SnapId,\n handleUserInput: (accepted: boolean) => Promise<void>,\n ): Promise<void>;\n\n getSelectedAccounts(snapId: SnapId): Promise<GetSelectedAccountsResponse>;\n\n redirectUser(snapId: SnapId, url: string, message: string): Promise<void>;\n};\n\n/**\n * Callback type to filter unknown account ID from a mapping account ID mapping.\n */\ntype FilterAccountIdFunction = <Entry>(\n accountMapping: Record<AccountId, Entry>,\n) => Record<AccountId, Entry>;\n\n/**\n * Normalize account's address.\n *\n * @param account - The account.\n * @returns The normalized account address.\n */\nfunction normalizeAccountAddress(account: KeyringAccount): string {\n // FIXME: Is it required to lowercase the address here? For now we'll keep this behavior\n // only for Ethereum addresses and use the original address for other non-EVM accounts.\n // For example, Solana addresses are case-sensitives.\n return isEvmAccountType(account.type)\n ? account.address.toLowerCase()\n : account.address;\n}\n\n/**\n * Keyring bridge implementation to support Snaps.\n */\nexport class SnapKeyring {\n static type: string = SNAP_KEYRING_TYPE;\n\n type: string;\n\n // Name and state are required for modular initialisation.\n name: typeof SNAP_KEYRING_NAME = SNAP_KEYRING_NAME;\n\n state = null;\n\n /**\n * Messenger to dispatch requests to the Snaps controller.\n */\n readonly #messenger: SnapKeyringMessenger;\n\n /**\n * Client used to call the Snap keyring.\n */\n readonly #snapClient: KeyringInternalSnapClient;\n\n /**\n * Mapping between account IDs and an object that contains the associated\n * account object and Snap ID.\n */\n #accounts: SnapIdMap<{\n account: KeyringAccount;\n snapId: SnapId;\n }>;\n\n /**\n * Mapping between request IDs and their deferred promises.\n */\n readonly #requests: SnapIdMap<{\n promise: DeferredPromise<any>;\n snapId: SnapId;\n }>;\n\n /**\n * Mapping between internal options, a correlation ID and a Snap ID.\n */\n readonly #options: SnapIdMap<{\n options: SnapKeyringInternalOptions;\n snapId: SnapId;\n // TODO: Add TTL to avoid having too many \"leaking\" internal options.\n }>;\n\n /**\n * Callbacks used to interact with other components.\n */\n readonly #callbacks: SnapKeyringCallbacks;\n\n /**\n * Whether to allow the creation and update of generic accounts.\n *\n * Account deletion is not affected by this flag and is always allowed.\n */\n readonly #isAnyAccountTypeAllowed: boolean;\n\n /**\n * Create a new Snap keyring.\n *\n * @param options - Constructor options.\n * @param options.messenger - Snap keyring messenger.\n * @param options.callbacks - Callbacks used to interact with other components.\n * @param options.isAnyAccountTypeAllowed - Whether to allow the `AnyAccountType` generic account type.\n * @returns A new Snap keyring.\n */\n constructor({\n messenger,\n callbacks,\n isAnyAccountTypeAllowed = false,\n }: {\n messenger: SnapKeyringMessenger;\n callbacks: SnapKeyringCallbacks;\n isAnyAccountTypeAllowed?: boolean;\n }) {\n this.type = SnapKeyring.type;\n this.#messenger = messenger;\n this.#snapClient = new KeyringInternalSnapClient({ messenger });\n this.#requests = new SnapIdMap();\n this.#accounts = new SnapIdMap();\n this.#options = new SnapIdMap();\n this.#callbacks = callbacks;\n this.#isAnyAccountTypeAllowed = isAnyAccountTypeAllowed;\n }\n\n /**\n * Gets keyring's version for a given Snap.\n *\n * @param snapId - The Snap ID.\n * @returns The Snap's keyring version.\n */\n #getKeyringVersion(snapId: SnapId): KeyringVersion {\n return getKeyringVersionFromPlatform((version: SemVerVersion) => {\n return this.#messenger.call(\n 'SnapController:isMinimumPlatformVersion',\n snapId,\n version,\n );\n });\n }\n\n /**\n * Get internal options given a correlation ID.\n *\n * NOTE: The associated options will be deleted automatically.\n *\n * @param snapId - Snap ID\n * @param correlationId - Correlation ID associated with the internal options.\n * @returns Internal options if found, `undefined` otherwise.\n */\n #getInternalOptions(\n snapId: SnapId,\n correlationId: string | undefined,\n ): SnapKeyringInternalOptions | undefined {\n if (correlationId) {\n // We still need to check if the correlation ID is valid and associated to\n // some internal options.\n //\n // NOTE: `found` will be `undefined` if a Snap tried to use a correlation ID that\n // belongs to another Snap ID. However, if a Snap starts 2 parallel flow (which\n // will results in 2 different correlation IDs), we won't be able to prevent\n // the Snap from swapping/mixing up those correlation IDs he owns.\n const found = this.#options.pop(snapId, correlationId);\n\n if (found) {\n return found.options;\n }\n\n console.warn(\n `SnapKeyring - Received unmapped correlation ID: \"${correlationId}\"`,\n );\n }\n\n return undefined;\n }\n\n /**\n * Handle an Account Created event from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountCreated(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountCreatedEventStruct);\n const {\n metamask, // Used for internal options.\n account: newAccountFromEvent,\n accountNameSuggestion,\n displayAccountNameSuggestion,\n displayConfirmation,\n } = message.params;\n\n // READ THIS CAREFULLY:\n // ------------------------------------------------------------------------\n // The account creation flow is now asynchronous. We expect the Snap to\n // first create the account data and then fire the \"AccountCreated\" event.\n\n // Potentially migrate the account.\n const account = transformAccount(newAccountFromEvent);\n\n // The `AnyAccountType.Account` generic account type is allowed only during\n // development, so we check whether it's allowed before continuing.\n if (\n !this.#isAnyAccountTypeAllowed &&\n account.type === AnyAccountType.Account\n ) {\n throw new Error(`Cannot create generic account '${account.id}'`);\n }\n\n // The UI still uses the account address to identify accounts, so we need\n // to block the creation of duplicate accounts for now to prevent accounts\n // from being overwritten.\n const address = normalizeAccountAddress(account);\n if (await this.#callbacks.addressExists(address)) {\n throw new Error(`Account address '${address}' already exists`);\n }\n\n // A Snap could try to create an account with a different address but with\n // an existing ID, so the above test only is not enough.\n if (this.#accounts.has(snapId, account.id)) {\n throw new Error(`Account '${account.id}' already exists`);\n }\n\n // A deferred promise that will be resolved once the Snap keyring has saved\n // its internal state.\n // This part of the flow is run asynchronously, so we have no other way of\n // letting the MetaMask client that this \"save\" has been run.\n // NOTE: Another way of fixing that could be to rely on events through the\n // messenger maybe?\n const onceSaved = new DeferredPromise<AccountId>();\n\n // Add the account to the keyring, but wait for the MetaMask client to\n // approve the account creation first.\n await this.#callbacks.addAccount(\n address,\n snapId,\n // This callback is passed to the MetaMask client, it will be called whenever\n // the end user will accept or not the account creation.\n async (accepted: boolean) => {\n if (accepted) {\n // We consider the account to be created on the Snap keyring only if\n // the user accepted it. Meaning that the Snap MIGHT HAVE created the\n // account on its own state, but the Snap keyring MIGHT NOT HAVE it yet.\n //\n // e.g The account creation dialog crashed on MetaMask, this callback\n // will never be called, but the Snap still has the account.\n this.#accounts.set(account.id, { account, snapId });\n\n // This is the \"true async part\". We do not `await` for this call, mainly\n // because this callback will persist the account on the client side\n // (through the `AccountsController`).\n //\n // Since this will happen after the Snap account creation and Snap\n // event, if anything goes wrong, we will delete the account by\n // calling `deleteAccount` on the Snap.\n // eslint-disable-next-line no-void\n void this.#callbacks\n .saveState()\n .then(() => {\n // This allows the MetaMask client to be \"notified\" when then\n // Snap keyring has truly persisted its state. From there, we should\n // be able to use the account (e.g. to display account creation\n // confirmation dialogs).\n onceSaved.resolve(account.id);\n })\n .catch(async (error) => {\n // FIXME: There's a potential race condition here, if the Snap did\n // not persist the account yet (this should mostly be for older Snaps).\n await this.#deleteAccount(snapId, account);\n\n // This allows the MetaMask client to be \"notified\" that something went\n // wrong with the Snap keyring. (e.g. useful to display account creation\n // error dialogs).\n onceSaved.reject(error);\n });\n }\n },\n onceSaved.promise,\n accountNameSuggestion,\n getInternalOptionsOf([\n // 1. We use the internal options from the Snap keyring.\n this.#getInternalOptions(snapId, metamask?.correlationId) ?? {},\n // 2. We use the ones coming from the Snap.\n {\n displayConfirmation,\n displayAccountNameSuggestion,\n },\n ]),\n );\n\n return null;\n }\n\n /**\n * Handle an Account Updated event from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountUpdated(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountUpdatedEventStruct);\n const { account: newAccountFromEvent } = message.params;\n const { account: oldAccount } =\n this.#accounts.get(snapId, newAccountFromEvent.id) ??\n throwError(`Account '${newAccountFromEvent.id}' not found`);\n\n // Potentially migrate the account.\n const newAccount = transformAccount(newAccountFromEvent);\n\n // The `AnyAccountType.Account` generic account type is allowed only during\n // development, so we check whether it's allowed before continuing.\n //\n // An account cannot be updated if the `isAnyAccountTypeAllowed` flag is\n // set to `false` and the new or old account is a generic account.\n const isGenericAccountInvolved =\n newAccount.type === AnyAccountType.Account ||\n oldAccount.type === AnyAccountType.Account;\n\n if (!this.#isAnyAccountTypeAllowed && isGenericAccountInvolved) {\n throw new Error(`Cannot update generic account '${newAccount.id}'`);\n }\n\n // The address of the account cannot be changed. In the future, we will\n // support changing the address of an account since it will be required to\n // support UTXO-based chains.\n if (!equalsIgnoreCase(oldAccount.address, newAccount.address)) {\n throw new Error(`Cannot change address of account '${newAccount.id}'`);\n }\n\n this.#accounts.set(newAccount.id, { account: newAccount, snapId });\n await this.#callbacks.saveState();\n return null;\n }\n\n /**\n * Handle an Account Deleted event from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountDeleted(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountDeletedEventStruct);\n const { id } = message.params;\n const entry = this.#accounts.get(snapId, id);\n\n // We can ignore the case where the account was already removed from the\n // keyring, making the deletion idempotent.\n //\n // This happens when the keyring calls the Snap to delete an account, and\n // the Snap calls the keyring back with an `AccountDeleted` event.\n if (entry === undefined) {\n return null;\n }\n\n // At this point we know that the account exists, so we can safely\n // destructure it.\n const { account } = entry;\n\n await this.#callbacks.removeAccount(\n normalizeAccountAddress(account),\n snapId,\n async (accepted) => {\n if (accepted) {\n await this.#callbacks.saveState();\n }\n },\n );\n return null;\n }\n\n /**\n * Handle an Get Selected Accounts method call from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Method call message.\n * @returns The selected accounts.\n */\n async #handleGetSelectedAccounts(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<GetSelectedAccountsResponse> {\n assert(message, GetSelectedAccountsRequestStruct);\n return this.#callbacks.getSelectedAccounts(snapId);\n }\n\n /**\n * Handle an Request Approved event from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleRequestApproved(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, RequestApprovedEventStruct);\n const { id, result } = message.params;\n const { promise } =\n this.#requests.get(snapId, id) ?? throwError(`Request '${id}' not found`);\n\n this.#requests.delete(snapId, id);\n promise.resolve(result);\n return null;\n }\n\n /**\n * Handle an Request Rejected event from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleRequestRejected(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, RequestRejectedEventStruct);\n const { id } = message.params;\n const { promise } =\n this.#requests.get(snapId, id) ?? throwError(`Request '${id}' not found`);\n\n this.#requests.delete(snapId, id);\n promise.reject(new Error(`Request rejected by user or snap.`));\n return null;\n }\n\n /**\n * Re-publish an account event.\n *\n * @param snapId - Snap ID.\n * @param event - The event type. This is a unique identifier for this event.\n * @param filteredEventCallback - A callback that returns the event to re-publish. This callback takes a filtering\n * function as parameter that can be used to filter out account ID that do not belong to this Snap ID.\n * @template EventType - A Snap keyring event type.\n * @returns `null`.\n */\n async #rePublishAccountEvent<EventType extends SnapKeyringEvents['type']>(\n snapId: SnapId,\n event: EventType,\n filteredEventCallback: (\n filter: FilterAccountIdFunction,\n ) => ExtractEventPayload<SnapKeyringEvents, EventType>,\n ): Promise<null> {\n // This callback can be used to filter out the accounts that no longer exists on the Snap (fail-safe) or to\n // prevent other Snaps from updating accounts they do not own.\n const filter: FilterAccountIdFunction = <Entry>(\n accountMapping: Record<AccountId, Entry>,\n ): Record<AccountId, Entry> => {\n return Object.entries(accountMapping).reduce<Record<AccountId, Entry>>(\n (filtered, [accountId, entry]) => {\n if (this.#accounts.has(snapId, accountId)) {\n // If the Snap owns this account, we can use it.\n filtered[accountId] = entry;\n } else {\n // Otherwise, we just filter it out and log it (for debugging/tracking purposes).\n console.warn(\n `SnapKeyring - ${event} - Found an unknown account ID \"${accountId}\" for Snap ID \"${snapId}\". Skipping.`,\n );\n }\n\n return filtered;\n },\n {},\n );\n };\n\n this.#messenger.publish(event, ...filteredEventCallback(filter));\n return null;\n }\n\n /**\n * Handle a balances updated event from a Snap.\n *\n * @param snapId - ID of the Snap.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountBalancesUpdated(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountBalancesUpdatedEventStruct);\n\n const event = message.params;\n return this.#rePublishAccountEvent(\n snapId,\n 'SnapKeyring:accountBalancesUpdated',\n (filter) => {\n event.balances = filter(event.balances);\n return [event];\n },\n );\n }\n\n /**\n * Handle a asset list updated event from a Snap.\n *\n * @param snapId - ID of the Snap.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountAssetListUpdated(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountAssetListUpdatedEventStruct);\n\n const event = message.params;\n return this.#rePublishAccountEvent(\n snapId,\n 'SnapKeyring:accountAssetListUpdated',\n (filter) => {\n event.assets = filter(event.assets);\n return [event];\n },\n );\n }\n\n /**\n * Handle a transactions updated event from a Snap.\n *\n * @param snapId - ID of the Snap.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountTransactionsUpdated(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountTransactionsUpdatedEventStruct);\n\n const event = message.params;\n return this.#rePublishAccountEvent(\n snapId,\n 'SnapKeyring:accountTransactionsUpdated',\n (filter) => {\n event.transactions = filter(event.transactions);\n return [event];\n },\n );\n }\n\n /**\n * Handle a message from a Snap.\n *\n * @param snapId - ID of the Snap.\n * @param message - Message sent by the Snap.\n * @returns The execution result.\n */\n async handleKeyringSnapMessage(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<Json> {\n assert(message, SnapMessageStruct);\n switch (message.method) {\n case `${KeyringEvent.AccountCreated}`: {\n return this.#handleAccountCreated(snapId, message);\n }\n\n case `${KeyringEvent.AccountUpdated}`: {\n return this.#handleAccountUpdated(snapId, message);\n }\n\n case `${KeyringEvent.AccountDeleted}`: {\n return this.#handleAccountDeleted(snapId, message);\n }\n\n case `${KeyringEvent.RequestApproved}`: {\n return this.#handleRequestApproved(snapId, message);\n }\n\n case `${KeyringEvent.RequestRejected}`: {\n return this.#handleRequestRejected(snapId, message);\n }\n\n // Assets related events:\n case `${KeyringEvent.AccountBalancesUpdated}`: {\n return this.#handleAccountBalancesUpdated(snapId, message);\n }\n\n case `${KeyringEvent.AccountAssetListUpdated}`: {\n return this.#handleAccountAssetListUpdated(snapId, message);\n }\n\n case `${KeyringEvent.AccountTransactionsUpdated}`: {\n return this.#handleAccountTransactionsUpdated(snapId, message);\n }\n\n case `${KeyringMethod.GetSelectedAccounts}`: {\n return this.#handleGetSelectedAccounts(snapId, message);\n }\n\n default:\n throw new Error(`Method not supported: ${message.method}`);\n }\n }\n\n /**\n * Serialize the keyring state.\n *\n * @returns Serialized keyring state.\n */\n async serialize(): Promise<KeyringState> {\n return {\n accounts: this.#accounts.toObject(),\n };\n }\n\n /**\n * Deserialize the keyring state into this keyring.\n *\n * @param state - Serialized keyring state.\n */\n async deserialize(state: KeyringState | undefined): Promise<void> {\n // If the state is undefined, it means that this is a new keyring, so we\n // don't need to do anything.\n if (state === undefined) {\n return;\n }\n\n // Running Snap keyring migrations. We might have some accounts that have a\n // different \"version\" than the one we expect.\n //\n // In this case, we \"transform\" then directly when deserializing to convert\n // them in the final account version.\n const accounts: KeyringState['accounts'] = {};\n for (const [snapId, entry] of Object.entries(state.accounts)) {\n // V1 accounts are missing the scopes.\n if (isAccountV1(entry.account)) {\n console.info(\n `SnapKeyring - Found a KeyringAccountV1, migrating to V2: ${entry.account.id}`,\n );\n accounts[snapId] = {\n ...entry,\n account: migrateAccountV1(entry.account),\n };\n } else {\n accounts[snapId] = entry;\n }\n }\n\n this.#accounts = SnapIdMap.fromObject(accounts);\n }\n\n /**\n * Get an account and its associated Snap ID from its ID.\n *\n * @param id - Account ID.\n * @throws An error if the account could not be found.\n * @returns The account associated with the given account ID in this keyring.\n */\n #getAccount(id: string): { account: KeyringAccount; snapId: SnapId } {\n const found = [...this.#accounts.values()].find(\n (entry) => entry.account.id === id,\n );\n\n if (!found) {\n throw new Error(`Unable to get account: unknown account ID: '${id}'`);\n }\n return found;\n }\n\n /**\n * Get the addresses of the accounts in this keyring.\n *\n * @returns The addresses of the accounts in this keyring.\n */\n async getAccounts(): Promise<string[]> {\n return unique(\n [...this.#accounts.values()].map(({ account }) =>\n normalizeAccountAddress(account),\n ),\n );\n }\n\n /**\n * Get the addresses of the accounts associated with a given Snap.\n *\n * @param snapId - Snap ID to filter by.\n * @returns The addresses of the accounts associated with the given Snap.\n */\n async getAccountsBySnapId(snapId: SnapId): Promise<string[]> {\n return unique(\n [...this.#accounts.values()]\n .filter(({ snapId: accountSnapId }) => accountSnapId === snapId)\n .map(({ account }) => normalizeAccountAddress(account)),\n );\n }\n\n /**\n * Create an account.\n *\n * @param snapId - Snap ID to create the account for.\n * @param options - Account creation options. Differs between keyrings.\n * @param internalOptions - Internal Snap keyring options.\n * @returns The account object.\n */\n async createAccount(\n snapId: SnapId,\n options: Record<string, Json>,\n internalOptions?: SnapKeyringInternalOptions,\n ): Promise<KeyringAccount> {\n const client = new KeyringInternalSnapClient({\n messenger: this.#messenger,\n snapId,\n });\n\n // The 'metamask' field is reserved, so we have to prevent use of it on\n // the \"normal options\".\n const reserved = 'metamask';\n if (hasProperty(options, reserved)) {\n throw new Error(\n `The '${reserved}' property is reserved for internal use`,\n );\n }\n\n // Those internal options are optional. If not set, we avoid registering anything\n // to internal map (to avoid holding resources for nothing). In this case, it's\n // just a normal `keyring_createAccount`.\n if (!internalOptions) {\n return await client.createAccount(options);\n }\n\n // A unique ID to identify this execution flow which allows to associate the\n // internal options and the current `keyring_createAccount` flow for that Snap.\n const correlationId = uuid();\n\n // Register those internal options to use them during the `keyring_createAccount`\n // flow.\n this.#options.set(correlationId, {\n snapId,\n options: internalOptions,\n });\n\n return await client.createAccount({\n ...options,\n // Create internal options context.\n // NOTE: Those options HAVE TO be re-emitted during the `notify:accountCreated` event.\n ...({\n metamask: {\n correlationId,\n },\n } as MetaMaskOptions),\n });\n }\n\n /**\n * Checks if a Snap ID is known from the keyring.\n *\n * @param snapId - Snap ID.\n * @returns `true` if the Snap ID is known, `false` otherwise.\n */\n hasSnapId(snapId: SnapId): boolean {\n return this.#accounts.hasSnapId(snapId);\n }\n\n /**\n * Resolve the Snap account's address associated from a signing request.\n *\n * @param snapId - Snap ID.\n * @param scope - CAIP-2 chain ID.\n * @param request - Signing request object.\n * @throws An error if the Snap ID is not known from the keyring.\n * @returns The resolved address if found, `null` otherwise.\n */\n async resolveAccountAddress(\n snapId: SnapId,\n scope: CaipChainId,\n request: JsonRpcRequest,\n ): Promise<ResolvedAccountAddress | null> {\n // We do check that the incoming Snap ID is known by the keyring.\n if (!this.hasSnapId(snapId)) {\n throw new Error(\n `Unable to resolve account address: unknown Snap ID: ${snapId}`,\n );\n }\n\n return await this.#snapClient\n .withSnapId(snapId)\n .resolveAccountAddress(scope, request);\n }\n\n /**\n * Submit a request to a Snap from an account ID.\n *\n * This request cannot be an asynchronous keyring request.\n *\n * @param opts - Request options.\n * @param opts.origin - Send origin.\n * @param opts.account - Account ID.\n * @param opts.method - Method to call.\n * @param opts.params - Method parameters.\n * @param opts.scope - Selected chain ID (CAIP-2).\n * @returns Promise that resolves to the result of the method call.\n */\n async submitRequest({\n origin,\n account: accountId,\n method,\n params,\n scope,\n }: {\n origin: string;\n // NOTE: We use `account` here rather than `id` to avoid ambiguity with a \"request ID\".\n // We already use this same field name for `KeyringAccount`s.\n account: string;\n method: string;\n params?: Json[] | Record<string, Json>;\n scope: string;\n }): Promise<Json> {\n const { account, snapId } = this.#getAccount(accountId);\n\n return await this.#submitSnapRequest({\n origin,\n snapId,\n account,\n method: method as AccountMethod,\n params,\n scope,\n // For non-EVM (in the context of the multichain API and SIP-26), we enforce responses\n // to be synchronous.\n noPending: true,\n });\n }\n\n /**\n * Submit a request to a Snap from an account address.\n *\n * @param opts - Request options.\n * @param opts.origin - Sender origin.\n * @param opts.address - Account address.\n * @param opts.method - Method to call.\n * @param opts.params - Method parameters.\n * @param opts.scope - Selected chain ID (CAIP-2).\n * @param opts.noPending - Whether the response is allowed to be pending.\n * @returns Promise that resolves to the result of the method call.\n */\n async #submitRequest<Response extends Json>({\n origin,\n address,\n method,\n params,\n scope = '',\n noPending = false,\n }: {\n origin: string;\n address: string;\n method: string;\n params?: Json[] | Record<string, Json>;\n scope?: string;\n noPending?: boolean;\n }): Promise<Response> {\n const { account, snapId } = this.#resolveAddress(address);\n\n return await this.#submitSnapRequest<Response>({\n origin,\n snapId,\n account,\n method: method as AccountMethod,\n params,\n scope,\n noPending,\n });\n }\n\n /**\n * Submits a request to a Snap and fix-up the payload depending on the version currently supported.\n *\n * @param options - The options for the Snap request.\n * @param options.version - The supported keyring version for the Snap.\n * @param options.snapId - The Snap ID to submit the request to.\n * @param options.request - The Snap request.\n * @returns A promise that resolves to the keyring response from the Snap.\n */\n async #submitSnapRequestForVersion({\n snapId,\n version,\n request,\n }: {\n snapId: SnapId;\n version: KeyringVersion;\n request: KeyringRequest;\n }): Promise<KeyringResponse> {\n // Get specific client for that Snap.\n const client = this.#snapClient.withSnapId(snapId);\n\n if (version === KeyringVersion.V1) {\n return await client.submitRequestV1(toKeyringRequestV1(request));\n }\n\n return await client.submitRequest(request);\n }\n\n /**\n * Submits a request to a Snap.\n *\n * @param options - The options for the Snap request.\n * @param options.origin - The sender origin.\n * @param options.snapId - The Snap ID to submit the request to.\n * @param options.account - The account to use for the request.\n * @param options.method - The Ethereum method to call.\n * @param options.params - The parameters to pass to the method, can be undefined.\n * @param options.scope - The chain ID to use for the request, can be an empty string.\n * @param options.noPending - Whether the response is allowed to be pending.\n * @returns A promise that resolves to the keyring response from the Snap.\n * @throws An error if the Snap fails to respond or if there's an issue with the request submission.\n */\n async #submitSnapRequest<Response extends Json>({\n origin,\n snapId,\n account,\n method,\n params,\n scope,\n noPending,\n }: {\n origin: string;\n snapId: SnapId;\n account: KeyringAccount;\n method: AccountMethod;\n params?: Json[] | Record<string, Json> | undefined;\n scope: string;\n noPending: boolean;\n }): Promise<Response> {\n if (!this.#hasMethod(account, method)) {\n throw new Error(\n `Method '${method}' not supported for account ${account.address}`,\n );\n }\n\n // Will both catch `undefined` and \"empty\" origins.\n if (!origin?.trim()) {\n throw new Error('An `origin` is required');\n }\n\n // Generate a new random request ID to keep track of the request execution flow.\n const requestId = uuid();\n\n // Create the promise before calling the Snap to prevent a race condition\n // where the Snap responds before we have a chance to create it.\n const requestPromise = this.#createRequestPromise<Response>(\n requestId,\n snapId,\n );\n\n try {\n const version = this.#getKeyringVersion(snapId);\n\n const request = {\n id: requestId,\n origin,\n scope,\n account: account.id,\n request: {\n method,\n ...(params !== undefined && { params }),\n },\n };\n\n log('Submit Snap request: ', request);\n\n const response = await this.#submitSnapRequestForVersion({\n version,\n snapId,\n request,\n });\n\n // Some methods, like the ones used to prepare and patch user operations,\n // require the Snap to answer synchronously in order to work with the\n // confirmation flow. This check lets the caller enforce this behavior.\n if (noPending && response.pending) {\n throw new Error(\n `Request '${requestId}' to Snap '${snapId}' is pending and noPending is true.`,\n );\n }\n\n // If the Snap answers synchronously, the promise must be removed from the\n // map to prevent a leak.\n if (!response.pending) {\n return this.#handleSyncResponse<Response>(response, requestId, snapId);\n }\n\n // If the Snap answers asynchronously, we will inform the user with a redirect\n if (response.redirect?.message || response.redirect?.url) {\n await this.#handleAsyncResponse(response.redirect, snapId);\n }\n\n return requestPromise.promise;\n } catch (error) {\n log('Snap Request failed: ', { requestId });\n\n // If the Snap failed to respond, delete the promise to prevent a leak.\n this.#clearRequestPromise(requestId, snapId);\n throw error;\n }\n }\n\n /**\n * Check if an account supports the given method.\n *\n * @param account - The account object to check for method support.\n * @param method - The Ethereum method to validate.\n * @returns `true` if the method is supported, `false` otherwise.\n */\n #hasMethod(account: KeyringAccount, method: AccountMethod): boolean {\n return (account.methods as AccountMethod[]).includes(method);\n }\n\n /**\n * Creates a promise for a request and adds it to the map of requests.\n *\n * @param requestId - The unique identifier for the request.\n * @param snapId - The Snap ID associated with the request.\n * @returns A DeferredPromise instance.\n */\n #createRequestPromise<Response>(\n requestId: string,\n snapId: SnapId,\n ): DeferredPromise<Response> {\n const promise = new DeferredPromise<Response>();\n this.#requests.set(requestId, { promise, snapId });\n return promise;\n }\n\n /**\n * Clear a promise for a request and delete it from the map of requests.\n *\n * @param requestId - The unique identifier for the request.\n * @param snapId - The Snap ID associated with the request.\n */\n #clearRequestPromise(requestId: string, snapId: SnapId): void {\n this.#requests.delete(snapId, requestId);\n }\n\n /**\n * Handles the synchronous response from a Snap. If the response indicates the request is not pending, it removes the request from the map.\n *\n * @param response - The response from the Snap.\n * @param response.pending - A boolean indicating if the request is pending should always be false in this context.\n * @param response.result - The result data from the Snap response.\n * @param requestId - The unique identifier for the request.\n * @param snapId - The Snap ID associated with the request.\n * @returns The result from the Snap response.\n */\n #handleSyncResponse<Response extends Json>(\n response: { pending: false; result: Json },\n requestId: string,\n snapId: SnapId,\n ): Response {\n this.#requests.delete(snapId, requestId);\n // We consider `Response` to be compatible with `result` here.\n return response.result as Response;\n }\n\n /**\n * Handles the async redirect and response from a Snap. Validates the redirect URL and informs the user with a message and URL if provided.\n *\n * @param redirect - The redirect information including message and URL.\n * @param redirect.message - The message to show to the user if provided.\n * @param redirect.url - The URL to redirect the user to if provided.\n * @param snapId - The Snap ID associated with the request.\n * @throws An error if the redirect URL is not an allowed origin for the Snap.\n */\n async #handleAsyncResponse(\n redirect: { message?: string; url?: string },\n snapId: SnapId,\n ): Promise<void> {\n const { message = '', url: redirectUrl = '' } = redirect;\n const url = this.#sanitizeRedirectUrl(redirectUrl);\n if (url) {\n this.#validateRedirectUrl(url, snapId);\n }\n await this.#callbacks.redirectUser(snapId, url, message);\n }\n\n /**\n * Sanitize a redirect URL.\n *\n * @param url - The URL to sanitize.\n * @returns The new sanitized redirect URL.\n */\n #sanitizeRedirectUrl(url: string): string {\n // We do check if the URL is empty or not since the Snap might not returns any URL at all.\n return url ? sanitizeUrl(url) : url;\n }\n\n /**\n * Validates if the redirect URL is in the Snap's allowed origins.\n *\n * @param url - The URL to validate.\n * @param snapId - The Snap ID to check allowed origins for.\n * @throws An error if the URL's origin is not in the Snap's allowed origins.\n */\n #validateRedirectUrl(url: string, snapId: SnapId): void {\n const { origin } = new URL(url);\n const snap = this.#getSnap(snapId);\n if (!snap) {\n throw new Error(`Snap '${snapId}' not found.`);\n }\n const allowedOrigins = this.#getSnapAllowedOrigins(snap);\n if (!allowedOrigins.includes(origin)) {\n throw new Error(\n `Redirect URL domain '${origin}' is not an allowed origin by snap '${snapId}'`,\n );\n }\n }\n\n /**\n * Sign a transaction.\n *\n * @param address - Sender's address.\n * @param transaction - Transaction.\n * @param _opts - Transaction options (not used).\n * @returns A promise that resolves to the signed transaction.\n */\n async signTransaction(\n address: string,\n transaction: TypedTransaction,\n _opts = {},\n ): Promise<Json | TypedTransaction> {\n const chainId = transaction.common.chainId();\n const tx = toJson({\n ...transaction.toJSON(),\n from: address,\n type: `0x${transaction.type.toString(16)}`,\n chainId: bigIntToHex(chainId),\n });\n\n const signedTx = await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.SignTransaction,\n params: [tx],\n scope: toCaipChainId(KnownCaipNamespace.Eip155, `${chainId}`),\n });\n\n // ! It's *** CRITICAL *** that we mask the signature here, otherwise the\n // ! Snap could overwrite the transaction.\n const signature = mask(\n signedTx,\n object({\n r: string(),\n s: string(),\n v: string(),\n }),\n );\n\n return TransactionFactory.fromTxData({\n ...(tx as Record<string, Json>),\n r: signature.r as Hex,\n s: signature.s as Hex,\n v: signature.v as Hex,\n });\n }\n\n /**\n * Sign a typed data message.\n *\n * @param address - Signer's address.\n * @param data - Data to sign.\n * @param opts - Signing options.\n * @returns The signature.\n */\n async signTypedData(\n address: string,\n data: Record<string, unknown>[] | TypedDataV1 | TypedMessage<any>,\n opts = { version: SignTypedDataVersion.V1 },\n ): Promise<string> {\n const methods = {\n [SignTypedDataVersion.V1]: EthMethod.SignTypedDataV1,\n [SignTypedDataVersion.V3]: EthMethod.SignTypedDataV3,\n [SignTypedDataVersion.V4]: EthMethod.SignTypedDataV4,\n };\n\n // Use 'V1' by default to match other keyring implementations. V1 will be\n // used if the version is not specified or not supported.\n const method = methods[opts.version] || EthMethod.SignTypedDataV1;\n\n // Extract chain ID as if it was a typed message (as defined by EIP-712), if\n // input is not a typed message, then chain ID will be undefined!\n const chainId = (data as TypedMessage<any>).domain?.chainId;\n\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method,\n params: toJson<Json[]>([address, data]),\n ...(chainId === undefined\n ? {}\n : {\n scope: toCaipChainId(KnownCaipNamespace.Eip155, `${chainId}`),\n }),\n }),\n EthBytesStruct,\n );\n }\n\n /**\n * Sign a message.\n *\n * @param address - Signer's address.\n * @param hash - Data to sign.\n * @returns The signature.\n */\n async signMessage(address: string, hash: any): Promise<string> {\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.Sign,\n params: toJson<Json[]>([address, hash]),\n }),\n EthBytesStruct,\n );\n }\n\n /**\n * Sign a personal message.\n *\n * Note: KeyringController says this should return a Buffer but it actually\n * expects a string.\n *\n * @param address - Signer's address.\n * @param data - Data to sign.\n * @returns Promise of the signature.\n */\n async signPersonalMessage(address: string, data: any): Promise<string> {\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.PersonalSign,\n params: toJson<Json[]>([data, address]),\n }),\n EthBytesStruct,\n );\n }\n\n /**\n * Convert a base transaction to a base UserOperation.\n *\n * @param address - Address of the sender.\n * @param transactions - Base transactions to include in the UserOperation.\n * @param context - Keyring execution context.\n * @returns A pseudo-UserOperation that can be used to construct a real.\n */\n async prepareUserOperation(\n address: string,\n transactions: EthBaseTransaction[],\n context: KeyringExecutionContext,\n ): Promise<EthBaseUserOperation> {\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.PrepareUserOperation,\n params: toJson<Json[]>(transactions),\n noPending: true,\n // We assume the chain ID is already well formatted\n scope: toCaipChainId(KnownCaipNamespace.Eip155, context.chainId),\n }),\n EthBaseUserOperationStruct,\n );\n }\n\n /**\n * Patches properties of a UserOperation. Currently, only the\n * `paymasterAndData` can be patched.\n *\n * @param address - Address of the sender.\n * @param userOp - UserOperation to patch.\n * @param context - Keyring execution context.\n * @returns A patch to apply to the UserOperation.\n */\n async patchUserOperation(\n address: string,\n userOp: EthUserOperation,\n context: KeyringExecutionContext,\n ): Promise<EthUserOperationPatch> {\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.PatchUserOperation,\n params: toJson<Json[]>([userOp]),\n noPending: true,\n // We assume the chain ID is already well formatted\n scope: toCaipChainId(KnownCaipNamespace.Eip155, context.chainId),\n }),\n EthUserOperationPatchStruct,\n );\n }\n\n /**\n * Signs an UserOperation.\n *\n * @param address - Address of the sender.\n * @param userOp - UserOperation to sign.\n * @param context - Leyring execution context.\n * @returns The signature of the UserOperation.\n */\n async signUserOperation(\n address: string,\n userOp: EthUserOperation,\n context: KeyringExecutionContext,\n ): Promise<string> {\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.SignUserOperation,\n params: toJson<Json[]>([userOp]),\n // We assume the chain ID is already well formatted\n scope: toCaipChainId(KnownCaipNamespace.Eip155, context.chainId),\n }),\n EthBytesStruct,\n );\n }\n\n /**\n * Gets the private data associated with the given address so\n * that it may be exported.\n *\n * If this keyring contains duplicate public keys the first\n * matching address is exported.\n *\n * Used by the UI to export an account.\n *\n * @param _address - Address of the account to export.\n */\n exportAccount(_address: string): [Uint8Array, Json] | undefined {\n throw new Error('Exporting accounts from snaps is not supported.');\n }\n\n /**\n * Removes the account matching the given address.\n *\n * @param address - Address of the account to remove.\n */\n async removeAccount(address: string): Promise<void> {\n const { account, snapId } = this.#resolveAddress(address);\n\n await this.#deleteAccount(snapId, account);\n }\n\n /**\n * Removes an account.\n *\n * @param snapId - Snap ID.\n * @param account - Account to delete.\n */\n async #deleteAccount(snapId: SnapId, account: KeyringAccount): Promise<void> {\n // Always remove the account from the maps, even if the Snap is going to\n // fail to delete it.\n this.#accounts.delete(snapId, account.id);\n\n try {\n await this.#snapClient.withSnapId(snapId).deleteAccount(account.id);\n } catch (error) {\n // If the Snap failed to delete the account, log the error and continue\n // with the account deletion, otherwise the account will be stuck in the\n // keyring.\n console.error(\n `Account '${account.address}' may not have been removed from snap '${snapId}':`,\n error,\n );\n }\n }\n\n /**\n * Resolve an address to an account and Snap ID.\n *\n * @param address - Address of the account to resolve.\n * @returns Account and Snap ID. Throws if the account or Snap ID is not\n * found.\n */\n #resolveAddress(address: string): {\n account: KeyringAccount;\n snapId: SnapId;\n } {\n return (\n [...this.#accounts.values()].find(({ account }) =>\n equalsIgnoreCase(account.address, address),\n ) ?? throwError(`Account '${address}' not found`)\n );\n }\n\n /**\n * Set the selected accounts.\n *\n * @param accounts - The accounts to set as selected.\n */\n async setSelectedAccounts(\n accounts: Record<SnapId, AccountId[]>,\n ): Promise<void> {\n for (const [snapId, accountIds] of Object.entries(accounts) as [\n SnapId,\n AccountId[],\n ][]) {\n await this.#snapClient.withSnapId(snapId).setSelectedAccounts(accountIds);\n }\n }\n\n /**\n * Get the Snap associated with the given Snap ID.\n *\n * @param snapId - Snap ID.\n * @returns The Snap or undefined if the Snap cannot be found.\n */\n #getSnap(snapId: SnapId): Snap | undefined {\n return this.#messenger.call('SnapController:get', snapId);\n }\n\n /**\n * Get the metadata of a Snap keyring account.\n *\n * @param snapId - Snap ID.\n * @returns The Snap metadata or undefined if the Snap cannot be found.\n */\n #getSnapMetadata(\n snapId: SnapId,\n ): InternalAccount['metadata']['snap'] | undefined {\n const snap = this.#getSnap(snapId);\n return snap\n ? { id: snapId, name: snap.manifest.proposedName, enabled: snap.enabled }\n : undefined;\n }\n\n /**\n * Get the allowed origins of a Snap.\n *\n * @param snap - Snap.\n * @returns The allowed origins of the Snap.\n */\n #getSnapAllowedOrigins(snap: Snap): string[] {\n return (\n snap.manifest.initialPermissions['endowment:keyring']?.allowedOrigins ??\n []\n );\n }\n\n /**\n * Return an internal account object for a given address.\n *\n * @param address - Address of the account to return.\n * @returns An internal account object for the given address.\n */\n getAccountByAddress(address: string): InternalAccount | undefined {\n const accounts = this.listAccounts();\n return accounts.find(({ address: accountAddress }) =>\n equalsIgnoreCase(accountAddress, address),\n );\n }\n\n /**\n * List all Snap keyring accounts.\n *\n * @returns An array containing all Snap keyring accounts.\n */\n listAccounts(): InternalAccount[] {\n return [...this.#accounts.values()].map(({ account, snapId }) => {\n const snap = this.#getSnapMetadata(snapId);\n return {\n ...account,\n // TODO: Do not convert the address to lowercase.\n //\n // This is a workaround to support the current UI which expects the\n // account address to be lowercase. This workaround should be removed\n // once we migrated the UI to use the account ID instead of the account\n // address.\n //\n // NOTE: We convert the address only for EVM accounts, see\n // `normalizeAccountAddress`.\n address: normalizeAccountAddress(account),\n metadata: {\n name: '',\n importTime: 0,\n keyring: {\n type: this.type,\n },\n ...(snap !== undefined && { snap }),\n },\n };\n });\n }\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import type { TypedTransaction } from "@ethereumjs/tx";
2
2
  import type { TypedDataV1, TypedMessage } from "@metamask/eth-sig-util";
3
3
  import { SignTypedDataVersion } from "@metamask/eth-sig-util";
4
- import type { KeyringAccount, KeyringExecutionContext, EthBaseTransaction, EthBaseUserOperation, EthUserOperation, EthUserOperationPatch, ResolvedAccountAddress, CaipChainId } from "@metamask/keyring-api";
4
+ import type { KeyringAccount, KeyringExecutionContext, EthBaseTransaction, EthBaseUserOperation, EthUserOperation, EthUserOperationPatch, ResolvedAccountAddress, CaipChainId, GetSelectedAccountsResponse } from "@metamask/keyring-api";
5
5
  import { type InternalAccount } from "@metamask/keyring-internal-api";
6
6
  import type { AccountId, JsonRpcRequest } from "@metamask/keyring-utils";
7
7
  import type { SnapId } from "@metamask/snaps-sdk";
@@ -33,6 +33,7 @@ export type SnapKeyringCallbacks = {
33
33
  addressExists(address: string): Promise<boolean>;
34
34
  addAccount(address: string, snapId: SnapId, handleUserInput: (accepted: boolean) => Promise<void>, onceSaved: Promise<AccountId>, accountNameSuggestion?: string, internalOptions?: SnapKeyringInternalOptions): Promise<void>;
35
35
  removeAccount(address: string, snapId: SnapId, handleUserInput: (accepted: boolean) => Promise<void>): Promise<void>;
36
+ getSelectedAccounts(snapId: SnapId): Promise<GetSelectedAccountsResponse>;
36
37
  redirectUser(snapId: SnapId, url: string, message: string): Promise<void>;
37
38
  };
38
39
  /**
@@ -222,6 +223,12 @@ export declare class SnapKeyring {
222
223
  * @param address - Address of the account to remove.
223
224
  */
224
225
  removeAccount(address: string): Promise<void>;
226
+ /**
227
+ * Set the selected accounts.
228
+ *
229
+ * @param accounts - The accounts to set as selected.
230
+ */
231
+ setSelectedAccounts(accounts: Record<SnapId, AccountId[]>): Promise<void>;
225
232
  /**
226
233
  * Return an internal account object for a given address.
227
234
  *
@@ -1 +1 @@
1
- {"version":3,"file":"SnapKeyring.d.cts","sourceRoot":"","sources":["../src/SnapKeyring.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SnapKeyring.d.cts","sourceRoot":"","sources":["../src/SnapKeyring.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import type { TypedTransaction } from "@ethereumjs/tx";
2
2
  import type { TypedDataV1, TypedMessage } from "@metamask/eth-sig-util";
3
3
  import { SignTypedDataVersion } from "@metamask/eth-sig-util";
4
- import type { KeyringAccount, KeyringExecutionContext, EthBaseTransaction, EthBaseUserOperation, EthUserOperation, EthUserOperationPatch, ResolvedAccountAddress, CaipChainId } from "@metamask/keyring-api";
4
+ import type { KeyringAccount, KeyringExecutionContext, EthBaseTransaction, EthBaseUserOperation, EthUserOperation, EthUserOperationPatch, ResolvedAccountAddress, CaipChainId, GetSelectedAccountsResponse } from "@metamask/keyring-api";
5
5
  import { type InternalAccount } from "@metamask/keyring-internal-api";
6
6
  import type { AccountId, JsonRpcRequest } from "@metamask/keyring-utils";
7
7
  import type { SnapId } from "@metamask/snaps-sdk";
@@ -33,6 +33,7 @@ export type SnapKeyringCallbacks = {
33
33
  addressExists(address: string): Promise<boolean>;
34
34
  addAccount(address: string, snapId: SnapId, handleUserInput: (accepted: boolean) => Promise<void>, onceSaved: Promise<AccountId>, accountNameSuggestion?: string, internalOptions?: SnapKeyringInternalOptions): Promise<void>;
35
35
  removeAccount(address: string, snapId: SnapId, handleUserInput: (accepted: boolean) => Promise<void>): Promise<void>;
36
+ getSelectedAccounts(snapId: SnapId): Promise<GetSelectedAccountsResponse>;
36
37
  redirectUser(snapId: SnapId, url: string, message: string): Promise<void>;
37
38
  };
38
39
  /**
@@ -222,6 +223,12 @@ export declare class SnapKeyring {
222
223
  * @param address - Address of the account to remove.
223
224
  */
224
225
  removeAccount(address: string): Promise<void>;
226
+ /**
227
+ * Set the selected accounts.
228
+ *
229
+ * @param accounts - The accounts to set as selected.
230
+ */
231
+ setSelectedAccounts(accounts: Record<SnapId, AccountId[]>): Promise<void>;
225
232
  /**
226
233
  * Return an internal account object for a given address.
227
234
  *
@@ -1 +1 @@
1
- {"version":3,"file":"SnapKeyring.d.mts","sourceRoot":"","sources":["../src/SnapKeyring.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SnapKeyring.d.mts","sourceRoot":"","sources":["../src/SnapKeyring.ts"],"names":[],"mappings":"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"}
@@ -12,10 +12,10 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
12
12
  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");
13
13
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
14
14
  };
15
- var _SnapKeyring_instances, _SnapKeyring_messenger, _SnapKeyring_snapClient, _SnapKeyring_accounts, _SnapKeyring_requests, _SnapKeyring_options, _SnapKeyring_callbacks, _SnapKeyring_isAnyAccountTypeAllowed, _SnapKeyring_getKeyringVersion, _SnapKeyring_getInternalOptions, _SnapKeyring_handleAccountCreated, _SnapKeyring_handleAccountUpdated, _SnapKeyring_handleAccountDeleted, _SnapKeyring_handleRequestApproved, _SnapKeyring_handleRequestRejected, _SnapKeyring_rePublishAccountEvent, _SnapKeyring_handleAccountBalancesUpdated, _SnapKeyring_handleAccountAssetListUpdated, _SnapKeyring_handleAccountTransactionsUpdated, _SnapKeyring_getAccount, _SnapKeyring_submitRequest, _SnapKeyring_submitSnapRequestForVersion, _SnapKeyring_submitSnapRequest, _SnapKeyring_hasMethod, _SnapKeyring_createRequestPromise, _SnapKeyring_clearRequestPromise, _SnapKeyring_handleSyncResponse, _SnapKeyring_handleAsyncResponse, _SnapKeyring_sanitizeRedirectUrl, _SnapKeyring_validateRedirectUrl, _SnapKeyring_deleteAccount, _SnapKeyring_resolveAddress, _SnapKeyring_getSnap, _SnapKeyring_getSnapMetadata, _SnapKeyring_getSnapAllowedOrigins;
15
+ var _SnapKeyring_instances, _SnapKeyring_messenger, _SnapKeyring_snapClient, _SnapKeyring_accounts, _SnapKeyring_requests, _SnapKeyring_options, _SnapKeyring_callbacks, _SnapKeyring_isAnyAccountTypeAllowed, _SnapKeyring_getKeyringVersion, _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_submitSnapRequestForVersion, _SnapKeyring_submitSnapRequest, _SnapKeyring_hasMethod, _SnapKeyring_createRequestPromise, _SnapKeyring_clearRequestPromise, _SnapKeyring_handleSyncResponse, _SnapKeyring_handleAsyncResponse, _SnapKeyring_sanitizeRedirectUrl, _SnapKeyring_validateRedirectUrl, _SnapKeyring_deleteAccount, _SnapKeyring_resolveAddress, _SnapKeyring_getSnap, _SnapKeyring_getSnapMetadata, _SnapKeyring_getSnapAllowedOrigins;
16
16
  import { TransactionFactory } from "@ethereumjs/tx";
17
17
  import { SignTypedDataVersion } from "@metamask/eth-sig-util";
18
- import { EthBytesStruct, EthMethod, EthBaseUserOperationStruct, EthUserOperationPatchStruct, isEvmAccountType, KeyringEvent, AccountAssetListUpdatedEventStruct, AccountBalancesUpdatedEventStruct, AccountTransactionsUpdatedEventStruct, AnyAccountType } from "@metamask/keyring-api";
18
+ import { EthBytesStruct, EthMethod, EthBaseUserOperationStruct, EthUserOperationPatchStruct, isEvmAccountType, KeyringEvent, AccountAssetListUpdatedEventStruct, AccountBalancesUpdatedEventStruct, AccountTransactionsUpdatedEventStruct, AnyAccountType, KeyringMethod, GetSelectedAccountsRequestStruct } from "@metamask/keyring-api";
19
19
  import { KeyringVersion, toKeyringRequestV1 } from "@metamask/keyring-internal-api";
20
20
  import { KeyringInternalSnapClient } from "@metamask/keyring-internal-snap-client";
21
21
  import { strictMask } from "@metamask/keyring-utils";
@@ -141,6 +141,9 @@ export class SnapKeyring {
141
141
  case `${KeyringEvent.AccountTransactionsUpdated}`: {
142
142
  return __classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_handleAccountTransactionsUpdated).call(this, snapId, message);
143
143
  }
144
+ case `${KeyringMethod.GetSelectedAccounts}`: {
145
+ return __classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_handleGetSelectedAccounts).call(this, snapId, message);
146
+ }
144
147
  default:
145
148
  throw new Error(`Method not supported: ${message.method}`);
146
149
  }
@@ -487,6 +490,16 @@ export class SnapKeyring {
487
490
  const { account, snapId } = __classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_resolveAddress).call(this, address);
488
491
  await __classPrivateFieldGet(this, _SnapKeyring_instances, "m", _SnapKeyring_deleteAccount).call(this, snapId, account);
489
492
  }
493
+ /**
494
+ * Set the selected accounts.
495
+ *
496
+ * @param accounts - The accounts to set as selected.
497
+ */
498
+ async setSelectedAccounts(accounts) {
499
+ for (const [snapId, accountIds] of Object.entries(accounts)) {
500
+ await __classPrivateFieldGet(this, _SnapKeyring_snapClient, "f").withSnapId(snapId).setSelectedAccounts(accountIds);
501
+ }
502
+ }
490
503
  /**
491
504
  * Return an internal account object for a given address.
492
505
  *
@@ -706,6 +719,17 @@ async function _SnapKeyring_handleAccountDeleted(snapId, message) {
706
719
  }
707
720
  });
708
721
  return null;
722
+ }, _SnapKeyring_handleGetSelectedAccounts =
723
+ /**
724
+ * Handle an Get Selected Accounts method call from a Snap.
725
+ *
726
+ * @param snapId - Snap ID.
727
+ * @param message - Method call message.
728
+ * @returns The selected accounts.
729
+ */
730
+ async function _SnapKeyring_handleGetSelectedAccounts(snapId, message) {
731
+ assert(message, GetSelectedAccountsRequestStruct);
732
+ return __classPrivateFieldGet(this, _SnapKeyring_callbacks, "f").getSelectedAccounts(snapId);
709
733
  }, _SnapKeyring_handleRequestApproved =
710
734
  /**
711
735
  * Handle an Request Approved event from a Snap.
@@ -1 +1 @@
1
- {"version":3,"file":"SnapKeyring.mjs","sourceRoot":"","sources":["../src/SnapKeyring.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-redundant-type-constituents */\n// This rule seems to be triggering a false positive. Possibly eslint is not\n// inferring the `EthMethod`, `BtcMethod`, and `InternalAccount` types correctly.\n\nimport type { TypedTransaction } from '@ethereumjs/tx';\nimport { TransactionFactory } from '@ethereumjs/tx';\nimport type { ExtractEventPayload } from '@metamask/base-controller';\nimport type { TypedDataV1, TypedMessage } from '@metamask/eth-sig-util';\nimport { SignTypedDataVersion } from '@metamask/eth-sig-util';\nimport type {\n KeyringAccount,\n KeyringExecutionContext,\n BtcMethod,\n EthBaseTransaction,\n EthBaseUserOperation,\n EthUserOperation,\n EthUserOperationPatch,\n ResolvedAccountAddress,\n CaipChainId,\n MetaMaskOptions,\n KeyringRequest,\n KeyringResponse,\n} from '@metamask/keyring-api';\nimport {\n EthBytesStruct,\n EthMethod,\n EthBaseUserOperationStruct,\n EthUserOperationPatchStruct,\n isEvmAccountType,\n KeyringEvent,\n AccountAssetListUpdatedEventStruct,\n AccountBalancesUpdatedEventStruct,\n AccountTransactionsUpdatedEventStruct,\n AnyAccountType,\n} from '@metamask/keyring-api';\nimport {\n KeyringVersion,\n toKeyringRequestV1,\n type InternalAccount,\n} from '@metamask/keyring-internal-api';\nimport { KeyringInternalSnapClient } from '@metamask/keyring-internal-snap-client';\nimport type { AccountId, JsonRpcRequest } from '@metamask/keyring-utils';\nimport { strictMask } from '@metamask/keyring-utils';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { type Snap } from '@metamask/snaps-utils';\nimport { assert, mask, object, string } from '@metamask/superstruct';\nimport type { Hex, Json, SemVerVersion } from '@metamask/utils';\nimport {\n bigIntToHex,\n hasProperty,\n KnownCaipNamespace,\n toCaipChainId,\n} from '@metamask/utils';\nimport { v4 as uuid } from 'uuid';\n\nimport { transformAccount } from './account';\nimport { DeferredPromise } from './DeferredPromise';\nimport {\n AccountCreatedEventStruct,\n AccountUpdatedEventStruct,\n AccountDeletedEventStruct,\n RequestApprovedEventStruct,\n RequestRejectedEventStruct,\n} from './events';\nimport { projectLogger as log } from './logger';\nimport { isAccountV1, migrateAccountV1 } from './migrations';\nimport {\n getInternalOptionsOf,\n type SnapKeyringInternalOptions,\n} from './options';\nimport { SnapIdMap } from './SnapIdMap';\nimport type {\n SnapKeyringEvents,\n SnapKeyringMessenger,\n} from './SnapKeyringMessenger';\nimport { SNAP_KEYRING_NAME } from './SnapKeyringMessenger';\nimport type { SnapMessage } from './types';\nimport { SnapMessageStruct } from './types';\nimport {\n equalsIgnoreCase,\n sanitizeUrl,\n throwError,\n toJson,\n unique,\n} from './util';\nimport { getKeyringVersionFromPlatform } from './versions';\n\nexport const SNAP_KEYRING_TYPE = 'Snap Keyring';\n\n// TODO: to be removed when this is added to the keyring-api\n\ntype AccountMethod = EthMethod | BtcMethod;\n\n/**\n * Snap keyring state.\n *\n * This state is persisted by the keyring controller and passed to the Snap\n * keyring when it's created.\n */\nexport type KeyringState = {\n accounts: Record<string, { account: KeyringAccount; snapId: SnapId }>;\n};\n\n/**\n * Snap keyring callbacks.\n *\n * These callbacks are used to interact with other components.\n */\nexport type SnapKeyringCallbacks = {\n saveState: () => Promise<void>;\n\n addressExists(address: string): Promise<boolean>;\n\n addAccount(\n address: string,\n snapId: SnapId,\n handleUserInput: (accepted: boolean) => Promise<void>,\n onceSaved: Promise<AccountId>,\n accountNameSuggestion?: string,\n internalOptions?: SnapKeyringInternalOptions,\n ): Promise<void>;\n\n removeAccount(\n address: string,\n snapId: SnapId,\n handleUserInput: (accepted: boolean) => Promise<void>,\n ): Promise<void>;\n\n redirectUser(snapId: SnapId, url: string, message: string): Promise<void>;\n};\n\n/**\n * Callback type to filter unknown account ID from a mapping account ID mapping.\n */\ntype FilterAccountIdFunction = <Entry>(\n accountMapping: Record<AccountId, Entry>,\n) => Record<AccountId, Entry>;\n\n/**\n * Normalize account's address.\n *\n * @param account - The account.\n * @returns The normalized account address.\n */\nfunction normalizeAccountAddress(account: KeyringAccount): string {\n // FIXME: Is it required to lowercase the address here? For now we'll keep this behavior\n // only for Ethereum addresses and use the original address for other non-EVM accounts.\n // For example, Solana addresses are case-sensitives.\n return isEvmAccountType(account.type)\n ? account.address.toLowerCase()\n : account.address;\n}\n\n/**\n * Keyring bridge implementation to support Snaps.\n */\nexport class SnapKeyring {\n static type: string = SNAP_KEYRING_TYPE;\n\n type: string;\n\n // Name and state are required for modular initialisation.\n name: typeof SNAP_KEYRING_NAME = SNAP_KEYRING_NAME;\n\n state = null;\n\n /**\n * Messenger to dispatch requests to the Snaps controller.\n */\n readonly #messenger: SnapKeyringMessenger;\n\n /**\n * Client used to call the Snap keyring.\n */\n readonly #snapClient: KeyringInternalSnapClient;\n\n /**\n * Mapping between account IDs and an object that contains the associated\n * account object and Snap ID.\n */\n #accounts: SnapIdMap<{\n account: KeyringAccount;\n snapId: SnapId;\n }>;\n\n /**\n * Mapping between request IDs and their deferred promises.\n */\n readonly #requests: SnapIdMap<{\n promise: DeferredPromise<any>;\n snapId: SnapId;\n }>;\n\n /**\n * Mapping between internal options, a correlation ID and a Snap ID.\n */\n readonly #options: SnapIdMap<{\n options: SnapKeyringInternalOptions;\n snapId: SnapId;\n // TODO: Add TTL to avoid having too many \"leaking\" internal options.\n }>;\n\n /**\n * Callbacks used to interact with other components.\n */\n readonly #callbacks: SnapKeyringCallbacks;\n\n /**\n * Whether to allow the creation and update of generic accounts.\n *\n * Account deletion is not affected by this flag and is always allowed.\n */\n readonly #isAnyAccountTypeAllowed: boolean;\n\n /**\n * Create a new Snap keyring.\n *\n * @param options - Constructor options.\n * @param options.messenger - Snap keyring messenger.\n * @param options.callbacks - Callbacks used to interact with other components.\n * @param options.isAnyAccountTypeAllowed - Whether to allow the `AnyAccountType` generic account type.\n * @returns A new Snap keyring.\n */\n constructor({\n messenger,\n callbacks,\n isAnyAccountTypeAllowed = false,\n }: {\n messenger: SnapKeyringMessenger;\n callbacks: SnapKeyringCallbacks;\n isAnyAccountTypeAllowed?: boolean;\n }) {\n this.type = SnapKeyring.type;\n this.#messenger = messenger;\n this.#snapClient = new KeyringInternalSnapClient({ messenger });\n this.#requests = new SnapIdMap();\n this.#accounts = new SnapIdMap();\n this.#options = new SnapIdMap();\n this.#callbacks = callbacks;\n this.#isAnyAccountTypeAllowed = isAnyAccountTypeAllowed;\n }\n\n /**\n * Gets keyring's version for a given Snap.\n *\n * @param snapId - The Snap ID.\n * @returns The Snap's keyring version.\n */\n #getKeyringVersion(snapId: SnapId): KeyringVersion {\n return getKeyringVersionFromPlatform((version: SemVerVersion) => {\n return this.#messenger.call(\n 'SnapController:isMinimumPlatformVersion',\n snapId,\n version,\n );\n });\n }\n\n /**\n * Get internal options given a correlation ID.\n *\n * NOTE: The associated options will be deleted automatically.\n *\n * @param snapId - Snap ID\n * @param correlationId - Correlation ID associated with the internal options.\n * @returns Internal options if found, `undefined` otherwise.\n */\n #getInternalOptions(\n snapId: SnapId,\n correlationId: string | undefined,\n ): SnapKeyringInternalOptions | undefined {\n if (correlationId) {\n // We still need to check if the correlation ID is valid and associated to\n // some internal options.\n //\n // NOTE: `found` will be `undefined` if a Snap tried to use a correlation ID that\n // belongs to another Snap ID. However, if a Snap starts 2 parallel flow (which\n // will results in 2 different correlation IDs), we won't be able to prevent\n // the Snap from swapping/mixing up those correlation IDs he owns.\n const found = this.#options.pop(snapId, correlationId);\n\n if (found) {\n return found.options;\n }\n\n console.warn(\n `SnapKeyring - Received unmapped correlation ID: \"${correlationId}\"`,\n );\n }\n\n return undefined;\n }\n\n /**\n * Handle an Account Created event from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountCreated(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountCreatedEventStruct);\n const {\n metamask, // Used for internal options.\n account: newAccountFromEvent,\n accountNameSuggestion,\n displayAccountNameSuggestion,\n displayConfirmation,\n } = message.params;\n\n // READ THIS CAREFULLY:\n // ------------------------------------------------------------------------\n // The account creation flow is now asynchronous. We expect the Snap to\n // first create the account data and then fire the \"AccountCreated\" event.\n\n // Potentially migrate the account.\n const account = transformAccount(newAccountFromEvent);\n\n // The `AnyAccountType.Account` generic account type is allowed only during\n // development, so we check whether it's allowed before continuing.\n if (\n !this.#isAnyAccountTypeAllowed &&\n account.type === AnyAccountType.Account\n ) {\n throw new Error(`Cannot create generic account '${account.id}'`);\n }\n\n // The UI still uses the account address to identify accounts, so we need\n // to block the creation of duplicate accounts for now to prevent accounts\n // from being overwritten.\n const address = normalizeAccountAddress(account);\n if (await this.#callbacks.addressExists(address)) {\n throw new Error(`Account address '${address}' already exists`);\n }\n\n // A Snap could try to create an account with a different address but with\n // an existing ID, so the above test only is not enough.\n if (this.#accounts.has(snapId, account.id)) {\n throw new Error(`Account '${account.id}' already exists`);\n }\n\n // A deferred promise that will be resolved once the Snap keyring has saved\n // its internal state.\n // This part of the flow is run asynchronously, so we have no other way of\n // letting the MetaMask client that this \"save\" has been run.\n // NOTE: Another way of fixing that could be to rely on events through the\n // messenger maybe?\n const onceSaved = new DeferredPromise<AccountId>();\n\n // Add the account to the keyring, but wait for the MetaMask client to\n // approve the account creation first.\n await this.#callbacks.addAccount(\n address,\n snapId,\n // This callback is passed to the MetaMask client, it will be called whenever\n // the end user will accept or not the account creation.\n async (accepted: boolean) => {\n if (accepted) {\n // We consider the account to be created on the Snap keyring only if\n // the user accepted it. Meaning that the Snap MIGHT HAVE created the\n // account on its own state, but the Snap keyring MIGHT NOT HAVE it yet.\n //\n // e.g The account creation dialog crashed on MetaMask, this callback\n // will never be called, but the Snap still has the account.\n this.#accounts.set(account.id, { account, snapId });\n\n // This is the \"true async part\". We do not `await` for this call, mainly\n // because this callback will persist the account on the client side\n // (through the `AccountsController`).\n //\n // Since this will happen after the Snap account creation and Snap\n // event, if anything goes wrong, we will delete the account by\n // calling `deleteAccount` on the Snap.\n // eslint-disable-next-line no-void\n void this.#callbacks\n .saveState()\n .then(() => {\n // This allows the MetaMask client to be \"notified\" when then\n // Snap keyring has truly persisted its state. From there, we should\n // be able to use the account (e.g. to display account creation\n // confirmation dialogs).\n onceSaved.resolve(account.id);\n })\n .catch(async (error) => {\n // FIXME: There's a potential race condition here, if the Snap did\n // not persist the account yet (this should mostly be for older Snaps).\n await this.#deleteAccount(snapId, account);\n\n // This allows the MetaMask client to be \"notified\" that something went\n // wrong with the Snap keyring. (e.g. useful to display account creation\n // error dialogs).\n onceSaved.reject(error);\n });\n }\n },\n onceSaved.promise,\n accountNameSuggestion,\n getInternalOptionsOf([\n // 1. We use the internal options from the Snap keyring.\n this.#getInternalOptions(snapId, metamask?.correlationId) ?? {},\n // 2. We use the ones coming from the Snap.\n {\n displayConfirmation,\n displayAccountNameSuggestion,\n },\n ]),\n );\n\n return null;\n }\n\n /**\n * Handle an Account Updated event from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountUpdated(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountUpdatedEventStruct);\n const { account: newAccountFromEvent } = message.params;\n const { account: oldAccount } =\n this.#accounts.get(snapId, newAccountFromEvent.id) ??\n throwError(`Account '${newAccountFromEvent.id}' not found`);\n\n // Potentially migrate the account.\n const newAccount = transformAccount(newAccountFromEvent);\n\n // The `AnyAccountType.Account` generic account type is allowed only during\n // development, so we check whether it's allowed before continuing.\n //\n // An account cannot be updated if the `isAnyAccountTypeAllowed` flag is\n // set to `false` and the new or old account is a generic account.\n const isGenericAccountInvolved =\n newAccount.type === AnyAccountType.Account ||\n oldAccount.type === AnyAccountType.Account;\n\n if (!this.#isAnyAccountTypeAllowed && isGenericAccountInvolved) {\n throw new Error(`Cannot update generic account '${newAccount.id}'`);\n }\n\n // The address of the account cannot be changed. In the future, we will\n // support changing the address of an account since it will be required to\n // support UTXO-based chains.\n if (!equalsIgnoreCase(oldAccount.address, newAccount.address)) {\n throw new Error(`Cannot change address of account '${newAccount.id}'`);\n }\n\n this.#accounts.set(newAccount.id, { account: newAccount, snapId });\n await this.#callbacks.saveState();\n return null;\n }\n\n /**\n * Handle an Account Deleted event from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountDeleted(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountDeletedEventStruct);\n const { id } = message.params;\n const entry = this.#accounts.get(snapId, id);\n\n // We can ignore the case where the account was already removed from the\n // keyring, making the deletion idempotent.\n //\n // This happens when the keyring calls the Snap to delete an account, and\n // the Snap calls the keyring back with an `AccountDeleted` event.\n if (entry === undefined) {\n return null;\n }\n\n // At this point we know that the account exists, so we can safely\n // destructure it.\n const { account } = entry;\n\n await this.#callbacks.removeAccount(\n normalizeAccountAddress(account),\n snapId,\n async (accepted) => {\n if (accepted) {\n await this.#callbacks.saveState();\n }\n },\n );\n return null;\n }\n\n /**\n * Handle an Request Approved event from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleRequestApproved(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, RequestApprovedEventStruct);\n const { id, result } = message.params;\n const { promise } =\n this.#requests.get(snapId, id) ?? throwError(`Request '${id}' not found`);\n\n this.#requests.delete(snapId, id);\n promise.resolve(result);\n return null;\n }\n\n /**\n * Handle an Request Rejected event from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleRequestRejected(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, RequestRejectedEventStruct);\n const { id } = message.params;\n const { promise } =\n this.#requests.get(snapId, id) ?? throwError(`Request '${id}' not found`);\n\n this.#requests.delete(snapId, id);\n promise.reject(new Error(`Request rejected by user or snap.`));\n return null;\n }\n\n /**\n * Re-publish an account event.\n *\n * @param snapId - Snap ID.\n * @param event - The event type. This is a unique identifier for this event.\n * @param filteredEventCallback - A callback that returns the event to re-publish. This callback takes a filtering\n * function as parameter that can be used to filter out account ID that do not belong to this Snap ID.\n * @template EventType - A Snap keyring event type.\n * @returns `null`.\n */\n async #rePublishAccountEvent<EventType extends SnapKeyringEvents['type']>(\n snapId: SnapId,\n event: EventType,\n filteredEventCallback: (\n filter: FilterAccountIdFunction,\n ) => ExtractEventPayload<SnapKeyringEvents, EventType>,\n ): Promise<null> {\n // This callback can be used to filter out the accounts that no longer exists on the Snap (fail-safe) or to\n // prevent other Snaps from updating accounts they do not own.\n const filter: FilterAccountIdFunction = <Entry>(\n accountMapping: Record<AccountId, Entry>,\n ): Record<AccountId, Entry> => {\n return Object.entries(accountMapping).reduce<Record<AccountId, Entry>>(\n (filtered, [accountId, entry]) => {\n if (this.#accounts.has(snapId, accountId)) {\n // If the Snap owns this account, we can use it.\n filtered[accountId] = entry;\n } else {\n // Otherwise, we just filter it out and log it (for debugging/tracking purposes).\n console.warn(\n `SnapKeyring - ${event} - Found an unknown account ID \"${accountId}\" for Snap ID \"${snapId}\". Skipping.`,\n );\n }\n\n return filtered;\n },\n {},\n );\n };\n\n this.#messenger.publish(event, ...filteredEventCallback(filter));\n return null;\n }\n\n /**\n * Handle a balances updated event from a Snap.\n *\n * @param snapId - ID of the Snap.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountBalancesUpdated(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountBalancesUpdatedEventStruct);\n\n const event = message.params;\n return this.#rePublishAccountEvent(\n snapId,\n 'SnapKeyring:accountBalancesUpdated',\n (filter) => {\n event.balances = filter(event.balances);\n return [event];\n },\n );\n }\n\n /**\n * Handle a asset list updated event from a Snap.\n *\n * @param snapId - ID of the Snap.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountAssetListUpdated(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountAssetListUpdatedEventStruct);\n\n const event = message.params;\n return this.#rePublishAccountEvent(\n snapId,\n 'SnapKeyring:accountAssetListUpdated',\n (filter) => {\n event.assets = filter(event.assets);\n return [event];\n },\n );\n }\n\n /**\n * Handle a transactions updated event from a Snap.\n *\n * @param snapId - ID of the Snap.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountTransactionsUpdated(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountTransactionsUpdatedEventStruct);\n\n const event = message.params;\n return this.#rePublishAccountEvent(\n snapId,\n 'SnapKeyring:accountTransactionsUpdated',\n (filter) => {\n event.transactions = filter(event.transactions);\n return [event];\n },\n );\n }\n\n /**\n * Handle a message from a Snap.\n *\n * @param snapId - ID of the Snap.\n * @param message - Message sent by the Snap.\n * @returns The execution result.\n */\n async handleKeyringSnapMessage(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<Json> {\n assert(message, SnapMessageStruct);\n switch (message.method) {\n case `${KeyringEvent.AccountCreated}`: {\n return this.#handleAccountCreated(snapId, message);\n }\n\n case `${KeyringEvent.AccountUpdated}`: {\n return this.#handleAccountUpdated(snapId, message);\n }\n\n case `${KeyringEvent.AccountDeleted}`: {\n return this.#handleAccountDeleted(snapId, message);\n }\n\n case `${KeyringEvent.RequestApproved}`: {\n return this.#handleRequestApproved(snapId, message);\n }\n\n case `${KeyringEvent.RequestRejected}`: {\n return this.#handleRequestRejected(snapId, message);\n }\n\n // Assets related events:\n case `${KeyringEvent.AccountBalancesUpdated}`: {\n return this.#handleAccountBalancesUpdated(snapId, message);\n }\n\n case `${KeyringEvent.AccountAssetListUpdated}`: {\n return this.#handleAccountAssetListUpdated(snapId, message);\n }\n\n case `${KeyringEvent.AccountTransactionsUpdated}`: {\n return this.#handleAccountTransactionsUpdated(snapId, message);\n }\n\n default:\n throw new Error(`Method not supported: ${message.method}`);\n }\n }\n\n /**\n * Serialize the keyring state.\n *\n * @returns Serialized keyring state.\n */\n async serialize(): Promise<KeyringState> {\n return {\n accounts: this.#accounts.toObject(),\n };\n }\n\n /**\n * Deserialize the keyring state into this keyring.\n *\n * @param state - Serialized keyring state.\n */\n async deserialize(state: KeyringState | undefined): Promise<void> {\n // If the state is undefined, it means that this is a new keyring, so we\n // don't need to do anything.\n if (state === undefined) {\n return;\n }\n\n // Running Snap keyring migrations. We might have some accounts that have a\n // different \"version\" than the one we expect.\n //\n // In this case, we \"transform\" then directly when deserializing to convert\n // them in the final account version.\n const accounts: KeyringState['accounts'] = {};\n for (const [snapId, entry] of Object.entries(state.accounts)) {\n // V1 accounts are missing the scopes.\n if (isAccountV1(entry.account)) {\n console.info(\n `SnapKeyring - Found a KeyringAccountV1, migrating to V2: ${entry.account.id}`,\n );\n accounts[snapId] = {\n ...entry,\n account: migrateAccountV1(entry.account),\n };\n } else {\n accounts[snapId] = entry;\n }\n }\n\n this.#accounts = SnapIdMap.fromObject(accounts);\n }\n\n /**\n * Get an account and its associated Snap ID from its ID.\n *\n * @param id - Account ID.\n * @throws An error if the account could not be found.\n * @returns The account associated with the given account ID in this keyring.\n */\n #getAccount(id: string): { account: KeyringAccount; snapId: SnapId } {\n const found = [...this.#accounts.values()].find(\n (entry) => entry.account.id === id,\n );\n\n if (!found) {\n throw new Error(`Unable to get account: unknown account ID: '${id}'`);\n }\n return found;\n }\n\n /**\n * Get the addresses of the accounts in this keyring.\n *\n * @returns The addresses of the accounts in this keyring.\n */\n async getAccounts(): Promise<string[]> {\n return unique(\n [...this.#accounts.values()].map(({ account }) =>\n normalizeAccountAddress(account),\n ),\n );\n }\n\n /**\n * Get the addresses of the accounts associated with a given Snap.\n *\n * @param snapId - Snap ID to filter by.\n * @returns The addresses of the accounts associated with the given Snap.\n */\n async getAccountsBySnapId(snapId: SnapId): Promise<string[]> {\n return unique(\n [...this.#accounts.values()]\n .filter(({ snapId: accountSnapId }) => accountSnapId === snapId)\n .map(({ account }) => normalizeAccountAddress(account)),\n );\n }\n\n /**\n * Create an account.\n *\n * @param snapId - Snap ID to create the account for.\n * @param options - Account creation options. Differs between keyrings.\n * @param internalOptions - Internal Snap keyring options.\n * @returns The account object.\n */\n async createAccount(\n snapId: SnapId,\n options: Record<string, Json>,\n internalOptions?: SnapKeyringInternalOptions,\n ): Promise<KeyringAccount> {\n const client = new KeyringInternalSnapClient({\n messenger: this.#messenger,\n snapId,\n });\n\n // The 'metamask' field is reserved, so we have to prevent use of it on\n // the \"normal options\".\n const reserved = 'metamask';\n if (hasProperty(options, reserved)) {\n throw new Error(\n `The '${reserved}' property is reserved for internal use`,\n );\n }\n\n // Those internal options are optional. If not set, we avoid registering anything\n // to internal map (to avoid holding resources for nothing). In this case, it's\n // just a normal `keyring_createAccount`.\n if (!internalOptions) {\n return await client.createAccount(options);\n }\n\n // A unique ID to identify this execution flow which allows to associate the\n // internal options and the current `keyring_createAccount` flow for that Snap.\n const correlationId = uuid();\n\n // Register those internal options to use them during the `keyring_createAccount`\n // flow.\n this.#options.set(correlationId, {\n snapId,\n options: internalOptions,\n });\n\n return await client.createAccount({\n ...options,\n // Create internal options context.\n // NOTE: Those options HAVE TO be re-emitted during the `notify:accountCreated` event.\n ...({\n metamask: {\n correlationId,\n },\n } as MetaMaskOptions),\n });\n }\n\n /**\n * Checks if a Snap ID is known from the keyring.\n *\n * @param snapId - Snap ID.\n * @returns `true` if the Snap ID is known, `false` otherwise.\n */\n hasSnapId(snapId: SnapId): boolean {\n return this.#accounts.hasSnapId(snapId);\n }\n\n /**\n * Resolve the Snap account's address associated from a signing request.\n *\n * @param snapId - Snap ID.\n * @param scope - CAIP-2 chain ID.\n * @param request - Signing request object.\n * @throws An error if the Snap ID is not known from the keyring.\n * @returns The resolved address if found, `null` otherwise.\n */\n async resolveAccountAddress(\n snapId: SnapId,\n scope: CaipChainId,\n request: JsonRpcRequest,\n ): Promise<ResolvedAccountAddress | null> {\n // We do check that the incoming Snap ID is known by the keyring.\n if (!this.hasSnapId(snapId)) {\n throw new Error(\n `Unable to resolve account address: unknown Snap ID: ${snapId}`,\n );\n }\n\n return await this.#snapClient\n .withSnapId(snapId)\n .resolveAccountAddress(scope, request);\n }\n\n /**\n * Submit a request to a Snap from an account ID.\n *\n * This request cannot be an asynchronous keyring request.\n *\n * @param opts - Request options.\n * @param opts.origin - Send origin.\n * @param opts.account - Account ID.\n * @param opts.method - Method to call.\n * @param opts.params - Method parameters.\n * @param opts.scope - Selected chain ID (CAIP-2).\n * @returns Promise that resolves to the result of the method call.\n */\n async submitRequest({\n origin,\n account: accountId,\n method,\n params,\n scope,\n }: {\n origin: string;\n // NOTE: We use `account` here rather than `id` to avoid ambiguity with a \"request ID\".\n // We already use this same field name for `KeyringAccount`s.\n account: string;\n method: string;\n params?: Json[] | Record<string, Json>;\n scope: string;\n }): Promise<Json> {\n const { account, snapId } = this.#getAccount(accountId);\n\n return await this.#submitSnapRequest({\n origin,\n snapId,\n account,\n method: method as AccountMethod,\n params,\n scope,\n // For non-EVM (in the context of the multichain API and SIP-26), we enforce responses\n // to be synchronous.\n noPending: true,\n });\n }\n\n /**\n * Submit a request to a Snap from an account address.\n *\n * @param opts - Request options.\n * @param opts.origin - Sender origin.\n * @param opts.address - Account address.\n * @param opts.method - Method to call.\n * @param opts.params - Method parameters.\n * @param opts.scope - Selected chain ID (CAIP-2).\n * @param opts.noPending - Whether the response is allowed to be pending.\n * @returns Promise that resolves to the result of the method call.\n */\n async #submitRequest<Response extends Json>({\n origin,\n address,\n method,\n params,\n scope = '',\n noPending = false,\n }: {\n origin: string;\n address: string;\n method: string;\n params?: Json[] | Record<string, Json>;\n scope?: string;\n noPending?: boolean;\n }): Promise<Response> {\n const { account, snapId } = this.#resolveAddress(address);\n\n return await this.#submitSnapRequest<Response>({\n origin,\n snapId,\n account,\n method: method as AccountMethod,\n params,\n scope,\n noPending,\n });\n }\n\n /**\n * Submits a request to a Snap and fix-up the payload depending on the version currently supported.\n *\n * @param options - The options for the Snap request.\n * @param options.version - The supported keyring version for the Snap.\n * @param options.snapId - The Snap ID to submit the request to.\n * @param options.request - The Snap request.\n * @returns A promise that resolves to the keyring response from the Snap.\n */\n async #submitSnapRequestForVersion({\n snapId,\n version,\n request,\n }: {\n snapId: SnapId;\n version: KeyringVersion;\n request: KeyringRequest;\n }): Promise<KeyringResponse> {\n // Get specific client for that Snap.\n const client = this.#snapClient.withSnapId(snapId);\n\n if (version === KeyringVersion.V1) {\n return await client.submitRequestV1(toKeyringRequestV1(request));\n }\n\n return await client.submitRequest(request);\n }\n\n /**\n * Submits a request to a Snap.\n *\n * @param options - The options for the Snap request.\n * @param options.origin - The sender origin.\n * @param options.snapId - The Snap ID to submit the request to.\n * @param options.account - The account to use for the request.\n * @param options.method - The Ethereum method to call.\n * @param options.params - The parameters to pass to the method, can be undefined.\n * @param options.scope - The chain ID to use for the request, can be an empty string.\n * @param options.noPending - Whether the response is allowed to be pending.\n * @returns A promise that resolves to the keyring response from the Snap.\n * @throws An error if the Snap fails to respond or if there's an issue with the request submission.\n */\n async #submitSnapRequest<Response extends Json>({\n origin,\n snapId,\n account,\n method,\n params,\n scope,\n noPending,\n }: {\n origin: string;\n snapId: SnapId;\n account: KeyringAccount;\n method: AccountMethod;\n params?: Json[] | Record<string, Json> | undefined;\n scope: string;\n noPending: boolean;\n }): Promise<Response> {\n if (!this.#hasMethod(account, method)) {\n throw new Error(\n `Method '${method}' not supported for account ${account.address}`,\n );\n }\n\n // Will both catch `undefined` and \"empty\" origins.\n if (!origin?.trim()) {\n throw new Error('An `origin` is required');\n }\n\n // Generate a new random request ID to keep track of the request execution flow.\n const requestId = uuid();\n\n // Create the promise before calling the Snap to prevent a race condition\n // where the Snap responds before we have a chance to create it.\n const requestPromise = this.#createRequestPromise<Response>(\n requestId,\n snapId,\n );\n\n try {\n const version = this.#getKeyringVersion(snapId);\n\n const request = {\n id: requestId,\n origin,\n scope,\n account: account.id,\n request: {\n method,\n ...(params !== undefined && { params }),\n },\n };\n\n log('Submit Snap request: ', request);\n\n const response = await this.#submitSnapRequestForVersion({\n version,\n snapId,\n request,\n });\n\n // Some methods, like the ones used to prepare and patch user operations,\n // require the Snap to answer synchronously in order to work with the\n // confirmation flow. This check lets the caller enforce this behavior.\n if (noPending && response.pending) {\n throw new Error(\n `Request '${requestId}' to Snap '${snapId}' is pending and noPending is true.`,\n );\n }\n\n // If the Snap answers synchronously, the promise must be removed from the\n // map to prevent a leak.\n if (!response.pending) {\n return this.#handleSyncResponse<Response>(response, requestId, snapId);\n }\n\n // If the Snap answers asynchronously, we will inform the user with a redirect\n if (response.redirect?.message || response.redirect?.url) {\n await this.#handleAsyncResponse(response.redirect, snapId);\n }\n\n return requestPromise.promise;\n } catch (error) {\n log('Snap Request failed: ', { requestId });\n\n // If the Snap failed to respond, delete the promise to prevent a leak.\n this.#clearRequestPromise(requestId, snapId);\n throw error;\n }\n }\n\n /**\n * Check if an account supports the given method.\n *\n * @param account - The account object to check for method support.\n * @param method - The Ethereum method to validate.\n * @returns `true` if the method is supported, `false` otherwise.\n */\n #hasMethod(account: KeyringAccount, method: AccountMethod): boolean {\n return (account.methods as AccountMethod[]).includes(method);\n }\n\n /**\n * Creates a promise for a request and adds it to the map of requests.\n *\n * @param requestId - The unique identifier for the request.\n * @param snapId - The Snap ID associated with the request.\n * @returns A DeferredPromise instance.\n */\n #createRequestPromise<Response>(\n requestId: string,\n snapId: SnapId,\n ): DeferredPromise<Response> {\n const promise = new DeferredPromise<Response>();\n this.#requests.set(requestId, { promise, snapId });\n return promise;\n }\n\n /**\n * Clear a promise for a request and delete it from the map of requests.\n *\n * @param requestId - The unique identifier for the request.\n * @param snapId - The Snap ID associated with the request.\n */\n #clearRequestPromise(requestId: string, snapId: SnapId): void {\n this.#requests.delete(snapId, requestId);\n }\n\n /**\n * Handles the synchronous response from a Snap. If the response indicates the request is not pending, it removes the request from the map.\n *\n * @param response - The response from the Snap.\n * @param response.pending - A boolean indicating if the request is pending should always be false in this context.\n * @param response.result - The result data from the Snap response.\n * @param requestId - The unique identifier for the request.\n * @param snapId - The Snap ID associated with the request.\n * @returns The result from the Snap response.\n */\n #handleSyncResponse<Response extends Json>(\n response: { pending: false; result: Json },\n requestId: string,\n snapId: SnapId,\n ): Response {\n this.#requests.delete(snapId, requestId);\n // We consider `Response` to be compatible with `result` here.\n return response.result as Response;\n }\n\n /**\n * Handles the async redirect and response from a Snap. Validates the redirect URL and informs the user with a message and URL if provided.\n *\n * @param redirect - The redirect information including message and URL.\n * @param redirect.message - The message to show to the user if provided.\n * @param redirect.url - The URL to redirect the user to if provided.\n * @param snapId - The Snap ID associated with the request.\n * @throws An error if the redirect URL is not an allowed origin for the Snap.\n */\n async #handleAsyncResponse(\n redirect: { message?: string; url?: string },\n snapId: SnapId,\n ): Promise<void> {\n const { message = '', url: redirectUrl = '' } = redirect;\n const url = this.#sanitizeRedirectUrl(redirectUrl);\n if (url) {\n this.#validateRedirectUrl(url, snapId);\n }\n await this.#callbacks.redirectUser(snapId, url, message);\n }\n\n /**\n * Sanitize a redirect URL.\n *\n * @param url - The URL to sanitize.\n * @returns The new sanitized redirect URL.\n */\n #sanitizeRedirectUrl(url: string): string {\n // We do check if the URL is empty or not since the Snap might not returns any URL at all.\n return url ? sanitizeUrl(url) : url;\n }\n\n /**\n * Validates if the redirect URL is in the Snap's allowed origins.\n *\n * @param url - The URL to validate.\n * @param snapId - The Snap ID to check allowed origins for.\n * @throws An error if the URL's origin is not in the Snap's allowed origins.\n */\n #validateRedirectUrl(url: string, snapId: SnapId): void {\n const { origin } = new URL(url);\n const snap = this.#getSnap(snapId);\n if (!snap) {\n throw new Error(`Snap '${snapId}' not found.`);\n }\n const allowedOrigins = this.#getSnapAllowedOrigins(snap);\n if (!allowedOrigins.includes(origin)) {\n throw new Error(\n `Redirect URL domain '${origin}' is not an allowed origin by snap '${snapId}'`,\n );\n }\n }\n\n /**\n * Sign a transaction.\n *\n * @param address - Sender's address.\n * @param transaction - Transaction.\n * @param _opts - Transaction options (not used).\n * @returns A promise that resolves to the signed transaction.\n */\n async signTransaction(\n address: string,\n transaction: TypedTransaction,\n _opts = {},\n ): Promise<Json | TypedTransaction> {\n const chainId = transaction.common.chainId();\n const tx = toJson({\n ...transaction.toJSON(),\n from: address,\n type: `0x${transaction.type.toString(16)}`,\n chainId: bigIntToHex(chainId),\n });\n\n const signedTx = await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.SignTransaction,\n params: [tx],\n scope: toCaipChainId(KnownCaipNamespace.Eip155, `${chainId}`),\n });\n\n // ! It's *** CRITICAL *** that we mask the signature here, otherwise the\n // ! Snap could overwrite the transaction.\n const signature = mask(\n signedTx,\n object({\n r: string(),\n s: string(),\n v: string(),\n }),\n );\n\n return TransactionFactory.fromTxData({\n ...(tx as Record<string, Json>),\n r: signature.r as Hex,\n s: signature.s as Hex,\n v: signature.v as Hex,\n });\n }\n\n /**\n * Sign a typed data message.\n *\n * @param address - Signer's address.\n * @param data - Data to sign.\n * @param opts - Signing options.\n * @returns The signature.\n */\n async signTypedData(\n address: string,\n data: Record<string, unknown>[] | TypedDataV1 | TypedMessage<any>,\n opts = { version: SignTypedDataVersion.V1 },\n ): Promise<string> {\n const methods = {\n [SignTypedDataVersion.V1]: EthMethod.SignTypedDataV1,\n [SignTypedDataVersion.V3]: EthMethod.SignTypedDataV3,\n [SignTypedDataVersion.V4]: EthMethod.SignTypedDataV4,\n };\n\n // Use 'V1' by default to match other keyring implementations. V1 will be\n // used if the version is not specified or not supported.\n const method = methods[opts.version] || EthMethod.SignTypedDataV1;\n\n // Extract chain ID as if it was a typed message (as defined by EIP-712), if\n // input is not a typed message, then chain ID will be undefined!\n const chainId = (data as TypedMessage<any>).domain?.chainId;\n\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method,\n params: toJson<Json[]>([address, data]),\n ...(chainId === undefined\n ? {}\n : {\n scope: toCaipChainId(KnownCaipNamespace.Eip155, `${chainId}`),\n }),\n }),\n EthBytesStruct,\n );\n }\n\n /**\n * Sign a message.\n *\n * @param address - Signer's address.\n * @param hash - Data to sign.\n * @returns The signature.\n */\n async signMessage(address: string, hash: any): Promise<string> {\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.Sign,\n params: toJson<Json[]>([address, hash]),\n }),\n EthBytesStruct,\n );\n }\n\n /**\n * Sign a personal message.\n *\n * Note: KeyringController says this should return a Buffer but it actually\n * expects a string.\n *\n * @param address - Signer's address.\n * @param data - Data to sign.\n * @returns Promise of the signature.\n */\n async signPersonalMessage(address: string, data: any): Promise<string> {\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.PersonalSign,\n params: toJson<Json[]>([data, address]),\n }),\n EthBytesStruct,\n );\n }\n\n /**\n * Convert a base transaction to a base UserOperation.\n *\n * @param address - Address of the sender.\n * @param transactions - Base transactions to include in the UserOperation.\n * @param context - Keyring execution context.\n * @returns A pseudo-UserOperation that can be used to construct a real.\n */\n async prepareUserOperation(\n address: string,\n transactions: EthBaseTransaction[],\n context: KeyringExecutionContext,\n ): Promise<EthBaseUserOperation> {\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.PrepareUserOperation,\n params: toJson<Json[]>(transactions),\n noPending: true,\n // We assume the chain ID is already well formatted\n scope: toCaipChainId(KnownCaipNamespace.Eip155, context.chainId),\n }),\n EthBaseUserOperationStruct,\n );\n }\n\n /**\n * Patches properties of a UserOperation. Currently, only the\n * `paymasterAndData` can be patched.\n *\n * @param address - Address of the sender.\n * @param userOp - UserOperation to patch.\n * @param context - Keyring execution context.\n * @returns A patch to apply to the UserOperation.\n */\n async patchUserOperation(\n address: string,\n userOp: EthUserOperation,\n context: KeyringExecutionContext,\n ): Promise<EthUserOperationPatch> {\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.PatchUserOperation,\n params: toJson<Json[]>([userOp]),\n noPending: true,\n // We assume the chain ID is already well formatted\n scope: toCaipChainId(KnownCaipNamespace.Eip155, context.chainId),\n }),\n EthUserOperationPatchStruct,\n );\n }\n\n /**\n * Signs an UserOperation.\n *\n * @param address - Address of the sender.\n * @param userOp - UserOperation to sign.\n * @param context - Leyring execution context.\n * @returns The signature of the UserOperation.\n */\n async signUserOperation(\n address: string,\n userOp: EthUserOperation,\n context: KeyringExecutionContext,\n ): Promise<string> {\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.SignUserOperation,\n params: toJson<Json[]>([userOp]),\n // We assume the chain ID is already well formatted\n scope: toCaipChainId(KnownCaipNamespace.Eip155, context.chainId),\n }),\n EthBytesStruct,\n );\n }\n\n /**\n * Gets the private data associated with the given address so\n * that it may be exported.\n *\n * If this keyring contains duplicate public keys the first\n * matching address is exported.\n *\n * Used by the UI to export an account.\n *\n * @param _address - Address of the account to export.\n */\n exportAccount(_address: string): [Uint8Array, Json] | undefined {\n throw new Error('Exporting accounts from snaps is not supported.');\n }\n\n /**\n * Removes the account matching the given address.\n *\n * @param address - Address of the account to remove.\n */\n async removeAccount(address: string): Promise<void> {\n const { account, snapId } = this.#resolveAddress(address);\n\n await this.#deleteAccount(snapId, account);\n }\n\n /**\n * Removes an account.\n *\n * @param snapId - Snap ID.\n * @param account - Account to delete.\n */\n async #deleteAccount(snapId: SnapId, account: KeyringAccount): Promise<void> {\n // Always remove the account from the maps, even if the Snap is going to\n // fail to delete it.\n this.#accounts.delete(snapId, account.id);\n\n try {\n await this.#snapClient.withSnapId(snapId).deleteAccount(account.id);\n } catch (error) {\n // If the Snap failed to delete the account, log the error and continue\n // with the account deletion, otherwise the account will be stuck in the\n // keyring.\n console.error(\n `Account '${account.address}' may not have been removed from snap '${snapId}':`,\n error,\n );\n }\n }\n\n /**\n * Resolve an address to an account and Snap ID.\n *\n * @param address - Address of the account to resolve.\n * @returns Account and Snap ID. Throws if the account or Snap ID is not\n * found.\n */\n #resolveAddress(address: string): {\n account: KeyringAccount;\n snapId: SnapId;\n } {\n return (\n [...this.#accounts.values()].find(({ account }) =>\n equalsIgnoreCase(account.address, address),\n ) ?? throwError(`Account '${address}' not found`)\n );\n }\n\n /**\n * Get the Snap associated with the given Snap ID.\n *\n * @param snapId - Snap ID.\n * @returns The Snap or undefined if the Snap cannot be found.\n */\n #getSnap(snapId: SnapId): Snap | undefined {\n return this.#messenger.call('SnapController:get', snapId);\n }\n\n /**\n * Get the metadata of a Snap keyring account.\n *\n * @param snapId - Snap ID.\n * @returns The Snap metadata or undefined if the Snap cannot be found.\n */\n #getSnapMetadata(\n snapId: SnapId,\n ): InternalAccount['metadata']['snap'] | undefined {\n const snap = this.#getSnap(snapId);\n return snap\n ? { id: snapId, name: snap.manifest.proposedName, enabled: snap.enabled }\n : undefined;\n }\n\n /**\n * Get the allowed origins of a Snap.\n *\n * @param snap - Snap.\n * @returns The allowed origins of the Snap.\n */\n #getSnapAllowedOrigins(snap: Snap): string[] {\n return (\n snap.manifest.initialPermissions['endowment:keyring']?.allowedOrigins ??\n []\n );\n }\n\n /**\n * Return an internal account object for a given address.\n *\n * @param address - Address of the account to return.\n * @returns An internal account object for the given address.\n */\n getAccountByAddress(address: string): InternalAccount | undefined {\n const accounts = this.listAccounts();\n return accounts.find(({ address: accountAddress }) =>\n equalsIgnoreCase(accountAddress, address),\n );\n }\n\n /**\n * List all Snap keyring accounts.\n *\n * @returns An array containing all Snap keyring accounts.\n */\n listAccounts(): InternalAccount[] {\n return [...this.#accounts.values()].map(({ account, snapId }) => {\n const snap = this.#getSnapMetadata(snapId);\n return {\n ...account,\n // TODO: Do not convert the address to lowercase.\n //\n // This is a workaround to support the current UI which expects the\n // account address to be lowercase. This workaround should be removed\n // once we migrated the UI to use the account ID instead of the account\n // address.\n //\n // NOTE: We convert the address only for EVM accounts, see\n // `normalizeAccountAddress`.\n address: normalizeAccountAddress(account),\n metadata: {\n name: '',\n importTime: 0,\n keyring: {\n type: this.type,\n },\n ...(snap !== undefined && { snap }),\n },\n };\n });\n }\n}\n"]}
1
+ {"version":3,"file":"SnapKeyring.mjs","sourceRoot":"","sources":["../src/SnapKeyring.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-redundant-type-constituents */\n// This rule seems to be triggering a false positive. Possibly eslint is not\n// inferring the `EthMethod`, `BtcMethod`, and `InternalAccount` types correctly.\n\nimport type { TypedTransaction } from '@ethereumjs/tx';\nimport { TransactionFactory } from '@ethereumjs/tx';\nimport type { ExtractEventPayload } from '@metamask/base-controller';\nimport type { TypedDataV1, TypedMessage } from '@metamask/eth-sig-util';\nimport { SignTypedDataVersion } from '@metamask/eth-sig-util';\nimport type {\n KeyringAccount,\n KeyringExecutionContext,\n BtcMethod,\n EthBaseTransaction,\n EthBaseUserOperation,\n EthUserOperation,\n EthUserOperationPatch,\n ResolvedAccountAddress,\n CaipChainId,\n MetaMaskOptions,\n KeyringRequest,\n KeyringResponse,\n GetSelectedAccountsResponse,\n} from '@metamask/keyring-api';\nimport {\n EthBytesStruct,\n EthMethod,\n EthBaseUserOperationStruct,\n EthUserOperationPatchStruct,\n isEvmAccountType,\n KeyringEvent,\n AccountAssetListUpdatedEventStruct,\n AccountBalancesUpdatedEventStruct,\n AccountTransactionsUpdatedEventStruct,\n AnyAccountType,\n KeyringMethod,\n GetSelectedAccountsRequestStruct,\n} from '@metamask/keyring-api';\nimport {\n KeyringVersion,\n toKeyringRequestV1,\n type InternalAccount,\n} from '@metamask/keyring-internal-api';\nimport { KeyringInternalSnapClient } from '@metamask/keyring-internal-snap-client';\nimport type { AccountId, JsonRpcRequest } from '@metamask/keyring-utils';\nimport { strictMask } from '@metamask/keyring-utils';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { type Snap } from '@metamask/snaps-utils';\nimport { assert, mask, object, string } from '@metamask/superstruct';\nimport type { Hex, Json, SemVerVersion } from '@metamask/utils';\nimport {\n bigIntToHex,\n hasProperty,\n KnownCaipNamespace,\n toCaipChainId,\n} from '@metamask/utils';\nimport { v4 as uuid } from 'uuid';\n\nimport { transformAccount } from './account';\nimport { DeferredPromise } from './DeferredPromise';\nimport {\n AccountCreatedEventStruct,\n AccountUpdatedEventStruct,\n AccountDeletedEventStruct,\n RequestApprovedEventStruct,\n RequestRejectedEventStruct,\n} from './events';\nimport { projectLogger as log } from './logger';\nimport { isAccountV1, migrateAccountV1 } from './migrations';\nimport {\n getInternalOptionsOf,\n type SnapKeyringInternalOptions,\n} from './options';\nimport { SnapIdMap } from './SnapIdMap';\nimport type {\n SnapKeyringEvents,\n SnapKeyringMessenger,\n} from './SnapKeyringMessenger';\nimport { SNAP_KEYRING_NAME } from './SnapKeyringMessenger';\nimport type { SnapMessage } from './types';\nimport { SnapMessageStruct } from './types';\nimport {\n equalsIgnoreCase,\n sanitizeUrl,\n throwError,\n toJson,\n unique,\n} from './util';\nimport { getKeyringVersionFromPlatform } from './versions';\n\nexport const SNAP_KEYRING_TYPE = 'Snap Keyring';\n\n// TODO: to be removed when this is added to the keyring-api\n\ntype AccountMethod = EthMethod | BtcMethod;\n\n/**\n * Snap keyring state.\n *\n * This state is persisted by the keyring controller and passed to the Snap\n * keyring when it's created.\n */\nexport type KeyringState = {\n accounts: Record<string, { account: KeyringAccount; snapId: SnapId }>;\n};\n\n/**\n * Snap keyring callbacks.\n *\n * These callbacks are used to interact with other components.\n */\nexport type SnapKeyringCallbacks = {\n saveState: () => Promise<void>;\n\n addressExists(address: string): Promise<boolean>;\n\n addAccount(\n address: string,\n snapId: SnapId,\n handleUserInput: (accepted: boolean) => Promise<void>,\n onceSaved: Promise<AccountId>,\n accountNameSuggestion?: string,\n internalOptions?: SnapKeyringInternalOptions,\n ): Promise<void>;\n\n removeAccount(\n address: string,\n snapId: SnapId,\n handleUserInput: (accepted: boolean) => Promise<void>,\n ): Promise<void>;\n\n getSelectedAccounts(snapId: SnapId): Promise<GetSelectedAccountsResponse>;\n\n redirectUser(snapId: SnapId, url: string, message: string): Promise<void>;\n};\n\n/**\n * Callback type to filter unknown account ID from a mapping account ID mapping.\n */\ntype FilterAccountIdFunction = <Entry>(\n accountMapping: Record<AccountId, Entry>,\n) => Record<AccountId, Entry>;\n\n/**\n * Normalize account's address.\n *\n * @param account - The account.\n * @returns The normalized account address.\n */\nfunction normalizeAccountAddress(account: KeyringAccount): string {\n // FIXME: Is it required to lowercase the address here? For now we'll keep this behavior\n // only for Ethereum addresses and use the original address for other non-EVM accounts.\n // For example, Solana addresses are case-sensitives.\n return isEvmAccountType(account.type)\n ? account.address.toLowerCase()\n : account.address;\n}\n\n/**\n * Keyring bridge implementation to support Snaps.\n */\nexport class SnapKeyring {\n static type: string = SNAP_KEYRING_TYPE;\n\n type: string;\n\n // Name and state are required for modular initialisation.\n name: typeof SNAP_KEYRING_NAME = SNAP_KEYRING_NAME;\n\n state = null;\n\n /**\n * Messenger to dispatch requests to the Snaps controller.\n */\n readonly #messenger: SnapKeyringMessenger;\n\n /**\n * Client used to call the Snap keyring.\n */\n readonly #snapClient: KeyringInternalSnapClient;\n\n /**\n * Mapping between account IDs and an object that contains the associated\n * account object and Snap ID.\n */\n #accounts: SnapIdMap<{\n account: KeyringAccount;\n snapId: SnapId;\n }>;\n\n /**\n * Mapping between request IDs and their deferred promises.\n */\n readonly #requests: SnapIdMap<{\n promise: DeferredPromise<any>;\n snapId: SnapId;\n }>;\n\n /**\n * Mapping between internal options, a correlation ID and a Snap ID.\n */\n readonly #options: SnapIdMap<{\n options: SnapKeyringInternalOptions;\n snapId: SnapId;\n // TODO: Add TTL to avoid having too many \"leaking\" internal options.\n }>;\n\n /**\n * Callbacks used to interact with other components.\n */\n readonly #callbacks: SnapKeyringCallbacks;\n\n /**\n * Whether to allow the creation and update of generic accounts.\n *\n * Account deletion is not affected by this flag and is always allowed.\n */\n readonly #isAnyAccountTypeAllowed: boolean;\n\n /**\n * Create a new Snap keyring.\n *\n * @param options - Constructor options.\n * @param options.messenger - Snap keyring messenger.\n * @param options.callbacks - Callbacks used to interact with other components.\n * @param options.isAnyAccountTypeAllowed - Whether to allow the `AnyAccountType` generic account type.\n * @returns A new Snap keyring.\n */\n constructor({\n messenger,\n callbacks,\n isAnyAccountTypeAllowed = false,\n }: {\n messenger: SnapKeyringMessenger;\n callbacks: SnapKeyringCallbacks;\n isAnyAccountTypeAllowed?: boolean;\n }) {\n this.type = SnapKeyring.type;\n this.#messenger = messenger;\n this.#snapClient = new KeyringInternalSnapClient({ messenger });\n this.#requests = new SnapIdMap();\n this.#accounts = new SnapIdMap();\n this.#options = new SnapIdMap();\n this.#callbacks = callbacks;\n this.#isAnyAccountTypeAllowed = isAnyAccountTypeAllowed;\n }\n\n /**\n * Gets keyring's version for a given Snap.\n *\n * @param snapId - The Snap ID.\n * @returns The Snap's keyring version.\n */\n #getKeyringVersion(snapId: SnapId): KeyringVersion {\n return getKeyringVersionFromPlatform((version: SemVerVersion) => {\n return this.#messenger.call(\n 'SnapController:isMinimumPlatformVersion',\n snapId,\n version,\n );\n });\n }\n\n /**\n * Get internal options given a correlation ID.\n *\n * NOTE: The associated options will be deleted automatically.\n *\n * @param snapId - Snap ID\n * @param correlationId - Correlation ID associated with the internal options.\n * @returns Internal options if found, `undefined` otherwise.\n */\n #getInternalOptions(\n snapId: SnapId,\n correlationId: string | undefined,\n ): SnapKeyringInternalOptions | undefined {\n if (correlationId) {\n // We still need to check if the correlation ID is valid and associated to\n // some internal options.\n //\n // NOTE: `found` will be `undefined` if a Snap tried to use a correlation ID that\n // belongs to another Snap ID. However, if a Snap starts 2 parallel flow (which\n // will results in 2 different correlation IDs), we won't be able to prevent\n // the Snap from swapping/mixing up those correlation IDs he owns.\n const found = this.#options.pop(snapId, correlationId);\n\n if (found) {\n return found.options;\n }\n\n console.warn(\n `SnapKeyring - Received unmapped correlation ID: \"${correlationId}\"`,\n );\n }\n\n return undefined;\n }\n\n /**\n * Handle an Account Created event from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountCreated(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountCreatedEventStruct);\n const {\n metamask, // Used for internal options.\n account: newAccountFromEvent,\n accountNameSuggestion,\n displayAccountNameSuggestion,\n displayConfirmation,\n } = message.params;\n\n // READ THIS CAREFULLY:\n // ------------------------------------------------------------------------\n // The account creation flow is now asynchronous. We expect the Snap to\n // first create the account data and then fire the \"AccountCreated\" event.\n\n // Potentially migrate the account.\n const account = transformAccount(newAccountFromEvent);\n\n // The `AnyAccountType.Account` generic account type is allowed only during\n // development, so we check whether it's allowed before continuing.\n if (\n !this.#isAnyAccountTypeAllowed &&\n account.type === AnyAccountType.Account\n ) {\n throw new Error(`Cannot create generic account '${account.id}'`);\n }\n\n // The UI still uses the account address to identify accounts, so we need\n // to block the creation of duplicate accounts for now to prevent accounts\n // from being overwritten.\n const address = normalizeAccountAddress(account);\n if (await this.#callbacks.addressExists(address)) {\n throw new Error(`Account address '${address}' already exists`);\n }\n\n // A Snap could try to create an account with a different address but with\n // an existing ID, so the above test only is not enough.\n if (this.#accounts.has(snapId, account.id)) {\n throw new Error(`Account '${account.id}' already exists`);\n }\n\n // A deferred promise that will be resolved once the Snap keyring has saved\n // its internal state.\n // This part of the flow is run asynchronously, so we have no other way of\n // letting the MetaMask client that this \"save\" has been run.\n // NOTE: Another way of fixing that could be to rely on events through the\n // messenger maybe?\n const onceSaved = new DeferredPromise<AccountId>();\n\n // Add the account to the keyring, but wait for the MetaMask client to\n // approve the account creation first.\n await this.#callbacks.addAccount(\n address,\n snapId,\n // This callback is passed to the MetaMask client, it will be called whenever\n // the end user will accept or not the account creation.\n async (accepted: boolean) => {\n if (accepted) {\n // We consider the account to be created on the Snap keyring only if\n // the user accepted it. Meaning that the Snap MIGHT HAVE created the\n // account on its own state, but the Snap keyring MIGHT NOT HAVE it yet.\n //\n // e.g The account creation dialog crashed on MetaMask, this callback\n // will never be called, but the Snap still has the account.\n this.#accounts.set(account.id, { account, snapId });\n\n // This is the \"true async part\". We do not `await` for this call, mainly\n // because this callback will persist the account on the client side\n // (through the `AccountsController`).\n //\n // Since this will happen after the Snap account creation and Snap\n // event, if anything goes wrong, we will delete the account by\n // calling `deleteAccount` on the Snap.\n // eslint-disable-next-line no-void\n void this.#callbacks\n .saveState()\n .then(() => {\n // This allows the MetaMask client to be \"notified\" when then\n // Snap keyring has truly persisted its state. From there, we should\n // be able to use the account (e.g. to display account creation\n // confirmation dialogs).\n onceSaved.resolve(account.id);\n })\n .catch(async (error) => {\n // FIXME: There's a potential race condition here, if the Snap did\n // not persist the account yet (this should mostly be for older Snaps).\n await this.#deleteAccount(snapId, account);\n\n // This allows the MetaMask client to be \"notified\" that something went\n // wrong with the Snap keyring. (e.g. useful to display account creation\n // error dialogs).\n onceSaved.reject(error);\n });\n }\n },\n onceSaved.promise,\n accountNameSuggestion,\n getInternalOptionsOf([\n // 1. We use the internal options from the Snap keyring.\n this.#getInternalOptions(snapId, metamask?.correlationId) ?? {},\n // 2. We use the ones coming from the Snap.\n {\n displayConfirmation,\n displayAccountNameSuggestion,\n },\n ]),\n );\n\n return null;\n }\n\n /**\n * Handle an Account Updated event from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountUpdated(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountUpdatedEventStruct);\n const { account: newAccountFromEvent } = message.params;\n const { account: oldAccount } =\n this.#accounts.get(snapId, newAccountFromEvent.id) ??\n throwError(`Account '${newAccountFromEvent.id}' not found`);\n\n // Potentially migrate the account.\n const newAccount = transformAccount(newAccountFromEvent);\n\n // The `AnyAccountType.Account` generic account type is allowed only during\n // development, so we check whether it's allowed before continuing.\n //\n // An account cannot be updated if the `isAnyAccountTypeAllowed` flag is\n // set to `false` and the new or old account is a generic account.\n const isGenericAccountInvolved =\n newAccount.type === AnyAccountType.Account ||\n oldAccount.type === AnyAccountType.Account;\n\n if (!this.#isAnyAccountTypeAllowed && isGenericAccountInvolved) {\n throw new Error(`Cannot update generic account '${newAccount.id}'`);\n }\n\n // The address of the account cannot be changed. In the future, we will\n // support changing the address of an account since it will be required to\n // support UTXO-based chains.\n if (!equalsIgnoreCase(oldAccount.address, newAccount.address)) {\n throw new Error(`Cannot change address of account '${newAccount.id}'`);\n }\n\n this.#accounts.set(newAccount.id, { account: newAccount, snapId });\n await this.#callbacks.saveState();\n return null;\n }\n\n /**\n * Handle an Account Deleted event from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountDeleted(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountDeletedEventStruct);\n const { id } = message.params;\n const entry = this.#accounts.get(snapId, id);\n\n // We can ignore the case where the account was already removed from the\n // keyring, making the deletion idempotent.\n //\n // This happens when the keyring calls the Snap to delete an account, and\n // the Snap calls the keyring back with an `AccountDeleted` event.\n if (entry === undefined) {\n return null;\n }\n\n // At this point we know that the account exists, so we can safely\n // destructure it.\n const { account } = entry;\n\n await this.#callbacks.removeAccount(\n normalizeAccountAddress(account),\n snapId,\n async (accepted) => {\n if (accepted) {\n await this.#callbacks.saveState();\n }\n },\n );\n return null;\n }\n\n /**\n * Handle an Get Selected Accounts method call from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Method call message.\n * @returns The selected accounts.\n */\n async #handleGetSelectedAccounts(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<GetSelectedAccountsResponse> {\n assert(message, GetSelectedAccountsRequestStruct);\n return this.#callbacks.getSelectedAccounts(snapId);\n }\n\n /**\n * Handle an Request Approved event from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleRequestApproved(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, RequestApprovedEventStruct);\n const { id, result } = message.params;\n const { promise } =\n this.#requests.get(snapId, id) ?? throwError(`Request '${id}' not found`);\n\n this.#requests.delete(snapId, id);\n promise.resolve(result);\n return null;\n }\n\n /**\n * Handle an Request Rejected event from a Snap.\n *\n * @param snapId - Snap ID.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleRequestRejected(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, RequestRejectedEventStruct);\n const { id } = message.params;\n const { promise } =\n this.#requests.get(snapId, id) ?? throwError(`Request '${id}' not found`);\n\n this.#requests.delete(snapId, id);\n promise.reject(new Error(`Request rejected by user or snap.`));\n return null;\n }\n\n /**\n * Re-publish an account event.\n *\n * @param snapId - Snap ID.\n * @param event - The event type. This is a unique identifier for this event.\n * @param filteredEventCallback - A callback that returns the event to re-publish. This callback takes a filtering\n * function as parameter that can be used to filter out account ID that do not belong to this Snap ID.\n * @template EventType - A Snap keyring event type.\n * @returns `null`.\n */\n async #rePublishAccountEvent<EventType extends SnapKeyringEvents['type']>(\n snapId: SnapId,\n event: EventType,\n filteredEventCallback: (\n filter: FilterAccountIdFunction,\n ) => ExtractEventPayload<SnapKeyringEvents, EventType>,\n ): Promise<null> {\n // This callback can be used to filter out the accounts that no longer exists on the Snap (fail-safe) or to\n // prevent other Snaps from updating accounts they do not own.\n const filter: FilterAccountIdFunction = <Entry>(\n accountMapping: Record<AccountId, Entry>,\n ): Record<AccountId, Entry> => {\n return Object.entries(accountMapping).reduce<Record<AccountId, Entry>>(\n (filtered, [accountId, entry]) => {\n if (this.#accounts.has(snapId, accountId)) {\n // If the Snap owns this account, we can use it.\n filtered[accountId] = entry;\n } else {\n // Otherwise, we just filter it out and log it (for debugging/tracking purposes).\n console.warn(\n `SnapKeyring - ${event} - Found an unknown account ID \"${accountId}\" for Snap ID \"${snapId}\". Skipping.`,\n );\n }\n\n return filtered;\n },\n {},\n );\n };\n\n this.#messenger.publish(event, ...filteredEventCallback(filter));\n return null;\n }\n\n /**\n * Handle a balances updated event from a Snap.\n *\n * @param snapId - ID of the Snap.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountBalancesUpdated(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountBalancesUpdatedEventStruct);\n\n const event = message.params;\n return this.#rePublishAccountEvent(\n snapId,\n 'SnapKeyring:accountBalancesUpdated',\n (filter) => {\n event.balances = filter(event.balances);\n return [event];\n },\n );\n }\n\n /**\n * Handle a asset list updated event from a Snap.\n *\n * @param snapId - ID of the Snap.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountAssetListUpdated(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountAssetListUpdatedEventStruct);\n\n const event = message.params;\n return this.#rePublishAccountEvent(\n snapId,\n 'SnapKeyring:accountAssetListUpdated',\n (filter) => {\n event.assets = filter(event.assets);\n return [event];\n },\n );\n }\n\n /**\n * Handle a transactions updated event from a Snap.\n *\n * @param snapId - ID of the Snap.\n * @param message - Event message.\n * @returns `null`.\n */\n async #handleAccountTransactionsUpdated(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<null> {\n assert(message, AccountTransactionsUpdatedEventStruct);\n\n const event = message.params;\n return this.#rePublishAccountEvent(\n snapId,\n 'SnapKeyring:accountTransactionsUpdated',\n (filter) => {\n event.transactions = filter(event.transactions);\n return [event];\n },\n );\n }\n\n /**\n * Handle a message from a Snap.\n *\n * @param snapId - ID of the Snap.\n * @param message - Message sent by the Snap.\n * @returns The execution result.\n */\n async handleKeyringSnapMessage(\n snapId: SnapId,\n message: SnapMessage,\n ): Promise<Json> {\n assert(message, SnapMessageStruct);\n switch (message.method) {\n case `${KeyringEvent.AccountCreated}`: {\n return this.#handleAccountCreated(snapId, message);\n }\n\n case `${KeyringEvent.AccountUpdated}`: {\n return this.#handleAccountUpdated(snapId, message);\n }\n\n case `${KeyringEvent.AccountDeleted}`: {\n return this.#handleAccountDeleted(snapId, message);\n }\n\n case `${KeyringEvent.RequestApproved}`: {\n return this.#handleRequestApproved(snapId, message);\n }\n\n case `${KeyringEvent.RequestRejected}`: {\n return this.#handleRequestRejected(snapId, message);\n }\n\n // Assets related events:\n case `${KeyringEvent.AccountBalancesUpdated}`: {\n return this.#handleAccountBalancesUpdated(snapId, message);\n }\n\n case `${KeyringEvent.AccountAssetListUpdated}`: {\n return this.#handleAccountAssetListUpdated(snapId, message);\n }\n\n case `${KeyringEvent.AccountTransactionsUpdated}`: {\n return this.#handleAccountTransactionsUpdated(snapId, message);\n }\n\n case `${KeyringMethod.GetSelectedAccounts}`: {\n return this.#handleGetSelectedAccounts(snapId, message);\n }\n\n default:\n throw new Error(`Method not supported: ${message.method}`);\n }\n }\n\n /**\n * Serialize the keyring state.\n *\n * @returns Serialized keyring state.\n */\n async serialize(): Promise<KeyringState> {\n return {\n accounts: this.#accounts.toObject(),\n };\n }\n\n /**\n * Deserialize the keyring state into this keyring.\n *\n * @param state - Serialized keyring state.\n */\n async deserialize(state: KeyringState | undefined): Promise<void> {\n // If the state is undefined, it means that this is a new keyring, so we\n // don't need to do anything.\n if (state === undefined) {\n return;\n }\n\n // Running Snap keyring migrations. We might have some accounts that have a\n // different \"version\" than the one we expect.\n //\n // In this case, we \"transform\" then directly when deserializing to convert\n // them in the final account version.\n const accounts: KeyringState['accounts'] = {};\n for (const [snapId, entry] of Object.entries(state.accounts)) {\n // V1 accounts are missing the scopes.\n if (isAccountV1(entry.account)) {\n console.info(\n `SnapKeyring - Found a KeyringAccountV1, migrating to V2: ${entry.account.id}`,\n );\n accounts[snapId] = {\n ...entry,\n account: migrateAccountV1(entry.account),\n };\n } else {\n accounts[snapId] = entry;\n }\n }\n\n this.#accounts = SnapIdMap.fromObject(accounts);\n }\n\n /**\n * Get an account and its associated Snap ID from its ID.\n *\n * @param id - Account ID.\n * @throws An error if the account could not be found.\n * @returns The account associated with the given account ID in this keyring.\n */\n #getAccount(id: string): { account: KeyringAccount; snapId: SnapId } {\n const found = [...this.#accounts.values()].find(\n (entry) => entry.account.id === id,\n );\n\n if (!found) {\n throw new Error(`Unable to get account: unknown account ID: '${id}'`);\n }\n return found;\n }\n\n /**\n * Get the addresses of the accounts in this keyring.\n *\n * @returns The addresses of the accounts in this keyring.\n */\n async getAccounts(): Promise<string[]> {\n return unique(\n [...this.#accounts.values()].map(({ account }) =>\n normalizeAccountAddress(account),\n ),\n );\n }\n\n /**\n * Get the addresses of the accounts associated with a given Snap.\n *\n * @param snapId - Snap ID to filter by.\n * @returns The addresses of the accounts associated with the given Snap.\n */\n async getAccountsBySnapId(snapId: SnapId): Promise<string[]> {\n return unique(\n [...this.#accounts.values()]\n .filter(({ snapId: accountSnapId }) => accountSnapId === snapId)\n .map(({ account }) => normalizeAccountAddress(account)),\n );\n }\n\n /**\n * Create an account.\n *\n * @param snapId - Snap ID to create the account for.\n * @param options - Account creation options. Differs between keyrings.\n * @param internalOptions - Internal Snap keyring options.\n * @returns The account object.\n */\n async createAccount(\n snapId: SnapId,\n options: Record<string, Json>,\n internalOptions?: SnapKeyringInternalOptions,\n ): Promise<KeyringAccount> {\n const client = new KeyringInternalSnapClient({\n messenger: this.#messenger,\n snapId,\n });\n\n // The 'metamask' field is reserved, so we have to prevent use of it on\n // the \"normal options\".\n const reserved = 'metamask';\n if (hasProperty(options, reserved)) {\n throw new Error(\n `The '${reserved}' property is reserved for internal use`,\n );\n }\n\n // Those internal options are optional. If not set, we avoid registering anything\n // to internal map (to avoid holding resources for nothing). In this case, it's\n // just a normal `keyring_createAccount`.\n if (!internalOptions) {\n return await client.createAccount(options);\n }\n\n // A unique ID to identify this execution flow which allows to associate the\n // internal options and the current `keyring_createAccount` flow for that Snap.\n const correlationId = uuid();\n\n // Register those internal options to use them during the `keyring_createAccount`\n // flow.\n this.#options.set(correlationId, {\n snapId,\n options: internalOptions,\n });\n\n return await client.createAccount({\n ...options,\n // Create internal options context.\n // NOTE: Those options HAVE TO be re-emitted during the `notify:accountCreated` event.\n ...({\n metamask: {\n correlationId,\n },\n } as MetaMaskOptions),\n });\n }\n\n /**\n * Checks if a Snap ID is known from the keyring.\n *\n * @param snapId - Snap ID.\n * @returns `true` if the Snap ID is known, `false` otherwise.\n */\n hasSnapId(snapId: SnapId): boolean {\n return this.#accounts.hasSnapId(snapId);\n }\n\n /**\n * Resolve the Snap account's address associated from a signing request.\n *\n * @param snapId - Snap ID.\n * @param scope - CAIP-2 chain ID.\n * @param request - Signing request object.\n * @throws An error if the Snap ID is not known from the keyring.\n * @returns The resolved address if found, `null` otherwise.\n */\n async resolveAccountAddress(\n snapId: SnapId,\n scope: CaipChainId,\n request: JsonRpcRequest,\n ): Promise<ResolvedAccountAddress | null> {\n // We do check that the incoming Snap ID is known by the keyring.\n if (!this.hasSnapId(snapId)) {\n throw new Error(\n `Unable to resolve account address: unknown Snap ID: ${snapId}`,\n );\n }\n\n return await this.#snapClient\n .withSnapId(snapId)\n .resolveAccountAddress(scope, request);\n }\n\n /**\n * Submit a request to a Snap from an account ID.\n *\n * This request cannot be an asynchronous keyring request.\n *\n * @param opts - Request options.\n * @param opts.origin - Send origin.\n * @param opts.account - Account ID.\n * @param opts.method - Method to call.\n * @param opts.params - Method parameters.\n * @param opts.scope - Selected chain ID (CAIP-2).\n * @returns Promise that resolves to the result of the method call.\n */\n async submitRequest({\n origin,\n account: accountId,\n method,\n params,\n scope,\n }: {\n origin: string;\n // NOTE: We use `account` here rather than `id` to avoid ambiguity with a \"request ID\".\n // We already use this same field name for `KeyringAccount`s.\n account: string;\n method: string;\n params?: Json[] | Record<string, Json>;\n scope: string;\n }): Promise<Json> {\n const { account, snapId } = this.#getAccount(accountId);\n\n return await this.#submitSnapRequest({\n origin,\n snapId,\n account,\n method: method as AccountMethod,\n params,\n scope,\n // For non-EVM (in the context of the multichain API and SIP-26), we enforce responses\n // to be synchronous.\n noPending: true,\n });\n }\n\n /**\n * Submit a request to a Snap from an account address.\n *\n * @param opts - Request options.\n * @param opts.origin - Sender origin.\n * @param opts.address - Account address.\n * @param opts.method - Method to call.\n * @param opts.params - Method parameters.\n * @param opts.scope - Selected chain ID (CAIP-2).\n * @param opts.noPending - Whether the response is allowed to be pending.\n * @returns Promise that resolves to the result of the method call.\n */\n async #submitRequest<Response extends Json>({\n origin,\n address,\n method,\n params,\n scope = '',\n noPending = false,\n }: {\n origin: string;\n address: string;\n method: string;\n params?: Json[] | Record<string, Json>;\n scope?: string;\n noPending?: boolean;\n }): Promise<Response> {\n const { account, snapId } = this.#resolveAddress(address);\n\n return await this.#submitSnapRequest<Response>({\n origin,\n snapId,\n account,\n method: method as AccountMethod,\n params,\n scope,\n noPending,\n });\n }\n\n /**\n * Submits a request to a Snap and fix-up the payload depending on the version currently supported.\n *\n * @param options - The options for the Snap request.\n * @param options.version - The supported keyring version for the Snap.\n * @param options.snapId - The Snap ID to submit the request to.\n * @param options.request - The Snap request.\n * @returns A promise that resolves to the keyring response from the Snap.\n */\n async #submitSnapRequestForVersion({\n snapId,\n version,\n request,\n }: {\n snapId: SnapId;\n version: KeyringVersion;\n request: KeyringRequest;\n }): Promise<KeyringResponse> {\n // Get specific client for that Snap.\n const client = this.#snapClient.withSnapId(snapId);\n\n if (version === KeyringVersion.V1) {\n return await client.submitRequestV1(toKeyringRequestV1(request));\n }\n\n return await client.submitRequest(request);\n }\n\n /**\n * Submits a request to a Snap.\n *\n * @param options - The options for the Snap request.\n * @param options.origin - The sender origin.\n * @param options.snapId - The Snap ID to submit the request to.\n * @param options.account - The account to use for the request.\n * @param options.method - The Ethereum method to call.\n * @param options.params - The parameters to pass to the method, can be undefined.\n * @param options.scope - The chain ID to use for the request, can be an empty string.\n * @param options.noPending - Whether the response is allowed to be pending.\n * @returns A promise that resolves to the keyring response from the Snap.\n * @throws An error if the Snap fails to respond or if there's an issue with the request submission.\n */\n async #submitSnapRequest<Response extends Json>({\n origin,\n snapId,\n account,\n method,\n params,\n scope,\n noPending,\n }: {\n origin: string;\n snapId: SnapId;\n account: KeyringAccount;\n method: AccountMethod;\n params?: Json[] | Record<string, Json> | undefined;\n scope: string;\n noPending: boolean;\n }): Promise<Response> {\n if (!this.#hasMethod(account, method)) {\n throw new Error(\n `Method '${method}' not supported for account ${account.address}`,\n );\n }\n\n // Will both catch `undefined` and \"empty\" origins.\n if (!origin?.trim()) {\n throw new Error('An `origin` is required');\n }\n\n // Generate a new random request ID to keep track of the request execution flow.\n const requestId = uuid();\n\n // Create the promise before calling the Snap to prevent a race condition\n // where the Snap responds before we have a chance to create it.\n const requestPromise = this.#createRequestPromise<Response>(\n requestId,\n snapId,\n );\n\n try {\n const version = this.#getKeyringVersion(snapId);\n\n const request = {\n id: requestId,\n origin,\n scope,\n account: account.id,\n request: {\n method,\n ...(params !== undefined && { params }),\n },\n };\n\n log('Submit Snap request: ', request);\n\n const response = await this.#submitSnapRequestForVersion({\n version,\n snapId,\n request,\n });\n\n // Some methods, like the ones used to prepare and patch user operations,\n // require the Snap to answer synchronously in order to work with the\n // confirmation flow. This check lets the caller enforce this behavior.\n if (noPending && response.pending) {\n throw new Error(\n `Request '${requestId}' to Snap '${snapId}' is pending and noPending is true.`,\n );\n }\n\n // If the Snap answers synchronously, the promise must be removed from the\n // map to prevent a leak.\n if (!response.pending) {\n return this.#handleSyncResponse<Response>(response, requestId, snapId);\n }\n\n // If the Snap answers asynchronously, we will inform the user with a redirect\n if (response.redirect?.message || response.redirect?.url) {\n await this.#handleAsyncResponse(response.redirect, snapId);\n }\n\n return requestPromise.promise;\n } catch (error) {\n log('Snap Request failed: ', { requestId });\n\n // If the Snap failed to respond, delete the promise to prevent a leak.\n this.#clearRequestPromise(requestId, snapId);\n throw error;\n }\n }\n\n /**\n * Check if an account supports the given method.\n *\n * @param account - The account object to check for method support.\n * @param method - The Ethereum method to validate.\n * @returns `true` if the method is supported, `false` otherwise.\n */\n #hasMethod(account: KeyringAccount, method: AccountMethod): boolean {\n return (account.methods as AccountMethod[]).includes(method);\n }\n\n /**\n * Creates a promise for a request and adds it to the map of requests.\n *\n * @param requestId - The unique identifier for the request.\n * @param snapId - The Snap ID associated with the request.\n * @returns A DeferredPromise instance.\n */\n #createRequestPromise<Response>(\n requestId: string,\n snapId: SnapId,\n ): DeferredPromise<Response> {\n const promise = new DeferredPromise<Response>();\n this.#requests.set(requestId, { promise, snapId });\n return promise;\n }\n\n /**\n * Clear a promise for a request and delete it from the map of requests.\n *\n * @param requestId - The unique identifier for the request.\n * @param snapId - The Snap ID associated with the request.\n */\n #clearRequestPromise(requestId: string, snapId: SnapId): void {\n this.#requests.delete(snapId, requestId);\n }\n\n /**\n * Handles the synchronous response from a Snap. If the response indicates the request is not pending, it removes the request from the map.\n *\n * @param response - The response from the Snap.\n * @param response.pending - A boolean indicating if the request is pending should always be false in this context.\n * @param response.result - The result data from the Snap response.\n * @param requestId - The unique identifier for the request.\n * @param snapId - The Snap ID associated with the request.\n * @returns The result from the Snap response.\n */\n #handleSyncResponse<Response extends Json>(\n response: { pending: false; result: Json },\n requestId: string,\n snapId: SnapId,\n ): Response {\n this.#requests.delete(snapId, requestId);\n // We consider `Response` to be compatible with `result` here.\n return response.result as Response;\n }\n\n /**\n * Handles the async redirect and response from a Snap. Validates the redirect URL and informs the user with a message and URL if provided.\n *\n * @param redirect - The redirect information including message and URL.\n * @param redirect.message - The message to show to the user if provided.\n * @param redirect.url - The URL to redirect the user to if provided.\n * @param snapId - The Snap ID associated with the request.\n * @throws An error if the redirect URL is not an allowed origin for the Snap.\n */\n async #handleAsyncResponse(\n redirect: { message?: string; url?: string },\n snapId: SnapId,\n ): Promise<void> {\n const { message = '', url: redirectUrl = '' } = redirect;\n const url = this.#sanitizeRedirectUrl(redirectUrl);\n if (url) {\n this.#validateRedirectUrl(url, snapId);\n }\n await this.#callbacks.redirectUser(snapId, url, message);\n }\n\n /**\n * Sanitize a redirect URL.\n *\n * @param url - The URL to sanitize.\n * @returns The new sanitized redirect URL.\n */\n #sanitizeRedirectUrl(url: string): string {\n // We do check if the URL is empty or not since the Snap might not returns any URL at all.\n return url ? sanitizeUrl(url) : url;\n }\n\n /**\n * Validates if the redirect URL is in the Snap's allowed origins.\n *\n * @param url - The URL to validate.\n * @param snapId - The Snap ID to check allowed origins for.\n * @throws An error if the URL's origin is not in the Snap's allowed origins.\n */\n #validateRedirectUrl(url: string, snapId: SnapId): void {\n const { origin } = new URL(url);\n const snap = this.#getSnap(snapId);\n if (!snap) {\n throw new Error(`Snap '${snapId}' not found.`);\n }\n const allowedOrigins = this.#getSnapAllowedOrigins(snap);\n if (!allowedOrigins.includes(origin)) {\n throw new Error(\n `Redirect URL domain '${origin}' is not an allowed origin by snap '${snapId}'`,\n );\n }\n }\n\n /**\n * Sign a transaction.\n *\n * @param address - Sender's address.\n * @param transaction - Transaction.\n * @param _opts - Transaction options (not used).\n * @returns A promise that resolves to the signed transaction.\n */\n async signTransaction(\n address: string,\n transaction: TypedTransaction,\n _opts = {},\n ): Promise<Json | TypedTransaction> {\n const chainId = transaction.common.chainId();\n const tx = toJson({\n ...transaction.toJSON(),\n from: address,\n type: `0x${transaction.type.toString(16)}`,\n chainId: bigIntToHex(chainId),\n });\n\n const signedTx = await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.SignTransaction,\n params: [tx],\n scope: toCaipChainId(KnownCaipNamespace.Eip155, `${chainId}`),\n });\n\n // ! It's *** CRITICAL *** that we mask the signature here, otherwise the\n // ! Snap could overwrite the transaction.\n const signature = mask(\n signedTx,\n object({\n r: string(),\n s: string(),\n v: string(),\n }),\n );\n\n return TransactionFactory.fromTxData({\n ...(tx as Record<string, Json>),\n r: signature.r as Hex,\n s: signature.s as Hex,\n v: signature.v as Hex,\n });\n }\n\n /**\n * Sign a typed data message.\n *\n * @param address - Signer's address.\n * @param data - Data to sign.\n * @param opts - Signing options.\n * @returns The signature.\n */\n async signTypedData(\n address: string,\n data: Record<string, unknown>[] | TypedDataV1 | TypedMessage<any>,\n opts = { version: SignTypedDataVersion.V1 },\n ): Promise<string> {\n const methods = {\n [SignTypedDataVersion.V1]: EthMethod.SignTypedDataV1,\n [SignTypedDataVersion.V3]: EthMethod.SignTypedDataV3,\n [SignTypedDataVersion.V4]: EthMethod.SignTypedDataV4,\n };\n\n // Use 'V1' by default to match other keyring implementations. V1 will be\n // used if the version is not specified or not supported.\n const method = methods[opts.version] || EthMethod.SignTypedDataV1;\n\n // Extract chain ID as if it was a typed message (as defined by EIP-712), if\n // input is not a typed message, then chain ID will be undefined!\n const chainId = (data as TypedMessage<any>).domain?.chainId;\n\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method,\n params: toJson<Json[]>([address, data]),\n ...(chainId === undefined\n ? {}\n : {\n scope: toCaipChainId(KnownCaipNamespace.Eip155, `${chainId}`),\n }),\n }),\n EthBytesStruct,\n );\n }\n\n /**\n * Sign a message.\n *\n * @param address - Signer's address.\n * @param hash - Data to sign.\n * @returns The signature.\n */\n async signMessage(address: string, hash: any): Promise<string> {\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.Sign,\n params: toJson<Json[]>([address, hash]),\n }),\n EthBytesStruct,\n );\n }\n\n /**\n * Sign a personal message.\n *\n * Note: KeyringController says this should return a Buffer but it actually\n * expects a string.\n *\n * @param address - Signer's address.\n * @param data - Data to sign.\n * @returns Promise of the signature.\n */\n async signPersonalMessage(address: string, data: any): Promise<string> {\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.PersonalSign,\n params: toJson<Json[]>([data, address]),\n }),\n EthBytesStruct,\n );\n }\n\n /**\n * Convert a base transaction to a base UserOperation.\n *\n * @param address - Address of the sender.\n * @param transactions - Base transactions to include in the UserOperation.\n * @param context - Keyring execution context.\n * @returns A pseudo-UserOperation that can be used to construct a real.\n */\n async prepareUserOperation(\n address: string,\n transactions: EthBaseTransaction[],\n context: KeyringExecutionContext,\n ): Promise<EthBaseUserOperation> {\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.PrepareUserOperation,\n params: toJson<Json[]>(transactions),\n noPending: true,\n // We assume the chain ID is already well formatted\n scope: toCaipChainId(KnownCaipNamespace.Eip155, context.chainId),\n }),\n EthBaseUserOperationStruct,\n );\n }\n\n /**\n * Patches properties of a UserOperation. Currently, only the\n * `paymasterAndData` can be patched.\n *\n * @param address - Address of the sender.\n * @param userOp - UserOperation to patch.\n * @param context - Keyring execution context.\n * @returns A patch to apply to the UserOperation.\n */\n async patchUserOperation(\n address: string,\n userOp: EthUserOperation,\n context: KeyringExecutionContext,\n ): Promise<EthUserOperationPatch> {\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.PatchUserOperation,\n params: toJson<Json[]>([userOp]),\n noPending: true,\n // We assume the chain ID is already well formatted\n scope: toCaipChainId(KnownCaipNamespace.Eip155, context.chainId),\n }),\n EthUserOperationPatchStruct,\n );\n }\n\n /**\n * Signs an UserOperation.\n *\n * @param address - Address of the sender.\n * @param userOp - UserOperation to sign.\n * @param context - Leyring execution context.\n * @returns The signature of the UserOperation.\n */\n async signUserOperation(\n address: string,\n userOp: EthUserOperation,\n context: KeyringExecutionContext,\n ): Promise<string> {\n return strictMask(\n await this.#submitRequest({\n origin: 'metamask',\n address,\n method: EthMethod.SignUserOperation,\n params: toJson<Json[]>([userOp]),\n // We assume the chain ID is already well formatted\n scope: toCaipChainId(KnownCaipNamespace.Eip155, context.chainId),\n }),\n EthBytesStruct,\n );\n }\n\n /**\n * Gets the private data associated with the given address so\n * that it may be exported.\n *\n * If this keyring contains duplicate public keys the first\n * matching address is exported.\n *\n * Used by the UI to export an account.\n *\n * @param _address - Address of the account to export.\n */\n exportAccount(_address: string): [Uint8Array, Json] | undefined {\n throw new Error('Exporting accounts from snaps is not supported.');\n }\n\n /**\n * Removes the account matching the given address.\n *\n * @param address - Address of the account to remove.\n */\n async removeAccount(address: string): Promise<void> {\n const { account, snapId } = this.#resolveAddress(address);\n\n await this.#deleteAccount(snapId, account);\n }\n\n /**\n * Removes an account.\n *\n * @param snapId - Snap ID.\n * @param account - Account to delete.\n */\n async #deleteAccount(snapId: SnapId, account: KeyringAccount): Promise<void> {\n // Always remove the account from the maps, even if the Snap is going to\n // fail to delete it.\n this.#accounts.delete(snapId, account.id);\n\n try {\n await this.#snapClient.withSnapId(snapId).deleteAccount(account.id);\n } catch (error) {\n // If the Snap failed to delete the account, log the error and continue\n // with the account deletion, otherwise the account will be stuck in the\n // keyring.\n console.error(\n `Account '${account.address}' may not have been removed from snap '${snapId}':`,\n error,\n );\n }\n }\n\n /**\n * Resolve an address to an account and Snap ID.\n *\n * @param address - Address of the account to resolve.\n * @returns Account and Snap ID. Throws if the account or Snap ID is not\n * found.\n */\n #resolveAddress(address: string): {\n account: KeyringAccount;\n snapId: SnapId;\n } {\n return (\n [...this.#accounts.values()].find(({ account }) =>\n equalsIgnoreCase(account.address, address),\n ) ?? throwError(`Account '${address}' not found`)\n );\n }\n\n /**\n * Set the selected accounts.\n *\n * @param accounts - The accounts to set as selected.\n */\n async setSelectedAccounts(\n accounts: Record<SnapId, AccountId[]>,\n ): Promise<void> {\n for (const [snapId, accountIds] of Object.entries(accounts) as [\n SnapId,\n AccountId[],\n ][]) {\n await this.#snapClient.withSnapId(snapId).setSelectedAccounts(accountIds);\n }\n }\n\n /**\n * Get the Snap associated with the given Snap ID.\n *\n * @param snapId - Snap ID.\n * @returns The Snap or undefined if the Snap cannot be found.\n */\n #getSnap(snapId: SnapId): Snap | undefined {\n return this.#messenger.call('SnapController:get', snapId);\n }\n\n /**\n * Get the metadata of a Snap keyring account.\n *\n * @param snapId - Snap ID.\n * @returns The Snap metadata or undefined if the Snap cannot be found.\n */\n #getSnapMetadata(\n snapId: SnapId,\n ): InternalAccount['metadata']['snap'] | undefined {\n const snap = this.#getSnap(snapId);\n return snap\n ? { id: snapId, name: snap.manifest.proposedName, enabled: snap.enabled }\n : undefined;\n }\n\n /**\n * Get the allowed origins of a Snap.\n *\n * @param snap - Snap.\n * @returns The allowed origins of the Snap.\n */\n #getSnapAllowedOrigins(snap: Snap): string[] {\n return (\n snap.manifest.initialPermissions['endowment:keyring']?.allowedOrigins ??\n []\n );\n }\n\n /**\n * Return an internal account object for a given address.\n *\n * @param address - Address of the account to return.\n * @returns An internal account object for the given address.\n */\n getAccountByAddress(address: string): InternalAccount | undefined {\n const accounts = this.listAccounts();\n return accounts.find(({ address: accountAddress }) =>\n equalsIgnoreCase(accountAddress, address),\n );\n }\n\n /**\n * List all Snap keyring accounts.\n *\n * @returns An array containing all Snap keyring accounts.\n */\n listAccounts(): InternalAccount[] {\n return [...this.#accounts.values()].map(({ account, snapId }) => {\n const snap = this.#getSnapMetadata(snapId);\n return {\n ...account,\n // TODO: Do not convert the address to lowercase.\n //\n // This is a workaround to support the current UI which expects the\n // account address to be lowercase. This workaround should be removed\n // once we migrated the UI to use the account ID instead of the account\n // address.\n //\n // NOTE: We convert the address only for EVM accounts, see\n // `normalizeAccountAddress`.\n address: normalizeAccountAddress(account),\n metadata: {\n name: '',\n importTime: 0,\n keyring: {\n type: this.type,\n },\n ...(snap !== undefined && { snap }),\n },\n };\n });\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/eth-snap-keyring",
3
- "version": "17.2.0-45ee2b8",
3
+ "version": "17.2.0-50e2da5",
4
4
  "description": "Snaps keyring bridge.",
5
5
  "repository": {
6
6
  "type": "git",