@metamask/connect-multichain 0.15.0 → 1.0.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.
- package/CHANGELOG.md +28 -1
- package/README.md +0 -1
- package/dist/browser/es/connect-multichain.d.mts +7 -6
- package/dist/browser/es/connect-multichain.mjs +451 -368
- package/dist/browser/es/connect-multichain.mjs.map +1 -1
- package/dist/browser/es/metafile-esm.json +1 -1
- package/dist/browser/iife/connect-multichain.d.ts +7 -6
- package/dist/browser/iife/connect-multichain.js +464 -368
- package/dist/browser/iife/connect-multichain.js.map +1 -1
- package/dist/browser/iife/metafile-iife.json +1 -1
- package/dist/browser/umd/connect-multichain.d.ts +7 -6
- package/dist/browser/umd/connect-multichain.js +451 -368
- package/dist/browser/umd/connect-multichain.js.map +1 -1
- package/dist/browser/umd/metafile-cjs.json +1 -1
- package/dist/node/cjs/connect-multichain.d.ts +7 -6
- package/dist/node/cjs/connect-multichain.js +453 -366
- package/dist/node/cjs/connect-multichain.js.map +1 -1
- package/dist/node/cjs/metafile-cjs.json +1 -1
- package/dist/node/es/connect-multichain.d.mts +7 -6
- package/dist/node/es/connect-multichain.mjs +450 -365
- package/dist/node/es/connect-multichain.mjs.map +1 -1
- package/dist/node/es/metafile-esm.json +1 -1
- package/dist/react-native/es/connect-multichain.d.mts +7 -6
- package/dist/react-native/es/connect-multichain.mjs +449 -364
- package/dist/react-native/es/connect-multichain.mjs.map +1 -1
- package/dist/react-native/es/metafile-esm.json +1 -1
- package/dist/src/domain/multichain/api/constants.d.ts +1 -0
- package/dist/src/domain/multichain/api/constants.d.ts.map +1 -1
- package/dist/src/domain/multichain/api/constants.js +13 -0
- package/dist/src/domain/multichain/api/constants.js.map +1 -1
- package/dist/src/domain/multichain/index.d.ts +2 -2
- package/dist/src/domain/multichain/index.d.ts.map +1 -1
- package/dist/src/domain/multichain/index.js.map +1 -1
- package/dist/src/domain/multichain/types.d.ts +0 -1
- package/dist/src/domain/multichain/types.d.ts.map +1 -1
- package/dist/src/domain/platform/index.d.ts.map +1 -1
- package/dist/src/domain/platform/index.js +27 -5
- package/dist/src/domain/platform/index.js.map +1 -1
- package/dist/src/domain/store/client.d.ts +3 -3
- package/dist/src/domain/store/client.d.ts.map +1 -1
- package/dist/src/domain/utils/index.d.ts +1 -0
- package/dist/src/domain/utils/index.d.ts.map +1 -1
- package/dist/src/domain/utils/index.js +5 -1
- package/dist/src/domain/utils/index.js.map +1 -1
- package/dist/src/multichain/index.d.ts +2 -3
- package/dist/src/multichain/index.d.ts.map +1 -1
- package/dist/src/multichain/index.js +142 -147
- package/dist/src/multichain/index.js.map +1 -1
- package/dist/src/multichain/rpc/requestRouter.d.ts +15 -0
- package/dist/src/multichain/rpc/requestRouter.d.ts.map +1 -1
- package/dist/src/multichain/rpc/requestRouter.js +31 -5
- package/dist/src/multichain/rpc/requestRouter.js.map +1 -1
- package/dist/src/multichain/transports/default/index.d.ts.map +1 -1
- package/dist/src/multichain/transports/default/index.js +16 -10
- package/dist/src/multichain/transports/default/index.js.map +1 -1
- package/dist/src/multichain/transports/multichainApiClientWrapper/index.d.ts +2 -1
- package/dist/src/multichain/transports/multichainApiClientWrapper/index.d.ts.map +1 -1
- package/dist/src/multichain/transports/multichainApiClientWrapper/index.js +25 -17
- package/dist/src/multichain/transports/multichainApiClientWrapper/index.js.map +1 -1
- package/dist/src/multichain/transports/mwp/index.d.ts +3 -1
- package/dist/src/multichain/transports/mwp/index.d.ts.map +1 -1
- package/dist/src/multichain/transports/mwp/index.js +227 -170
- package/dist/src/multichain/transports/mwp/index.js.map +1 -1
- package/dist/src/store/index.d.ts +3 -3
- package/dist/src/store/index.d.ts.map +1 -1
- package/dist/src/store/index.js +8 -8
- package/dist/src/store/index.js.map +1 -1
- package/dist/src/ui/ModalFactory.d.ts.map +1 -1
- package/dist/src/ui/ModalFactory.js +5 -1
- package/dist/src/ui/ModalFactory.js.map +1 -1
- package/dist/src/ui/index.js +1 -1
- package/dist/src/ui/index.js.map +1 -1
- package/dist/src/ui/modals/web/install.d.ts.map +1 -1
- package/dist/src/ui/modals/web/install.js.map +1 -1
- package/dist/types/connect-multichain.d.ts +7 -6
- package/package.json +2 -2
|
@@ -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/analytics.ts","../../../src/domain/utils/index.ts","../../../src/domain/index.ts","../../../src/multichain/utils/index.ts","../../../src/multichain/transports/constants.ts","../../../src/multichain/transports/mwp/index.ts","../../../src/multichain/transports/mwp/KeyManager.ts","../../../src/ui/modals/base/utils.ts","../../../src/ui/modals/base/AbstractInstallModal.ts","../../../src/ui/modals/web/install.ts","../../../src/ui/modals/base/AbstractOTPModal.ts","../../../src/ui/modals/web/otp.ts","../../../src/ui/modals/web/index.ts","../../../src/store/adapters/web.ts","../../../src/polyfills/buffer-shim.ts","../../../src/index.browser.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/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(\n public readonly reason: string,\n public readonly rpcCode?: number,\n public readonly rpcMessage?: string,\n ) {\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 // Sepolia 11155111\n 'eip155:11155111': 'https://sepolia.infura.io/v3/',\n // Hoodi\n 'eip155:560048': 'https://hoodi.infura.io/v3/',\n // ###### Linea ######\n // Mainnet Alpha\n 'eip155:59144': 'https://linea-mainnet.infura.io/v3/',\n // Sepolia\n 'eip155:59141': 'https://linea-sepolia.infura.io/v3/',\n // ###### Polygon ######\n // Mainnet\n 'eip155:137': 'https://polygon-mainnet.infura.io/v3/',\n // Amoy\n 'eip155:80002': 'https://polygon-amoy.infura.io/v3/',\n // ###### Optimism ######\n // Mainnet\n 'eip155:10': 'https://optimism-mainnet.infura.io/v3/',\n // Sepolia\n 'eip155:11155420': 'https://optimism-sepolia.infura.io/v3/',\n // ###### Arbitrum ######\n // Mainnet\n 'eip155:42161': 'https://arbitrum-mainnet.infura.io/v3/',\n // Sepolia\n 'eip155:421614': 'https://arbitrum-sepolia.infura.io/v3/',\n // ###### Base ######\n // Mainnet\n 'eip155:8453': 'https://base-mainnet.infura.io/v3/',\n // Sepolia\n 'eip155:84532': 'https://base-sepolia.infura.io/v3/',\n // ###### Blast ######\n // Mainnet\n 'eip155:81457': 'https://blast-mainnet.infura.io/v3/',\n // Sepolia\n 'eip155:168587773': 'https://blast-sepolia.infura.io/v3/',\n // ###### zkSync ######\n // Mainnet\n 'eip155:324': 'https://zksync-mainnet.infura.io/v3/',\n // Sepolia\n 'eip155:300': 'https://zksync-sepolia.infura.io/v3/',\n // ###### BSC ######\n // Mainnet\n 'eip155:56': 'https://bsc-mainnet.infura.io/v3/',\n // Testnet\n 'eip155:97': 'https://bsc-testnet.infura.io/v3/',\n // ###### opBNB ######\n // Mainnet\n 'eip155:204': 'https://opbnb-mainnet.infura.io/v3/',\n // Testnet\n 'eip155:5611': 'https://opbnb-testnet.infura.io/v3/',\n // ###### Scroll ######\n // Mainnet\n 'eip155:534352': 'https://scroll-mainnet.infura.io/v3/',\n // Sepolia\n 'eip155:534351': 'https://scroll-sepolia.infura.io/v3/',\n // ###### Mantle ######\n // Mainnet\n 'eip155:5000': 'https://mantle-mainnet.infura.io/v3/',\n // Sepolia\n 'eip155:5003': 'https://mantle-sepolia.infura.io/v3/',\n // ###### Sei ######\n // Mainnet\n 'eip155:1329': 'https://sei-mainnet.infura.io/v3/',\n // Testnet\n 'eip155:713715': 'https://sei-testnet.infura.io/v3/',\n // ###### Swellchain ######\n // Mainnet\n 'eip155:1923': 'https://swellchain-mainnet.infura.io/v3/',\n // Testnet\n 'eip155:1924': 'https://swellchain-testnet.infura.io/v3/',\n // ###### Unichain ######\n // Mainnet\n 'eip155:130': 'https://unichain-mainnet.infura.io/v3/',\n // Sepolia\n 'eip155:1301': 'https://unichain-sepolia.infura.io/v3/',\n // ###### Hemi ######\n // Mainnet\n 'eip155:43111': 'https://hemi-mainnet.infura.io/v3/',\n // Testnet\n 'eip155:743111': 'https://hemi-testnet.infura.io/v3/',\n // ###### MegaETH ######\n // Mainnet\n 'eip155:6342': 'https://megaeth-mainnet.infura.io/v3/',\n // Testnet\n 'eip155:6342001': 'https://megaeth-testnet.infura.io/v3/',\n // ###### Monad ######\n // Mainnet\n 'eip155:143': 'https://monad-mainnet.infura.io/v3/',\n // Testnet\n 'eip155:10143': 'https://monad-testnet.infura.io/v3/',\n // ###### Palm ######\n // Mainnet\n 'eip155:11297108109': 'https://palm-mainnet.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 // ###### 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 // Sepolia\n 'eip155:44787': 'https://celo-sepolia.infura.io/v3/',\n // ###### Solana ######\n // Mainnet\n 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp':\n 'https://solana-mainnet.infura.io/v3/',\n // Devnet\n 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1':\n 'https://solana-devnet.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","import type { CaipChainId } from '@metamask/utils';\n\nimport { infuraRpcUrls } from './constants';\nimport type { RpcUrlsMap } from './types';\n\n/**\n * Generates Infura RPC URLs for common networks keyed by CAIP Chain ID.\n *\n * @param options - The options for generating Infura RPC URLs\n * @param options.infuraApiKey - The Infura API key\n * @param options.caipChainIds - Optional CAIP-2 chain IDs to filter the output\n * @returns A map of CAIP-2 chain IDs to Infura RPC URLs\n */\nexport function getInfuraRpcUrls({\n infuraApiKey,\n caipChainIds,\n}: {\n infuraApiKey: string;\n caipChainIds?: CaipChainId[];\n}): RpcUrlsMap {\n const keys =\n caipChainIds && caipChainIds.length > 0\n ? caipChainIds\n : (Object.keys(infuraRpcUrls) as CaipChainId[]);\n\n return keys.reduce<RpcUrlsMap>((acc, key) => {\n const baseUrl = infuraRpcUrls[key];\n if (baseUrl) {\n acc[key] = `${baseUrl}${infuraApiKey}`;\n }\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 { InvokeMethodOptions, RPCAPI, Scope } from './api/types';\nimport type {\n ExtendedTransport,\n MergeableMultichainOptions,\n MultichainOptions,\n} from './types';\nimport type { StoreClient } from '../store/client';\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, analytics, versions, 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 const analytics = {\n ...opts.analytics,\n ...(partial.analytics ?? {}),\n };\n if (opts.analytics?.enabled === false) {\n analytics.enabled = false;\n }\n\n this.options = {\n ...opts,\n api: {\n ...opts.api,\n supportedNetworks: {\n ...opts.api.supportedNetworks,\n ...(partial.api?.supportedNetworks ?? {}),\n },\n },\n versions: {\n ...opts.versions,\n ...(partial.versions ?? {}),\n },\n analytics: {\n ...analytics,\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 return navigator?.product === 'ReactNative';\n}\n\nfunction isReactNative(): boolean {\n // Modern Hermes-based RN: window is undefined, but global.navigator.product is set.\n // This check must come first so getPlatformType() resolves to ReactNative rather\n // than NonBrowser when isNotBrowser() would otherwise catch this case.\n if (\n typeof global !== 'undefined' &&\n global?.navigator?.product === 'ReactNative'\n ) {\n return true;\n }\n\n // Legacy RN environments where window === global\n const hasWindowNavigator =\n typeof window !== 'undefined' && window.navigator !== undefined;\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 @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 TransportType,\n} from '../../domain';\nimport { getPlatformType, RPCInvokeMethodErr } from '../../domain';\n\n/**\n * Tag describing the cause of a failed wallet action / connection. Surfaced\n * as the `failure_reason` property on `mmconnect_wallet_action_failed` and\n * `mmconnect_connection_failed` events so we can distinguish e.g. a transport\n * timeout from a wallet-side internal error in Mixpanel.\n *\n * Intentionally a string union (not a const enum) so callers stay free to\n * pass through a new bucket; the schema-side property is an open string for\n * the same reason.\n */\nexport type FailureReason =\n | 'transport_timeout'\n | 'transport_disconnect'\n | 'wallet_method_unsupported'\n | 'wallet_invalid_params'\n | 'wallet_internal_error'\n | 'wallet_unauthorized'\n | 'unrecognized_chain'\n | 'unknown';\n\n/**\n * Maximum length of `error_message_sample` after sanitisation. Mirrors the\n * `maxLength: 200` constraint declared in the analytics-api `api.spec.yml`.\n */\nconst ERROR_MESSAGE_SAMPLE_MAX_LENGTH = 200;\n\n/**\n * Patterns scrubbed from `error_message_sample` before it leaves the SDK.\n * The goal is to surface enough error context for triage in Mixpanel\n * without leaking PII / wallet addresses / RPC endpoints / large numeric\n * quantities, across any chain the SDK might route to.\n *\n * Order matters. URLs are stripped early so address-shaped path segments\n * inside URLs aren't re-mangled by later passes. Specific patterns run\n * before broad ones (e.g. EVM `0x{40}` before the generic long-hex pass)\n * so the longer / more specific match wins. Bech32 runs before generic\n * Base58 because the two alphabets partially overlap — Bech32 includes\n * `0` (which Base58 excludes) and Base58 includes `o`/`i`/`b`/`l` (which\n * Bech32 excludes) — so running Base58 first can chop off the tail of an\n * HRP-prefixed Bech32 address at the first `l`/`i`/`o`/`b` and leave the\n * suffix unscrubbed. Decimal-number scrubbing runs last so it doesn't\n * fragment hex / Base58 tokens that contain digit runs.\n */\nconst SANITISE_PATTERNS: { pattern: RegExp; replacement: string }[] = [\n // EVM-style 20-byte hex addresses (e.g. `0x` + 40 hex chars).\n { pattern: /0x[a-fA-F0-9]{40}/gu, replacement: '<addr>' },\n // Other long hex blobs: tx hashes, signatures, raw byte strings, large\n // hex amounts. 16+ hex chars catches 32-byte hashes/signatures without\n // snagging EVM method selectors (8 chars) or short hex codes.\n { pattern: /(?:0x)?[a-fA-F0-9]{16,}/gu, replacement: '<hex>' },\n // URLs of any scheme up to the first whitespace / quote / closing paren.\n // Catches RPC endpoints, dapp deeplinks, query strings with secrets.\n { pattern: /https?:\\/\\/[^\\s\"')]+/gu, replacement: '<url>' },\n // Bech32 addresses: short HRP (1-10 lowercase chars) + `1` separator +\n // ≥38 chars of Bech32 data alphabet `[ac-hj-np-z02-9]` (excludes the\n // look-alike chars `b`, `i`, `o`, `1`). Covers Bitcoin SegWit\n // (`bc1…`/`tb1…`) and Cosmos-SDK chains (`cosmos1…`, `osmo1…`,\n // `juno1…`, `inj1…`, etc.) without enumerating every HRP. Runs before\n // the Base58 pattern below — see header comment for why.\n {\n pattern: /\\b[a-z]{1,10}1[ac-hj-np-z02-9]{38,}\\b/gu,\n replacement: '<addr>',\n },\n // Base58 tokens (32+ chars, Base58 alphabet `[1-9A-HJ-NP-Za-km-z]`).\n // Covers Solana pubkeys (32-44 chars), Solana tx signatures (~88 chars),\n // and Bitcoin Base58 addresses ≥32 chars. The 32-char floor and `\\b`\n // word boundary keep English words and shorter alphanumerics safe.\n {\n pattern: /\\b[1-9A-HJ-NP-Za-km-z]{32,}\\b/gu,\n replacement: '<addr>',\n },\n // Long decimal numbers — token amounts, gas units, timestamps, lamports.\n // 10+ digits catches typical chain quantities without affecting JSON-RPC\n // codes (-32601, 4001, etc.) or short numeric IDs.\n { pattern: /\\d{10,}/gu, replacement: '<num>' },\n];\n\n/**\n * Sanitises an error message for inclusion in analytics. Strips wallet\n * addresses (EVM hex, Solana / Bitcoin Base58, Bech32), long hex blobs,\n * URLs, and large decimal numbers, then truncates to\n * {@link ERROR_MESSAGE_SAMPLE_MAX_LENGTH} characters. Returns `undefined`\n * if there's no message to sample.\n *\n * @param message - Raw error message\n * @returns A safe-to-emit short string, or `undefined`\n */\nexport function sanitiseErrorMessage(\n message: string | undefined,\n): string | undefined {\n if (!message) {\n return undefined;\n }\n let sanitised = message;\n for (const { pattern, replacement } of SANITISE_PATTERNS) {\n sanitised = sanitised.replace(pattern, replacement);\n }\n if (sanitised.length > ERROR_MESSAGE_SAMPLE_MAX_LENGTH) {\n // Trim and mark as truncated so consumers can tell vs. naturally short\n // messages. The trailing ellipsis fits inside the maxLength budget.\n sanitised = `${sanitised.slice(0, ERROR_MESSAGE_SAMPLE_MAX_LENGTH - 1)}…`;\n }\n return sanitised;\n}\n\n/**\n * Pulls the most informative `code` / `message` pair out of an error,\n * unwrapping `RPCInvokeMethodErr` so the wallet-side code (e.g. 4001) is\n * visible to classifiers instead of being hidden behind the SDK's static\n * `code: 53`. Falls back to the outer error if there is no inner wallet code.\n *\n * @param error - The error object to inspect\n * @returns The most relevant `{ code, message }` pair we can extract\n */\nfunction getUnwrappedErrorDetails(error: unknown): {\n code: number | undefined;\n message: string;\n} {\n if (typeof error !== 'object' || error === null) {\n return { code: undefined, message: '' };\n }\n\n if (error instanceof RPCInvokeMethodErr) {\n return {\n code: error.rpcCode ?? error.code,\n message: error.rpcMessage ?? error.message ?? '',\n };\n }\n\n const errorObj = error as { code?: number; message?: string };\n return {\n code: errorObj.code,\n message: errorObj.message ?? '',\n };\n}\n\n/**\n * Checks if an error represents a user rejection.\n *\n * Unwraps `RPCInvokeMethodErr` so the wallet's `code: 4001` survives the\n * SDK's transport-boundary wrapping (the outer error otherwise reports\n * `code: 53`, which would never match the heuristics here).\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 { code, message } = getUnwrappedErrorDetails(error);\n const errorMessage = message.toLowerCase();\n\n // EIP-1193 4001 \"User Rejected Request\" is the canonical rejection code.\n // Note: 4100 \"Unauthorized\" is deliberately NOT matched here. On multichain\n // sessions it's what the CAIP-25 permission layer returns when a method\n // isn't in the granted scope (the layer rejects it before the method\n // handler runs). That's a permission/support signal, not a user-driven\n // rejection — misclassifying it as `_rejected` hides genuine permission\n // issues from `_failed`.\n return (\n code === 4001 ||\n errorMessage.includes('reject') ||\n errorMessage.includes('denied') ||\n errorMessage.includes('cancel') ||\n // Narrow \"user …\" matches — bare \"user\" is too greedy (catches Account\n // Abstraction errors like \"user operation reverted\").\n errorMessage.includes('user rejected') ||\n errorMessage.includes('user denied') ||\n errorMessage.includes('user cancelled') ||\n errorMessage.includes('user canceled')\n );\n}\n\n/**\n * Classifies a failed wallet action / connection error into a short tag for\n * the `failure_reason` analytics property. Caller is expected to have already\n * established that the error is *not* a user rejection (use `isRejectionError`\n * for that branching).\n *\n * The taxonomy is deliberately producer-side-only — the schema accepts any\n * string — so we can add buckets here without an API migration. Once the\n * distribution stabilises we may convert the schema field to a closed enum.\n *\n * @param error - The error to classify\n * @returns A short, snake_case tag describing why the operation failed\n */\nexport function classifyFailureReason(error: unknown): FailureReason {\n if (typeof error !== 'object' || error === null) {\n return 'unknown';\n }\n\n const errorObj = error as { name?: string; message?: string };\n const errorName = errorObj.name ?? '';\n const errorMessageRaw = errorObj.message ?? '';\n const errorMessage = errorMessageRaw.toLowerCase();\n\n // Wallet-side JSON-RPC / EIP-1193 code is the strongest signal we have —\n // check it before any message-substring heuristics so a wallet error like\n // `{ code: 4900, message: 'Disconnected' }` doesn't get caught by the\n // transport-disconnect text match below. Unwraps `RPCInvokeMethodErr` so\n // the wallet's actual error code is visible.\n const { code } = getUnwrappedErrorDetails(error);\n if (typeof code === 'number') {\n // JSON-RPC 2.0 + EIP-1474 standard codes.\n if (code === -32601) {\n return 'wallet_method_unsupported';\n }\n if (code === -32602) {\n return 'wallet_invalid_params';\n }\n if (code === -32603) {\n return 'wallet_internal_error';\n }\n // Standard JSON-RPC server error range.\n if (code <= -32000 && code >= -32099) {\n return 'wallet_internal_error';\n }\n // EIP-1193 named provider codes — handled individually. Codes in the\n // 1000–4999 range that aren't matched here fall through to `unknown`.\n if (code === 4100) {\n // Unauthorized — most commonly fires when a method isn't in the\n // CAIP-25 scope's granted methods list (the multichain permission\n // layer rejects it before the method handler runs). Distinct from\n // a user rejection (4001) and worth tracking separately.\n return 'wallet_unauthorized';\n }\n if (code === 4200) {\n // Unsupported method — wallet handler exists but explicitly refuses.\n return 'wallet_method_unsupported';\n }\n if (code === 4902) {\n // Unrecognized chain ID — `wallet_switchEthereumChain` to a chain the\n // wallet hasn't been told about. MetaMask (extension + mobile) always\n // sets code 4902 on this error, so we don't need a message-substring\n // fallback below.\n return 'unrecognized_chain';\n }\n // Anything else in the EIP-1193 / EIP-1474 provider-defined range\n // (1000–4999) falls through to `unknown` — we can promote specific codes\n // into their own buckets later as the distribution stabilises, without a\n // schema migration. Two buckets for \"we don't know what this is\" adds\n // noise without insight.\n }\n\n // Transport-layer errors. Two shapes exist:\n // - `TransportTimeoutError` from `@metamask/multichain-api-client` (used by\n // MWP and the warmup paths of the default extension transport). It's a\n // subclass of `TransportError` so we match on the name field rather than\n // importing the symbol (the type lives in a runtime dependency that the\n // analytics utils shouldn't pull in directly).\n // - A plain `new Error('Request timeout')` thrown by `DefaultTransport`'s\n // own setTimeout. Indistinguishable from other errors without the message.\n if (\n errorName === 'TransportTimeoutError' ||\n errorMessageRaw === 'Request timeout' ||\n errorMessage.includes('timed out') ||\n errorMessage.includes('timeout')\n ) {\n return 'transport_timeout';\n }\n // Transport disconnect. Narrowed substring set so we don't snag wallet\n // error messages that happen to contain \"disconnect\" (e.g. EIP-1193\n // `4900 Disconnected`, which the wallet-code branch above already routed\n // to `unknown` per policy).\n if (\n errorName === 'TransportError' ||\n errorMessage.includes('not connected') ||\n errorMessage.includes('transport disconnect') ||\n errorMessage.includes('connection lost') ||\n errorMessage.includes('socket closed')\n ) {\n return 'transport_disconnect';\n }\n\n return 'unknown';\n}\n\n/**\n * Bundle of diagnostic properties attached to `mmconnect_*_failed` events:\n * the bucketed {@link FailureReason}, the raw wallet-side error code if\n * present, and a sanitised sample of the original message. All three are\n * derived from a single error so producers only need to call this once.\n *\n * `error_code` and `error_message_sample` are intentionally optional —\n * many SDK-internal errors (e.g. `'Transport not initialized'`) have\n * neither a numeric code nor a useful message; in that case the caller\n * should attach only `failure_reason`.\n */\nexport type ErrorDiagnostics = {\n failure_reason: FailureReason;\n error_code?: number;\n error_message_sample?: string;\n};\n\n/**\n * Computes the full set of diagnostic properties to attach to a\n * `mmconnect_*_failed` event from a single error. Combines\n * {@link classifyFailureReason}, the unwrapped wallet code, and a\n * sanitised message sample so producer call sites stay a single line.\n *\n * @param error - The error to inspect\n * @returns Diagnostics ready to spread into the event properties\n */\nexport function extractErrorDiagnostics(error: unknown): ErrorDiagnostics {\n const failureReason = classifyFailureReason(error);\n const { code, message } = getUnwrappedErrorDetails(error);\n const messageSample = sanitiseErrorMessage(message);\n return {\n failure_reason: failureReason,\n ...(typeof code === 'number' ? { error_code: code } : {}),\n ...(messageSample ? { error_message_sample: messageSample } : {}),\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_versions: Record<string, string>;\n dapp_id: string;\n platform: PlatformType;\n anon_id: string;\n}> {\n const dappId = getDappId(options.dapp);\n const platform = getPlatformType();\n const anonId = await storage.getAnonId();\n\n return {\n mmconnect_versions: options.versions ?? {},\n dapp_id: dappId,\n platform,\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 * @param transportType - The transport type to use for the analytics event\n * @param extra - Optional event-specific diagnostic properties. Used by\n * `mmconnect_wallet_action_failed` to attach the {@link ErrorDiagnostics}\n * bundle (`failure_reason`, `error_code`, `error_message_sample`).\n * @param extra.failure_reason - A short tag describing why the operation\n * failed; see `classifyFailureReason` and the `FailureReason` union.\n * @param extra.error_code - The raw wallet-side error code, if present.\n * @param extra.error_message_sample - A sanitised, truncated sample of the\n * original error message.\n * @returns Wallet action analytics properties\n */\nexport async function getWalletActionAnalyticsProperties(\n options: MultichainOptions,\n storage: StoreClient,\n invokeOptions: InvokeMethodOptions,\n transportType: TransportType,\n extra?: {\n failure_reason?: FailureReason;\n error_code?: number;\n error_message_sample?: string;\n },\n): Promise<{\n mmconnect_versions: Record<string, string>;\n dapp_id: string;\n method: string;\n caip_chain_id: string;\n anon_id: string;\n transport_type: TransportType;\n failure_reason?: FailureReason;\n error_code?: number;\n error_message_sample?: string;\n}> {\n const dappId = getDappId(options.dapp);\n const anonId = await storage.getAnonId();\n\n return {\n mmconnect_versions: options.versions ?? {},\n dapp_id: dappId,\n method: invokeOptions.request.method,\n caip_chain_id: invokeOptions.scope,\n anon_id: anonId,\n transport_type: transportType,\n ...(extra?.failure_reason ? { failure_reason: extra.failure_reason } : {}),\n ...(typeof extra?.error_code === 'number'\n ? { error_code: extra.error_code }\n : {}),\n ...(extra?.error_message_sample\n ? { error_message_sample: extra.error_message_sample }\n : {}),\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 classifyFailureReason,\n getWalletActionAnalyticsProperties,\n isRejectionError,\n} from '../../multichain/utils/analytics';\nexport type { FailureReason } 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","/* 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","export const EIP_1193_PROVIDER_STREAM_NAME = 'metamask-provider';\nexport const MULTICHAIN_PROVIDER_STREAM_NAME = 'metamask-multichain-provider';\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 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 getPlatformType,\n PlatformType,\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?: {\n scopes: Scope[];\n caipAccountIds: CaipAccountId[];\n forceRequest?: boolean;\n },\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 (options.forceRequest || !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 forceRequest?: boolean;\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 const platformType = getPlatformType();\n const isQRCodeFlow = [\n PlatformType.DesktopWeb,\n PlatformType.NonBrowser,\n ].includes(platformType);\n\n const initialPayload = {\n name: MULTICHAIN_PROVIDER_STREAM_NAME,\n data: request,\n };\n\n dappClient\n .connect({\n mode: 'trusted',\n initialPayload: isQRCodeFlow ? undefined : initialPayload,\n })\n .then(async () => {\n if (isQRCodeFlow) {\n return dappClient.sendRequest(initialPayload);\n }\n return undefined;\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 import(\n '@metamask/mobile-wallet-protocol-core'\n );\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","/* 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';\n\n/**\n * Creates an {@link IKeyManager} backed by the `eciesjs` library.\n *\n * The factory dynamically imports `eciesjs` so the heavy crypto dependency is\n * only loaded when MWP transport is actually used. The returned object closes\n * over the imported symbols, allowing synchronous methods like\n * `generateKeyPair` and `validatePeerKey` to work without a second await.\n *\n * @returns A ready-to-use key manager instance.\n */\nexport async function createKeyManager(): Promise<IKeyManager> {\n const { decrypt, encrypt, PrivateKey, PublicKey } = await import('eciesjs');\n\n return {\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}\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 no-restricted-globals -- Web modal uses document */\nimport type { MmInstallModalCustomEvent } from '@metamask/multichain-ui';\n\nimport { AbstractInstallModal } from '../base/AbstractInstallModal';\n\nexport class InstallModal extends AbstractInstallModal {\n renderQRCode(): void {\n // Not needed for web as its using install Modal\n }\n\n mount(): void {\n const { options } = this;\n const modal = document.createElement(\n 'mm-install-modal',\n ) as HTMLMmInstallModalElement;\n\n modal.showInstallModal = options.showInstallModal;\n modal.addEventListener('close', (ev: Event) => {\n const { detail } = ev as MmInstallModalCustomEvent<{\n shouldTerminate?: boolean;\n }>;\n options.onClose(detail?.shouldTerminate);\n });\n modal.addEventListener(\n 'startDesktopOnboarding',\n options.startDesktopOnboarding,\n );\n modal.link = options.link;\n\n this.instance = modal;\n options.parentElement?.appendChild(modal);\n\n this.startExpirationCheck(options.connectionRequest);\n }\n\n unmount(): void {\n const { options, instance: modal } = this;\n this.stopExpirationCheck();\n if (modal && options.parentElement?.contains(modal)) {\n options.parentElement.removeChild(modal);\n this.instance = undefined;\n }\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","/* eslint-disable no-restricted-globals -- Browser storage adapter uses window.indexedDB */\n/* eslint-disable @typescript-eslint/naming-convention -- DB_NAME is a constant */\n/* eslint-disable @typescript-eslint/explicit-function-return-type -- Inferred types are sufficient */\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 @typescript-eslint/prefer-promise-reject-errors -- Custom error objects */\nimport { StoreAdapter } from '../../domain';\n\ntype KvStores = 'sdk-kv-store' | 'key-value-pairs';\n\nexport class StoreAdapterWeb extends StoreAdapter {\n static readonly stores: KvStores[] = ['sdk-kv-store', 'key-value-pairs'];\n\n static readonly DB_NAME = 'mmconnect';\n\n readonly platform = 'web';\n\n readonly dbPromise: Promise<IDBDatabase>;\n\n private get internal(): IDBFactory {\n if (typeof window === 'undefined' || !window.indexedDB) {\n throw new Error('indexedDB is not available in this environment');\n }\n return window.indexedDB;\n }\n\n constructor(\n dbNameSuffix: `-${string}` = '-kv-store',\n private readonly storeName: KvStores = StoreAdapterWeb.stores[0],\n ) {\n super();\n\n const dbName = `${StoreAdapterWeb.DB_NAME}${dbNameSuffix}`;\n this.dbPromise = new Promise((resolve, reject) => {\n try {\n const request = this.internal.open(dbName, 1);\n request.onerror = () => reject(new Error('Failed to open IndexedDB.'));\n request.onsuccess = () => resolve(request.result);\n request.onupgradeneeded = () => {\n const db = request.result;\n for (const name of StoreAdapterWeb.stores) {\n if (!db.objectStoreNames.contains(name)) {\n db.createObjectStore(name);\n }\n }\n };\n } catch (error) {\n reject(error);\n }\n });\n }\n\n async get(key: string): Promise<string | null> {\n const { storeName } = this;\n const db = await this.dbPromise;\n return new Promise((resolve, reject) => {\n try {\n const tx = db.transaction(storeName, 'readonly');\n const store = tx.objectStore(storeName);\n const request = store.get(key);\n request.onerror = () =>\n reject(new Error('Failed to get value from IndexedDB.'));\n request.onsuccess = () => resolve((request.result as string) ?? null);\n } catch (error) {\n reject(error);\n }\n });\n }\n\n async set(key: string, value: string): Promise<void> {\n const { storeName } = this;\n const db = await this.dbPromise;\n return new Promise((resolve, reject) => {\n try {\n const tx = db.transaction(storeName, 'readwrite');\n const store = tx.objectStore(storeName);\n const request = store.put(value, key);\n request.onerror = () =>\n reject(new Error('Failed to set value in IndexedDB.'));\n request.onsuccess = () => resolve();\n } catch (error) {\n reject(error);\n }\n });\n }\n\n async delete(key: string): Promise<void> {\n const { storeName } = this;\n const db = await this.dbPromise;\n return new Promise((resolve, reject) => {\n try {\n const tx = db.transaction(storeName, 'readwrite');\n const store = tx.objectStore(storeName);\n const request = store.delete(key);\n request.onerror = () =>\n reject(new Error('Failed to delete value from IndexedDB.'));\n request.onsuccess = () => resolve();\n } catch (error) {\n reject(error);\n }\n });\n }\n}\n","/* eslint-disable import-x/no-nodejs-modules -- Buffer polyfill requires Node.js module */\n/**\n * Buffer polyfill for browser and React Native environments.\n *\n * This shim sets up the global Buffer object before any code that depends on it runs.\n * It's imported at the top of platform-specific entry points (index.browser.ts, index.native.ts).\n *\n * Node.js environments already have Buffer globally available, so this is a no-op there.\n */\nimport { Buffer } from 'buffer';\n\nimport { getGlobalObject } from '../multichain/utils';\n\n// Only set Buffer if it's not already defined (avoid overwriting Node.js native Buffer)\nconst globalObj = getGlobalObject();\nglobalObj.Buffer ??= Buffer;\n","/* eslint-disable import-x/no-unassigned-import -- Polyfill must be imported first */\n// Buffer polyfill must be imported first to set up globalThis.Buffer\nimport './polyfills/buffer-shim';\n\nimport 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/web');\n let storage: StoreClient;\n if (options.storage) {\n storage = options.storage;\n } else {\n const { StoreAdapterWeb } = await import('./store/adapters/web');\n const adapter = new StoreAdapterWeb();\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 type { SessionRequest } from '@metamask/mobile-wallet-protocol-core';\nimport type { 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 extractErrorDiagnostics,\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 {\n getDappId,\n getGlobalObject,\n mergeRequestedSessionWithExisting,\n openDeeplink,\n setupDappMetadata,\n} from './utils';\n\nexport { getInfuraRpcUrls } from '../domain/multichain/api/infura';\n\n// Value substitued by tsup at build time\ndeclare const __PACKAGE_VERSION__: string | undefined;\n\n// ENFORCE NAMESPACE THAT CAN BE DISABLED\nconst logger = createLogger('metamask-sdk:core');\n\nconst SINGLETON_KEY = '__METAMASK_CONNECT_MULTICHAIN_SINGLETON__';\n\ntype ReusableMultichainSingleton = {\n mergeOptions: (options: MultichainOptions) => void;\n options: MultichainOptions;\n storage: StoreClient;\n};\n\n/**\n * Applies analytics defaults while preserving explicitly disabled analytics.\n *\n * @param analyticsOptions - Partial analytics options supplied by the consumer.\n * @returns Analytics options with defaults applied.\n */\nfunction normalizeAnalyticsOptions(\n analyticsOptions: MultichainOptions['analytics'],\n): Required<NonNullable<MultichainOptions['analytics']>> {\n return {\n ...(analyticsOptions ?? {}),\n enabled: analyticsOptions?.enabled ?? true,\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n integrationType: analyticsOptions?.integrationType || 'direct',\n };\n}\n\n/**\n * Checks whether dapp-side analytics are enabled for the SDK instance.\n *\n * @param options - Current SDK options.\n * @returns Whether analytics events should be collected and sent.\n */\nfunction isAnalyticsEnabled(options: MultichainOptions): boolean {\n return options.analytics?.enabled !== false;\n}\n\n/**\n * Sets up analytics globals using only APIs available on existing singleton\n * instances, including instances created by older bundled package copies.\n *\n * @param options - Current SDK options.\n * @param storage - Storage client for retrieving the anonymous ID.\n * @param setAnonId - Optional callback for updating the current instance anon ID.\n */\nasync function setupAnalyticsGlobals(\n options: MultichainOptions,\n storage: StoreClient,\n setAnonId?: (anonId: string | undefined) => void,\n): Promise<void> {\n if (!isAnalyticsEnabled(options)) {\n setAnonId?.(undefined);\n analytics.disable();\n return;\n }\n\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 dappId = getDappId(options.dapp);\n const anonId = await storage.getAnonId();\n setAnonId?.(anonId);\n\n const { integrationType } = options.analytics ?? {\n integrationType: '',\n };\n analytics.setGlobalProperty('mmconnect_versions', options.versions ?? {});\n analytics.setGlobalProperty('dapp_id', dappId);\n analytics.setGlobalProperty('anon_id', anonId);\n analytics.setGlobalProperty('platform', platform);\n if (integrationType) {\n analytics.setGlobalProperty('integration_types', [integrationType]);\n }\n analytics.enable();\n}\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 #transportType?: TransportType;\n\n public _status: ConnectionStatus = 'pending';\n\n #listener: (() => void | Promise<void>) | undefined;\n\n #anonId: string | 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.emit('stateChanged', value);\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 transportType(): TransportType {\n return this.#transportType ?? TransportType.UNKNOWN;\n }\n\n get storage(): StoreClient {\n return this.options.storage;\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 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: normalizeAnalyticsOptions(options.analytics),\n versions: {\n // typeof guard needed: Metro (React Native) bundles TS source directly,\n // bypassing the tsup build that substitutes __PACKAGE_VERSION__.\n 'connect-multichain':\n typeof __PACKAGE_VERSION__ === 'undefined'\n ? 'unknown'\n : __PACKAGE_VERSION__,\n ...(options.versions ?? {}),\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 // `analytics`, `versions`, `ui.*`, `mobile.*`, `transport.extensionId`,\n // `debug`. Take note that the value for `dapp` is not merged as it does not\n // make sense for subsequent calls to `createMultichainClient` to have a\n // 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 | ReusableMultichainSingleton>\n | undefined;\n if (existing) {\n const instance = await existing;\n instance.mergeOptions(options);\n if (instance instanceof MetaMaskConnectMultichain) {\n await instance.#setupAnalytics();\n } else {\n await setupAnalyticsGlobals(instance.options, instance.storage);\n }\n if (options.debug) {\n enableDebug('metamask-sdk:*');\n }\n return instance as MetaMaskConnectMultichain;\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 /**\n * Sets up analytics globals for the current SDK options.\n */\n async #setupAnalytics(): Promise<void> {\n await setupAnalyticsGlobals(this.options, this.storage, (anonId) => {\n this.#anonId = anonId;\n });\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<ExtendedTransport | undefined> {\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.#transportType = TransportType.Browser;\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 { MWPTransport } = await import('./transports/mwp');\n const apiTransport = new MWPTransport(dappClient, kvstore);\n this.#dappClient = dappClient;\n this.#transport = apiTransport;\n this.#transportType = TransportType.MWP;\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.#transportType === TransportType.MWP) {\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 #buildConnectionMetadata(): ConnectionRequest['metadata'] {\n const metadata: ConnectionRequest['metadata'] = {\n dapp: this.options.dapp,\n sdk: { version: getVersion(), platform: getPlatformType() },\n };\n if (isAnalyticsEnabled(this.options) && this.#anonId) {\n metadata.analytics = { remote_session_id: this.#anonId };\n }\n return metadata;\n }\n\n async #init(): Promise<void> {\n try {\n await this.#setupAnalytics();\n await this.#setupTransport();\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 [mwpCore, { DappClient: DappClientClass }, { createKeyManager }] =\n await Promise.all([\n import('@metamask/mobile-wallet-protocol-core'),\n import('@metamask/mobile-wallet-protocol-dapp-client'),\n import('./transports/mwp/KeyManager'),\n ]);\n const keymanager = await createKeyManager();\n\n const { adapter: kvstore } = this.options.storage;\n const sessionstore = await mwpCore.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 mwpCore.WebSocketTransport.create({\n url: MWP_RELAY_URL,\n kvstore,\n websocket,\n });\n const dappClient = new DappClientClass({\n transport,\n sessionstore,\n keymanager,\n });\n return dappClient;\n }\n\n async #setupMWP(): Promise<void> {\n if (this.#transportType === TransportType.MWP) {\n return;\n }\n const { adapter: kvstore } = this.options.storage;\n const dappClient = await this.#createDappClient();\n this.#dappClient = dappClient;\n const { MWPTransport } = await import('./transports/mwp');\n const apiTransport = new MWPTransport(dappClient, kvstore);\n this.#transport = apiTransport;\n this.#transportType = TransportType.MWP;\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: this.#buildConnectionMetadata(),\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 const { ProtocolError, ErrorCode } = await import(\n '@metamask/mobile-wallet-protocol-core'\n );\n if (error instanceof ProtocolError) {\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: this.#buildConnectionMetadata(),\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 const { ProtocolError } = await import(\n '@metamask/mobile-wallet-protocol-core'\n );\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.#transportType === TransportType.Browser) {\n return this.#transport as DefaultTransport;\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.#transportType = TransportType.Browser;\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: this.#buildConnectionMetadata(),\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 if (isAnalyticsEnabled(this.options)) {\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 }\n return undefined; // explicitly return `undefined` to avoid eslintpromise/always-return\n })\n .catch(async (error) => {\n this.status = 'disconnected';\n if (isAnalyticsEnabled(this.options)) {\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 ...extractErrorDiagnostics(error),\n });\n }\n } catch {\n logger('Error tracking connection failed/rejected event', error);\n }\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 if (isAnalyticsEnabled(this.options)) {\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\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.#transportType === TransportType.MWP) {\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.#transportType = 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(\n transport,\n rpcClient,\n options,\n this.#transportType ?? TransportType.UNKNOWN,\n );\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: this.#buildConnectionMetadata(),\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 type TransportType,\n} from '../../domain';\nimport { openDeeplink } from '../utils';\nimport {\n extractErrorDiagnostics,\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 * Normalizes unknown invocation errors to the router error type.\n *\n * @param error - Unknown error thrown during method execution.\n * @returns Error instance surfaced by invokeMethod.\n */\nfunction toRPCInvokeMethodErr(error: unknown): RPCInvokeMethodErr {\n if (error instanceof RPCInvokeMethodErr) {\n return error;\n }\n const castError = error as { message?: string; code?: number };\n return new RPCInvokeMethodErr(\n castError.message ?? 'Unknown error',\n castError.code,\n );\n}\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 private readonly transportType: TransportType,\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 error.code,\n 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 if (this.config.analytics?.enabled === false) {\n try {\n return await execute();\n } catch (error) {\n throw toRPCInvokeMethodErr(error);\n }\n }\n\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, error);\n }\n throw toRPCInvokeMethodErr(error);\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 this.transportType,\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 this.transportType,\n );\n analytics.track('mmconnect_wallet_action_succeeded', props);\n }\n\n /**\n * Tracks wallet action failed event.\n *\n * @param options - The invoke method options.\n * @param error - The error that caused the failure (used to classify the\n * `failure_reason` property on the event).\n */\n async #trackWalletActionFailed(\n options: InvokeMethodOptions,\n error: unknown,\n ): Promise<void> {\n const props = await getWalletActionAnalyticsProperties(\n this.config,\n this.config.storage,\n options,\n this.transportType,\n extractErrorDiagnostics(error),\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 this.transportType,\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 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 * 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 // Attach the numeric RPC code so it survives the transport boundary\n // and can be re-surfaced as an EIP-1193 error by higher layers.\n // This path is exercised by sendEip1193Message callers.\n const error = new Error(\n response.error.message || 'Request failed',\n ) as Error & { code?: number };\n if (typeof response.error.code === 'number') {\n error.code = response.error.code;\n }\n pendingRequest.reject(error);\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 'method' in responseData\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 // #transport.connect() internally calls disconnect() if the transport is connected,\n // and clears all listeners in the process. This ensures that we don't lose any listeners\n // by only connecting if we aren't already connected. Opting for this approach rather than a larger refactor\n // of who is responsible for managing listener setup and cleanup.\n if (!this.#transport.isConnected()) {\n await this.#transport.connect();\n }\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 isTransportConnected(): boolean {\n return (\n this.isTransportDefined() &&\n this.metamaskConnectMultichain.transport.isConnected()\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 // Purposely noop, resolves successfully. Actual connection is handled by the underlying client/transport.\n async connect(): Promise<void> {\n return Promise.resolve();\n }\n\n // Purposely noop, resolves successfully. Actual connection is handled by the underlying client/transport.\n async disconnect(): Promise<void> {\n return Promise.resolve();\n }\n\n // Purposely hardcoded to true. Actual connection is handled by the underlying client/transport.\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\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 await this.metamaskConnectMultichain.connect(\n scopes,\n accounts,\n createSessionParams.sessionProperties,\n );\n return this.metamaskConnectMultichain.transport.request({\n method: 'wallet_getSession',\n });\n }\n\n async #walletGetSession(request: TransportRequestWithId) {\n if (!this.isTransportConnected()) {\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 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.isTransportConnected()) {\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 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 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 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 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":["logger","_a","TransportType","_a","analytics","_a","PlatformType","_a","init_utils","_a","init_utils","init_constants","providerErrors","DEFAULT_REQUEST_TIMEOUT","init_utils","init_constants","message","_a","sessionRequest","init_utils","logger","init_utils","_a","web_exports","init_web","_a","init_utils","Buffer","analytics","_a","init_utils","_a","_a","init_utils","_a","init_utils","_notificationCallbacks","_a","init_utils","logger","_a","analytics","isReactNative","_transport","init_fn","isEnabled","MWPTransport","createKeyManager","init_utils","_a","otpCode","StoreAdapterWeb"]}
|
|
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/analytics.ts","../../../src/domain/utils/index.ts","../../../src/domain/index.ts","../../../src/multichain/utils/index.ts","../../../src/multichain/transports/constants.ts","../../../src/multichain/transports/mwp/index.ts","../../../src/multichain/transports/mwp/KeyManager.ts","../../../src/ui/modals/base/utils.ts","../../../src/ui/modals/base/AbstractInstallModal.ts","../../../src/ui/modals/web/install.ts","../../../src/ui/modals/base/AbstractOTPModal.ts","../../../src/ui/modals/web/otp.ts","../../../src/ui/modals/web/index.ts","../../../src/store/adapters/web.ts","../../../src/polyfills/buffer-shim.ts","../../../src/index.browser.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/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(\n public readonly reason: string,\n public readonly rpcCode?: number,\n public readonly rpcMessage?: string,\n ) {\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 // Sepolia 11155111\n 'eip155:11155111': 'https://sepolia.infura.io/v3/',\n // Hoodi\n 'eip155:560048': 'https://hoodi.infura.io/v3/',\n // ###### Linea ######\n // Mainnet Alpha\n 'eip155:59144': 'https://linea-mainnet.infura.io/v3/',\n // Sepolia\n 'eip155:59141': 'https://linea-sepolia.infura.io/v3/',\n // ###### Polygon ######\n // Mainnet\n 'eip155:137': 'https://polygon-mainnet.infura.io/v3/',\n // Amoy\n 'eip155:80002': 'https://polygon-amoy.infura.io/v3/',\n // ###### Optimism ######\n // Mainnet\n 'eip155:10': 'https://optimism-mainnet.infura.io/v3/',\n // Sepolia\n 'eip155:11155420': 'https://optimism-sepolia.infura.io/v3/',\n // ###### Arbitrum ######\n // Mainnet\n 'eip155:42161': 'https://arbitrum-mainnet.infura.io/v3/',\n // Sepolia\n 'eip155:421614': 'https://arbitrum-sepolia.infura.io/v3/',\n // ###### Base ######\n // Mainnet\n 'eip155:8453': 'https://base-mainnet.infura.io/v3/',\n // Sepolia\n 'eip155:84532': 'https://base-sepolia.infura.io/v3/',\n // ###### Blast ######\n // Mainnet\n 'eip155:81457': 'https://blast-mainnet.infura.io/v3/',\n // Sepolia\n 'eip155:168587773': 'https://blast-sepolia.infura.io/v3/',\n // ###### zkSync ######\n // Mainnet\n 'eip155:324': 'https://zksync-mainnet.infura.io/v3/',\n // Sepolia\n 'eip155:300': 'https://zksync-sepolia.infura.io/v3/',\n // ###### BSC ######\n // Mainnet\n 'eip155:56': 'https://bsc-mainnet.infura.io/v3/',\n // Testnet\n 'eip155:97': 'https://bsc-testnet.infura.io/v3/',\n // ###### opBNB ######\n // Mainnet\n 'eip155:204': 'https://opbnb-mainnet.infura.io/v3/',\n // Testnet\n 'eip155:5611': 'https://opbnb-testnet.infura.io/v3/',\n // ###### Scroll ######\n // Mainnet\n 'eip155:534352': 'https://scroll-mainnet.infura.io/v3/',\n // Sepolia\n 'eip155:534351': 'https://scroll-sepolia.infura.io/v3/',\n // ###### Mantle ######\n // Mainnet\n 'eip155:5000': 'https://mantle-mainnet.infura.io/v3/',\n // Sepolia\n 'eip155:5003': 'https://mantle-sepolia.infura.io/v3/',\n // ###### Sei ######\n // Mainnet\n 'eip155:1329': 'https://sei-mainnet.infura.io/v3/',\n // Testnet\n 'eip155:713715': 'https://sei-testnet.infura.io/v3/',\n // ###### Swellchain ######\n // Mainnet\n 'eip155:1923': 'https://swellchain-mainnet.infura.io/v3/',\n // Testnet\n 'eip155:1924': 'https://swellchain-testnet.infura.io/v3/',\n // ###### Unichain ######\n // Mainnet\n 'eip155:130': 'https://unichain-mainnet.infura.io/v3/',\n // Sepolia\n 'eip155:1301': 'https://unichain-sepolia.infura.io/v3/',\n // ###### Hemi ######\n // Mainnet\n 'eip155:43111': 'https://hemi-mainnet.infura.io/v3/',\n // Testnet\n 'eip155:743111': 'https://hemi-testnet.infura.io/v3/',\n // ###### MegaETH ######\n // Mainnet\n 'eip155:6342': 'https://megaeth-mainnet.infura.io/v3/',\n // Testnet\n 'eip155:6342001': 'https://megaeth-testnet.infura.io/v3/',\n // ###### Monad ######\n // Mainnet\n 'eip155:143': 'https://monad-mainnet.infura.io/v3/',\n // Testnet\n 'eip155:10143': 'https://monad-testnet.infura.io/v3/',\n // ###### Palm ######\n // Mainnet\n 'eip155:11297108109': 'https://palm-mainnet.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 // ###### 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 // Sepolia\n 'eip155:44787': 'https://celo-sepolia.infura.io/v3/',\n // ###### Solana ######\n // Mainnet\n 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp':\n 'https://solana-mainnet.infura.io/v3/',\n // Devnet\n 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1':\n 'https://solana-devnet.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\n// EIP-1193 / legacy provider methods that bypass the multichain `wallet_invokeMethod`\n// envelope and are forwarded directly to the underlying transport's\n// `sendEip1193Message` (raw method/params, native extension/MWP postMessage routing).\n// These are wallet-side concerns that the Multichain API does not model:\n// - `wallet_addEthereumChain` / `wallet_switchEthereumChain` mutate the wallet's\n// chain configuration, not session scope state.\n// - `eth_accounts` is occasionally needed as a live read against the wallet\n// (see EVM `#onSessionChanged`) outside the cached SDK session state.\nexport const EIP1193_PASSTHROUGH_METHODS = new Set([\n 'wallet_addEthereumChain',\n 'wallet_switchEthereumChain',\n 'eth_accounts',\n]);\n","import type { CaipChainId } from '@metamask/utils';\n\nimport { infuraRpcUrls } from './constants';\nimport type { RpcUrlsMap } from './types';\n\n/**\n * Generates Infura RPC URLs for common networks keyed by CAIP Chain ID.\n *\n * @param options - The options for generating Infura RPC URLs\n * @param options.infuraApiKey - The Infura API key\n * @param options.caipChainIds - Optional CAIP-2 chain IDs to filter the output\n * @returns A map of CAIP-2 chain IDs to Infura RPC URLs\n */\nexport function getInfuraRpcUrls({\n infuraApiKey,\n caipChainIds,\n}: {\n infuraApiKey: string;\n caipChainIds?: CaipChainId[];\n}): RpcUrlsMap {\n const keys =\n caipChainIds && caipChainIds.length > 0\n ? caipChainIds\n : (Object.keys(infuraRpcUrls) as CaipChainId[]);\n\n return keys.reduce<RpcUrlsMap>((acc, key) => {\n const baseUrl = infuraRpcUrls[key];\n if (baseUrl) {\n acc[key] = `${baseUrl}${infuraApiKey}`;\n }\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 { InvokeMethodOptions, RPCAPI, Scope } from './api/types';\nimport type { MergeableMultichainOptions, MultichainOptions } from './types';\nimport type { StoreClient } from '../store/client';\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 transportType: TransportType;\n\n abstract version: string;\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, analytics, versions, 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 const analytics = {\n ...opts.analytics,\n ...(partial.analytics ?? {}),\n };\n if (opts.analytics?.enabled === false) {\n analytics.enabled = false;\n }\n\n this.options = {\n ...opts,\n api: {\n ...opts.api,\n supportedNetworks: {\n ...opts.api.supportedNetworks,\n ...(partial.api?.supportedNetworks ?? {}),\n },\n },\n versions: {\n ...opts.versions,\n ...(partial.versions ?? {}),\n },\n analytics: {\n ...analytics,\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\nconst NATIVE_METAMASK_EIP6963_RDNS = new Set([\n 'io.metamask',\n 'io.metamask.mobile',\n]);\n\nfunction isNotBrowser(): boolean {\n if (typeof window === 'undefined') {\n return true;\n }\n if (!window?.navigator) {\n return true;\n }\n return navigator?.product === 'ReactNative';\n}\n\nfunction isReactNative(): boolean {\n // Modern Hermes-based RN: window is undefined, but global.navigator.product is set.\n // This check must come first so getPlatformType() resolves to ReactNative rather\n // than NonBrowser when isNotBrowser() would otherwise catch this case.\n if (\n typeof global !== 'undefined' &&\n global?.navigator?.product === 'ReactNative'\n ) {\n return true;\n }\n\n // Legacy RN environments where window === global\n const hasWindowNavigator =\n typeof window !== 'undefined' && window.navigator !== undefined;\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 // Keep the same window reference if the global is torn down before timeout.\n const targetWindow = window;\n\n const handler = (event: any) => {\n if (event?.detail?.info?.rdns) {\n providers.push(event.detail);\n }\n };\n\n targetWindow.addEventListener('eip6963:announceProvider', handler);\n targetWindow.dispatchEvent(new Event('eip6963:requestProvider'));\n\n setTimeout(() => {\n // The window/global can be torn down before this timeout fires (e.g. test\n // environment teardown, SPA navigation), which makes the captured\n // reference's methods unavailable. Guard so the timer never throws an\n // unhandled exception; fall back to \"no extension\" when detection can't\n // complete.\n try {\n if (typeof targetWindow?.removeEventListener === 'function') {\n targetWindow.removeEventListener('eip6963:announceProvider', handler);\n }\n\n const hasMetaMask = providers.some(\n (provider) =>\n typeof provider?.info?.rdns === 'string' &&\n NATIVE_METAMASK_EIP6963_RDNS.has(provider.info.rdns),\n );\n\n resolve(hasMetaMask);\n } catch {\n resolve(false);\n }\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 getTransportType(): Promise<TransportType | null>;\n\n abstract setTransportType(transportType: TransportType): Promise<void>;\n\n abstract removeTransportType(): 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 @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 TransportType,\n} from '../../domain';\nimport { getPlatformType, RPCInvokeMethodErr } from '../../domain';\n\n/**\n * Tag describing the cause of a failed wallet action / connection. Surfaced\n * as the `failure_reason` property on `mmconnect_wallet_action_failed` and\n * `mmconnect_connection_failed` events so we can distinguish e.g. a transport\n * timeout from a wallet-side internal error in Mixpanel.\n *\n * Intentionally a string union (not a const enum) so callers stay free to\n * pass through a new bucket; the schema-side property is an open string for\n * the same reason.\n */\nexport type FailureReason =\n | 'transport_timeout'\n | 'transport_disconnect'\n | 'wallet_method_unsupported'\n | 'wallet_invalid_params'\n | 'wallet_internal_error'\n | 'wallet_unauthorized'\n | 'unrecognized_chain'\n | 'unknown';\n\n/**\n * Maximum length of `error_message_sample` after sanitisation. Mirrors the\n * `maxLength: 200` constraint declared in the analytics-api `api.spec.yml`.\n */\nconst ERROR_MESSAGE_SAMPLE_MAX_LENGTH = 200;\n\n/**\n * Patterns scrubbed from `error_message_sample` before it leaves the SDK.\n * The goal is to surface enough error context for triage in Mixpanel\n * without leaking PII / wallet addresses / RPC endpoints / large numeric\n * quantities, across any chain the SDK might route to.\n *\n * Order matters. URLs are stripped early so address-shaped path segments\n * inside URLs aren't re-mangled by later passes. Specific patterns run\n * before broad ones (e.g. EVM `0x{40}` before the generic long-hex pass)\n * so the longer / more specific match wins. Bech32 runs before generic\n * Base58 because the two alphabets partially overlap — Bech32 includes\n * `0` (which Base58 excludes) and Base58 includes `o`/`i`/`b`/`l` (which\n * Bech32 excludes) — so running Base58 first can chop off the tail of an\n * HRP-prefixed Bech32 address at the first `l`/`i`/`o`/`b` and leave the\n * suffix unscrubbed. Decimal-number scrubbing runs last so it doesn't\n * fragment hex / Base58 tokens that contain digit runs.\n */\nconst SANITISE_PATTERNS: { pattern: RegExp; replacement: string }[] = [\n // EVM-style 20-byte hex addresses (e.g. `0x` + 40 hex chars).\n { pattern: /0x[a-fA-F0-9]{40}/gu, replacement: '<addr>' },\n // Other long hex blobs: tx hashes, signatures, raw byte strings, large\n // hex amounts. 16+ hex chars catches 32-byte hashes/signatures without\n // snagging EVM method selectors (8 chars) or short hex codes.\n { pattern: /(?:0x)?[a-fA-F0-9]{16,}/gu, replacement: '<hex>' },\n // URLs of any scheme up to the first whitespace / quote / closing paren.\n // Catches RPC endpoints, dapp deeplinks, query strings with secrets.\n { pattern: /https?:\\/\\/[^\\s\"')]+/gu, replacement: '<url>' },\n // Bech32 addresses: short HRP (1-10 lowercase chars) + `1` separator +\n // ≥38 chars of Bech32 data alphabet `[ac-hj-np-z02-9]` (excludes the\n // look-alike chars `b`, `i`, `o`, `1`). Covers Bitcoin SegWit\n // (`bc1…`/`tb1…`) and Cosmos-SDK chains (`cosmos1…`, `osmo1…`,\n // `juno1…`, `inj1…`, etc.) without enumerating every HRP. Runs before\n // the Base58 pattern below — see header comment for why.\n {\n pattern: /\\b[a-z]{1,10}1[ac-hj-np-z02-9]{38,}\\b/gu,\n replacement: '<addr>',\n },\n // Base58 tokens (32+ chars, Base58 alphabet `[1-9A-HJ-NP-Za-km-z]`).\n // Covers Solana pubkeys (32-44 chars), Solana tx signatures (~88 chars),\n // and Bitcoin Base58 addresses ≥32 chars. The 32-char floor and `\\b`\n // word boundary keep English words and shorter alphanumerics safe.\n {\n pattern: /\\b[1-9A-HJ-NP-Za-km-z]{32,}\\b/gu,\n replacement: '<addr>',\n },\n // Long decimal numbers — token amounts, gas units, timestamps, lamports.\n // 10+ digits catches typical chain quantities without affecting JSON-RPC\n // codes (-32601, 4001, etc.) or short numeric IDs.\n { pattern: /\\d{10,}/gu, replacement: '<num>' },\n];\n\n/**\n * Sanitises an error message for inclusion in analytics. Strips wallet\n * addresses (EVM hex, Solana / Bitcoin Base58, Bech32), long hex blobs,\n * URLs, and large decimal numbers, then truncates to\n * {@link ERROR_MESSAGE_SAMPLE_MAX_LENGTH} characters. Returns `undefined`\n * if there's no message to sample.\n *\n * @param message - Raw error message\n * @returns A safe-to-emit short string, or `undefined`\n */\nexport function sanitiseErrorMessage(\n message: string | undefined,\n): string | undefined {\n if (!message) {\n return undefined;\n }\n let sanitised = message;\n for (const { pattern, replacement } of SANITISE_PATTERNS) {\n sanitised = sanitised.replace(pattern, replacement);\n }\n if (sanitised.length > ERROR_MESSAGE_SAMPLE_MAX_LENGTH) {\n // Trim and mark as truncated so consumers can tell vs. naturally short\n // messages. The trailing ellipsis fits inside the maxLength budget.\n sanitised = `${sanitised.slice(0, ERROR_MESSAGE_SAMPLE_MAX_LENGTH - 1)}…`;\n }\n return sanitised;\n}\n\n/**\n * Pulls the most informative `code` / `message` pair out of an error,\n * unwrapping `RPCInvokeMethodErr` so the wallet-side code (e.g. 4001) is\n * visible to classifiers instead of being hidden behind the SDK's static\n * `code: 53`. Falls back to the outer error if there is no inner wallet code.\n *\n * @param error - The error object to inspect\n * @returns The most relevant `{ code, message }` pair we can extract\n */\nfunction getUnwrappedErrorDetails(error: unknown): {\n code: number | undefined;\n message: string;\n} {\n if (typeof error !== 'object' || error === null) {\n return { code: undefined, message: '' };\n }\n\n if (error instanceof RPCInvokeMethodErr) {\n return {\n code: error.rpcCode ?? error.code,\n message: error.rpcMessage ?? error.message ?? '',\n };\n }\n\n const errorObj = error as { code?: number; message?: string };\n return {\n code: errorObj.code,\n message: errorObj.message ?? '',\n };\n}\n\n/**\n * Checks if an error represents a user rejection.\n *\n * Unwraps `RPCInvokeMethodErr` so the wallet's `code: 4001` survives the\n * SDK's transport-boundary wrapping (the outer error otherwise reports\n * `code: 53`, which would never match the heuristics here).\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 { code, message } = getUnwrappedErrorDetails(error);\n const errorMessage = message.toLowerCase();\n\n // EIP-1193 4001 \"User Rejected Request\" is the canonical rejection code.\n // Note: 4100 \"Unauthorized\" is deliberately NOT matched here. On multichain\n // sessions it's what the CAIP-25 permission layer returns when a method\n // isn't in the granted scope (the layer rejects it before the method\n // handler runs). That's a permission/support signal, not a user-driven\n // rejection — misclassifying it as `_rejected` hides genuine permission\n // issues from `_failed`.\n return (\n code === 4001 ||\n errorMessage.includes('reject') ||\n errorMessage.includes('denied') ||\n errorMessage.includes('cancel') ||\n // Narrow \"user …\" matches — bare \"user\" is too greedy (catches Account\n // Abstraction errors like \"user operation reverted\").\n errorMessage.includes('user rejected') ||\n errorMessage.includes('user denied') ||\n errorMessage.includes('user cancelled') ||\n errorMessage.includes('user canceled')\n );\n}\n\n/**\n * Classifies a failed wallet action / connection error into a short tag for\n * the `failure_reason` analytics property. Caller is expected to have already\n * established that the error is *not* a user rejection (use `isRejectionError`\n * for that branching).\n *\n * The taxonomy is deliberately producer-side-only — the schema accepts any\n * string — so we can add buckets here without an API migration. Once the\n * distribution stabilises we may convert the schema field to a closed enum.\n *\n * @param error - The error to classify\n * @returns A short, snake_case tag describing why the operation failed\n */\nexport function classifyFailureReason(error: unknown): FailureReason {\n if (typeof error !== 'object' || error === null) {\n return 'unknown';\n }\n\n const errorObj = error as { name?: string; message?: string };\n const errorName = errorObj.name ?? '';\n const errorMessageRaw = errorObj.message ?? '';\n const errorMessage = errorMessageRaw.toLowerCase();\n\n // Wallet-side JSON-RPC / EIP-1193 code is the strongest signal we have —\n // check it before any message-substring heuristics so a wallet error like\n // `{ code: 4900, message: 'Disconnected' }` doesn't get caught by the\n // transport-disconnect text match below. Unwraps `RPCInvokeMethodErr` so\n // the wallet's actual error code is visible.\n const { code } = getUnwrappedErrorDetails(error);\n if (typeof code === 'number') {\n // JSON-RPC 2.0 + EIP-1474 standard codes.\n if (code === -32601) {\n return 'wallet_method_unsupported';\n }\n if (code === -32602) {\n return 'wallet_invalid_params';\n }\n if (code === -32603) {\n return 'wallet_internal_error';\n }\n // Standard JSON-RPC server error range.\n if (code <= -32000 && code >= -32099) {\n return 'wallet_internal_error';\n }\n // EIP-1193 named provider codes — handled individually. Codes in the\n // 1000–4999 range that aren't matched here fall through to `unknown`.\n if (code === 4100) {\n // Unauthorized — most commonly fires when a method isn't in the\n // CAIP-25 scope's granted methods list (the multichain permission\n // layer rejects it before the method handler runs). Distinct from\n // a user rejection (4001) and worth tracking separately.\n return 'wallet_unauthorized';\n }\n if (code === 4200) {\n // Unsupported method — wallet handler exists but explicitly refuses.\n return 'wallet_method_unsupported';\n }\n if (code === 4902) {\n // Unrecognized chain ID — `wallet_switchEthereumChain` to a chain the\n // wallet hasn't been told about. MetaMask (extension + mobile) always\n // sets code 4902 on this error, so we don't need a message-substring\n // fallback below.\n return 'unrecognized_chain';\n }\n // Anything else in the EIP-1193 / EIP-1474 provider-defined range\n // (1000–4999) falls through to `unknown` — we can promote specific codes\n // into their own buckets later as the distribution stabilises, without a\n // schema migration. Two buckets for \"we don't know what this is\" adds\n // noise without insight.\n }\n\n // Transport-layer errors. Two shapes exist:\n // - `TransportTimeoutError` from `@metamask/multichain-api-client` (used by\n // MWP and the warmup paths of the default extension transport). It's a\n // subclass of `TransportError` so we match on the name field rather than\n // importing the symbol (the type lives in a runtime dependency that the\n // analytics utils shouldn't pull in directly).\n // - A plain `new Error('Request timeout')` thrown by `DefaultTransport`'s\n // own setTimeout. Indistinguishable from other errors without the message.\n if (\n errorName === 'TransportTimeoutError' ||\n errorMessageRaw === 'Request timeout' ||\n errorMessage.includes('timed out') ||\n errorMessage.includes('timeout')\n ) {\n return 'transport_timeout';\n }\n // Transport disconnect. Narrowed substring set so we don't snag wallet\n // error messages that happen to contain \"disconnect\" (e.g. EIP-1193\n // `4900 Disconnected`, which the wallet-code branch above already routed\n // to `unknown` per policy).\n if (\n errorName === 'TransportError' ||\n errorMessage.includes('not connected') ||\n errorMessage.includes('transport disconnect') ||\n errorMessage.includes('connection lost') ||\n errorMessage.includes('socket closed')\n ) {\n return 'transport_disconnect';\n }\n\n return 'unknown';\n}\n\n/**\n * Bundle of diagnostic properties attached to `mmconnect_*_failed` events:\n * the bucketed {@link FailureReason}, the raw wallet-side error code if\n * present, and a sanitised sample of the original message. All three are\n * derived from a single error so producers only need to call this once.\n *\n * `error_code` and `error_message_sample` are intentionally optional —\n * many SDK-internal errors (e.g. `'Transport not initialized'`) have\n * neither a numeric code nor a useful message; in that case the caller\n * should attach only `failure_reason`.\n */\nexport type ErrorDiagnostics = {\n failure_reason: FailureReason;\n error_code?: number;\n error_message_sample?: string;\n};\n\n/**\n * Computes the full set of diagnostic properties to attach to a\n * `mmconnect_*_failed` event from a single error. Combines\n * {@link classifyFailureReason}, the unwrapped wallet code, and a\n * sanitised message sample so producer call sites stay a single line.\n *\n * @param error - The error to inspect\n * @returns Diagnostics ready to spread into the event properties\n */\nexport function extractErrorDiagnostics(error: unknown): ErrorDiagnostics {\n const failureReason = classifyFailureReason(error);\n const { code, message } = getUnwrappedErrorDetails(error);\n const messageSample = sanitiseErrorMessage(message);\n return {\n failure_reason: failureReason,\n ...(typeof code === 'number' ? { error_code: code } : {}),\n ...(messageSample ? { error_message_sample: messageSample } : {}),\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_versions: Record<string, string>;\n dapp_id: string;\n platform: PlatformType;\n anon_id: string;\n}> {\n const dappId = getDappId(options.dapp);\n const platform = getPlatformType();\n const anonId = await storage.getAnonId();\n\n return {\n mmconnect_versions: options.versions ?? {},\n dapp_id: dappId,\n platform,\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 * @param transportType - The transport type to use for the analytics event\n * @param extra - Optional event-specific diagnostic properties. Used by\n * `mmconnect_wallet_action_failed` to attach the {@link ErrorDiagnostics}\n * bundle (`failure_reason`, `error_code`, `error_message_sample`).\n * @param extra.failure_reason - A short tag describing why the operation\n * failed; see `classifyFailureReason` and the `FailureReason` union.\n * @param extra.error_code - The raw wallet-side error code, if present.\n * @param extra.error_message_sample - A sanitised, truncated sample of the\n * original error message.\n * @returns Wallet action analytics properties\n */\nexport async function getWalletActionAnalyticsProperties(\n options: MultichainOptions,\n storage: StoreClient,\n invokeOptions: InvokeMethodOptions,\n transportType: TransportType,\n extra?: {\n failure_reason?: FailureReason;\n error_code?: number;\n error_message_sample?: string;\n },\n): Promise<{\n mmconnect_versions: Record<string, string>;\n dapp_id: string;\n method: string;\n caip_chain_id: string;\n anon_id: string;\n transport_type: TransportType;\n failure_reason?: FailureReason;\n error_code?: number;\n error_message_sample?: string;\n}> {\n const dappId = getDappId(options.dapp);\n const anonId = await storage.getAnonId();\n\n return {\n mmconnect_versions: options.versions ?? {},\n dapp_id: dappId,\n method: invokeOptions.request.method,\n caip_chain_id: invokeOptions.scope,\n anon_id: anonId,\n transport_type: transportType,\n ...(extra?.failure_reason ? { failure_reason: extra.failure_reason } : {}),\n ...(typeof extra?.error_code === 'number'\n ? { error_code: extra.error_code }\n : {}),\n ...(extra?.error_message_sample\n ? { error_message_sample: extra.error_message_sample }\n : {}),\n };\n}\n","/* eslint-disable @typescript-eslint/naming-convention -- __PACKAGE_VERSION__ is an esbuild define convention */\n\n// Value substituted by tsup at build time\ndeclare const __PACKAGE_VERSION__: string | undefined;\n\n// typeof guard needed: Metro (React Native) bundles TS source directly,\n// bypassing the tsup build that substitutes __PACKAGE_VERSION__.\nexport const packageVersion: string =\n typeof __PACKAGE_VERSION__ === 'undefined' ? 'unknown' : __PACKAGE_VERSION__;\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 packageVersion;\n}\n\nexport {\n classifyFailureReason,\n getWalletActionAnalyticsProperties,\n isRejectionError,\n} from '../../multichain/utils/analytics';\nexport type { FailureReason } 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","/* 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","export const EIP_1193_PROVIDER_STREAM_NAME = 'metamask-provider';\nexport const MULTICHAIN_PROVIDER_STREAM_NAME = 'metamask-multichain-provider';\n","/* eslint-disable consistent-return */\n/* eslint-disable @typescript-eslint/no-misused-promises */\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 */\nimport type {\n Session,\n SessionRequest,\n} 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';\nimport { createDeferredPromise } from '@metamask/utils';\n\nimport {\n createLogger,\n getPlatformType,\n PlatformType,\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 getResponseError(messagePayload: Record<string, unknown>): unknown {\n if ('error' in messagePayload && messagePayload.error) {\n return messagePayload.error;\n }\n\n const { result } = messagePayload;\n if (\n typeof result === 'object' &&\n result !== null &&\n 'error' in result &&\n result.error &&\n this.isErrorPayload(result.error)\n ) {\n return result.error;\n }\n\n return undefined;\n }\n\n private isErrorPayload(errorPayload: unknown): boolean {\n if (errorPayload instanceof Error) {\n return true;\n }\n\n const errorData = errorPayload as Record<string, unknown>;\n return (\n typeof errorData?.code === 'number' &&\n typeof errorData?.message === 'string'\n );\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 const responseError = this.getResponseError(messagePayload);\n\n if (responseError) {\n this.pendingRequests.delete(messagePayload.id);\n request.reject(this.parseWalletError(responseError));\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 async #onResumeHandler(options?: {\n scopes: Scope[];\n caipAccountIds: CaipAccountId[];\n forceRequest?: boolean;\n }): Promise<void> {\n await this.waitForWalletSessionIfNotCached();\n const sessionResponse = await this.request({ method: 'wallet_getSession' });\n if (sessionResponse.error) {\n throw new Error(sessionResponse.error.message);\n }\n let walletSession = sessionResponse.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 (options.forceRequest || !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 throw 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 // Hitting this branch implies that the MWP session was established,\n // but the user has not yet accepted the initial wallet_createSession approval,\n // but the page has refreshed and we've lost that previous context and so we\n // are trying to recover by making a new wallet_createSession request.\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 throw 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 }\n\n async #resumeSession(\n session: Session,\n options?: {\n scopes: Scope[];\n caipAccountIds: CaipAccountId[];\n forceRequest?: boolean;\n },\n ): Promise<void> {\n // Captured before any work begins so that a `session_request` event fired\n // during resume (e.g. when the resume path falls through to\n // `wallet_createSession`) doesn't skew the timeout decision.\n const isContinuingPriorAttempt =\n (await this.getStoredPendingSessionRequest()) !== null;\n\n const resumeDeferred = createDeferredPromise();\n const runOnResumeHandler = async (): Promise<void> => {\n try {\n resumeDeferred.resolve(await this.#onResumeHandler(options));\n } catch (err) {\n resumeDeferred.reject(err);\n }\n };\n\n if (this.dappClient.state === 'CONNECTED') {\n runOnResumeHandler();\n } else {\n this.dappClient.once('connected', runOnResumeHandler);\n this.dappClient\n .resume(session.id ?? '')\n .catch((err) => resumeDeferred.reject(err));\n }\n\n // The resume path can fall through to `wallet_createSession` (forceRequest,\n // recovery from a missing wallet session, or a scope/account change), which\n // requires a human to approve in the wallet. Use the longer\n // `connectionTimeout` for those flows; only use the shorter `resumeTimeout`\n // when we're continuing an in-flight prior attempt.\n const timeoutDeferred = createDeferredPromise<never>();\n const timeout = setTimeout(\n () => timeoutDeferred.reject(new TransportTimeoutError()),\n isContinuingPriorAttempt\n ? this.options.resumeTimeout\n : this.options.connectionTimeout,\n );\n\n const cleanup = () => this.dappClient.off('connected', runOnResumeHandler);\n\n return Promise.race([\n resumeDeferred.promise,\n timeoutDeferred.promise,\n ]).finally(() => {\n clearTimeout(timeout);\n cleanup();\n });\n }\n\n /**\n * Starts a brand-new MWP session via `wallet_createSession`. Registers a\n * one-shot message handler that resolves on the wallet's response, races\n * the result against an internal timeout, and always tears down the\n * message listener when settled.\n *\n * If a prior connection attempt is still pending in storage (e.g. across a\n * page reload) the shorter `resumeTimeout` is used, since we're continuing\n * that in-flight attempt rather than starting from scratch.\n *\n * @param options - The session options.\n * @param options.scopes - The CAIP-2 scopes requested for the new session.\n * @param options.caipAccountIds - The CAIP-10 account IDs to associate with the session.\n * @param options.sessionProperties - Optional MWP session properties forwarded to the wallet.\n * @returns A promise that resolves when the wallet acknowledges the session,\n * or rejects on error / timeout.\n */\n async #startSession(options?: {\n scopes: Scope[];\n caipAccountIds: CaipAccountId[];\n sessionProperties?: SessionProperties;\n }): Promise<void> {\n const { dappClient } = this;\n\n // Captured before any work begins so that the session_request event fired\n // by `dappClient.connect()` (which overwrites the stored value) doesn't\n // skew the timeout decision.\n const isContinuingPriorAttempt =\n (await this.getStoredPendingSessionRequest()) !== null;\n\n const connDeferred = createDeferredPromise();\n\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 let handler: ((message: unknown) => Promise<void>) | undefined;\n const removeHandler = (): void => {\n if (handler) {\n this.dappClient.off('message', handler);\n handler = undefined;\n }\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 handler = async (message: unknown): 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 const responseError = this.getResponseError(messagePayload);\n\n // Handle error response (e.g., user rejected the connection)\n if (responseError) {\n connDeferred.reject(this.parseWalletError(responseError));\n return;\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 connDeferred.resolve();\n };\n\n this.dappClient.on('message', handler);\n\n const platformType = getPlatformType();\n const isQRCodeFlow = [\n PlatformType.DesktopWeb,\n PlatformType.NonBrowser,\n ].includes(platformType);\n\n const initialPayload = {\n name: MULTICHAIN_PROVIDER_STREAM_NAME,\n data: request,\n };\n\n dappClient\n .connect({\n mode: 'trusted',\n initialPayload: isQRCodeFlow ? undefined : initialPayload,\n })\n .then(async () => {\n if (isQRCodeFlow) {\n return dappClient.sendRequest(initialPayload);\n }\n return undefined;\n })\n .catch((error) => connDeferred.reject(error));\n\n const timeoutDeferred = createDeferredPromise<never>();\n const timeout = setTimeout(\n () => timeoutDeferred.reject(new TransportTimeoutError()),\n isContinuingPriorAttempt\n ? this.options.resumeTimeout\n : this.options.connectionTimeout,\n );\n\n return Promise.race([\n connDeferred.promise,\n timeoutDeferred.promise,\n ]).finally(() => {\n clearTimeout(timeout);\n removeHandler();\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 forceRequest?: boolean;\n }): Promise<void> {\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 connection = session\n ? this.#resumeSession(session, options)\n : this.#startSession(options);\n\n return connection\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 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 return this.dappClient.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 import(\n '@metamask/mobile-wallet-protocol-core'\n );\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","/* 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';\n\n/**\n * Creates an {@link IKeyManager} backed by the `eciesjs` library.\n *\n * The factory dynamically imports `eciesjs` so the heavy crypto dependency is\n * only loaded when MWP transport is actually used. The returned object closes\n * over the imported symbols, allowing synchronous methods like\n * `generateKeyPair` and `validatePeerKey` to work without a second await.\n *\n * @returns A ready-to-use key manager instance.\n */\nexport async function createKeyManager(): Promise<IKeyManager> {\n const { decrypt, encrypt, PrivateKey, PublicKey } = await import('eciesjs');\n\n return {\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}\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 no-restricted-globals -- Web modal uses document */\nimport type { MmInstallModalCustomEvent } from '@metamask/multichain-ui';\n\nimport { AbstractInstallModal } from '../base/AbstractInstallModal';\n\nexport class InstallModal extends AbstractInstallModal {\n renderQRCode(): void {\n // Not needed for web as its using install Modal\n }\n\n mount(): void {\n const { options } = this;\n const modal = document.createElement('mm-install-modal');\n\n modal.showInstallModal = options.showInstallModal;\n modal.addEventListener('close', (ev: Event) => {\n const { detail } = ev as MmInstallModalCustomEvent<{\n shouldTerminate?: boolean;\n }>;\n options.onClose(detail?.shouldTerminate);\n });\n modal.addEventListener(\n 'startDesktopOnboarding',\n options.startDesktopOnboarding,\n );\n modal.link = options.link;\n\n this.instance = modal;\n options.parentElement?.appendChild(modal);\n\n this.startExpirationCheck(options.connectionRequest);\n }\n\n unmount(): void {\n const { options, instance: modal } = this;\n this.stopExpirationCheck();\n if (modal && options.parentElement?.contains(modal)) {\n options.parentElement.removeChild(modal);\n this.instance = undefined;\n }\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","/* eslint-disable no-restricted-globals -- Browser storage adapter uses window.indexedDB */\n/* eslint-disable @typescript-eslint/naming-convention -- DB_NAME is a constant */\n/* eslint-disable @typescript-eslint/explicit-function-return-type -- Inferred types are sufficient */\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 @typescript-eslint/prefer-promise-reject-errors -- Custom error objects */\nimport { StoreAdapter } from '../../domain';\n\ntype KvStores = 'sdk-kv-store' | 'key-value-pairs';\n\nexport class StoreAdapterWeb extends StoreAdapter {\n static readonly stores: KvStores[] = ['sdk-kv-store', 'key-value-pairs'];\n\n static readonly DB_NAME = 'mmconnect';\n\n readonly platform = 'web';\n\n readonly dbPromise: Promise<IDBDatabase>;\n\n private get internal(): IDBFactory {\n if (typeof window === 'undefined' || !window.indexedDB) {\n throw new Error('indexedDB is not available in this environment');\n }\n return window.indexedDB;\n }\n\n constructor(\n dbNameSuffix: `-${string}` = '-kv-store',\n private readonly storeName: KvStores = StoreAdapterWeb.stores[0],\n ) {\n super();\n\n const dbName = `${StoreAdapterWeb.DB_NAME}${dbNameSuffix}`;\n this.dbPromise = new Promise((resolve, reject) => {\n try {\n const request = this.internal.open(dbName, 1);\n request.onerror = () => reject(new Error('Failed to open IndexedDB.'));\n request.onsuccess = () => resolve(request.result);\n request.onupgradeneeded = () => {\n const db = request.result;\n for (const name of StoreAdapterWeb.stores) {\n if (!db.objectStoreNames.contains(name)) {\n db.createObjectStore(name);\n }\n }\n };\n } catch (error) {\n reject(error);\n }\n });\n }\n\n async get(key: string): Promise<string | null> {\n const { storeName } = this;\n const db = await this.dbPromise;\n return new Promise((resolve, reject) => {\n try {\n const tx = db.transaction(storeName, 'readonly');\n const store = tx.objectStore(storeName);\n const request = store.get(key);\n request.onerror = () =>\n reject(new Error('Failed to get value from IndexedDB.'));\n request.onsuccess = () => resolve((request.result as string) ?? null);\n } catch (error) {\n reject(error);\n }\n });\n }\n\n async set(key: string, value: string): Promise<void> {\n const { storeName } = this;\n const db = await this.dbPromise;\n return new Promise((resolve, reject) => {\n try {\n const tx = db.transaction(storeName, 'readwrite');\n const store = tx.objectStore(storeName);\n const request = store.put(value, key);\n request.onerror = () =>\n reject(new Error('Failed to set value in IndexedDB.'));\n request.onsuccess = () => resolve();\n } catch (error) {\n reject(error);\n }\n });\n }\n\n async delete(key: string): Promise<void> {\n const { storeName } = this;\n const db = await this.dbPromise;\n return new Promise((resolve, reject) => {\n try {\n const tx = db.transaction(storeName, 'readwrite');\n const store = tx.objectStore(storeName);\n const request = store.delete(key);\n request.onerror = () =>\n reject(new Error('Failed to delete value from IndexedDB.'));\n request.onsuccess = () => resolve();\n } catch (error) {\n reject(error);\n }\n });\n }\n}\n","/* eslint-disable import-x/no-nodejs-modules -- Buffer polyfill requires Node.js module */\n/**\n * Buffer polyfill for browser and React Native environments.\n *\n * This shim sets up the global Buffer object before any code that depends on it runs.\n * It's imported at the top of platform-specific entry points (index.browser.ts, index.native.ts).\n *\n * Node.js environments already have Buffer globally available, so this is a no-op there.\n */\nimport { Buffer } from 'buffer';\n\nimport { getGlobalObject } from '../multichain/utils';\n\n// Only set Buffer if it's not already defined (avoid overwriting Node.js native Buffer)\nconst globalObj = getGlobalObject();\nglobalObj.Buffer ??= Buffer;\n","/* eslint-disable import-x/no-unassigned-import -- Polyfill must be imported first */\n// Buffer polyfill must be imported first to set up globalThis.Buffer\nimport './polyfills/buffer-shim';\n\nimport 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/web');\n let storage: StoreClient;\n if (options.storage) {\n storage = options.storage;\n } else {\n const { StoreAdapterWeb } = await import('./store/adapters/web');\n const adapter = new StoreAdapterWeb();\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 type { SessionRequest } from '@metamask/mobile-wallet-protocol-core';\nimport type { 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';\nimport { createDeferredPromise } 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 extractErrorDiagnostics,\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 {\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\ntype ReusableMultichainSingleton = {\n mergeOptions: (options: MultichainOptions) => void;\n options: MultichainOptions;\n storage: StoreClient;\n version?: string;\n};\n\n/**\n * Applies analytics defaults while preserving explicitly disabled analytics.\n *\n * @param analyticsOptions - Partial analytics options supplied by the consumer.\n * @returns Analytics options with defaults applied.\n */\nfunction normalizeAnalyticsOptions(\n analyticsOptions: MultichainOptions['analytics'],\n): Required<NonNullable<MultichainOptions['analytics']>> {\n return {\n ...(analyticsOptions ?? {}),\n enabled: analyticsOptions?.enabled ?? true,\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n integrationType: analyticsOptions?.integrationType || 'direct',\n };\n}\n\n/**\n * Checks whether dapp-side analytics are enabled for the SDK instance.\n *\n * @param options - Current SDK options.\n * @returns Whether analytics events should be collected and sent.\n */\nfunction isAnalyticsEnabled(options: MultichainOptions): boolean {\n return options.analytics?.enabled !== false;\n}\n\n/**\n * Sets up analytics globals using only APIs available on existing singleton\n * instances, including instances created by older bundled package copies.\n *\n * @param options - Current SDK options.\n * @param storage - Storage client for retrieving the anonymous ID.\n * @param setAnonId - Optional callback for updating the current instance anon ID.\n */\nasync function setupAnalyticsGlobals(\n options: MultichainOptions,\n storage: StoreClient,\n setAnonId?: (anonId: string | undefined) => void,\n): Promise<void> {\n if (!isAnalyticsEnabled(options)) {\n setAnonId?.(undefined);\n analytics.disable();\n return;\n }\n\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 dappId = getDappId(options.dapp);\n const anonId = await storage.getAnonId();\n setAnonId?.(anonId);\n\n const { integrationType } = options.analytics ?? {\n integrationType: '',\n };\n analytics.setGlobalProperty('mmconnect_versions', options.versions ?? {});\n analytics.setGlobalProperty('dapp_id', dappId);\n analytics.setGlobalProperty('anon_id', anonId);\n analytics.setGlobalProperty('platform', platform);\n if (integrationType) {\n analytics.setGlobalProperty('integration_types', [integrationType]);\n }\n analytics.enable();\n}\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 #transportType?: TransportType;\n\n public _status: ConnectionStatus = 'pending';\n\n #listener: (() => void | Promise<void>) | undefined;\n\n #anonId: string | 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.emit('stateChanged', value);\n }\n\n get provider(): MultichainApiClient<RPCAPI> {\n return this.#provider;\n }\n\n #transportOrThrow(): 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 transportType(): TransportType {\n return this.#transportType ?? TransportType.UNKNOWN;\n }\n\n get storage(): StoreClient {\n return this.options.storage;\n }\n\n get version(): string {\n return getVersion();\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 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: normalizeAnalyticsOptions(options.analytics),\n versions: {\n 'connect-multichain': getVersion(),\n ...(options.versions ?? {}),\n },\n };\n\n super(allOptions);\n\n this.#providerTransportWrapper = new MultichainApiClientWrapperTransport(\n this,\n () => this.#transport,\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 // `analytics`, `versions`, `ui.*`, `mobile.*`, `transport.extensionId`,\n // `debug`. Take note that the value for `dapp` is not merged as it does not\n // make sense for subsequent calls to `createMultichainClient` to have a\n // 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 | ReusableMultichainSingleton>\n | undefined;\n if (existing) {\n const instance = await existing;\n\n if (instance.version !== getVersion()) {\n console.warn(\n `MetaMask Connect does not support using multiple versions of @metamask/connect-multichain. ` +\n `Attempted to create a new instance with version ${getVersion()}, but an existing ${instance.version} singleton was already initialized. ` +\n `Using the existing ${instance.version} singleton. This is NOT supported and may lead to unexpected behavior. ` +\n `Please ensure there is only one version of @metamask/connect-multichain package resolved in your application.`,\n );\n }\n\n instance.mergeOptions(options);\n if (instance instanceof MetaMaskConnectMultichain) {\n await instance.#setupAnalytics();\n } else {\n await setupAnalyticsGlobals(instance.options, instance.storage);\n }\n if (options.debug) {\n enableDebug('metamask-sdk:*');\n }\n return instance as MetaMaskConnectMultichain;\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 })().catch((error) => {\n globalObject[SINGLETON_KEY] = undefined;\n console.error('Error initializing MetaMaskConnectMultichain', error);\n throw error;\n });\n\n globalObject[SINGLETON_KEY] = instancePromise;\n\n return instancePromise;\n }\n\n /**\n * Sets up analytics globals for the current SDK options.\n */\n async #setupAnalytics(): Promise<void> {\n await setupAnalyticsGlobals(this.options, this.storage, (anonId) => {\n this.#anonId = anonId;\n });\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<ExtendedTransport | undefined> {\n const transportType = await this.storage.getTransportType();\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.#transportType = TransportType.Browser;\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 { MWPTransport } = await import('./transports/mwp');\n const apiTransport = new MWPTransport(dappClient, kvstore);\n this.#dappClient = dappClient;\n this.#transport = apiTransport;\n this.#transportType = TransportType.MWP;\n this.#providerTransportWrapper.setupTransportNotificationListener();\n this.#listener = apiTransport.onNotification(\n this.#onTransportNotification.bind(this),\n );\n return apiTransport;\n }\n\n await this.storage.removeTransportType();\n }\n\n return undefined;\n }\n\n async #setupTransport(): Promise<void> {\n const transport = await this.#getStoredTransport();\n if (transport) {\n if (!transport.isConnected()) {\n this.status = 'connecting';\n await transport.connect();\n }\n this.status = 'connected';\n if (this.#transportType === TransportType.MWP) {\n await this.storage.setTransportType(TransportType.MWP);\n } else {\n await this.storage.setTransportType(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.#transportOrThrow().init();\n } catch (error) {\n console.error('Passive init failed:', error);\n }\n }\n }\n }\n\n #buildConnectionMetadata(): ConnectionRequest['metadata'] {\n const metadata: ConnectionRequest['metadata'] = {\n dapp: this.options.dapp,\n sdk: { version: getVersion(), platform: getPlatformType() },\n };\n if (isAnalyticsEnabled(this.options) && this.#anonId) {\n metadata.analytics = { remote_session_id: this.#anonId };\n }\n return metadata;\n }\n\n async #init(): Promise<void> {\n try {\n await this.#setupAnalytics();\n await this.#setupTransport();\n } catch (error) {\n await this.storage.removeTransportType();\n this.status = 'pending';\n logger('MetaMaskSDK error during initialization', error);\n }\n }\n\n async #createDappClient(): Promise<DappClient> {\n const [mwpCore, { DappClient: DappClientClass }, { createKeyManager }] =\n await Promise.all([\n import('@metamask/mobile-wallet-protocol-core'),\n import('@metamask/mobile-wallet-protocol-dapp-client'),\n import('./transports/mwp/KeyManager'),\n ]);\n const keymanager = await createKeyManager();\n\n const { adapter: kvstore } = this.options.storage;\n const sessionstore = await mwpCore.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 mwpCore.WebSocketTransport.create({\n url: MWP_RELAY_URL,\n kvstore,\n websocket,\n });\n const dappClient = new DappClientClass({\n transport,\n sessionstore,\n keymanager,\n });\n return dappClient;\n }\n\n async #setupMWP(): Promise<void> {\n if (this.#transportType === TransportType.MWP) {\n return;\n }\n const { adapter: kvstore } = this.options.storage;\n const dappClient = await this.#createDappClient();\n this.#dappClient = dappClient;\n const { MWPTransport } = await import('./transports/mwp');\n const apiTransport = new MWPTransport(dappClient, kvstore);\n this.#transport = apiTransport;\n this.#transportType = TransportType.MWP;\n this.#providerTransportWrapper.setupTransportNotificationListener();\n this.#listener = apiTransport.onNotification(\n this.#onTransportNotification.bind(this),\n );\n await this.storage.setTransportType(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.removeTransportType();\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 const completion = createDeferredPromise();\n\n const createConnectionRequest = async (): Promise<ConnectionRequest> => {\n if (\n this.dappClient.state === 'CONNECTED' ||\n this.dappClient.state === 'CONNECTING'\n ) {\n await this.dappClient.disconnect();\n }\n\n // The session_request event carries the pending request needed to build\n // the deeplink / QR code. We resolve this deferred when it fires.\n const sessionRequestDeferred = createDeferredPromise<ConnectionRequest>();\n this.dappClient.on(\n 'session_request',\n (sessionRequest: SessionRequest) => {\n sessionRequestDeferred.resolve({\n sessionRequest,\n metadata: this.#buildConnectionMetadata(),\n });\n },\n );\n\n // Start the connection flow in the background — it will eventually emit\n // session_request (resolving sessionRequestDeferred) and then either\n // succeed (handled by the successCallback below) or fail (rejecting\n // the outer completion deferred).\n this.#transportOrThrow()\n .connect({ scopes, caipAccountIds, sessionProperties })\n .then(async () => {\n await this.options.ui.factory.unload();\n this.options.ui.factory.modal?.unmount();\n this.status = 'connected';\n await this.storage.setTransportType(TransportType.MWP);\n })\n .catch(async (error) => {\n const { ProtocolError, ErrorCode } = await import(\n '@metamask/mobile-wallet-protocol-core'\n );\n if (error instanceof ProtocolError) {\n if (error.code !== ErrorCode.REQUEST_EXPIRED) {\n this.status = 'disconnected';\n await this.options.ui.factory.unload(error);\n completion.reject(error);\n }\n // If the request is expired the QR code is automatically regenerated — ignore this case\n } else {\n this.status = 'disconnected';\n const normalizedError =\n error instanceof Error ? error : new Error(String(error));\n await this.options.ui.factory.unload(normalizedError);\n completion.reject(normalizedError);\n }\n });\n\n return sessionRequestDeferred.promise;\n };\n\n this.options.ui.factory\n .renderInstallModal(\n desktopPreferred,\n createConnectionRequest,\n async (error?: Error) => {\n if (error) {\n await this.storage.removeTransportType();\n completion.reject(error);\n } else {\n await this.storage.setTransportType(TransportType.MWP);\n completion.resolve();\n }\n },\n (uri: string) => {\n this.emit('display_uri', uri);\n },\n )\n .catch((error) => {\n completion.reject(\n error instanceof Error ? error : new Error(String(error)),\n );\n });\n\n return completion.promise;\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 if (\n this.dappClient.state === 'CONNECTED' ||\n this.dappClient.state === 'CONNECTING'\n ) {\n await this.dappClient.disconnect().catch(() => undefined);\n }\n\n // Listen for session_request to generate and emit the QR code link.\n // Captured as a named ref so the listener can be removed when the\n // connection settles — otherwise each #headlessConnect() call would leak\n // a listener that re-emits `display_uri` for every future session_request.\n const onSessionRequest = (sessionRequest: SessionRequest): void => {\n const connectionRequest: ConnectionRequest = {\n sessionRequest,\n metadata: this.#buildConnectionMetadata(),\n };\n const deeplink =\n this.options.ui.factory.createConnectionDeeplink(connectionRequest);\n this.emit('display_uri', deeplink);\n };\n this.dappClient.on('session_request', onSessionRequest);\n\n try {\n await this.#transportOrThrow().connect({\n scopes,\n caipAccountIds,\n sessionProperties,\n });\n this.status = 'connected';\n await this.storage.setTransportType(TransportType.MWP);\n } catch (error) {\n const { ProtocolError } = await import(\n '@metamask/mobile-wallet-protocol-core'\n );\n this.status = 'disconnected';\n await this.storage.removeTransportType();\n // In headless mode, we don't auto-regenerate QR codes since there's no modal to display them\n if (error instanceof ProtocolError || error instanceof Error) {\n throw error;\n }\n throw new Error(String(error));\n } finally {\n this.dappClient.off('session_request', onSessionRequest);\n }\n }\n\n async #setupDefaultTransport(\n options: { persist?: boolean } = { persist: true },\n ): Promise<DefaultTransport> {\n if (this.#transportType === TransportType.Browser) {\n return this.#transport as DefaultTransport;\n }\n\n if (options?.persist) {\n await this.storage.setTransportType(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.#transportType = TransportType.Browser;\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.#transportOrThrow().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: this.#buildConnectionMetadata(),\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.#transportOrThrow()\n .connect({ scopes, caipAccountIds, sessionProperties })\n .then(resolve)\n .catch(async (error) => {\n await this.storage.removeTransportType();\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 if (isAnalyticsEnabled(this.options)) {\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 }\n return undefined; // explicitly return `undefined` to avoid eslintpromise/always-return\n })\n .catch(async (error) => {\n this.status = 'disconnected';\n if (isAnalyticsEnabled(this.options)) {\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 ...extractErrorDiagnostics(error),\n });\n }\n } catch {\n logger('Error tracking connection failed/rejected event', error);\n }\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 if (isAnalyticsEnabled(this.options)) {\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\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.#transportType === TransportType.MWP) {\n return this.storage.setTransportType(TransportType.MWP);\n }\n return this.storage.setTransportType(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 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.removeTransportType();\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.#transportType = 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 = this.#transportOrThrow();\n const { options } = this;\n\n const rpcClient = new RpcClient(options, this.#sdkInfo);\n const requestRouter = new RequestRouter(\n transport,\n rpcClient,\n options,\n this.#transportType ?? TransportType.UNKNOWN,\n );\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.#transportOrThrow().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: this.#buildConnectionMetadata(),\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: SessionData = { 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(\n 'wallet_sessionChanged',\n (response.result as SessionData | undefined) ?? emptySession,\n );\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 EIP1193_PASSTHROUGH_METHODS,\n type ExtendedTransport,\n type InvokeMethodOptions,\n isSecure,\n type MultichainOptions,\n RPC_HANDLED_METHODS,\n RPCInvokeMethodErr,\n SDK_HANDLED_METHODS,\n type TransportType,\n} from '../../domain';\nimport { openDeeplink } from '../utils';\nimport {\n extractErrorDiagnostics,\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 * Normalizes unknown invocation errors to the router error type.\n *\n * @param error - Unknown error thrown during method execution.\n * @returns Error instance surfaced by invokeMethod.\n */\nfunction toRPCInvokeMethodErr(error: unknown): RPCInvokeMethodErr {\n if (error instanceof RPCInvokeMethodErr) {\n return error;\n }\n const castError = error as { message?: string; code?: number };\n return new RPCInvokeMethodErr(\n castError.message ?? 'Unknown error',\n castError.code,\n );\n}\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 private readonly transportType: TransportType,\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 (EIP1193_PASSTHROUGH_METHODS.has(method)) {\n return this.handleWithEip1193Passthrough(options);\n }\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 EIP-1193 / legacy provider methods (e.g. `wallet_addEthereumChain`,\n * `wallet_switchEthereumChain`, `eth_accounts`) directly to the underlying\n * transport's `sendEip1193Message`, bypassing the multichain\n * `wallet_invokeMethod` envelope. These methods are wallet-side concerns the\n * Multichain API does not model, so we forward the raw `{ method, params }`\n * payload and return the wallet's full JSON-RPC response envelope unchanged.\n *\n * Analytics tracking is intentionally skipped here: ecosystem clients\n * (e.g. `connect-evm`) emit their own `wallet_action_*` events around these\n * passthrough calls, and adding router-level tracking would double-count.\n *\n * @param options\n */\n private async handleWithEip1193Passthrough(\n options: InvokeMethodOptions,\n ): Promise<Json> {\n const response = await this.transport.sendEip1193Message({\n method: options.request.method,\n params: options.request.params,\n });\n // Note that this result object will not be in the same shape as the wallet's wallet_invokeMethod response envelope.\n // This is a purposeful deviation. EIP1193_PASSTHROUGH_METHODS are only meant to be called via the MultichainClient.invokeMethod()\n // by our connect-evm package. No other external callers should be calling these methods through this entry point. These methods should not be\n // documented as part of the MultichainClient.invokeMethod().\n return response.result as Json;\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 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 if (this.config.analytics?.enabled === false) {\n try {\n return await execute();\n } catch (error) {\n throw toRPCInvokeMethodErr(error);\n }\n }\n\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, error);\n }\n throw toRPCInvokeMethodErr(error);\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 this.transportType,\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 this.transportType,\n );\n analytics.track('mmconnect_wallet_action_succeeded', props);\n }\n\n /**\n * Tracks wallet action failed event.\n *\n * @param options - The invoke method options.\n * @param error - The error that caused the failure (used to classify the\n * `failure_reason` property on the event).\n */\n async #trackWalletActionFailed(\n options: InvokeMethodOptions,\n error: unknown,\n ): Promise<void> {\n const props = await getWalletActionAnalyticsProperties(\n this.config,\n this.config.storage,\n options,\n this.transportType,\n extractErrorDiagnostics(error),\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 this.transportType,\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 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 * 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 #parseWalletError(errorPayload: unknown): Error {\n const errorData = errorPayload as Record<string, unknown>;\n const error = new Error(\n typeof errorData.message === 'string'\n ? errorData.message\n : 'Request failed',\n ) as Error & { code?: number };\n\n if (typeof errorData.code === 'number') {\n error.code = errorData.code;\n }\n\n return error;\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(this.#parseWalletError(response.error));\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 'method' in responseData\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 // #transport.connect() internally calls disconnect() if the transport is connected,\n // and clears all listeners in the process. This ensures that we don't lose any listeners\n // by only connecting if we aren't already connected. Opting for this approach rather than a larger refactor\n // of who is responsible for managing listener setup and cleanup.\n if (!this.#transport.isConnected()) {\n await this.#transport.connect();\n }\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 const response = await this.#transport.request(request, options);\n\n if (response.error) {\n throw this.#parseWalletError(response.error);\n }\n\n return response as TResponse;\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 {\n ExtendedTransport,\n InvokeMethodOptions,\n RPCAPI,\n Scope,\n} 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 readonly #getTransport: () => ExtendedTransport | undefined;\n\n notificationListener: (() => void) | undefined;\n\n constructor(\n private readonly metamaskConnectMultichain: MetaMaskConnectMultichain,\n getTransport: () => ExtendedTransport | undefined,\n ) {\n this.#getTransport = getTransport;\n }\n\n isTransportDefined(): boolean {\n return this.#getTransport() !== undefined;\n }\n\n isTransportConnected(): boolean {\n return this.#getTransport()?.isConnected() ?? false;\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 const transport = this.#getTransport();\n if (!transport || this.notificationListener) {\n return;\n }\n this.notificationListener = transport.onNotification(\n this.notifyCallbacks.bind(this),\n );\n }\n\n // Purposely noop, resolves successfully. Actual connection is handled by the underlying client/transport.\n async connect(): Promise<void> {\n return Promise.resolve();\n }\n\n // Purposely noop, resolves successfully. Actual connection is handled by the underlying client/transport.\n async disconnect(): Promise<void> {\n return Promise.resolve();\n }\n\n // Purposely hardcoded to true. Actual connection is handled by the underlying client/transport.\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\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 await this.metamaskConnectMultichain.connect(\n scopes,\n accounts,\n createSessionParams.sessionProperties,\n );\n const transport = this.#getTransport();\n if (!transport) {\n throw new Error('Transport not initialized after connect');\n }\n return transport.request({\n method: 'wallet_getSession',\n });\n }\n\n async #walletGetSession(request: TransportRequestWithId) {\n const transport = this.#getTransport();\n if (!transport?.isConnected()) {\n return {\n jsonrpc: '2.0',\n id: request.id,\n result: {\n sessionScopes: {},\n },\n };\n }\n return transport.request({\n method: 'wallet_getSession',\n });\n }\n\n async #walletRevokeSession(request: TransportRequestWithId) {\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.isTransportConnected()) {\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 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 as parseTransportType } 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 getTransportType(): Promise<TransportType | null> {\n try {\n const transportType = await this.adapter.get('multichain-transport');\n if (!transportType) {\n return null;\n }\n return parseTransportType(transportType);\n } catch (err) {\n throw new StorageGetErr(\n this.adapter.platform,\n 'multichain-transport',\n err.message,\n );\n }\n }\n\n async setTransportType(transportType: TransportType): Promise<void> {\n try {\n await this.adapter.set('multichain-transport', transportType);\n } catch (err) {\n throw new StorageSetErr(\n this.adapter.platform,\n 'multichain-transport',\n err.message,\n );\n }\n }\n\n async removeTransportType(): 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 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 generateQRCode: async (request: ConnectionRequest) => {\n const newLink = this.createConnectionDeeplink(request);\n this.displayUriCallback?.(newLink);\n return newLink;\n },\n onClose: (shouldTerminate?: boolean) => {\n this.onCloseModal(shouldTerminate).catch((error) => {\n console.error('Failed to close modal:', error);\n });\n },\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 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 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":["logger","_a","TransportType","_a","analytics","_a","PlatformType","_a","init_utils","_a","init_utils","init_constants","providerErrors","DEFAULT_REQUEST_TIMEOUT","init_utils","init_constants","message","_a","init_utils","logger","init_utils","_a","web_exports","init_web","_a","init_utils","Buffer","analytics","createDeferredPromise","_a","init_utils","_a","_a","init_utils","_a","init_utils","_notificationCallbacks","_a","init_utils","logger","_a","analytics","isReactNative","_transport","init_fn","isEnabled","MWPTransport","createKeyManager","createDeferredPromise","init_utils","_a","otpCode","StoreAdapterWeb"]}
|