@metamask/connect-multichain 0.7.0 → 0.8.0

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +13 -1
  2. package/dist/browser/es/connect-multichain.d.mts +1 -0
  3. package/dist/browser/es/connect-multichain.mjs +96 -51
  4. package/dist/browser/es/connect-multichain.mjs.map +1 -1
  5. package/dist/browser/es/metafile-esm.json +1 -1
  6. package/dist/browser/iife/connect-multichain.d.ts +1 -0
  7. package/dist/browser/iife/connect-multichain.js +2651 -4959
  8. package/dist/browser/iife/connect-multichain.js.map +1 -1
  9. package/dist/browser/iife/metafile-iife.json +1 -1
  10. package/dist/browser/umd/connect-multichain.d.ts +1 -0
  11. package/dist/browser/umd/connect-multichain.js +95 -50
  12. package/dist/browser/umd/connect-multichain.js.map +1 -1
  13. package/dist/browser/umd/metafile-cjs.json +1 -1
  14. package/dist/node/cjs/connect-multichain.d.ts +1 -0
  15. package/dist/node/cjs/connect-multichain.js +95 -50
  16. package/dist/node/cjs/connect-multichain.js.map +1 -1
  17. package/dist/node/cjs/metafile-cjs.json +1 -1
  18. package/dist/node/es/connect-multichain.d.mts +1 -0
  19. package/dist/node/es/connect-multichain.mjs +96 -51
  20. package/dist/node/es/connect-multichain.mjs.map +1 -1
  21. package/dist/node/es/metafile-esm.json +1 -1
  22. package/dist/react-native/es/connect-multichain.d.mts +1 -0
  23. package/dist/react-native/es/connect-multichain.mjs +96 -51
  24. package/dist/react-native/es/connect-multichain.mjs.map +1 -1
  25. package/dist/react-native/es/metafile-esm.json +1 -1
  26. package/dist/src/domain/multichain/types.d.ts +1 -0
  27. package/dist/src/domain/multichain/types.d.ts.map +1 -1
  28. package/dist/src/multichain/index.d.ts.map +1 -1
  29. package/dist/src/multichain/index.js +65 -22
  30. package/dist/src/multichain/index.js.map +1 -1
  31. package/dist/src/multichain/transports/default/index.d.ts +1 -0
  32. package/dist/src/multichain/transports/default/index.d.ts.map +1 -1
  33. package/dist/src/multichain/transports/default/index.js +28 -32
  34. package/dist/src/multichain/transports/default/index.js.map +1 -1
  35. package/dist/src/multichain/transports/mwp/KeyManager.d.ts +1 -0
  36. package/dist/src/multichain/transports/mwp/KeyManager.d.ts.map +1 -1
  37. package/dist/src/multichain/transports/mwp/KeyManager.js +4 -1
  38. package/dist/src/multichain/transports/mwp/KeyManager.js.map +1 -1
  39. package/dist/src/multichain/transports/mwp/index.d.ts +1 -0
  40. package/dist/src/multichain/transports/mwp/index.d.ts.map +1 -1
  41. package/dist/src/multichain/transports/mwp/index.js +6 -1
  42. package/dist/src/multichain/transports/mwp/index.js.map +1 -1
  43. package/dist/types/connect-multichain.d.ts +1 -0
  44. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/domain/errors/base.ts","../../../src/domain/errors/rpc.ts","../../../src/domain/errors/index.ts","../../../src/domain/events/index.ts","../../../src/domain/logger/index.ts","../../../src/domain/multichain/api/constants.ts","../../../src/domain/multichain/api/infura.ts","../../../src/domain/multichain/index.ts","../../../src/domain/platform/index.ts","../../../src/domain/store/adapter.ts","../../../src/domain/store/client.ts","../../../src/domain/store/index.ts","../../../src/domain/ui/types.ts","../../../src/domain/ui/index.ts","../../../src/multichain/utils/index.ts","../../../src/multichain/utils/analytics.ts","../../../src/domain/utils/index.ts","../../../src/domain/index.ts","../../../src/ui/modals/base/utils.ts","../../../src/ui/modals/base/AbstractInstallModal.ts","../../../src/ui/modals/node/install.ts","../../../src/ui/modals/base/AbstractOTPModal.ts","../../../src/ui/modals/node/otp.ts","../../../src/ui/modals/node/index.ts","../../../src/store/adapters/node.ts","../../../src/index.node.ts","../../../src/multichain/index.ts","../../../src/config/index.ts","../../../src/multichain/rpc/handlers/rpcClient.ts","../../../src/multichain/rpc/requestRouter.ts","../../../src/multichain/transports/default/index.ts","../../../src/multichain/transports/multichainApiClientWrapper/index.ts","../../../src/multichain/transports/mwp/index.ts","../../../src/multichain/transports/constants.ts","../../../src/multichain/transports/mwp/KeyManager.ts","../../../src/store/index.ts","../../../src/domain/errors/storage.ts","../../../src/ui/ModalFactory.ts","../../../src/ui/index.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/naming-convention */\n/* eslint-disable @typescript-eslint/parameter-properties */\nimport type { ErrorCodes } from './types';\n\nexport abstract class BaseErr<\n C extends string,\n T extends ErrorCodes,\n> extends Error {\n constructor(\n public readonly message: `${C}Err${T}: ${string}`,\n public readonly code: T,\n ) {\n super(message);\n }\n}\n","/* eslint-disable @typescript-eslint/parameter-properties */\nimport { BaseErr } from './base';\nimport type { RPCErrorCodes } from './types';\n\nexport class RPCHttpErr extends BaseErr<'RPC', RPCErrorCodes> {\n static readonly code = 50;\n\n constructor(\n readonly rpcEndpoint: string,\n readonly method: string,\n readonly httpStatus: number,\n ) {\n super(\n `RPCErr${RPCHttpErr.code}: ${httpStatus} on ${rpcEndpoint} for method ${method}`,\n RPCHttpErr.code,\n );\n }\n}\n\nexport class RPCReadonlyResponseErr extends BaseErr<'RPC', RPCErrorCodes> {\n static readonly code = 51;\n\n constructor(public readonly reason: string) {\n super(\n `RPCErr${RPCReadonlyResponseErr.code}: RPC Client response reason ${reason}`,\n RPCReadonlyResponseErr.code,\n );\n }\n}\n\nexport class RPCReadonlyRequestErr extends BaseErr<'RPC', RPCErrorCodes> {\n static readonly code = 52;\n\n constructor(public readonly reason: string) {\n super(\n `RPCErr${RPCReadonlyRequestErr.code}: RPC Client fetch reason ${reason}`,\n RPCReadonlyRequestErr.code,\n );\n }\n}\n\nexport class RPCInvokeMethodErr extends BaseErr<'RPC', RPCErrorCodes> {\n static readonly code = 53;\n\n constructor(public readonly reason: string) {\n super(\n `RPCErr${RPCInvokeMethodErr.code}: RPC Client invoke method reason (${reason})`,\n RPCInvokeMethodErr.code,\n );\n }\n}\n","export * from './rpc';\nexport type * from './types';\n","/* eslint-disable @typescript-eslint/explicit-function-return-type */\nimport { EventEmitter as EventEmitter3 } from 'eventemitter3';\n\n/**\n * A type-safe event emitter that provides a strongly-typed wrapper around EventEmitter2.\n *\n * This class ensures type safety for event names and their corresponding argument types,\n * making it easier to work with events in a type-safe manner.\n *\n * @template TEvents - A record type mapping event names to their argument types.\n * Each key represents an event name, and the value is a tuple of argument types.\n */\nexport class EventEmitter<TEvents extends Record<string, unknown[]>> {\n readonly #emitter = new EventEmitter3();\n\n /**\n * Emits an event with the specified name and arguments.\n *\n * @template TEventName - The name of the event to emit (must be a key of TEvents)\n * @param eventName - The name of the event to emit\n * @param eventArg - The arguments to pass to the event handlers\n */\n emit<TEventName extends keyof TEvents & string>(\n eventName: TEventName,\n ...eventArg: TEvents[TEventName]\n ) {\n this.#emitter.emit(eventName, ...eventArg);\n }\n\n /**\n * Registers an event handler for the specified event.\n *\n * @template TEventName - The name of the event to listen for (must be a key of TEvents)\n * @param eventName - The name of the event to listen for\n * @param handler - The function to call when the event is emitted\n * @returns Nothing\n */\n on<TEventName extends keyof TEvents & string>(\n eventName: TEventName,\n handler: (...eventArg: TEvents[TEventName]) => void,\n ) {\n this.#emitter.on(eventName, handler as (...args: any[]) => void);\n return () => {\n this.off(eventName, handler as (...args: any[]) => void);\n };\n }\n\n /**\n * Removes a specific event handler for the specified event.\n *\n * @template TEventName - The name of the event to remove the handler from (must be a key of TEvents)\n * @param eventName - The name of the event to remove the handler from\n * @param handler - The specific handler function to remove\n */\n off<TEventName extends keyof TEvents & string>(\n eventName: TEventName,\n handler: (...eventArg: TEvents[TEventName]) => void,\n ) {\n this.#emitter.off(eventName, handler as (...args: any[]) => void);\n }\n\n /**\n * Removes a specific event handler for the specified event.\n * Added for compatibility as some libraries use this method name.\n *\n * @template TEventName - The name of the event to remove the handler from (must be a key of TEvents)\n * @param eventName - The name of the event to remove the handler from\n * @param handler - The specific handler function to remove\n */\n removeListener<TEventName extends keyof TEvents & string>(\n eventName: TEventName,\n handler: (...eventArg: TEvents[TEventName]) => void,\n ) {\n this.#emitter.off(eventName, handler as (...args: any[]) => void);\n }\n\n /**\n * Registers an event handler for the specified event that will only be called once.\n *\n * @template TEventName - The name of the event to listen for (must be a key of TEvents)\n * @param eventName - The name of the event to listen for\n * @param handler - The function to call when the event is emitted (only once)\n * @returns A function to remove the listener\n */\n once<TEventName extends keyof TEvents & string>(\n eventName: TEventName,\n handler: (...eventArg: TEvents[TEventName]) => void,\n ) {\n this.#emitter.once(eventName, handler as (...args: any[]) => void);\n return () => {\n this.off(eventName, handler as (...args: any[]) => void);\n };\n }\n\n /**\n * Returns the number of listeners registered for the specified event.\n *\n * @template TEventName - The name of the event to count listeners for (must be a key of TEvents)\n * @param eventName - The name of the event to count listeners for\n * @returns The number of listeners registered for the event\n */\n listenerCount<TEventName extends keyof TEvents & string>(\n eventName: TEventName,\n ): number {\n return this.#emitter.listenerCount(eventName);\n }\n}\n\nexport type * from './types';\n","/* eslint-disable no-restricted-globals */\n// eslint-disable-next-line import-x/no-extraneous-dependencies\nimport debug from 'debug';\n\nimport type { StoreClient } from '../store/client';\n\n/**\n * Supported debug namespace types for the MetaMask SDK logger.\n * These namespaces help categorize and filter debug output.\n */\nexport type LoggerNameSpaces =\n | 'metamask-sdk:*'\n | 'metamask-sdk'\n | 'metamask-sdk:core'\n | 'metamask-sdk:provider'\n | 'metamask-sdk:ui'\n | 'metamask-sdk:transport';\n\n/**\n * Creates a debug logger instance with the specified namespace and color.\n *\n * This function initializes a debug logger using the 'debug' library,\n * which allows for conditional logging based on environment variables or storage settings.\n *\n * @param namespace - The debug namespace to use for this logger instance\n * @param color - The ANSI color code to use for log output (default: '214' for yellow)\n * @returns A configured debug logger instance\n */\nexport const createLogger = (\n namespace: LoggerNameSpaces = 'metamask-sdk',\n color = '214',\n): debug.Debugger => {\n const logger = debug(namespace);\n logger.color = color; // Yellow color (basic ANSI)\n return logger;\n};\n\n/**\n * Enables debug logging for the specified namespace.\n *\n * This function activates debug output for the given namespace,\n * allowing debug messages to be displayed in the console.\n *\n * @param namespace - The debug namespace to enable\n */\nexport const enableDebug = (\n namespace: LoggerNameSpaces = 'metamask-sdk',\n): void => {\n debug.enable(namespace);\n};\n\n/**\n * Checks if a specific namespace is enabled in the given debug value string.\n *\n * This function determines whether debug logging should be active for a namespace\n * by checking if the debug value contains the namespace, a wildcard pattern, or\n * the general MetaMask SDK wildcard.\n *\n * @param debugValue - The debug configuration string (e.g., from environment or storage)\n * @param namespace - The namespace to check for enablement\n * @returns True if the namespace should have debug logging enabled, false otherwise\n */\nfunction isNamespaceEnabled(\n debugValue: string,\n namespace: LoggerNameSpaces,\n): boolean {\n return (\n debugValue.includes(namespace) ||\n debugValue.includes('metamask-sdk:*') ||\n debugValue.includes('*')\n );\n}\n\n/**\n * Determines if debug logging is enabled for a specific namespace.\n *\n * This function checks multiple sources to determine if debug logging should be active:\n * 1. First checks the process environment variable 'debug'\n * 2. Falls back to checking the debug setting in storage\n * 3. Returns false if neither source enables the namespace\n *\n * @param namespace - The namespace to check for debug enablement\n * @param storage - The storage client to check for debug settings\n * @returns Promise that resolves to true if debug logging is enabled, false otherwise\n */\nexport const isEnabled = async (\n namespace: LoggerNameSpaces,\n storage: StoreClient,\n): Promise<boolean> => {\n if ('process' in globalThis && process?.env?.DEBUG) {\n const { DEBUG } = process.env;\n return isNamespaceEnabled(DEBUG, namespace);\n }\n\n const storageDebug = await storage.getDebug();\n if (storageDebug) {\n return isNamespaceEnabled(storageDebug, namespace);\n }\n\n return false;\n};\n","/* c8 ignore start */\nimport type { RpcUrlsMap } from './types';\n\nexport const infuraRpcUrls: RpcUrlsMap = {\n // ###### Ethereum ######\n // Mainnet\n 'eip155:1': 'https://mainnet.infura.io/v3/',\n // Goerli\n 'eip155:5': 'https://goerli.infura.io/v3/',\n // Sepolia 11155111\n 'eip155:11155111': 'https://sepolia.infura.io/v3/',\n // ###### Linea ######\n // Mainnet Alpha\n 'eip155:59144': 'https://linea-mainnet.infura.io/v3/',\n // Testnet ( linea goerli )\n 'eip155:59140': 'https://linea-goerli.infura.io/v3/',\n // ###### Polygon ######\n // Mainnet\n 'eip155:137': 'https://polygon-mainnet.infura.io/v3/',\n // Mumbai\n 'eip155:80001': 'https://polygon-mumbai.infura.io/v3/',\n // ###### Optimism ######\n // Mainnet\n 'eip155:10': 'https://optimism-mainnet.infura.io/v3/',\n // Goerli\n 'eip155:420': 'https://optimism-goerli.infura.io/v3/',\n // ###### Arbitrum ######\n // Mainnet\n 'eip155:42161': 'https://arbitrum-mainnet.infura.io/v3/',\n // Goerli\n 'eip155:421613': 'https://arbitrum-goerli.infura.io/v3/',\n // ###### Palm ######\n // Mainnet\n 'eip155:11297108109': 'https://palm-mainnet.infura.io/v3/',\n // Testnet\n 'eip155:11297108099': 'https://palm-testnet.infura.io/v3/',\n // ###### Avalanche C-Chain ######\n // Mainnet\n 'eip155:43114': 'https://avalanche-mainnet.infura.io/v3/',\n // Fuji\n 'eip155:43113': 'https://avalanche-fuji.infura.io/v3/',\n // // ###### NEAR ######\n // // Mainnet\n // 'near:mainnet': `https://near-mainnet.infura.io/v3/`,\n // // Testnet\n // 'near:testnet': `https://near-testnet.infura.io/v3/`,\n // ###### Aurora ######\n // Mainnet\n 'eip155:1313161554': 'https://aurora-mainnet.infura.io/v3/',\n // Testnet\n 'eip155:1313161555': 'https://aurora-testnet.infura.io/v3/',\n // ###### StarkNet ######\n // Mainnet\n //\n // 'starknet:SN_MAIN': `https://starknet-mainnet.infura.io/v3/`,\n // // Goerli\n // 'starknet:SN_GOERLI': `https://starknet-goerli.infura.io/v3/`,\n // // Goerli 2\n // 'starknet:SN_GOERLI2': `https://starknet-goerli2.infura.io/v3/`,\n // ###### Celo ######\n // Mainnet\n 'eip155:42220': 'https://celo-mainnet.infura.io/v3/',\n // Alfajores Testnet\n 'eip155:44787': 'https://celo-alfajores.infura.io/v3/',\n};\n\n// Methods that are passed through to the RPC node\nexport const RPC_HANDLED_METHODS = new Set([\n 'eth_blockNumber',\n 'eth_gasPrice',\n 'eth_maxPriorityFeePerGas',\n 'eth_blobBaseFee',\n 'eth_feeHistory',\n 'eth_getBalance',\n 'eth_getCode',\n 'eth_getStorageAt',\n 'eth_call',\n 'eth_estimateGas',\n 'eth_getLogs',\n 'eth_getProof',\n 'eth_getTransactionCount',\n 'eth_getBlockByNumber',\n 'eth_getBlockByHash',\n 'eth_getBlockTransactionCountByNumber',\n 'eth_getBlockTransactionCountByHash',\n 'eth_getUncleCountByBlockNumber',\n 'eth_getUncleCountByBlockHash',\n 'eth_getTransactionByHash',\n 'eth_getTransactionByBlockNumberAndIndex',\n 'eth_getTransactionByBlockHashAndIndex',\n 'eth_getTransactionReceipt',\n 'eth_getUncleByBlockNumberAndIndex',\n 'eth_getUncleByBlockHashAndIndex',\n 'eth_getFilterChanges',\n 'eth_getFilterLogs',\n 'eth_newBlockFilter',\n 'eth_newFilter',\n 'eth_newPendingTransactionFilter',\n 'eth_sendRawTransaction',\n 'eth_syncing',\n 'eth_uninstallFilter',\n]);\n\n// Methods that are handled by the SDK directly\nexport const SDK_HANDLED_METHODS = new Set(['eth_accounts', 'eth_chainId']);\n","/* eslint-disable jsdoc/require-jsdoc */\nimport { infuraRpcUrls } from './constants';\nimport type { RpcUrlsMap } from './types';\n\nexport function getInfuraRpcUrls(infuraAPIKey: string): RpcUrlsMap {\n return Object.keys(infuraRpcUrls).reduce<RpcUrlsMap>((acc, key) => {\n const typedKey = key as keyof typeof infuraRpcUrls;\n acc[typedKey] = `${infuraRpcUrls[typedKey]}${infuraAPIKey}`;\n return acc;\n }, {});\n}\n","/* eslint-disable @typescript-eslint/parameter-properties */\n/* eslint-disable jsdoc/require-jsdoc */\nimport type {\n MultichainApiClient,\n SessionProperties,\n} from '@metamask/multichain-api-client';\nimport type { CaipAccountId, Json } from '@metamask/utils';\n\nimport { EventEmitter, type SDKEvents } from '../events';\nimport type { StoreClient } from '../store/client';\nimport type { InvokeMethodOptions, RPCAPI, Scope } from './api/types';\nimport type {\n ExtendedTransport,\n MergeableMultichainOptions,\n MultichainOptions,\n} from './types';\n\nexport type ConnectionStatus =\n | 'pending'\n | 'loaded'\n | 'disconnected'\n | 'connected'\n | 'connecting';\n\nexport enum TransportType {\n Browser = 'browser',\n MWP = 'mwp',\n UNKNOWN = 'unknown',\n}\n\n/**\n * Abstract base class for the Multichain SDK implementation.\n *\n * This class defines the core interface that all Multichain SDK implementations\n * must provide, including session management, connection handling, and method invocation.\n */\nexport abstract class MultichainCore extends EventEmitter<SDKEvents> {\n abstract storage: StoreClient;\n\n abstract status: ConnectionStatus;\n\n abstract provider: MultichainApiClient<RPCAPI>;\n\n abstract transport: ExtendedTransport;\n\n abstract transportType: TransportType;\n\n /**\n * Establishes a connection to the multichain provider, or re-use existing session\n *\n * @returns Promise that resolves to the session data\n */\n abstract connect(\n scopes: Scope[],\n caipAccountIds: CaipAccountId[],\n sessionProperties?: SessionProperties,\n forceRequest?: boolean,\n ): Promise<void>;\n\n /**\n * Disconnects from the multichain provider.\n *\n * @returns Promise that resolves when disconnection is complete\n */\n abstract disconnect(scopes?: Scope[]): Promise<void>;\n\n /**\n * Invokes an RPC method with the specified options.\n *\n * @param options - The method invocation options including scope and request details\n * @returns Promise that resolves to the method result\n */\n abstract invokeMethod(options: InvokeMethodOptions): Promise<Json>;\n\n abstract openSimpleDeeplinkIfNeeded(): void;\n\n abstract emitSessionChanged(): Promise<void>;\n\n constructor(protected options: MultichainOptions) {\n super();\n }\n\n /**\n * Merges the given options into the current instance options.\n * Only the mergeable keys are updated (api.supportedNetworks, ui.*, mobile.*, transport.extensionId, debug).\n * The main thing to note is that the value for `dapp` is not merged as it does not make sense for\n * subsequent calls to `createMultichainClient` to have a different `dapp` value.\n * Used when createMultichainClient is called with an existing singleton.\n *\n * @param partial - Options to merge/overwrite onto the current instance\n */\n mergeOptions(partial: MergeableMultichainOptions): void {\n const opts = this.options;\n this.options = {\n ...opts,\n api: {\n ...opts.api,\n supportedNetworks: {\n ...opts.api.supportedNetworks,\n ...(partial.api?.supportedNetworks ?? {}),\n },\n },\n ui: {\n ...opts.ui,\n headless: partial.ui?.headless ?? opts.ui.headless,\n preferExtension: partial.ui?.preferExtension ?? opts.ui.preferExtension,\n showInstallModal:\n partial.ui?.showInstallModal ?? opts.ui.showInstallModal,\n },\n mobile: {\n ...opts.mobile,\n ...(partial.mobile ?? {}),\n },\n transport: {\n ...(opts.transport ?? {}),\n extensionId:\n partial.transport?.extensionId ?? opts.transport?.extensionId,\n },\n debug: partial.debug ?? opts.debug,\n };\n }\n}\n/* c8 ignore end */\n\nexport function getTransportType(type: string): TransportType {\n switch (type) {\n case 'browser':\n return TransportType.Browser;\n case 'mwp':\n return TransportType.MWP;\n default:\n return TransportType.UNKNOWN;\n }\n}\n\nexport * from './api/constants';\nexport * from './api/infura';\nexport type * from './api/types';\nexport type * from './types';\n","/* eslint-disable @typescript-eslint/explicit-function-return-type */\n/* eslint-disable no-restricted-globals */\n/* eslint-disable jsdoc/require-jsdoc */\n/* eslint-disable @typescript-eslint/naming-convention */\n/* eslint-disable import-x/no-named-as-default-member -- Bowser.parse is the intended API */\nimport Bowser from 'bowser';\n\nexport enum PlatformType {\n // React Native or Nodejs\n NonBrowser = 'nodejs',\n // MetaMask Mobile in-app browser\n MetaMaskMobileWebview = 'in-app-browser',\n // Desktop Browser\n DesktopWeb = 'web-desktop',\n // Mobile Browser\n MobileWeb = 'web-mobile',\n // ReactNative\n ReactNative = 'react-native',\n}\n\nfunction isNotBrowser(): boolean {\n if (typeof window === 'undefined') {\n return true;\n }\n if (!window?.navigator) {\n return true;\n }\n if (\n typeof global !== 'undefined' &&\n global?.navigator?.product === 'ReactNative'\n ) {\n return true;\n }\n return navigator?.product === 'ReactNative';\n}\n\nfunction isReactNative(): boolean {\n const hasWindowNavigator =\n typeof window !== 'undefined' && window.navigator !== undefined;\n const nav = hasWindowNavigator ? window.navigator : undefined;\n\n if (!nav) {\n return false;\n }\n\n return hasWindowNavigator && window.navigator?.product === 'ReactNative';\n}\n\nfunction isMetaMaskMobileWebView(): boolean {\n return (\n typeof window !== 'undefined' &&\n // @ts-expect-error ReactNativeWebView should be defined\n Boolean(window.ReactNativeWebView) &&\n Boolean(window.navigator.userAgent.endsWith('MetaMaskMobile'))\n );\n}\n\nfunction isMobile(): boolean {\n const browser = Bowser.parse(window.navigator.userAgent);\n return (\n browser?.platform?.type === 'mobile' || browser?.platform?.type === 'tablet'\n );\n}\n\nexport function getPlatformType(): PlatformType {\n if (isReactNative()) {\n return PlatformType.ReactNative;\n }\n if (isNotBrowser()) {\n return PlatformType.NonBrowser;\n }\n if (isMetaMaskMobileWebView()) {\n return PlatformType.MetaMaskMobileWebview;\n }\n if (isMobile()) {\n return PlatformType.MobileWeb;\n }\n return PlatformType.DesktopWeb;\n}\n\n/**\n * Check if MetaMask extension is installed\n *\n * @returns True if extension is installed, false otherwise\n */\nexport function isMetamaskExtensionInstalled(): boolean {\n if (typeof window === 'undefined') {\n return false;\n }\n // @ts-expect-error ethereum should be defined\n return Boolean(window.ethereum?.isMetaMask);\n}\n\nexport function isSecure(): boolean {\n const platformType = getPlatformType();\n return isReactNative() || platformType === PlatformType.MobileWeb;\n}\n\n// Immediately start MetaMask detection when module loads\nconst detectionPromise: Promise<boolean> = (async () => {\n const pt = getPlatformType();\n if (pt === PlatformType.NonBrowser || pt === PlatformType.ReactNative) {\n return Promise.resolve(false);\n }\n\n return new Promise((resolve) => {\n const providers: any[] = [];\n\n const handler = (event: any) => {\n if (event?.detail?.info?.rdns) {\n providers.push(event.detail);\n }\n };\n\n window.addEventListener('eip6963:announceProvider', handler);\n window.dispatchEvent(new Event('eip6963:requestProvider'));\n\n setTimeout(() => {\n window.removeEventListener('eip6963:announceProvider', handler);\n\n const hasMetaMask = providers.some((provider) =>\n provider?.info?.rdns?.startsWith('io.metamask'),\n );\n\n resolve(hasMetaMask);\n }, 300); // default timeout\n });\n})();\n\nexport async function hasExtension(): Promise<boolean> {\n return detectionPromise;\n}\n","/* eslint-disable @typescript-eslint/parameter-properties */\n/* c8 ignore start */\n// biome-ignore lint/suspicious/noExplicitAny: Needed here\nexport type StoreOptions = Record<string, any>;\n\nexport abstract class StoreAdapter {\n abstract platform: 'web' | 'rn' | 'node';\n\n constructor(public options?: StoreOptions) {}\n\n abstract get(key: string): Promise<string | null>;\n\n abstract set(key: string, value: string): Promise<void>;\n\n abstract delete(key: string): Promise<void>;\n}\n","/* c8 ignore start */\nimport type { StoreAdapter } from '.';\nimport type { TransportType } from '../multichain';\n\nexport abstract class StoreClient {\n abstract adapter: StoreAdapter;\n\n abstract getAnonId(): Promise<string>;\n\n abstract getExtensionId(): Promise<string | null>;\n\n abstract setExtensionId(extensionId: string): Promise<void>;\n\n abstract getTransport(): Promise<TransportType | null>;\n\n abstract setTransport(transport: TransportType): Promise<void>;\n\n abstract removeTransport(): Promise<void>;\n\n abstract setAnonId(anonId: string): Promise<void>;\n\n abstract removeExtensionId(): Promise<void>;\n\n abstract removeAnonId(): Promise<void>;\n\n abstract getDebug(): Promise<string | null>;\n}\n","export * from './adapter';\nexport * from './client';\n","import type { Components } from '@metamask/multichain-ui';\n\nimport type { ConnectionRequest } from '../multichain';\n\nexport type OTPCode = string;\nexport type QRLink = string;\n\nexport type InstallWidgetProps = Components.MmInstallModal & {\n parentElement?: Element;\n connectionRequest: ConnectionRequest;\n onClose: (shouldTerminate?: boolean) => void;\n startDesktopOnboarding: () => void;\n createConnectionRequest: () => Promise<ConnectionRequest>;\n generateQRCode: (connectionRequest: ConnectionRequest) => Promise<QRLink>;\n /**\n * Callback invoked when a QR code link is generated or regenerated.\n * This allows consumers to display their own custom QR code UI.\n *\n * @param uri - The deeplink URI to be displayed as a QR code\n */\n onDisplayUri?: (uri: QRLink) => void;\n};\n\nexport type OTPCodeWidgetProps = Components.MmOtpModal & {\n parentElement?: Element;\n onClose: () => Promise<void>;\n onDisconnect?: () => void;\n createOTPCode: () => Promise<OTPCode>;\n updateOTPCode: (otpValue: string) => void;\n};\n\nexport type DataType = OTPCode | QRLink;\n/**\n * Abstract Modal class with shared functionality across all models\n */\nexport abstract class Modal<Options, Data extends DataType = DataType> {\n protected abstract instance?:\n | HTMLMmInstallModalElement\n | HTMLMmOtpModalElement\n | undefined;\n\n abstract mount(): void;\n\n abstract unmount(): void;\n\n // eslint-disable-next-line @typescript-eslint/parameter-properties\n constructor(protected readonly options: Options) {}\n\n get isMounted(): boolean {\n return this.instance !== undefined;\n }\n\n get data(): Data {\n if (\n typeof this.options === 'object' &&\n this.options &&\n 'link' in this.options\n ) {\n return this.options.link as Data;\n }\n\n if (\n typeof this.options === 'object' &&\n this.options &&\n 'otpCode' in this.options\n ) {\n return this.options.otpCode as Data;\n }\n\n throw new Error('Invalid options');\n }\n\n set data(data: Data) {\n if (\n typeof this.options === 'object' &&\n this.options &&\n 'link' in this.options\n ) {\n this.options.link = data;\n }\n\n if (\n typeof this.options === 'object' &&\n this.options &&\n 'otpCode' in this.options\n ) {\n this.options.otpCode = data;\n }\n }\n}\n","export type * from './factory';\nexport * from './types';\n","/* eslint-disable no-restricted-globals -- Browser APIs are intentionally used */\n/* eslint-disable jsdoc/require-param-description -- Auto-generated JSDoc */\n/* eslint-disable jsdoc/require-returns -- Auto-generated JSDoc */\n/* eslint-disable @typescript-eslint/explicit-function-return-type -- Inferred types are sufficient */\nimport type { SessionProperties } from '@metamask/multichain-api-client';\nimport {\n type CaipAccountId,\n type CaipChainId,\n parseCaipAccountId,\n parseCaipChainId,\n} from '@metamask/utils';\nimport { deflate } from 'pako';\n\nimport {\n type DappSettings,\n getPlatformType,\n type MultichainOptions,\n PlatformType,\n type Scope,\n type SessionData,\n} from '../../domain';\n\nexport type OptionalScopes = Record<Scope, SessionData['sessionScopes'][Scope]>;\n\n/**\n * Returns the global object for the current JS environment.\n *\n * @returns The global object as a record for indexing\n */\nexport function getGlobalObject(): Record<string, unknown> {\n if (typeof globalThis !== 'undefined') {\n return globalThis as unknown as Record<string, unknown>;\n }\n if (typeof global !== 'undefined') {\n return global as unknown as Record<string, unknown>;\n }\n if (typeof self !== 'undefined') {\n return self as unknown as Record<string, unknown>;\n }\n if (typeof window !== 'undefined') {\n return window as unknown as Record<string, unknown>;\n }\n throw new Error('Unable to locate global object');\n}\n\n/**\n * Cross-platform base64 encoding\n * Works in browser, Node.js, and React Native environments\n *\n * @param str\n */\nfunction base64Encode(str: string): string {\n if (typeof btoa !== 'undefined') {\n // Browser and React Native with polyfills\n return btoa(str);\n } else if (typeof Buffer !== 'undefined') {\n // Node.js\n return Buffer.from(str).toString('base64');\n }\n throw new Error('No base64 encoding method available');\n}\n\n/**\n * Compress a string using pako (deflateRaw)\n * Returns a base64-encoded compressed string\n *\n * @param str\n */\nexport function compressString(str: string): string {\n const compressed = deflate(str);\n\n // Convert Uint8Array to string for base64 encoding\n const binaryString = String.fromCharCode.apply(null, Array.from(compressed));\n return base64Encode(binaryString);\n}\n\n/**\n *\n * @param dapp\n */\nexport function getDappId(dapp: DappSettings) {\n return dapp.url ?? dapp.name;\n}\n\n/**\n *\n * @param options\n * @param deeplink\n * @param universalLink\n */\nexport function openDeeplink(\n options: MultichainOptions,\n deeplink: string,\n universalLink: string,\n) {\n const { mobile } = options;\n const useDeeplink = mobile?.useDeeplink ?? true;\n if (useDeeplink) {\n if (typeof window !== 'undefined') {\n // We don't need to open a deeplink in a new tab\n // It avoid the browser to display a blank page\n window.location.href = deeplink;\n }\n } else if (typeof document !== 'undefined') {\n // Workaround for https://github.com/rainbow-me/rainbowkit/issues/524.\n // Using 'window.open' causes issues on iOS in non-Safari browsers and\n // WebViews where a blank tab is left behind after connecting.\n // This is especially bad in some WebView scenarios (e.g. following a\n // link from Twitter) where the user doesn't have any mechanism for\n // closing the blank tab.\n // For whatever reason, links with a target of \"_blank\" don't suffer\n // from this problem, and programmatically clicking a detached link\n // element with the same attributes also avoids the issue.\n const link = document.createElement('a');\n link.href = universalLink;\n link.target = '_self';\n link.rel = 'noreferrer noopener';\n link.click();\n }\n}\n\n/**\n * Merges existing session (from getCaipSession) with newly requested scopes, accounts, and session properties.\n * Derives existing scopes/accounts from sessionData.sessionScopes, then merges with requested values.\n *\n * @param sessionData - Current CAIP session data\n * @param scopes - Newly requested scopes\n * @param caipAccountIds - Newly requested account IDs\n * @param sessionProperties - New session properties to merge over existing\n * @returns requestedScopes, requestedCaipAccountIds, and requestedSessionProperties\n */\nexport function mergeRequestedSessionWithExisting(\n sessionData: SessionData,\n scopes: Scope[],\n caipAccountIds: CaipAccountId[],\n sessionProperties?: SessionProperties,\n): {\n mergedScopes: Scope[];\n mergedCaipAccountIds: CaipAccountId[];\n mergedSessionProperties: SessionProperties;\n} {\n const existingCaipChainIds = Object.keys(sessionData.sessionScopes);\n const existingCaipAccountIds: string[] = [];\n Object.values(sessionData.sessionScopes).forEach((scopeObject) => {\n if (scopeObject?.accounts && Array.isArray(scopeObject.accounts)) {\n scopeObject.accounts.forEach((account) => {\n existingCaipAccountIds.push(account);\n });\n }\n });\n\n const mergedScopes = Array.from(\n new Set([...existingCaipChainIds, ...scopes]),\n ) as Scope[];\n const mergedCaipAccountIds = Array.from(\n new Set([...existingCaipAccountIds, ...caipAccountIds]),\n ) as CaipAccountId[];\n const mergedSessionProperties = {\n ...sessionData.sessionProperties,\n ...sessionProperties,\n };\n return {\n mergedScopes,\n mergedCaipAccountIds,\n mergedSessionProperties,\n };\n}\n\n/**\n *\n * @param scopes\n */\nexport function getOptionalScopes(scopes: Scope[]) {\n return scopes.reduce<OptionalScopes>(\n (prev, scope) => ({\n // biome-ignore lint/performance/noAccumulatingSpread: Needed\n ...prev,\n [scope]: {\n methods: [],\n notifications: [],\n accounts: [],\n },\n }),\n {},\n );\n}\n\nexport const extractFavicon = () => {\n if (typeof document === 'undefined') {\n return undefined;\n }\n\n let favicon: string | undefined;\n const nodeList = document.getElementsByTagName('link');\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let i = 0; i < nodeList.length; i++) {\n if (\n nodeList[i].getAttribute('rel') === 'icon' ||\n nodeList[i].getAttribute('rel') === 'shortcut icon'\n ) {\n favicon = nodeList[i].getAttribute('href') ?? undefined;\n }\n }\n return favicon;\n};\n\n/**\n * Normalizes a non-http(s) URL from a React Native app into a valid https URL.\n * Extracts the scheme, sanitizes it to a DNS-safe label, and builds a .rn.dapp.local URL.\n *\n * @param url - The original URL to normalize\n * @returns An object with the normalized URL and original scheme, or undefined if no normalization needed\n */\nfunction normalizeNativeUrl(\n url: string,\n): { url: string; nativeScheme: string } | undefined {\n // Matches \"http://\" or \"https://\"\n const httpPattern = /^https?:\\/\\//u;\n if (httpPattern.test(url)) {\n return undefined;\n }\n\n // Captures the scheme before \"://\" — e.g. \"myapp\" from \"myapp://path\"\n const schemeMatch = url.match(/^([^:]*):\\/\\//u);\n const rawScheme = schemeMatch?.[1] ?? url;\n const sanitized = rawScheme\n .toLowerCase()\n // Replace non-DNS chars with hyphens — e.g. \"My.App\" -> \"my-app\"\n .replace(/[^a-z0-9-]/gu, '-')\n // Strip leading/trailing hyphens — e.g. \"-my-app-\" -> \"my-app\"\n .replace(/^-+|-+$/gu, '');\n\n const subdomain = (sanitized || 'unknown').slice(0, 63).replace(/-+$/u, '');\n\n return {\n url: `https://${subdomain}.rn.dapp.local`,\n nativeScheme: url,\n };\n}\n\n/**\n *\n * @param options\n */\nexport function setupDappMetadata(\n options: MultichainOptions,\n): MultichainOptions {\n const platform = getPlatformType();\n const isBrowser =\n platform === PlatformType.DesktopWeb ||\n platform === PlatformType.MobileWeb ||\n platform === PlatformType.MetaMaskMobileWebview;\n\n if (!options.dapp?.name) {\n throw new Error('You must provide dapp name');\n }\n if (isBrowser) {\n options.dapp = {\n ...options.dapp,\n url: `${window.location.protocol}//${window.location.host}`,\n };\n }\n if (!options.dapp?.url) {\n throw new Error('You must provide dapp url');\n }\n\n // Normalize non-http(s) URLs on React Native platforms\n if (platform === PlatformType.ReactNative && options.dapp.url) {\n const normalized = normalizeNativeUrl(options.dapp.url);\n if (normalized) {\n console.info(\n `Normalizing dapp URL for React Native: \"${options.dapp.url}\" -> \"${normalized.url}\"`,\n );\n options.dapp = {\n ...options.dapp,\n url: normalized.url,\n nativeScheme: normalized.nativeScheme,\n };\n }\n }\n\n const BASE_64_ICON_MAX_LENGTH = 163400;\n // Check if iconUrl and url are valid\n const urlPattern = /^(http|https):\\/\\/[^\\s]*$/u; // Regular expression for URLs starting with http:// or https://\n if (options.dapp) {\n if ('iconUrl' in options.dapp) {\n if (options.dapp.iconUrl && !urlPattern.test(options.dapp.iconUrl)) {\n console.warn(\n 'Invalid dappMetadata.iconUrl: URL must start with http:// or https://',\n );\n options.dapp.iconUrl = undefined;\n }\n }\n // This check ensures that the base64Icon string in the dappMetadata does not exceed 163,400 characters.\n // The character limit is important because a longer base64-encoded string causes the connection to the mobile app to fail.\n // Keeping the base64Icon string length below this threshold ensures reliable communication and functionality.\n if ('base64Icon' in options.dapp) {\n if (\n options.dapp.base64Icon &&\n options.dapp.base64Icon.length > BASE_64_ICON_MAX_LENGTH\n ) {\n console.warn(\n 'Invalid dappMetadata.base64Icon: Base64-encoded icon string length must be less than 163400 characters',\n );\n\n options.dapp.base64Icon = undefined;\n }\n }\n if (options.dapp.url && !urlPattern.test(options.dapp.url)) {\n console.warn(\n 'Invalid dappMetadata.url: URL must start with http:// or https://',\n );\n }\n const favicon = extractFavicon();\n if (\n favicon &&\n !('iconUrl' in options.dapp) &&\n !('base64Icon' in options.dapp)\n ) {\n const faviconUrl = `${window.location.protocol}//${window.location.host}${favicon}`;\n // @ts-expect-error -- iconUrl may not exist on all dapp types\n options.dapp.iconUrl = faviconUrl;\n }\n }\n return options;\n}\n\n/**\n * Enhanced scope checking function that validates both scopes and accounts\n *\n * @param currentScopes - Current scopes from the existing session\n * @param proposedScopes - Proposed scopes from the connect options\n * @param walletSession - The existing wallet session data\n * @param proposedCaipAccountIds - Proposed account IDs from the connect options\n * @returns true if scopes and accounts match, false otherwise\n */\nexport function isSameScopesAndAccounts(\n currentScopes: Scope[],\n proposedScopes: Scope[],\n walletSession: SessionData,\n proposedCaipAccountIds: CaipAccountId[],\n): boolean {\n const isSameScopes =\n currentScopes.every((scope) => proposedScopes.includes(scope)) &&\n proposedScopes.every((scope) => currentScopes.includes(scope));\n\n if (!isSameScopes) {\n return false;\n }\n\n const existingAccountIds: CaipAccountId[] = Object.values(\n walletSession.sessionScopes,\n )\n .filter(({ accounts }) => Boolean(accounts))\n .flatMap(({ accounts }) => accounts ?? []);\n\n const allProposedAccountsIncluded = proposedCaipAccountIds.every(\n (proposedAccountId) => existingAccountIds.includes(proposedAccountId),\n );\n\n return allProposedAccountsIncluded;\n}\n\n/**\n *\n * @param caipAccountIds\n */\nexport function getValidAccounts(caipAccountIds: CaipAccountId[]) {\n return caipAccountIds.reduce<ReturnType<typeof parseCaipAccountId>[]>(\n (caipAccounts, caipAccountId) => {\n try {\n // biome-ignore lint/performance/noAccumulatingSpread: Needed\n return [...caipAccounts, parseCaipAccountId(caipAccountId)];\n } catch (error) {\n const stringifiedAccountId = JSON.stringify(caipAccountId);\n console.error(\n `Invalid CAIP account ID: ${stringifiedAccountId}`,\n error,\n );\n return caipAccounts;\n }\n },\n [],\n );\n}\n\n/**\n * Adds valid accounts to their corresponding scopes based on chain namespace and reference.\n * Returns a new OptionalScopes object without modifying the input.\n *\n * @param optionalScopes - The scopes to add accounts to\n * @param validAccounts - Array of parsed valid accounts\n * @returns A new OptionalScopes object with accounts added to matching scopes\n */\nexport function addValidAccounts(\n optionalScopes: OptionalScopes,\n validAccounts: ReturnType<typeof getValidAccounts>,\n): OptionalScopes {\n if (!optionalScopes || !validAccounts?.length) {\n return optionalScopes;\n }\n\n const result: OptionalScopes = Object.fromEntries(\n Object.entries(optionalScopes).map(([scope, scopeData]) => [\n scope,\n {\n methods: [...(scopeData?.methods ?? [])],\n notifications: [...(scopeData?.notifications ?? [])],\n accounts: [...(scopeData?.accounts ?? [])],\n },\n ]),\n );\n\n // Group accounts by their chain identifier for efficient lookup\n const accountsByChain = new Map<string, CaipAccountId[]>();\n for (const account of validAccounts) {\n const chainKey = `${account.chain.namespace}:${account.chain.reference}`;\n const accountId: CaipAccountId = `${account.chainId}:${account.address}`;\n\n if (!accountsByChain.has(chainKey)) {\n accountsByChain.set(chainKey, []);\n }\n accountsByChain.get(chainKey)?.push(accountId);\n }\n\n // Add accounts to matching scopes\n for (const [scopeKey, scopeData] of Object.entries(result)) {\n if (!scopeData?.accounts) {\n continue;\n }\n\n try {\n const scope = scopeKey as CaipChainId;\n const scopeDetails = parseCaipChainId(scope);\n const chainKey = `${scopeDetails.namespace}:${scopeDetails.reference}`;\n\n const matchingAccounts = accountsByChain.get(chainKey);\n if (matchingAccounts) {\n const existingAccounts = new Set(scopeData.accounts);\n const newAccounts = matchingAccounts.filter(\n (account) => !existingAccounts.has(account),\n );\n scopeData.accounts.push(...newAccounts);\n }\n } catch (error) {\n console.error(`Invalid scope format: ${scopeKey}`, error);\n }\n }\n\n return result;\n}\n\n// uint32 (two's complement) max\n// more conservative than Number.MAX_SAFE_INTEGER\nconst MAX = 4_294_967_295;\nlet idCounter = Math.floor(Math.random() * MAX);\n\nexport const getUniqueRequestId = (): number => {\n idCounter = (idCounter + 1) % MAX;\n return idCounter;\n};\n","/* eslint-disable @typescript-eslint/naming-convention */\n/* eslint-disable @typescript-eslint/no-unused-vars -- Scope type used in JSDoc */\nimport { getDappId } from '.';\nimport type {\n InvokeMethodOptions,\n MultichainOptions,\n PlatformType,\n Scope,\n StoreClient,\n} from '../../domain';\nimport { getPlatformType, getVersion, TransportType } from '../../domain';\n\n/**\n * Checks if an error represents a user rejection.\n *\n * @param error - The error object to check\n * @returns True if the error indicates a user rejection, false otherwise\n */\nexport function isRejectionError(error: unknown): boolean {\n if (typeof error !== 'object' || error === null) {\n return false;\n }\n\n const errorObj = error as { code?: number; message?: string };\n const errorCode = errorObj.code;\n const errorMessage = errorObj.message?.toLowerCase() ?? '';\n\n return (\n errorCode === 4001 || // User rejected request (common EIP-1193 code)\n errorCode === 4100 || // Unauthorized (common rejection code)\n errorMessage.includes('reject') ||\n errorMessage.includes('denied') ||\n errorMessage.includes('cancel') ||\n errorMessage.includes('user')\n );\n}\n\n/**\n * Gets base analytics properties that are common across all events.\n *\n * @param options - Multichain options containing dapp and analytics config\n * @param storage - Storage client for getting anonymous ID\n * @returns Base analytics properties\n */\nexport async function getBaseAnalyticsProperties(\n options: MultichainOptions,\n storage: StoreClient,\n): Promise<{\n mmconnect_version: string;\n dapp_id: string;\n platform: PlatformType;\n integration_type: string;\n anon_id: string;\n}> {\n const version = getVersion();\n const dappId = getDappId(options.dapp);\n const platform = getPlatformType();\n const anonId = await storage.getAnonId();\n const integrationType =\n (options.analytics as { enabled: true; integrationType: string })\n ?.integrationType ?? TransportType.UNKNOWN;\n\n return {\n mmconnect_version: version,\n dapp_id: dappId,\n platform,\n integration_type: integrationType,\n anon_id: anonId,\n };\n}\n\n/**\n * Gets analytics properties specific to wallet action events.\n *\n * @param options - Multichain options containing dapp and analytics config\n * @param storage - Storage client for getting anonymous ID\n * @param invokeOptions - The invoke method options containing method and scope\n * @returns Wallet action analytics properties\n */\nexport async function getWalletActionAnalyticsProperties(\n options: MultichainOptions,\n storage: StoreClient,\n invokeOptions: InvokeMethodOptions,\n): Promise<{\n mmconnect_version: string;\n dapp_id: string;\n method: string;\n integration_type: string;\n caip_chain_id: string;\n anon_id: string;\n}> {\n const version = getVersion();\n const dappId = getDappId(options.dapp);\n const anonId = await storage.getAnonId();\n const integrationType =\n (options.analytics as { enabled: true; integrationType: string })\n ?.integrationType ?? 'unknown';\n\n return {\n mmconnect_version: version,\n dapp_id: dappId,\n method: invokeOptions.request.method,\n integration_type: integrationType,\n caip_chain_id: invokeOptions.scope,\n anon_id: anonId,\n };\n}\n","/**\n * Returns the version of the Multichain SDK.\n *\n * @returns The version of the Multichain SDK.\n */\nexport function getVersion(): string {\n return '0.0.0';\n}\n\nexport {\n getWalletActionAnalyticsProperties,\n isRejectionError,\n} from '../../multichain/utils/analytics';\n","export * from './errors';\nexport * from './events';\nexport * from './logger';\nexport * from './multichain';\nexport * from './platform';\nexport * from './store';\nexport * from './ui';\nexport * from './utils';\n","/**\n * Formats remaining time in a human-readable format.\n *\n * @param milliseconds - The remaining time in milliseconds.\n * @returns A formatted string representing the remaining time.\n */\nexport function formatRemainingTime(milliseconds: number): string {\n if (milliseconds <= 0) {\n return 'EXPIRED';\n }\n const seconds = Math.floor(milliseconds / 1000);\n return `${seconds}s`;\n}\n\n/**\n * Determines whether to log the countdown at the current remaining seconds.\n *\n * @param remainingSeconds - The remaining seconds until expiration.\n * @returns True if the countdown should be logged, false otherwise.\n */\nexport function shouldLogCountdown(remainingSeconds: number): boolean {\n // Log at specific intervals to avoid spam\n if (remainingSeconds <= 10) {\n // Log every second for the last 10 seconds\n return true;\n } else if (remainingSeconds <= 30) {\n // Log every 5 seconds for the last 30 seconds\n return remainingSeconds % 5 === 0;\n } else if (remainingSeconds <= 60) {\n // Log every 10 seconds for the last minute\n return remainingSeconds % 10 === 0;\n } else if (remainingSeconds <= 300) {\n // Log every 30 seconds for the last 5 minutes\n return remainingSeconds % 30 === 0;\n }\n // Log every minute for longer durations\n return remainingSeconds % 60 === 0;\n}\n","/* eslint-disable @typescript-eslint/explicit-function-return-type -- Getters/setters have inferred types */\n/* eslint-disable require-atomic-updates -- False positive: connectionRequest is reassigned atomically */\n/* eslint-disable @typescript-eslint/no-misused-promises -- setInterval callback is async intentionally */\nimport { formatRemainingTime, shouldLogCountdown } from './utils';\nimport {\n type ConnectionRequest,\n createLogger,\n type InstallWidgetProps,\n Modal,\n type QRLink,\n} from '../../../domain';\n\nconst logger = createLogger('metamask-sdk:ui');\n\nexport abstract class AbstractInstallModal extends Modal<InstallWidgetProps> {\n protected instance?: HTMLMmInstallModalElement | undefined;\n\n #expirationInterval: NodeJS.Timeout | null = null;\n\n #lastLoggedCountdown: number = -1;\n\n abstract renderQRCode(\n link: QRLink,\n connectionRequest: ConnectionRequest,\n ): void;\n\n get link() {\n return this.data;\n }\n\n set link(link: QRLink) {\n this.data = link;\n }\n\n get connectionRequest() {\n return this.options.connectionRequest;\n }\n\n set connectionRequest(connectionRequest: ConnectionRequest) {\n this.options.connectionRequest = connectionRequest;\n }\n\n protected updateLink(link: QRLink) {\n this.link = link;\n if (this.instance) {\n this.instance.link = link;\n }\n }\n\n protected updateExpiresIn(expiresIn: number) {\n if (expiresIn >= 0 && this.instance) {\n this.instance.expiresIn = expiresIn;\n }\n }\n\n protected startExpirationCheck(connectionRequest: ConnectionRequest): void {\n this.stopExpirationCheck();\n\n let currentConnectionRequest: ConnectionRequest = connectionRequest;\n\n this.#expirationInterval = setInterval(async () => {\n const { sessionRequest } = currentConnectionRequest;\n const now = Date.now();\n const remainingMs = sessionRequest.expiresAt - now;\n\n const remainingSeconds = Math.floor(remainingMs / 1000);\n\n if (\n remainingMs > 0 &&\n shouldLogCountdown(remainingSeconds) &&\n this.#lastLoggedCountdown !== remainingSeconds\n ) {\n const formattedTime = formatRemainingTime(remainingMs);\n logger(\n `[UI: InstallModal-nodejs()] QR code expires in: ${formattedTime} (${remainingSeconds}s)`,\n );\n this.#lastLoggedCountdown = remainingSeconds;\n }\n\n if (now >= sessionRequest.expiresAt) {\n this.stopExpirationCheck();\n logger(\n '[UI: InstallModal-nodejs()] ⏰ QR code EXPIRED! Generating new one...',\n );\n try {\n // Generate new session request\n currentConnectionRequest =\n await this.options.createConnectionRequest();\n const generateQRCode = await this.options.generateQRCode(\n currentConnectionRequest,\n );\n this.#lastLoggedCountdown = -1; // Reset countdown logging\n\n // Update local instances with new data\n this.updateLink(generateQRCode);\n this.updateExpiresIn(remainingSeconds);\n\n // Render QRCode on each platform\n this.renderQRCode(generateQRCode, currentConnectionRequest);\n } catch (error) {\n logger(\n `[UI: InstallModal-nodejs()] ❌ Error generating new QR code: ${error}`,\n );\n }\n }\n }, 1000);\n }\n\n protected stopExpirationCheck(): void {\n if (this.#expirationInterval) {\n clearInterval(this.#expirationInterval);\n this.#expirationInterval = null;\n logger(\n '[UI: InstallModal-nodejs()] 🛑 Stopped QR code expiration checking',\n );\n }\n }\n}\n","/* eslint-disable @typescript-eslint/explicit-function-return-type */\n/* eslint-disable no-restricted-syntax */\nimport encodeQR from '@paulmillr/qr';\n\nimport {\n type ConnectionRequest,\n createLogger,\n type QRLink,\n} from '../../../domain';\nimport { AbstractInstallModal } from '../base/AbstractInstallModal';\nimport { formatRemainingTime, shouldLogCountdown } from '../base/utils';\n\nconst logger = createLogger('metamask-sdk:ui');\n\nexport class InstallModal extends AbstractInstallModal {\n private displayQRWithCountdown(qrCodeLink: QRLink, expiresInMs: number) {\n const isExpired = expiresInMs <= 0;\n const formattedTime = formatRemainingTime(expiresInMs);\n const qrCode = encodeQR(qrCodeLink, 'ascii');\n\n // Clear console and display QR code with live countdown\n console.clear();\n console.log(qrCode);\n\n if (isExpired) {\n console.log('EXPIRED - Generating new QR code...');\n } else {\n console.log(`EXPIRES IN: ${formattedTime}`);\n }\n }\n\n renderQRCode(link: QRLink, connectionRequest: ConnectionRequest): void {\n const { sessionRequest } = connectionRequest;\n const expiresIn = sessionRequest.expiresAt - Date.now();\n const expiresInSeconds = Math.floor(expiresIn / 1000);\n const shouldLog = shouldLogCountdown(expiresInSeconds);\n const formattedTime = formatRemainingTime(expiresIn);\n this.startExpirationCheck(connectionRequest);\n\n this.displayQRWithCountdown(link, expiresIn);\n\n if (shouldLog) {\n logger(\n `[UI: InstallModal-nodejs()] QR code expires in: ${formattedTime} (${expiresIn}ms)`,\n );\n }\n }\n\n mount() {\n if (!this.link) {\n throw new Error('Session request is required');\n }\n const { link, connectionRequest } = this;\n this.renderQRCode(link, connectionRequest);\n }\n\n unmount(): void {\n console.clear();\n this.stopExpirationCheck();\n }\n}\n","import { Modal, type OTPCodeWidgetProps } from '../../../domain';\n\nexport abstract class AbstractOTPCodeModal extends Modal<OTPCodeWidgetProps> {\n protected instance?: HTMLMmOtpModalElement | undefined;\n\n get otpCode(): string {\n return this.data;\n }\n\n set otpCode(code: string) {\n this.data = code;\n }\n\n updateOTPCode(code: string): void {\n this.otpCode = code;\n if (this.instance) {\n this.instance.otpCode = code;\n }\n }\n}\n","import { AbstractOTPCodeModal } from '../base/AbstractOTPModal';\n\n/**\n * TODO: This is a placeholder for the OTP code modal.\n * It will be replaced with the actual OTP code modal once it is implemented.\n */\nexport class OTPCodeModal extends AbstractOTPCodeModal {\n mount(): void {\n // No-op: placeholder implementation\n }\n\n unmount(): void {\n // No-op: placeholder implementation\n }\n}\n","export { InstallModal } from './install';\nexport { OTPCodeModal } from './otp';\n","import { StoreAdapter } from '../../domain';\n\nexport class StoreAdapterNode extends StoreAdapter {\n readonly platform = 'node';\n\n readonly #storage = new Map<string, string>();\n\n async get(key: string): Promise<string | null> {\n return this.#storage.get(key) ?? null;\n }\n\n async set(key: string, value: string): Promise<void> {\n this.#storage.set(key, value);\n }\n\n async delete(key: string): Promise<void> {\n this.#storage.delete(key);\n }\n}\n","import type { CreateMultichainFN, StoreClient } from './domain';\nimport { enableDebug } from './domain';\nimport { MetaMaskConnectMultichain } from './multichain';\nimport { Store } from './store';\nimport { ModalFactory } from './ui';\n\nexport * from './domain';\n\nexport const createMultichainClient: CreateMultichainFN = async (options) => {\n if (options.debug) {\n enableDebug('metamask-sdk:*');\n }\n\n const uiModules = await import('./ui/modals/node');\n let storage: StoreClient;\n if (options.storage) {\n storage = options.storage;\n } else {\n const { StoreAdapterNode } = await import('./store/adapters/node');\n const adapter = new StoreAdapterNode();\n storage = new Store(adapter);\n }\n const factory = new ModalFactory(uiModules);\n return MetaMaskConnectMultichain.create({\n ...options,\n storage,\n ui: {\n ...options.ui,\n factory,\n },\n });\n};\n","/* eslint-disable @typescript-eslint/no-misused-promises */\n/* eslint-disable @typescript-eslint/naming-convention */\n/* eslint-disable no-restricted-globals */\n/* eslint-disable promise/always-return -- Event handlers */\n/* eslint-disable no-async-promise-executor -- Async promise executor needed for complex flow */\nimport { analytics } from '@metamask/analytics';\nimport {\n ErrorCode,\n ProtocolError,\n type SessionRequest,\n SessionStore,\n WebSocketTransport,\n} from '@metamask/mobile-wallet-protocol-core';\nimport { DappClient } from '@metamask/mobile-wallet-protocol-dapp-client';\nimport {\n type SessionProperties,\n getMultichainClient,\n type MultichainApiClient,\n type SessionData,\n} from '@metamask/multichain-api-client';\nimport type { CaipAccountId, Json } from '@metamask/utils';\n\nimport {\n METAMASK_CONNECT_BASE_URL,\n METAMASK_DEEPLINK_BASE,\n MWP_RELAY_URL,\n} from '../config';\nimport {\n getVersion,\n type InvokeMethodOptions,\n type MultichainOptions,\n type RPCAPI,\n type Scope,\n type StoreClient,\n TransportType,\n} from '../domain';\nimport {\n getBaseAnalyticsProperties,\n isRejectionError,\n} from './utils/analytics';\nimport {\n createLogger,\n enableDebug,\n isEnabled as isLoggerEnabled,\n} from '../domain/logger';\nimport {\n type ConnectionRequest,\n type ExtendedTransport,\n MultichainCore,\n type ConnectionStatus,\n} from '../domain/multichain';\nimport {\n getPlatformType,\n hasExtension,\n isSecure,\n PlatformType,\n} from '../domain/platform';\nimport { RpcClient } from './rpc/handlers/rpcClient';\nimport { RequestRouter } from './rpc/requestRouter';\nimport { DefaultTransport } from './transports/default';\nimport { MultichainApiClientWrapperTransport } from './transports/multichainApiClientWrapper';\nimport { MWPTransport } from './transports/mwp';\nimport { keymanager } from './transports/mwp/KeyManager';\nimport {\n getDappId,\n getGlobalObject,\n mergeRequestedSessionWithExisting,\n openDeeplink,\n setupDappMetadata,\n} from './utils';\n\nexport { getInfuraRpcUrls } from '../domain/multichain/api/infura';\n\n// ENFORCE NAMESPACE THAT CAN BE DISABLED\nconst logger = createLogger('metamask-sdk:core');\n\nconst SINGLETON_KEY = '__METAMASK_CONNECT_MULTICHAIN_SINGLETON__';\n\nexport class MetaMaskConnectMultichain extends MultichainCore {\n readonly #provider: MultichainApiClient<RPCAPI>;\n\n readonly #providerTransportWrapper: MultichainApiClientWrapperTransport;\n\n #transport: ExtendedTransport | undefined = undefined;\n\n #dappClient: DappClient | undefined = undefined;\n\n #beforeUnloadListener: (() => void) | undefined;\n\n public _status: ConnectionStatus = 'pending';\n\n #listener: (() => void | Promise<void>) | undefined;\n\n get status(): ConnectionStatus {\n return this._status;\n }\n\n set status(value: ConnectionStatus) {\n this._status = value;\n this.options.transport?.onNotification?.({\n method: 'stateChanged',\n params: value,\n });\n }\n\n get provider(): MultichainApiClient<RPCAPI> {\n return this.#provider;\n }\n\n get transport(): ExtendedTransport {\n if (!this.#transport) {\n throw new Error('Transport not initialized, establish connection first');\n }\n return this.#transport;\n }\n\n get dappClient(): DappClient {\n if (!this.#dappClient) {\n throw new Error('DappClient not initialized, establish connection first');\n }\n return this.#dappClient;\n }\n\n get storage(): StoreClient {\n return this.options.storage;\n }\n\n get transportType(): TransportType {\n return this.#transport instanceof MWPTransport\n ? TransportType.MWP\n : TransportType.Browser;\n }\n\n readonly #sdkInfo = `Sdk/Javascript SdkVersion/${getVersion()} Platform/${getPlatformType()} dApp/${this.options.dapp.url ?? this.options.dapp.name} dAppTitle/${this.options.dapp.name}`;\n\n constructor(options: MultichainOptions) {\n const withDappMetadata = setupDappMetadata(options);\n const integrationType = options.analytics?.integrationType ?? 'direct';\n const allOptions = {\n ...withDappMetadata,\n ui: {\n ...withDappMetadata.ui,\n preferExtension: withDappMetadata.ui.preferExtension ?? true,\n showInstallModal: withDappMetadata.ui.showInstallModal ?? false,\n headless: withDappMetadata.ui.headless ?? false,\n },\n analytics: {\n ...(options.analytics ?? {}),\n integrationType,\n },\n };\n\n super(allOptions);\n\n this.#providerTransportWrapper = new MultichainApiClientWrapperTransport(\n this,\n );\n this.#provider = getMultichainClient({\n transport: this.#providerTransportWrapper,\n });\n }\n\n // Creates a singleton instance of MetaMaskConnectMultichain.\n // If the singleton already exists, it merges the incoming options with the\n // existing singleton options for the following keys: `api.supportedNetworks`,\n // `ui.*`, `mobile.*`, `transport.extensionId`, `debug`. Take note that the\n // value for `dapp` is not merged as it does not make sense for subsequent calls to\n // `createMultichainClient` to have a different `dapp` value.\n static async create(\n options: MultichainOptions,\n ): Promise<MetaMaskConnectMultichain> {\n const globalObject = getGlobalObject();\n const existing = globalObject[SINGLETON_KEY] as\n | Promise<MetaMaskConnectMultichain>\n | undefined;\n if (existing) {\n const instance = await existing;\n instance.mergeOptions(options);\n if (options.debug) {\n enableDebug('metamask-sdk:*');\n }\n return instance;\n }\n\n const instancePromise = (async (): Promise<MetaMaskConnectMultichain> => {\n const instance = new MetaMaskConnectMultichain(options);\n const isEnabled = await isLoggerEnabled(\n 'metamask-sdk:core',\n instance.options.storage,\n );\n if (isEnabled) {\n enableDebug('metamask-sdk:core');\n }\n await instance.#init();\n return instance;\n })();\n\n globalObject[SINGLETON_KEY] = instancePromise;\n\n instancePromise.catch((error) => {\n globalObject[SINGLETON_KEY] = undefined;\n console.error('Error initializing MetaMaskConnectMultichain', error);\n });\n\n return instancePromise;\n }\n\n async #setupAnalytics(): Promise<void> {\n const platform = getPlatformType();\n const isBrowser =\n platform === PlatformType.MetaMaskMobileWebview ||\n platform === PlatformType.DesktopWeb ||\n platform === PlatformType.MobileWeb;\n\n const isReactNative = platform === PlatformType.ReactNative;\n\n if (!isBrowser && !isReactNative) {\n return;\n }\n\n const version = getVersion();\n const dappId = getDappId(this.options.dapp);\n const anonId = await this.storage.getAnonId();\n\n const { integrationType } = this.options.analytics ?? {\n integrationType: '',\n };\n analytics.setGlobalProperty('mmconnect_version', version);\n analytics.setGlobalProperty('dapp_id', dappId);\n analytics.setGlobalProperty('anon_id', anonId);\n analytics.setGlobalProperty('platform', platform);\n analytics.setGlobalProperty('integration_type', integrationType);\n analytics.enable();\n }\n\n async #onTransportNotification(payload: any): Promise<void> {\n if (\n typeof payload === 'object' &&\n payload !== null &&\n 'method' in payload\n ) {\n this.emit(payload.method as string, payload.params ?? payload.result);\n }\n }\n\n async #getStoredTransport(): Promise<\n DefaultTransport | MWPTransport | undefined\n > {\n const transportType = await this.storage.getTransport();\n const hasExtensionInstalled = await hasExtension();\n if (transportType) {\n if (transportType === TransportType.Browser) {\n if (hasExtensionInstalled) {\n const apiTransport = new DefaultTransport();\n this.#transport = apiTransport;\n this.#providerTransportWrapper.setupTransportNotificationListener();\n this.#listener = apiTransport.onNotification(\n this.#onTransportNotification.bind(this),\n );\n return apiTransport;\n }\n } else if (transportType === TransportType.MWP) {\n const { adapter: kvstore } = this.options.storage;\n const dappClient = await this.#createDappClient();\n const apiTransport = new MWPTransport(dappClient, kvstore);\n this.#dappClient = dappClient;\n this.#transport = apiTransport;\n this.#providerTransportWrapper.setupTransportNotificationListener();\n this.#listener = apiTransport.onNotification(\n this.#onTransportNotification.bind(this),\n );\n return apiTransport;\n }\n\n await this.storage.removeTransport();\n }\n\n return undefined;\n }\n\n async #setupTransport(): Promise<void> {\n const transport = await this.#getStoredTransport();\n if (transport) {\n if (!this.transport.isConnected()) {\n this.status = 'connecting';\n await this.transport.connect();\n }\n this.status = 'connected';\n if (this.transport instanceof MWPTransport) {\n await this.storage.setTransport(TransportType.MWP);\n } else {\n await this.storage.setTransport(TransportType.Browser);\n }\n } else {\n this.status = 'loaded';\n }\n }\n\n async #init(): Promise<void> {\n try {\n await this.#setupAnalytics();\n await this.#setupTransport();\n try {\n const baseProps = await getBaseAnalyticsProperties(\n this.options,\n this.storage,\n );\n analytics.track('mmconnect_initialized', baseProps);\n } catch (error) {\n logger('Error tracking initialized event', error);\n }\n } catch (error) {\n await this.storage.removeTransport();\n this.status = 'pending';\n logger('MetaMaskSDK error during initialization', error);\n }\n }\n\n async #createDappClient(): Promise<DappClient> {\n const { adapter: kvstore } = this.options.storage;\n const sessionstore = new SessionStore(kvstore);\n const websocket =\n // eslint-disable-next-line no-negated-condition\n typeof window !== 'undefined'\n ? WebSocket\n : (await import('ws')).WebSocket;\n const transport = await WebSocketTransport.create({\n url: MWP_RELAY_URL,\n kvstore,\n websocket,\n });\n const dappClient = new DappClient({ transport, sessionstore, keymanager });\n return dappClient;\n }\n\n async #setupMWP(): Promise<void> {\n if (this.#transport instanceof MWPTransport) {\n return;\n }\n // Only setup MWP if it is not already mwp\n const { adapter: kvstore } = this.options.storage;\n const dappClient = await this.#createDappClient();\n this.#dappClient = dappClient;\n const apiTransport = new MWPTransport(dappClient, kvstore);\n this.#transport = apiTransport;\n this.#providerTransportWrapper.setupTransportNotificationListener();\n this.#listener = this.transport.onNotification(\n this.#onTransportNotification.bind(this),\n );\n await this.storage.setTransport(TransportType.MWP);\n }\n\n async #onBeforeUnload(): Promise<void> {\n // Fixes glitch with \"connecting\" state when modal is still visible and we close screen or refresh\n if (this.options.ui.factory.modal?.isMounted) {\n await this.storage.removeTransport();\n }\n }\n\n #createBeforeUnloadListener(): () => void {\n const handler = this.#onBeforeUnload.bind(this);\n\n if (\n typeof window !== 'undefined' &&\n typeof window.addEventListener !== 'undefined'\n ) {\n window.addEventListener('beforeunload', handler);\n }\n return () => {\n if (\n typeof window !== 'undefined' &&\n typeof window.removeEventListener !== 'undefined'\n ) {\n window.removeEventListener('beforeunload', handler);\n }\n };\n }\n\n async #renderInstallModalAsync(\n desktopPreferred: boolean,\n scopes: Scope[],\n caipAccountIds: CaipAccountId[],\n sessionProperties?: SessionProperties,\n ): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n // Use Connection Modal\n this.options.ui.factory\n .renderInstallModal(\n desktopPreferred,\n async () => {\n if (\n this.dappClient.state === 'CONNECTED' ||\n this.dappClient.state === 'CONNECTING'\n ) {\n await this.dappClient.disconnect();\n }\n return new Promise<ConnectionRequest>((_resolve) => {\n this.dappClient.on(\n 'session_request',\n (sessionRequest: SessionRequest) => {\n _resolve({\n sessionRequest,\n metadata: {\n dapp: this.options.dapp,\n sdk: {\n version: getVersion(),\n platform: getPlatformType(),\n },\n },\n });\n },\n );\n\n (async (): Promise<void> => {\n try {\n await this.transport.connect({\n scopes,\n caipAccountIds,\n sessionProperties,\n });\n await this.options.ui.factory.unload();\n this.options.ui.factory.modal?.unmount();\n this.status = 'connected';\n await this.storage.setTransport(TransportType.MWP);\n } catch (error) {\n if (error instanceof ProtocolError) {\n // Ignore Request expired errors to allow modal to regenerate expired qr codes\n if (error.code !== ErrorCode.REQUEST_EXPIRED) {\n this.status = 'disconnected';\n // Close the modal on error\n await this.options.ui.factory.unload(error);\n reject(error);\n }\n // If request is expires, the QRCode will automatically be regenerated we can ignore this case\n } else {\n this.status = 'disconnected';\n const normalizedError =\n error instanceof Error ? error : new Error(String(error));\n // Close the modal on error\n await this.options.ui.factory.unload(normalizedError);\n reject(normalizedError);\n }\n }\n })().catch(() => {\n // Error already handled in the async function\n });\n });\n },\n async (error?: Error) => {\n if (error) {\n await this.storage.removeTransport();\n reject(error);\n } else {\n await this.storage.setTransport(TransportType.MWP);\n resolve();\n }\n },\n (uri: string) => {\n this.emit('display_uri', uri);\n },\n )\n .catch((error) => {\n reject(error instanceof Error ? error : new Error(String(error)));\n });\n });\n }\n\n async #showInstallModal(\n desktopPreferred: boolean,\n scopes: Scope[],\n caipAccountIds: CaipAccountId[],\n sessionProperties?: SessionProperties,\n ): Promise<void> {\n // create the listener only once to avoid memory leaks\n this.#beforeUnloadListener ??= this.#createBeforeUnloadListener();\n\n // In headless mode, don't render UI but still emit display_uri events\n if (this.options.ui.headless) {\n await this.#headlessConnect(scopes, caipAccountIds, sessionProperties);\n } else {\n await this.#renderInstallModalAsync(\n desktopPreferred,\n scopes,\n caipAccountIds,\n sessionProperties,\n );\n }\n }\n\n /**\n * Handles connection in headless mode without rendering any UI.\n * Emits display_uri events to allow consumers to build custom QR code UI.\n *\n * @param scopes - The requested permission scopes\n * @param caipAccountIds - The requested account IDs\n * @param sessionProperties - Optional session properties\n */\n async #headlessConnect(\n scopes: Scope[],\n caipAccountIds: CaipAccountId[],\n sessionProperties?: SessionProperties,\n ): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (\n this.dappClient.state === 'CONNECTED' ||\n this.dappClient.state === 'CONNECTING'\n ) {\n this.dappClient.disconnect().catch(() => {\n // Ignore disconnect errors\n });\n }\n\n // Listen for session_request to generate and emit the QR code link\n this.dappClient.on(\n 'session_request',\n (sessionRequest: SessionRequest) => {\n const connectionRequest: ConnectionRequest = {\n sessionRequest,\n metadata: {\n dapp: this.options.dapp,\n sdk: {\n version: getVersion(),\n platform: getPlatformType(),\n },\n },\n };\n\n // Generate and emit the QR code link\n const deeplink =\n this.options.ui.factory.createConnectionDeeplink(connectionRequest);\n this.emit('display_uri', deeplink);\n },\n );\n\n // Start the connection\n this.transport\n .connect({ scopes, caipAccountIds, sessionProperties })\n .then(async () => {\n this.status = 'connected';\n await this.storage.setTransport(TransportType.MWP);\n resolve();\n })\n .catch(async (error) => {\n if (error instanceof ProtocolError) {\n // In headless mode, we don't auto-regenerate QR codes\n // since there's no modal to display them\n this.status = 'disconnected';\n await this.storage.removeTransport();\n reject(error);\n } else {\n this.status = 'disconnected';\n await this.storage.removeTransport();\n reject(error instanceof Error ? error : new Error(String(error)));\n }\n });\n });\n }\n\n async #setupDefaultTransport(): Promise<DefaultTransport> {\n this.status = 'connecting';\n await this.storage.setTransport(TransportType.Browser);\n const transport = new DefaultTransport();\n this.#listener = transport.onNotification(\n this.#onTransportNotification.bind(this),\n );\n this.#transport = transport;\n this.#providerTransportWrapper.setupTransportNotificationListener();\n return transport;\n }\n\n async #deeplinkConnect(\n scopes: Scope[],\n caipAccountIds: CaipAccountId[],\n sessionProperties?: SessionProperties,\n ): Promise<void> {\n return new Promise<void>(async (resolve, reject) => {\n // Handle the response to the initial wallet_createSession request\n const dappClientMessageHandler = (payload: unknown): void => {\n if (\n typeof payload !== 'object' ||\n payload === null ||\n !('data' in payload)\n ) {\n return;\n }\n const data = payload.data as { result?: SessionData; error?: unknown };\n if (typeof data === 'object' && data !== null) {\n // optimistically assume any error is due to the initial wallet_createSession request failure\n if (data.error) {\n this.dappClient.off('message', dappClientMessageHandler);\n reject(data.error as Error);\n }\n // if sessionScopes is set in the result, then this is a response to wallet_createSession\n if (data?.result?.sessionScopes) {\n this.dappClient.off('message', dappClientMessageHandler);\n // unsure if we need to call resolve here like we do above for reject()\n }\n }\n };\n this.dappClient.on('message', dappClientMessageHandler);\n\n let timeout: NodeJS.Timeout | undefined;\n\n if (this.transport.isConnected()) {\n timeout = setTimeout(() => {\n this.openSimpleDeeplinkIfNeeded();\n }, 250);\n } else {\n this.dappClient.once(\n 'session_request',\n (sessionRequest: SessionRequest) => {\n const connectionRequest = {\n sessionRequest,\n metadata: {\n dapp: this.options.dapp,\n sdk: { version: getVersion(), platform: getPlatformType() },\n },\n };\n const deeplink =\n this.options.ui.factory.createConnectionDeeplink(\n connectionRequest,\n );\n const universalLink =\n this.options.ui.factory.createConnectionUniversalLink(\n connectionRequest,\n );\n\n // Emit display_uri event for deeplink connections\n this.emit('display_uri', deeplink);\n\n if (this.options.mobile?.preferredOpenLink) {\n this.options.mobile.preferredOpenLink(deeplink, '_self');\n } else {\n openDeeplink(this.options, deeplink, universalLink);\n }\n },\n );\n }\n\n return this.transport\n .connect({ scopes, caipAccountIds, sessionProperties })\n .then(resolve)\n .catch(async (error) => {\n await this.storage.removeTransport();\n this.dappClient.off('message', dappClientMessageHandler);\n reject(error instanceof Error ? error : new Error(String(error)));\n })\n .finally(() => {\n if (timeout) {\n clearTimeout(timeout);\n }\n });\n });\n }\n\n async #handleConnection(\n promise: Promise<void>,\n scopes: Scope[],\n transportType: TransportType,\n ): Promise<void> {\n this.status = 'connecting';\n return promise\n .then(async () => {\n this.status = 'connected';\n try {\n const baseProps = await getBaseAnalyticsProperties(\n this.options,\n this.storage,\n );\n\n analytics.track('mmconnect_connection_established', {\n ...baseProps,\n transport_type: transportType,\n user_permissioned_chains: scopes,\n });\n } catch (error) {\n logger('Error tracking connection_established event', error);\n }\n return undefined; // explicitly return `undefined` to avoid eslintpromise/always-return\n })\n .catch(async (error) => {\n this.status = 'disconnected';\n try {\n const baseProps = await getBaseAnalyticsProperties(\n this.options,\n this.storage,\n );\n const isRejection = isRejectionError(error);\n\n if (isRejection) {\n analytics.track('mmconnect_connection_rejected', {\n ...baseProps,\n transport_type: transportType,\n });\n } else {\n analytics.track('mmconnect_connection_failed', {\n ...baseProps,\n transport_type: transportType,\n });\n }\n } catch {\n logger('Error tracking connection failed/rejected event', error);\n }\n throw error;\n });\n }\n\n // TODO: make this into param object\n async connect(\n scopes: Scope[],\n caipAccountIds: CaipAccountId[],\n sessionProperties?: SessionProperties,\n forceRequest?: boolean,\n ): Promise<void> {\n if (\n this.status === 'connecting' &&\n this.transportType === TransportType.MWP\n ) {\n await this.#openConnectDeeplinkIfNeeded();\n throw new Error(\n 'Existing connection is pending. Please check your MetaMask Mobile app to continue.',\n );\n }\n const { ui } = this.options;\n const platformType = getPlatformType();\n const isWeb =\n platformType === PlatformType.MetaMaskMobileWebview ||\n platformType === PlatformType.DesktopWeb;\n const { preferExtension = true, showInstallModal = false } = ui;\n const secure = isSecure();\n const hasExtensionInstalled = await hasExtension();\n\n let transportType;\n if (\n platformType === PlatformType.MetaMaskMobileWebview ||\n (isWeb && hasExtensionInstalled && preferExtension)\n ) {\n transportType = TransportType.Browser;\n } else {\n transportType = TransportType.MWP;\n }\n\n try {\n const baseProps = await getBaseAnalyticsProperties(\n this.options,\n this.storage,\n );\n const dappConfiguredChains = Object.keys(\n this.options.api.supportedNetworks,\n );\n\n analytics.track('mmconnect_connection_initiated', {\n ...baseProps,\n transport_type: transportType,\n dapp_configured_chains: dappConfiguredChains,\n dapp_requested_chains: scopes,\n });\n } catch (error) {\n logger('Error tracking connection_initiated event', error);\n }\n\n const sessionData = await this.#getCaipSession();\n\n const { mergedScopes, mergedCaipAccountIds, mergedSessionProperties } =\n mergeRequestedSessionWithExisting(\n sessionData,\n scopes,\n caipAccountIds,\n sessionProperties,\n );\n\n // Needed because empty object will cause wallet_createSession to return an error\n const nonEmptySessionProperties =\n Object.keys(mergedSessionProperties ?? {}).length > 0\n ? mergedSessionProperties\n : undefined;\n\n if (this.#transport?.isConnected() && !secure) {\n return this.#handleConnection(\n this.#transport\n .connect({\n scopes: mergedScopes,\n caipAccountIds: mergedCaipAccountIds,\n sessionProperties: nonEmptySessionProperties,\n forceRequest,\n })\n .then(async () => {\n if (this.#transport instanceof MWPTransport) {\n return this.storage.setTransport(TransportType.MWP);\n }\n return this.storage.setTransport(TransportType.Browser);\n }),\n scopes,\n transportType,\n );\n }\n\n // In MetaMask Mobile In App Browser, window.ethereum is available directly\n if (platformType === PlatformType.MetaMaskMobileWebview) {\n const defaultTransport = await this.#setupDefaultTransport();\n return this.#handleConnection(\n defaultTransport.connect({\n scopes: mergedScopes,\n caipAccountIds: mergedCaipAccountIds,\n sessionProperties: nonEmptySessionProperties,\n forceRequest,\n }),\n scopes,\n transportType,\n );\n }\n\n if (isWeb && hasExtensionInstalled && preferExtension) {\n // If metamask extension is available, connect to it\n const defaultTransport = await this.#setupDefaultTransport();\n // Web transport has no initial payload\n return this.#handleConnection(\n defaultTransport.connect({\n scopes: mergedScopes,\n caipAccountIds: mergedCaipAccountIds,\n sessionProperties: nonEmptySessionProperties,\n forceRequest,\n }),\n scopes,\n transportType,\n );\n }\n\n // Connection will now be InstallModal + QRCodes or Deeplinks, both require mwp\n await this.#setupMWP();\n\n // Determine preferred option for install modal\n const shouldShowInstallModal = hasExtensionInstalled\n ? showInstallModal\n : !preferExtension || showInstallModal;\n\n if (secure && !shouldShowInstallModal) {\n // Desktop is not preferred option, so we use deeplinks (mobile web)\n return this.#handleConnection(\n this.#deeplinkConnect(\n mergedScopes,\n mergedCaipAccountIds,\n nonEmptySessionProperties,\n ),\n scopes,\n transportType,\n );\n }\n\n // Show install modal for RN, Web + Node\n return this.#handleConnection(\n this.#showInstallModal(\n shouldShowInstallModal,\n mergedScopes,\n mergedCaipAccountIds,\n nonEmptySessionProperties,\n ),\n scopes,\n transportType,\n );\n }\n\n public override emit(event: string, args: any): void {\n this.options.transport?.onNotification?.({ method: event, params: args });\n super.emit(event, args);\n }\n\n async #getCaipSession(): Promise<SessionData> {\n let sessionData: SessionData = {\n sessionScopes: {},\n sessionProperties: {},\n };\n if (this.status === 'connected') {\n const response = await this.transport.request({\n method: 'wallet_getSession',\n });\n if (response.result) {\n sessionData = response.result as SessionData;\n }\n }\n return sessionData;\n }\n\n async disconnect(scopes: Scope[] = []): Promise<void> {\n const sessionData = await this.#getCaipSession();\n\n const remainingScopes =\n scopes.length === 0\n ? []\n : Object.keys(sessionData.sessionScopes).filter(\n (scope) => !scopes.includes(scope as Scope),\n );\n\n await this.#transport?.disconnect(scopes);\n\n if (remainingScopes.length === 0) {\n await this.#listener?.();\n this.#beforeUnloadListener?.();\n\n await this.storage.removeTransport();\n\n this.#listener = undefined;\n this.#beforeUnloadListener = undefined;\n this.#transport = undefined;\n this.#providerTransportWrapper.clearTransportNotificationListener();\n this.#dappClient = undefined;\n this.status = 'disconnected';\n }\n }\n\n async invokeMethod(request: InvokeMethodOptions): Promise<Json> {\n const { transport, options } = this;\n\n const rpcClient = new RpcClient(options, this.#sdkInfo);\n const requestRouter = new RequestRouter(transport, rpcClient, options);\n // TODO: need read only method support for solana\n return requestRouter.invokeMethod(request);\n }\n\n // DRY THIS WITH REQUEST ROUTER\n openSimpleDeeplinkIfNeeded(): void {\n const { ui, mobile } = this.options;\n const { showInstallModal = false } = ui ?? {};\n const secure = isSecure();\n const shouldOpenDeeplink = secure && !showInstallModal;\n\n if (shouldOpenDeeplink) {\n setTimeout(async () => {\n const session = await this.transport.getActiveSession();\n if (!session) {\n throw new Error('No active session found');\n }\n\n const url = `${METAMASK_DEEPLINK_BASE}/mwp?id=${encodeURIComponent(session.id)}`;\n if (mobile?.preferredOpenLink) {\n mobile.preferredOpenLink(url, '_self');\n } else {\n openDeeplink(this.options, url, METAMASK_CONNECT_BASE_URL);\n }\n }, 10); // small delay to ensure the message encryption and dispatch completes\n }\n }\n\n async #openConnectDeeplinkIfNeeded(): Promise<void> {\n const { ui } = this.options;\n const { showInstallModal = false } = ui ?? {};\n const secure = isSecure();\n const shouldOpenDeeplink = secure && !showInstallModal;\n\n if (!shouldOpenDeeplink) {\n return;\n }\n\n const storedSessionRequest =\n await this.#transport?.getStoredPendingSessionRequest();\n if (!storedSessionRequest) {\n return;\n }\n\n const connectionRequest = {\n sessionRequest: storedSessionRequest,\n metadata: {\n dapp: this.options.dapp,\n sdk: { version: getVersion(), platform: getPlatformType() },\n },\n };\n const deeplink =\n this.options.ui.factory.createConnectionDeeplink(connectionRequest);\n\n const universalLink =\n this.options.ui.factory.createConnectionUniversalLink(connectionRequest);\n\n if (this.options.mobile?.preferredOpenLink) {\n this.options.mobile.preferredOpenLink(deeplink, '_self');\n } else {\n openDeeplink(this.options, deeplink, universalLink);\n }\n }\n\n // Provides a way for ecosystem clients (EVM, Solana, etc.) to get the current CAIP session data\n // when instantiating themselves (as they would have already missed any initial sessionChanged events emitted by ConnectMultichain)\n // without having to concern themselves with the current transport connection status.\n async emitSessionChanged(): Promise<void> {\n const emptySession = { sessionScopes: {} };\n\n if (this.status !== 'connected' && this.status !== 'connecting') {\n // If we aren't connected or connecting, there definitely is no active CAIP session\n // so we optimistically emit an empty session to signify that to the ecosystem client consumers (EVM, Solana, etc.)\n this.emit('wallet_sessionChanged', emptySession);\n return;\n }\n\n // Otherwise, we need to fetch the current CAIP session from the wallet\n const response = await this.transport.request({\n method: 'wallet_getSession',\n });\n\n // And then simulate a sessionChanged event with the current CAIP session data\n this.emit('wallet_sessionChanged', response.result ?? emptySession);\n }\n}\n","export const MWP_RELAY_URL =\n 'wss://mm-sdk-relay.api.cx.metamask.io/connection/websocket';\n\nexport const METAMASK_CONNECT_BASE_URL = 'https://metamask.app.link/connect';\nexport const METAMASK_DEEPLINK_BASE = 'metamask://connect';\n","/* eslint-disable no-restricted-syntax -- Private class properties use established patterns */\n/* eslint-disable @typescript-eslint/explicit-function-return-type -- Inferred types are sufficient */\n/* eslint-disable @typescript-eslint/parameter-properties -- Constructor shorthand is intentional */\n/* eslint-disable @typescript-eslint/no-shadow -- fetch import shadows global */\n\nimport type { Json } from '@metamask/utils';\nimport fetch from 'cross-fetch';\n\nimport {\n RPCHttpErr,\n RPCReadonlyRequestErr,\n RPCReadonlyResponseErr,\n} from '../../../domain';\nimport type {\n RPCResponse,\n RpcUrlsMap,\n Scope,\n InvokeMethodOptions,\n MultichainOptions,\n} from '../../../domain';\n\nlet rpcId = 1;\n\n/**\n * Gets the next RPC ID for request tracking.\n *\n * @returns The next unique RPC ID.\n */\nexport function getNextRpcId(): number {\n rpcId += 1;\n return rpcId;\n}\n\nexport class MissingRpcEndpointErr extends Error {}\n\nexport class RpcClient {\n constructor(\n private readonly config: MultichainOptions,\n private readonly sdkInfo: string,\n ) {}\n\n /**\n * Routes the request to a configured RPC node.\n *\n * @param options - The invoke method options.\n * @returns The JSON response from the RPC node.\n */\n async request(options: InvokeMethodOptions): Promise<Json> {\n const { request } = options;\n const body = JSON.stringify({\n jsonrpc: '2.0',\n method: request.method,\n params: request.params,\n id: getNextRpcId(),\n });\n const rpcEndpoint = this.getRpcEndpoint(options.scope);\n const rpcRequest = await this.fetchWithTimeout(\n rpcEndpoint,\n body,\n 'POST',\n this.getHeaders(rpcEndpoint),\n 30_000,\n ); // 30 seconds default timeout\n const response = await this.parseResponse(rpcRequest);\n return response;\n }\n\n private getRpcEndpoint(scope: Scope) {\n const supportedNetworks: RpcUrlsMap =\n this.config?.api?.supportedNetworks ?? {};\n\n const rpcEndpoint = supportedNetworks[scope];\n if (!rpcEndpoint) {\n throw new MissingRpcEndpointErr(\n `No RPC endpoint found for scope ${scope}`,\n );\n }\n return rpcEndpoint;\n }\n\n private async fetchWithTimeout(\n endpoint: string,\n body: string,\n method: string,\n headers: Record<string, string>,\n timeout: number,\n ): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(endpoint, {\n method,\n headers,\n body,\n signal: controller.signal,\n });\n clearTimeout(timeoutId);\n if (!response.ok) {\n throw new RPCHttpErr(endpoint, method, response.status);\n }\n return response;\n } catch (error) {\n clearTimeout(timeoutId);\n if (error instanceof RPCHttpErr) {\n throw error;\n }\n if (error instanceof Error && error.name === 'AbortError') {\n throw new RPCReadonlyRequestErr(`Request timeout after ${timeout}ms`);\n }\n throw new RPCReadonlyRequestErr(error.message);\n }\n }\n\n private async parseResponse(response: Response) {\n try {\n const rpcResponse = (await response.json()) as RPCResponse;\n return rpcResponse.result as Json;\n } catch (error) {\n throw new RPCReadonlyResponseErr(error.message);\n }\n }\n\n private getHeaders(rpcEndpoint: string) {\n const defaultHeaders = {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n };\n if (rpcEndpoint.includes('infura')) {\n return {\n ...defaultHeaders,\n 'Metamask-Sdk-Info': this.sdkInfo,\n };\n }\n return defaultHeaders;\n }\n}\n","/* eslint-disable no-restricted-syntax -- Private class properties use established patterns */\n/* eslint-disable @typescript-eslint/parameter-properties -- Constructor shorthand is intentional */\n/* eslint-disable jsdoc/require-param-description -- Auto-generated JSDoc */\n/* eslint-disable jsdoc/require-returns -- Auto-generated JSDoc */\n/* eslint-disable @typescript-eslint/no-misused-promises -- setTimeout callback is async intentionally */\nimport { analytics } from '@metamask/analytics';\nimport type { Json } from '@metamask/utils';\n\nimport {\n METAMASK_CONNECT_BASE_URL,\n METAMASK_DEEPLINK_BASE,\n} from '../../config';\nimport {\n type ExtendedTransport,\n type InvokeMethodOptions,\n isSecure,\n type MultichainOptions,\n RPC_HANDLED_METHODS,\n RPCInvokeMethodErr,\n SDK_HANDLED_METHODS,\n} from '../../domain';\nimport { openDeeplink } from '../utils';\nimport {\n getWalletActionAnalyticsProperties,\n isRejectionError,\n} from '../utils/analytics';\nimport type { RpcClient } from './handlers/rpcClient';\nimport { MissingRpcEndpointErr } from './handlers/rpcClient';\n\nlet rpcId = 1;\n\n/**\n * Gets the next RPC ID for request tracking.\n *\n * @returns The next unique RPC ID.\n */\nexport function getNextRpcId(): number {\n rpcId += 1;\n return rpcId;\n}\n\nexport class RequestRouter {\n constructor(\n private readonly transport: ExtendedTransport,\n private readonly rpcClient: RpcClient,\n private readonly config: MultichainOptions,\n ) {}\n\n /**\n * The main entry point for invoking an RPC method.\n * This method acts as a router, determining the correct handling strategy\n * for the request and delegating to the appropriate private handler.\n *\n * @param options\n */\n async invokeMethod(options: InvokeMethodOptions): Promise<Json> {\n const { method } = options.request;\n if (RPC_HANDLED_METHODS.has(method)) {\n return this.handleWithRpcNode(options);\n }\n if (SDK_HANDLED_METHODS.has(method)) {\n return this.handleWithSdkState(options);\n }\n return this.handleWithWallet(options);\n }\n\n /**\n * Forwards the request directly to the wallet via the transport.\n *\n * @param options\n */\n private async handleWithWallet(options: InvokeMethodOptions): Promise<Json> {\n return this.#withAnalyticsTracking(options, async () => {\n const request = this.transport.request({\n method: 'wallet_invokeMethod',\n params: options,\n });\n\n const { ui, mobile } = this.config;\n const { showInstallModal = false } = ui ?? {};\n const secure = isSecure();\n const shouldOpenDeeplink = secure && !showInstallModal;\n\n if (shouldOpenDeeplink) {\n setTimeout(async () => {\n const session = await this.transport.getActiveSession();\n if (!session) {\n throw new Error('No active session found');\n }\n\n const url = `${METAMASK_DEEPLINK_BASE}/mwp?id=${encodeURIComponent(session.id)}`;\n if (mobile?.preferredOpenLink) {\n mobile.preferredOpenLink(url, '_self');\n } else {\n openDeeplink(this.config, url, METAMASK_CONNECT_BASE_URL);\n }\n }, 10); // small delay to ensure the message encryption and dispatch completes\n }\n\n const response = await request;\n if (response.error) {\n const { error } = response;\n throw new RPCInvokeMethodErr(\n `RPC Request failed with code ${error.code}: ${error.message}`,\n );\n }\n\n return response.result as Json;\n });\n }\n\n /**\n * Wraps execution with analytics tracking.\n *\n * @param options - The invoke method options\n * @param execute - The function to execute\n * @returns The result of the execution\n */\n async #withAnalyticsTracking(\n options: InvokeMethodOptions,\n execute: () => Promise<Json>,\n ): Promise<Json> {\n await this.#trackWalletActionRequested(options);\n\n try {\n const result = await execute();\n\n await this.#trackWalletActionSucceeded(options);\n\n return result;\n } catch (error) {\n const isRejection = isRejectionError(error);\n\n if (isRejection) {\n await this.#trackWalletActionRejected(options);\n } else {\n await this.#trackWalletActionFailed(options);\n }\n if (error instanceof RPCInvokeMethodErr) {\n throw error;\n }\n throw new RPCInvokeMethodErr(error.message);\n }\n }\n\n /**\n * Tracks wallet action requested event.\n *\n * @param options\n */\n async #trackWalletActionRequested(\n options: InvokeMethodOptions,\n ): Promise<void> {\n const props = await getWalletActionAnalyticsProperties(\n this.config,\n this.config.storage,\n options,\n );\n analytics.track('mmconnect_wallet_action_requested', props);\n }\n\n /**\n * Tracks wallet action succeeded event.\n *\n * @param options\n */\n async #trackWalletActionSucceeded(\n options: InvokeMethodOptions,\n ): Promise<void> {\n const props = await getWalletActionAnalyticsProperties(\n this.config,\n this.config.storage,\n options,\n );\n analytics.track('mmconnect_wallet_action_succeeded', props);\n }\n\n /**\n * Tracks wallet action failed event.\n *\n * @param options\n */\n async #trackWalletActionFailed(options: InvokeMethodOptions): Promise<void> {\n const props = await getWalletActionAnalyticsProperties(\n this.config,\n this.config.storage,\n options,\n );\n analytics.track('mmconnect_wallet_action_failed', props);\n }\n\n /**\n * Tracks wallet action rejected event.\n *\n * @param options\n */\n async #trackWalletActionRejected(\n options: InvokeMethodOptions,\n ): Promise<void> {\n const props = await getWalletActionAnalyticsProperties(\n this.config,\n this.config.storage,\n options,\n );\n analytics.track('mmconnect_wallet_action_rejected', props);\n }\n\n /**\n * Routes the request to a configured RPC node.\n *\n * @param options\n */\n private async handleWithRpcNode(options: InvokeMethodOptions): Promise<Json> {\n return this.#withAnalyticsTracking(options, async () => {\n try {\n return await this.rpcClient.request(options);\n } catch (error) {\n if (error instanceof MissingRpcEndpointErr) {\n return this.handleWithWallet(options);\n }\n throw error;\n }\n });\n }\n\n /**\n * Responds directly from the SDK's session state.\n *\n * @param options\n */\n private async handleWithSdkState(\n options: InvokeMethodOptions,\n ): Promise<Json> {\n // TODO: to be implemented\n console.warn(\n `Method \"${options.request.method}\" is configured for SDK state handling, but this is not yet implemented. Falling back to wallet passthrough.`,\n );\n // Fallback to wallet\n return this.handleWithWallet(options);\n }\n}\n","import type { Session } from '@metamask/mobile-wallet-protocol-core';\nimport type { SessionRequest } from '@metamask/mobile-wallet-protocol-dapp-client';\nimport {\n type SessionProperties,\n type CreateSessionParams,\n getDefaultTransport,\n type Transport,\n type TransportRequest,\n type TransportResponse,\n} from '@metamask/multichain-api-client';\nimport type { CaipAccountId } from '@metamask/utils';\nimport type { ExtendedTransport, RPCAPI, Scope, SessionData } from 'src/domain';\n\nimport {\n addValidAccounts,\n getOptionalScopes,\n getUniqueRequestId,\n getValidAccounts,\n isSameScopesAndAccounts,\n} from '../../utils';\n\nconst DEFAULT_REQUEST_TIMEOUT = 60 * 1000;\n\ntype PendingRequest = {\n resolve: (value: TransportResponse) => void;\n reject: (error: Error) => void;\n timeout: NodeJS.Timeout;\n};\n\nexport class DefaultTransport implements ExtendedTransport {\n readonly #notificationCallbacks: Set<(data: unknown) => void> = new Set();\n\n readonly #transport: Transport = getDefaultTransport();\n\n readonly #defaultRequestOptions = {\n timeout: DEFAULT_REQUEST_TIMEOUT,\n };\n\n readonly #pendingRequests = new Map<string, PendingRequest>();\n\n #handleResponseListener: ((event: MessageEvent) => void) | undefined;\n\n #handleNotificationListener: ((event: MessageEvent) => void) | undefined;\n\n #notifyCallbacks(data: unknown): void {\n for (const callback of this.#notificationCallbacks) {\n try {\n callback(data);\n } catch (error) {\n console.log(\n '[WindowPostMessageTransport] notifyCallbacks error:',\n error,\n );\n }\n }\n }\n\n #isMetamaskProviderEvent(event: MessageEvent): boolean {\n return (\n event?.data?.data?.name === 'metamask-provider' &&\n // eslint-disable-next-line no-restricted-globals\n event.origin === location.origin\n );\n }\n\n #handleResponse(event: MessageEvent): void {\n if (!this.#isMetamaskProviderEvent(event)) {\n return;\n }\n\n const responseData = event?.data?.data?.data;\n\n // Ignore requests (they have 'method' field) - only process responses\n if (\n typeof responseData === 'object' &&\n responseData !== null &&\n 'method' in responseData\n ) {\n return;\n }\n\n if (\n typeof responseData === 'object' &&\n responseData !== null &&\n 'id' in responseData &&\n ('result' in responseData || 'error' in responseData)\n ) {\n const responseId = String(responseData.id);\n\n const pendingRequest = this.#pendingRequests.get(responseId);\n if (pendingRequest) {\n clearTimeout(pendingRequest.timeout);\n this.#pendingRequests.delete(responseId);\n\n const response = responseData as TransportResponse;\n if ('error' in response && response.error) {\n pendingRequest.reject(\n new Error(response.error.message || 'Request failed'),\n );\n } else {\n pendingRequest.resolve(response);\n }\n }\n }\n }\n\n #handleNotification(event: MessageEvent): void {\n if (!this.#isMetamaskProviderEvent(event)) {\n return;\n }\n\n const responseData = event?.data?.data?.data;\n\n if (\n (typeof responseData === 'object' &&\n responseData.method === 'metamask_chainChanged') ||\n responseData.method === 'metamask_accountsChanged'\n ) {\n this.#notifyCallbacks(responseData);\n }\n }\n\n #setupMessageListener(): void {\n // Only set up listener if it's not already set up for this instance\n if (this.#handleResponseListener) {\n return;\n }\n\n // Create a new handler bound to this instance\n // Rename this to handleResponse or something like this\n this.#handleResponseListener = this.#handleResponse.bind(this);\n this.#handleNotificationListener = this.#handleNotification.bind(this);\n\n // Add the listener\n // eslint-disable-next-line no-restricted-globals\n window.addEventListener('message', this.#handleResponseListener);\n // eslint-disable-next-line no-restricted-globals\n window.addEventListener('message', this.#handleNotificationListener);\n }\n\n async sendEip1193Message<\n TRequest extends TransportRequest,\n TResponse extends TransportResponse,\n >(payload: TRequest, options?: { timeout?: number }): Promise<TResponse> {\n // Setup message listener if not already set up\n this.#setupMessageListener();\n\n // Generate unique request ID - increment counter to ensure uniqueness\n const requestId = String(getUniqueRequestId());\n\n // Create request with ID - MetaMask expects JSON-RPC format\n const request = {\n jsonrpc: '2.0',\n id: requestId,\n ...payload,\n };\n\n return new Promise<TResponse>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.#pendingRequests.delete(requestId);\n reject(new Error('Request timeout'));\n }, options?.timeout ?? this.#defaultRequestOptions.timeout);\n\n this.#pendingRequests.set(requestId, {\n resolve: (response: TransportResponse) => {\n resolve(response as TResponse);\n },\n reject,\n timeout,\n });\n\n // eslint-disable-next-line no-restricted-globals\n window.postMessage(\n {\n target: 'metamask-contentscript',\n data: {\n name: 'metamask-provider',\n data: request,\n },\n },\n // eslint-disable-next-line no-restricted-globals\n location.origin,\n );\n });\n }\n\n async connect(options?: {\n scopes: Scope[];\n caipAccountIds: CaipAccountId[];\n sessionProperties?: SessionProperties;\n forceRequest?: boolean;\n }): Promise<void> {\n // Ensure message listener is set up before connecting\n this.#setupMessageListener();\n\n await this.#transport.connect();\n\n // Get wallet session\n const sessionRequest = await this.request(\n { method: 'wallet_getSession' },\n this.#defaultRequestOptions,\n );\n if (sessionRequest.error) {\n throw new Error(sessionRequest.error.message);\n }\n let walletSession = sessionRequest.result as SessionData;\n\n const createSessionParams: CreateSessionParams<RPCAPI> = {\n optionalScopes: addValidAccounts(\n getOptionalScopes(options?.scopes ?? []),\n getValidAccounts(options?.caipAccountIds ?? []),\n ),\n sessionProperties: options?.sessionProperties,\n };\n\n if (walletSession && options && !options.forceRequest) {\n const currentScopes = Object.keys(\n walletSession?.sessionScopes ?? {},\n ) as Scope[];\n const proposedScopes = options?.scopes ?? [];\n const proposedCaipAccountIds = options?.caipAccountIds ?? [];\n const hasSameScopesAndAccounts = isSameScopesAndAccounts(\n currentScopes,\n proposedScopes,\n walletSession,\n proposedCaipAccountIds,\n );\n\n if (!hasSameScopesAndAccounts) {\n const response = await this.request(\n { method: 'wallet_createSession', params: createSessionParams },\n this.#defaultRequestOptions,\n );\n if (response.error) {\n throw new Error(response.error.message);\n }\n walletSession = response.result as SessionData;\n }\n } else if (!walletSession || options?.forceRequest) {\n const response = await this.request(\n { method: 'wallet_createSession', params: createSessionParams },\n this.#defaultRequestOptions,\n );\n if (response.error) {\n throw new Error(response.error.message);\n }\n walletSession = response.result as SessionData;\n }\n this.#notifyCallbacks({\n method: 'wallet_sessionChanged',\n params: walletSession,\n });\n }\n\n async disconnect(scopes: Scope[] = []): Promise<void> {\n await this.request({ method: 'wallet_revokeSession', params: { scopes } });\n\n const response = await this.request({ method: 'wallet_getSession' });\n const { sessionScopes } = response.result as SessionData;\n\n if (Object.keys(sessionScopes).length > 0) {\n return;\n }\n\n this.#notificationCallbacks.clear();\n\n // Remove the message listener when disconnecting\n if (this.#handleResponseListener) {\n // eslint-disable-next-line no-restricted-globals\n window.removeEventListener('message', this.#handleResponseListener);\n this.#handleResponseListener = undefined;\n }\n\n // Remove the notification listener when disconnecting\n if (this.#handleNotificationListener) {\n // eslint-disable-next-line no-restricted-globals\n window.removeEventListener('message', this.#handleNotificationListener);\n this.#handleNotificationListener = undefined;\n }\n\n // Reject all pending requests\n for (const [, request] of this.#pendingRequests) {\n clearTimeout(request.timeout);\n request.reject(new Error('Transport disconnected'));\n }\n this.#pendingRequests.clear();\n\n await this.#transport.disconnect();\n }\n\n isConnected(): boolean {\n return this.#transport.isConnected();\n }\n\n async request<\n TRequest extends TransportRequest,\n TResponse extends TransportResponse,\n >(\n request: TRequest,\n options: { timeout?: number } = this.#defaultRequestOptions,\n ): Promise<TResponse> {\n return this.#transport.request(request, options);\n }\n\n onNotification(callback: (data: unknown) => void): () => void {\n this.#transport.onNotification(callback);\n this.#notificationCallbacks.add(callback);\n return () => {\n this.#notificationCallbacks.delete(callback);\n };\n }\n\n async getActiveSession(): Promise<Session | undefined> {\n // This code path should never be triggered when the DefaultTransport is being used\n // It's only purpose is for exposing the session ID used for deeplinking to the mobile app\n // and so it is only implemented for the MWPTransport.\n throw new Error(\n 'getActiveSession is purposely not implemented for the DefaultTransport',\n );\n }\n\n async getStoredPendingSessionRequest(): Promise<SessionRequest | null> {\n throw new Error(\n 'getStoredPendingSessionRequest is purposely not implemented for the DefaultTransport',\n );\n }\n}\n","/* eslint-disable no-restricted-syntax -- Private class properties use established patterns */\n/* eslint-disable @typescript-eslint/explicit-function-return-type -- Inferred types are sufficient */\n/* eslint-disable @typescript-eslint/parameter-properties -- Constructor shorthand is intentional */\n\nimport type {\n CreateSessionParams,\n RevokeSessionParams,\n Transport,\n TransportRequest,\n TransportResponse,\n} from '@metamask/multichain-api-client';\nimport { providerErrors } from '@metamask/rpc-errors';\nimport type { CaipAccountId } from '@metamask/utils';\nimport type { InvokeMethodOptions, RPCAPI, Scope } from 'src/domain';\nimport type { MetaMaskConnectMultichain } from 'src/multichain';\n\nimport { getUniqueRequestId } from '../../utils';\n\ntype TransportRequestWithId = TransportRequest & { id: number };\n\nexport class MultichainApiClientWrapperTransport implements Transport {\n readonly #notificationCallbacks = new Set<(data: unknown) => void>();\n\n notificationListener: (() => void) | undefined;\n\n constructor(\n private readonly metamaskConnectMultichain: MetaMaskConnectMultichain,\n ) {}\n\n isTransportDefined(): boolean {\n try {\n return Boolean(this.metamaskConnectMultichain.transport);\n } catch (_error) {\n return false;\n }\n }\n\n clearNotificationCallbacks(): void {\n this.#notificationCallbacks.clear();\n }\n\n notifyCallbacks(data: unknown): void {\n this.#notificationCallbacks.forEach((callback) => {\n callback(data);\n });\n }\n\n clearTransportNotificationListener(): void {\n this.notificationListener?.();\n this.notificationListener = undefined;\n }\n\n setupTransportNotificationListener(): void {\n if (!this.isTransportDefined() || this.notificationListener) {\n return;\n }\n this.notificationListener =\n this.metamaskConnectMultichain.transport.onNotification(\n this.notifyCallbacks.bind(this),\n );\n }\n\n async connect(): Promise<void> {\n console.log('📚 connect');\n await this.metamaskConnectMultichain.emitSessionChanged();\n }\n\n async disconnect(): Promise<void> {\n return Promise.resolve();\n }\n\n isConnected(): boolean {\n return true;\n }\n\n async request<\n ParamsType extends TransportRequest,\n ReturnType extends TransportResponse,\n >(\n params: ParamsType,\n _options: { timeout?: number } = {},\n ): Promise<ReturnType> {\n const id = getUniqueRequestId();\n const requestPayload = {\n id,\n jsonrpc: '2.0',\n ...params,\n };\n\n switch (requestPayload.method) {\n case 'wallet_createSession':\n return this.#walletCreateSession(requestPayload) as Promise<ReturnType>;\n case 'wallet_getSession':\n return this.#walletGetSession(requestPayload) as Promise<ReturnType>;\n case 'wallet_revokeSession':\n return this.#walletRevokeSession(requestPayload) as Promise<ReturnType>;\n case 'wallet_invokeMethod':\n return this.#walletInvokeMethod(requestPayload) as Promise<ReturnType>;\n default:\n throw new Error(`Unsupported method: ${requestPayload.method}`);\n }\n\n throw new Error(`Unknown method: ${requestPayload.method}`);\n }\n\n onNotification(callback: (data: unknown) => void): () => void {\n this.setupTransportNotificationListener();\n this.#notificationCallbacks.add(callback);\n return () => {\n this.#notificationCallbacks.delete(callback);\n };\n }\n\n async #walletCreateSession(request: TransportRequestWithId) {\n const createSessionParams = request.params as CreateSessionParams<RPCAPI>;\n const scopes = Object.keys({\n ...createSessionParams.optionalScopes,\n ...createSessionParams.requiredScopes,\n }) as Scope[];\n const scopeAccounts: CaipAccountId[] = [];\n\n scopes.forEach((scope) => {\n const requiredScope = createSessionParams.requiredScopes?.[scope];\n const optionalScope = createSessionParams.optionalScopes?.[scope];\n if (requiredScope) {\n scopeAccounts.push(...(requiredScope.accounts ?? []));\n }\n\n if (optionalScope) {\n scopeAccounts.push(...(optionalScope.accounts ?? []));\n }\n });\n const accounts = [...new Set(scopeAccounts)];\n\n console.log('📚 SDK connect');\n await this.metamaskConnectMultichain.connect(\n scopes,\n accounts,\n createSessionParams.sessionProperties,\n );\n console.log('📚 SDK connected');\n return this.metamaskConnectMultichain.transport.request({\n method: 'wallet_getSession',\n });\n }\n\n async #walletGetSession(request: TransportRequestWithId) {\n if (!this.isTransportDefined()) {\n return {\n jsonrpc: '2.0',\n id: request.id,\n result: {\n sessionScopes: {},\n },\n };\n }\n return this.metamaskConnectMultichain.transport.request({\n method: 'wallet_getSession',\n });\n }\n\n async #walletRevokeSession(request: TransportRequestWithId) {\n if (!this.isTransportDefined()) {\n return { jsonrpc: '2.0', id: request.id, result: true };\n }\n\n const revokeSessionParams = request.params as\n | RevokeSessionParams<RPCAPI>\n | undefined;\n const scopes = revokeSessionParams?.scopes ?? [];\n\n try {\n await this.metamaskConnectMultichain.disconnect(scopes as Scope[]);\n return { jsonrpc: '2.0', id: request.id, result: true };\n } catch (_error) {\n return { jsonrpc: '2.0', id: request.id, result: false };\n }\n }\n\n async #walletInvokeMethod(request: TransportRequestWithId) {\n if (!this.isTransportDefined()) {\n return { error: providerErrors.unauthorized() };\n }\n const result = this.metamaskConnectMultichain.invokeMethod(\n request.params as InvokeMethodOptions,\n );\n\n return {\n result,\n };\n }\n}\n","/* eslint-disable @typescript-eslint/prefer-promise-reject-errors */\n/* eslint-disable consistent-return */\n/* eslint-disable promise/param-names */\n/* eslint-disable @typescript-eslint/no-misused-promises */\n/* eslint-disable @typescript-eslint/no-shadow */\n/* eslint-disable id-denylist */\n/* eslint-disable @typescript-eslint/no-floating-promises */\n/* eslint-disable no-restricted-globals */\n/* eslint-disable @typescript-eslint/parameter-properties */\n/* eslint-disable @typescript-eslint/explicit-function-return-type */\n/* eslint-disable @typescript-eslint/prefer-readonly */\n/* eslint-disable no-restricted-syntax */\n/* eslint-disable @typescript-eslint/naming-convention */\n/* eslint-disable no-async-promise-executor -- Async promise executor needed for complex flow */\nimport type {\n Session,\n SessionRequest,\n} from '@metamask/mobile-wallet-protocol-core';\nimport { SessionStore } from '@metamask/mobile-wallet-protocol-core';\nimport type { DappClient } from '@metamask/mobile-wallet-protocol-dapp-client';\nimport {\n type SessionProperties,\n type CreateSessionParams,\n type TransportRequest,\n type TransportResponse,\n TransportTimeoutError,\n} from '@metamask/multichain-api-client';\nimport { JsonRpcError, providerErrors, rpcErrors } from '@metamask/rpc-errors';\nimport type { CaipAccountId } from '@metamask/utils';\n\nimport {\n createLogger,\n type ExtendedTransport,\n type RPCAPI,\n type Scope,\n type SessionData,\n type StoreAdapter,\n} from '../../../domain';\nimport {\n addValidAccounts,\n getOptionalScopes,\n getUniqueRequestId,\n getValidAccounts,\n isSameScopesAndAccounts,\n} from '../../utils';\nimport { MULTICHAIN_PROVIDER_STREAM_NAME } from '../constants';\n\nconst DEFAULT_REQUEST_TIMEOUT = 60 * 1000;\nconst CONNECTION_GRACE_PERIOD = 60 * 1000;\nconst DEFAULT_CONNECTION_TIMEOUT =\n DEFAULT_REQUEST_TIMEOUT + CONNECTION_GRACE_PERIOD;\nconst DEFAULT_RESUME_TIMEOUT = 10 * 1000;\nconst SESSION_STORE_KEY = 'cache_wallet_getSession';\nconst ACCOUNTS_STORE_KEY = 'cache_eth_accounts';\nconst CHAIN_STORE_KEY = 'cache_eth_chainId';\nconst PENDING_SESSION_REQUEST_KEY = 'pending_session_request';\n\nconst CACHED_METHOD_LIST = [\n 'wallet_getSession',\n 'wallet_createSession',\n 'wallet_sessionChanged',\n];\nconst CACHED_RESET_METHOD_LIST = [\n 'wallet_revokeSession',\n 'wallet_revokePermissions',\n];\n\ntype PendingRequests = {\n request: { jsonrpc: string; id: string } & TransportRequest;\n method: string;\n resolve: (value: TransportResponse) => void;\n reject: (error: Error) => void;\n timeout: NodeJS.Timeout;\n};\n\nconst logger = createLogger('metamask-sdk:transport');\n\n/**\n * Mobile Wallet Protocol transport implementation\n * Bridges the MWP DappClient with the multichain API client Transport interface\n */\nexport class MWPTransport implements ExtendedTransport {\n private __pendingRequests = new Map<string, PendingRequests>();\n\n private notificationCallbacks = new Set<(data: unknown) => void>();\n\n private currentSessionRequest: SessionRequest | undefined;\n\n private windowFocusHandler: (() => void) | undefined;\n\n get pendingRequests() {\n return this.__pendingRequests;\n }\n\n set pendingRequests(pendingRequests: Map<string, PendingRequests>) {\n this.__pendingRequests = pendingRequests;\n }\n\n get sessionRequest() {\n return this.currentSessionRequest;\n }\n\n constructor(\n private dappClient: DappClient,\n private kvstore: StoreAdapter,\n private options: {\n requestTimeout: number;\n connectionTimeout: number;\n resumeTimeout: number;\n } = {\n requestTimeout: DEFAULT_REQUEST_TIMEOUT,\n connectionTimeout: DEFAULT_CONNECTION_TIMEOUT,\n resumeTimeout: DEFAULT_RESUME_TIMEOUT,\n },\n ) {\n this.dappClient.on('message', this.handleMessage.bind(this));\n // We store the pending session request in the KVStore so that we can:\n // 1. Use it to regenerate the deeplink to re-prompt the user with if they\n // attempt to connect while there is a pending connection attempt.\n // 2. Determine if there was a pending connection attempt when MultichainConnect\n // is initializing itself for the first time on page load and correctly set\n // the appropriate timeout duration for that connection attempt.\n this.dappClient.on('session_request', (sessionRequest: SessionRequest) => {\n this.currentSessionRequest = sessionRequest;\n this.kvstore\n .set(PENDING_SESSION_REQUEST_KEY, JSON.stringify(sessionRequest))\n .catch((err) => {\n logger('Failed to store pending session request', err);\n });\n });\n if (\n typeof window !== 'undefined' &&\n typeof window.addEventListener !== 'undefined'\n ) {\n this.windowFocusHandler = this.onWindowFocus.bind(this);\n window.addEventListener('focus', this.windowFocusHandler);\n }\n }\n\n /**\n * Returns the stored pending session request from the dappClient session_request event, if any.\n *\n * @returns The stored SessionRequest, or null if none or invalid.\n */\n async getStoredPendingSessionRequest(): Promise<SessionRequest | null> {\n try {\n const raw = await this.kvstore.get(PENDING_SESSION_REQUEST_KEY);\n if (!raw) {\n return null;\n }\n return JSON.parse(raw) as SessionRequest;\n } catch {\n return null;\n }\n }\n\n /**\n * Removes the stored pending session request from the KVStore.\n * This is necessary to ensure that ConnectMultichain is able to correctly\n * infer the MWP Transport connection attempt status.\n */\n private async removeStoredPendingSessionRequest(): Promise<void> {\n await this.kvstore.delete(PENDING_SESSION_REQUEST_KEY);\n }\n\n private onWindowFocus(): void {\n if (!this.isConnected()) {\n this.dappClient.reconnect();\n }\n }\n\n private notifyCallbacks(data: unknown): void {\n this.notificationCallbacks.forEach((callback) => callback(data));\n }\n\n private rejectRequest(\n id: string,\n error = new Error('Request rejected'),\n ): void {\n const request = this.pendingRequests.get(id);\n if (request) {\n this.pendingRequests.delete(id);\n clearTimeout(request.timeout);\n request.reject(error);\n }\n }\n\n private parseWalletError(errorPayload: unknown): Error {\n const errorData = errorPayload as Record<string, unknown>;\n\n if (\n typeof errorData.code === 'number' &&\n typeof errorData.message === 'string'\n ) {\n const { code, message } = errorData;\n\n if (code >= 1000 && code <= 4999) {\n return providerErrors.custom({ code, message });\n }\n\n return new JsonRpcError(code, message);\n }\n\n const message =\n errorPayload instanceof Error\n ? errorPayload.message\n : JSON.stringify(errorPayload);\n\n return rpcErrors.internal({ message });\n }\n\n private handleMessage(message: unknown): void {\n if (typeof message === 'object' && message !== null) {\n if ('data' in message) {\n const messagePayload = message.data as Record<string, unknown>;\n\n if ('id' in messagePayload && typeof messagePayload.id === 'string') {\n const request = this.pendingRequests.get(messagePayload.id);\n\n if (request) {\n clearTimeout(request.timeout);\n\n // Check if the message contains an error (e.g., user rejected)\n if ('error' in messagePayload && messagePayload.error) {\n this.pendingRequests.delete(messagePayload.id);\n request.reject(this.parseWalletError(messagePayload.error));\n return;\n }\n\n // Success case - resolve the promise\n const requestWithName = {\n ...messagePayload,\n method:\n request.method === 'wallet_getSession' ||\n request.method === 'wallet_createSession'\n ? 'wallet_sessionChanged'\n : request.method,\n } as unknown as {\n jsonrpc: string;\n id: string;\n } & TransportResponse;\n\n const notification = {\n ...messagePayload,\n method:\n request.method === 'wallet_getSession' ||\n request.method === 'wallet_createSession'\n ? 'wallet_sessionChanged'\n : request.method,\n params: requestWithName.result,\n };\n\n this.notifyCallbacks(notification);\n request.resolve(requestWithName);\n this.pendingRequests.delete(messagePayload.id);\n }\n } else {\n if (\n (message.data as { method: string }).method ===\n 'metamask_chainChanged'\n ) {\n this.kvstore.set(\n CHAIN_STORE_KEY,\n JSON.stringify(\n (message.data as { params: { chainId: number } }).params\n .chainId,\n ),\n );\n }\n\n if (\n (message.data as { method: string }).method ===\n 'metamask_accountsChanged'\n ) {\n this.kvstore.set(\n ACCOUNTS_STORE_KEY,\n JSON.stringify(\n (message.data as { params: { accounts: string[] } }).params,\n ),\n );\n }\n\n // Ensure session changes are always persisted to the store\n if (\n (message.data as { method: string }).method ===\n 'wallet_sessionChanged'\n ) {\n const notification = message.data as {\n method: string;\n params: SessionData;\n };\n\n const response = {\n result: notification.params,\n };\n\n this.kvstore.set(SESSION_STORE_KEY, JSON.stringify(response));\n }\n\n this.notifyCallbacks(message.data);\n }\n }\n }\n }\n\n private async onResumeSuccess(\n resumeResolve: () => void,\n resumeReject: (err: Error) => void,\n options?: { scopes: Scope[]; caipAccountIds: CaipAccountId[] },\n ): Promise<void> {\n try {\n await this.waitForWalletSessionIfNotCached();\n const sessionRequest = await this.request({\n method: 'wallet_getSession',\n });\n // TODO: verify if this branching logic can ever be hit\n if (sessionRequest.error) {\n return resumeReject(new Error(sessionRequest.error.message));\n }\n let walletSession = sessionRequest.result as SessionData;\n if (walletSession && options) {\n const currentScopes = Object.keys(\n walletSession?.sessionScopes ?? {},\n ) as Scope[];\n const proposedScopes = options?.scopes ?? [];\n const proposedCaipAccountIds = options?.caipAccountIds ?? [];\n const hasSameScopesAndAccounts = isSameScopesAndAccounts(\n currentScopes,\n proposedScopes,\n walletSession,\n proposedCaipAccountIds,\n );\n if (!hasSameScopesAndAccounts) {\n const optionalScopes = addValidAccounts(\n getOptionalScopes(options?.scopes ?? []),\n getValidAccounts(options?.caipAccountIds ?? []),\n );\n const sessionRequest: CreateSessionParams<RPCAPI> = {\n optionalScopes,\n };\n const response = await this.request({\n method: 'wallet_createSession',\n params: sessionRequest,\n });\n if (response.error) {\n return resumeReject(new Error(response.error.message));\n }\n // TODO: Maybe find a better way to revoke sessions on wallet without triggering an empty notification\n // Issue of this is it will send a session update event with an empty session and right after we may get the session recovered\n // await this.request({ method: 'wallet_revokeSession', params: walletSession });\n walletSession = response.result as SessionData;\n }\n } else if (!walletSession) {\n // TODO: verify if this branching logic can ever be hit\n const optionalScopes = addValidAccounts(\n getOptionalScopes(options?.scopes ?? []),\n getValidAccounts(options?.caipAccountIds ?? []),\n );\n const sessionRequest: CreateSessionParams<RPCAPI> = { optionalScopes };\n const response = await this.request({\n method: 'wallet_createSession',\n params: sessionRequest,\n });\n if (response.error) {\n return resumeReject(new Error(response.error.message));\n }\n walletSession = response.result as SessionData;\n }\n await this.removeStoredPendingSessionRequest();\n this.notifyCallbacks({\n method: 'wallet_sessionChanged',\n params: walletSession,\n });\n return resumeResolve();\n } catch (err) {\n return resumeReject(err as Error);\n }\n }\n\n // TODO: Rename this\n async sendEip1193Message<\n TRequest extends TransportRequest,\n TResponse extends TransportResponse,\n >(payload: TRequest, options?: { timeout?: number }): Promise<TResponse> {\n const request = {\n jsonrpc: '2.0',\n id: String(getUniqueRequestId()),\n ...payload,\n };\n\n const cachedWalletSession = await this.getCachedResponse(request);\n if (cachedWalletSession) {\n this.notifyCallbacks(cachedWalletSession);\n return cachedWalletSession as TResponse;\n }\n\n return new Promise<TResponse>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.rejectRequest(request.id, new TransportTimeoutError());\n }, options?.timeout ?? this.options.requestTimeout);\n\n this.pendingRequests.set(request.id, {\n request,\n method: request.method,\n resolve: async (response: TransportResponse) => {\n await this.storeWalletSession(request, response);\n return resolve(response as TResponse);\n },\n reject,\n timeout,\n });\n\n this.dappClient\n .sendRequest({\n name: 'metamask-provider',\n data: request,\n })\n .catch(reject);\n });\n }\n\n async connect(options?: {\n scopes: Scope[];\n caipAccountIds: CaipAccountId[];\n sessionProperties?: SessionProperties;\n }): Promise<void> {\n const { dappClient } = this;\n\n const session = await this.getActiveSession();\n if (session) {\n logger('active session found', {\n id: session.id,\n channel: session.channel,\n expiresAt: session.expiresAt,\n });\n }\n\n const storedSessionRequestBeforeConnectionAttempt =\n await this.getStoredPendingSessionRequest();\n\n let timeout: NodeJS.Timeout;\n let initialConnectionMessageHandler:\n | ((message: unknown) => Promise<void>)\n | undefined;\n const connectionPromise = new Promise<void>(async (resolve, reject) => {\n let connection: Promise<void>;\n if (session) {\n connection = new Promise<void>((resumeResolve, resumeReject) => {\n if (this.dappClient.state === 'CONNECTED') {\n this.onResumeSuccess(resumeResolve, resumeReject, options);\n } else {\n this.dappClient.once('connected', async () => {\n this.onResumeSuccess(resumeResolve, resumeReject, options);\n });\n dappClient.resume(session?.id ?? '');\n }\n });\n } else {\n connection = new Promise<void>(\n (resolveConnection, rejectConnection) => {\n const optionalScopes = addValidAccounts(\n getOptionalScopes(options?.scopes ?? []),\n getValidAccounts(options?.caipAccountIds ?? []),\n );\n const sessionRequest: CreateSessionParams<RPCAPI> = {\n optionalScopes,\n sessionProperties: options?.sessionProperties,\n };\n const request = {\n jsonrpc: '2.0',\n id: String(getUniqueRequestId()),\n method: 'wallet_createSession',\n params: sessionRequest,\n };\n\n // Handler for initial connection messages - checks for error responses\n // and properly rejects the connection promise with EIP-1193 error codes\n initialConnectionMessageHandler = async (\n message: unknown,\n ): Promise<void> => {\n if (typeof message !== 'object' || message === null) {\n return;\n }\n if (!('data' in message)) {\n return;\n }\n\n const messagePayload = message.data as Record<string, unknown>;\n\n // Match by ID (preferred) or by method (backward compatibility for notifications without ID)\n const isMatchingId = messagePayload.id === request.id;\n const isMatchingMethod =\n messagePayload.method === 'wallet_createSession' ||\n messagePayload.method === 'wallet_sessionChanged';\n\n if (!isMatchingId && !isMatchingMethod) {\n return;\n }\n\n // Handle error response (e.g., user rejected the connection)\n if (messagePayload.error) {\n return rejectConnection(\n this.parseWalletError(messagePayload.error),\n );\n }\n\n // Success case - store session, notify, and resolve\n await this.storeWalletSession(\n request,\n messagePayload as TransportResponse,\n );\n await this.removeStoredPendingSessionRequest();\n this.notifyCallbacks(messagePayload);\n return resolveConnection();\n };\n\n this.dappClient.on('message', initialConnectionMessageHandler);\n\n dappClient\n .connect({\n mode: 'trusted',\n initialPayload: {\n name: MULTICHAIN_PROVIDER_STREAM_NAME,\n data: request,\n },\n })\n .catch((error) => {\n if (initialConnectionMessageHandler) {\n this.dappClient.off(\n 'message',\n initialConnectionMessageHandler,\n );\n }\n rejectConnection(error);\n });\n },\n );\n }\n\n timeout = setTimeout(\n () => {\n reject(new TransportTimeoutError());\n },\n storedSessionRequestBeforeConnectionAttempt\n ? this.options.resumeTimeout\n : this.options.connectionTimeout,\n );\n\n connection.then(resolve).catch(reject);\n });\n\n return connectionPromise\n .catch(async (error) => {\n // Clean up the MWP session from the KVStore so stale sessions\n // don't cause subsequent connect attempts to enter the resume path\n await this.dappClient.disconnect();\n throw error;\n })\n .finally(() => {\n if (timeout) {\n clearTimeout(timeout);\n }\n if (initialConnectionMessageHandler) {\n this.dappClient.off('message', initialConnectionMessageHandler);\n initialConnectionMessageHandler = undefined;\n }\n this.removeStoredPendingSessionRequest();\n });\n }\n\n /**\n * Disconnects from the Mobile Wallet Protocol\n *\n * @param [scopes] - The scopes to revoke. If not provided or empty, all scopes will be revoked.\n * @returns Nothing\n */\n async disconnect(scopes: Scope[] = []): Promise<void> {\n const cachedSession = await this.getCachedResponse({\n jsonrpc: '2.0',\n id: '0',\n method: 'wallet_getSession',\n });\n const cachedSessionScopes =\n (cachedSession?.result as SessionData | undefined)?.sessionScopes ?? {};\n\n const remainingScopes =\n scopes.length === 0\n ? []\n : Object.keys(cachedSessionScopes).filter(\n (scope) => !scopes.includes(scope as Scope),\n );\n\n const newSessionScopes = Object.fromEntries(\n Object.entries(cachedSessionScopes).filter(([key]) =>\n remainingScopes.includes(key),\n ),\n );\n\n // NOTE: Purposely not awaiting this to avoid blocking the disconnect flow.\n // This might not actually get executed on the wallet if the user doesn't open\n // their wallet before the message TTL or if the underlying transport isn't actually connected\n this.request({ method: 'wallet_revokeSession', params: { scopes } }).catch(\n (err) => {\n console.error('error revoking session', err);\n },\n );\n\n // Clear the cached values for eth_accounts and eth_chainId if all eip155 scopes were removed.\n const remainingScopesIncludeEip155 = remainingScopes.some((scope) =>\n scope.includes('eip155'),\n );\n if (!remainingScopesIncludeEip155) {\n this.kvstore.delete(ACCOUNTS_STORE_KEY);\n this.kvstore.delete(CHAIN_STORE_KEY);\n }\n\n if (remainingScopes.length > 0) {\n this.kvstore.set(\n SESSION_STORE_KEY,\n JSON.stringify({\n result: {\n sessionScopes: newSessionScopes,\n },\n }),\n );\n } else {\n this.kvstore.delete(SESSION_STORE_KEY);\n\n // Clean up window focus event listener\n if (\n typeof window !== 'undefined' &&\n typeof window.removeEventListener !== 'undefined' &&\n this.windowFocusHandler\n ) {\n window.removeEventListener('focus', this.windowFocusHandler);\n this.windowFocusHandler = undefined;\n }\n\n await this.dappClient.disconnect();\n }\n\n this.notifyCallbacks({\n method: 'wallet_sessionChanged',\n params: {\n sessionScopes: newSessionScopes,\n },\n });\n }\n\n /**\n * Checks if the transport is connected\n *\n * @returns True if transport is connected, false otherwise\n */\n isConnected(): boolean {\n // biome-ignore lint/suspicious/noExplicitAny: required if state is not made public in dappClient\n return (this.dappClient as any).state === 'CONNECTED';\n }\n\n /**\n * Attempts to re-establish a connection via DappClient\n *\n * @returns Nothing\n */\n // TODO: We should re-evaluate adding this to the WebSocketTransport layer from `@metamask/mobile-wallet-protocol-core`\n // ticket: https://consensyssoftware.atlassian.net/browse/WAPI-862\n private async attemptResumeSession(): Promise<void> {\n try {\n await this.dappClient.reconnect();\n // Wait for connection to be established\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error('Resume timeout'));\n }, 2_000);\n\n if (this.isConnected()) {\n clearTimeout(timeout);\n resolve();\n } else {\n this.dappClient.once('connected', () => {\n clearTimeout(timeout);\n resolve();\n });\n }\n });\n } catch (error) {\n return Promise.reject(\n new Error(`Failed to resume session: ${error.message}`),\n );\n }\n }\n\n private async getCachedResponse(\n request: { jsonrpc: string; id: string } & TransportRequest,\n ): Promise<TransportResponse | undefined> {\n if (request.method === 'wallet_getSession') {\n const walletGetSession = await this.kvstore.get(SESSION_STORE_KEY);\n if (walletGetSession) {\n const walletSession = JSON.parse(walletGetSession);\n return {\n id: request.id,\n jsonrpc: '2.0',\n result: walletSession.params ?? walletSession.result, // \"what?... why walletSession.params?..\"\n method: request.method,\n } as unknown as TransportResponse;\n }\n } else if (request.method === 'eth_accounts') {\n const ethAccounts = await this.kvstore.get(ACCOUNTS_STORE_KEY);\n if (ethAccounts) {\n return {\n id: request.id,\n jsonrpc: '2.0',\n result: JSON.parse(ethAccounts),\n method: request.method,\n } as unknown as TransportResponse;\n }\n } else if (request.method === 'eth_chainId') {\n const ethChainId = await this.kvstore.get(CHAIN_STORE_KEY);\n if (ethChainId) {\n return {\n id: request.id,\n jsonrpc: '2.0',\n result: JSON.parse(ethChainId),\n method: request.method,\n } as unknown as TransportResponse;\n }\n }\n }\n\n private async storeWalletSession(\n request: TransportRequest,\n response: TransportResponse,\n ): Promise<void> {\n if (response.error) {\n return;\n }\n if (CACHED_METHOD_LIST.includes(request.method)) {\n await this.kvstore.set(SESSION_STORE_KEY, JSON.stringify(response));\n } else if (request.method === 'eth_accounts') {\n await this.kvstore.set(\n ACCOUNTS_STORE_KEY,\n JSON.stringify(response.result),\n );\n } else if (request.method === 'eth_chainId') {\n await this.kvstore.set(CHAIN_STORE_KEY, JSON.stringify(response.result));\n } else if (CACHED_RESET_METHOD_LIST.includes(request.method)) {\n await this.kvstore.delete(SESSION_STORE_KEY);\n await this.kvstore.delete(ACCOUNTS_STORE_KEY);\n await this.kvstore.delete(CHAIN_STORE_KEY);\n }\n }\n\n async request<\n TRequest extends TransportRequest,\n TResponse extends TransportResponse,\n >(payload: TRequest, options?: { timeout?: number }): Promise<TResponse> {\n const request = {\n jsonrpc: '2.0',\n id: String(getUniqueRequestId()),\n ...payload,\n };\n\n const cachedWalletSession = await this.getCachedResponse(request);\n if (cachedWalletSession) {\n this.notifyCallbacks(cachedWalletSession);\n return cachedWalletSession as TResponse;\n }\n\n if (!this.isConnected()) {\n await this.attemptResumeSession();\n }\n\n return new Promise<TResponse>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.rejectRequest(request.id, new TransportTimeoutError());\n }, options?.timeout ?? this.options.requestTimeout);\n\n this.pendingRequests.set(request.id, {\n request,\n method: request.method,\n resolve: async (response: TransportResponse) => {\n await this.storeWalletSession(request, response);\n return resolve(response as TResponse);\n },\n reject,\n timeout,\n });\n\n this.dappClient\n .sendRequest({\n name: MULTICHAIN_PROVIDER_STREAM_NAME,\n data: request,\n })\n .catch(reject);\n });\n }\n\n onNotification(callback: (data: unknown) => void): () => void {\n this.notificationCallbacks.add(callback);\n return () => {\n this.notificationCallbacks.delete(callback);\n };\n }\n\n async getActiveSession(): Promise<Session | undefined> {\n const { kvstore } = this;\n const sessionStore = new SessionStore(kvstore);\n\n try {\n const [activeSession] = await sessionStore.list();\n return activeSession;\n } catch (error) {\n // TODO: verify if this try catch is necessary\n logger('error getting active session', error);\n return undefined;\n }\n }\n\n // This method checks if an existing CAIP session response is cached or waits for one\n // to be received from the wallet if not cached. This is necessary because there is an edge\n // case during the initial connection flow where after the user has accepted the permission approval\n // and returned back to the dapp from the wallet, the dapp page may have gotten unloaded and refreshed.\n // When it is unloaded and refreshed, it will try to resume the session by making a request for wallet_getSession\n // which should resolve from cache, but because a race condition makes it possible for the response from the wallet\n // for the initial wallet_createSession connection request to not have been handled and cached yet. This results\n // in the wallet_getSession request never resolving unless we wait for it explicitly as done in this method.\n private async waitForWalletSessionIfNotCached() {\n const cachedWalletGetSessionResponse =\n await this.kvstore.get(SESSION_STORE_KEY);\n if (cachedWalletGetSessionResponse) {\n return;\n }\n let unsubscribe: () => void;\n const responsePromise = new Promise<void>((resolve) => {\n unsubscribe = this.onNotification((message) => {\n if (typeof message === 'object' && message !== null) {\n if ('data' in message) {\n const messagePayload = message.data as Record<string, unknown>;\n if (\n messagePayload.method === 'wallet_getSession' ||\n messagePayload.method === 'wallet_sessionChanged'\n ) {\n unsubscribe();\n resolve();\n }\n }\n }\n });\n });\n\n const timeoutPromise = new Promise<void>((_resolve, reject) => {\n setTimeout(() => {\n unsubscribe();\n this.removeStoredPendingSessionRequest();\n reject(new TransportTimeoutError());\n }, this.options.resumeTimeout);\n });\n\n return Promise.race([responsePromise, timeoutPromise]);\n }\n}\n","export const EIP_1193_PROVIDER_STREAM_NAME = 'metamask-provider';\nexport const MULTICHAIN_PROVIDER_STREAM_NAME = 'metamask-multichain-provider';\n","/* eslint-disable no-restricted-globals -- Buffer is polyfilled for browser/RN environments */\n/* eslint-disable @typescript-eslint/await-thenable -- decrypt returns Promise in some implementations */\nimport type {\n IKeyManager,\n KeyPair,\n} from '@metamask/mobile-wallet-protocol-core';\nimport { decrypt, encrypt, PrivateKey } from 'eciesjs';\n\nclass KeyManager implements IKeyManager {\n generateKeyPair(): KeyPair {\n const privateKey = new PrivateKey();\n return {\n privateKey: new Uint8Array(privateKey.secret),\n publicKey: privateKey.publicKey.toBytes(true),\n };\n }\n\n async encrypt(\n plaintext: string,\n theirPublicKey: Uint8Array,\n ): Promise<string> {\n const plaintextBuffer = Buffer.from(plaintext, 'utf8');\n const encryptedBuffer = encrypt(theirPublicKey, plaintextBuffer);\n return encryptedBuffer.toString('base64');\n }\n\n async decrypt(\n encryptedB64: string,\n myPrivateKey: Uint8Array,\n ): Promise<string> {\n const encryptedBuffer = Buffer.from(encryptedB64, 'base64');\n const decryptedBuffer = await decrypt(myPrivateKey, encryptedBuffer);\n return Buffer.from(decryptedBuffer).toString('utf8');\n }\n}\n\nexport const keymanager = new KeyManager();\n","/* eslint-disable id-denylist -- 'err' is a common pattern for catch clauses */\n/* eslint-disable @typescript-eslint/parameter-properties -- Constructor shorthand */\nimport * as uuid from 'uuid';\n\nimport type { StoreAdapter, TransportType } from '../domain';\nimport {\n StorageDeleteErr,\n StorageGetErr,\n StorageSetErr,\n} from '../domain/errors/storage';\nimport { getTransportType } from '../domain/multichain';\nimport { StoreClient } from '../domain/store/client';\n\nexport class Store extends StoreClient {\n constructor(public adapter: StoreAdapter) {\n super();\n }\n\n async getTransport(): Promise<TransportType | null> {\n try {\n const transport = await this.adapter.get('multichain-transport');\n if (!transport) {\n return null;\n }\n return getTransportType(transport);\n } catch (err) {\n throw new StorageGetErr(\n this.adapter.platform,\n 'multichain-transport',\n err.message,\n );\n }\n }\n\n async setTransport(transport: TransportType): Promise<void> {\n try {\n await this.adapter.set('multichain-transport', transport);\n } catch (err) {\n throw new StorageSetErr(\n this.adapter.platform,\n 'multichain-transport',\n err.message,\n );\n }\n }\n\n async removeTransport(): Promise<void> {\n try {\n await this.adapter.delete('multichain-transport');\n } catch (err) {\n throw new StorageDeleteErr(\n this.adapter.platform,\n 'multichain-transport',\n err.message,\n );\n }\n }\n\n async getAnonId(): Promise<string> {\n try {\n const anonId = await this.adapter.get('anonId');\n if (anonId) {\n return anonId;\n }\n const newAnonId = uuid.v4();\n await this.adapter.set('anonId', newAnonId);\n return newAnonId;\n } catch (err) {\n throw new StorageGetErr(this.adapter.platform, 'anonId', err.message);\n }\n }\n\n async getExtensionId(): Promise<string | null> {\n try {\n return await this.adapter.get('extensionId');\n } catch (err) {\n throw new StorageGetErr(\n this.adapter.platform,\n 'extensionId',\n err.message,\n );\n }\n }\n\n async setAnonId(anonId: string): Promise<void> {\n try {\n return await this.adapter.set('anonId', anonId);\n } catch (err) {\n throw new StorageSetErr(this.adapter.platform, 'anonId', err.message);\n }\n }\n\n async setExtensionId(extensionId: string): Promise<void> {\n try {\n return await this.adapter.set('extensionId', extensionId);\n } catch (err) {\n throw new StorageSetErr(\n this.adapter.platform,\n 'extensionId',\n err.message,\n );\n }\n }\n\n async removeExtensionId(): Promise<void> {\n try {\n return await this.adapter.delete('extensionId');\n } catch (err) {\n throw new StorageDeleteErr(\n this.adapter.platform,\n 'extensionId',\n err.message,\n );\n }\n }\n\n async removeAnonId(): Promise<void> {\n try {\n return await this.adapter.delete('anonId');\n } catch (err) {\n throw new StorageDeleteErr(this.adapter.platform, 'anonId', err.message);\n }\n }\n\n async getDebug(): Promise<string | null> {\n try {\n return await this.adapter.get('DEBUG');\n } catch (err) {\n throw new StorageGetErr(this.adapter.platform, 'DEBUG', err.message);\n }\n }\n}\n","/* eslint-disable @typescript-eslint/parameter-properties */\nimport { BaseErr } from './base';\nimport type { StorageErrorCodes } from './types';\n\nexport class StorageGetErr extends BaseErr<'Storage', StorageErrorCodes> {\n static readonly code = 60;\n\n constructor(\n public readonly platform: 'web' | 'rn' | 'node',\n public readonly key: string,\n public readonly reason: string,\n ) {\n super(\n `StorageErr${StorageGetErr.code}: ${platform} storage get error in key: ${key} - ${reason}`,\n StorageGetErr.code,\n );\n }\n}\n\nexport class StorageSetErr extends BaseErr<'Storage', StorageErrorCodes> {\n static readonly code = 61;\n\n constructor(\n public readonly platform: 'web' | 'rn' | 'node',\n public readonly key: string,\n public readonly reason: string,\n ) {\n super(\n `StorageErr${StorageSetErr.code}: ${platform} storage set error in key: ${key} - ${reason}`,\n StorageSetErr.code,\n );\n }\n}\n\nexport class StorageDeleteErr extends BaseErr<'Storage', StorageErrorCodes> {\n static readonly code = 62;\n\n constructor(\n public readonly platform: 'web' | 'rn' | 'node',\n public readonly key: string,\n public readonly reason: string,\n ) {\n super(\n `StorageErr${StorageDeleteErr.code}: ${platform} storage delete error in key: ${key} - ${reason}`,\n StorageDeleteErr.code,\n );\n }\n}\n","/* eslint-disable @typescript-eslint/no-shadow */\n\n/* eslint-disable no-restricted-globals */\n/* eslint-disable jsdoc/require-returns */\n/* eslint-disable @typescript-eslint/parameter-properties */\n/* eslint-disable @typescript-eslint/explicit-function-return-type */\n/* eslint-disable no-restricted-syntax */\n\n/* eslint-disable @typescript-eslint/naming-convention */\nimport MetaMaskOnboarding from '@metamask/onboarding';\n\nimport { METAMASK_CONNECT_BASE_URL, METAMASK_DEEPLINK_BASE } from '../config';\nimport {\n type ConnectionRequest,\n getPlatformType,\n getVersion,\n type Modal,\n type OTPCode,\n PlatformType,\n} from '../domain';\nimport type { AbstractOTPCodeModal } from './modals/base/AbstractOTPModal';\nimport type { FactoryModals, ModalTypes } from './modals/types';\nimport { compressString } from '../multichain/utils';\n\n/**\n * Preload function type for loading UI dependencies\n */\nexport type PreloadFn = () => Promise<void>;\n\n/**\n * Base ModalFactory class that accepts a preload function.\n * Platform-specific implementations should extend this class.\n */\nexport abstract class BaseModalFactory<\n T extends FactoryModals = FactoryModals,\n> {\n public modal!: Modal<any>;\n\n private readonly platform: PlatformType = getPlatformType();\n\n private successCallback!: (error?: Error) => Promise<void>;\n\n private displayUriCallback?: (uri: string) => void;\n\n /**\n * Creates a new modal factory instance.\n *\n * @param options - The modals configuration object\n */\n constructor(protected readonly options: T) {\n this.validateModals();\n }\n\n /**\n * Platform-specific preload function to be implemented by subclasses.\n */\n protected abstract preload(): Promise<void>;\n\n private validateModals() {\n const requiredModals = ['InstallModal', 'OTPCodeModal'];\n const missingModals = requiredModals.filter(\n (modal) => !this.options[modal as ModalTypes],\n );\n if (missingModals.length > 0) {\n throw new Error(`Missing required modals: ${missingModals.join(', ')}`);\n }\n }\n\n async unload(error?: Error) {\n this.modal?.unmount();\n await this.successCallback?.(error);\n }\n\n /**\n * Determines if the current platform is a mobile native environment.\n * Currently only includes React Native.\n */\n get isMobile() {\n return this.platform === PlatformType.ReactNative;\n }\n\n /**\n * Determines if the current platform is a Node.js environment.\n * Used for server-side or non-browser environments.\n */\n get isNode() {\n return this.platform === PlatformType.NonBrowser;\n }\n\n /**\n * Determines if the current platform is a web environment.\n * Includes desktop web, MetaMask mobile webview, and mobile web.\n */\n get isWeb() {\n return (\n this.platform === PlatformType.DesktopWeb ||\n this.platform === PlatformType.MetaMaskMobileWebview ||\n this.platform === PlatformType.MobileWeb\n );\n }\n\n private getContainer() {\n return typeof document === 'undefined'\n ? undefined\n : document.createElement('div');\n }\n\n private getMountedContainer() {\n if (typeof document === 'undefined') {\n return undefined;\n }\n const container = this.getContainer();\n if (container) {\n document.body.appendChild(container);\n }\n return container;\n }\n\n createConnectionDeeplink(connectionRequest?: ConnectionRequest) {\n if (!connectionRequest) {\n throw new Error(\n 'createConnectionDeeplink can only be called with a connection request',\n );\n }\n const json = JSON.stringify(connectionRequest);\n const compressed = compressString(json);\n const urlEncoded = encodeURIComponent(compressed);\n return `${METAMASK_DEEPLINK_BASE}/mwp?p=${urlEncoded}&c=1`;\n }\n\n createConnectionUniversalLink(connectionRequest?: ConnectionRequest) {\n if (!connectionRequest) {\n return `${METAMASK_CONNECT_BASE_URL}`;\n }\n const json = JSON.stringify(connectionRequest);\n const compressed = compressString(json);\n const urlEncoded = encodeURIComponent(compressed);\n return `${METAMASK_CONNECT_BASE_URL}/mwp?p=${urlEncoded}&c=1`;\n }\n\n private async onCloseModal(shouldTerminate = true) {\n return this.unload(\n shouldTerminate ? new Error('User closed modal') : undefined,\n );\n }\n\n private onStartDesktopOnboarding() {\n new MetaMaskOnboarding().startOnboarding();\n }\n\n public async renderInstallModal(\n showInstallModal: boolean,\n createConnectionRequest: () => Promise<ConnectionRequest>,\n successCallback: (error?: Error) => Promise<void>,\n onDisplayUri?: (uri: string) => void,\n ) {\n this.modal?.unmount();\n await this.preload();\n this.successCallback = successCallback;\n this.displayUriCallback = onDisplayUri;\n\n const parentElement = this.getMountedContainer();\n const connectionRequest = await createConnectionRequest();\n const qrCodeLink = this.createConnectionDeeplink(connectionRequest);\n\n this.displayUriCallback?.(qrCodeLink);\n\n const modal: Modal<any> = new this.options.InstallModal({\n expiresIn:\n (connectionRequest.sessionRequest.expiresAt - Date.now()) / 1000,\n connectionRequest,\n parentElement,\n showInstallModal,\n link: qrCodeLink,\n sdkVersion: getVersion(),\n generateQRCode: async (request: ConnectionRequest) => {\n const newLink = this.createConnectionDeeplink(request);\n this.displayUriCallback?.(newLink);\n return newLink;\n },\n onClose: this.onCloseModal.bind(this),\n startDesktopOnboarding: this.onStartDesktopOnboarding.bind(this),\n createConnectionRequest,\n onDisplayUri: this.displayUriCallback,\n });\n\n this.modal = modal;\n modal.mount();\n }\n\n public async renderOTPCodeModal(\n createOTPCode: () => Promise<OTPCode>,\n successCallback: (error?: Error) => Promise<void>,\n updateOTPCode: (otpCode: OTPCode, modal: AbstractOTPCodeModal) => void,\n ) {\n this.modal?.unmount();\n await this.preload();\n this.successCallback = successCallback;\n\n const container = this.getMountedContainer();\n const otpCode = await createOTPCode();\n\n const modal: AbstractOTPCodeModal = new this.options.OTPCodeModal({\n parentElement: container,\n sdkVersion: getVersion(),\n otpCode,\n onClose: this.onCloseModal.bind(this),\n createOTPCode,\n updateOTPCode: (otpCode: OTPCode) => updateOTPCode(otpCode, modal),\n });\n\n this.modal = modal;\n modal.mount();\n }\n}\n","/* eslint-disable no-restricted-globals -- Web UI uses document */\n/* eslint-disable @typescript-eslint/naming-convention -- Type parameter T is a standard convention */\n/**\n * Browser/Web UI module entry point\n */\nimport { BaseModalFactory } from './ModalFactory';\nimport type { FactoryModals } from './modals/types';\n\n/**\n * Web-specific preload that loads Stencil custom elements\n */\nexport async function preload(): Promise<void> {\n if (typeof document === 'undefined') {\n return;\n }\n try {\n const { defineCustomElements } = await import(\n '@metamask/multichain-ui/loader'\n );\n await defineCustomElements();\n } catch (error) {\n console.error('Failed to load customElements:', error);\n }\n}\n\n/**\n * ModalFactory for browser/web environments.\n * Loads Stencil web components via dynamic import.\n */\nexport class ModalFactory<\n T extends FactoryModals = FactoryModals,\n> extends BaseModalFactory<T> {\n protected async preload(): Promise<void> {\n return preload();\n }\n}\n"],"mappings":"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","names":["EventEmitter3","logger","debug","_a","TransportType","_a","_a","Bowser","PlatformType","_a","_a","init_utils","init_utils","init_utils","logger","init_utils","logger","init_utils","encodeQR","node_exports","init_node","_a","import_analytics","import_mobile_wallet_protocol_core","import_multichain_api_client","_a","fetch","import_analytics","_a","_notificationCallbacks","_a","import_multichain_api_client","import_rpc_errors","DEFAULT_REQUEST_TIMEOUT","message","_a","sessionRequest","logger","_transport","_a","isEnabled","isReactNative","_a","MetaMaskOnboarding","otpCode","StoreAdapterNode"]}
1
+ {"version":3,"sources":["../../../src/domain/errors/base.ts","../../../src/domain/errors/rpc.ts","../../../src/domain/errors/index.ts","../../../src/domain/events/index.ts","../../../src/domain/logger/index.ts","../../../src/domain/multichain/api/constants.ts","../../../src/domain/multichain/api/infura.ts","../../../src/domain/multichain/index.ts","../../../src/domain/platform/index.ts","../../../src/domain/store/adapter.ts","../../../src/domain/store/client.ts","../../../src/domain/store/index.ts","../../../src/domain/ui/types.ts","../../../src/domain/ui/index.ts","../../../src/multichain/utils/index.ts","../../../src/multichain/utils/analytics.ts","../../../src/domain/utils/index.ts","../../../src/domain/index.ts","../../../src/ui/modals/base/utils.ts","../../../src/ui/modals/base/AbstractInstallModal.ts","../../../src/ui/modals/node/install.ts","../../../src/ui/modals/base/AbstractOTPModal.ts","../../../src/ui/modals/node/otp.ts","../../../src/ui/modals/node/index.ts","../../../src/store/adapters/node.ts","../../../src/index.node.ts","../../../src/multichain/index.ts","../../../src/config/index.ts","../../../src/multichain/rpc/handlers/rpcClient.ts","../../../src/multichain/rpc/requestRouter.ts","../../../src/multichain/transports/default/index.ts","../../../src/multichain/transports/multichainApiClientWrapper/index.ts","../../../src/multichain/transports/mwp/index.ts","../../../src/multichain/transports/constants.ts","../../../src/multichain/transports/mwp/KeyManager.ts","../../../src/store/index.ts","../../../src/domain/errors/storage.ts","../../../src/ui/ModalFactory.ts","../../../src/ui/index.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/naming-convention */\n/* eslint-disable @typescript-eslint/parameter-properties */\nimport type { ErrorCodes } from './types';\n\nexport abstract class BaseErr<\n C extends string,\n T extends ErrorCodes,\n> extends Error {\n constructor(\n public readonly message: `${C}Err${T}: ${string}`,\n public readonly code: T,\n ) {\n super(message);\n }\n}\n","/* eslint-disable @typescript-eslint/parameter-properties */\nimport { BaseErr } from './base';\nimport type { RPCErrorCodes } from './types';\n\nexport class RPCHttpErr extends BaseErr<'RPC', RPCErrorCodes> {\n static readonly code = 50;\n\n constructor(\n readonly rpcEndpoint: string,\n readonly method: string,\n readonly httpStatus: number,\n ) {\n super(\n `RPCErr${RPCHttpErr.code}: ${httpStatus} on ${rpcEndpoint} for method ${method}`,\n RPCHttpErr.code,\n );\n }\n}\n\nexport class RPCReadonlyResponseErr extends BaseErr<'RPC', RPCErrorCodes> {\n static readonly code = 51;\n\n constructor(public readonly reason: string) {\n super(\n `RPCErr${RPCReadonlyResponseErr.code}: RPC Client response reason ${reason}`,\n RPCReadonlyResponseErr.code,\n );\n }\n}\n\nexport class RPCReadonlyRequestErr extends BaseErr<'RPC', RPCErrorCodes> {\n static readonly code = 52;\n\n constructor(public readonly reason: string) {\n super(\n `RPCErr${RPCReadonlyRequestErr.code}: RPC Client fetch reason ${reason}`,\n RPCReadonlyRequestErr.code,\n );\n }\n}\n\nexport class RPCInvokeMethodErr extends BaseErr<'RPC', RPCErrorCodes> {\n static readonly code = 53;\n\n constructor(public readonly reason: string) {\n super(\n `RPCErr${RPCInvokeMethodErr.code}: RPC Client invoke method reason (${reason})`,\n RPCInvokeMethodErr.code,\n );\n }\n}\n","export * from './rpc';\nexport type * from './types';\n","/* eslint-disable @typescript-eslint/explicit-function-return-type */\nimport { EventEmitter as EventEmitter3 } from 'eventemitter3';\n\n/**\n * A type-safe event emitter that provides a strongly-typed wrapper around EventEmitter2.\n *\n * This class ensures type safety for event names and their corresponding argument types,\n * making it easier to work with events in a type-safe manner.\n *\n * @template TEvents - A record type mapping event names to their argument types.\n * Each key represents an event name, and the value is a tuple of argument types.\n */\nexport class EventEmitter<TEvents extends Record<string, unknown[]>> {\n readonly #emitter = new EventEmitter3();\n\n /**\n * Emits an event with the specified name and arguments.\n *\n * @template TEventName - The name of the event to emit (must be a key of TEvents)\n * @param eventName - The name of the event to emit\n * @param eventArg - The arguments to pass to the event handlers\n */\n emit<TEventName extends keyof TEvents & string>(\n eventName: TEventName,\n ...eventArg: TEvents[TEventName]\n ) {\n this.#emitter.emit(eventName, ...eventArg);\n }\n\n /**\n * Registers an event handler for the specified event.\n *\n * @template TEventName - The name of the event to listen for (must be a key of TEvents)\n * @param eventName - The name of the event to listen for\n * @param handler - The function to call when the event is emitted\n * @returns Nothing\n */\n on<TEventName extends keyof TEvents & string>(\n eventName: TEventName,\n handler: (...eventArg: TEvents[TEventName]) => void,\n ) {\n this.#emitter.on(eventName, handler as (...args: any[]) => void);\n return () => {\n this.off(eventName, handler as (...args: any[]) => void);\n };\n }\n\n /**\n * Removes a specific event handler for the specified event.\n *\n * @template TEventName - The name of the event to remove the handler from (must be a key of TEvents)\n * @param eventName - The name of the event to remove the handler from\n * @param handler - The specific handler function to remove\n */\n off<TEventName extends keyof TEvents & string>(\n eventName: TEventName,\n handler: (...eventArg: TEvents[TEventName]) => void,\n ) {\n this.#emitter.off(eventName, handler as (...args: any[]) => void);\n }\n\n /**\n * Removes a specific event handler for the specified event.\n * Added for compatibility as some libraries use this method name.\n *\n * @template TEventName - The name of the event to remove the handler from (must be a key of TEvents)\n * @param eventName - The name of the event to remove the handler from\n * @param handler - The specific handler function to remove\n */\n removeListener<TEventName extends keyof TEvents & string>(\n eventName: TEventName,\n handler: (...eventArg: TEvents[TEventName]) => void,\n ) {\n this.#emitter.off(eventName, handler as (...args: any[]) => void);\n }\n\n /**\n * Registers an event handler for the specified event that will only be called once.\n *\n * @template TEventName - The name of the event to listen for (must be a key of TEvents)\n * @param eventName - The name of the event to listen for\n * @param handler - The function to call when the event is emitted (only once)\n * @returns A function to remove the listener\n */\n once<TEventName extends keyof TEvents & string>(\n eventName: TEventName,\n handler: (...eventArg: TEvents[TEventName]) => void,\n ) {\n this.#emitter.once(eventName, handler as (...args: any[]) => void);\n return () => {\n this.off(eventName, handler as (...args: any[]) => void);\n };\n }\n\n /**\n * Returns the number of listeners registered for the specified event.\n *\n * @template TEventName - The name of the event to count listeners for (must be a key of TEvents)\n * @param eventName - The name of the event to count listeners for\n * @returns The number of listeners registered for the event\n */\n listenerCount<TEventName extends keyof TEvents & string>(\n eventName: TEventName,\n ): number {\n return this.#emitter.listenerCount(eventName);\n }\n}\n\nexport type * from './types';\n","/* eslint-disable no-restricted-globals */\n// eslint-disable-next-line import-x/no-extraneous-dependencies\nimport debug from 'debug';\n\nimport type { StoreClient } from '../store/client';\n\n/**\n * Supported debug namespace types for the MetaMask SDK logger.\n * These namespaces help categorize and filter debug output.\n */\nexport type LoggerNameSpaces =\n | 'metamask-sdk:*'\n | 'metamask-sdk'\n | 'metamask-sdk:core'\n | 'metamask-sdk:provider'\n | 'metamask-sdk:ui'\n | 'metamask-sdk:transport';\n\n/**\n * Creates a debug logger instance with the specified namespace and color.\n *\n * This function initializes a debug logger using the 'debug' library,\n * which allows for conditional logging based on environment variables or storage settings.\n *\n * @param namespace - The debug namespace to use for this logger instance\n * @param color - The ANSI color code to use for log output (default: '214' for yellow)\n * @returns A configured debug logger instance\n */\nexport const createLogger = (\n namespace: LoggerNameSpaces = 'metamask-sdk',\n color = '214',\n): debug.Debugger => {\n const logger = debug(namespace);\n logger.color = color; // Yellow color (basic ANSI)\n return logger;\n};\n\n/**\n * Enables debug logging for the specified namespace.\n *\n * This function activates debug output for the given namespace,\n * allowing debug messages to be displayed in the console.\n *\n * @param namespace - The debug namespace to enable\n */\nexport const enableDebug = (\n namespace: LoggerNameSpaces = 'metamask-sdk',\n): void => {\n debug.enable(namespace);\n};\n\n/**\n * Checks if a specific namespace is enabled in the given debug value string.\n *\n * This function determines whether debug logging should be active for a namespace\n * by checking if the debug value contains the namespace, a wildcard pattern, or\n * the general MetaMask SDK wildcard.\n *\n * @param debugValue - The debug configuration string (e.g., from environment or storage)\n * @param namespace - The namespace to check for enablement\n * @returns True if the namespace should have debug logging enabled, false otherwise\n */\nfunction isNamespaceEnabled(\n debugValue: string,\n namespace: LoggerNameSpaces,\n): boolean {\n return (\n debugValue.includes(namespace) ||\n debugValue.includes('metamask-sdk:*') ||\n debugValue.includes('*')\n );\n}\n\n/**\n * Determines if debug logging is enabled for a specific namespace.\n *\n * This function checks multiple sources to determine if debug logging should be active:\n * 1. First checks the process environment variable 'debug'\n * 2. Falls back to checking the debug setting in storage\n * 3. Returns false if neither source enables the namespace\n *\n * @param namespace - The namespace to check for debug enablement\n * @param storage - The storage client to check for debug settings\n * @returns Promise that resolves to true if debug logging is enabled, false otherwise\n */\nexport const isEnabled = async (\n namespace: LoggerNameSpaces,\n storage: StoreClient,\n): Promise<boolean> => {\n if ('process' in globalThis && process?.env?.DEBUG) {\n const { DEBUG } = process.env;\n return isNamespaceEnabled(DEBUG, namespace);\n }\n\n const storageDebug = await storage.getDebug();\n if (storageDebug) {\n return isNamespaceEnabled(storageDebug, namespace);\n }\n\n return false;\n};\n","/* c8 ignore start */\nimport type { RpcUrlsMap } from './types';\n\nexport const infuraRpcUrls: RpcUrlsMap = {\n // ###### Ethereum ######\n // Mainnet\n 'eip155:1': 'https://mainnet.infura.io/v3/',\n // Goerli\n 'eip155:5': 'https://goerli.infura.io/v3/',\n // Sepolia 11155111\n 'eip155:11155111': 'https://sepolia.infura.io/v3/',\n // ###### Linea ######\n // Mainnet Alpha\n 'eip155:59144': 'https://linea-mainnet.infura.io/v3/',\n // Testnet ( linea goerli )\n 'eip155:59140': 'https://linea-goerli.infura.io/v3/',\n // ###### Polygon ######\n // Mainnet\n 'eip155:137': 'https://polygon-mainnet.infura.io/v3/',\n // Mumbai\n 'eip155:80001': 'https://polygon-mumbai.infura.io/v3/',\n // ###### Optimism ######\n // Mainnet\n 'eip155:10': 'https://optimism-mainnet.infura.io/v3/',\n // Goerli\n 'eip155:420': 'https://optimism-goerli.infura.io/v3/',\n // ###### Arbitrum ######\n // Mainnet\n 'eip155:42161': 'https://arbitrum-mainnet.infura.io/v3/',\n // Goerli\n 'eip155:421613': 'https://arbitrum-goerli.infura.io/v3/',\n // ###### Palm ######\n // Mainnet\n 'eip155:11297108109': 'https://palm-mainnet.infura.io/v3/',\n // Testnet\n 'eip155:11297108099': 'https://palm-testnet.infura.io/v3/',\n // ###### Avalanche C-Chain ######\n // Mainnet\n 'eip155:43114': 'https://avalanche-mainnet.infura.io/v3/',\n // Fuji\n 'eip155:43113': 'https://avalanche-fuji.infura.io/v3/',\n // // ###### NEAR ######\n // // Mainnet\n // 'near:mainnet': `https://near-mainnet.infura.io/v3/`,\n // // Testnet\n // 'near:testnet': `https://near-testnet.infura.io/v3/`,\n // ###### Aurora ######\n // Mainnet\n 'eip155:1313161554': 'https://aurora-mainnet.infura.io/v3/',\n // Testnet\n 'eip155:1313161555': 'https://aurora-testnet.infura.io/v3/',\n // ###### StarkNet ######\n // Mainnet\n //\n // 'starknet:SN_MAIN': `https://starknet-mainnet.infura.io/v3/`,\n // // Goerli\n // 'starknet:SN_GOERLI': `https://starknet-goerli.infura.io/v3/`,\n // // Goerli 2\n // 'starknet:SN_GOERLI2': `https://starknet-goerli2.infura.io/v3/`,\n // ###### Celo ######\n // Mainnet\n 'eip155:42220': 'https://celo-mainnet.infura.io/v3/',\n // Alfajores Testnet\n 'eip155:44787': 'https://celo-alfajores.infura.io/v3/',\n};\n\n// Methods that are passed through to the RPC node\nexport const RPC_HANDLED_METHODS = new Set([\n 'eth_blockNumber',\n 'eth_gasPrice',\n 'eth_maxPriorityFeePerGas',\n 'eth_blobBaseFee',\n 'eth_feeHistory',\n 'eth_getBalance',\n 'eth_getCode',\n 'eth_getStorageAt',\n 'eth_call',\n 'eth_estimateGas',\n 'eth_getLogs',\n 'eth_getProof',\n 'eth_getTransactionCount',\n 'eth_getBlockByNumber',\n 'eth_getBlockByHash',\n 'eth_getBlockTransactionCountByNumber',\n 'eth_getBlockTransactionCountByHash',\n 'eth_getUncleCountByBlockNumber',\n 'eth_getUncleCountByBlockHash',\n 'eth_getTransactionByHash',\n 'eth_getTransactionByBlockNumberAndIndex',\n 'eth_getTransactionByBlockHashAndIndex',\n 'eth_getTransactionReceipt',\n 'eth_getUncleByBlockNumberAndIndex',\n 'eth_getUncleByBlockHashAndIndex',\n 'eth_getFilterChanges',\n 'eth_getFilterLogs',\n 'eth_newBlockFilter',\n 'eth_newFilter',\n 'eth_newPendingTransactionFilter',\n 'eth_sendRawTransaction',\n 'eth_syncing',\n 'eth_uninstallFilter',\n]);\n\n// Methods that are handled by the SDK directly\nexport const SDK_HANDLED_METHODS = new Set(['eth_accounts', 'eth_chainId']);\n","/* eslint-disable jsdoc/require-jsdoc */\nimport { infuraRpcUrls } from './constants';\nimport type { RpcUrlsMap } from './types';\n\nexport function getInfuraRpcUrls(infuraAPIKey: string): RpcUrlsMap {\n return Object.keys(infuraRpcUrls).reduce<RpcUrlsMap>((acc, key) => {\n const typedKey = key as keyof typeof infuraRpcUrls;\n acc[typedKey] = `${infuraRpcUrls[typedKey]}${infuraAPIKey}`;\n return acc;\n }, {});\n}\n","/* eslint-disable @typescript-eslint/parameter-properties */\n/* eslint-disable jsdoc/require-jsdoc */\nimport type {\n MultichainApiClient,\n SessionProperties,\n} from '@metamask/multichain-api-client';\nimport type { CaipAccountId, Json } from '@metamask/utils';\n\nimport { EventEmitter, type SDKEvents } from '../events';\nimport type { StoreClient } from '../store/client';\nimport type { InvokeMethodOptions, RPCAPI, Scope } from './api/types';\nimport type {\n ExtendedTransport,\n MergeableMultichainOptions,\n MultichainOptions,\n} from './types';\n\nexport type ConnectionStatus =\n | 'pending'\n | 'loaded'\n | 'disconnected'\n | 'connected'\n | 'connecting';\n\nexport enum TransportType {\n Browser = 'browser',\n MWP = 'mwp',\n UNKNOWN = 'unknown',\n}\n\n/**\n * Abstract base class for the Multichain SDK implementation.\n *\n * This class defines the core interface that all Multichain SDK implementations\n * must provide, including session management, connection handling, and method invocation.\n */\nexport abstract class MultichainCore extends EventEmitter<SDKEvents> {\n abstract storage: StoreClient;\n\n abstract status: ConnectionStatus;\n\n abstract provider: MultichainApiClient<RPCAPI>;\n\n abstract transport: ExtendedTransport;\n\n abstract transportType: TransportType;\n\n /**\n * Establishes a connection to the multichain provider, or re-use existing session\n *\n * @returns Promise that resolves to the session data\n */\n abstract connect(\n scopes: Scope[],\n caipAccountIds: CaipAccountId[],\n sessionProperties?: SessionProperties,\n forceRequest?: boolean,\n ): Promise<void>;\n\n /**\n * Disconnects from the multichain provider.\n *\n * @returns Promise that resolves when disconnection is complete\n */\n abstract disconnect(scopes?: Scope[]): Promise<void>;\n\n /**\n * Invokes an RPC method with the specified options.\n *\n * @param options - The method invocation options including scope and request details\n * @returns Promise that resolves to the method result\n */\n abstract invokeMethod(options: InvokeMethodOptions): Promise<Json>;\n\n abstract openSimpleDeeplinkIfNeeded(): void;\n\n abstract emitSessionChanged(): Promise<void>;\n\n constructor(protected options: MultichainOptions) {\n super();\n }\n\n /**\n * Merges the given options into the current instance options.\n * Only the mergeable keys are updated (api.supportedNetworks, ui.*, mobile.*, transport.extensionId, debug).\n * The main thing to note is that the value for `dapp` is not merged as it does not make sense for\n * subsequent calls to `createMultichainClient` to have a different `dapp` value.\n * Used when createMultichainClient is called with an existing singleton.\n *\n * @param partial - Options to merge/overwrite onto the current instance\n */\n mergeOptions(partial: MergeableMultichainOptions): void {\n const opts = this.options;\n this.options = {\n ...opts,\n api: {\n ...opts.api,\n supportedNetworks: {\n ...opts.api.supportedNetworks,\n ...(partial.api?.supportedNetworks ?? {}),\n },\n },\n ui: {\n ...opts.ui,\n headless: partial.ui?.headless ?? opts.ui.headless,\n preferExtension: partial.ui?.preferExtension ?? opts.ui.preferExtension,\n showInstallModal:\n partial.ui?.showInstallModal ?? opts.ui.showInstallModal,\n },\n mobile: {\n ...opts.mobile,\n ...(partial.mobile ?? {}),\n },\n transport: {\n ...(opts.transport ?? {}),\n extensionId:\n partial.transport?.extensionId ?? opts.transport?.extensionId,\n },\n debug: partial.debug ?? opts.debug,\n };\n }\n}\n/* c8 ignore end */\n\nexport function getTransportType(type: string): TransportType {\n switch (type) {\n case 'browser':\n return TransportType.Browser;\n case 'mwp':\n return TransportType.MWP;\n default:\n return TransportType.UNKNOWN;\n }\n}\n\nexport * from './api/constants';\nexport * from './api/infura';\nexport type * from './api/types';\nexport type * from './types';\n","/* eslint-disable @typescript-eslint/explicit-function-return-type */\n/* eslint-disable no-restricted-globals */\n/* eslint-disable jsdoc/require-jsdoc */\n/* eslint-disable @typescript-eslint/naming-convention */\n/* eslint-disable import-x/no-named-as-default-member -- Bowser.parse is the intended API */\nimport Bowser from 'bowser';\n\nexport enum PlatformType {\n // React Native or Nodejs\n NonBrowser = 'nodejs',\n // MetaMask Mobile in-app browser\n MetaMaskMobileWebview = 'in-app-browser',\n // Desktop Browser\n DesktopWeb = 'web-desktop',\n // Mobile Browser\n MobileWeb = 'web-mobile',\n // ReactNative\n ReactNative = 'react-native',\n}\n\nfunction isNotBrowser(): boolean {\n if (typeof window === 'undefined') {\n return true;\n }\n if (!window?.navigator) {\n return true;\n }\n if (\n typeof global !== 'undefined' &&\n global?.navigator?.product === 'ReactNative'\n ) {\n return true;\n }\n return navigator?.product === 'ReactNative';\n}\n\nfunction isReactNative(): boolean {\n const hasWindowNavigator =\n typeof window !== 'undefined' && window.navigator !== undefined;\n const nav = hasWindowNavigator ? window.navigator : undefined;\n\n if (!nav) {\n return false;\n }\n\n return hasWindowNavigator && window.navigator?.product === 'ReactNative';\n}\n\nfunction isMetaMaskMobileWebView(): boolean {\n return (\n typeof window !== 'undefined' &&\n // @ts-expect-error ReactNativeWebView should be defined\n Boolean(window.ReactNativeWebView) &&\n Boolean(window.navigator.userAgent.endsWith('MetaMaskMobile'))\n );\n}\n\nfunction isMobile(): boolean {\n const browser = Bowser.parse(window.navigator.userAgent);\n return (\n browser?.platform?.type === 'mobile' || browser?.platform?.type === 'tablet'\n );\n}\n\nexport function getPlatformType(): PlatformType {\n if (isReactNative()) {\n return PlatformType.ReactNative;\n }\n if (isNotBrowser()) {\n return PlatformType.NonBrowser;\n }\n if (isMetaMaskMobileWebView()) {\n return PlatformType.MetaMaskMobileWebview;\n }\n if (isMobile()) {\n return PlatformType.MobileWeb;\n }\n return PlatformType.DesktopWeb;\n}\n\n/**\n * Check if MetaMask extension is installed\n *\n * @returns True if extension is installed, false otherwise\n */\nexport function isMetamaskExtensionInstalled(): boolean {\n if (typeof window === 'undefined') {\n return false;\n }\n // @ts-expect-error ethereum should be defined\n return Boolean(window.ethereum?.isMetaMask);\n}\n\nexport function isSecure(): boolean {\n const platformType = getPlatformType();\n return isReactNative() || platformType === PlatformType.MobileWeb;\n}\n\n// Immediately start MetaMask detection when module loads\nconst detectionPromise: Promise<boolean> = (async () => {\n const pt = getPlatformType();\n if (pt === PlatformType.NonBrowser || pt === PlatformType.ReactNative) {\n return Promise.resolve(false);\n }\n\n return new Promise((resolve) => {\n const providers: any[] = [];\n\n const handler = (event: any) => {\n if (event?.detail?.info?.rdns) {\n providers.push(event.detail);\n }\n };\n\n window.addEventListener('eip6963:announceProvider', handler);\n window.dispatchEvent(new Event('eip6963:requestProvider'));\n\n setTimeout(() => {\n window.removeEventListener('eip6963:announceProvider', handler);\n\n const hasMetaMask = providers.some((provider) =>\n provider?.info?.rdns?.startsWith('io.metamask'),\n );\n\n resolve(hasMetaMask);\n }, 300); // default timeout\n });\n})();\n\nexport async function hasExtension(): Promise<boolean> {\n return detectionPromise;\n}\n","/* eslint-disable @typescript-eslint/parameter-properties */\n/* c8 ignore start */\n// biome-ignore lint/suspicious/noExplicitAny: Needed here\nexport type StoreOptions = Record<string, any>;\n\nexport abstract class StoreAdapter {\n abstract platform: 'web' | 'rn' | 'node';\n\n constructor(public options?: StoreOptions) {}\n\n abstract get(key: string): Promise<string | null>;\n\n abstract set(key: string, value: string): Promise<void>;\n\n abstract delete(key: string): Promise<void>;\n}\n","/* c8 ignore start */\nimport type { StoreAdapter } from '.';\nimport type { TransportType } from '../multichain';\n\nexport abstract class StoreClient {\n abstract adapter: StoreAdapter;\n\n abstract getAnonId(): Promise<string>;\n\n abstract getExtensionId(): Promise<string | null>;\n\n abstract setExtensionId(extensionId: string): Promise<void>;\n\n abstract getTransport(): Promise<TransportType | null>;\n\n abstract setTransport(transport: TransportType): Promise<void>;\n\n abstract removeTransport(): Promise<void>;\n\n abstract setAnonId(anonId: string): Promise<void>;\n\n abstract removeExtensionId(): Promise<void>;\n\n abstract removeAnonId(): Promise<void>;\n\n abstract getDebug(): Promise<string | null>;\n}\n","export * from './adapter';\nexport * from './client';\n","import type { Components } from '@metamask/multichain-ui';\n\nimport type { ConnectionRequest } from '../multichain';\n\nexport type OTPCode = string;\nexport type QRLink = string;\n\nexport type InstallWidgetProps = Components.MmInstallModal & {\n parentElement?: Element;\n connectionRequest: ConnectionRequest;\n onClose: (shouldTerminate?: boolean) => void;\n startDesktopOnboarding: () => void;\n createConnectionRequest: () => Promise<ConnectionRequest>;\n generateQRCode: (connectionRequest: ConnectionRequest) => Promise<QRLink>;\n /**\n * Callback invoked when a QR code link is generated or regenerated.\n * This allows consumers to display their own custom QR code UI.\n *\n * @param uri - The deeplink URI to be displayed as a QR code\n */\n onDisplayUri?: (uri: QRLink) => void;\n};\n\nexport type OTPCodeWidgetProps = Components.MmOtpModal & {\n parentElement?: Element;\n onClose: () => Promise<void>;\n onDisconnect?: () => void;\n createOTPCode: () => Promise<OTPCode>;\n updateOTPCode: (otpValue: string) => void;\n};\n\nexport type DataType = OTPCode | QRLink;\n/**\n * Abstract Modal class with shared functionality across all models\n */\nexport abstract class Modal<Options, Data extends DataType = DataType> {\n protected abstract instance?:\n | HTMLMmInstallModalElement\n | HTMLMmOtpModalElement\n | undefined;\n\n abstract mount(): void;\n\n abstract unmount(): void;\n\n // eslint-disable-next-line @typescript-eslint/parameter-properties\n constructor(protected readonly options: Options) {}\n\n get isMounted(): boolean {\n return this.instance !== undefined;\n }\n\n get data(): Data {\n if (\n typeof this.options === 'object' &&\n this.options &&\n 'link' in this.options\n ) {\n return this.options.link as Data;\n }\n\n if (\n typeof this.options === 'object' &&\n this.options &&\n 'otpCode' in this.options\n ) {\n return this.options.otpCode as Data;\n }\n\n throw new Error('Invalid options');\n }\n\n set data(data: Data) {\n if (\n typeof this.options === 'object' &&\n this.options &&\n 'link' in this.options\n ) {\n this.options.link = data;\n }\n\n if (\n typeof this.options === 'object' &&\n this.options &&\n 'otpCode' in this.options\n ) {\n this.options.otpCode = data;\n }\n }\n}\n","export type * from './factory';\nexport * from './types';\n","/* eslint-disable no-restricted-globals -- Browser APIs are intentionally used */\n/* eslint-disable jsdoc/require-param-description -- Auto-generated JSDoc */\n/* eslint-disable jsdoc/require-returns -- Auto-generated JSDoc */\n/* eslint-disable @typescript-eslint/explicit-function-return-type -- Inferred types are sufficient */\nimport type { SessionProperties } from '@metamask/multichain-api-client';\nimport {\n type CaipAccountId,\n type CaipChainId,\n parseCaipAccountId,\n parseCaipChainId,\n} from '@metamask/utils';\nimport { deflate } from 'pako';\n\nimport {\n type DappSettings,\n getPlatformType,\n type MultichainOptions,\n PlatformType,\n type Scope,\n type SessionData,\n} from '../../domain';\n\nexport type OptionalScopes = Record<Scope, SessionData['sessionScopes'][Scope]>;\n\n/**\n * Returns the global object for the current JS environment.\n *\n * @returns The global object as a record for indexing\n */\nexport function getGlobalObject(): Record<string, unknown> {\n if (typeof globalThis !== 'undefined') {\n return globalThis as unknown as Record<string, unknown>;\n }\n if (typeof global !== 'undefined') {\n return global as unknown as Record<string, unknown>;\n }\n if (typeof self !== 'undefined') {\n return self as unknown as Record<string, unknown>;\n }\n if (typeof window !== 'undefined') {\n return window as unknown as Record<string, unknown>;\n }\n throw new Error('Unable to locate global object');\n}\n\n/**\n * Cross-platform base64 encoding\n * Works in browser, Node.js, and React Native environments\n *\n * @param str\n */\nfunction base64Encode(str: string): string {\n if (typeof btoa !== 'undefined') {\n // Browser and React Native with polyfills\n return btoa(str);\n } else if (typeof Buffer !== 'undefined') {\n // Node.js\n return Buffer.from(str).toString('base64');\n }\n throw new Error('No base64 encoding method available');\n}\n\n/**\n * Compress a string using pako (deflateRaw)\n * Returns a base64-encoded compressed string\n *\n * @param str\n */\nexport function compressString(str: string): string {\n const compressed = deflate(str);\n\n // Convert Uint8Array to string for base64 encoding\n const binaryString = String.fromCharCode.apply(null, Array.from(compressed));\n return base64Encode(binaryString);\n}\n\n/**\n *\n * @param dapp\n */\nexport function getDappId(dapp: DappSettings) {\n return dapp.url ?? dapp.name;\n}\n\n/**\n *\n * @param options\n * @param deeplink\n * @param universalLink\n */\nexport function openDeeplink(\n options: MultichainOptions,\n deeplink: string,\n universalLink: string,\n) {\n const { mobile } = options;\n const useDeeplink = mobile?.useDeeplink ?? true;\n if (useDeeplink) {\n if (typeof window !== 'undefined') {\n // We don't need to open a deeplink in a new tab\n // It avoid the browser to display a blank page\n window.location.href = deeplink;\n }\n } else if (typeof document !== 'undefined') {\n // Workaround for https://github.com/rainbow-me/rainbowkit/issues/524.\n // Using 'window.open' causes issues on iOS in non-Safari browsers and\n // WebViews where a blank tab is left behind after connecting.\n // This is especially bad in some WebView scenarios (e.g. following a\n // link from Twitter) where the user doesn't have any mechanism for\n // closing the blank tab.\n // For whatever reason, links with a target of \"_blank\" don't suffer\n // from this problem, and programmatically clicking a detached link\n // element with the same attributes also avoids the issue.\n const link = document.createElement('a');\n link.href = universalLink;\n link.target = '_self';\n link.rel = 'noreferrer noopener';\n link.click();\n }\n}\n\n/**\n * Merges existing session (from getCaipSession) with newly requested scopes, accounts, and session properties.\n * Derives existing scopes/accounts from sessionData.sessionScopes, then merges with requested values.\n *\n * @param sessionData - Current CAIP session data\n * @param scopes - Newly requested scopes\n * @param caipAccountIds - Newly requested account IDs\n * @param sessionProperties - New session properties to merge over existing\n * @returns requestedScopes, requestedCaipAccountIds, and requestedSessionProperties\n */\nexport function mergeRequestedSessionWithExisting(\n sessionData: SessionData,\n scopes: Scope[],\n caipAccountIds: CaipAccountId[],\n sessionProperties?: SessionProperties,\n): {\n mergedScopes: Scope[];\n mergedCaipAccountIds: CaipAccountId[];\n mergedSessionProperties: SessionProperties;\n} {\n const existingCaipChainIds = Object.keys(sessionData.sessionScopes);\n const existingCaipAccountIds: string[] = [];\n Object.values(sessionData.sessionScopes).forEach((scopeObject) => {\n if (scopeObject?.accounts && Array.isArray(scopeObject.accounts)) {\n scopeObject.accounts.forEach((account) => {\n existingCaipAccountIds.push(account);\n });\n }\n });\n\n const mergedScopes = Array.from(\n new Set([...existingCaipChainIds, ...scopes]),\n ) as Scope[];\n const mergedCaipAccountIds = Array.from(\n new Set([...existingCaipAccountIds, ...caipAccountIds]),\n ) as CaipAccountId[];\n const mergedSessionProperties = {\n ...sessionData.sessionProperties,\n ...sessionProperties,\n };\n return {\n mergedScopes,\n mergedCaipAccountIds,\n mergedSessionProperties,\n };\n}\n\n/**\n *\n * @param scopes\n */\nexport function getOptionalScopes(scopes: Scope[]) {\n return scopes.reduce<OptionalScopes>(\n (prev, scope) => ({\n // biome-ignore lint/performance/noAccumulatingSpread: Needed\n ...prev,\n [scope]: {\n methods: [],\n notifications: [],\n accounts: [],\n },\n }),\n {},\n );\n}\n\nexport const extractFavicon = () => {\n if (typeof document === 'undefined') {\n return undefined;\n }\n\n let favicon: string | undefined;\n const nodeList = document.getElementsByTagName('link');\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let i = 0; i < nodeList.length; i++) {\n if (\n nodeList[i].getAttribute('rel') === 'icon' ||\n nodeList[i].getAttribute('rel') === 'shortcut icon'\n ) {\n favicon = nodeList[i].getAttribute('href') ?? undefined;\n }\n }\n return favicon;\n};\n\n/**\n * Normalizes a non-http(s) URL from a React Native app into a valid https URL.\n * Extracts the scheme, sanitizes it to a DNS-safe label, and builds a .rn.dapp.local URL.\n *\n * @param url - The original URL to normalize\n * @returns An object with the normalized URL and original scheme, or undefined if no normalization needed\n */\nfunction normalizeNativeUrl(\n url: string,\n): { url: string; nativeScheme: string } | undefined {\n // Matches \"http://\" or \"https://\"\n const httpPattern = /^https?:\\/\\//u;\n if (httpPattern.test(url)) {\n return undefined;\n }\n\n // Captures the scheme before \"://\" — e.g. \"myapp\" from \"myapp://path\"\n const schemeMatch = url.match(/^([^:]*):\\/\\//u);\n const rawScheme = schemeMatch?.[1] ?? url;\n const sanitized = rawScheme\n .toLowerCase()\n // Replace non-DNS chars with hyphens — e.g. \"My.App\" -> \"my-app\"\n .replace(/[^a-z0-9-]/gu, '-')\n // Strip leading/trailing hyphens — e.g. \"-my-app-\" -> \"my-app\"\n .replace(/^-+|-+$/gu, '');\n\n const subdomain = (sanitized || 'unknown').slice(0, 63).replace(/-+$/u, '');\n\n return {\n url: `https://${subdomain}.rn.dapp.local`,\n nativeScheme: url,\n };\n}\n\n/**\n *\n * @param options\n */\nexport function setupDappMetadata(\n options: MultichainOptions,\n): MultichainOptions {\n const platform = getPlatformType();\n const isBrowser =\n platform === PlatformType.DesktopWeb ||\n platform === PlatformType.MobileWeb ||\n platform === PlatformType.MetaMaskMobileWebview;\n\n if (!options.dapp?.name) {\n throw new Error('You must provide dapp name');\n }\n if (isBrowser) {\n options.dapp = {\n ...options.dapp,\n url: `${window.location.protocol}//${window.location.host}`,\n };\n }\n if (!options.dapp?.url) {\n throw new Error('You must provide dapp url');\n }\n\n // Normalize non-http(s) URLs on React Native platforms\n if (platform === PlatformType.ReactNative && options.dapp.url) {\n const normalized = normalizeNativeUrl(options.dapp.url);\n if (normalized) {\n console.info(\n `Normalizing dapp URL for React Native: \"${options.dapp.url}\" -> \"${normalized.url}\"`,\n );\n options.dapp = {\n ...options.dapp,\n url: normalized.url,\n nativeScheme: normalized.nativeScheme,\n };\n }\n }\n\n const BASE_64_ICON_MAX_LENGTH = 163400;\n // Check if iconUrl and url are valid\n const urlPattern = /^(http|https):\\/\\/[^\\s]*$/u; // Regular expression for URLs starting with http:// or https://\n if (options.dapp) {\n if ('iconUrl' in options.dapp) {\n if (options.dapp.iconUrl && !urlPattern.test(options.dapp.iconUrl)) {\n console.warn(\n 'Invalid dappMetadata.iconUrl: URL must start with http:// or https://',\n );\n options.dapp.iconUrl = undefined;\n }\n }\n // This check ensures that the base64Icon string in the dappMetadata does not exceed 163,400 characters.\n // The character limit is important because a longer base64-encoded string causes the connection to the mobile app to fail.\n // Keeping the base64Icon string length below this threshold ensures reliable communication and functionality.\n if ('base64Icon' in options.dapp) {\n if (\n options.dapp.base64Icon &&\n options.dapp.base64Icon.length > BASE_64_ICON_MAX_LENGTH\n ) {\n console.warn(\n 'Invalid dappMetadata.base64Icon: Base64-encoded icon string length must be less than 163400 characters',\n );\n\n options.dapp.base64Icon = undefined;\n }\n }\n if (options.dapp.url && !urlPattern.test(options.dapp.url)) {\n console.warn(\n 'Invalid dappMetadata.url: URL must start with http:// or https://',\n );\n }\n const favicon = extractFavicon();\n if (\n favicon &&\n !('iconUrl' in options.dapp) &&\n !('base64Icon' in options.dapp)\n ) {\n const faviconUrl = `${window.location.protocol}//${window.location.host}${favicon}`;\n // @ts-expect-error -- iconUrl may not exist on all dapp types\n options.dapp.iconUrl = faviconUrl;\n }\n }\n return options;\n}\n\n/**\n * Enhanced scope checking function that validates both scopes and accounts\n *\n * @param currentScopes - Current scopes from the existing session\n * @param proposedScopes - Proposed scopes from the connect options\n * @param walletSession - The existing wallet session data\n * @param proposedCaipAccountIds - Proposed account IDs from the connect options\n * @returns true if scopes and accounts match, false otherwise\n */\nexport function isSameScopesAndAccounts(\n currentScopes: Scope[],\n proposedScopes: Scope[],\n walletSession: SessionData,\n proposedCaipAccountIds: CaipAccountId[],\n): boolean {\n const isSameScopes =\n currentScopes.every((scope) => proposedScopes.includes(scope)) &&\n proposedScopes.every((scope) => currentScopes.includes(scope));\n\n if (!isSameScopes) {\n return false;\n }\n\n const existingAccountIds: CaipAccountId[] = Object.values(\n walletSession.sessionScopes,\n )\n .filter(({ accounts }) => Boolean(accounts))\n .flatMap(({ accounts }) => accounts ?? []);\n\n const allProposedAccountsIncluded = proposedCaipAccountIds.every(\n (proposedAccountId) => existingAccountIds.includes(proposedAccountId),\n );\n\n return allProposedAccountsIncluded;\n}\n\n/**\n *\n * @param caipAccountIds\n */\nexport function getValidAccounts(caipAccountIds: CaipAccountId[]) {\n return caipAccountIds.reduce<ReturnType<typeof parseCaipAccountId>[]>(\n (caipAccounts, caipAccountId) => {\n try {\n // biome-ignore lint/performance/noAccumulatingSpread: Needed\n return [...caipAccounts, parseCaipAccountId(caipAccountId)];\n } catch (error) {\n const stringifiedAccountId = JSON.stringify(caipAccountId);\n console.error(\n `Invalid CAIP account ID: ${stringifiedAccountId}`,\n error,\n );\n return caipAccounts;\n }\n },\n [],\n );\n}\n\n/**\n * Adds valid accounts to their corresponding scopes based on chain namespace and reference.\n * Returns a new OptionalScopes object without modifying the input.\n *\n * @param optionalScopes - The scopes to add accounts to\n * @param validAccounts - Array of parsed valid accounts\n * @returns A new OptionalScopes object with accounts added to matching scopes\n */\nexport function addValidAccounts(\n optionalScopes: OptionalScopes,\n validAccounts: ReturnType<typeof getValidAccounts>,\n): OptionalScopes {\n if (!optionalScopes || !validAccounts?.length) {\n return optionalScopes;\n }\n\n const result: OptionalScopes = Object.fromEntries(\n Object.entries(optionalScopes).map(([scope, scopeData]) => [\n scope,\n {\n methods: [...(scopeData?.methods ?? [])],\n notifications: [...(scopeData?.notifications ?? [])],\n accounts: [...(scopeData?.accounts ?? [])],\n },\n ]),\n );\n\n // Group accounts by their chain identifier for efficient lookup\n const accountsByChain = new Map<string, CaipAccountId[]>();\n for (const account of validAccounts) {\n const chainKey = `${account.chain.namespace}:${account.chain.reference}`;\n const accountId: CaipAccountId = `${account.chainId}:${account.address}`;\n\n if (!accountsByChain.has(chainKey)) {\n accountsByChain.set(chainKey, []);\n }\n accountsByChain.get(chainKey)?.push(accountId);\n }\n\n // Add accounts to matching scopes\n for (const [scopeKey, scopeData] of Object.entries(result)) {\n if (!scopeData?.accounts) {\n continue;\n }\n\n try {\n const scope = scopeKey as CaipChainId;\n const scopeDetails = parseCaipChainId(scope);\n const chainKey = `${scopeDetails.namespace}:${scopeDetails.reference}`;\n\n const matchingAccounts = accountsByChain.get(chainKey);\n if (matchingAccounts) {\n const existingAccounts = new Set(scopeData.accounts);\n const newAccounts = matchingAccounts.filter(\n (account) => !existingAccounts.has(account),\n );\n scopeData.accounts.push(...newAccounts);\n }\n } catch (error) {\n console.error(`Invalid scope format: ${scopeKey}`, error);\n }\n }\n\n return result;\n}\n\n// uint32 (two's complement) max\n// more conservative than Number.MAX_SAFE_INTEGER\nconst MAX = 4_294_967_295;\nlet idCounter = Math.floor(Math.random() * MAX);\n\nexport const getUniqueRequestId = (): number => {\n idCounter = (idCounter + 1) % MAX;\n return idCounter;\n};\n","/* eslint-disable @typescript-eslint/naming-convention */\n/* eslint-disable @typescript-eslint/no-unused-vars -- Scope type used in JSDoc */\nimport { getDappId } from '.';\nimport type {\n InvokeMethodOptions,\n MultichainOptions,\n PlatformType,\n Scope,\n StoreClient,\n} from '../../domain';\nimport { getPlatformType, getVersion, TransportType } from '../../domain';\n\n/**\n * Checks if an error represents a user rejection.\n *\n * @param error - The error object to check\n * @returns True if the error indicates a user rejection, false otherwise\n */\nexport function isRejectionError(error: unknown): boolean {\n if (typeof error !== 'object' || error === null) {\n return false;\n }\n\n const errorObj = error as { code?: number; message?: string };\n const errorCode = errorObj.code;\n const errorMessage = errorObj.message?.toLowerCase() ?? '';\n\n return (\n errorCode === 4001 || // User rejected request (common EIP-1193 code)\n errorCode === 4100 || // Unauthorized (common rejection code)\n errorMessage.includes('reject') ||\n errorMessage.includes('denied') ||\n errorMessage.includes('cancel') ||\n errorMessage.includes('user')\n );\n}\n\n/**\n * Gets base analytics properties that are common across all events.\n *\n * @param options - Multichain options containing dapp and analytics config\n * @param storage - Storage client for getting anonymous ID\n * @returns Base analytics properties\n */\nexport async function getBaseAnalyticsProperties(\n options: MultichainOptions,\n storage: StoreClient,\n): Promise<{\n mmconnect_version: string;\n dapp_id: string;\n platform: PlatformType;\n integration_type: string;\n anon_id: string;\n}> {\n const version = getVersion();\n const dappId = getDappId(options.dapp);\n const platform = getPlatformType();\n const anonId = await storage.getAnonId();\n const integrationType =\n (options.analytics as { enabled: true; integrationType: string })\n ?.integrationType ?? TransportType.UNKNOWN;\n\n return {\n mmconnect_version: version,\n dapp_id: dappId,\n platform,\n integration_type: integrationType,\n anon_id: anonId,\n };\n}\n\n/**\n * Gets analytics properties specific to wallet action events.\n *\n * @param options - Multichain options containing dapp and analytics config\n * @param storage - Storage client for getting anonymous ID\n * @param invokeOptions - The invoke method options containing method and scope\n * @returns Wallet action analytics properties\n */\nexport async function getWalletActionAnalyticsProperties(\n options: MultichainOptions,\n storage: StoreClient,\n invokeOptions: InvokeMethodOptions,\n): Promise<{\n mmconnect_version: string;\n dapp_id: string;\n method: string;\n integration_type: string;\n caip_chain_id: string;\n anon_id: string;\n}> {\n const version = getVersion();\n const dappId = getDappId(options.dapp);\n const anonId = await storage.getAnonId();\n const integrationType =\n (options.analytics as { enabled: true; integrationType: string })\n ?.integrationType ?? 'unknown';\n\n return {\n mmconnect_version: version,\n dapp_id: dappId,\n method: invokeOptions.request.method,\n integration_type: integrationType,\n caip_chain_id: invokeOptions.scope,\n anon_id: anonId,\n };\n}\n","/**\n * Returns the version of the Multichain SDK.\n *\n * @returns The version of the Multichain SDK.\n */\nexport function getVersion(): string {\n return '0.0.0';\n}\n\nexport {\n getWalletActionAnalyticsProperties,\n isRejectionError,\n} from '../../multichain/utils/analytics';\n","export * from './errors';\nexport * from './events';\nexport * from './logger';\nexport * from './multichain';\nexport * from './platform';\nexport * from './store';\nexport * from './ui';\nexport * from './utils';\n","/**\n * Formats remaining time in a human-readable format.\n *\n * @param milliseconds - The remaining time in milliseconds.\n * @returns A formatted string representing the remaining time.\n */\nexport function formatRemainingTime(milliseconds: number): string {\n if (milliseconds <= 0) {\n return 'EXPIRED';\n }\n const seconds = Math.floor(milliseconds / 1000);\n return `${seconds}s`;\n}\n\n/**\n * Determines whether to log the countdown at the current remaining seconds.\n *\n * @param remainingSeconds - The remaining seconds until expiration.\n * @returns True if the countdown should be logged, false otherwise.\n */\nexport function shouldLogCountdown(remainingSeconds: number): boolean {\n // Log at specific intervals to avoid spam\n if (remainingSeconds <= 10) {\n // Log every second for the last 10 seconds\n return true;\n } else if (remainingSeconds <= 30) {\n // Log every 5 seconds for the last 30 seconds\n return remainingSeconds % 5 === 0;\n } else if (remainingSeconds <= 60) {\n // Log every 10 seconds for the last minute\n return remainingSeconds % 10 === 0;\n } else if (remainingSeconds <= 300) {\n // Log every 30 seconds for the last 5 minutes\n return remainingSeconds % 30 === 0;\n }\n // Log every minute for longer durations\n return remainingSeconds % 60 === 0;\n}\n","/* eslint-disable @typescript-eslint/explicit-function-return-type -- Getters/setters have inferred types */\n/* eslint-disable require-atomic-updates -- False positive: connectionRequest is reassigned atomically */\n/* eslint-disable @typescript-eslint/no-misused-promises -- setInterval callback is async intentionally */\nimport { formatRemainingTime, shouldLogCountdown } from './utils';\nimport {\n type ConnectionRequest,\n createLogger,\n type InstallWidgetProps,\n Modal,\n type QRLink,\n} from '../../../domain';\n\nconst logger = createLogger('metamask-sdk:ui');\n\nexport abstract class AbstractInstallModal extends Modal<InstallWidgetProps> {\n protected instance?: HTMLMmInstallModalElement | undefined;\n\n #expirationInterval: NodeJS.Timeout | null = null;\n\n #lastLoggedCountdown: number = -1;\n\n abstract renderQRCode(\n link: QRLink,\n connectionRequest: ConnectionRequest,\n ): void;\n\n get link() {\n return this.data;\n }\n\n set link(link: QRLink) {\n this.data = link;\n }\n\n get connectionRequest() {\n return this.options.connectionRequest;\n }\n\n set connectionRequest(connectionRequest: ConnectionRequest) {\n this.options.connectionRequest = connectionRequest;\n }\n\n protected updateLink(link: QRLink) {\n this.link = link;\n if (this.instance) {\n this.instance.link = link;\n }\n }\n\n protected updateExpiresIn(expiresIn: number) {\n if (expiresIn >= 0 && this.instance) {\n this.instance.expiresIn = expiresIn;\n }\n }\n\n protected startExpirationCheck(connectionRequest: ConnectionRequest): void {\n this.stopExpirationCheck();\n\n let currentConnectionRequest: ConnectionRequest = connectionRequest;\n\n this.#expirationInterval = setInterval(async () => {\n const { sessionRequest } = currentConnectionRequest;\n const now = Date.now();\n const remainingMs = sessionRequest.expiresAt - now;\n\n const remainingSeconds = Math.floor(remainingMs / 1000);\n\n if (\n remainingMs > 0 &&\n shouldLogCountdown(remainingSeconds) &&\n this.#lastLoggedCountdown !== remainingSeconds\n ) {\n const formattedTime = formatRemainingTime(remainingMs);\n logger(\n `[UI: InstallModal-nodejs()] QR code expires in: ${formattedTime} (${remainingSeconds}s)`,\n );\n this.#lastLoggedCountdown = remainingSeconds;\n }\n\n if (now >= sessionRequest.expiresAt) {\n this.stopExpirationCheck();\n logger(\n '[UI: InstallModal-nodejs()] ⏰ QR code EXPIRED! Generating new one...',\n );\n try {\n // Generate new session request\n currentConnectionRequest =\n await this.options.createConnectionRequest();\n const generateQRCode = await this.options.generateQRCode(\n currentConnectionRequest,\n );\n this.#lastLoggedCountdown = -1; // Reset countdown logging\n\n // Update local instances with new data\n this.updateLink(generateQRCode);\n this.updateExpiresIn(remainingSeconds);\n\n // Render QRCode on each platform\n this.renderQRCode(generateQRCode, currentConnectionRequest);\n } catch (error) {\n logger(\n `[UI: InstallModal-nodejs()] ❌ Error generating new QR code: ${error}`,\n );\n }\n }\n }, 1000);\n }\n\n protected stopExpirationCheck(): void {\n if (this.#expirationInterval) {\n clearInterval(this.#expirationInterval);\n this.#expirationInterval = null;\n logger(\n '[UI: InstallModal-nodejs()] 🛑 Stopped QR code expiration checking',\n );\n }\n }\n}\n","/* eslint-disable @typescript-eslint/explicit-function-return-type */\n/* eslint-disable no-restricted-syntax */\nimport encodeQR from '@paulmillr/qr';\n\nimport {\n type ConnectionRequest,\n createLogger,\n type QRLink,\n} from '../../../domain';\nimport { AbstractInstallModal } from '../base/AbstractInstallModal';\nimport { formatRemainingTime, shouldLogCountdown } from '../base/utils';\n\nconst logger = createLogger('metamask-sdk:ui');\n\nexport class InstallModal extends AbstractInstallModal {\n private displayQRWithCountdown(qrCodeLink: QRLink, expiresInMs: number) {\n const isExpired = expiresInMs <= 0;\n const formattedTime = formatRemainingTime(expiresInMs);\n const qrCode = encodeQR(qrCodeLink, 'ascii');\n\n // Clear console and display QR code with live countdown\n console.clear();\n console.log(qrCode);\n\n if (isExpired) {\n console.log('EXPIRED - Generating new QR code...');\n } else {\n console.log(`EXPIRES IN: ${formattedTime}`);\n }\n }\n\n renderQRCode(link: QRLink, connectionRequest: ConnectionRequest): void {\n const { sessionRequest } = connectionRequest;\n const expiresIn = sessionRequest.expiresAt - Date.now();\n const expiresInSeconds = Math.floor(expiresIn / 1000);\n const shouldLog = shouldLogCountdown(expiresInSeconds);\n const formattedTime = formatRemainingTime(expiresIn);\n this.startExpirationCheck(connectionRequest);\n\n this.displayQRWithCountdown(link, expiresIn);\n\n if (shouldLog) {\n logger(\n `[UI: InstallModal-nodejs()] QR code expires in: ${formattedTime} (${expiresIn}ms)`,\n );\n }\n }\n\n mount() {\n if (!this.link) {\n throw new Error('Session request is required');\n }\n const { link, connectionRequest } = this;\n this.renderQRCode(link, connectionRequest);\n }\n\n unmount(): void {\n console.clear();\n this.stopExpirationCheck();\n }\n}\n","import { Modal, type OTPCodeWidgetProps } from '../../../domain';\n\nexport abstract class AbstractOTPCodeModal extends Modal<OTPCodeWidgetProps> {\n protected instance?: HTMLMmOtpModalElement | undefined;\n\n get otpCode(): string {\n return this.data;\n }\n\n set otpCode(code: string) {\n this.data = code;\n }\n\n updateOTPCode(code: string): void {\n this.otpCode = code;\n if (this.instance) {\n this.instance.otpCode = code;\n }\n }\n}\n","import { AbstractOTPCodeModal } from '../base/AbstractOTPModal';\n\n/**\n * TODO: This is a placeholder for the OTP code modal.\n * It will be replaced with the actual OTP code modal once it is implemented.\n */\nexport class OTPCodeModal extends AbstractOTPCodeModal {\n mount(): void {\n // No-op: placeholder implementation\n }\n\n unmount(): void {\n // No-op: placeholder implementation\n }\n}\n","export { InstallModal } from './install';\nexport { OTPCodeModal } from './otp';\n","import { StoreAdapter } from '../../domain';\n\nexport class StoreAdapterNode extends StoreAdapter {\n readonly platform = 'node';\n\n readonly #storage = new Map<string, string>();\n\n async get(key: string): Promise<string | null> {\n return this.#storage.get(key) ?? null;\n }\n\n async set(key: string, value: string): Promise<void> {\n this.#storage.set(key, value);\n }\n\n async delete(key: string): Promise<void> {\n this.#storage.delete(key);\n }\n}\n","import type { CreateMultichainFN, StoreClient } from './domain';\nimport { enableDebug } from './domain';\nimport { MetaMaskConnectMultichain } from './multichain';\nimport { Store } from './store';\nimport { ModalFactory } from './ui';\n\nexport * from './domain';\n\nexport const createMultichainClient: CreateMultichainFN = async (options) => {\n if (options.debug) {\n enableDebug('metamask-sdk:*');\n }\n\n const uiModules = await import('./ui/modals/node');\n let storage: StoreClient;\n if (options.storage) {\n storage = options.storage;\n } else {\n const { StoreAdapterNode } = await import('./store/adapters/node');\n const adapter = new StoreAdapterNode();\n storage = new Store(adapter);\n }\n const factory = new ModalFactory(uiModules);\n return MetaMaskConnectMultichain.create({\n ...options,\n storage,\n ui: {\n ...options.ui,\n factory,\n },\n });\n};\n","/* eslint-disable @typescript-eslint/no-misused-promises */\n/* eslint-disable @typescript-eslint/naming-convention */\n/* eslint-disable no-restricted-globals */\n/* eslint-disable promise/always-return -- Event handlers */\n/* eslint-disable no-async-promise-executor -- Async promise executor needed for complex flow */\nimport { analytics } from '@metamask/analytics';\nimport {\n ErrorCode,\n ProtocolError,\n type SessionRequest,\n SessionStore,\n WebSocketTransport,\n} from '@metamask/mobile-wallet-protocol-core';\nimport { DappClient } from '@metamask/mobile-wallet-protocol-dapp-client';\nimport {\n type SessionProperties,\n getMultichainClient,\n type MultichainApiClient,\n type SessionData,\n} from '@metamask/multichain-api-client';\nimport type { CaipAccountId, Json } from '@metamask/utils';\n\nimport {\n METAMASK_CONNECT_BASE_URL,\n METAMASK_DEEPLINK_BASE,\n MWP_RELAY_URL,\n} from '../config';\nimport {\n getVersion,\n type InvokeMethodOptions,\n type MultichainOptions,\n type RPCAPI,\n type Scope,\n type StoreClient,\n TransportType,\n} from '../domain';\nimport {\n getBaseAnalyticsProperties,\n isRejectionError,\n} from './utils/analytics';\nimport {\n createLogger,\n enableDebug,\n isEnabled as isLoggerEnabled,\n} from '../domain/logger';\nimport {\n type ConnectionRequest,\n type ExtendedTransport,\n MultichainCore,\n type ConnectionStatus,\n} from '../domain/multichain';\nimport {\n getPlatformType,\n hasExtension,\n isSecure,\n PlatformType,\n} from '../domain/platform';\nimport { RpcClient } from './rpc/handlers/rpcClient';\nimport { RequestRouter } from './rpc/requestRouter';\nimport { DefaultTransport } from './transports/default';\nimport { MultichainApiClientWrapperTransport } from './transports/multichainApiClientWrapper';\nimport { MWPTransport } from './transports/mwp';\nimport { keymanager } from './transports/mwp/KeyManager';\nimport {\n getDappId,\n getGlobalObject,\n mergeRequestedSessionWithExisting,\n openDeeplink,\n setupDappMetadata,\n} from './utils';\n\nexport { getInfuraRpcUrls } from '../domain/multichain/api/infura';\n\n// ENFORCE NAMESPACE THAT CAN BE DISABLED\nconst logger = createLogger('metamask-sdk:core');\n\nconst SINGLETON_KEY = '__METAMASK_CONNECT_MULTICHAIN_SINGLETON__';\n\nexport class MetaMaskConnectMultichain extends MultichainCore {\n readonly #provider: MultichainApiClient<RPCAPI>;\n\n readonly #providerTransportWrapper: MultichainApiClientWrapperTransport;\n\n #transport: ExtendedTransport | undefined = undefined;\n\n #dappClient: DappClient | undefined = undefined;\n\n #beforeUnloadListener: (() => void) | undefined;\n\n public _status: ConnectionStatus = 'pending';\n\n #listener: (() => void | Promise<void>) | undefined;\n\n get status(): ConnectionStatus {\n return this._status;\n }\n\n set status(value: ConnectionStatus) {\n if (this._status === value) {\n return;\n }\n this._status = value;\n this.options.transport?.onNotification?.({\n method: 'stateChanged',\n params: value,\n });\n }\n\n get provider(): MultichainApiClient<RPCAPI> {\n return this.#provider;\n }\n\n get transport(): ExtendedTransport {\n if (!this.#transport) {\n throw new Error('Transport not initialized, establish connection first');\n }\n return this.#transport;\n }\n\n get dappClient(): DappClient {\n if (!this.#dappClient) {\n throw new Error('DappClient not initialized, establish connection first');\n }\n return this.#dappClient;\n }\n\n get storage(): StoreClient {\n return this.options.storage;\n }\n\n get transportType(): TransportType {\n return this.#transport instanceof MWPTransport\n ? TransportType.MWP\n : TransportType.Browser;\n }\n\n readonly #sdkInfo = `Sdk/Javascript SdkVersion/${getVersion()} Platform/${getPlatformType()} dApp/${this.options.dapp.url ?? this.options.dapp.name} dAppTitle/${this.options.dapp.name}`;\n\n constructor(options: MultichainOptions) {\n const withDappMetadata = setupDappMetadata(options);\n const integrationType = options.analytics?.integrationType ?? 'direct';\n const allOptions = {\n ...withDappMetadata,\n ui: {\n ...withDappMetadata.ui,\n preferExtension: withDappMetadata.ui.preferExtension ?? true,\n showInstallModal: withDappMetadata.ui.showInstallModal ?? false,\n headless: withDappMetadata.ui.headless ?? false,\n },\n analytics: {\n ...(options.analytics ?? {}),\n integrationType,\n },\n };\n\n super(allOptions);\n\n this.#providerTransportWrapper = new MultichainApiClientWrapperTransport(\n this,\n );\n this.#provider = getMultichainClient({\n transport: this.#providerTransportWrapper,\n });\n }\n\n // Creates a singleton instance of MetaMaskConnectMultichain.\n // If the singleton already exists, it merges the incoming options with the\n // existing singleton options for the following keys: `api.supportedNetworks`,\n // `ui.*`, `mobile.*`, `transport.extensionId`, `debug`. Take note that the\n // value for `dapp` is not merged as it does not make sense for subsequent calls to\n // `createMultichainClient` to have a different `dapp` value.\n static async create(\n options: MultichainOptions,\n ): Promise<MetaMaskConnectMultichain> {\n const globalObject = getGlobalObject();\n const existing = globalObject[SINGLETON_KEY] as\n | Promise<MetaMaskConnectMultichain>\n | undefined;\n if (existing) {\n const instance = await existing;\n instance.mergeOptions(options);\n if (options.debug) {\n enableDebug('metamask-sdk:*');\n }\n return instance;\n }\n\n const instancePromise = (async (): Promise<MetaMaskConnectMultichain> => {\n const instance = new MetaMaskConnectMultichain(options);\n const isEnabled = await isLoggerEnabled(\n 'metamask-sdk:core',\n instance.options.storage,\n );\n if (isEnabled) {\n enableDebug('metamask-sdk:core');\n }\n await instance.#init();\n return instance;\n })();\n\n globalObject[SINGLETON_KEY] = instancePromise;\n\n instancePromise.catch((error) => {\n globalObject[SINGLETON_KEY] = undefined;\n console.error('Error initializing MetaMaskConnectMultichain', error);\n });\n\n return instancePromise;\n }\n\n async #setupAnalytics(): Promise<void> {\n const platform = getPlatformType();\n const isBrowser =\n platform === PlatformType.MetaMaskMobileWebview ||\n platform === PlatformType.DesktopWeb ||\n platform === PlatformType.MobileWeb;\n\n const isReactNative = platform === PlatformType.ReactNative;\n\n if (!isBrowser && !isReactNative) {\n return;\n }\n\n const version = getVersion();\n const dappId = getDappId(this.options.dapp);\n const anonId = await this.storage.getAnonId();\n\n const { integrationType } = this.options.analytics ?? {\n integrationType: '',\n };\n analytics.setGlobalProperty('mmconnect_version', version);\n analytics.setGlobalProperty('dapp_id', dappId);\n analytics.setGlobalProperty('anon_id', anonId);\n analytics.setGlobalProperty('platform', platform);\n analytics.setGlobalProperty('integration_type', integrationType);\n analytics.enable();\n }\n\n async #onTransportNotification(payload: any): Promise<void> {\n if (\n typeof payload === 'object' &&\n payload !== null &&\n 'method' in payload\n ) {\n if (payload.method === 'wallet_sessionChanged') {\n const sessionScopes =\n (payload.params as SessionData | undefined)?.sessionScopes ?? {};\n const hasScopes = Object.keys(sessionScopes).length > 0;\n // During passive init, status is already 'loaded' — don't downgrade to 'disconnected'\n // just because the extension has no active session yet.\n if (this.status === 'loaded' && !hasScopes) {\n return;\n }\n this.status = hasScopes ? 'connected' : 'disconnected';\n }\n\n this.emit(payload.method as string, payload.params ?? payload.result);\n }\n }\n\n async #getStoredTransport(): Promise<\n DefaultTransport | MWPTransport | undefined\n > {\n const transportType = await this.storage.getTransport();\n const hasExtensionInstalled = await hasExtension();\n if (transportType) {\n if (transportType === TransportType.Browser) {\n if (hasExtensionInstalled) {\n const apiTransport = new DefaultTransport();\n this.#transport = apiTransport;\n this.#providerTransportWrapper.setupTransportNotificationListener();\n this.#listener = apiTransport.onNotification(\n this.#onTransportNotification.bind(this),\n );\n return apiTransport;\n }\n } else if (transportType === TransportType.MWP) {\n const { adapter: kvstore } = this.options.storage;\n const dappClient = await this.#createDappClient();\n const apiTransport = new MWPTransport(dappClient, kvstore);\n this.#dappClient = dappClient;\n this.#transport = apiTransport;\n this.#providerTransportWrapper.setupTransportNotificationListener();\n this.#listener = apiTransport.onNotification(\n this.#onTransportNotification.bind(this),\n );\n return apiTransport;\n }\n\n await this.storage.removeTransport();\n }\n\n return undefined;\n }\n\n async #setupTransport(): Promise<void> {\n const transport = await this.#getStoredTransport();\n if (transport) {\n if (!this.transport.isConnected()) {\n this.status = 'connecting';\n await this.transport.connect();\n }\n this.status = 'connected';\n if (this.transport instanceof MWPTransport) {\n await this.storage.setTransport(TransportType.MWP);\n } else {\n await this.storage.setTransport(TransportType.Browser);\n }\n } else {\n this.status = 'loaded';\n const hasExtensionInstalled = await hasExtension();\n const preferExtension = this.options.ui.preferExtension ?? true;\n // Setup passive listening for extension wallet_sessionChanged events\n if (hasExtensionInstalled && preferExtension) {\n await this.#setupDefaultTransport({ persist: false });\n // Normally calling DefaultTransport.connect() ensures that the transport is initialized\n // and that wallet_sessionChanged (faked) is emitted. But because we are not\n // calling transport.connect(), we need to initialize DefaultTransport manually.\n try {\n await this.transport.init();\n } catch (error) {\n console.error('Passive init failed:', error);\n }\n }\n }\n }\n\n async #init(): Promise<void> {\n try {\n await this.#setupAnalytics();\n await this.#setupTransport();\n try {\n const baseProps = await getBaseAnalyticsProperties(\n this.options,\n this.storage,\n );\n analytics.track('mmconnect_initialized', baseProps);\n } catch (error) {\n logger('Error tracking initialized event', error);\n }\n } catch (error) {\n await this.storage.removeTransport();\n this.status = 'pending';\n logger('MetaMaskSDK error during initialization', error);\n }\n }\n\n async #createDappClient(): Promise<DappClient> {\n const { adapter: kvstore } = this.options.storage;\n const sessionstore = await SessionStore.create(kvstore);\n const websocket =\n // eslint-disable-next-line no-negated-condition\n typeof window !== 'undefined'\n ? WebSocket\n : (await import('ws')).WebSocket;\n const transport = await WebSocketTransport.create({\n url: MWP_RELAY_URL,\n kvstore,\n websocket,\n });\n const dappClient = new DappClient({ transport, sessionstore, keymanager });\n return dappClient;\n }\n\n async #setupMWP(): Promise<void> {\n if (this.#transport instanceof MWPTransport) {\n return;\n }\n // Only setup MWP if it is not already mwp\n const { adapter: kvstore } = this.options.storage;\n const dappClient = await this.#createDappClient();\n this.#dappClient = dappClient;\n const apiTransport = new MWPTransport(dappClient, kvstore);\n this.#transport = apiTransport;\n this.#providerTransportWrapper.setupTransportNotificationListener();\n this.#listener = this.transport.onNotification(\n this.#onTransportNotification.bind(this),\n );\n await this.storage.setTransport(TransportType.MWP);\n }\n\n async #onBeforeUnload(): Promise<void> {\n // Fixes glitch with \"connecting\" state when modal is still visible and we close screen or refresh\n if (this.options.ui.factory.modal?.isMounted) {\n await this.storage.removeTransport();\n }\n }\n\n #createBeforeUnloadListener(): () => void {\n const handler = this.#onBeforeUnload.bind(this);\n\n if (\n typeof window !== 'undefined' &&\n typeof window.addEventListener !== 'undefined'\n ) {\n window.addEventListener('beforeunload', handler);\n }\n return () => {\n if (\n typeof window !== 'undefined' &&\n typeof window.removeEventListener !== 'undefined'\n ) {\n window.removeEventListener('beforeunload', handler);\n }\n };\n }\n\n async #renderInstallModalAsync(\n desktopPreferred: boolean,\n scopes: Scope[],\n caipAccountIds: CaipAccountId[],\n sessionProperties?: SessionProperties,\n ): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n // Use Connection Modal\n this.options.ui.factory\n .renderInstallModal(\n desktopPreferred,\n async () => {\n if (\n this.dappClient.state === 'CONNECTED' ||\n this.dappClient.state === 'CONNECTING'\n ) {\n await this.dappClient.disconnect();\n }\n return new Promise<ConnectionRequest>((_resolve) => {\n this.dappClient.on(\n 'session_request',\n (sessionRequest: SessionRequest) => {\n _resolve({\n sessionRequest,\n metadata: {\n dapp: this.options.dapp,\n sdk: {\n version: getVersion(),\n platform: getPlatformType(),\n },\n },\n });\n },\n );\n\n (async (): Promise<void> => {\n try {\n await this.transport.connect({\n scopes,\n caipAccountIds,\n sessionProperties,\n });\n await this.options.ui.factory.unload();\n this.options.ui.factory.modal?.unmount();\n this.status = 'connected';\n await this.storage.setTransport(TransportType.MWP);\n } catch (error) {\n if (error instanceof ProtocolError) {\n // Ignore Request expired errors to allow modal to regenerate expired qr codes\n if (error.code !== ErrorCode.REQUEST_EXPIRED) {\n this.status = 'disconnected';\n // Close the modal on error\n await this.options.ui.factory.unload(error);\n reject(error);\n }\n // If request is expires, the QRCode will automatically be regenerated we can ignore this case\n } else {\n this.status = 'disconnected';\n const normalizedError =\n error instanceof Error ? error : new Error(String(error));\n // Close the modal on error\n await this.options.ui.factory.unload(normalizedError);\n reject(normalizedError);\n }\n }\n })().catch(() => {\n // Error already handled in the async function\n });\n });\n },\n async (error?: Error) => {\n if (error) {\n await this.storage.removeTransport();\n reject(error);\n } else {\n await this.storage.setTransport(TransportType.MWP);\n resolve();\n }\n },\n (uri: string) => {\n this.emit('display_uri', uri);\n },\n )\n .catch((error) => {\n reject(error instanceof Error ? error : new Error(String(error)));\n });\n });\n }\n\n async #showInstallModal(\n desktopPreferred: boolean,\n scopes: Scope[],\n caipAccountIds: CaipAccountId[],\n sessionProperties?: SessionProperties,\n ): Promise<void> {\n // create the listener only once to avoid memory leaks\n this.#beforeUnloadListener ??= this.#createBeforeUnloadListener();\n\n // In headless mode, don't render UI but still emit display_uri events\n if (this.options.ui.headless) {\n await this.#headlessConnect(scopes, caipAccountIds, sessionProperties);\n } else {\n await this.#renderInstallModalAsync(\n desktopPreferred,\n scopes,\n caipAccountIds,\n sessionProperties,\n );\n }\n }\n\n /**\n * Handles connection in headless mode without rendering any UI.\n * Emits display_uri events to allow consumers to build custom QR code UI.\n *\n * @param scopes - The requested permission scopes\n * @param caipAccountIds - The requested account IDs\n * @param sessionProperties - Optional session properties\n */\n async #headlessConnect(\n scopes: Scope[],\n caipAccountIds: CaipAccountId[],\n sessionProperties?: SessionProperties,\n ): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (\n this.dappClient.state === 'CONNECTED' ||\n this.dappClient.state === 'CONNECTING'\n ) {\n this.dappClient.disconnect().catch(() => {\n // Ignore disconnect errors\n });\n }\n\n // Listen for session_request to generate and emit the QR code link\n this.dappClient.on(\n 'session_request',\n (sessionRequest: SessionRequest) => {\n const connectionRequest: ConnectionRequest = {\n sessionRequest,\n metadata: {\n dapp: this.options.dapp,\n sdk: {\n version: getVersion(),\n platform: getPlatformType(),\n },\n },\n };\n\n // Generate and emit the QR code link\n const deeplink =\n this.options.ui.factory.createConnectionDeeplink(connectionRequest);\n this.emit('display_uri', deeplink);\n },\n );\n\n // Start the connection\n this.transport\n .connect({ scopes, caipAccountIds, sessionProperties })\n .then(async () => {\n this.status = 'connected';\n await this.storage.setTransport(TransportType.MWP);\n resolve();\n })\n .catch(async (error) => {\n if (error instanceof ProtocolError) {\n // In headless mode, we don't auto-regenerate QR codes\n // since there's no modal to display them\n this.status = 'disconnected';\n await this.storage.removeTransport();\n reject(error);\n } else {\n this.status = 'disconnected';\n await this.storage.removeTransport();\n reject(error instanceof Error ? error : new Error(String(error)));\n }\n });\n });\n }\n\n async #setupDefaultTransport(\n options: { persist?: boolean } = { persist: true },\n ): Promise<DefaultTransport> {\n if (this.#transport instanceof DefaultTransport) {\n return this.#transport;\n }\n\n if (options?.persist) {\n await this.storage.setTransport(TransportType.Browser);\n }\n const transport = new DefaultTransport();\n this.#listener = transport.onNotification(\n this.#onTransportNotification.bind(this),\n );\n this.#transport = transport;\n this.#providerTransportWrapper.setupTransportNotificationListener();\n return transport;\n }\n\n async #deeplinkConnect(\n scopes: Scope[],\n caipAccountIds: CaipAccountId[],\n sessionProperties?: SessionProperties,\n ): Promise<void> {\n return new Promise<void>(async (resolve, reject) => {\n // Handle the response to the initial wallet_createSession request\n const dappClientMessageHandler = (payload: unknown): void => {\n if (\n typeof payload !== 'object' ||\n payload === null ||\n !('data' in payload)\n ) {\n return;\n }\n const data = payload.data as { result?: SessionData; error?: unknown };\n if (typeof data === 'object' && data !== null) {\n // optimistically assume any error is due to the initial wallet_createSession request failure\n if (data.error) {\n this.dappClient.off('message', dappClientMessageHandler);\n reject(data.error as Error);\n }\n // if sessionScopes is set in the result, then this is a response to wallet_createSession\n if (data?.result?.sessionScopes) {\n this.dappClient.off('message', dappClientMessageHandler);\n // unsure if we need to call resolve here like we do above for reject()\n }\n }\n };\n this.dappClient.on('message', dappClientMessageHandler);\n\n let timeout: NodeJS.Timeout | undefined;\n\n if (this.transport.isConnected()) {\n timeout = setTimeout(() => {\n this.openSimpleDeeplinkIfNeeded();\n }, 250);\n } else {\n this.dappClient.once(\n 'session_request',\n (sessionRequest: SessionRequest) => {\n const connectionRequest = {\n sessionRequest,\n metadata: {\n dapp: this.options.dapp,\n sdk: { version: getVersion(), platform: getPlatformType() },\n },\n };\n const deeplink =\n this.options.ui.factory.createConnectionDeeplink(\n connectionRequest,\n );\n const universalLink =\n this.options.ui.factory.createConnectionUniversalLink(\n connectionRequest,\n );\n\n // Emit display_uri event for deeplink connections\n this.emit('display_uri', deeplink);\n\n if (this.options.mobile?.preferredOpenLink) {\n this.options.mobile.preferredOpenLink(deeplink, '_self');\n } else {\n openDeeplink(this.options, deeplink, universalLink);\n }\n },\n );\n }\n\n return this.transport\n .connect({ scopes, caipAccountIds, sessionProperties })\n .then(resolve)\n .catch(async (error) => {\n await this.storage.removeTransport();\n this.dappClient.off('message', dappClientMessageHandler);\n reject(error instanceof Error ? error : new Error(String(error)));\n })\n .finally(() => {\n if (timeout) {\n clearTimeout(timeout);\n }\n });\n });\n }\n\n async #handleConnection(\n promise: Promise<void>,\n scopes: Scope[],\n transportType: TransportType,\n ): Promise<void> {\n this.status = 'connecting';\n return promise\n .then(async () => {\n this.status = 'connected';\n try {\n const baseProps = await getBaseAnalyticsProperties(\n this.options,\n this.storage,\n );\n\n analytics.track('mmconnect_connection_established', {\n ...baseProps,\n transport_type: transportType,\n user_permissioned_chains: scopes,\n });\n } catch (error) {\n logger('Error tracking connection_established event', error);\n }\n return undefined; // explicitly return `undefined` to avoid eslintpromise/always-return\n })\n .catch(async (error) => {\n this.status = 'disconnected';\n try {\n const baseProps = await getBaseAnalyticsProperties(\n this.options,\n this.storage,\n );\n const isRejection = isRejectionError(error);\n\n if (isRejection) {\n analytics.track('mmconnect_connection_rejected', {\n ...baseProps,\n transport_type: transportType,\n });\n } else {\n analytics.track('mmconnect_connection_failed', {\n ...baseProps,\n transport_type: transportType,\n });\n }\n } catch {\n logger('Error tracking connection failed/rejected event', error);\n }\n throw error;\n });\n }\n\n // TODO: make this into param object\n async connect(\n scopes: Scope[],\n caipAccountIds: CaipAccountId[],\n sessionProperties?: SessionProperties,\n forceRequest?: boolean,\n ): Promise<void> {\n if (\n this.status === 'connecting' &&\n this.transportType === TransportType.MWP\n ) {\n await this.#openConnectDeeplinkIfNeeded();\n throw new Error(\n 'Existing connection is pending. Please check your MetaMask Mobile app to continue.',\n );\n }\n const { ui } = this.options;\n const platformType = getPlatformType();\n const isWeb =\n platformType === PlatformType.MetaMaskMobileWebview ||\n platformType === PlatformType.DesktopWeb;\n const { preferExtension = true, showInstallModal = false } = ui;\n const secure = isSecure();\n const hasExtensionInstalled = await hasExtension();\n\n let transportType;\n if (\n platformType === PlatformType.MetaMaskMobileWebview ||\n (isWeb && hasExtensionInstalled && preferExtension)\n ) {\n transportType = TransportType.Browser;\n } else {\n transportType = TransportType.MWP;\n }\n\n try {\n const baseProps = await getBaseAnalyticsProperties(\n this.options,\n this.storage,\n );\n const dappConfiguredChains = Object.keys(\n this.options.api.supportedNetworks,\n );\n\n analytics.track('mmconnect_connection_initiated', {\n ...baseProps,\n transport_type: transportType,\n dapp_configured_chains: dappConfiguredChains,\n dapp_requested_chains: scopes,\n });\n } catch (error) {\n logger('Error tracking connection_initiated event', error);\n }\n\n const sessionData = await this.#getCaipSession();\n\n const { mergedScopes, mergedCaipAccountIds, mergedSessionProperties } =\n mergeRequestedSessionWithExisting(\n sessionData,\n scopes,\n caipAccountIds,\n sessionProperties,\n );\n\n // Needed because empty object will cause wallet_createSession to return an error\n const nonEmptySessionProperties =\n Object.keys(mergedSessionProperties ?? {}).length > 0\n ? mergedSessionProperties\n : undefined;\n\n if (this.#transport?.isConnected() && !secure) {\n return this.#handleConnection(\n this.#transport\n .connect({\n scopes: mergedScopes,\n caipAccountIds: mergedCaipAccountIds,\n sessionProperties: nonEmptySessionProperties,\n forceRequest,\n })\n .then(async () => {\n if (this.#transport instanceof MWPTransport) {\n return this.storage.setTransport(TransportType.MWP);\n }\n return this.storage.setTransport(TransportType.Browser);\n }),\n scopes,\n transportType,\n );\n }\n\n // In MetaMask Mobile In App Browser, window.ethereum is available directly\n if (platformType === PlatformType.MetaMaskMobileWebview) {\n const defaultTransport = await this.#setupDefaultTransport();\n return this.#handleConnection(\n defaultTransport.connect({\n scopes: mergedScopes,\n caipAccountIds: mergedCaipAccountIds,\n sessionProperties: nonEmptySessionProperties,\n forceRequest,\n }),\n scopes,\n transportType,\n );\n }\n\n if (isWeb && hasExtensionInstalled && preferExtension) {\n // If metamask extension is available, connect to it\n const defaultTransport = await this.#setupDefaultTransport();\n // Web transport has no initial payload\n return this.#handleConnection(\n defaultTransport.connect({\n scopes: mergedScopes,\n caipAccountIds: mergedCaipAccountIds,\n sessionProperties: nonEmptySessionProperties,\n forceRequest,\n }),\n scopes,\n transportType,\n );\n }\n\n // Connection will now be InstallModal + QRCodes or Deeplinks, both require mwp\n await this.#setupMWP();\n\n // Determine preferred option for install modal\n const shouldShowInstallModal = hasExtensionInstalled\n ? showInstallModal\n : !preferExtension || showInstallModal;\n\n if (secure && !shouldShowInstallModal) {\n // Desktop is not preferred option, so we use deeplinks (mobile web)\n return this.#handleConnection(\n this.#deeplinkConnect(\n mergedScopes,\n mergedCaipAccountIds,\n nonEmptySessionProperties,\n ),\n scopes,\n transportType,\n );\n }\n\n // Show install modal for RN, Web + Node\n return this.#handleConnection(\n this.#showInstallModal(\n shouldShowInstallModal,\n mergedScopes,\n mergedCaipAccountIds,\n nonEmptySessionProperties,\n ),\n scopes,\n transportType,\n );\n }\n\n public override emit(event: string, args: any): void {\n this.options.transport?.onNotification?.({ method: event, params: args });\n super.emit(event, args);\n }\n\n async #getCaipSession(): Promise<SessionData> {\n let sessionData: SessionData = {\n sessionScopes: {},\n sessionProperties: {},\n };\n if (this.#transport?.isConnected()) {\n try {\n const response = await this.transport.request({\n method: 'wallet_getSession',\n });\n if (response.result) {\n sessionData = response.result as SessionData;\n }\n } catch {\n // If session retrieval fails, return empty session\n }\n }\n return sessionData;\n }\n\n async disconnect(scopes: Scope[] = []): Promise<void> {\n const sessionData = await this.#getCaipSession();\n\n const remainingScopes =\n scopes.length === 0\n ? []\n : Object.keys(sessionData.sessionScopes).filter(\n (scope) => !scopes.includes(scope as Scope),\n );\n\n await this.#transport?.disconnect(scopes);\n\n if (remainingScopes.length === 0) {\n await this.storage.removeTransport();\n\n // We want to leave the DefaultTransport instance connected so that we can\n // still listen for wallet_sessionChanged events.\n if (this.transportType !== TransportType.Browser) {\n await this.#listener?.();\n this.#beforeUnloadListener?.();\n this.#listener = undefined;\n this.#beforeUnloadListener = undefined;\n this.#transport = undefined;\n this.#providerTransportWrapper.clearTransportNotificationListener();\n this.#dappClient = undefined;\n }\n\n this.status = 'disconnected';\n }\n }\n\n async invokeMethod(request: InvokeMethodOptions): Promise<Json> {\n const { transport, options } = this;\n\n const rpcClient = new RpcClient(options, this.#sdkInfo);\n const requestRouter = new RequestRouter(transport, rpcClient, options);\n // TODO: need read only method support for solana\n return requestRouter.invokeMethod(request);\n }\n\n // DRY THIS WITH REQUEST ROUTER\n openSimpleDeeplinkIfNeeded(): void {\n const { ui, mobile } = this.options;\n const { showInstallModal = false } = ui ?? {};\n const secure = isSecure();\n const shouldOpenDeeplink = secure && !showInstallModal;\n\n if (shouldOpenDeeplink) {\n setTimeout(async () => {\n const session = await this.transport.getActiveSession();\n if (!session) {\n throw new Error('No active session found');\n }\n\n const url = `${METAMASK_DEEPLINK_BASE}/mwp?id=${encodeURIComponent(session.id)}`;\n if (mobile?.preferredOpenLink) {\n mobile.preferredOpenLink(url, '_self');\n } else {\n openDeeplink(this.options, url, METAMASK_CONNECT_BASE_URL);\n }\n }, 10); // small delay to ensure the message encryption and dispatch completes\n }\n }\n\n async #openConnectDeeplinkIfNeeded(): Promise<void> {\n const { ui } = this.options;\n const { showInstallModal = false } = ui ?? {};\n const secure = isSecure();\n const shouldOpenDeeplink = secure && !showInstallModal;\n\n if (!shouldOpenDeeplink) {\n return;\n }\n\n const storedSessionRequest =\n await this.#transport?.getStoredPendingSessionRequest();\n if (!storedSessionRequest) {\n return;\n }\n\n const connectionRequest = {\n sessionRequest: storedSessionRequest,\n metadata: {\n dapp: this.options.dapp,\n sdk: { version: getVersion(), platform: getPlatformType() },\n },\n };\n const deeplink =\n this.options.ui.factory.createConnectionDeeplink(connectionRequest);\n\n const universalLink =\n this.options.ui.factory.createConnectionUniversalLink(connectionRequest);\n\n if (this.options.mobile?.preferredOpenLink) {\n this.options.mobile.preferredOpenLink(deeplink, '_self');\n } else {\n openDeeplink(this.options, deeplink, universalLink);\n }\n }\n\n // Provides a way for ecosystem clients (EVM, Solana, etc.) to get the current CAIP session data\n // when instantiating themselves (as they would have already missed any initial sessionChanged events emitted by ConnectMultichain)\n // without having to concern themselves with the current transport connection status.\n async emitSessionChanged(): Promise<void> {\n const emptySession = { sessionScopes: {} };\n\n if (!this.#transport?.isConnected()) {\n // If we aren't connected or connecting, there definitely is no active CAIP session\n // so we optimistically emit an empty session to signify that to the ecosystem client consumers (EVM, Solana, etc.)\n this.emit('wallet_sessionChanged', emptySession);\n return;\n }\n\n // Otherwise, we need to fetch the current CAIP session from the wallet\n const response = await this.transport.request({\n method: 'wallet_getSession',\n });\n\n // And then simulate a sessionChanged event with the current CAIP session data\n this.emit('wallet_sessionChanged', response.result ?? emptySession);\n }\n}\n","export const MWP_RELAY_URL =\n 'wss://mm-sdk-relay.api.cx.metamask.io/connection/websocket';\n\nexport const METAMASK_CONNECT_BASE_URL = 'https://metamask.app.link/connect';\nexport const METAMASK_DEEPLINK_BASE = 'metamask://connect';\n","/* eslint-disable no-restricted-syntax -- Private class properties use established patterns */\n/* eslint-disable @typescript-eslint/explicit-function-return-type -- Inferred types are sufficient */\n/* eslint-disable @typescript-eslint/parameter-properties -- Constructor shorthand is intentional */\n/* eslint-disable @typescript-eslint/no-shadow -- fetch import shadows global */\n\nimport type { Json } from '@metamask/utils';\nimport fetch from 'cross-fetch';\n\nimport {\n RPCHttpErr,\n RPCReadonlyRequestErr,\n RPCReadonlyResponseErr,\n} from '../../../domain';\nimport type {\n RPCResponse,\n RpcUrlsMap,\n Scope,\n InvokeMethodOptions,\n MultichainOptions,\n} from '../../../domain';\n\nlet rpcId = 1;\n\n/**\n * Gets the next RPC ID for request tracking.\n *\n * @returns The next unique RPC ID.\n */\nexport function getNextRpcId(): number {\n rpcId += 1;\n return rpcId;\n}\n\nexport class MissingRpcEndpointErr extends Error {}\n\nexport class RpcClient {\n constructor(\n private readonly config: MultichainOptions,\n private readonly sdkInfo: string,\n ) {}\n\n /**\n * Routes the request to a configured RPC node.\n *\n * @param options - The invoke method options.\n * @returns The JSON response from the RPC node.\n */\n async request(options: InvokeMethodOptions): Promise<Json> {\n const { request } = options;\n const body = JSON.stringify({\n jsonrpc: '2.0',\n method: request.method,\n params: request.params,\n id: getNextRpcId(),\n });\n const rpcEndpoint = this.getRpcEndpoint(options.scope);\n const rpcRequest = await this.fetchWithTimeout(\n rpcEndpoint,\n body,\n 'POST',\n this.getHeaders(rpcEndpoint),\n 30_000,\n ); // 30 seconds default timeout\n const response = await this.parseResponse(rpcRequest);\n return response;\n }\n\n private getRpcEndpoint(scope: Scope) {\n const supportedNetworks: RpcUrlsMap =\n this.config?.api?.supportedNetworks ?? {};\n\n const rpcEndpoint = supportedNetworks[scope];\n if (!rpcEndpoint) {\n throw new MissingRpcEndpointErr(\n `No RPC endpoint found for scope ${scope}`,\n );\n }\n return rpcEndpoint;\n }\n\n private async fetchWithTimeout(\n endpoint: string,\n body: string,\n method: string,\n headers: Record<string, string>,\n timeout: number,\n ): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(endpoint, {\n method,\n headers,\n body,\n signal: controller.signal,\n });\n clearTimeout(timeoutId);\n if (!response.ok) {\n throw new RPCHttpErr(endpoint, method, response.status);\n }\n return response;\n } catch (error) {\n clearTimeout(timeoutId);\n if (error instanceof RPCHttpErr) {\n throw error;\n }\n if (error instanceof Error && error.name === 'AbortError') {\n throw new RPCReadonlyRequestErr(`Request timeout after ${timeout}ms`);\n }\n throw new RPCReadonlyRequestErr(error.message);\n }\n }\n\n private async parseResponse(response: Response) {\n try {\n const rpcResponse = (await response.json()) as RPCResponse;\n return rpcResponse.result as Json;\n } catch (error) {\n throw new RPCReadonlyResponseErr(error.message);\n }\n }\n\n private getHeaders(rpcEndpoint: string) {\n const defaultHeaders = {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n };\n if (rpcEndpoint.includes('infura')) {\n return {\n ...defaultHeaders,\n 'Metamask-Sdk-Info': this.sdkInfo,\n };\n }\n return defaultHeaders;\n }\n}\n","/* eslint-disable no-restricted-syntax -- Private class properties use established patterns */\n/* eslint-disable @typescript-eslint/parameter-properties -- Constructor shorthand is intentional */\n/* eslint-disable jsdoc/require-param-description -- Auto-generated JSDoc */\n/* eslint-disable jsdoc/require-returns -- Auto-generated JSDoc */\n/* eslint-disable @typescript-eslint/no-misused-promises -- setTimeout callback is async intentionally */\nimport { analytics } from '@metamask/analytics';\nimport type { Json } from '@metamask/utils';\n\nimport {\n METAMASK_CONNECT_BASE_URL,\n METAMASK_DEEPLINK_BASE,\n} from '../../config';\nimport {\n type ExtendedTransport,\n type InvokeMethodOptions,\n isSecure,\n type MultichainOptions,\n RPC_HANDLED_METHODS,\n RPCInvokeMethodErr,\n SDK_HANDLED_METHODS,\n} from '../../domain';\nimport { openDeeplink } from '../utils';\nimport {\n getWalletActionAnalyticsProperties,\n isRejectionError,\n} from '../utils/analytics';\nimport type { RpcClient } from './handlers/rpcClient';\nimport { MissingRpcEndpointErr } from './handlers/rpcClient';\n\nlet rpcId = 1;\n\n/**\n * Gets the next RPC ID for request tracking.\n *\n * @returns The next unique RPC ID.\n */\nexport function getNextRpcId(): number {\n rpcId += 1;\n return rpcId;\n}\n\nexport class RequestRouter {\n constructor(\n private readonly transport: ExtendedTransport,\n private readonly rpcClient: RpcClient,\n private readonly config: MultichainOptions,\n ) {}\n\n /**\n * The main entry point for invoking an RPC method.\n * This method acts as a router, determining the correct handling strategy\n * for the request and delegating to the appropriate private handler.\n *\n * @param options\n */\n async invokeMethod(options: InvokeMethodOptions): Promise<Json> {\n const { method } = options.request;\n if (RPC_HANDLED_METHODS.has(method)) {\n return this.handleWithRpcNode(options);\n }\n if (SDK_HANDLED_METHODS.has(method)) {\n return this.handleWithSdkState(options);\n }\n return this.handleWithWallet(options);\n }\n\n /**\n * Forwards the request directly to the wallet via the transport.\n *\n * @param options\n */\n private async handleWithWallet(options: InvokeMethodOptions): Promise<Json> {\n return this.#withAnalyticsTracking(options, async () => {\n const request = this.transport.request({\n method: 'wallet_invokeMethod',\n params: options,\n });\n\n const { ui, mobile } = this.config;\n const { showInstallModal = false } = ui ?? {};\n const secure = isSecure();\n const shouldOpenDeeplink = secure && !showInstallModal;\n\n if (shouldOpenDeeplink) {\n setTimeout(async () => {\n const session = await this.transport.getActiveSession();\n if (!session) {\n throw new Error('No active session found');\n }\n\n const url = `${METAMASK_DEEPLINK_BASE}/mwp?id=${encodeURIComponent(session.id)}`;\n if (mobile?.preferredOpenLink) {\n mobile.preferredOpenLink(url, '_self');\n } else {\n openDeeplink(this.config, url, METAMASK_CONNECT_BASE_URL);\n }\n }, 10); // small delay to ensure the message encryption and dispatch completes\n }\n\n const response = await request;\n if (response.error) {\n const { error } = response;\n throw new RPCInvokeMethodErr(\n `RPC Request failed with code ${error.code}: ${error.message}`,\n );\n }\n\n return response.result as Json;\n });\n }\n\n /**\n * Wraps execution with analytics tracking.\n *\n * @param options - The invoke method options\n * @param execute - The function to execute\n * @returns The result of the execution\n */\n async #withAnalyticsTracking(\n options: InvokeMethodOptions,\n execute: () => Promise<Json>,\n ): Promise<Json> {\n await this.#trackWalletActionRequested(options);\n\n try {\n const result = await execute();\n\n await this.#trackWalletActionSucceeded(options);\n\n return result;\n } catch (error) {\n const isRejection = isRejectionError(error);\n\n if (isRejection) {\n await this.#trackWalletActionRejected(options);\n } else {\n await this.#trackWalletActionFailed(options);\n }\n if (error instanceof RPCInvokeMethodErr) {\n throw error;\n }\n throw new RPCInvokeMethodErr(error.message);\n }\n }\n\n /**\n * Tracks wallet action requested event.\n *\n * @param options\n */\n async #trackWalletActionRequested(\n options: InvokeMethodOptions,\n ): Promise<void> {\n const props = await getWalletActionAnalyticsProperties(\n this.config,\n this.config.storage,\n options,\n );\n analytics.track('mmconnect_wallet_action_requested', props);\n }\n\n /**\n * Tracks wallet action succeeded event.\n *\n * @param options\n */\n async #trackWalletActionSucceeded(\n options: InvokeMethodOptions,\n ): Promise<void> {\n const props = await getWalletActionAnalyticsProperties(\n this.config,\n this.config.storage,\n options,\n );\n analytics.track('mmconnect_wallet_action_succeeded', props);\n }\n\n /**\n * Tracks wallet action failed event.\n *\n * @param options\n */\n async #trackWalletActionFailed(options: InvokeMethodOptions): Promise<void> {\n const props = await getWalletActionAnalyticsProperties(\n this.config,\n this.config.storage,\n options,\n );\n analytics.track('mmconnect_wallet_action_failed', props);\n }\n\n /**\n * Tracks wallet action rejected event.\n *\n * @param options\n */\n async #trackWalletActionRejected(\n options: InvokeMethodOptions,\n ): Promise<void> {\n const props = await getWalletActionAnalyticsProperties(\n this.config,\n this.config.storage,\n options,\n );\n analytics.track('mmconnect_wallet_action_rejected', props);\n }\n\n /**\n * Routes the request to a configured RPC node.\n *\n * @param options\n */\n private async handleWithRpcNode(options: InvokeMethodOptions): Promise<Json> {\n return this.#withAnalyticsTracking(options, async () => {\n try {\n return await this.rpcClient.request(options);\n } catch (error) {\n if (error instanceof MissingRpcEndpointErr) {\n return this.handleWithWallet(options);\n }\n throw error;\n }\n });\n }\n\n /**\n * Responds directly from the SDK's session state.\n *\n * @param options\n */\n private async handleWithSdkState(\n options: InvokeMethodOptions,\n ): Promise<Json> {\n // TODO: to be implemented\n console.warn(\n `Method \"${options.request.method}\" is configured for SDK state handling, but this is not yet implemented. Falling back to wallet passthrough.`,\n );\n // Fallback to wallet\n return this.handleWithWallet(options);\n }\n}\n","import type { Session } from '@metamask/mobile-wallet-protocol-core';\nimport type { SessionRequest } from '@metamask/mobile-wallet-protocol-dapp-client';\nimport {\n type SessionProperties,\n type CreateSessionParams,\n getDefaultTransport,\n type Transport,\n type TransportRequest,\n type TransportResponse,\n} from '@metamask/multichain-api-client';\nimport type { CaipAccountId } from '@metamask/utils';\nimport type { ExtendedTransport, RPCAPI, Scope, SessionData } from 'src/domain';\n\nimport {\n addValidAccounts,\n getOptionalScopes,\n getUniqueRequestId,\n getValidAccounts,\n isSameScopesAndAccounts,\n} from '../../utils';\n\nconst DEFAULT_REQUEST_TIMEOUT = 60 * 1000;\n\ntype PendingRequest = {\n resolve: (value: TransportResponse) => void;\n reject: (error: Error) => void;\n timeout: NodeJS.Timeout;\n};\n\nexport class DefaultTransport implements ExtendedTransport {\n readonly #notificationCallbacks: Set<(data: unknown) => void> = new Set();\n\n readonly #transport: Transport = getDefaultTransport();\n\n readonly #defaultRequestOptions = {\n timeout: DEFAULT_REQUEST_TIMEOUT,\n };\n\n readonly #pendingRequests = new Map<string, PendingRequest>();\n\n #handleResponseListener: ((event: MessageEvent) => void) | undefined;\n\n #handleNotificationListener: ((event: MessageEvent) => void) | undefined;\n\n #notifyCallbacks(data: unknown): void {\n for (const callback of this.#notificationCallbacks) {\n try {\n callback(data);\n } catch (error) {\n console.log(\n '[WindowPostMessageTransport] notifyCallbacks error:',\n error,\n );\n }\n }\n }\n\n #isMetamaskProviderEvent(event: MessageEvent): boolean {\n return (\n event?.data?.data?.name === 'metamask-provider' &&\n // eslint-disable-next-line no-restricted-globals\n event.origin === location.origin\n );\n }\n\n #handleResponse(event: MessageEvent): void {\n if (!this.#isMetamaskProviderEvent(event)) {\n return;\n }\n\n const responseData = event?.data?.data?.data;\n\n // Ignore requests (they have 'method' field) - only process responses\n if (\n typeof responseData === 'object' &&\n responseData !== null &&\n 'method' in responseData\n ) {\n return;\n }\n\n if (\n typeof responseData === 'object' &&\n responseData !== null &&\n 'id' in responseData &&\n ('result' in responseData || 'error' in responseData)\n ) {\n const responseId = String(responseData.id);\n\n const pendingRequest = this.#pendingRequests.get(responseId);\n if (pendingRequest) {\n clearTimeout(pendingRequest.timeout);\n this.#pendingRequests.delete(responseId);\n\n const response = responseData as TransportResponse;\n if ('error' in response && response.error) {\n pendingRequest.reject(\n new Error(response.error.message || 'Request failed'),\n );\n } else {\n pendingRequest.resolve(response);\n }\n }\n }\n }\n\n #handleNotification(event: MessageEvent): void {\n if (!this.#isMetamaskProviderEvent(event)) {\n return;\n }\n\n const responseData = event?.data?.data?.data;\n\n if (\n typeof responseData === 'object' &&\n responseData !== null &&\n (responseData.method === 'metamask_chainChanged' ||\n responseData.method === 'metamask_accountsChanged')\n ) {\n this.#notifyCallbacks(responseData);\n }\n }\n\n #setupMessageListener(): void {\n // Only set up listener if it's not already set up for this instance\n if (this.#handleResponseListener) {\n return;\n }\n\n // Create a new handler bound to this instance\n // Rename this to handleResponse or something like this\n this.#handleResponseListener = this.#handleResponse.bind(this);\n this.#handleNotificationListener = this.#handleNotification.bind(this);\n\n // Add the listener\n // eslint-disable-next-line no-restricted-globals\n window.addEventListener('message', this.#handleResponseListener);\n // eslint-disable-next-line no-restricted-globals\n window.addEventListener('message', this.#handleNotificationListener);\n }\n\n async #init(): Promise<void> {\n this.#setupMessageListener();\n await this.#transport.connect();\n }\n\n async sendEip1193Message<\n TRequest extends TransportRequest,\n TResponse extends TransportResponse,\n >(payload: TRequest, options?: { timeout?: number }): Promise<TResponse> {\n // Setup message listener if not already set up\n this.#setupMessageListener();\n\n // Generate unique request ID - increment counter to ensure uniqueness\n const requestId = String(getUniqueRequestId());\n\n // Create request with ID - MetaMask expects JSON-RPC format\n const request = {\n jsonrpc: '2.0',\n id: requestId,\n ...payload,\n };\n\n return new Promise<TResponse>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.#pendingRequests.delete(requestId);\n reject(new Error('Request timeout'));\n }, options?.timeout ?? this.#defaultRequestOptions.timeout);\n\n this.#pendingRequests.set(requestId, {\n resolve: (response: TransportResponse) => {\n resolve(response as TResponse);\n },\n reject,\n timeout,\n });\n\n // eslint-disable-next-line no-restricted-globals\n window.postMessage(\n {\n target: 'metamask-contentscript',\n data: {\n name: 'metamask-provider',\n data: request,\n },\n },\n // eslint-disable-next-line no-restricted-globals\n location.origin,\n );\n });\n }\n\n async init(): Promise<void> {\n await this.#init();\n let walletSession: SessionData = { sessionScopes: {} };\n try {\n const sessionRequest = await this.request(\n { method: 'wallet_getSession' },\n this.#defaultRequestOptions,\n );\n walletSession = sessionRequest.result as SessionData;\n } catch {\n console.error(\n 'Failed to get wallet session during DefaultTransport init',\n );\n }\n this.#notifyCallbacks({\n method: 'wallet_sessionChanged',\n params: walletSession,\n });\n }\n\n async connect(options?: {\n scopes: Scope[];\n caipAccountIds: CaipAccountId[];\n sessionProperties?: SessionProperties;\n forceRequest?: boolean;\n }): Promise<void> {\n await this.#init();\n\n // Get wallet session\n const sessionRequest = await this.request(\n { method: 'wallet_getSession' },\n this.#defaultRequestOptions,\n );\n if (sessionRequest.error) {\n throw new Error(sessionRequest.error.message);\n }\n let walletSession = sessionRequest.result as SessionData;\n\n const createSessionParams: CreateSessionParams<RPCAPI> = {\n optionalScopes: addValidAccounts(\n getOptionalScopes(options?.scopes ?? []),\n getValidAccounts(options?.caipAccountIds ?? []),\n ),\n sessionProperties: options?.sessionProperties,\n };\n\n if (walletSession && options && !options.forceRequest) {\n const currentScopes = Object.keys(\n walletSession?.sessionScopes ?? {},\n ) as Scope[];\n const proposedScopes = options?.scopes ?? [];\n const proposedCaipAccountIds = options?.caipAccountIds ?? [];\n const hasSameScopesAndAccounts = isSameScopesAndAccounts(\n currentScopes,\n proposedScopes,\n walletSession,\n proposedCaipAccountIds,\n );\n\n if (!hasSameScopesAndAccounts) {\n const response = await this.request(\n { method: 'wallet_createSession', params: createSessionParams },\n this.#defaultRequestOptions,\n );\n if (response.error) {\n throw new Error(response.error.message);\n }\n walletSession = response.result as SessionData;\n }\n } else if (!walletSession || options?.forceRequest) {\n const response = await this.request(\n { method: 'wallet_createSession', params: createSessionParams },\n this.#defaultRequestOptions,\n );\n if (response.error) {\n throw new Error(response.error.message);\n }\n walletSession = response.result as SessionData;\n }\n this.#notifyCallbacks({\n method: 'wallet_sessionChanged',\n params: walletSession,\n });\n }\n\n async disconnect(scopes: Scope[] = []): Promise<void> {\n await this.request({ method: 'wallet_revokeSession', params: { scopes } });\n }\n\n isConnected(): boolean {\n return this.#transport.isConnected();\n }\n\n async request<\n TRequest extends TransportRequest,\n TResponse extends TransportResponse,\n >(\n request: TRequest,\n options: { timeout?: number } = this.#defaultRequestOptions,\n ): Promise<TResponse> {\n return this.#transport.request(request, options);\n }\n\n onNotification(callback: (data: unknown) => void): () => void {\n this.#transport.onNotification(callback);\n this.#notificationCallbacks.add(callback);\n return () => {\n this.#notificationCallbacks.delete(callback);\n };\n }\n\n async getActiveSession(): Promise<Session | undefined> {\n // This code path should never be triggered when the DefaultTransport is being used\n // It's only purpose is for exposing the session ID used for deeplinking to the mobile app\n // and so it is only implemented for the MWPTransport.\n throw new Error(\n 'getActiveSession is purposely not implemented for the DefaultTransport',\n );\n }\n\n async getStoredPendingSessionRequest(): Promise<SessionRequest | null> {\n throw new Error(\n 'getStoredPendingSessionRequest is purposely not implemented for the DefaultTransport',\n );\n }\n}\n","/* eslint-disable no-restricted-syntax -- Private class properties use established patterns */\n/* eslint-disable @typescript-eslint/explicit-function-return-type -- Inferred types are sufficient */\n/* eslint-disable @typescript-eslint/parameter-properties -- Constructor shorthand is intentional */\n\nimport type {\n CreateSessionParams,\n RevokeSessionParams,\n Transport,\n TransportRequest,\n TransportResponse,\n} from '@metamask/multichain-api-client';\nimport { providerErrors } from '@metamask/rpc-errors';\nimport type { CaipAccountId } from '@metamask/utils';\nimport type { InvokeMethodOptions, RPCAPI, Scope } from 'src/domain';\nimport type { MetaMaskConnectMultichain } from 'src/multichain';\n\nimport { getUniqueRequestId } from '../../utils';\n\ntype TransportRequestWithId = TransportRequest & { id: number };\n\nexport class MultichainApiClientWrapperTransport implements Transport {\n readonly #notificationCallbacks = new Set<(data: unknown) => void>();\n\n notificationListener: (() => void) | undefined;\n\n constructor(\n private readonly metamaskConnectMultichain: MetaMaskConnectMultichain,\n ) {}\n\n isTransportDefined(): boolean {\n try {\n return Boolean(this.metamaskConnectMultichain.transport);\n } catch (_error) {\n return false;\n }\n }\n\n clearNotificationCallbacks(): void {\n this.#notificationCallbacks.clear();\n }\n\n notifyCallbacks(data: unknown): void {\n this.#notificationCallbacks.forEach((callback) => {\n callback(data);\n });\n }\n\n clearTransportNotificationListener(): void {\n this.notificationListener?.();\n this.notificationListener = undefined;\n }\n\n setupTransportNotificationListener(): void {\n if (!this.isTransportDefined() || this.notificationListener) {\n return;\n }\n this.notificationListener =\n this.metamaskConnectMultichain.transport.onNotification(\n this.notifyCallbacks.bind(this),\n );\n }\n\n async connect(): Promise<void> {\n console.log('📚 connect');\n await this.metamaskConnectMultichain.emitSessionChanged();\n }\n\n async disconnect(): Promise<void> {\n return Promise.resolve();\n }\n\n isConnected(): boolean {\n return true;\n }\n\n async request<\n ParamsType extends TransportRequest,\n ReturnType extends TransportResponse,\n >(\n params: ParamsType,\n _options: { timeout?: number } = {},\n ): Promise<ReturnType> {\n const id = getUniqueRequestId();\n const requestPayload = {\n id,\n jsonrpc: '2.0',\n ...params,\n };\n\n switch (requestPayload.method) {\n case 'wallet_createSession':\n return this.#walletCreateSession(requestPayload) as Promise<ReturnType>;\n case 'wallet_getSession':\n return this.#walletGetSession(requestPayload) as Promise<ReturnType>;\n case 'wallet_revokeSession':\n return this.#walletRevokeSession(requestPayload) as Promise<ReturnType>;\n case 'wallet_invokeMethod':\n return this.#walletInvokeMethod(requestPayload) as Promise<ReturnType>;\n default:\n throw new Error(`Unsupported method: ${requestPayload.method}`);\n }\n\n throw new Error(`Unknown method: ${requestPayload.method}`);\n }\n\n onNotification(callback: (data: unknown) => void): () => void {\n this.setupTransportNotificationListener();\n this.#notificationCallbacks.add(callback);\n return () => {\n this.#notificationCallbacks.delete(callback);\n };\n }\n\n async #walletCreateSession(request: TransportRequestWithId) {\n const createSessionParams = request.params as CreateSessionParams<RPCAPI>;\n const scopes = Object.keys({\n ...createSessionParams.optionalScopes,\n ...createSessionParams.requiredScopes,\n }) as Scope[];\n const scopeAccounts: CaipAccountId[] = [];\n\n scopes.forEach((scope) => {\n const requiredScope = createSessionParams.requiredScopes?.[scope];\n const optionalScope = createSessionParams.optionalScopes?.[scope];\n if (requiredScope) {\n scopeAccounts.push(...(requiredScope.accounts ?? []));\n }\n\n if (optionalScope) {\n scopeAccounts.push(...(optionalScope.accounts ?? []));\n }\n });\n const accounts = [...new Set(scopeAccounts)];\n\n console.log('📚 SDK connect');\n await this.metamaskConnectMultichain.connect(\n scopes,\n accounts,\n createSessionParams.sessionProperties,\n );\n console.log('📚 SDK connected');\n return this.metamaskConnectMultichain.transport.request({\n method: 'wallet_getSession',\n });\n }\n\n async #walletGetSession(request: TransportRequestWithId) {\n if (!this.isTransportDefined()) {\n return {\n jsonrpc: '2.0',\n id: request.id,\n result: {\n sessionScopes: {},\n },\n };\n }\n return this.metamaskConnectMultichain.transport.request({\n method: 'wallet_getSession',\n });\n }\n\n async #walletRevokeSession(request: TransportRequestWithId) {\n if (!this.isTransportDefined()) {\n return { jsonrpc: '2.0', id: request.id, result: true };\n }\n\n const revokeSessionParams = request.params as\n | RevokeSessionParams<RPCAPI>\n | undefined;\n const scopes = revokeSessionParams?.scopes ?? [];\n\n try {\n await this.metamaskConnectMultichain.disconnect(scopes as Scope[]);\n return { jsonrpc: '2.0', id: request.id, result: true };\n } catch (_error) {\n return { jsonrpc: '2.0', id: request.id, result: false };\n }\n }\n\n async #walletInvokeMethod(request: TransportRequestWithId) {\n if (!this.isTransportDefined()) {\n return { error: providerErrors.unauthorized() };\n }\n const result = this.metamaskConnectMultichain.invokeMethod(\n request.params as InvokeMethodOptions,\n );\n\n return {\n result,\n };\n }\n}\n","/* eslint-disable @typescript-eslint/prefer-promise-reject-errors */\n/* eslint-disable consistent-return */\n/* eslint-disable promise/param-names */\n/* eslint-disable @typescript-eslint/no-misused-promises */\n/* eslint-disable @typescript-eslint/no-shadow */\n/* eslint-disable id-denylist */\n/* eslint-disable @typescript-eslint/no-floating-promises */\n/* eslint-disable no-restricted-globals */\n/* eslint-disable @typescript-eslint/parameter-properties */\n/* eslint-disable @typescript-eslint/explicit-function-return-type */\n/* eslint-disable @typescript-eslint/prefer-readonly */\n/* eslint-disable no-restricted-syntax */\n/* eslint-disable @typescript-eslint/naming-convention */\n/* eslint-disable no-async-promise-executor -- Async promise executor needed for complex flow */\nimport type {\n Session,\n SessionRequest,\n} from '@metamask/mobile-wallet-protocol-core';\nimport { SessionStore } from '@metamask/mobile-wallet-protocol-core';\nimport type { DappClient } from '@metamask/mobile-wallet-protocol-dapp-client';\nimport {\n type SessionProperties,\n type CreateSessionParams,\n type TransportRequest,\n type TransportResponse,\n TransportTimeoutError,\n} from '@metamask/multichain-api-client';\nimport { JsonRpcError, providerErrors, rpcErrors } from '@metamask/rpc-errors';\nimport type { CaipAccountId } from '@metamask/utils';\n\nimport {\n createLogger,\n type ExtendedTransport,\n type RPCAPI,\n type Scope,\n type SessionData,\n type StoreAdapter,\n} from '../../../domain';\nimport {\n addValidAccounts,\n getOptionalScopes,\n getUniqueRequestId,\n getValidAccounts,\n isSameScopesAndAccounts,\n} from '../../utils';\nimport { MULTICHAIN_PROVIDER_STREAM_NAME } from '../constants';\n\nconst DEFAULT_REQUEST_TIMEOUT = 60 * 1000;\nconst CONNECTION_GRACE_PERIOD = 60 * 1000;\nconst DEFAULT_CONNECTION_TIMEOUT =\n DEFAULT_REQUEST_TIMEOUT + CONNECTION_GRACE_PERIOD;\nconst DEFAULT_RESUME_TIMEOUT = 10 * 1000;\nconst SESSION_STORE_KEY = 'cache_wallet_getSession';\nconst ACCOUNTS_STORE_KEY = 'cache_eth_accounts';\nconst CHAIN_STORE_KEY = 'cache_eth_chainId';\nconst PENDING_SESSION_REQUEST_KEY = 'pending_session_request';\n\nconst CACHED_METHOD_LIST = [\n 'wallet_getSession',\n 'wallet_createSession',\n 'wallet_sessionChanged',\n];\nconst CACHED_RESET_METHOD_LIST = [\n 'wallet_revokeSession',\n 'wallet_revokePermissions',\n];\n\ntype PendingRequests = {\n request: { jsonrpc: string; id: string } & TransportRequest;\n method: string;\n resolve: (value: TransportResponse) => void;\n reject: (error: Error) => void;\n timeout: NodeJS.Timeout;\n};\n\nconst logger = createLogger('metamask-sdk:transport');\n\n/**\n * Mobile Wallet Protocol transport implementation\n * Bridges the MWP DappClient with the multichain API client Transport interface\n */\nexport class MWPTransport implements ExtendedTransport {\n private __pendingRequests = new Map<string, PendingRequests>();\n\n private notificationCallbacks = new Set<(data: unknown) => void>();\n\n private currentSessionRequest: SessionRequest | undefined;\n\n private windowFocusHandler: (() => void) | undefined;\n\n get pendingRequests() {\n return this.__pendingRequests;\n }\n\n set pendingRequests(pendingRequests: Map<string, PendingRequests>) {\n this.__pendingRequests = pendingRequests;\n }\n\n get sessionRequest() {\n return this.currentSessionRequest;\n }\n\n constructor(\n private dappClient: DappClient,\n private kvstore: StoreAdapter,\n private options: {\n requestTimeout: number;\n connectionTimeout: number;\n resumeTimeout: number;\n } = {\n requestTimeout: DEFAULT_REQUEST_TIMEOUT,\n connectionTimeout: DEFAULT_CONNECTION_TIMEOUT,\n resumeTimeout: DEFAULT_RESUME_TIMEOUT,\n },\n ) {\n this.dappClient.on('message', this.handleMessage.bind(this));\n // We store the pending session request in the KVStore so that we can:\n // 1. Use it to regenerate the deeplink to re-prompt the user with if they\n // attempt to connect while there is a pending connection attempt.\n // 2. Determine if there was a pending connection attempt when MultichainConnect\n // is initializing itself for the first time on page load and correctly set\n // the appropriate timeout duration for that connection attempt.\n this.dappClient.on('session_request', (sessionRequest: SessionRequest) => {\n this.currentSessionRequest = sessionRequest;\n this.kvstore\n .set(PENDING_SESSION_REQUEST_KEY, JSON.stringify(sessionRequest))\n .catch((err) => {\n logger('Failed to store pending session request', err);\n });\n });\n if (\n typeof window !== 'undefined' &&\n typeof window.addEventListener !== 'undefined'\n ) {\n this.windowFocusHandler = this.onWindowFocus.bind(this);\n window.addEventListener('focus', this.windowFocusHandler);\n }\n }\n\n /**\n * Returns the stored pending session request from the dappClient session_request event, if any.\n *\n * @returns The stored SessionRequest, or null if none or invalid.\n */\n async getStoredPendingSessionRequest(): Promise<SessionRequest | null> {\n try {\n const raw = await this.kvstore.get(PENDING_SESSION_REQUEST_KEY);\n if (!raw) {\n return null;\n }\n return JSON.parse(raw) as SessionRequest;\n } catch {\n return null;\n }\n }\n\n /**\n * Removes the stored pending session request from the KVStore.\n * This is necessary to ensure that ConnectMultichain is able to correctly\n * infer the MWP Transport connection attempt status.\n */\n private async removeStoredPendingSessionRequest(): Promise<void> {\n await this.kvstore.delete(PENDING_SESSION_REQUEST_KEY);\n }\n\n private onWindowFocus(): void {\n if (!this.isConnected()) {\n this.dappClient.reconnect();\n }\n }\n\n private notifyCallbacks(data: unknown): void {\n this.notificationCallbacks.forEach((callback) => callback(data));\n }\n\n private rejectRequest(\n id: string,\n error = new Error('Request rejected'),\n ): void {\n const request = this.pendingRequests.get(id);\n if (request) {\n this.pendingRequests.delete(id);\n clearTimeout(request.timeout);\n request.reject(error);\n }\n }\n\n private parseWalletError(errorPayload: unknown): Error {\n const errorData = errorPayload as Record<string, unknown>;\n\n if (\n typeof errorData.code === 'number' &&\n typeof errorData.message === 'string'\n ) {\n const { code, message } = errorData;\n\n if (code >= 1000 && code <= 4999) {\n return providerErrors.custom({ code, message });\n }\n\n return new JsonRpcError(code, message);\n }\n\n const message =\n errorPayload instanceof Error\n ? errorPayload.message\n : JSON.stringify(errorPayload);\n\n return rpcErrors.internal({ message });\n }\n\n private handleMessage(message: unknown): void {\n if (typeof message === 'object' && message !== null) {\n if ('data' in message) {\n const messagePayload = message.data as Record<string, unknown>;\n\n if ('id' in messagePayload && typeof messagePayload.id === 'string') {\n const request = this.pendingRequests.get(messagePayload.id);\n\n if (request) {\n clearTimeout(request.timeout);\n\n // Check if the message contains an error (e.g., user rejected)\n if ('error' in messagePayload && messagePayload.error) {\n this.pendingRequests.delete(messagePayload.id);\n request.reject(this.parseWalletError(messagePayload.error));\n return;\n }\n\n // Success case - resolve the promise\n const requestWithName = {\n ...messagePayload,\n method:\n request.method === 'wallet_getSession' ||\n request.method === 'wallet_createSession'\n ? 'wallet_sessionChanged'\n : request.method,\n } as unknown as {\n jsonrpc: string;\n id: string;\n } & TransportResponse;\n\n const notification = {\n ...messagePayload,\n method:\n request.method === 'wallet_getSession' ||\n request.method === 'wallet_createSession'\n ? 'wallet_sessionChanged'\n : request.method,\n params: requestWithName.result,\n };\n\n this.notifyCallbacks(notification);\n request.resolve(requestWithName);\n this.pendingRequests.delete(messagePayload.id);\n }\n } else {\n if (\n (message.data as { method: string }).method ===\n 'metamask_chainChanged'\n ) {\n this.kvstore.set(\n CHAIN_STORE_KEY,\n JSON.stringify(\n (message.data as { params: { chainId: number } }).params\n .chainId,\n ),\n );\n }\n\n if (\n (message.data as { method: string }).method ===\n 'metamask_accountsChanged'\n ) {\n this.kvstore.set(\n ACCOUNTS_STORE_KEY,\n JSON.stringify(\n (message.data as { params: { accounts: string[] } }).params,\n ),\n );\n }\n\n // Ensure session changes are always persisted to the store\n if (\n (message.data as { method: string }).method ===\n 'wallet_sessionChanged'\n ) {\n const notification = message.data as {\n method: string;\n params: SessionData;\n };\n\n const response = {\n result: notification.params,\n };\n\n this.kvstore.set(SESSION_STORE_KEY, JSON.stringify(response));\n }\n\n this.notifyCallbacks(message.data);\n }\n }\n }\n }\n\n private async onResumeSuccess(\n resumeResolve: () => void,\n resumeReject: (err: Error) => void,\n options?: { scopes: Scope[]; caipAccountIds: CaipAccountId[] },\n ): Promise<void> {\n try {\n await this.waitForWalletSessionIfNotCached();\n const sessionRequest = await this.request({\n method: 'wallet_getSession',\n });\n // TODO: verify if this branching logic can ever be hit\n if (sessionRequest.error) {\n return resumeReject(new Error(sessionRequest.error.message));\n }\n let walletSession = sessionRequest.result as SessionData;\n if (walletSession && options) {\n const currentScopes = Object.keys(\n walletSession?.sessionScopes ?? {},\n ) as Scope[];\n const proposedScopes = options?.scopes ?? [];\n const proposedCaipAccountIds = options?.caipAccountIds ?? [];\n const hasSameScopesAndAccounts = isSameScopesAndAccounts(\n currentScopes,\n proposedScopes,\n walletSession,\n proposedCaipAccountIds,\n );\n if (!hasSameScopesAndAccounts) {\n const optionalScopes = addValidAccounts(\n getOptionalScopes(options?.scopes ?? []),\n getValidAccounts(options?.caipAccountIds ?? []),\n );\n const sessionRequest: CreateSessionParams<RPCAPI> = {\n optionalScopes,\n };\n const response = await this.request({\n method: 'wallet_createSession',\n params: sessionRequest,\n });\n if (response.error) {\n return resumeReject(new Error(response.error.message));\n }\n // TODO: Maybe find a better way to revoke sessions on wallet without triggering an empty notification\n // Issue of this is it will send a session update event with an empty session and right after we may get the session recovered\n // await this.request({ method: 'wallet_revokeSession', params: walletSession });\n walletSession = response.result as SessionData;\n }\n } else if (!walletSession) {\n // TODO: verify if this branching logic can ever be hit\n const optionalScopes = addValidAccounts(\n getOptionalScopes(options?.scopes ?? []),\n getValidAccounts(options?.caipAccountIds ?? []),\n );\n const sessionRequest: CreateSessionParams<RPCAPI> = { optionalScopes };\n const response = await this.request({\n method: 'wallet_createSession',\n params: sessionRequest,\n });\n if (response.error) {\n return resumeReject(new Error(response.error.message));\n }\n walletSession = response.result as SessionData;\n }\n await this.removeStoredPendingSessionRequest();\n this.notifyCallbacks({\n method: 'wallet_sessionChanged',\n params: walletSession,\n });\n return resumeResolve();\n } catch (err) {\n return resumeReject(err as Error);\n }\n }\n\n async init(): Promise<void> {\n // no-op for MWP — passive init is only relevant for DefaultTransport\n }\n\n // TODO: Rename this\n async sendEip1193Message<\n TRequest extends TransportRequest,\n TResponse extends TransportResponse,\n >(payload: TRequest, options?: { timeout?: number }): Promise<TResponse> {\n const request = {\n jsonrpc: '2.0',\n id: String(getUniqueRequestId()),\n ...payload,\n };\n\n const cachedWalletSession = await this.getCachedResponse(request);\n if (cachedWalletSession) {\n this.notifyCallbacks(cachedWalletSession);\n return cachedWalletSession as TResponse;\n }\n\n return new Promise<TResponse>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.rejectRequest(request.id, new TransportTimeoutError());\n }, options?.timeout ?? this.options.requestTimeout);\n\n this.pendingRequests.set(request.id, {\n request,\n method: request.method,\n resolve: async (response: TransportResponse) => {\n await this.storeWalletSession(request, response);\n return resolve(response as TResponse);\n },\n reject,\n timeout,\n });\n\n this.dappClient\n .sendRequest({\n name: 'metamask-provider',\n data: request,\n })\n .catch(reject);\n });\n }\n\n async connect(options?: {\n scopes: Scope[];\n caipAccountIds: CaipAccountId[];\n sessionProperties?: SessionProperties;\n }): Promise<void> {\n const { dappClient } = this;\n\n const session = await this.getActiveSession();\n if (session) {\n logger('active session found', {\n id: session.id,\n channel: session.channel,\n expiresAt: session.expiresAt,\n });\n }\n\n const storedSessionRequestBeforeConnectionAttempt =\n await this.getStoredPendingSessionRequest();\n\n let timeout: NodeJS.Timeout;\n let initialConnectionMessageHandler:\n | ((message: unknown) => Promise<void>)\n | undefined;\n const connectionPromise = new Promise<void>(async (resolve, reject) => {\n let connection: Promise<void>;\n if (session) {\n connection = new Promise<void>((resumeResolve, resumeReject) => {\n if (this.dappClient.state === 'CONNECTED') {\n this.onResumeSuccess(resumeResolve, resumeReject, options);\n } else {\n this.dappClient.once('connected', async () => {\n this.onResumeSuccess(resumeResolve, resumeReject, options);\n });\n dappClient.resume(session?.id ?? '');\n }\n });\n } else {\n connection = new Promise<void>(\n (resolveConnection, rejectConnection) => {\n const optionalScopes = addValidAccounts(\n getOptionalScopes(options?.scopes ?? []),\n getValidAccounts(options?.caipAccountIds ?? []),\n );\n const sessionRequest: CreateSessionParams<RPCAPI> = {\n optionalScopes,\n sessionProperties: options?.sessionProperties,\n };\n const request = {\n jsonrpc: '2.0',\n id: String(getUniqueRequestId()),\n method: 'wallet_createSession',\n params: sessionRequest,\n };\n\n // Handler for initial connection messages - checks for error responses\n // and properly rejects the connection promise with EIP-1193 error codes\n initialConnectionMessageHandler = async (\n message: unknown,\n ): Promise<void> => {\n if (typeof message !== 'object' || message === null) {\n return;\n }\n if (!('data' in message)) {\n return;\n }\n\n const messagePayload = message.data as Record<string, unknown>;\n\n // Match by ID (preferred) or by method (backward compatibility for notifications without ID)\n const isMatchingId = messagePayload.id === request.id;\n const isMatchingMethod =\n messagePayload.method === 'wallet_createSession' ||\n messagePayload.method === 'wallet_sessionChanged';\n\n if (!isMatchingId && !isMatchingMethod) {\n return;\n }\n\n // Handle error response (e.g., user rejected the connection)\n if (messagePayload.error) {\n return rejectConnection(\n this.parseWalletError(messagePayload.error),\n );\n }\n\n // Success case - store session, notify, and resolve\n await this.storeWalletSession(\n request,\n messagePayload as TransportResponse,\n );\n await this.removeStoredPendingSessionRequest();\n this.notifyCallbacks(messagePayload);\n return resolveConnection();\n };\n\n this.dappClient.on('message', initialConnectionMessageHandler);\n\n dappClient\n .connect({\n mode: 'trusted',\n initialPayload: {\n name: MULTICHAIN_PROVIDER_STREAM_NAME,\n data: request,\n },\n })\n .catch((error) => {\n if (initialConnectionMessageHandler) {\n this.dappClient.off(\n 'message',\n initialConnectionMessageHandler,\n );\n }\n rejectConnection(error);\n });\n },\n );\n }\n\n timeout = setTimeout(\n () => {\n reject(new TransportTimeoutError());\n },\n storedSessionRequestBeforeConnectionAttempt\n ? this.options.resumeTimeout\n : this.options.connectionTimeout,\n );\n\n connection.then(resolve).catch(reject);\n });\n\n return connectionPromise\n .catch(async (error) => {\n // Clean up the MWP session from the KVStore so stale sessions\n // don't cause subsequent connect attempts to enter the resume path\n await this.dappClient.disconnect();\n throw error;\n })\n .finally(() => {\n if (timeout) {\n clearTimeout(timeout);\n }\n if (initialConnectionMessageHandler) {\n this.dappClient.off('message', initialConnectionMessageHandler);\n initialConnectionMessageHandler = undefined;\n }\n this.removeStoredPendingSessionRequest();\n });\n }\n\n /**\n * Disconnects from the Mobile Wallet Protocol\n *\n * @param [scopes] - The scopes to revoke. If not provided or empty, all scopes will be revoked.\n * @returns Nothing\n */\n async disconnect(scopes: Scope[] = []): Promise<void> {\n const cachedSession = await this.getCachedResponse({\n jsonrpc: '2.0',\n id: '0',\n method: 'wallet_getSession',\n });\n const cachedSessionScopes =\n (cachedSession?.result as SessionData | undefined)?.sessionScopes ?? {};\n\n const remainingScopes =\n scopes.length === 0\n ? []\n : Object.keys(cachedSessionScopes).filter(\n (scope) => !scopes.includes(scope as Scope),\n );\n\n const newSessionScopes = Object.fromEntries(\n Object.entries(cachedSessionScopes).filter(([key]) =>\n remainingScopes.includes(key),\n ),\n );\n\n // NOTE: Purposely not awaiting this to avoid blocking the disconnect flow.\n // This might not actually get executed on the wallet if the user doesn't open\n // their wallet before the message TTL or if the underlying transport isn't actually connected\n this.request({ method: 'wallet_revokeSession', params: { scopes } }).catch(\n (err) => {\n console.error('error revoking session', err);\n },\n );\n\n // Clear the cached values for eth_accounts and eth_chainId if all eip155 scopes were removed.\n const remainingScopesIncludeEip155 = remainingScopes.some((scope) =>\n scope.includes('eip155'),\n );\n if (!remainingScopesIncludeEip155) {\n this.kvstore.delete(ACCOUNTS_STORE_KEY);\n this.kvstore.delete(CHAIN_STORE_KEY);\n }\n\n if (remainingScopes.length > 0) {\n this.kvstore.set(\n SESSION_STORE_KEY,\n JSON.stringify({\n result: {\n sessionScopes: newSessionScopes,\n },\n }),\n );\n } else {\n this.kvstore.delete(SESSION_STORE_KEY);\n\n // Clean up window focus event listener\n if (\n typeof window !== 'undefined' &&\n typeof window.removeEventListener !== 'undefined' &&\n this.windowFocusHandler\n ) {\n window.removeEventListener('focus', this.windowFocusHandler);\n this.windowFocusHandler = undefined;\n }\n\n await this.dappClient.disconnect();\n }\n\n this.notifyCallbacks({\n method: 'wallet_sessionChanged',\n params: {\n sessionScopes: newSessionScopes,\n },\n });\n }\n\n /**\n * Checks if the transport is connected\n *\n * @returns True if transport is connected, false otherwise\n */\n isConnected(): boolean {\n // biome-ignore lint/suspicious/noExplicitAny: required if state is not made public in dappClient\n return (this.dappClient as any).state === 'CONNECTED';\n }\n\n /**\n * Attempts to re-establish a connection via DappClient\n *\n * @returns Nothing\n */\n // TODO: We should re-evaluate adding this to the WebSocketTransport layer from `@metamask/mobile-wallet-protocol-core`\n // ticket: https://consensyssoftware.atlassian.net/browse/WAPI-862\n private async attemptResumeSession(): Promise<void> {\n try {\n await this.dappClient.reconnect();\n // Wait for connection to be established\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error('Resume timeout'));\n }, 2_000);\n\n if (this.isConnected()) {\n clearTimeout(timeout);\n resolve();\n } else {\n this.dappClient.once('connected', () => {\n clearTimeout(timeout);\n resolve();\n });\n }\n });\n } catch (error) {\n return Promise.reject(\n new Error(`Failed to resume session: ${error.message}`),\n );\n }\n }\n\n private async getCachedResponse(\n request: { jsonrpc: string; id: string } & TransportRequest,\n ): Promise<TransportResponse | undefined> {\n if (request.method === 'wallet_getSession') {\n const walletGetSession = await this.kvstore.get(SESSION_STORE_KEY);\n if (walletGetSession) {\n const walletSession = JSON.parse(walletGetSession);\n return {\n id: request.id,\n jsonrpc: '2.0',\n result: walletSession.params ?? walletSession.result, // \"what?... why walletSession.params?..\"\n method: request.method,\n } as unknown as TransportResponse;\n }\n } else if (request.method === 'eth_accounts') {\n const ethAccounts = await this.kvstore.get(ACCOUNTS_STORE_KEY);\n if (ethAccounts) {\n return {\n id: request.id,\n jsonrpc: '2.0',\n result: JSON.parse(ethAccounts),\n method: request.method,\n } as unknown as TransportResponse;\n }\n } else if (request.method === 'eth_chainId') {\n const ethChainId = await this.kvstore.get(CHAIN_STORE_KEY);\n if (ethChainId) {\n return {\n id: request.id,\n jsonrpc: '2.0',\n result: JSON.parse(ethChainId),\n method: request.method,\n } as unknown as TransportResponse;\n }\n }\n }\n\n private async storeWalletSession(\n request: TransportRequest,\n response: TransportResponse,\n ): Promise<void> {\n if (response.error) {\n return;\n }\n if (CACHED_METHOD_LIST.includes(request.method)) {\n await this.kvstore.set(SESSION_STORE_KEY, JSON.stringify(response));\n } else if (request.method === 'eth_accounts') {\n await this.kvstore.set(\n ACCOUNTS_STORE_KEY,\n JSON.stringify(response.result),\n );\n } else if (request.method === 'eth_chainId') {\n await this.kvstore.set(CHAIN_STORE_KEY, JSON.stringify(response.result));\n } else if (CACHED_RESET_METHOD_LIST.includes(request.method)) {\n await this.kvstore.delete(SESSION_STORE_KEY);\n await this.kvstore.delete(ACCOUNTS_STORE_KEY);\n await this.kvstore.delete(CHAIN_STORE_KEY);\n }\n }\n\n async request<\n TRequest extends TransportRequest,\n TResponse extends TransportResponse,\n >(payload: TRequest, options?: { timeout?: number }): Promise<TResponse> {\n const request = {\n jsonrpc: '2.0',\n id: String(getUniqueRequestId()),\n ...payload,\n };\n\n const cachedWalletSession = await this.getCachedResponse(request);\n if (cachedWalletSession) {\n this.notifyCallbacks(cachedWalletSession);\n return cachedWalletSession as TResponse;\n }\n\n if (!this.isConnected()) {\n await this.attemptResumeSession();\n }\n\n return new Promise<TResponse>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.rejectRequest(request.id, new TransportTimeoutError());\n }, options?.timeout ?? this.options.requestTimeout);\n\n this.pendingRequests.set(request.id, {\n request,\n method: request.method,\n resolve: async (response: TransportResponse) => {\n await this.storeWalletSession(request, response);\n return resolve(response as TResponse);\n },\n reject,\n timeout,\n });\n\n this.dappClient\n .sendRequest({\n name: MULTICHAIN_PROVIDER_STREAM_NAME,\n data: request,\n })\n .catch(reject);\n });\n }\n\n onNotification(callback: (data: unknown) => void): () => void {\n this.notificationCallbacks.add(callback);\n return () => {\n this.notificationCallbacks.delete(callback);\n };\n }\n\n async getActiveSession(): Promise<Session | undefined> {\n const { kvstore } = this;\n const sessionStore = await SessionStore.create(kvstore);\n\n try {\n const [activeSession] = await sessionStore.list();\n return activeSession;\n } catch (error) {\n // TODO: verify if this try catch is necessary\n logger('error getting active session', error);\n return undefined;\n }\n }\n\n // This method checks if an existing CAIP session response is cached or waits for one\n // to be received from the wallet if not cached. This is necessary because there is an edge\n // case during the initial connection flow where after the user has accepted the permission approval\n // and returned back to the dapp from the wallet, the dapp page may have gotten unloaded and refreshed.\n // When it is unloaded and refreshed, it will try to resume the session by making a request for wallet_getSession\n // which should resolve from cache, but because a race condition makes it possible for the response from the wallet\n // for the initial wallet_createSession connection request to not have been handled and cached yet. This results\n // in the wallet_getSession request never resolving unless we wait for it explicitly as done in this method.\n private async waitForWalletSessionIfNotCached() {\n const cachedWalletGetSessionResponse =\n await this.kvstore.get(SESSION_STORE_KEY);\n if (cachedWalletGetSessionResponse) {\n return;\n }\n let unsubscribe: () => void;\n const responsePromise = new Promise<void>((resolve) => {\n unsubscribe = this.onNotification((message) => {\n if (typeof message === 'object' && message !== null) {\n if ('data' in message) {\n const messagePayload = message.data as Record<string, unknown>;\n if (\n messagePayload.method === 'wallet_getSession' ||\n messagePayload.method === 'wallet_sessionChanged'\n ) {\n unsubscribe();\n resolve();\n }\n }\n }\n });\n });\n\n const timeoutPromise = new Promise<void>((_resolve, reject) => {\n setTimeout(() => {\n unsubscribe();\n this.removeStoredPendingSessionRequest();\n reject(new TransportTimeoutError());\n }, this.options.resumeTimeout);\n });\n\n return Promise.race([responsePromise, timeoutPromise]);\n }\n}\n","export const EIP_1193_PROVIDER_STREAM_NAME = 'metamask-provider';\nexport const MULTICHAIN_PROVIDER_STREAM_NAME = 'metamask-multichain-provider';\n","/* eslint-disable no-restricted-globals -- Buffer is polyfilled for browser/RN environments */\n/* eslint-disable @typescript-eslint/await-thenable -- decrypt returns Promise in some implementations */\nimport type {\n IKeyManager,\n KeyPair,\n} from '@metamask/mobile-wallet-protocol-core';\nimport { decrypt, encrypt, PrivateKey, PublicKey } from 'eciesjs';\n\nclass KeyManager implements IKeyManager {\n generateKeyPair(): KeyPair {\n const privateKey = new PrivateKey();\n return {\n privateKey: new Uint8Array(privateKey.secret),\n publicKey: privateKey.publicKey.toBytes(true),\n };\n }\n\n async encrypt(\n plaintext: string,\n theirPublicKey: Uint8Array,\n ): Promise<string> {\n const plaintextBuffer = Buffer.from(plaintext, 'utf8');\n const encryptedBuffer = encrypt(theirPublicKey, plaintextBuffer);\n return encryptedBuffer.toString('base64');\n }\n\n async decrypt(\n encryptedB64: string,\n myPrivateKey: Uint8Array,\n ): Promise<string> {\n const encryptedBuffer = Buffer.from(encryptedB64, 'base64');\n const decryptedBuffer = await decrypt(myPrivateKey, encryptedBuffer);\n return Buffer.from(decryptedBuffer).toString('utf8');\n }\n\n validatePeerKey(key: Uint8Array): void {\n PublicKey.fromHex(Buffer.from(key).toString('hex'));\n }\n}\n\nexport const keymanager = new KeyManager();\n","/* eslint-disable id-denylist -- 'err' is a common pattern for catch clauses */\n/* eslint-disable @typescript-eslint/parameter-properties -- Constructor shorthand */\nimport * as uuid from 'uuid';\n\nimport type { StoreAdapter, TransportType } from '../domain';\nimport {\n StorageDeleteErr,\n StorageGetErr,\n StorageSetErr,\n} from '../domain/errors/storage';\nimport { getTransportType } from '../domain/multichain';\nimport { StoreClient } from '../domain/store/client';\n\nexport class Store extends StoreClient {\n constructor(public adapter: StoreAdapter) {\n super();\n }\n\n async getTransport(): Promise<TransportType | null> {\n try {\n const transport = await this.adapter.get('multichain-transport');\n if (!transport) {\n return null;\n }\n return getTransportType(transport);\n } catch (err) {\n throw new StorageGetErr(\n this.adapter.platform,\n 'multichain-transport',\n err.message,\n );\n }\n }\n\n async setTransport(transport: TransportType): Promise<void> {\n try {\n await this.adapter.set('multichain-transport', transport);\n } catch (err) {\n throw new StorageSetErr(\n this.adapter.platform,\n 'multichain-transport',\n err.message,\n );\n }\n }\n\n async removeTransport(): Promise<void> {\n try {\n await this.adapter.delete('multichain-transport');\n } catch (err) {\n throw new StorageDeleteErr(\n this.adapter.platform,\n 'multichain-transport',\n err.message,\n );\n }\n }\n\n async getAnonId(): Promise<string> {\n try {\n const anonId = await this.adapter.get('anonId');\n if (anonId) {\n return anonId;\n }\n const newAnonId = uuid.v4();\n await this.adapter.set('anonId', newAnonId);\n return newAnonId;\n } catch (err) {\n throw new StorageGetErr(this.adapter.platform, 'anonId', err.message);\n }\n }\n\n async getExtensionId(): Promise<string | null> {\n try {\n return await this.adapter.get('extensionId');\n } catch (err) {\n throw new StorageGetErr(\n this.adapter.platform,\n 'extensionId',\n err.message,\n );\n }\n }\n\n async setAnonId(anonId: string): Promise<void> {\n try {\n return await this.adapter.set('anonId', anonId);\n } catch (err) {\n throw new StorageSetErr(this.adapter.platform, 'anonId', err.message);\n }\n }\n\n async setExtensionId(extensionId: string): Promise<void> {\n try {\n return await this.adapter.set('extensionId', extensionId);\n } catch (err) {\n throw new StorageSetErr(\n this.adapter.platform,\n 'extensionId',\n err.message,\n );\n }\n }\n\n async removeExtensionId(): Promise<void> {\n try {\n return await this.adapter.delete('extensionId');\n } catch (err) {\n throw new StorageDeleteErr(\n this.adapter.platform,\n 'extensionId',\n err.message,\n );\n }\n }\n\n async removeAnonId(): Promise<void> {\n try {\n return await this.adapter.delete('anonId');\n } catch (err) {\n throw new StorageDeleteErr(this.adapter.platform, 'anonId', err.message);\n }\n }\n\n async getDebug(): Promise<string | null> {\n try {\n return await this.adapter.get('DEBUG');\n } catch (err) {\n throw new StorageGetErr(this.adapter.platform, 'DEBUG', err.message);\n }\n }\n}\n","/* eslint-disable @typescript-eslint/parameter-properties */\nimport { BaseErr } from './base';\nimport type { StorageErrorCodes } from './types';\n\nexport class StorageGetErr extends BaseErr<'Storage', StorageErrorCodes> {\n static readonly code = 60;\n\n constructor(\n public readonly platform: 'web' | 'rn' | 'node',\n public readonly key: string,\n public readonly reason: string,\n ) {\n super(\n `StorageErr${StorageGetErr.code}: ${platform} storage get error in key: ${key} - ${reason}`,\n StorageGetErr.code,\n );\n }\n}\n\nexport class StorageSetErr extends BaseErr<'Storage', StorageErrorCodes> {\n static readonly code = 61;\n\n constructor(\n public readonly platform: 'web' | 'rn' | 'node',\n public readonly key: string,\n public readonly reason: string,\n ) {\n super(\n `StorageErr${StorageSetErr.code}: ${platform} storage set error in key: ${key} - ${reason}`,\n StorageSetErr.code,\n );\n }\n}\n\nexport class StorageDeleteErr extends BaseErr<'Storage', StorageErrorCodes> {\n static readonly code = 62;\n\n constructor(\n public readonly platform: 'web' | 'rn' | 'node',\n public readonly key: string,\n public readonly reason: string,\n ) {\n super(\n `StorageErr${StorageDeleteErr.code}: ${platform} storage delete error in key: ${key} - ${reason}`,\n StorageDeleteErr.code,\n );\n }\n}\n","/* eslint-disable @typescript-eslint/no-shadow */\n\n/* eslint-disable no-restricted-globals */\n/* eslint-disable jsdoc/require-returns */\n/* eslint-disable @typescript-eslint/parameter-properties */\n/* eslint-disable @typescript-eslint/explicit-function-return-type */\n/* eslint-disable no-restricted-syntax */\n\n/* eslint-disable @typescript-eslint/naming-convention */\nimport MetaMaskOnboarding from '@metamask/onboarding';\n\nimport { METAMASK_CONNECT_BASE_URL, METAMASK_DEEPLINK_BASE } from '../config';\nimport {\n type ConnectionRequest,\n getPlatformType,\n getVersion,\n type Modal,\n type OTPCode,\n PlatformType,\n} from '../domain';\nimport type { AbstractOTPCodeModal } from './modals/base/AbstractOTPModal';\nimport type { FactoryModals, ModalTypes } from './modals/types';\nimport { compressString } from '../multichain/utils';\n\n/**\n * Preload function type for loading UI dependencies\n */\nexport type PreloadFn = () => Promise<void>;\n\n/**\n * Base ModalFactory class that accepts a preload function.\n * Platform-specific implementations should extend this class.\n */\nexport abstract class BaseModalFactory<\n T extends FactoryModals = FactoryModals,\n> {\n public modal!: Modal<any>;\n\n private readonly platform: PlatformType = getPlatformType();\n\n private successCallback!: (error?: Error) => Promise<void>;\n\n private displayUriCallback?: (uri: string) => void;\n\n /**\n * Creates a new modal factory instance.\n *\n * @param options - The modals configuration object\n */\n constructor(protected readonly options: T) {\n this.validateModals();\n }\n\n /**\n * Platform-specific preload function to be implemented by subclasses.\n */\n protected abstract preload(): Promise<void>;\n\n private validateModals() {\n const requiredModals = ['InstallModal', 'OTPCodeModal'];\n const missingModals = requiredModals.filter(\n (modal) => !this.options[modal as ModalTypes],\n );\n if (missingModals.length > 0) {\n throw new Error(`Missing required modals: ${missingModals.join(', ')}`);\n }\n }\n\n async unload(error?: Error) {\n this.modal?.unmount();\n await this.successCallback?.(error);\n }\n\n /**\n * Determines if the current platform is a mobile native environment.\n * Currently only includes React Native.\n */\n get isMobile() {\n return this.platform === PlatformType.ReactNative;\n }\n\n /**\n * Determines if the current platform is a Node.js environment.\n * Used for server-side or non-browser environments.\n */\n get isNode() {\n return this.platform === PlatformType.NonBrowser;\n }\n\n /**\n * Determines if the current platform is a web environment.\n * Includes desktop web, MetaMask mobile webview, and mobile web.\n */\n get isWeb() {\n return (\n this.platform === PlatformType.DesktopWeb ||\n this.platform === PlatformType.MetaMaskMobileWebview ||\n this.platform === PlatformType.MobileWeb\n );\n }\n\n private getContainer() {\n return typeof document === 'undefined'\n ? undefined\n : document.createElement('div');\n }\n\n private getMountedContainer() {\n if (typeof document === 'undefined') {\n return undefined;\n }\n const container = this.getContainer();\n if (container) {\n document.body.appendChild(container);\n }\n return container;\n }\n\n createConnectionDeeplink(connectionRequest?: ConnectionRequest) {\n if (!connectionRequest) {\n throw new Error(\n 'createConnectionDeeplink can only be called with a connection request',\n );\n }\n const json = JSON.stringify(connectionRequest);\n const compressed = compressString(json);\n const urlEncoded = encodeURIComponent(compressed);\n return `${METAMASK_DEEPLINK_BASE}/mwp?p=${urlEncoded}&c=1`;\n }\n\n createConnectionUniversalLink(connectionRequest?: ConnectionRequest) {\n if (!connectionRequest) {\n return `${METAMASK_CONNECT_BASE_URL}`;\n }\n const json = JSON.stringify(connectionRequest);\n const compressed = compressString(json);\n const urlEncoded = encodeURIComponent(compressed);\n return `${METAMASK_CONNECT_BASE_URL}/mwp?p=${urlEncoded}&c=1`;\n }\n\n private async onCloseModal(shouldTerminate = true) {\n return this.unload(\n shouldTerminate ? new Error('User closed modal') : undefined,\n );\n }\n\n private onStartDesktopOnboarding() {\n new MetaMaskOnboarding().startOnboarding();\n }\n\n public async renderInstallModal(\n showInstallModal: boolean,\n createConnectionRequest: () => Promise<ConnectionRequest>,\n successCallback: (error?: Error) => Promise<void>,\n onDisplayUri?: (uri: string) => void,\n ) {\n this.modal?.unmount();\n await this.preload();\n this.successCallback = successCallback;\n this.displayUriCallback = onDisplayUri;\n\n const parentElement = this.getMountedContainer();\n const connectionRequest = await createConnectionRequest();\n const qrCodeLink = this.createConnectionDeeplink(connectionRequest);\n\n this.displayUriCallback?.(qrCodeLink);\n\n const modal: Modal<any> = new this.options.InstallModal({\n expiresIn:\n (connectionRequest.sessionRequest.expiresAt - Date.now()) / 1000,\n connectionRequest,\n parentElement,\n showInstallModal,\n link: qrCodeLink,\n sdkVersion: getVersion(),\n generateQRCode: async (request: ConnectionRequest) => {\n const newLink = this.createConnectionDeeplink(request);\n this.displayUriCallback?.(newLink);\n return newLink;\n },\n onClose: this.onCloseModal.bind(this),\n startDesktopOnboarding: this.onStartDesktopOnboarding.bind(this),\n createConnectionRequest,\n onDisplayUri: this.displayUriCallback,\n });\n\n this.modal = modal;\n modal.mount();\n }\n\n public async renderOTPCodeModal(\n createOTPCode: () => Promise<OTPCode>,\n successCallback: (error?: Error) => Promise<void>,\n updateOTPCode: (otpCode: OTPCode, modal: AbstractOTPCodeModal) => void,\n ) {\n this.modal?.unmount();\n await this.preload();\n this.successCallback = successCallback;\n\n const container = this.getMountedContainer();\n const otpCode = await createOTPCode();\n\n const modal: AbstractOTPCodeModal = new this.options.OTPCodeModal({\n parentElement: container,\n sdkVersion: getVersion(),\n otpCode,\n onClose: this.onCloseModal.bind(this),\n createOTPCode,\n updateOTPCode: (otpCode: OTPCode) => updateOTPCode(otpCode, modal),\n });\n\n this.modal = modal;\n modal.mount();\n }\n}\n","/* eslint-disable no-restricted-globals -- Web UI uses document */\n/* eslint-disable @typescript-eslint/naming-convention -- Type parameter T is a standard convention */\n/**\n * Browser/Web UI module entry point\n */\nimport { BaseModalFactory } from './ModalFactory';\nimport type { FactoryModals } from './modals/types';\n\n/**\n * Web-specific preload that loads Stencil custom elements\n */\nexport async function preload(): Promise<void> {\n if (typeof document === 'undefined') {\n return;\n }\n try {\n const { defineCustomElements } = await import(\n '@metamask/multichain-ui/loader'\n );\n await defineCustomElements();\n } catch (error) {\n console.error('Failed to load customElements:', error);\n }\n}\n\n/**\n * ModalFactory for browser/web environments.\n * Loads Stencil web components via dynamic import.\n */\nexport class ModalFactory<\n T extends FactoryModals = FactoryModals,\n> extends BaseModalFactory<T> {\n protected async preload(): Promise<void> {\n return preload();\n }\n}\n"],"mappings":"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","names":["EventEmitter3","logger","debug","_a","TransportType","_a","_a","Bowser","PlatformType","_a","_a","init_utils","init_utils","init_utils","logger","init_utils","logger","init_utils","encodeQR","node_exports","init_node","_a","import_analytics","import_mobile_wallet_protocol_core","import_multichain_api_client","_a","fetch","import_analytics","_a","_notificationCallbacks","_a","import_multichain_api_client","import_rpc_errors","DEFAULT_REQUEST_TIMEOUT","message","_a","sessionRequest","logger","_transport","init_fn","_a","isEnabled","isReactNative","_a","MetaMaskOnboarding","otpCode","StoreAdapterNode"]}