@dynamic-labs-sdk/metamask 1.30.3 → 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
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","names":["uri: string"],"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,YAAQ,OAAO,CAAC,OAAO,KAAK,iCAAiC,QAAQ,MAAM;AAC3E,aAAS;;AAEX,WAAQ,kBAAkB,SAAS;WAC5B,OAAO;AACd,WAAQ,OAAO,CAAC,OAAO,KAAK,iCAAiC,MAAM;AACnE,YAAS;;GAEX;;;;;AC5DJ,IAAa,iCAAb,cAAoD,UAAU;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,SAAwB,kBAAkB,KACnB;AAYvB,QAXkB,0BAA0B,OAAO,CAAC,eAAe,CAE3C,MACrB,aACC,SAAS,UAAU,SACnB,SAAS,uBAAuB,mBAAmB,oBACnD,SAAS,SAAS,aACd,aAAa,CACd,SAAS,qBAAqB,CACpC,EAEa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACehB,MAAa,yBAAyB,OACpC,EACE,6BAA6B,MAC7B,OACA,eACA,yBAEF,SAAwB,kBAAkB,KACK;CAC/C,MAAM,eAAe,sCAAsC,EAAE,OAAO,EAAE,OAAO;AAE7E,KAAI,iBAAiB,OACnB,SAAQ,OAAO,CAAC,OAAO,KACrB,kDAAkD,MAAM,uBAAuB,aAAa,2FAA2F,aAAa,oCACrM;CAGH,MAAM,aAAa,MAAM,cAAc,OAAO;CAE9C,MAAM,cAAc,uBAA+B;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,IAAIA;AACJ,KAAI;AACF,QAAM,MAAM,YAAY;WAChB;AACR,eAAa;;CAGf,MAAM,WAAW,YAA0D;AACzE,QAAM;EAEN,MAAM,iBAAiB,MAAM,sBAAsB,OAAO;AAE1D,4BAA0B,OAAO,CAAC,SAAS;GACzC,UAAU,uBAAuB;GACjC;GACD,CAAC;EAEF,MAAM,EAAE,cAAc,MAAM,eAAe,uBAAuB;EAIlE,MAAM,cAAc,UAAU;AAE9B,MAAI,gBAAgB,OAClB,OAAM,IAAI,qBAAqB;AAyBjC,SAAO,EAAE,gBATc,qCACrB;GACE;GACA,gBAAgB,CAhBiB;IACnC,SAAS;IACT,OAAO,eAAe;IACtB,IAAI,sBAAsB;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,cAAqD,UAAU;CAC7D,cAAc;AACZ,QAAM;GACJ,OAAO;GACP,MAAM;GACN,SAAS;GACT,MAAM;GACN,cACE;GACH,CAAC;;;;;;ACPN,qBAAqB,MAAM,QAAQ"}
1
+ {"version":3,"file":"index.esm.js","names":["uri: string"],"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,WACkB,qBAAqB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;ACJhD,IAAa,iCAAb,cAAoD,UAAU;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,SAAwB,kBAAkB,KACnB;AAYvB,QAXkB,0BAA0B,OAAO,CAAC,eAAe,CAE3C,MACrB,aACC,SAAS,UAAU,SACnB,SAAS,uBAAuB,mBAAmB,oBACnD,SAAS,SAAS,aACd,aAAa,CACd,SAAS,qBAAqB,CACpC,EAEa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACYhB,MAAa,yBAAyB,OACpC,EACE,6BAA6B,MAC7B,OACA,yBAEF,SAAwB,kBAAkB,KACK;CAC/C,MAAM,EAAE,WAAW,QAAQ,OAAO;CAClC,MAAM,eAAe,sCAAsC,EAAE,OAAO,EAAE,OAAO;CAC7E,MAAM,cAAc,uBAA+B;CACnD,MAAM,mBAAmB,kBAAkB,EAAE,OAAO,EAAE,OAAO;CAC7D,MAAM,gCACJ,yCAAyC,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,IAAIA;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,4BAA0B,OAAO,CAAC,WAAW,eAAe,IAAI;AAChE,4BAA0B,OAAO,CAAC,SAAS;GACzC,UAAU,uBAAuB;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,IAAI,qBAAqB;AAyBjC,SAAO,EAAE,gBATc,qCACrB;GACE;GACA,gBAAgB,CAhBiB;IACnC,SAAS;IACT,OAAO,eAAe;IACtB,IAAI,sBAAsB;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;;;;;ACjL1B,qBAAqB,MAAM,QAAQ"}
@@ -1,50 +1,15 @@
1
+ import { c as name, l as version, n as clearMetaMaskStorage, r as getMetaMaskScopes, s as MetaMaskUnscopedNetworkError, t as getOrCreateMetaMaskClientInstanceManager } from "./getOrCreateMetaMaskClientInstanceManager-Dz57S3Bm.native.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
- import AsyncStorage from "@react-native-async-storage/async-storage";
4
4
  import { BaseError, NoAddressFoundError } from "@dynamic-labs-sdk/client";
5
5
  import { WalletProviderEnum } from "@dynamic-labs/sdk-api-core";
6
6
 
7
- //#region package.json
8
- var name = "@dynamic-labs-sdk/metamask";
9
- var version = "1.30.3";
10
-
11
- //#endregion
12
- //#region src/clearMetaMaskSessionStorage/clearMetaMaskSessionStorage.native.ts
13
- /**
14
- * Keys the MetaMask SDK writes verbatim (its RN store adapter applies no
15
- * namespace) that together make up a pairing. Deliberately excludes `anonId`,
16
- * `extensionId` and `DEBUG`: those are analytics and logger configuration, not
17
- * session state, and starting a new pairing is no reason to reset them.
18
- */
19
- const METAMASK_SESSION_KEYS = new Set([
20
- "cache_wallet_getSession",
21
- "cache_eth_accounts",
22
- "cache_eth_chainId",
23
- "pending_session_request",
24
- "multichain-transport",
25
- "websocket-transport-client-id",
26
- "sessions:master-list"
27
- ]);
7
+ //#region src/clearMetaMaskSessionStorage/clearMetaMaskSessionStorage.ts
28
8
  /**
29
- * Prefixes whose full keys embed a session id or relay channel, so they cannot
30
- * be named up front and have to be matched against the stored key list.
31
- */
32
- const METAMASK_SESSION_KEY_PREFIXES = [
33
- "session:",
34
- "nonce:",
35
- "latest-nonces:"
36
- ];
37
- const FAILED_TO_CLEAR_SESSION_MESSAGE = "[metamask] failed to clear the persisted session from AsyncStorage; the next pairing may resume a stale session instead of showing a new one";
38
- /**
39
- * Deletes the MetaMask SDK's persisted pairing session from AsyncStorage, which
40
- * is where its React Native store adapter keeps it, so the next connect call
41
- * starts a fresh pairing and emits a `display_uri` instead of silently resuming
42
- * a session that no longer works.
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.
43
11
  *
44
- * Call this only when a new pairing is actually being requested. The SDK's
45
- * mobile transport is built to resume a session across app launches, so wiping
46
- * it on startup would leave a user who is still connected unable to sign
47
- * without scanning again.
12
+ * @deprecated The clearMetaMaskSessionStorage is not needed anymore since the SDK itself will handle the storage
48
13
  *
49
14
  * @example
50
15
  * ```ts
@@ -55,24 +20,36 @@ const FAILED_TO_CLEAR_SESSION_MESSAGE = "[metamask] failed to clear the persiste
55
20
  * @param client - The Dynamic client instance. Required (rather than
56
21
  * defaulting to the last-initialized client) so a storage-clear failure is
57
22
  * always logged against the client that actually requested it.
58
- * @returns A promise that resolves once the keys are removed. Never rejects — a
59
- * storage failure must not take down the connect flow that depends on it.
23
+ * @returns A promise that resolves once the persisted session is reset.
60
24
  * @see connectWithMetaMaskUri
61
- * @see getMetaMaskExtensionWalletProviderKey
25
+ * @see createMetaMaskClientInstanceManager
62
26
  * @notInstrumented
63
27
  */
64
- const clearMetaMaskSessionStorage = async (client) => {
65
- try {
66
- const keysToRemove = (await AsyncStorage.getAllKeys()).filter((key) => METAMASK_SESSION_KEYS.has(key) || METAMASK_SESSION_KEY_PREFIXES.some((prefix) => key.startsWith(prefix)));
67
- if (keysToRemove.length === 0) return;
68
- await AsyncStorage.multiRemove(keysToRemove);
69
- } catch (error) {
70
- getCore(client).logger.warn(FAILED_TO_CLEAR_SESSION_MESSAGE, error);
71
- }
72
- };
28
+ const clearMetaMaskSessionStorage = (client) => clearMetaMaskStorage(client);
73
29
 
74
30
  //#endregion
75
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
+ */
76
53
  var MetaMaskDisplayUriMissingError = class extends BaseError {
77
54
  constructor() {
78
55
  super({
@@ -109,7 +86,7 @@ const METAMASK_NAME_NEEDLE = "metamask";
109
86
  * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
110
87
  * @returns The wallet provider key string, or `undefined` if no MetaMask extension is announced.
111
88
  * @see connectWithMetaMaskUri
112
- * @see clearMetaMaskSessionStorage
89
+ * @see clearMetaMaskStorage
113
90
  * @notInstrumented
114
91
  */
115
92
  const getMetaMaskExtensionWalletProviderKey = ({ chain }, client = getDefaultClient()) => {
@@ -131,33 +108,41 @@ const getMetaMaskExtensionWalletProviderKey = ({ chain }, client = getDefaultCli
131
108
  * ```ts
132
109
  * const { uri, approval } = await connectWithMetaMaskUri({
133
110
  * chain: 'EVM',
134
- * getController: (client) => getEvmMetaMaskController(client),
135
111
  * walletProviderBuilder: (client) => buildEvmWalletProvider(client),
136
112
  * });
137
113
  * // Render QR code with `uri`, then await approval()
138
114
  * ```
139
115
  *
140
116
  * @param params.chain - Chain being connected; used to scope the extension-installed lookup.
141
- * @param params.getController - Returns the chain-specific MetaMaskController for the pairing.
142
117
  * @param params.walletProviderBuilder - Builds the chain-specific WalletProvider after pairing approval.
143
118
  * @param [params.addToDynamicWalletAccounts] - Whether to add the wallet to the client. Defaults to `true`.
144
119
  * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
145
120
  * @returns An object with `uri` (the pairing URI) and `approval` (async function resolving to wallet accounts).
146
121
  * @throws {MetaMaskDisplayUriMissingError} If `connect` settles before a display_uri is emitted.
147
122
  * @throws {NoAddressFoundError} If no address is returned after pairing approval.
148
- * @see clearMetaMaskSessionStorage
123
+ * @see clearMetaMaskStorage
149
124
  * @see getMetaMaskExtensionWalletProviderKey
150
125
  * @notInstrumented
151
126
  */
152
- 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);
153
129
  const announcedKey = getMetaMaskExtensionWalletProviderKey({ chain }, client);
154
- 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.`);
155
- const controller = await getController(client);
156
130
  const uriDeferred = createDeferredPromise();
157
- 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 });
158
138
  uriDeferred.resolve(displayUri);
139
+ };
140
+ metaMaskClientInstanceManager.events.on("display_uri", onDisplayUri);
141
+ logger.debug("[MetaMask:Connect] Requesting URI pairing", {
142
+ chain,
143
+ connectionScopes
159
144
  });
160
- const connectPromise = controller.connect();
145
+ const connectPromise = metaMaskClient.connect(connectionScopes, []);
161
146
  connectPromise.then(() => {
162
147
  uriDeferred.reject(new MetaMaskDisplayUriMissingError());
163
148
  }).catch((error) => {
@@ -166,17 +151,24 @@ const connectWithMetaMaskUri = async ({ addToDynamicWalletAccounts = true, chain
166
151
  let uri;
167
152
  try {
168
153
  uri = await uriDeferred.promise;
154
+ logger.debug("[MetaMask:Connect] URI ready for display", { chain });
169
155
  } finally {
170
- unsubscribe();
156
+ metaMaskClientInstanceManager.events.off("display_uri", onDisplayUri);
171
157
  }
172
158
  const approval = async () => {
173
159
  await connectPromise;
174
- const walletProvider = await walletProviderBuilder(client);
160
+ logger.debug("[MetaMask:Connect] Pairing approved", { chain });
161
+ const walletProvider = walletProviderBuilder(client);
162
+ getWalletProviderRegistry(client).unregister(walletProvider.key);
175
163
  getWalletProviderRegistry(client).register({
176
164
  priority: WalletProviderPriority.WALLET_SDK,
177
165
  walletProvider
178
166
  });
179
167
  const { addresses } = await walletProvider.getConnectedAddresses();
168
+ logger.debug("[MetaMask:Connect] Connected addresses resolved", {
169
+ addresses,
170
+ chain
171
+ });
180
172
  const mainAddress = addresses[0];
181
173
  if (mainAddress === void 0) throw new NoAddressFoundError();
182
174
  return { walletAccounts: reconcileWalletAccountsAgainstClient({
@@ -202,24 +194,10 @@ const connectWithMetaMaskUri = async ({ addToDynamicWalletAccounts = true, chain
202
194
  };
203
195
  };
204
196
 
205
- //#endregion
206
- //#region src/errors/MetaMaskWalletNotConnectedError/MetaMaskWalletNotConnectedError.ts
207
- var MetaMaskWalletNotConnectedError = class extends BaseError {
208
- constructor() {
209
- super({
210
- cause: null,
211
- code: "metamask_wallet_not_connected",
212
- docsUrl: null,
213
- name: "MetaMaskWalletNotConnectedError",
214
- shortMessage: "MetaMask SDK has no connected wallet account. Complete the URI pairing (await the connect approval) before building the MetaMask wallet provider."
215
- });
216
- }
217
- };
218
-
219
197
  //#endregion
220
198
  //#region src/exports/index.ts
221
199
  assertPackageVersion(name, version);
222
200
 
223
201
  //#endregion
224
- export { MetaMaskDisplayUriMissingError, MetaMaskWalletNotConnectedError, clearMetaMaskSessionStorage, connectWithMetaMaskUri, getMetaMaskExtensionWalletProviderKey };
202
+ export { MetaMaskDisplayUriMissingError, MetaMaskUnscopedNetworkError, clearMetaMaskSessionStorage, connectWithMetaMaskUri, getMetaMaskExtensionWalletProviderKey };
225
203
  //# sourceMappingURL=index.native.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.native.esm.js","names":["uri: string"],"sources":["../package.json","../src/clearMetaMaskSessionStorage/clearMetaMaskSessionStorage.native.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';\nimport AsyncStorage from '@react-native-async-storage/async-storage';\n\n/**\n * Keys the MetaMask SDK writes verbatim (its RN store adapter applies no\n * namespace) that together make up a pairing. Deliberately excludes `anonId`,\n * `extensionId` and `DEBUG`: those are analytics and logger configuration, not\n * session state, and starting a new pairing is no reason to reset them.\n */\nconst METAMASK_SESSION_KEYS = new Set([\n // Cached `wallet_getSession` response — the CAIP session (accounts, scopes).\n 'cache_wallet_getSession',\n 'cache_eth_accounts',\n 'cache_eth_chainId',\n // A `session_request` the wallet never answered, kept so the SDK can resume\n // the pairing UI after the app was backgrounded mid-scan.\n 'pending_session_request',\n // Which transport is active; this is what tells the SDK to resume on launch.\n 'multichain-transport',\n 'websocket-transport-client-id',\n // Index of every `session:<id>` record, used to enumerate and GC them.\n 'sessions:master-list',\n]);\n\n/**\n * Prefixes whose full keys embed a session id or relay channel, so they cannot\n * be named up front and have to be matched against the stored key list.\n */\nconst METAMASK_SESSION_KEY_PREFIXES = ['session:', 'nonce:', 'latest-nonces:'];\n\nconst FAILED_TO_CLEAR_SESSION_MESSAGE =\n '[metamask] failed to clear the persisted session from AsyncStorage; the next pairing may resume a stale session instead of showing a new one';\n\n/**\n * Deletes the MetaMask SDK's persisted pairing session from AsyncStorage, which\n * is where its React Native store adapter keeps it, so the next connect call\n * starts a fresh pairing and emits a `display_uri` instead of silently resuming\n * a session that no longer works.\n *\n * Call this only when a new pairing is actually being requested. The SDK's\n * mobile transport is built to resume a session across app launches, so wiping\n * it on startup would leave a user who is still connected unable to sign\n * without scanning again.\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 keys are removed. Never rejects — a\n * storage failure must not take down the connect flow that depends on it.\n * @see connectWithMetaMaskUri\n * @see getMetaMaskExtensionWalletProviderKey\n * @notInstrumented\n */\nexport const clearMetaMaskSessionStorage = async (\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 try {\n const storedKeys = await AsyncStorage.getAllKeys();\n\n // Filtering the fixed names against what is actually stored keeps\n // `multiRemove` off keys that were never written, and lets the no-op case\n // skip the write entirely.\n const keysToRemove = storedKeys.filter(\n (key) =>\n METAMASK_SESSION_KEYS.has(key) ||\n METAMASK_SESSION_KEY_PREFIXES.some((prefix) => key.startsWith(prefix))\n );\n\n if (keysToRemove.length === 0) {\n return;\n }\n\n await AsyncStorage.multiRemove(keysToRemove);\n } catch (error) {\n // Matches the web implementation in resolving anyway, so the caller's\n // pairing attempt still proceeds. It is logged rather than dropped because\n // a failure here puts the caller back on the stale session it was trying to\n // escape, and this is the only trace of why.\n //\n getCore(client).logger.warn(FAILED_TO_CLEAR_SESSION_MESSAGE, error);\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":";;;;;;;;;;;;;;;;;;ACUA,MAAM,wBAAwB,IAAI,IAAI;CAEpC;CACA;CACA;CAGA;CAEA;CACA;CAEA;CACD,CAAC;;;;;AAMF,MAAM,gCAAgC;CAAC;CAAY;CAAU;CAAiB;AAE9E,MAAM,kCACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BF,MAAa,8BAA8B,OAGzC,WACkB;AAClB,KAAI;EAMF,MAAM,gBALa,MAAM,aAAa,YAAY,EAKlB,QAC7B,QACC,sBAAsB,IAAI,IAAI,IAC9B,8BAA8B,MAAM,WAAW,IAAI,WAAW,OAAO,CAAC,CACzE;AAED,MAAI,aAAa,WAAW,EAC1B;AAGF,QAAM,aAAa,YAAY,aAAa;UACrC,OAAO;AAMd,UAAQ,OAAO,CAAC,OAAO,KAAK,iCAAiC,MAAM;;;;;;ACtFvE,IAAa,iCAAb,cAAoD,UAAU;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,SAAwB,kBAAkB,KACnB;AAYvB,QAXkB,0BAA0B,OAAO,CAAC,eAAe,CAE3C,MACrB,aACC,SAAS,UAAU,SACnB,SAAS,uBAAuB,mBAAmB,oBACnD,SAAS,SAAS,aACd,aAAa,CACd,SAAS,qBAAqB,CACpC,EAEa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACehB,MAAa,yBAAyB,OACpC,EACE,6BAA6B,MAC7B,OACA,eACA,yBAEF,SAAwB,kBAAkB,KACK;CAC/C,MAAM,eAAe,sCAAsC,EAAE,OAAO,EAAE,OAAO;AAE7E,KAAI,iBAAiB,OACnB,SAAQ,OAAO,CAAC,OAAO,KACrB,kDAAkD,MAAM,uBAAuB,aAAa,2FAA2F,aAAa,oCACrM;CAGH,MAAM,aAAa,MAAM,cAAc,OAAO;CAE9C,MAAM,cAAc,uBAA+B;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,IAAIA;AACJ,KAAI;AACF,QAAM,MAAM,YAAY;WAChB;AACR,eAAa;;CAGf,MAAM,WAAW,YAA0D;AACzE,QAAM;EAEN,MAAM,iBAAiB,MAAM,sBAAsB,OAAO;AAE1D,4BAA0B,OAAO,CAAC,SAAS;GACzC,UAAU,uBAAuB;GACjC;GACD,CAAC;EAEF,MAAM,EAAE,cAAc,MAAM,eAAe,uBAAuB;EAIlE,MAAM,cAAc,UAAU;AAE9B,MAAI,gBAAgB,OAClB,OAAM,IAAI,qBAAqB;AAyBjC,SAAO,EAAE,gBATc,qCACrB;GACE;GACA,gBAAgB,CAhBiB;IACnC,SAAS;IACT,OAAO,eAAe;IACtB,IAAI,sBAAsB;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,cAAqD,UAAU;CAC7D,cAAc;AACZ,QAAM;GACJ,OAAO;GACP,MAAM;GACN,SAAS;GACT,MAAM;GACN,cACE;GACH,CAAC;;;;;;ACPN,qBAAqB,MAAM,QAAQ"}
1
+ {"version":3,"file":"index.native.esm.js","names":["uri: string"],"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,WACkB,qBAAqB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;ACJhD,IAAa,iCAAb,cAAoD,UAAU;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,SAAwB,kBAAkB,KACnB;AAYvB,QAXkB,0BAA0B,OAAO,CAAC,eAAe,CAE3C,MACrB,aACC,SAAS,UAAU,SACnB,SAAS,uBAAuB,mBAAmB,oBACnD,SAAS,SAAS,aACd,aAAa,CACd,SAAS,qBAAqB,CACpC,EAEa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACYhB,MAAa,yBAAyB,OACpC,EACE,6BAA6B,MAC7B,OACA,yBAEF,SAAwB,kBAAkB,KACK;CAC/C,MAAM,EAAE,WAAW,QAAQ,OAAO;CAClC,MAAM,eAAe,sCAAsC,EAAE,OAAO,EAAE,OAAO;CAC7E,MAAM,cAAc,uBAA+B;CACnD,MAAM,mBAAmB,kBAAkB,EAAE,OAAO,EAAE,OAAO;CAC7D,MAAM,gCACJ,yCAAyC,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,IAAIA;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,4BAA0B,OAAO,CAAC,WAAW,eAAe,IAAI;AAChE,4BAA0B,OAAO,CAAC,SAAS;GACzC,UAAU,uBAAuB;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,IAAI,qBAAqB;AAyBjC,SAAO,EAAE,gBATc,qCACrB;GACE;GACA,gBAAgB,CAhBiB;IACnC,SAAS;IACT,OAAO,eAAe;IACtB,IAAI,sBAAsB;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;;;;;ACjL1B,qBAAqB,MAAM,QAAQ"}
@@ -0,0 +1,45 @@
1
+ import type { DynamicClient } from '@dynamic-labs-sdk/client';
2
+ import { type EventEmitter } from '@dynamic-labs-sdk/client/core';
3
+ import type { MultichainCore } from '@metamask/connect-multichain';
4
+ /**
5
+ * Events a `MetaMaskClientInstanceManager` forwards from the underlying
6
+ * `@metamask/connect-multichain` client, for callers that don't hold a
7
+ * reference to the raw SDK client.
8
+ */
9
+ export type MetaMaskClientEvents = {
10
+ display_uri: (evt: string) => void;
11
+ };
12
+ /**
13
+ * The per-client handle returned by `createMetaMaskClientInstanceManager`.
14
+ */
15
+ export type MetaMaskClientInstanceManager = {
16
+ /** Wipes persisted MetaMask storage and forces the next build to start fresh. */
17
+ clearMetaMaskStorageAndInstance: () => Promise<void>;
18
+ /** Emits `MetaMaskClientEvents` forwarded from the underlying SDK client. */
19
+ events: EventEmitter<MetaMaskClientEvents>;
20
+ /** Resolves the shared `MultichainCore` client, building it on first access. */
21
+ getMetaMaskClient(): Promise<MultichainCore>;
22
+ };
23
+ /**
24
+ * Creates the per-client manager that lazily builds, tears down, and rebuilds
25
+ * the shared `@metamask/connect-multichain` client instance, and forwards its
26
+ * `display_uri` event to callers that don't hold a reference to the raw SDK
27
+ * client.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * const manager = createMetaMaskClientInstanceManager(client);
32
+ * const metaMaskClient = await manager.getMetaMaskClient();
33
+ * ```
34
+ *
35
+ * @returns A `MetaMaskClientInstanceManager` scoped to `client`.
36
+ * @throws {MetaMaskClientNotInitializedError} From `getMetaMaskClient` if a
37
+ * build was never started -- a defensive guard, since `refreshMetaMaskClient`
38
+ * always starts one. A build that starts but fails instead rejects
39
+ * `getMetaMaskClient()` with its original error.
40
+ * @see createMetaMaskStorageClient
41
+ * @see clearMetaMaskStorage
42
+ * @notInstrumented
43
+ */
44
+ export declare const createMetaMaskClientInstanceManager: (client: DynamicClient) => MetaMaskClientInstanceManager;
45
+ //# sourceMappingURL=createMetaMaskClientInstanceManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createMetaMaskClientInstanceManager.d.ts","sourceRoot":"","sources":["../../../src/metaMaskClientInstanceManager/createMetaMaskClientInstanceManager/createMetaMaskClientInstanceManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EACL,KAAK,YAAY,EAKlB,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAUnE;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,6BAA6B,GAAG;IAC1C,iFAAiF;IACjF,+BAA+B,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,6EAA6E;IAC7E,MAAM,EAAE,YAAY,CAAC,oBAAoB,CAAC,CAAC;IAC3C,gFAAgF;IAChF,iBAAiB,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;CAC9C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,mCAAmC,WACtC,aAAa,KACpB,6BA+HF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { createMetaMaskClientInstanceManager } from './createMetaMaskClientInstanceManager';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/metaMaskClientInstanceManager/createMetaMaskClientInstanceManager/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mCAAmC,EAAE,MAAM,uCAAuC,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Returns this client's `MetaMaskClientInstanceManager`, creating it on first
3
+ * access. Every chain's MetaMask wallet provider (EVM, Solana, ...) calls
4
+ * this to reach the SAME manager -- and therefore the same shared multichain
5
+ * session -- rather than each building its own.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * const manager = getOrCreateMetaMaskClientInstanceManager(client);
10
+ * const metaMaskClient = await manager.getMetaMaskClient();
11
+ * ```
12
+ * @param client - The Dynamic client instance.
13
+ * @returns The client's `MetaMaskClientInstanceManager`.
14
+ * @see createMetaMaskClientInstanceManager
15
+ * @see disconnectMetaMaskWalletProvider
16
+ */
17
+ export declare const getOrCreateMetaMaskClientInstanceManager: (client: import("@dynamic-labs-sdk/client").DynamicClient) => import("../createMetaMaskClientInstanceManager/createMetaMaskClientInstanceManager").MetaMaskClientInstanceManager;
18
+ //# sourceMappingURL=getOrCreateMetaMaskClientInstanceManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getOrCreateMetaMaskClientInstanceManager.d.ts","sourceRoot":"","sources":["../../../src/metaMaskClientInstanceManager/getOrCreateMetaMaskClientInstanceManager/getOrCreateMetaMaskClientInstanceManager.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,wCAAwC,kLAIlD,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { getOrCreateMetaMaskClientInstanceManager } from './getOrCreateMetaMaskClientInstanceManager';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/metaMaskClientInstanceManager/getOrCreateMetaMaskClientInstanceManager/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wCAAwC,EAAE,MAAM,4CAA4C,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { DynamicClient } from '@dynamic-labs-sdk/client';
2
+ /**
3
+ * Resets the MetaMask SDK's persisted store blob back to its initial
4
+ * (empty) value, so the next connect call starts a fresh pairing and emits a
5
+ * `display_uri` instead of silently resuming a session that no longer works.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * await clearMetaMaskStorage(client);
10
+ * // Next connectWithMetaMaskUri call will emit a fresh URI immediately.
11
+ * ```
12
+ *
13
+ * @param client - The Dynamic client instance. Required (rather than
14
+ * defaulting to the last-initialized client) so a storage-clear failure is
15
+ * always logged against the client that actually requested it.
16
+ * @returns A promise that resolves once the blob is reset. Never rejects -- a
17
+ * storage failure must not take down the connect flow that depends on it.
18
+ * @see connectWithMetaMaskUri
19
+ * @see createMetaMaskStorageClient
20
+ * @notInstrumented
21
+ */
22
+ export declare const clearMetaMaskStorage: (client: DynamicClient) => Promise<void>;
23
+ //# sourceMappingURL=clearMetaMaskStorage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clearMetaMaskStorage.d.ts","sourceRoot":"","sources":["../../../src/metaMaskStorage/clearMetaMaskStorage/clearMetaMaskStorage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAS9D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,oBAAoB,WACvB,aAAa,KACpB,OAAO,CAAC,IAAI,CAiBd,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { clearMetaMaskStorage } from './clearMetaMaskStorage';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/metaMaskStorage/clearMetaMaskStorage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { MetaMaskStoreValue } from '../metaMaskStorage.schema';
2
+ /**
3
+ * Builds the persisted store blob's value for when there is nothing stored
4
+ * yet, or after a clear. A function rather than a shared constant, so every
5
+ * caller gets its own object and can't mutate a value other callers rely on.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * const initial = createInitialMetaMaskStoreValue();
10
+ * // { entries: {}, schemaVersion: 1 }
11
+ * ```
12
+ *
13
+ * @returns A fresh, empty `MetaMaskStoreValue`.
14
+ * @see createMetaMaskStorageClient
15
+ * @see clearMetaMaskStorage
16
+ * @notInstrumented
17
+ */
18
+ export declare const createInitialMetaMaskStoreValue: () => MetaMaskStoreValue;
19
+ //# sourceMappingURL=createInitialMetaMaskStoreValue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createInitialMetaMaskStoreValue.d.ts","sourceRoot":"","sources":["../../../src/metaMaskStorage/createInitialMetaMaskStoreValue/createInitialMetaMaskStoreValue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,+BAA+B,QAAO,kBAGjD,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { StoreClient } from '@metamask/connect-multichain';
2
+ import type { DynamicClient } from '@dynamic-labs-sdk/client';
3
+ /**
4
+ * Builds a storage-service-backed store for the MetaMask multichain client,
5
+ * in place of its own default web adapter (IndexedDB) and React Native
6
+ * adapter (raw `AsyncStorage`), so every platform persists through the same
7
+ * core `Storage` service and `clearMetaMaskStorage` can reliably wipe it.
8
+ *
9
+ * The SDK controls every key name it reads/writes through `adapter`,
10
+ * including ones that embed an unpredictable id (`session:<id>`), so every
11
+ * key it uses is folded into a single stored blob (`metaMaskStoreStorageKeySchema`)
12
+ * rather than one storage key per SDK key. `DEBUG` is never persisted at all,
13
+ * answered live from the client's own logger.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const storeClient = createMetaMaskStorageClient(client);
18
+ * const multichainClient = createMultichainClient({ storage: storeClient });
19
+ * ```
20
+ *
21
+ * @returns A `StoreClient` backed by the client's core `Storage` service.
22
+ * @throws {MetaMaskStorageError} If the underlying `Storage` service's
23
+ * `getItem`/`setItem` calls fail for any of the adapter's read/write/delete
24
+ * operations.
25
+ * @see createInitialMetaMaskStoreValue
26
+ * @see clearMetaMaskStorage
27
+ * @notInstrumented
28
+ */
29
+ export declare const createMetaMaskStorageClient: (client: DynamicClient) => StoreClient;
30
+ //# sourceMappingURL=createMetaMaskStorageClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createMetaMaskStorageClient.d.ts","sourceRoot":"","sources":["../../../src/metaMaskStorage/createMetaMaskStorageClient/createMetaMaskStorageClient.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAE9E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAe9D;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,2BAA2B,WAAY,aAAa,KAAG,WA6GnE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { createMetaMaskStorageClient } from './createMetaMaskStorageClient';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/metaMaskStorage/createMetaMaskStorageClient/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC"}
@@ -0,0 +1,30 @@
1
+ import * as z from 'zod/mini';
2
+ /**
3
+ * Single storage key holding every value the MetaMask multichain SDK writes
4
+ * through our `StoreAdapter` (sessions, nonces, cached accounts/chain,
5
+ * pending pairing requests, transport ids, ...), keyed by whatever key string
6
+ * the SDK itself hands us -- the SDK controls every key name, including ones
7
+ * that embed an unpredictable id (`session:<id>`), so this can't be split
8
+ * into one storage key per SDK key.
9
+ *
10
+ * `entries[ANON_ID_ENTRY_KEY]` also lives in here, alongside `extensionId`
11
+ * and the other transport keys.
12
+ *
13
+ * `clearMetaMaskStorage` resets this key back to its initial value; nothing
14
+ * else needs to know the individual key names the SDK is using.
15
+ */
16
+ export declare const metaMaskStoreStorageKeySchema: import("@dynamic-labs-sdk/client/core").StorageKeySchema<{
17
+ entries: Record<string, string>;
18
+ schemaVersion: 1;
19
+ }>;
20
+ /**
21
+ * The persisted store blob's shape. Exported here because it is shared by
22
+ * every function operating on this storage key.
23
+ */
24
+ export type MetaMaskStoreValue = z.infer<typeof metaMaskStoreStorageKeySchema.schema>;
25
+ /**
26
+ * Reserved `entries` key the MetaMask SDK itself never writes to, used to
27
+ * carry the SDK's anonymous analytics id inside the same store blob.
28
+ */
29
+ export declare const ANON_ID_ENTRY_KEY = "anonId";
30
+ //# sourceMappingURL=metaMaskStorage.schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metaMaskStorage.schema.d.ts","sourceRoot":"","sources":["../../src/metaMaskStorage/metaMaskStorage.schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAG9B;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,6BAA6B;;;EAMxC,CAAC;AAEH;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,MAAM,CAAC,CAAC;AAEtF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,WAAW,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { SequenceQueue } from '@dynamic-labs-sdk/client/core';
2
+ /**
3
+ * Single shared queue serializing every read-modify-write against
4
+ * `metaMaskStoreStorageKeySchema` -- `createMetaMaskStorageClient`'s adapter
5
+ * reads/writes/anonId operations and `clearMetaMaskStorage`'s reset all go
6
+ * through this same instance, so a write that started before a clear can't
7
+ * land after it and resurrect the data the clear was meant to erase.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * await queueMetaMaskStorageWrite(() => storage.setItem(key, value), client);
12
+ * ```
13
+ *
14
+ * @returns A `SequenceQueue` that runs one queued task at a time, in order.
15
+ * @see createMetaMaskStorageClient
16
+ * @see clearMetaMaskStorage
17
+ * @notInstrumented
18
+ */
19
+ export declare const queueMetaMaskStorageWrite: SequenceQueue;
20
+ //# sourceMappingURL=queueMetaMaskStorageWrite.d.ts.map