@dynamic-labs-sdk/metamask 1.31.0 → 1.31.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/dist/assertMetaMaskNetworkIsGranted/assertMetaMaskNetworkIsGranted.d.ts +37 -0
  2. package/dist/assertMetaMaskNetworkIsGranted/assertMetaMaskNetworkIsGranted.d.ts.map +1 -0
  3. package/dist/assertMetaMaskNetworkIsGranted/index.d.ts +2 -0
  4. package/dist/assertMetaMaskNetworkIsGranted/index.d.ts.map +1 -0
  5. package/dist/clearMetaMaskSessionStorage/clearMetaMaskSessionStorage.d.ts +6 -6
  6. package/dist/clearMetaMaskSessionStorage/clearMetaMaskSessionStorage.d.ts.map +1 -1
  7. package/dist/connectWithMetaMaskUri/connectWithMetaMaskUri.d.ts +3 -8
  8. package/dist/connectWithMetaMaskUri/connectWithMetaMaskUri.d.ts.map +1 -1
  9. package/dist/constants.d.ts +8 -0
  10. package/dist/constants.d.ts.map +1 -0
  11. package/dist/core.cjs +465 -0
  12. package/dist/core.cjs.map +1 -0
  13. package/dist/core.esm.js +459 -0
  14. package/dist/core.esm.js.map +1 -0
  15. package/dist/core.native.esm.js +459 -0
  16. package/dist/core.native.esm.js.map +1 -0
  17. package/dist/createMetaMaskWalletProviderEventEmitter/createMetaMaskWalletProviderEventEmitter.d.ts +44 -0
  18. package/dist/createMetaMaskWalletProviderEventEmitter/createMetaMaskWalletProviderEventEmitter.d.ts.map +1 -0
  19. package/dist/createMetaMaskWalletProviderEventEmitter/index.d.ts +3 -0
  20. package/dist/createMetaMaskWalletProviderEventEmitter/index.d.ts.map +1 -0
  21. package/dist/disconnectMetaMaskWalletProvider/disconnectMetaMaskWalletProvider.d.ts +56 -0
  22. package/dist/disconnectMetaMaskWalletProvider/disconnectMetaMaskWalletProvider.d.ts.map +1 -0
  23. package/dist/disconnectMetaMaskWalletProvider/index.d.ts +3 -0
  24. package/dist/disconnectMetaMaskWalletProvider/index.d.ts.map +1 -0
  25. package/dist/errors/MetaMaskClientNotInitializedError/MetaMaskClientNotInitializedError.d.ts +12 -0
  26. package/dist/errors/MetaMaskClientNotInitializedError/MetaMaskClientNotInitializedError.d.ts.map +1 -0
  27. package/dist/errors/MetaMaskClientNotInitializedError/index.d.ts +2 -0
  28. package/dist/errors/MetaMaskClientNotInitializedError/index.d.ts.map +1 -0
  29. package/dist/errors/MetaMaskDisplayUriMissingError/MetaMaskDisplayUriMissingError.d.ts +21 -0
  30. package/dist/errors/MetaMaskDisplayUriMissingError/MetaMaskDisplayUriMissingError.d.ts.map +1 -1
  31. package/dist/errors/MetaMaskStorageError/MetaMaskStorageError.d.ts +12 -0
  32. package/dist/errors/MetaMaskStorageError/MetaMaskStorageError.d.ts.map +1 -0
  33. package/dist/errors/MetaMaskStorageError/index.d.ts +2 -0
  34. package/dist/errors/MetaMaskStorageError/index.d.ts.map +1 -0
  35. package/dist/errors/MetaMaskUnscopedNetworkError/MetaMaskUnscopedNetworkError.d.ts +29 -0
  36. package/dist/errors/MetaMaskUnscopedNetworkError/MetaMaskUnscopedNetworkError.d.ts.map +1 -0
  37. package/dist/errors/MetaMaskUnscopedNetworkError/index.d.ts +2 -0
  38. package/dist/errors/MetaMaskUnscopedNetworkError/index.d.ts.map +1 -0
  39. package/dist/errors/UnsupportedMetaMaskChainError/UnsupportedMetaMaskChainError.d.ts +9 -0
  40. package/dist/errors/UnsupportedMetaMaskChainError/UnsupportedMetaMaskChainError.d.ts.map +1 -0
  41. package/dist/errors/UnsupportedMetaMaskChainError/index.d.ts +2 -0
  42. package/dist/errors/UnsupportedMetaMaskChainError/index.d.ts.map +1 -0
  43. package/dist/exports/core.d.ts +21 -0
  44. package/dist/exports/core.d.ts.map +1 -0
  45. package/dist/exports/index.d.ts +2 -2
  46. package/dist/exports/index.d.ts.map +1 -1
  47. package/dist/getGrantedMetaMaskScopes/getGrantedMetaMaskScopes.d.ts +40 -0
  48. package/dist/getGrantedMetaMaskScopes/getGrantedMetaMaskScopes.d.ts.map +1 -0
  49. package/dist/getGrantedMetaMaskScopes/index.d.ts +3 -0
  50. package/dist/getGrantedMetaMaskScopes/index.d.ts.map +1 -0
  51. package/dist/getMetaMaskExtensionWalletProviderKey/getMetaMaskExtensionWalletProviderKey.d.ts +1 -1
  52. package/dist/getMetaMaskScopeForNetworkId/getMetaMaskScopeForNetworkId.d.ts +39 -0
  53. package/dist/getMetaMaskScopeForNetworkId/getMetaMaskScopeForNetworkId.d.ts.map +1 -0
  54. package/dist/getMetaMaskScopeForNetworkId/index.d.ts +2 -0
  55. package/dist/getMetaMaskScopeForNetworkId/index.d.ts.map +1 -0
  56. package/dist/getMetaMaskScopes/getMetaMaskScopes.d.ts +28 -0
  57. package/dist/getMetaMaskScopes/getMetaMaskScopes.d.ts.map +1 -0
  58. package/dist/getMetaMaskScopes/index.d.ts +2 -0
  59. package/dist/getMetaMaskScopes/index.d.ts.map +1 -0
  60. package/dist/getMetaMaskSupportedNetworks/getMetaMaskSupportedNetworks.d.ts +23 -0
  61. package/dist/getMetaMaskSupportedNetworks/getMetaMaskSupportedNetworks.d.ts.map +1 -0
  62. package/dist/getMetaMaskSupportedNetworks/index.d.ts +2 -0
  63. package/dist/getMetaMaskSupportedNetworks/index.d.ts.map +1 -0
  64. package/dist/getNetworkIdFromMetaMaskScope/getNetworkIdFromMetaMaskScope.d.ts +35 -0
  65. package/dist/getNetworkIdFromMetaMaskScope/getNetworkIdFromMetaMaskScope.d.ts.map +1 -0
  66. package/dist/getNetworkIdFromMetaMaskScope/index.d.ts +2 -0
  67. package/dist/getNetworkIdFromMetaMaskScope/index.d.ts.map +1 -0
  68. package/dist/getOrCreateMetaMaskClientInstanceManager-DWd07xVz.esm.js +621 -0
  69. package/dist/getOrCreateMetaMaskClientInstanceManager-DWd07xVz.esm.js.map +1 -0
  70. package/dist/getOrCreateMetaMaskClientInstanceManager-Dz57S3Bm.native.esm.js +621 -0
  71. package/dist/getOrCreateMetaMaskClientInstanceManager-Dz57S3Bm.native.esm.js.map +1 -0
  72. package/dist/getOrCreateMetaMaskClientInstanceManager-l6T7WUT5.cjs +708 -0
  73. package/dist/getOrCreateMetaMaskClientInstanceManager-l6T7WUT5.cjs.map +1 -0
  74. package/dist/getScopeAccountsFromMetaMaskClient/getScopeAccountsFromMetaMaskClient.d.ts +38 -0
  75. package/dist/getScopeAccountsFromMetaMaskClient/getScopeAccountsFromMetaMaskClient.d.ts.map +1 -0
  76. package/dist/getScopeAccountsFromMetaMaskClient/index.d.ts +2 -0
  77. package/dist/getScopeAccountsFromMetaMaskClient/index.d.ts.map +1 -0
  78. package/dist/index.cjs +57 -57
  79. package/dist/index.cjs.map +1 -1
  80. package/dist/index.esm.js +56 -56
  81. package/dist/index.esm.js.map +1 -1
  82. package/dist/index.native.esm.js +56 -78
  83. package/dist/index.native.esm.js.map +1 -1
  84. package/dist/metaMaskClientInstanceManager/createMetaMaskClientInstanceManager/createMetaMaskClientInstanceManager.d.ts +45 -0
  85. package/dist/metaMaskClientInstanceManager/createMetaMaskClientInstanceManager/createMetaMaskClientInstanceManager.d.ts.map +1 -0
  86. package/dist/metaMaskClientInstanceManager/createMetaMaskClientInstanceManager/index.d.ts +2 -0
  87. package/dist/metaMaskClientInstanceManager/createMetaMaskClientInstanceManager/index.d.ts.map +1 -0
  88. package/dist/metaMaskClientInstanceManager/getOrCreateMetaMaskClientInstanceManager/getOrCreateMetaMaskClientInstanceManager.d.ts +18 -0
  89. package/dist/metaMaskClientInstanceManager/getOrCreateMetaMaskClientInstanceManager/getOrCreateMetaMaskClientInstanceManager.d.ts.map +1 -0
  90. package/dist/metaMaskClientInstanceManager/getOrCreateMetaMaskClientInstanceManager/index.d.ts +2 -0
  91. package/dist/metaMaskClientInstanceManager/getOrCreateMetaMaskClientInstanceManager/index.d.ts.map +1 -0
  92. package/dist/metaMaskStorage/clearMetaMaskStorage/clearMetaMaskStorage.d.ts +23 -0
  93. package/dist/metaMaskStorage/clearMetaMaskStorage/clearMetaMaskStorage.d.ts.map +1 -0
  94. package/dist/metaMaskStorage/clearMetaMaskStorage/index.d.ts +2 -0
  95. package/dist/metaMaskStorage/clearMetaMaskStorage/index.d.ts.map +1 -0
  96. package/dist/metaMaskStorage/createInitialMetaMaskStoreValue/createInitialMetaMaskStoreValue.d.ts +19 -0
  97. package/dist/metaMaskStorage/createInitialMetaMaskStoreValue/createInitialMetaMaskStoreValue.d.ts.map +1 -0
  98. package/dist/metaMaskStorage/createMetaMaskStorageClient/createMetaMaskStorageClient.d.ts +30 -0
  99. package/dist/metaMaskStorage/createMetaMaskStorageClient/createMetaMaskStorageClient.d.ts.map +1 -0
  100. package/dist/metaMaskStorage/createMetaMaskStorageClient/index.d.ts +2 -0
  101. package/dist/metaMaskStorage/createMetaMaskStorageClient/index.d.ts.map +1 -0
  102. package/dist/metaMaskStorage/metaMaskStorage.schema.d.ts +30 -0
  103. package/dist/metaMaskStorage/metaMaskStorage.schema.d.ts.map +1 -0
  104. package/dist/metaMaskStorage/queueMetaMaskStorageWrite/queueMetaMaskStorageWrite.d.ts +20 -0
  105. package/dist/metaMaskStorage/queueMetaMaskStorageWrite/queueMetaMaskStorageWrite.d.ts.map +1 -0
  106. package/dist/metamask.types.d.ts +0 -20
  107. package/dist/metamask.types.d.ts.map +1 -1
  108. package/dist/reconcileMetaMaskWalletProvider/index.d.ts +3 -0
  109. package/dist/reconcileMetaMaskWalletProvider/index.d.ts.map +1 -0
  110. package/dist/reconcileMetaMaskWalletProvider/reconcileMetaMaskWalletProvider.d.ts +60 -0
  111. package/dist/reconcileMetaMaskWalletProvider/reconcileMetaMaskWalletProvider.d.ts.map +1 -0
  112. package/dist/resolveActiveMetaMaskScope/index.d.ts +3 -0
  113. package/dist/resolveActiveMetaMaskScope/index.d.ts.map +1 -0
  114. package/dist/resolveActiveMetaMaskScope/resolveActiveMetaMaskScope.d.ts +67 -0
  115. package/dist/resolveActiveMetaMaskScope/resolveActiveMetaMaskScope.d.ts.map +1 -0
  116. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  117. package/dist/utils/clearMetaMaskSdkSingleton/clearMetaMaskSdkSingleton.d.ts +23 -0
  118. package/dist/utils/clearMetaMaskSdkSingleton/clearMetaMaskSdkSingleton.d.ts.map +1 -0
  119. package/dist/utils/createMetaMaskPreferredOpenLink/createMetaMaskPreferredOpenLink.d.ts +21 -0
  120. package/dist/utils/createMetaMaskPreferredOpenLink/createMetaMaskPreferredOpenLink.d.ts.map +1 -0
  121. package/dist/utils/createMetaMaskPreferredOpenLink/index.d.ts +2 -0
  122. package/dist/utils/createMetaMaskPreferredOpenLink/index.d.ts.map +1 -0
  123. package/package.json +11 -3
  124. package/dist/errors/MetaMaskWalletNotConnectedError/MetaMaskWalletNotConnectedError.d.ts +0 -5
  125. package/dist/errors/MetaMaskWalletNotConnectedError/MetaMaskWalletNotConnectedError.d.ts.map +0 -1
  126. package/dist/errors/MetaMaskWalletNotConnectedError/index.d.ts +0 -2
  127. package/dist/errors/MetaMaskWalletNotConnectedError/index.d.ts.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getOrCreateMetaMaskClientInstanceManager-l6T7WUT5.cjs","names":["BaseError","BaseError","BaseError","supportedNetworks: MetaMaskSupportedNetworks","queueMetaMaskStorageWrite: SequenceQueue","z","BaseError","adapter: StoreAdapter","metaMaskClientPromise: Promise<MultichainCore> | null","clearEventListeners: () => void","builtClientPromise: Promise<MultichainCore>"],"sources":["../package.json","../src/errors/MetaMaskUnscopedNetworkError/MetaMaskUnscopedNetworkError.ts","../src/constants.ts","../src/errors/UnsupportedMetaMaskChainError/UnsupportedMetaMaskChainError.ts","../src/getMetaMaskScopeForNetworkId/getMetaMaskScopeForNetworkId.ts","../src/getMetaMaskScopes/getMetaMaskScopes.ts","../src/errors/MetaMaskClientNotInitializedError/MetaMaskClientNotInitializedError.ts","../src/getMetaMaskSupportedNetworks/getMetaMaskSupportedNetworks.ts","../src/metaMaskStorage/createInitialMetaMaskStoreValue/createInitialMetaMaskStoreValue.ts","../src/metaMaskStorage/queueMetaMaskStorageWrite/queueMetaMaskStorageWrite.ts","../src/metaMaskStorage/metaMaskStorage.schema.ts","../src/metaMaskStorage/clearMetaMaskStorage/clearMetaMaskStorage.ts","../src/errors/MetaMaskStorageError/MetaMaskStorageError.ts","../src/metaMaskStorage/createMetaMaskStorageClient/createMetaMaskStorageClient.ts","../src/utils/clearMetaMaskSdkSingleton/clearMetaMaskSdkSingleton.ts","../src/utils/createMetaMaskPreferredOpenLink/createMetaMaskPreferredOpenLink.ts","../src/metaMaskClientInstanceManager/createMetaMaskClientInstanceManager/createMetaMaskClientInstanceManager.ts","../src/metaMaskClientInstanceManager/getOrCreateMetaMaskClientInstanceManager/getOrCreateMetaMaskClientInstanceManager.ts"],"sourcesContent":["","import { BaseError } from '@dynamic-labs-sdk/client';\n\n/**\n * Thrown when attempting to switch a MetaMask multichain wallet provider to\n * a network whose CAIP-2 scope was requested at connect time but never\n * granted an account by MetaMask in the current session (e.g. the user only\n * approved mainnet, not a preconfigured devnet, during pairing). Switching\n * to it anyway would silently break every subsequent signing/sending call\n * on that network, since MetaMask rejects those against an ungranted scope.\n *\n * @example\n * ```ts\n * try {\n * await switchActiveNetwork({ networkId: '103', walletAccount });\n * } catch (error) {\n * if (error instanceof MetaMaskUnscopedNetworkError) {\n * // Tell the user to approve this network in MetaMask, then retry.\n * }\n * }\n * ```\n * @see assertMetaMaskNetworkIsGranted\n * @see resolveActiveMetaMaskScope\n */\nexport class MetaMaskUnscopedNetworkError extends BaseError {\n constructor({ networkId, scope }: { networkId: string; scope: string }) {\n super({\n cause: null,\n code: 'metamask_unscoped_network',\n docsUrl: null,\n metaMessages: [`scope: ${scope}`],\n name: 'MetaMaskUnscopedNetworkError',\n shortMessage: `Cannot switch to network \"${networkId}\": MetaMask did not grant an account for scope \"${scope}\" in the current session.`,\n });\n }\n}\n","import type { Chain } from '@dynamic-labs-sdk/client';\n\n/**\n * Chains MetaMask's multichain client can build a CAIP-2 scope for. Shared by\n * every scope/network-mapping helper so the supported set only needs to\n * change in one place.\n */\nexport const SUPPORTED_METAMASK_CHAINS = ['EVM', 'SOL'] as Chain[];\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\n/** Thrown when a chain has no MetaMask multichain scope mapping defined. */\nexport class UnsupportedMetaMaskChainError extends BaseError {\n constructor({\n chain,\n supportedChains,\n }: {\n chain: string;\n supportedChains: string[];\n }) {\n super({\n cause: null,\n code: 'metamask_unsupported_chain',\n docsUrl: null,\n name: 'UnsupportedMetaMaskChainError',\n shortMessage: `Unsupported chain \"${chain}\" for MetaMask. Supported chains: ${supportedChains.join(', ')}`,\n });\n }\n}\n","import type { Chain, DynamicClient } from '@dynamic-labs-sdk/client';\nimport { getNetworksData } from '@dynamic-labs-sdk/client';\nimport type { RPCAPI, Scope } from '@metamask/connect-multichain';\n\nimport { SUPPORTED_METAMASK_CHAINS } from '../constants';\nimport { UnsupportedMetaMaskChainError } from '../errors/UnsupportedMetaMaskChainError';\n\nexport type GetMetaMaskScopeForNetworkIdParams = {\n chain: Chain;\n networkId: string;\n};\n\n/**\n * Maps a single Dynamic-configured network to its CAIP-2 MetaMask\n * multichain scope -- the same per-network mapping `getMetaMaskScopes`\n * applies to every configured network at once, extracted so callers that\n * already have one `networkId` (e.g. the \"active network\" registry) don't\n * need to rebuild and filter the whole configured list to find it.\n *\n * EVM's `networkId` IS the CAIP-2 reference (`eip155:<networkId>`); SOL's\n * `networkId` is an internal routing id, so the network's base58 genesis\n * hash is used instead (`solana:<genesisHash>`). Returns `undefined` when no\n * configured SOL network matches, or matches but has no genesis hash --\n * these are normal (\"this networkId isn't usable as a MetaMask scope\"), not\n * error conditions.\n *\n * @example\n * ```ts\n * const scope = getMetaMaskScopeForNetworkId(\n * { chain: 'SOL', networkId: '101' },\n * client\n * );\n * // 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'\n * ```\n *\n * @returns The CAIP-2 scope for `networkId`, or `undefined` if it can't be\n * expressed as one (e.g. a SOL network with no genesis hash configured).\n * @throws {UnsupportedMetaMaskChainError} If `chain` isn't a chain MetaMask\n * scopes can be built for.\n * @see getMetaMaskScopes\n * @see getNetworkIdFromMetaMaskScope\n * @notInstrumented\n */\nexport const getMetaMaskScopeForNetworkId = (\n { chain, networkId }: GetMetaMaskScopeForNetworkIdParams,\n client: DynamicClient\n): Scope<RPCAPI> | undefined => {\n if (chain === 'EVM') {\n return `eip155:${networkId}` as Scope<RPCAPI>;\n }\n\n if (chain === 'SOL') {\n const network = getNetworksData(client).find(\n (candidate) => candidate.chain === 'SOL' && candidate.networkId === networkId\n );\n\n return network?.genesisHash\n ? (`solana:${network.genesisHash}` as Scope<RPCAPI>)\n : undefined;\n }\n\n throw new UnsupportedMetaMaskChainError({\n chain,\n supportedChains: SUPPORTED_METAMASK_CHAINS,\n });\n};\n","import type { Chain, DynamicClient } from '@dynamic-labs-sdk/client';\nimport { getNetworksData } from '@dynamic-labs-sdk/client';\nimport type { RPCAPI, Scope } from '@metamask/connect-multichain';\n\nimport { SUPPORTED_METAMASK_CHAINS } from '../constants';\nimport { UnsupportedMetaMaskChainError } from '../errors/UnsupportedMetaMaskChainError';\nimport { getMetaMaskScopeForNetworkId } from '../getMetaMaskScopeForNetworkId';\n\ntype GetMetaMaskScopesOptions = {\n chain: Chain;\n};\n\n/**\n * Builds the CAIP-2 scopes to request for a chain's MetaMask multichain\n * session, one per configured network. SOL scopes use the network's genesis\n * hash (not `networkId`, which is an internal routing id for SOL) since\n * that's the CAIP-2 reference MetaMask expects.\n *\n * @example\n * ```ts\n * const scopes = getMetaMaskScopes({ chain: 'EVM' }, client);\n * // ['eip155:1', 'eip155:137']\n * ```\n *\n * @returns The CAIP-2 scopes for every configured network of `chain` that\n * can be expressed as one.\n * @throws {UnsupportedMetaMaskChainError} If `chain` isn't a chain MetaMask\n * scopes can be built for.\n * @see getMetaMaskScopeForNetworkId\n * @see getMetaMaskSupportedNetworks\n * @notInstrumented\n */\nexport const getMetaMaskScopes = (\n { chain }: GetMetaMaskScopesOptions,\n client: DynamicClient\n): Scope<RPCAPI>[] => {\n if (!chain || !SUPPORTED_METAMASK_CHAINS.includes(chain)) {\n throw new UnsupportedMetaMaskChainError({\n chain,\n supportedChains: SUPPORTED_METAMASK_CHAINS,\n });\n }\n\n const networks = getNetworksData(client).filter(\n (network) => network.chain === chain\n );\n\n return networks.flatMap((network) => {\n const scope = getMetaMaskScopeForNetworkId(\n { chain: network.chain, networkId: network.networkId },\n client\n );\n\n // Skip networks that can't be expressed as a MetaMask scope (e.g. a SOL\n // network with no genesis hash configured) rather than build an invalid\n // one -- see `getMetaMaskScopeForNetworkId`.\n return scope ? [scope] : [];\n });\n};\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\n/**\n * Thrown when `getMetaMaskClient()` is called but the underlying\n * `@metamask/connect-multichain` client failed to initialize -- this should\n * be unreachable in practice, since `getMetaMaskClient` always triggers\n * `refreshMetaMaskClient` first when no client promise exists yet, but it\n * guards against a future change silently returning `undefined` instead.\n */\nexport class MetaMaskClientNotInitializedError extends BaseError {\n constructor() {\n super({\n cause: null,\n code: 'metamask_client_not_initialized',\n docsUrl: null,\n name: 'MetaMaskClientNotInitializedError',\n shortMessage: 'MetaMask client not initialized',\n });\n }\n}\n","import type { DynamicClient } from '@dynamic-labs-sdk/client';\nimport { getNetworksData } from '@dynamic-labs-sdk/client';\nimport { getCore } from '@dynamic-labs-sdk/client/core';\n\nimport { SUPPORTED_METAMASK_CHAINS } from '../constants';\n\ntype MetaMaskSupportedNetworks = Record<\n `eip155:${string}` | `solana:${string}`,\n string\n>;\n\n/**\n * Builds the `api.supportedNetworks` map for MetaMask's multichain client:\n * EVM networks keyed by their CAIP-2 `eip155:<networkId>` scope, SOL networks\n * keyed by their CAIP-2 `solana:<genesisHash>` scope (SOL's `networkId` is an\n * internal routing id, not usable as a CAIP-2 reference).\n *\n * @example\n * ```ts\n * const supportedNetworks = getMetaMaskSupportedNetworks(client);\n * // { 'eip155:1': 'https://...', 'solana:5eykt4...': 'https://...' }\n * ```\n *\n * @returns The RPC URL for every configured EVM/SOL network, keyed by its\n * MetaMask-recognized network identifier.\n * @see getMetaMaskScopes\n * @see createMetaMaskClientInstanceManager\n * @notInstrumented\n */\nexport const getMetaMaskSupportedNetworks = (\n client: DynamicClient\n): MetaMaskSupportedNetworks => {\n const { logger } = getCore(client);\n\n const networks = getNetworksData(client).filter((network) =>\n SUPPORTED_METAMASK_CHAINS.includes(network.chain)\n );\n\n const supportedNetworks: MetaMaskSupportedNetworks = {};\n\n for (const network of networks) {\n if (network.chain === 'EVM') {\n supportedNetworks[`eip155:${network.networkId}`] =\n network.rpcUrls.http[0];\n }\n\n // SOL's `networkId` is an internal routing id, not the CAIP-2 reference —\n // the multichain client's `solana:` scope needs the base58 genesis hash.\n // Skip networks that haven't configured one.\n if (network.chain === 'SOL' && network.genesisHash) {\n supportedNetworks[`solana:${network.genesisHash}`] =\n network.rpcUrls.http[0];\n }\n }\n\n logger.debug('[MetaMask:Client] Resolved supported networks', {\n supportedNetworks,\n });\n\n return supportedNetworks;\n};\n","import type { MetaMaskStoreValue } from '../metaMaskStorage.schema';\n\n/**\n * Builds the persisted store blob's value for when there is nothing stored\n * yet, or after a clear. A function rather than a shared constant, so every\n * caller gets its own object and can't mutate a value other callers rely on.\n *\n * @example\n * ```ts\n * const initial = createInitialMetaMaskStoreValue();\n * // { entries: {}, schemaVersion: 1 }\n * ```\n *\n * @returns A fresh, empty `MetaMaskStoreValue`.\n * @see createMetaMaskStorageClient\n * @see clearMetaMaskStorage\n * @notInstrumented\n */\nexport const createInitialMetaMaskStoreValue = (): MetaMaskStoreValue => ({\n entries: {},\n schemaVersion: 1,\n});\n","import { createSequenceQueue } from '@dynamic-labs-sdk/client/core';\nimport type { SequenceQueue } from '@dynamic-labs-sdk/client/core';\n\n/**\n * Single shared queue serializing every read-modify-write against\n * `metaMaskStoreStorageKeySchema` -- `createMetaMaskStorageClient`'s adapter\n * reads/writes/anonId operations and `clearMetaMaskStorage`'s reset all go\n * through this same instance, so a write that started before a clear can't\n * land after it and resurrect the data the clear was meant to erase.\n *\n * @example\n * ```ts\n * await queueMetaMaskStorageWrite(() => storage.setItem(key, value), client);\n * ```\n *\n * @returns A `SequenceQueue` that runs one queued task at a time, in order.\n * @see createMetaMaskStorageClient\n * @see clearMetaMaskStorage\n * @notInstrumented\n */\nexport const queueMetaMaskStorageWrite: SequenceQueue = createSequenceQueue();\n","import * as z from 'zod/mini';\nimport { createStorageKeySchema } from '@dynamic-labs-sdk/client/core';\n\n/**\n * Single storage key holding every value the MetaMask multichain SDK writes\n * through our `StoreAdapter` (sessions, nonces, cached accounts/chain,\n * pending pairing requests, transport ids, ...), keyed by whatever key string\n * the SDK itself hands us -- the SDK controls every key name, including ones\n * that embed an unpredictable id (`session:<id>`), so this can't be split\n * into one storage key per SDK key.\n *\n * `entries[ANON_ID_ENTRY_KEY]` also lives in here, alongside `extensionId`\n * and the other transport keys.\n *\n * `clearMetaMaskStorage` resets this key back to its initial value; nothing\n * else needs to know the individual key names the SDK is using.\n */\nexport const metaMaskStoreStorageKeySchema = createStorageKeySchema({\n key: 'metaMaskStore',\n schema: z.object({\n entries: z.record(z.string(), z.string()),\n schemaVersion: z.literal(1),\n }),\n});\n\n/**\n * The persisted store blob's shape. Exported here because it is shared by\n * every function operating on this storage key.\n */\nexport type MetaMaskStoreValue = z.infer<typeof metaMaskStoreStorageKeySchema.schema>;\n\n/**\n * Reserved `entries` key the MetaMask SDK itself never writes to, used to\n * carry the SDK's anonymous analytics id inside the same store blob.\n */\nexport const ANON_ID_ENTRY_KEY = 'anonId';\n","import { getCore } from '@dynamic-labs-sdk/client/core';\nimport type { DynamicClient } from '@dynamic-labs-sdk/client';\n\nimport { createInitialMetaMaskStoreValue } from '../createInitialMetaMaskStoreValue/createInitialMetaMaskStoreValue';\nimport { queueMetaMaskStorageWrite } from '../queueMetaMaskStorageWrite/queueMetaMaskStorageWrite';\nimport { metaMaskStoreStorageKeySchema } from '../metaMaskStorage.schema';\n\nconst FAILED_TO_CLEAR_STORAGE_MESSAGE =\n '[MetaMask:Session] Failed to clear the persisted store; the next pairing may resume a stale session instead of showing a new one';\n\n/**\n * Resets the MetaMask SDK's persisted store blob back to its initial\n * (empty) value, so the next connect call starts a fresh pairing and emits a\n * `display_uri` instead of silently resuming a session that no longer works.\n *\n * @example\n * ```ts\n * await clearMetaMaskStorage(client);\n * // Next connectWithMetaMaskUri call will emit a fresh URI immediately.\n * ```\n *\n * @param client - The Dynamic client instance. Required (rather than\n * defaulting to the last-initialized client) so a storage-clear failure is\n * always logged against the client that actually requested it.\n * @returns A promise that resolves once the blob is reset. Never rejects -- a\n * storage failure must not take down the connect flow that depends on it.\n * @see connectWithMetaMaskUri\n * @see createMetaMaskStorageClient\n * @notInstrumented\n */\nexport const clearMetaMaskStorage = async (\n client: DynamicClient\n): Promise<void> => {\n const { logger, storage } = getCore(client);\n\n try {\n await queueMetaMaskStorageWrite(\n () =>\n storage.setItem(\n metaMaskStoreStorageKeySchema,\n createInitialMetaMaskStoreValue()\n ),\n client\n );\n\n logger.debug('[MetaMask:Session] Cleared persisted store');\n } catch (error) {\n logger.warn(FAILED_TO_CLEAR_STORAGE_MESSAGE, { error });\n }\n};\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\ntype MetaMaskStorageErrorParams = {\n cause: unknown;\n key: string;\n operation: 'get' | 'set' | 'delete';\n};\n\n/** Thrown when the underlying storage service rejects a read/write/delete for the MetaMask multichain client's own store (e.g. quota exceeded, private-browsing restrictions). */\nexport class MetaMaskStorageError extends BaseError {\n constructor({ cause, key, operation }: MetaMaskStorageErrorParams) {\n super({\n cause: cause instanceof Error ? cause : null,\n code: 'metamask_storage_error',\n docsUrl: null,\n name: 'MetaMaskStorageError',\n shortMessage: `Failed to ${operation} MetaMask multichain client storage key \"${key}\"`,\n });\n }\n}\n","import { getCore, getPlatform } from '@dynamic-labs-sdk/client/core';\nimport type { StoreAdapter, StoreClient } from '@metamask/connect-multichain';\nimport { getTransportType } from '@metamask/connect-multichain';\nimport type { DynamicClient } from '@dynamic-labs-sdk/client';\n\nimport { MetaMaskStorageError } from '../../errors/MetaMaskStorageError';\nimport { createInitialMetaMaskStoreValue } from '../createInitialMetaMaskStoreValue/createInitialMetaMaskStoreValue';\nimport { queueMetaMaskStorageWrite } from '../queueMetaMaskStorageWrite/queueMetaMaskStorageWrite';\nimport { ANON_ID_ENTRY_KEY, metaMaskStoreStorageKeySchema } from '../metaMaskStorage.schema';\n\nconst TRANSPORT_TYPE_KEY = 'multichain-transport';\nconst EXTENSION_ID_KEY = 'extensionId';\n\n/** Maps this SDK's platform literal onto the one `@metamask/connect-multichain`'s `StoreAdapter` expects. */\nconst toStoreAdapterPlatform = (\n platform: ReturnType<typeof getPlatform>\n): StoreAdapter['platform'] => (platform === 'react-native' ? 'rn' : 'web');\n\n/**\n * Builds a storage-service-backed store for the MetaMask multichain client,\n * in place of its own default web adapter (IndexedDB) and React Native\n * adapter (raw `AsyncStorage`), so every platform persists through the same\n * core `Storage` service and `clearMetaMaskStorage` can reliably wipe it.\n *\n * The SDK controls every key name it reads/writes through `adapter`,\n * including ones that embed an unpredictable id (`session:<id>`), so every\n * key it uses is folded into a single stored blob (`metaMaskStoreStorageKeySchema`)\n * rather than one storage key per SDK key. `DEBUG` is never persisted at all,\n * answered live from the client's own logger.\n *\n * @example\n * ```ts\n * const storeClient = createMetaMaskStorageClient(client);\n * const multichainClient = createMultichainClient({ storage: storeClient });\n * ```\n *\n * @returns A `StoreClient` backed by the client's core `Storage` service.\n * @throws {MetaMaskStorageError} If the underlying `Storage` service's\n * `getItem`/`setItem` calls fail for any of the adapter's read/write/delete\n * operations.\n * @see createInitialMetaMaskStoreValue\n * @see clearMetaMaskStorage\n * @notInstrumented\n */\nexport const createMetaMaskStorageClient = (client: DynamicClient): StoreClient => {\n const { logger, storage } = getCore(client);\n\n // eslint-disable-next-line custom-rules/require-single-object-param -- signature dictated by `StoreAdapter.get`\n const read = async (key: string): Promise<string | null> => {\n try {\n const { entries } =\n (await storage.getItem(metaMaskStoreStorageKeySchema)) ??\n createInitialMetaMaskStoreValue();\n\n return entries[key] ?? null;\n } catch (error) {\n throw new MetaMaskStorageError({ cause: error, key, operation: 'get' });\n }\n };\n\n // eslint-disable-next-line custom-rules/require-single-object-param -- signature dictated by `StoreAdapter.set`\n const write = async (key: string, value: string): Promise<void> => {\n try {\n await queueMetaMaskStorageWrite(async () => {\n const current =\n (await storage.getItem(metaMaskStoreStorageKeySchema)) ??\n createInitialMetaMaskStoreValue();\n\n await storage.setItem(metaMaskStoreStorageKeySchema, {\n ...current,\n entries: { ...current.entries, [key]: value },\n });\n }, client);\n } catch (error) {\n throw new MetaMaskStorageError({ cause: error, key, operation: 'set' });\n }\n };\n\n // eslint-disable-next-line custom-rules/require-single-object-param -- signature dictated by `StoreAdapter.delete`\n const remove = async (key: string): Promise<void> => {\n try {\n await queueMetaMaskStorageWrite(async () => {\n const current =\n (await storage.getItem(metaMaskStoreStorageKeySchema)) ??\n createInitialMetaMaskStoreValue();\n const remainingEntries = Object.fromEntries(\n Object.entries(current.entries).filter(\n ([entryKey]) => entryKey !== key\n )\n );\n\n await storage.setItem(metaMaskStoreStorageKeySchema, {\n ...current,\n entries: remainingEntries,\n });\n }, client);\n } catch (error) {\n throw new MetaMaskStorageError({ cause: error, key, operation: 'delete' });\n }\n };\n\n const adapter: StoreAdapter = {\n delete: remove,\n get: read,\n platform: toStoreAdapterPlatform(getPlatform()),\n set: write,\n };\n\n return {\n adapter,\n // Queued (rather than a plain read-then-write) so its check-then-create\n // can't race itself into generating two different ids for the same\n // client -- the SDK calls `getAnonId()` from multiple internal call sites.\n getAnonId: () =>\n queueMetaMaskStorageWrite(async () => {\n const current =\n (await storage.getItem(metaMaskStoreStorageKeySchema)) ??\n createInitialMetaMaskStoreValue();\n const existing = current.entries[ANON_ID_ENTRY_KEY];\n\n if (existing) {\n return existing;\n }\n\n const anonId = crypto.randomUUID();\n\n await storage.setItem(metaMaskStoreStorageKeySchema, {\n ...current,\n entries: { ...current.entries, [ANON_ID_ENTRY_KEY]: anonId },\n });\n\n return anonId;\n }, client),\n getDebug: () =>\n // The SDK matches this against its own debug namespaces via\n // `debugValue.includes(namespace) || debugValue.includes('metamask-sdk:*')`\n // -- a boolean-shaped string like `'true'` would never match, so this\n // has to be a namespace pattern, not a flag.\n Promise.resolve(logger.isEnabled('debug') ? 'metamask-sdk:*' : null),\n getExtensionId: () => adapter.get(EXTENSION_ID_KEY),\n getTransportType: async () => {\n const value = await adapter.get(TRANSPORT_TYPE_KEY);\n\n return value ? getTransportType(value) : null;\n },\n removeAnonId: () => remove(ANON_ID_ENTRY_KEY),\n removeExtensionId: () => adapter.delete(EXTENSION_ID_KEY),\n removeTransportType: () => adapter.delete(TRANSPORT_TYPE_KEY),\n setAnonId: (anonId) => write(ANON_ID_ENTRY_KEY, anonId),\n setExtensionId: (extensionId) => adapter.set(EXTENSION_ID_KEY, extensionId),\n setTransportType: (transportType) =>\n adapter.set(TRANSPORT_TYPE_KEY, transportType),\n };\n};\n","// Mirrors `@metamask/connect-multichain`'s own singleton key -- not exported\n// by the SDK, so it must be kept in sync by hand whenever the pinned version\n// in packages/metamask/package.json changes.\nconst METAMASK_SDK_SINGLETON_GLOBAL_KEY =\n '__METAMASK_CONNECT_MULTICHAIN_SINGLETON__';\n\n/**\n * Deletes the upstream `@metamask/connect-multichain` SDK's own cached\n * client instance off `globalThis`.\n *\n * The SDK's `createMultichainClient` reuses a private `globalThis` singleton\n * and only merges in a subset of options on repeat calls -- notably not\n * `storage` -- so it keeps talking to its original `StoreAdapter` even after\n * a fresh `clearMetaMaskStorage` call. Deleting this key forces a genuinely\n * new instance (and storage adapter) on the next `createMultichainClient` call.\n *\n * @example\n * ```ts\n * clearMetaMaskSdkSingleton();\n * // Next createMultichainClient call builds a fresh client and adapter.\n * ```\n *\n * @returns Nothing -- the singleton key is deleted synchronously.\n * @see createMetaMaskClientInstanceManager\n * @see clearMetaMaskStorage\n * @notInstrumented\n */\nexport const clearMetaMaskSdkSingleton = (): void => {\n delete (globalThis as Record<string, unknown>)[\n METAMASK_SDK_SINGLETON_GLOBAL_KEY\n ];\n};\n","import type { DynamicClient } from '@dynamic-labs-sdk/client';\nimport { getCore } from '@dynamic-labs-sdk/client/core';\n\n/**\n * Builds the `preferredOpenLink` callback handed to `@metamask/connect-multichain`,\n * routing wallet deeplinks through the core `deeplink` service instead of the\n * SDK's own default handling, so every platform (web, React Native, Expo)\n * opens them the same way the rest of the SDK does.\n *\n * @example\n * ```ts\n * const preferredOpenLink = createMetaMaskPreferredOpenLink(client);\n * preferredOpenLink('https://metamask.app.link/...');\n * ```\n *\n * @returns A callback that opens a MetaMask-issued deeplink through the\n * core `deeplink` service.\n * @see createMetaMaskClientInstanceManager\n * @see createMetaMaskStorageClient\n * @notInstrumented\n */\nexport const createMetaMaskPreferredOpenLink = (\n client: DynamicClient\n): ((deeplink: string) => void) =>\n (deeplink) => {\n const { logger, openDeeplink } = getCore(client);\n\n logger.debug('[MetaMask:Client] Opening MetaMask deeplink', { deeplink });\n\n void openDeeplink(deeplink)\n .then(() => logger.debug('[MetaMask:Client] Deeplink opened'))\n .catch((error) =>\n logger.error('[MetaMask:Client] Failed to open deeplink', {\n deeplink,\n error,\n })\n );\n };\n","import type { DynamicClient } from '@dynamic-labs-sdk/client';\nimport {\n type EventEmitter,\n createEventEmitter,\n getAppMetadata,\n getCore,\n getNativeLinkScheme,\n} from '@dynamic-labs-sdk/client/core';\nimport type { MultichainCore } from '@metamask/connect-multichain';\nimport { createMultichainClient } from '@metamask/connect-multichain';\n\nimport { MetaMaskClientNotInitializedError } from '../../errors/MetaMaskClientNotInitializedError';\nimport { getMetaMaskSupportedNetworks } from '../../getMetaMaskSupportedNetworks';\nimport { clearMetaMaskStorage } from '../../metaMaskStorage/clearMetaMaskStorage';\nimport { createMetaMaskStorageClient } from '../../metaMaskStorage/createMetaMaskStorageClient';\nimport { clearMetaMaskSdkSingleton } from '../../utils/clearMetaMaskSdkSingleton/clearMetaMaskSdkSingleton';\nimport { createMetaMaskPreferredOpenLink } from '../../utils/createMetaMaskPreferredOpenLink/createMetaMaskPreferredOpenLink';\n\n/**\n * Events a `MetaMaskClientInstanceManager` forwards from the underlying\n * `@metamask/connect-multichain` client, for callers that don't hold a\n * reference to the raw SDK client.\n */\nexport type MetaMaskClientEvents = {\n display_uri: (evt: string) => void;\n};\n\n/**\n * The per-client handle returned by `createMetaMaskClientInstanceManager`.\n */\nexport type MetaMaskClientInstanceManager = {\n /** Wipes persisted MetaMask storage and forces the next build to start fresh. */\n clearMetaMaskStorageAndInstance: () => Promise<void>;\n /** Emits `MetaMaskClientEvents` forwarded from the underlying SDK client. */\n events: EventEmitter<MetaMaskClientEvents>;\n /** Resolves the shared `MultichainCore` client, building it on first access. */\n getMetaMaskClient(): Promise<MultichainCore>;\n};\n\n/**\n * Creates the per-client manager that lazily builds, tears down, and rebuilds\n * the shared `@metamask/connect-multichain` client instance, and forwards its\n * `display_uri` event to callers that don't hold a reference to the raw SDK\n * client.\n *\n * @example\n * ```ts\n * const manager = createMetaMaskClientInstanceManager(client);\n * const metaMaskClient = await manager.getMetaMaskClient();\n * ```\n *\n * @returns A `MetaMaskClientInstanceManager` scoped to `client`.\n * @throws {MetaMaskClientNotInitializedError} From `getMetaMaskClient` if a\n * build was never started -- a defensive guard, since `refreshMetaMaskClient`\n * always starts one. A build that starts but fails instead rejects\n * `getMetaMaskClient()` with its original error.\n * @see createMetaMaskStorageClient\n * @see clearMetaMaskStorage\n * @notInstrumented\n */\nexport const createMetaMaskClientInstanceManager = (\n client: DynamicClient\n): MetaMaskClientInstanceManager => {\n let metaMaskClientPromise: Promise<MultichainCore> | null;\n let clearEventListeners: () => void;\n const { logger } = getCore(client);\n const events = createEventEmitter<MetaMaskClientEvents>();\n\n const refreshMetaMaskClient = () => {\n // Runs synchronously up to the assignment below, so this guard makes\n // concurrent callers (e.g. two overlapping getMetaMaskClient() calls\n // before the first client exists) share the same build instead of\n // racing -- the loser's clearEventListeners would otherwise be\n // overwritten and its listener leaked. Callers that need a genuine\n // rebuild (clearMetaMaskStorageAndInstance) reset the promise to null\n // first.\n if (metaMaskClientPromise) {\n return;\n }\n\n const { appName, appLogoUrl, appUniversalLink, appNativeLink } =\n getAppMetadata(client);\n const supportedNetworks = getMetaMaskSupportedNetworks(client);\n const nativeScheme = getNativeLinkScheme({ nativeLink: appNativeLink });\n const debug = logger.isEnabled('debug');\n\n logger.debug('[MetaMask:Client] Creating MetaMask client', {\n appLogoUrl,\n appName,\n appUniversalLink,\n debug,\n nativeScheme,\n supportedNetworks,\n });\n\n if (clearEventListeners) {\n clearEventListeners();\n }\n\n clearMetaMaskSdkSingleton();\n\n const builtClientPromise: Promise<MultichainCore> = createMultichainClient({\n api: {\n supportedNetworks,\n },\n dapp: {\n iconUrl: appLogoUrl,\n name: appName,\n nativeScheme,\n url: appUniversalLink ?? '',\n },\n debug,\n mobile: {\n preferredOpenLink: createMetaMaskPreferredOpenLink(client),\n },\n // Backed by the core `Storage` service on every platform, so\n // `clearMetaMaskStorage` can reliably wipe everything the SDK writes\n // -- see `createMetaMaskStorageClient`.\n storage: createMetaMaskStorageClient(client),\n ui: { headless: true },\n }).then((metaMaskClient) => {\n const createEventMapper = <T extends keyof MetaMaskClientEvents>(\n event: T\n ) => {\n return (...args: Parameters<MetaMaskClientEvents[T]>) => {\n logger.debug(`[MetaMask:Events] ${event} event received`, { args });\n events.emit(event, ...args);\n };\n };\n\n const onDisplayUri = createEventMapper('display_uri');\n\n metaMaskClient.on('display_uri', onDisplayUri);\n\n const detachListeners = () => {\n metaMaskClient.off('display_uri', onDisplayUri);\n };\n\n // A newer build may have already replaced this one (e.g. triggered by\n // clearMetaMaskStorageAndInstance while this build was still pending).\n // Detach immediately instead of registering as the active cleanup --\n // otherwise this stale client's listener stays attached forever, or\n // clobbers (or gets clobbered by) the newer client's cleanup.\n if (metaMaskClientPromise !== builtClientPromise) {\n detachListeners();\n return metaMaskClient;\n }\n\n clearEventListeners = detachListeners;\n\n return metaMaskClient;\n });\n\n metaMaskClientPromise = builtClientPromise;\n\n // A rejected build must not stay cached -- otherwise every later\n // getMetaMaskClient() call would keep returning the same rejection\n // forever, with no way to recover short of clearMetaMaskStorageAndInstance.\n // Only clear the cache if it still points at this build: a newer build\n // (e.g. triggered by clearMetaMaskStorageAndInstance while this one was\n // still pending) may have already replaced it, and this rejection must\n // not clobber that newer, possibly-successful build.\n builtClientPromise.catch(() => {\n if (metaMaskClientPromise === builtClientPromise) {\n metaMaskClientPromise = null;\n }\n });\n };\n\n return {\n clearMetaMaskStorageAndInstance: async () => {\n await clearMetaMaskStorage(client);\n\n metaMaskClientPromise = null;\n refreshMetaMaskClient();\n },\n events,\n getMetaMaskClient: async () => {\n if (!metaMaskClientPromise) {\n refreshMetaMaskClient();\n }\n\n if (!metaMaskClientPromise) {\n throw new MetaMaskClientNotInitializedError();\n }\n\n return metaMaskClientPromise;\n },\n };\n};\n","import { createRuntimeServiceAccessKey } from '@dynamic-labs-sdk/client/core';\n\nimport { createMetaMaskClientInstanceManager } from '../createMetaMaskClientInstanceManager';\n\nconst META_MASK_CLIENT_INSTANCE_MANAGER_KEY =\n 'META_MASK_CLIENT_INSTANCE_MANAGER';\n\n/**\n * Returns this client's `MetaMaskClientInstanceManager`, creating it on first\n * access. Every chain's MetaMask wallet provider (EVM, Solana, ...) calls\n * this to reach the SAME manager -- and therefore the same shared multichain\n * session -- rather than each building its own.\n *\n * @example\n * ```ts\n * const manager = getOrCreateMetaMaskClientInstanceManager(client);\n * const metaMaskClient = await manager.getMetaMaskClient();\n * ```\n * @param client - The Dynamic client instance.\n * @returns The client's `MetaMaskClientInstanceManager`.\n * @see createMetaMaskClientInstanceManager\n * @see disconnectMetaMaskWalletProvider\n */\nexport const getOrCreateMetaMaskClientInstanceManager =\n createRuntimeServiceAccessKey(\n META_MASK_CLIENT_INSTANCE_MANAGER_KEY,\n (client) => createMetaMaskClientInstanceManager(client)\n );\n"],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { DynamicClient } from '@dynamic-labs-sdk/client';
2
+ import type { MultichainCore } from '@metamask/connect-multichain';
3
+ type Session = Awaited<ReturnType<MultichainCore['provider']['getSession']>>;
4
+ type SessionScopes = NonNullable<Session>['sessionScopes'];
5
+ type ScopeObject = SessionScopes[keyof SessionScopes];
6
+ type ScopeAccounts = NonNullable<ScopeObject['accounts']>;
7
+ export type GetScopeAccountsFromMetaMaskClientParams = {
8
+ metaMaskClient: MultichainCore;
9
+ scope: Parameters<MultichainCore['connect']>[0][number];
10
+ };
11
+ /**
12
+ * Reads the accounts MetaMask granted for a single CAIP-2 scope out of the
13
+ * current session, replacing direct `provider.getSession()` access so chain
14
+ * packages never touch the raw session shape. Empty when there's no session
15
+ * or the scope wasn't granted.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * const accounts = await getScopeAccountsFromMetaMaskClient(
20
+ * { metaMaskClient, scope: 'eip155:1' },
21
+ * client
22
+ * );
23
+ * // ['eip155:1:0x...']
24
+ * ```
25
+ *
26
+ * @param client - The Dynamic client instance whose logger this reports
27
+ * against. Required (rather than defaulting to the last-initialized client)
28
+ * so a missing/empty-scope result is always traceable to the client that
29
+ * requested it.
30
+ * @returns The accounts granted for `scope`, or an empty array if there's no
31
+ * session or the scope wasn't granted.
32
+ * @see createMetaMaskMultichainClient
33
+ * @see getGrantedMetaMaskScopes
34
+ * @notInstrumented
35
+ */
36
+ export declare const getScopeAccountsFromMetaMaskClient: ({ metaMaskClient, scope }: GetScopeAccountsFromMetaMaskClientParams, client: DynamicClient) => Promise<ScopeAccounts>;
37
+ export {};
38
+ //# sourceMappingURL=getScopeAccountsFromMetaMaskClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getScopeAccountsFromMetaMaskClient.d.ts","sourceRoot":"","sources":["../../src/getScopeAccountsFromMetaMaskClient/getScopeAccountsFromMetaMaskClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEnE,KAAK,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AAC7E,KAAK,aAAa,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,eAAe,CAAC,CAAC;AAC3D,KAAK,WAAW,GAAG,aAAa,CAAC,MAAM,aAAa,CAAC,CAAC;AACtD,KAAK,aAAa,GAAG,WAAW,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC;AAE1D,MAAM,MAAM,wCAAwC,GAAG;IACrD,cAAc,EAAE,cAAc,CAAC;IAC/B,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;CACzD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,kCAAkC,8BAClB,wCAAwC,UAC3D,aAAa,KACpB,OAAO,CAAC,aAAa,CAYvB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { getScopeAccountsFromMetaMaskClient } from './getScopeAccountsFromMetaMaskClient';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/getScopeAccountsFromMetaMaskClient/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kCAAkC,EAAE,MAAM,sCAAsC,CAAC"}
package/dist/index.cjs CHANGED
@@ -1,21 +1,15 @@
1
+ const require_getOrCreateMetaMaskClientInstanceManager = require('./getOrCreateMetaMaskClientInstanceManager-l6T7WUT5.cjs');
1
2
  let _dynamic_labs_sdk_assert_package_version = require("@dynamic-labs-sdk/assert-package-version");
2
3
  let _dynamic_labs_sdk_client_core = require("@dynamic-labs-sdk/client/core");
3
4
  let _dynamic_labs_sdk_client = require("@dynamic-labs-sdk/client");
4
5
  let _dynamic_labs_sdk_api_core = require("@dynamic-labs/sdk-api-core");
5
6
 
6
- //#region package.json
7
- var name = "@dynamic-labs-sdk/metamask";
8
- var version = "1.31.0";
9
-
10
- //#endregion
11
7
  //#region src/clearMetaMaskSessionStorage/clearMetaMaskSessionStorage.ts
12
- const METAMASK_SDK_IDB_NAME = "mmconnect-kv-store";
13
- const FAILED_TO_CLEAR_SESSION_MESSAGE = "[metamask] failed to clear the persisted session from IndexedDB; the next pairing may resume a stale session instead of showing a new one";
14
8
  /**
15
- * Deletes the MetaMask SDK's IndexedDB session storage so the next connect call
16
- * emits a fresh `display_uri` synchronously instead of spending the SDK's
17
- * 10-second resume timeout reviving a dead pairing. Safe in SSR (no-op) and
18
- * when the DB is held open by another tab (resolves on `blocked`).
9
+ * Resets the MetaMask SDK's persisted session so the next connect call
10
+ * emits a fresh `display_uri` instead of resuming a stale pairing.
11
+ *
12
+ * @deprecated The clearMetaMaskSessionStorage is not needed anymore since the SDK itself will handle the storage
19
13
  *
20
14
  * @example
21
15
  * ```ts
@@ -26,31 +20,36 @@ const FAILED_TO_CLEAR_SESSION_MESSAGE = "[metamask] failed to clear the persiste
26
20
  * @param client - The Dynamic client instance. Required (rather than
27
21
  * defaulting to the last-initialized client) so a storage-clear failure is
28
22
  * always logged against the client that actually requested it.
29
- * @returns A promise that resolves once the database is deleted (or immediately in SSR).
23
+ * @returns A promise that resolves once the persisted session is reset.
30
24
  * @see connectWithMetaMaskUri
31
- * @see getMetaMaskExtensionWalletProviderKey
25
+ * @see createMetaMaskClientInstanceManager
32
26
  * @notInstrumented
33
27
  */
34
- const clearMetaMaskSessionStorage = (client) => {
35
- if (typeof indexedDB === "undefined") return Promise.resolve();
36
- return new Promise((resolve) => {
37
- try {
38
- const request = indexedDB.deleteDatabase(METAMASK_SDK_IDB_NAME);
39
- request.onsuccess = () => resolve();
40
- request.onerror = () => {
41
- (0, _dynamic_labs_sdk_client_core.getCore)(client).logger.warn(FAILED_TO_CLEAR_SESSION_MESSAGE, request.error);
42
- resolve();
43
- };
44
- request.onblocked = () => resolve();
45
- } catch (error) {
46
- (0, _dynamic_labs_sdk_client_core.getCore)(client).logger.warn(FAILED_TO_CLEAR_SESSION_MESSAGE, error);
47
- resolve();
48
- }
49
- });
50
- };
28
+ const clearMetaMaskSessionStorage = (client) => require_getOrCreateMetaMaskClientInstanceManager.clearMetaMaskStorage(client);
51
29
 
52
30
  //#endregion
53
31
  //#region src/errors/MetaMaskDisplayUriMissingError/MetaMaskDisplayUriMissingError.ts
32
+ /**
33
+ * Thrown when the MetaMask SDK's `connect()` call settles (resolves or
34
+ * rejects) without ever emitting a `display_uri` event. `connectWithMetaMaskUri`
35
+ * requires that event to produce the pairing URI/QR code; without it, there
36
+ * is nothing to render and the caller would otherwise hang indefinitely
37
+ * awaiting a URI that will never arrive.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * try {
42
+ * await connectWithMetaMaskUri({ onDisplayUri }, client);
43
+ * } catch (error) {
44
+ * if (error instanceof MetaMaskDisplayUriMissingError) {
45
+ * // The MetaMask SDK never produced a pairing URI; surface a generic
46
+ * // connection failure instead of hanging.
47
+ * }
48
+ * }
49
+ * ```
50
+ * @see connectWithMetaMaskUri
51
+ * @see MetaMaskUnscopedNetworkError
52
+ */
54
53
  var MetaMaskDisplayUriMissingError = class extends _dynamic_labs_sdk_client.BaseError {
55
54
  constructor() {
56
55
  super({
@@ -87,7 +86,7 @@ const METAMASK_NAME_NEEDLE = "metamask";
87
86
  * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
88
87
  * @returns The wallet provider key string, or `undefined` if no MetaMask extension is announced.
89
88
  * @see connectWithMetaMaskUri
90
- * @see clearMetaMaskSessionStorage
89
+ * @see clearMetaMaskStorage
91
90
  * @notInstrumented
92
91
  */
93
92
  const getMetaMaskExtensionWalletProviderKey = ({ chain }, client = (0, _dynamic_labs_sdk_client_core.getDefaultClient)()) => {
@@ -109,33 +108,41 @@ const getMetaMaskExtensionWalletProviderKey = ({ chain }, client = (0, _dynamic_
109
108
  * ```ts
110
109
  * const { uri, approval } = await connectWithMetaMaskUri({
111
110
  * chain: 'EVM',
112
- * getController: (client) => getEvmMetaMaskController(client),
113
111
  * walletProviderBuilder: (client) => buildEvmWalletProvider(client),
114
112
  * });
115
113
  * // Render QR code with `uri`, then await approval()
116
114
  * ```
117
115
  *
118
116
  * @param params.chain - Chain being connected; used to scope the extension-installed lookup.
119
- * @param params.getController - Returns the chain-specific MetaMaskController for the pairing.
120
117
  * @param params.walletProviderBuilder - Builds the chain-specific WalletProvider after pairing approval.
121
118
  * @param [params.addToDynamicWalletAccounts] - Whether to add the wallet to the client. Defaults to `true`.
122
119
  * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
123
120
  * @returns An object with `uri` (the pairing URI) and `approval` (async function resolving to wallet accounts).
124
121
  * @throws {MetaMaskDisplayUriMissingError} If `connect` settles before a display_uri is emitted.
125
122
  * @throws {NoAddressFoundError} If no address is returned after pairing approval.
126
- * @see clearMetaMaskSessionStorage
123
+ * @see clearMetaMaskStorage
127
124
  * @see getMetaMaskExtensionWalletProviderKey
128
125
  * @notInstrumented
129
126
  */
130
- const connectWithMetaMaskUri = async ({ addToDynamicWalletAccounts = true, chain, getController, walletProviderBuilder }, client = (0, _dynamic_labs_sdk_client_core.getDefaultClient)()) => {
127
+ const connectWithMetaMaskUri = async ({ addToDynamicWalletAccounts = true, chain, walletProviderBuilder }, client = (0, _dynamic_labs_sdk_client_core.getDefaultClient)()) => {
128
+ const { logger } = (0, _dynamic_labs_sdk_client_core.getCore)(client);
131
129
  const announcedKey = getMetaMaskExtensionWalletProviderKey({ chain }, client);
132
- if (announcedKey !== void 0) (0, _dynamic_labs_sdk_client_core.getCore)(client).logger.warn(`[metamask] MetaMask extension is announced for ${chain} as wallet provider "${announcedKey}"; proceeding with URI pairing. Consider connectWithWalletProvider({ walletProviderKey: "${announcedKey}" }) for the best user experience.`);
133
- const controller = await getController(client);
134
130
  const uriDeferred = (0, _dynamic_labs_sdk_client_core.createDeferredPromise)();
135
- const unsubscribe = controller.onDisplayUri((displayUri) => {
131
+ const connectionScopes = require_getOrCreateMetaMaskClientInstanceManager.getMetaMaskScopes({ chain }, client);
132
+ const metaMaskClientInstanceManager = require_getOrCreateMetaMaskClientInstanceManager.getOrCreateMetaMaskClientInstanceManager(client);
133
+ await metaMaskClientInstanceManager.clearMetaMaskStorageAndInstance();
134
+ const metaMaskClient = await metaMaskClientInstanceManager.getMetaMaskClient();
135
+ if (announcedKey !== void 0) logger.warn(`[MetaMask:Connect] Extension is announced for ${chain} as wallet provider "${announcedKey}"; proceeding with URI pairing anyway. Consider connectWithWalletProvider({ walletProviderKey: "${announcedKey}" }) for the best user experience.`);
136
+ const onDisplayUri = (displayUri) => {
137
+ logger.debug("[MetaMask:Connect] Received display_uri event", { displayUri });
136
138
  uriDeferred.resolve(displayUri);
139
+ };
140
+ metaMaskClientInstanceManager.events.on("display_uri", onDisplayUri);
141
+ logger.debug("[MetaMask:Connect] Requesting URI pairing", {
142
+ chain,
143
+ connectionScopes
137
144
  });
138
- const connectPromise = controller.connect();
145
+ const connectPromise = metaMaskClient.connect(connectionScopes, []);
139
146
  connectPromise.then(() => {
140
147
  uriDeferred.reject(new MetaMaskDisplayUriMissingError());
141
148
  }).catch((error) => {
@@ -144,17 +151,24 @@ const connectWithMetaMaskUri = async ({ addToDynamicWalletAccounts = true, chain
144
151
  let uri;
145
152
  try {
146
153
  uri = await uriDeferred.promise;
154
+ logger.debug("[MetaMask:Connect] URI ready for display", { chain });
147
155
  } finally {
148
- unsubscribe();
156
+ metaMaskClientInstanceManager.events.off("display_uri", onDisplayUri);
149
157
  }
150
158
  const approval = async () => {
151
159
  await connectPromise;
152
- const walletProvider = await walletProviderBuilder(client);
160
+ logger.debug("[MetaMask:Connect] Pairing approved", { chain });
161
+ const walletProvider = walletProviderBuilder(client);
162
+ (0, _dynamic_labs_sdk_client_core.getWalletProviderRegistry)(client).unregister(walletProvider.key);
153
163
  (0, _dynamic_labs_sdk_client_core.getWalletProviderRegistry)(client).register({
154
164
  priority: _dynamic_labs_sdk_client_core.WalletProviderPriority.WALLET_SDK,
155
165
  walletProvider
156
166
  });
157
167
  const { addresses } = await walletProvider.getConnectedAddresses();
168
+ logger.debug("[MetaMask:Connect] Connected addresses resolved", {
169
+ addresses,
170
+ chain
171
+ });
158
172
  const mainAddress = addresses[0];
159
173
  if (mainAddress === void 0) throw new _dynamic_labs_sdk_client.NoAddressFoundError();
160
174
  return { walletAccounts: (0, _dynamic_labs_sdk_client_core.reconcileWalletAccountsAgainstClient)({
@@ -180,27 +194,13 @@ const connectWithMetaMaskUri = async ({ addToDynamicWalletAccounts = true, chain
180
194
  };
181
195
  };
182
196
 
183
- //#endregion
184
- //#region src/errors/MetaMaskWalletNotConnectedError/MetaMaskWalletNotConnectedError.ts
185
- var MetaMaskWalletNotConnectedError = class extends _dynamic_labs_sdk_client.BaseError {
186
- constructor() {
187
- super({
188
- cause: null,
189
- code: "metamask_wallet_not_connected",
190
- docsUrl: null,
191
- name: "MetaMaskWalletNotConnectedError",
192
- shortMessage: "MetaMask SDK has no connected wallet account. Complete the URI pairing (await the connect approval) before building the MetaMask wallet provider."
193
- });
194
- }
195
- };
196
-
197
197
  //#endregion
198
198
  //#region src/exports/index.ts
199
- (0, _dynamic_labs_sdk_assert_package_version.assertPackageVersion)(name, version);
199
+ (0, _dynamic_labs_sdk_assert_package_version.assertPackageVersion)(require_getOrCreateMetaMaskClientInstanceManager.name, require_getOrCreateMetaMaskClientInstanceManager.version);
200
200
 
201
201
  //#endregion
202
202
  exports.MetaMaskDisplayUriMissingError = MetaMaskDisplayUriMissingError;
203
- exports.MetaMaskWalletNotConnectedError = MetaMaskWalletNotConnectedError;
203
+ exports.MetaMaskUnscopedNetworkError = require_getOrCreateMetaMaskClientInstanceManager.MetaMaskUnscopedNetworkError;
204
204
  exports.clearMetaMaskSessionStorage = clearMetaMaskSessionStorage;
205
205
  exports.connectWithMetaMaskUri = connectWithMetaMaskUri;
206
206
  exports.getMetaMaskExtensionWalletProviderKey = getMetaMaskExtensionWalletProviderKey;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["BaseError","WalletProviderEnum","uri: string","WalletProviderPriority","NoAddressFoundError","BaseError"],"sources":["../package.json","../src/clearMetaMaskSessionStorage/clearMetaMaskSessionStorage.ts","../src/errors/MetaMaskDisplayUriMissingError/MetaMaskDisplayUriMissingError.ts","../src/getMetaMaskExtensionWalletProviderKey/getMetaMaskExtensionWalletProviderKey.ts","../src/connectWithMetaMaskUri/connectWithMetaMaskUri.ts","../src/errors/MetaMaskWalletNotConnectedError/MetaMaskWalletNotConnectedError.ts","../src/exports/index.ts"],"sourcesContent":["","import type { DynamicClient } from '@dynamic-labs-sdk/client';\nimport { getCore } from '@dynamic-labs-sdk/client/core';\n\n// MetaMask SDK persists session state in this IndexedDB database.\n// Hardcoded inside `@metamask/connect-multichain` (the SDK shared by\n// every chain-specific connect-* facade) as `${DB_NAME}${dbNameSuffix}`\n// → `mmconnect` + `-kv-store` on web.\nconst METAMASK_SDK_IDB_NAME = 'mmconnect-kv-store';\n\nconst FAILED_TO_CLEAR_SESSION_MESSAGE =\n '[metamask] failed to clear the persisted session from IndexedDB; the next pairing may resume a stale session instead of showing a new one';\n\n/**\n * Deletes the MetaMask SDK's IndexedDB session storage so the next connect call\n * emits a fresh `display_uri` synchronously instead of spending the SDK's\n * 10-second resume timeout reviving a dead pairing. Safe in SSR (no-op) and\n * when the DB is held open by another tab (resolves on `blocked`).\n *\n * @example\n * ```ts\n * await clearMetaMaskSessionStorage(client);\n * // Next connectWithMetaMaskUri call will emit a fresh URI immediately.\n * ```\n *\n * @param client - The Dynamic client instance. Required (rather than\n * defaulting to the last-initialized client) so a storage-clear failure is\n * always logged against the client that actually requested it.\n * @returns A promise that resolves once the database is deleted (or immediately in SSR).\n * @see connectWithMetaMaskUri\n * @see getMetaMaskExtensionWalletProviderKey\n * @notInstrumented\n */\nexport const clearMetaMaskSessionStorage = (\n // No default: avoids misattributing the failure-path warning below.\n // eslint-disable-next-line custom-rules/check-dynamic-client-param-in-external-functions\n client: DynamicClient\n): Promise<void> => {\n if (typeof indexedDB === 'undefined') {\n return Promise.resolve();\n }\n\n return new Promise<void>((resolve) => {\n try {\n const request = indexedDB.deleteDatabase(METAMASK_SDK_IDB_NAME);\n request.onsuccess = () => resolve();\n // `onblocked` fires when a concurrent tab holds the DB open; that is\n // expected multi-tab behaviour, not a failure, so it resolves quietly.\n // We still resolve on `onerror` so the consumer's connect flow is not\n // stalled indefinitely, but it is logged first: a failed delete here\n // puts the caller back on the stale session it was trying to escape.\n // The Promise executor already ignores subsequent resolve calls, so no\n // extra guard is needed when multiple lifecycle events fire on the\n // same request.\n request.onerror = () => {\n getCore(client).logger.warn(FAILED_TO_CLEAR_SESSION_MESSAGE, request.error);\n resolve();\n };\n request.onblocked = () => resolve();\n } catch (error) {\n getCore(client).logger.warn(FAILED_TO_CLEAR_SESSION_MESSAGE, error);\n resolve();\n }\n });\n};\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\nexport class MetaMaskDisplayUriMissingError extends BaseError {\n constructor() {\n super({\n cause: null,\n code: 'metamask_display_uri_missing',\n docsUrl: null,\n name: 'MetaMaskDisplayUriMissingError',\n shortMessage:\n 'MetaMask SDK completed the connection without emitting a display_uri. The connect helper requires the SDK to produce a pairing URI. Please reach out to Dynamic about this error.',\n });\n }\n}\n","import type { Chain, DynamicClient } from '@dynamic-labs-sdk/client';\nimport {\n getDefaultClient,\n getWalletProviderRegistry,\n} from '@dynamic-labs-sdk/client/core';\nimport { WalletProviderEnum } from '@dynamic-labs/sdk-api-core';\n\nconst METAMASK_NAME_NEEDLE = 'metamask';\n\ntype GetMetaMaskExtensionWalletProviderKeyParams = {\n /** Chain to scope the lookup to. */\n chain: Chain;\n};\n\n/**\n * Returns the wallet provider key of the MetaMask browser extension announced\n * for the given chain (EIP-6963 on EVM, Wallet Standard on Solana), or\n * `undefined` when none is announced. Matches on normalized display name to\n * cover MetaMask, Flask, and other variants. Synchronous and safe to call from\n * a React render. Pass the returned key to `connectWithWalletProvider` to route\n * the connection through the announced provider; fall back to the chain's\n * `connectWithMetaMaskUri<Chain>` helper when `undefined`.\n *\n * @example\n * ```ts\n * const key = getMetaMaskExtensionWalletProviderKey({ chain: 'EVM' });\n * if (key) {\n * await connectWithWalletProvider({ walletProviderKey: key });\n * }\n * ```\n *\n * @param params.chain - Chain to scope the lookup to.\n * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.\n * @returns The wallet provider key string, or `undefined` if no MetaMask extension is announced.\n * @see connectWithMetaMaskUri\n * @see clearMetaMaskSessionStorage\n * @notInstrumented\n */\nexport const getMetaMaskExtensionWalletProviderKey = (\n { chain }: GetMetaMaskExtensionWalletProviderKeyParams,\n client: DynamicClient = getDefaultClient()\n): string | undefined => {\n const providers = getWalletProviderRegistry(client).listProviders();\n\n const match = providers.find(\n (provider) =>\n provider.chain === chain &&\n provider.walletProviderType === WalletProviderEnum.BrowserExtension &&\n provider.metadata.displayName\n ?.toLowerCase()\n .includes(METAMASK_NAME_NEEDLE)\n );\n\n return match?.key;\n};\n","import type {\n Chain,\n DynamicClient,\n WalletAccount,\n WalletProviderUriConnectionResult,\n} from '@dynamic-labs-sdk/client';\nimport { NoAddressFoundError } from '@dynamic-labs-sdk/client';\nimport type { WalletProvider } from '@dynamic-labs-sdk/client/core';\nimport {\n WalletProviderPriority,\n createDeferredPromise,\n formatWalletAccountId,\n getCore,\n getDefaultClient,\n getWalletProviderRegistry,\n reconcileWalletAccountsAgainstClient,\n} from '@dynamic-labs-sdk/client/core';\n\nimport { MetaMaskDisplayUriMissingError } from '../errors/MetaMaskDisplayUriMissingError';\nimport { getMetaMaskExtensionWalletProviderKey } from '../getMetaMaskExtensionWalletProviderKey';\nimport type { MetaMaskController } from '../metamask.types';\n\nexport type ConnectWithMetaMaskUriParams = {\n /** Whether to add the connected wallet account to the Dynamic client. Defaults to `true`. */\n addToDynamicWalletAccounts?: boolean;\n /** Chain being connected; used to scope the extension-installed lookup. */\n chain: Chain;\n /** Returns the chain-specific `MetaMaskController` that drives the pairing. */\n getController: (client: DynamicClient) => Promise<MetaMaskController>;\n /**\n * Builds the chain-specific `WalletProvider` AFTER the pairing has been\n * approved. Must NOT include a `connect` method — the provider is registered\n * purely for signing routing and would otherwise leak into the wallet picker.\n */\n walletProviderBuilder: (client: DynamicClient) => Promise<WalletProvider>;\n};\n\n/**\n * Drives a MetaMask SDK pairing for any chain and returns `{ approval, uri }`\n * so consumers can render the QR / hand the URI to a deeplink. Logs an\n * advisory warning when the extension is already announced for the chain —\n * pairing still proceeds, but the consumer is told which announced provider\n * key to route through for the best UX. Builds and registers the chain-\n * specific wallet provider only after pairing is approved; the provider\n * therefore never appears in the wallet picker (no `connect` method).\n *\n * @example\n * ```ts\n * const { uri, approval } = await connectWithMetaMaskUri({\n * chain: 'EVM',\n * getController: (client) => getEvmMetaMaskController(client),\n * walletProviderBuilder: (client) => buildEvmWalletProvider(client),\n * });\n * // Render QR code with `uri`, then await approval()\n * ```\n *\n * @param params.chain - Chain being connected; used to scope the extension-installed lookup.\n * @param params.getController - Returns the chain-specific MetaMaskController for the pairing.\n * @param params.walletProviderBuilder - Builds the chain-specific WalletProvider after pairing approval.\n * @param [params.addToDynamicWalletAccounts] - Whether to add the wallet to the client. Defaults to `true`.\n * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.\n * @returns An object with `uri` (the pairing URI) and `approval` (async function resolving to wallet accounts).\n * @throws {MetaMaskDisplayUriMissingError} If `connect` settles before a display_uri is emitted.\n * @throws {NoAddressFoundError} If no address is returned after pairing approval.\n * @see clearMetaMaskSessionStorage\n * @see getMetaMaskExtensionWalletProviderKey\n * @notInstrumented\n */\nexport const connectWithMetaMaskUri = async (\n {\n addToDynamicWalletAccounts = true,\n chain,\n getController,\n walletProviderBuilder,\n }: ConnectWithMetaMaskUriParams,\n client: DynamicClient = getDefaultClient()\n): Promise<WalletProviderUriConnectionResult> => {\n const announcedKey = getMetaMaskExtensionWalletProviderKey({ chain }, client);\n\n if (announcedKey !== undefined) {\n getCore(client).logger.warn(\n `[metamask] MetaMask extension is announced for ${chain} as wallet provider \"${announcedKey}\"; proceeding with URI pairing. Consider connectWithWalletProvider({ walletProviderKey: \"${announcedKey}\" }) for the best user experience.`\n );\n }\n\n const controller = await getController(client);\n\n const uriDeferred = createDeferredPromise<string>();\n\n const unsubscribe = controller.onDisplayUri((displayUri) => {\n uriDeferred.resolve(displayUri);\n });\n\n const connectPromise = controller.connect();\n\n // If `connect` settles before a `display_uri` is emitted, no URI was made\n // available and the pairing is unusable. Reject the deferred so the caller\n // surfaces `MetaMaskDisplayUriMissingError` (or the underlying failure).\n connectPromise\n .then(() => {\n uriDeferred.reject(new MetaMaskDisplayUriMissingError());\n })\n .catch((error: unknown) => {\n uriDeferred.reject(error);\n });\n\n let uri: string;\n try {\n uri = await uriDeferred.promise;\n } finally {\n unsubscribe();\n }\n\n const approval = async (): Promise<{ walletAccounts: WalletAccount[] }> => {\n await connectPromise;\n\n const walletProvider = await walletProviderBuilder(client);\n\n getWalletProviderRegistry(client).register({\n priority: WalletProviderPriority.WALLET_SDK,\n walletProvider,\n });\n\n const { addresses } = await walletProvider.getConnectedAddresses();\n\n // MetaMask SDK exposes a single active address per pairing (same model as\n // EIP-1193 `eth_accounts`); we only materialize the first one.\n const mainAddress = addresses[0];\n\n if (mainAddress === undefined) {\n throw new NoAddressFoundError();\n }\n\n const walletAccount: WalletAccount = {\n address: mainAddress,\n chain: walletProvider.chain,\n id: formatWalletAccountId({\n address: mainAddress,\n chain: walletProvider.chain,\n walletProviderKey: walletProvider.key,\n }),\n lastSelectedAt: null,\n verifiedCredentialId: null,\n walletProviderKey: walletProvider.key,\n };\n\n const walletAccounts = reconcileWalletAccountsAgainstClient(\n {\n addToDynamicWalletAccounts,\n walletAccounts: [walletAccount],\n walletProviderKey: walletProvider.key,\n },\n client\n );\n\n return { walletAccounts };\n };\n\n return { approval, uri };\n};\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\nexport class MetaMaskWalletNotConnectedError extends BaseError {\n constructor() {\n super({\n cause: null,\n code: 'metamask_wallet_not_connected',\n docsUrl: null,\n name: 'MetaMaskWalletNotConnectedError',\n shortMessage:\n 'MetaMask SDK has no connected wallet account. Complete the URI pairing (await the connect approval) before building the MetaMask wallet provider.',\n });\n }\n}\n","import { assertPackageVersion } from '@dynamic-labs-sdk/assert-package-version';\n\nimport { name, version } from '../../package.json';\n\nassertPackageVersion(name, version);\n\nexport { clearMetaMaskSessionStorage } from '../clearMetaMaskSessionStorage';\nexport { connectWithMetaMaskUri } from '../connectWithMetaMaskUri';\nexport type { ConnectWithMetaMaskUriParams } from '../connectWithMetaMaskUri';\nexport { MetaMaskDisplayUriMissingError } from '../errors/MetaMaskDisplayUriMissingError';\nexport { MetaMaskWalletNotConnectedError } from '../errors/MetaMaskWalletNotConnectedError';\nexport { getMetaMaskExtensionWalletProviderKey } from '../getMetaMaskExtensionWalletProviderKey';\nexport type {\n DisplayUriListener,\n MetaMaskController,\n} from '../metamask.types';\n"],"mappings":";;;;;;;;;;;ACOA,MAAM,wBAAwB;AAE9B,MAAM,kCACJ;;;;;;;;;;;;;;;;;;;;;AAsBF,MAAa,+BAGX,WACkB;AAClB,KAAI,OAAO,cAAc,YACvB,QAAO,QAAQ,SAAS;AAG1B,QAAO,IAAI,SAAe,YAAY;AACpC,MAAI;GACF,MAAM,UAAU,UAAU,eAAe,sBAAsB;AAC/D,WAAQ,kBAAkB,SAAS;AASnC,WAAQ,gBAAgB;AACtB,+CAAQ,OAAO,CAAC,OAAO,KAAK,iCAAiC,QAAQ,MAAM;AAC3E,aAAS;;AAEX,WAAQ,kBAAkB,SAAS;WAC5B,OAAO;AACd,8CAAQ,OAAO,CAAC,OAAO,KAAK,iCAAiC,MAAM;AACnE,YAAS;;GAEX;;;;;AC5DJ,IAAa,iCAAb,cAAoDA,mCAAU;CAC5D,cAAc;AACZ,QAAM;GACJ,OAAO;GACP,MAAM;GACN,SAAS;GACT,MAAM;GACN,cACE;GACH,CAAC;;;;;;ACJN,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;AA+B7B,MAAa,yCACX,EAAE,SACF,8DAA0C,KACnB;AAYvB,qEAX4C,OAAO,CAAC,eAAe,CAE3C,MACrB,aACC,SAAS,UAAU,SACnB,SAAS,uBAAuBC,8CAAmB,oBACnD,SAAS,SAAS,aACd,aAAa,CACd,SAAS,qBAAqB,CACpC,EAEa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACehB,MAAa,yBAAyB,OACpC,EACE,6BAA6B,MAC7B,OACA,eACA,yBAEF,8DAA0C,KACK;CAC/C,MAAM,eAAe,sCAAsC,EAAE,OAAO,EAAE,OAAO;AAE7E,KAAI,iBAAiB,OACnB,4CAAQ,OAAO,CAAC,OAAO,KACrB,kDAAkD,MAAM,uBAAuB,aAAa,2FAA2F,aAAa,oCACrM;CAGH,MAAM,aAAa,MAAM,cAAc,OAAO;CAE9C,MAAM,wEAA6C;CAEnD,MAAM,cAAc,WAAW,cAAc,eAAe;AAC1D,cAAY,QAAQ,WAAW;GAC/B;CAEF,MAAM,iBAAiB,WAAW,SAAS;AAK3C,gBACG,WAAW;AACV,cAAY,OAAO,IAAI,gCAAgC,CAAC;GACxD,CACD,OAAO,UAAmB;AACzB,cAAY,OAAO,MAAM;GACzB;CAEJ,IAAIC;AACJ,KAAI;AACF,QAAM,MAAM,YAAY;WAChB;AACR,eAAa;;CAGf,MAAM,WAAW,YAA0D;AACzE,QAAM;EAEN,MAAM,iBAAiB,MAAM,sBAAsB,OAAO;AAE1D,+DAA0B,OAAO,CAAC,SAAS;GACzC,UAAUC,qDAAuB;GACjC;GACD,CAAC;EAEF,MAAM,EAAE,cAAc,MAAM,eAAe,uBAAuB;EAIlE,MAAM,cAAc,UAAU;AAE9B,MAAI,gBAAgB,OAClB,OAAM,IAAIC,8CAAqB;AAyBjC,SAAO,EAAE,wFARP;GACE;GACA,gBAAgB,CAhBiB;IACnC,SAAS;IACT,OAAO,eAAe;IACtB,6DAA0B;KACxB,SAAS;KACT,OAAO,eAAe;KACtB,mBAAmB,eAAe;KACnC,CAAC;IACF,gBAAgB;IAChB,sBAAsB;IACtB,mBAAmB,eAAe;IACnC,CAKkC;GAC/B,mBAAmB,eAAe;GACnC,EACD,OACD,EAEwB;;AAG3B,QAAO;EAAE;EAAU;EAAK;;;;;AC5J1B,IAAa,kCAAb,cAAqDC,mCAAU;CAC7D,cAAc;AACZ,QAAM;GACJ,OAAO;GACP,MAAM;GACN,SAAS;GACT,MAAM;GACN,cACE;GACH,CAAC;;;;;;mECPe,MAAM,QAAQ"}
1
+ {"version":3,"file":"index.cjs","names":["clearMetaMaskStorage","BaseError","WalletProviderEnum","getMetaMaskScopes","getOrCreateMetaMaskClientInstanceManager","uri: string","WalletProviderPriority","NoAddressFoundError","name","version"],"sources":["../src/clearMetaMaskSessionStorage/clearMetaMaskSessionStorage.ts","../src/errors/MetaMaskDisplayUriMissingError/MetaMaskDisplayUriMissingError.ts","../src/getMetaMaskExtensionWalletProviderKey/getMetaMaskExtensionWalletProviderKey.ts","../src/connectWithMetaMaskUri/connectWithMetaMaskUri.ts","../src/exports/index.ts"],"sourcesContent":["import type { DynamicClient } from '@dynamic-labs-sdk/client';\n\nimport { clearMetaMaskStorage } from '../metaMaskStorage/clearMetaMaskStorage';\n\n/**\n * Resets the MetaMask SDK's persisted session so the next connect call\n * emits a fresh `display_uri` instead of resuming a stale pairing.\n *\n * @deprecated The clearMetaMaskSessionStorage is not needed anymore since the SDK itself will handle the storage\n *\n * @example\n * ```ts\n * await clearMetaMaskSessionStorage(client);\n * // Next connectWithMetaMaskUri call will emit a fresh URI immediately.\n * ```\n *\n * @param client - The Dynamic client instance. Required (rather than\n * defaulting to the last-initialized client) so a storage-clear failure is\n * always logged against the client that actually requested it.\n * @returns A promise that resolves once the persisted session is reset.\n * @see connectWithMetaMaskUri\n * @see createMetaMaskClientInstanceManager\n * @notInstrumented\n */\nexport const clearMetaMaskSessionStorage = (\n // eslint-disable-next-line custom-rules/check-dynamic-client-param-in-external-functions\n client: DynamicClient\n): Promise<void> => clearMetaMaskStorage(client);\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\n/**\n * Thrown when the MetaMask SDK's `connect()` call settles (resolves or\n * rejects) without ever emitting a `display_uri` event. `connectWithMetaMaskUri`\n * requires that event to produce the pairing URI/QR code; without it, there\n * is nothing to render and the caller would otherwise hang indefinitely\n * awaiting a URI that will never arrive.\n *\n * @example\n * ```ts\n * try {\n * await connectWithMetaMaskUri({ onDisplayUri }, client);\n * } catch (error) {\n * if (error instanceof MetaMaskDisplayUriMissingError) {\n * // The MetaMask SDK never produced a pairing URI; surface a generic\n * // connection failure instead of hanging.\n * }\n * }\n * ```\n * @see connectWithMetaMaskUri\n * @see MetaMaskUnscopedNetworkError\n */\nexport class MetaMaskDisplayUriMissingError extends BaseError {\n constructor() {\n super({\n cause: null,\n code: 'metamask_display_uri_missing',\n docsUrl: null,\n name: 'MetaMaskDisplayUriMissingError',\n shortMessage:\n 'MetaMask SDK completed the connection without emitting a display_uri. The connect helper requires the SDK to produce a pairing URI. Please reach out to Dynamic about this error.',\n });\n }\n}\n","import type { Chain, DynamicClient } from '@dynamic-labs-sdk/client';\nimport {\n getDefaultClient,\n getWalletProviderRegistry,\n} from '@dynamic-labs-sdk/client/core';\nimport { WalletProviderEnum } from '@dynamic-labs/sdk-api-core';\n\nconst METAMASK_NAME_NEEDLE = 'metamask';\n\ntype GetMetaMaskExtensionWalletProviderKeyParams = {\n /** Chain to scope the lookup to. */\n chain: Chain;\n};\n\n/**\n * Returns the wallet provider key of the MetaMask browser extension announced\n * for the given chain (EIP-6963 on EVM, Wallet Standard on Solana), or\n * `undefined` when none is announced. Matches on normalized display name to\n * cover MetaMask, Flask, and other variants. Synchronous and safe to call from\n * a React render. Pass the returned key to `connectWithWalletProvider` to route\n * the connection through the announced provider; fall back to the chain's\n * `connectWithMetaMaskUri<Chain>` helper when `undefined`.\n *\n * @example\n * ```ts\n * const key = getMetaMaskExtensionWalletProviderKey({ chain: 'EVM' });\n * if (key) {\n * await connectWithWalletProvider({ walletProviderKey: key });\n * }\n * ```\n *\n * @param params.chain - Chain to scope the lookup to.\n * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.\n * @returns The wallet provider key string, or `undefined` if no MetaMask extension is announced.\n * @see connectWithMetaMaskUri\n * @see clearMetaMaskStorage\n * @notInstrumented\n */\nexport const getMetaMaskExtensionWalletProviderKey = (\n { chain }: GetMetaMaskExtensionWalletProviderKeyParams,\n client: DynamicClient = getDefaultClient()\n): string | undefined => {\n const providers = getWalletProviderRegistry(client).listProviders();\n\n const match = providers.find(\n (provider) =>\n provider.chain === chain &&\n provider.walletProviderType === WalletProviderEnum.BrowserExtension &&\n provider.metadata.displayName\n ?.toLowerCase()\n .includes(METAMASK_NAME_NEEDLE)\n );\n\n return match?.key;\n};\n","import type {\n Chain,\n DynamicClient,\n WalletAccount,\n WalletProviderUriConnectionResult,\n} from '@dynamic-labs-sdk/client';\nimport { NoAddressFoundError } from '@dynamic-labs-sdk/client';\nimport type { WalletProvider } from '@dynamic-labs-sdk/client/core';\nimport {\n WalletProviderPriority,\n createDeferredPromise,\n formatWalletAccountId,\n getCore,\n getDefaultClient,\n getWalletProviderRegistry,\n reconcileWalletAccountsAgainstClient,\n} from '@dynamic-labs-sdk/client/core';\n\nimport { MetaMaskDisplayUriMissingError } from '../errors/MetaMaskDisplayUriMissingError';\nimport { getMetaMaskExtensionWalletProviderKey } from '../getMetaMaskExtensionWalletProviderKey';\nimport { getMetaMaskScopes } from '../getMetaMaskScopes';\nimport { getOrCreateMetaMaskClientInstanceManager } from '../metaMaskClientInstanceManager/getOrCreateMetaMaskClientInstanceManager';\n\nexport type ConnectWithMetaMaskUriParams = {\n /** Whether to add the connected wallet account to the Dynamic client. Defaults to `true`. */\n addToDynamicWalletAccounts?: boolean;\n /** Chain being connected; used to scope the extension-installed lookup. */\n chain: Chain;\n /**\n * Builds the chain-specific `WalletProvider` AFTER the pairing has been\n * approved. Must NOT include a `connect` method — the provider is registered\n * purely for signing routing and would otherwise leak into the wallet picker.\n */\n walletProviderBuilder: (client: DynamicClient) => WalletProvider;\n};\n\n/**\n * Drives a MetaMask SDK pairing for any chain and returns `{ approval, uri }`\n * so consumers can render the QR / hand the URI to a deeplink. Logs an\n * advisory warning when the extension is already announced for the chain —\n * pairing still proceeds, but the consumer is told which announced provider\n * key to route through for the best UX. Builds and registers the chain-\n * specific wallet provider only after pairing is approved; the provider\n * therefore never appears in the wallet picker (no `connect` method).\n *\n * @example\n * ```ts\n * const { uri, approval } = await connectWithMetaMaskUri({\n * chain: 'EVM',\n * walletProviderBuilder: (client) => buildEvmWalletProvider(client),\n * });\n * // Render QR code with `uri`, then await approval()\n * ```\n *\n * @param params.chain - Chain being connected; used to scope the extension-installed lookup.\n * @param params.walletProviderBuilder - Builds the chain-specific WalletProvider after pairing approval.\n * @param [params.addToDynamicWalletAccounts] - Whether to add the wallet to the client. Defaults to `true`.\n * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.\n * @returns An object with `uri` (the pairing URI) and `approval` (async function resolving to wallet accounts).\n * @throws {MetaMaskDisplayUriMissingError} If `connect` settles before a display_uri is emitted.\n * @throws {NoAddressFoundError} If no address is returned after pairing approval.\n * @see clearMetaMaskStorage\n * @see getMetaMaskExtensionWalletProviderKey\n * @notInstrumented\n */\nexport const connectWithMetaMaskUri = async (\n {\n addToDynamicWalletAccounts = true,\n chain,\n walletProviderBuilder,\n }: ConnectWithMetaMaskUriParams,\n client: DynamicClient = getDefaultClient()\n): Promise<WalletProviderUriConnectionResult> => {\n const { logger } = getCore(client);\n const announcedKey = getMetaMaskExtensionWalletProviderKey({ chain }, client);\n const uriDeferred = createDeferredPromise<string>();\n const connectionScopes = getMetaMaskScopes({ chain }, client);\n const metaMaskClientInstanceManager =\n getOrCreateMetaMaskClientInstanceManager(client);\n\n await metaMaskClientInstanceManager.clearMetaMaskStorageAndInstance();\n\n const metaMaskClient =\n await metaMaskClientInstanceManager.getMetaMaskClient();\n\n if (announcedKey !== undefined) {\n logger.warn(\n `[MetaMask:Connect] Extension is announced for ${chain} as wallet provider \"${announcedKey}\"; proceeding with URI pairing anyway. Consider connectWithWalletProvider({ walletProviderKey: \"${announcedKey}\" }) for the best user experience.`\n );\n }\n\n // eslint-disable-next-line custom-rules/require-single-object-param -- signature dictated by the SDK's `display_uri` event\n const onDisplayUri = (displayUri: string) => {\n logger.debug('[MetaMask:Connect] Received display_uri event', {\n displayUri,\n });\n\n uriDeferred.resolve(displayUri);\n };\n\n metaMaskClientInstanceManager.events.on('display_uri', onDisplayUri);\n\n logger.debug('[MetaMask:Connect] Requesting URI pairing', {\n chain,\n connectionScopes,\n });\n\n const connectPromise = metaMaskClient.connect(connectionScopes, []);\n\n connectPromise\n .then(() => {\n uriDeferred.reject(new MetaMaskDisplayUriMissingError());\n })\n .catch((error: unknown) => {\n uriDeferred.reject(error);\n });\n\n let uri: string;\n try {\n uri = await uriDeferred.promise;\n logger.debug('[MetaMask:Connect] URI ready for display', { chain });\n } finally {\n metaMaskClientInstanceManager.events.off('display_uri', onDisplayUri);\n }\n\n const approval = async (): Promise<{ walletAccounts: WalletAccount[] }> => {\n await connectPromise;\n logger.debug('[MetaMask:Connect] Pairing approved', { chain });\n\n const walletProvider = walletProviderBuilder(client);\n\n // A chain extension (e.g. addMetaMaskEvmExtension) may have already\n // registered a connect-less SDK placeholder under this same deterministic\n // key at this same WALLET_SDK priority. register() only overwrites an\n // existing key on a strictly higher priority, so registering directly\n // here would silently no-op and leave the placeholder in place -- clear\n // it first so the now-connected provider always takes its slot.\n getWalletProviderRegistry(client).unregister(walletProvider.key);\n getWalletProviderRegistry(client).register({\n priority: WalletProviderPriority.WALLET_SDK,\n walletProvider,\n });\n\n const { addresses } = await walletProvider.getConnectedAddresses();\n logger.debug('[MetaMask:Connect] Connected addresses resolved', {\n addresses,\n chain,\n });\n\n // MetaMask SDK exposes a single active address per pairing (same model as\n // EIP-1193 `eth_accounts`); we only materialize the first one.\n const mainAddress = addresses[0];\n\n if (mainAddress === undefined) {\n throw new NoAddressFoundError();\n }\n\n const walletAccount: WalletAccount = {\n address: mainAddress,\n chain: walletProvider.chain,\n id: formatWalletAccountId({\n address: mainAddress,\n chain: walletProvider.chain,\n walletProviderKey: walletProvider.key,\n }),\n lastSelectedAt: null,\n verifiedCredentialId: null,\n walletProviderKey: walletProvider.key,\n };\n\n const walletAccounts = reconcileWalletAccountsAgainstClient(\n {\n addToDynamicWalletAccounts,\n walletAccounts: [walletAccount],\n walletProviderKey: walletProvider.key,\n },\n client\n );\n\n return { walletAccounts };\n };\n return { approval, uri };\n};\n","import { assertPackageVersion } from '@dynamic-labs-sdk/assert-package-version';\n\nimport { name, version } from '../../package.json';\n\nassertPackageVersion(name, version);\n\nexport { clearMetaMaskSessionStorage } from '../clearMetaMaskSessionStorage';\nexport { connectWithMetaMaskUri } from '../connectWithMetaMaskUri';\nexport type { ConnectWithMetaMaskUriParams } from '../connectWithMetaMaskUri';\nexport { MetaMaskDisplayUriMissingError } from '../errors/MetaMaskDisplayUriMissingError';\nexport { MetaMaskUnscopedNetworkError } from '../errors/MetaMaskUnscopedNetworkError';\nexport { getMetaMaskExtensionWalletProviderKey } from '../getMetaMaskExtensionWalletProviderKey';\nexport type { DisplayUriListener } from '../metamask.types';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAa,+BAEX,WACkBA,sEAAqB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;ACJhD,IAAa,iCAAb,cAAoDC,mCAAU;CAC5D,cAAc;AACZ,QAAM;GACJ,OAAO;GACP,MAAM;GACN,SAAS;GACT,MAAM;GACN,cACE;GACH,CAAC;;;;;;ACzBN,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;AA+B7B,MAAa,yCACX,EAAE,SACF,8DAA0C,KACnB;AAYvB,qEAX4C,OAAO,CAAC,eAAe,CAE3C,MACrB,aACC,SAAS,UAAU,SACnB,SAAS,uBAAuBC,8CAAmB,oBACnD,SAAS,SAAS,aACd,aAAa,CACd,SAAS,qBAAqB,CACpC,EAEa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACYhB,MAAa,yBAAyB,OACpC,EACE,6BAA6B,MAC7B,OACA,yBAEF,8DAA0C,KACK;CAC/C,MAAM,EAAE,sDAAmB,OAAO;CAClC,MAAM,eAAe,sCAAsC,EAAE,OAAO,EAAE,OAAO;CAC7E,MAAM,wEAA6C;CACnD,MAAM,mBAAmBC,mEAAkB,EAAE,OAAO,EAAE,OAAO;CAC7D,MAAM,gCACJC,0FAAyC,OAAO;AAElD,OAAM,8BAA8B,iCAAiC;CAErE,MAAM,iBACJ,MAAM,8BAA8B,mBAAmB;AAEzD,KAAI,iBAAiB,OACnB,QAAO,KACL,iDAAiD,MAAM,uBAAuB,aAAa,kGAAkG,aAAa,oCAC3M;CAIH,MAAM,gBAAgB,eAAuB;AAC3C,SAAO,MAAM,iDAAiD,EAC5D,YACD,CAAC;AAEF,cAAY,QAAQ,WAAW;;AAGjC,+BAA8B,OAAO,GAAG,eAAe,aAAa;AAEpE,QAAO,MAAM,6CAA6C;EACxD;EACA;EACD,CAAC;CAEF,MAAM,iBAAiB,eAAe,QAAQ,kBAAkB,EAAE,CAAC;AAEnE,gBACG,WAAW;AACV,cAAY,OAAO,IAAI,gCAAgC,CAAC;GACxD,CACD,OAAO,UAAmB;AACzB,cAAY,OAAO,MAAM;GACzB;CAEJ,IAAIC;AACJ,KAAI;AACF,QAAM,MAAM,YAAY;AACxB,SAAO,MAAM,4CAA4C,EAAE,OAAO,CAAC;WAC3D;AACR,gCAA8B,OAAO,IAAI,eAAe,aAAa;;CAGvE,MAAM,WAAW,YAA0D;AACzE,QAAM;AACN,SAAO,MAAM,uCAAuC,EAAE,OAAO,CAAC;EAE9D,MAAM,iBAAiB,sBAAsB,OAAO;AAQpD,+DAA0B,OAAO,CAAC,WAAW,eAAe,IAAI;AAChE,+DAA0B,OAAO,CAAC,SAAS;GACzC,UAAUC,qDAAuB;GACjC;GACD,CAAC;EAEF,MAAM,EAAE,cAAc,MAAM,eAAe,uBAAuB;AAClE,SAAO,MAAM,mDAAmD;GAC9D;GACA;GACD,CAAC;EAIF,MAAM,cAAc,UAAU;AAE9B,MAAI,gBAAgB,OAClB,OAAM,IAAIC,8CAAqB;AAyBjC,SAAO,EAAE,wFARP;GACE;GACA,gBAAgB,CAhBiB;IACnC,SAAS;IACT,OAAO,eAAe;IACtB,6DAA0B;KACxB,SAAS;KACT,OAAO,eAAe;KACtB,mBAAmB,eAAe;KACnC,CAAC;IACF,gBAAgB;IAChB,sBAAsB;IACtB,mBAAmB,eAAe;IACnC,CAKkC;GAC/B,mBAAmB,eAAe;GACnC,EACD,OACD,EAEwB;;AAE3B,QAAO;EAAE;EAAU;EAAK;;;;;mECjLLC,uDAAMC,yDAAQ"}
package/dist/index.esm.js CHANGED
@@ -1,21 +1,15 @@
1
+ import { c as name, l as version, n as clearMetaMaskStorage, r as getMetaMaskScopes, s as MetaMaskUnscopedNetworkError, t as getOrCreateMetaMaskClientInstanceManager } from "./getOrCreateMetaMaskClientInstanceManager-DWd07xVz.esm.js";
1
2
  import { assertPackageVersion } from "@dynamic-labs-sdk/assert-package-version";
2
3
  import { WalletProviderPriority, createDeferredPromise, formatWalletAccountId, getCore, getDefaultClient, getWalletProviderRegistry, reconcileWalletAccountsAgainstClient } from "@dynamic-labs-sdk/client/core";
3
4
  import { BaseError, NoAddressFoundError } from "@dynamic-labs-sdk/client";
4
5
  import { WalletProviderEnum } from "@dynamic-labs/sdk-api-core";
5
6
 
6
- //#region package.json
7
- var name = "@dynamic-labs-sdk/metamask";
8
- var version = "1.31.0";
9
-
10
- //#endregion
11
7
  //#region src/clearMetaMaskSessionStorage/clearMetaMaskSessionStorage.ts
12
- const METAMASK_SDK_IDB_NAME = "mmconnect-kv-store";
13
- const FAILED_TO_CLEAR_SESSION_MESSAGE = "[metamask] failed to clear the persisted session from IndexedDB; the next pairing may resume a stale session instead of showing a new one";
14
8
  /**
15
- * Deletes the MetaMask SDK's IndexedDB session storage so the next connect call
16
- * emits a fresh `display_uri` synchronously instead of spending the SDK's
17
- * 10-second resume timeout reviving a dead pairing. Safe in SSR (no-op) and
18
- * when the DB is held open by another tab (resolves on `blocked`).
9
+ * Resets the MetaMask SDK's persisted session so the next connect call
10
+ * emits a fresh `display_uri` instead of resuming a stale pairing.
11
+ *
12
+ * @deprecated The clearMetaMaskSessionStorage is not needed anymore since the SDK itself will handle the storage
19
13
  *
20
14
  * @example
21
15
  * ```ts
@@ -26,31 +20,36 @@ const FAILED_TO_CLEAR_SESSION_MESSAGE = "[metamask] failed to clear the persiste
26
20
  * @param client - The Dynamic client instance. Required (rather than
27
21
  * defaulting to the last-initialized client) so a storage-clear failure is
28
22
  * always logged against the client that actually requested it.
29
- * @returns A promise that resolves once the database is deleted (or immediately in SSR).
23
+ * @returns A promise that resolves once the persisted session is reset.
30
24
  * @see connectWithMetaMaskUri
31
- * @see getMetaMaskExtensionWalletProviderKey
25
+ * @see createMetaMaskClientInstanceManager
32
26
  * @notInstrumented
33
27
  */
34
- const clearMetaMaskSessionStorage = (client) => {
35
- if (typeof indexedDB === "undefined") return Promise.resolve();
36
- return new Promise((resolve) => {
37
- try {
38
- const request = indexedDB.deleteDatabase(METAMASK_SDK_IDB_NAME);
39
- request.onsuccess = () => resolve();
40
- request.onerror = () => {
41
- getCore(client).logger.warn(FAILED_TO_CLEAR_SESSION_MESSAGE, request.error);
42
- resolve();
43
- };
44
- request.onblocked = () => resolve();
45
- } catch (error) {
46
- getCore(client).logger.warn(FAILED_TO_CLEAR_SESSION_MESSAGE, error);
47
- resolve();
48
- }
49
- });
50
- };
28
+ const clearMetaMaskSessionStorage = (client) => clearMetaMaskStorage(client);
51
29
 
52
30
  //#endregion
53
31
  //#region src/errors/MetaMaskDisplayUriMissingError/MetaMaskDisplayUriMissingError.ts
32
+ /**
33
+ * Thrown when the MetaMask SDK's `connect()` call settles (resolves or
34
+ * rejects) without ever emitting a `display_uri` event. `connectWithMetaMaskUri`
35
+ * requires that event to produce the pairing URI/QR code; without it, there
36
+ * is nothing to render and the caller would otherwise hang indefinitely
37
+ * awaiting a URI that will never arrive.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * try {
42
+ * await connectWithMetaMaskUri({ onDisplayUri }, client);
43
+ * } catch (error) {
44
+ * if (error instanceof MetaMaskDisplayUriMissingError) {
45
+ * // The MetaMask SDK never produced a pairing URI; surface a generic
46
+ * // connection failure instead of hanging.
47
+ * }
48
+ * }
49
+ * ```
50
+ * @see connectWithMetaMaskUri
51
+ * @see MetaMaskUnscopedNetworkError
52
+ */
54
53
  var MetaMaskDisplayUriMissingError = class extends BaseError {
55
54
  constructor() {
56
55
  super({
@@ -87,7 +86,7 @@ const METAMASK_NAME_NEEDLE = "metamask";
87
86
  * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
88
87
  * @returns The wallet provider key string, or `undefined` if no MetaMask extension is announced.
89
88
  * @see connectWithMetaMaskUri
90
- * @see clearMetaMaskSessionStorage
89
+ * @see clearMetaMaskStorage
91
90
  * @notInstrumented
92
91
  */
93
92
  const getMetaMaskExtensionWalletProviderKey = ({ chain }, client = getDefaultClient()) => {
@@ -109,33 +108,41 @@ const getMetaMaskExtensionWalletProviderKey = ({ chain }, client = getDefaultCli
109
108
  * ```ts
110
109
  * const { uri, approval } = await connectWithMetaMaskUri({
111
110
  * chain: 'EVM',
112
- * getController: (client) => getEvmMetaMaskController(client),
113
111
  * walletProviderBuilder: (client) => buildEvmWalletProvider(client),
114
112
  * });
115
113
  * // Render QR code with `uri`, then await approval()
116
114
  * ```
117
115
  *
118
116
  * @param params.chain - Chain being connected; used to scope the extension-installed lookup.
119
- * @param params.getController - Returns the chain-specific MetaMaskController for the pairing.
120
117
  * @param params.walletProviderBuilder - Builds the chain-specific WalletProvider after pairing approval.
121
118
  * @param [params.addToDynamicWalletAccounts] - Whether to add the wallet to the client. Defaults to `true`.
122
119
  * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
123
120
  * @returns An object with `uri` (the pairing URI) and `approval` (async function resolving to wallet accounts).
124
121
  * @throws {MetaMaskDisplayUriMissingError} If `connect` settles before a display_uri is emitted.
125
122
  * @throws {NoAddressFoundError} If no address is returned after pairing approval.
126
- * @see clearMetaMaskSessionStorage
123
+ * @see clearMetaMaskStorage
127
124
  * @see getMetaMaskExtensionWalletProviderKey
128
125
  * @notInstrumented
129
126
  */
130
- const connectWithMetaMaskUri = async ({ addToDynamicWalletAccounts = true, chain, getController, walletProviderBuilder }, client = getDefaultClient()) => {
127
+ const connectWithMetaMaskUri = async ({ addToDynamicWalletAccounts = true, chain, walletProviderBuilder }, client = getDefaultClient()) => {
128
+ const { logger } = getCore(client);
131
129
  const announcedKey = getMetaMaskExtensionWalletProviderKey({ chain }, client);
132
- if (announcedKey !== void 0) getCore(client).logger.warn(`[metamask] MetaMask extension is announced for ${chain} as wallet provider "${announcedKey}"; proceeding with URI pairing. Consider connectWithWalletProvider({ walletProviderKey: "${announcedKey}" }) for the best user experience.`);
133
- const controller = await getController(client);
134
130
  const uriDeferred = createDeferredPromise();
135
- const unsubscribe = controller.onDisplayUri((displayUri) => {
131
+ const connectionScopes = getMetaMaskScopes({ chain }, client);
132
+ const metaMaskClientInstanceManager = getOrCreateMetaMaskClientInstanceManager(client);
133
+ await metaMaskClientInstanceManager.clearMetaMaskStorageAndInstance();
134
+ const metaMaskClient = await metaMaskClientInstanceManager.getMetaMaskClient();
135
+ if (announcedKey !== void 0) logger.warn(`[MetaMask:Connect] Extension is announced for ${chain} as wallet provider "${announcedKey}"; proceeding with URI pairing anyway. Consider connectWithWalletProvider({ walletProviderKey: "${announcedKey}" }) for the best user experience.`);
136
+ const onDisplayUri = (displayUri) => {
137
+ logger.debug("[MetaMask:Connect] Received display_uri event", { displayUri });
136
138
  uriDeferred.resolve(displayUri);
139
+ };
140
+ metaMaskClientInstanceManager.events.on("display_uri", onDisplayUri);
141
+ logger.debug("[MetaMask:Connect] Requesting URI pairing", {
142
+ chain,
143
+ connectionScopes
137
144
  });
138
- const connectPromise = controller.connect();
145
+ const connectPromise = metaMaskClient.connect(connectionScopes, []);
139
146
  connectPromise.then(() => {
140
147
  uriDeferred.reject(new MetaMaskDisplayUriMissingError());
141
148
  }).catch((error) => {
@@ -144,17 +151,24 @@ const connectWithMetaMaskUri = async ({ addToDynamicWalletAccounts = true, chain
144
151
  let uri;
145
152
  try {
146
153
  uri = await uriDeferred.promise;
154
+ logger.debug("[MetaMask:Connect] URI ready for display", { chain });
147
155
  } finally {
148
- unsubscribe();
156
+ metaMaskClientInstanceManager.events.off("display_uri", onDisplayUri);
149
157
  }
150
158
  const approval = async () => {
151
159
  await connectPromise;
152
- const walletProvider = await walletProviderBuilder(client);
160
+ logger.debug("[MetaMask:Connect] Pairing approved", { chain });
161
+ const walletProvider = walletProviderBuilder(client);
162
+ getWalletProviderRegistry(client).unregister(walletProvider.key);
153
163
  getWalletProviderRegistry(client).register({
154
164
  priority: WalletProviderPriority.WALLET_SDK,
155
165
  walletProvider
156
166
  });
157
167
  const { addresses } = await walletProvider.getConnectedAddresses();
168
+ logger.debug("[MetaMask:Connect] Connected addresses resolved", {
169
+ addresses,
170
+ chain
171
+ });
158
172
  const mainAddress = addresses[0];
159
173
  if (mainAddress === void 0) throw new NoAddressFoundError();
160
174
  return { walletAccounts: reconcileWalletAccountsAgainstClient({
@@ -180,24 +194,10 @@ const connectWithMetaMaskUri = async ({ addToDynamicWalletAccounts = true, chain
180
194
  };
181
195
  };
182
196
 
183
- //#endregion
184
- //#region src/errors/MetaMaskWalletNotConnectedError/MetaMaskWalletNotConnectedError.ts
185
- var MetaMaskWalletNotConnectedError = class extends BaseError {
186
- constructor() {
187
- super({
188
- cause: null,
189
- code: "metamask_wallet_not_connected",
190
- docsUrl: null,
191
- name: "MetaMaskWalletNotConnectedError",
192
- shortMessage: "MetaMask SDK has no connected wallet account. Complete the URI pairing (await the connect approval) before building the MetaMask wallet provider."
193
- });
194
- }
195
- };
196
-
197
197
  //#endregion
198
198
  //#region src/exports/index.ts
199
199
  assertPackageVersion(name, version);
200
200
 
201
201
  //#endregion
202
- export { MetaMaskDisplayUriMissingError, MetaMaskWalletNotConnectedError, clearMetaMaskSessionStorage, connectWithMetaMaskUri, getMetaMaskExtensionWalletProviderKey };
202
+ export { MetaMaskDisplayUriMissingError, MetaMaskUnscopedNetworkError, clearMetaMaskSessionStorage, connectWithMetaMaskUri, getMetaMaskExtensionWalletProviderKey };
203
203
  //# sourceMappingURL=index.esm.js.map