@dynamic-labs-sdk/metamask 1.17.1 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,6 +4,15 @@
4
4
  * 10-second resume timeout reviving a dead pairing. Safe in SSR (no-op) and
5
5
  * when the DB is held open by another tab (resolves on `blocked`).
6
6
  *
7
+ * @example
8
+ * ```ts
9
+ * await clearMetaMaskSessionStorage();
10
+ * // Next connectWithMetaMaskUri call will emit a fresh URI immediately.
11
+ * ```
12
+ *
13
+ * @returns A promise that resolves once the database is deleted (or immediately in SSR).
14
+ * @see connectWithMetaMaskUri
15
+ * @see getMetaMaskExtensionWalletProviderKey
7
16
  * @notInstrumented
8
17
  */
9
18
  export declare const clearMetaMaskSessionStorage: () => Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"clearMetaMaskSessionStorage.d.ts","sourceRoot":"","sources":["../../src/clearMetaMaskSessionStorage/clearMetaMaskSessionStorage.ts"],"names":[],"mappings":"AAMA;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,QAAO,OAAO,CAAC,IAAI,CAsB1D,CAAC"}
1
+ {"version":3,"file":"clearMetaMaskSessionStorage.d.ts","sourceRoot":"","sources":["../../src/clearMetaMaskSessionStorage/clearMetaMaskSessionStorage.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,2BAA2B,QAAO,OAAO,CAAC,IAAI,CAsB1D,CAAC"}
@@ -24,6 +24,26 @@ export type ConnectWithMetaMaskUriParams = {
24
24
  * specific wallet provider only after pairing is approved; the provider
25
25
  * therefore never appears in the wallet picker (no `connect` method).
26
26
  *
27
+ * @example
28
+ * ```ts
29
+ * const { uri, approval } = await connectWithMetaMaskUri({
30
+ * chain: 'EVM',
31
+ * getController: (client) => getEvmMetaMaskController(client),
32
+ * walletProviderBuilder: (client) => buildEvmWalletProvider(client),
33
+ * });
34
+ * // Render QR code with `uri`, then await approval()
35
+ * ```
36
+ *
37
+ * @param params.chain - Chain being connected; used to scope the extension-installed lookup.
38
+ * @param params.getController - Returns the chain-specific MetaMaskController for the pairing.
39
+ * @param params.walletProviderBuilder - Builds the chain-specific WalletProvider after pairing approval.
40
+ * @param [params.addToDynamicWalletAccounts] - Whether to add the wallet to the client. Defaults to `true`.
41
+ * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
42
+ * @returns An object with `uri` (the pairing URI) and `approval` (async function resolving to wallet accounts).
43
+ * @throws {MetaMaskDisplayUriMissingError} If `connect` settles before a display_uri is emitted.
44
+ * @throws {NoAddressFoundError} If no address is returned after pairing approval.
45
+ * @see clearMetaMaskSessionStorage
46
+ * @see getMetaMaskExtensionWalletProviderKey
27
47
  * @notInstrumented
28
48
  */
29
49
  export declare const connectWithMetaMaskUri: ({ addToDynamicWalletAccounts, chain, getController, walletProviderBuilder, }: ConnectWithMetaMaskUriParams, client?: DynamicClient) => Promise<WalletProviderUriConnectionResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"connectWithMetaMaskUri.d.ts","sourceRoot":"","sources":["../../src/connectWithMetaMaskUri/connectWithMetaMaskUri.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,aAAa,EAEb,iCAAiC,EAClC,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAapE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,MAAM,MAAM,4BAA4B,GAAG;IACzC,6FAA6F;IAC7F,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,2EAA2E;IAC3E,KAAK,EAAE,KAAK,CAAC;IACb,+EAA+E;IAC/E,aAAa,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACtE;;;;OAIG;IACH,qBAAqB,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;CAC3E,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,iFAM9B,4BAA4B,WACvB,aAAa,KACpB,OAAO,CAAC,iCAAiC,CAmF3C,CAAC"}
1
+ {"version":3,"file":"connectWithMetaMaskUri.d.ts","sourceRoot":"","sources":["../../src/connectWithMetaMaskUri/connectWithMetaMaskUri.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,aAAa,EAEb,iCAAiC,EAClC,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAapE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,MAAM,MAAM,4BAA4B,GAAG;IACzC,6FAA6F;IAC7F,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,2EAA2E;IAC3E,KAAK,EAAE,KAAK,CAAC;IACb,+EAA+E;IAC/E,aAAa,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACtE;;;;OAIG;IACH,qBAAqB,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;CAC3E,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,sBAAsB,iFAM9B,4BAA4B,WACvB,aAAa,KACpB,OAAO,CAAC,iCAAiC,CAmF3C,CAAC"}
@@ -12,6 +12,19 @@ type GetMetaMaskExtensionWalletProviderKeyParams = {
12
12
  * the connection through the announced provider; fall back to the chain's
13
13
  * `connectWithMetaMaskUri<Chain>` helper when `undefined`.
14
14
  *
15
+ * @example
16
+ * ```ts
17
+ * const key = getMetaMaskExtensionWalletProviderKey({ chain: 'EVM' });
18
+ * if (key) {
19
+ * await connectWithWalletProvider({ walletProviderKey: key });
20
+ * }
21
+ * ```
22
+ *
23
+ * @param params.chain - Chain to scope the lookup to.
24
+ * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
25
+ * @returns The wallet provider key string, or `undefined` if no MetaMask extension is announced.
26
+ * @see connectWithMetaMaskUri
27
+ * @see clearMetaMaskSessionStorage
15
28
  * @notInstrumented
16
29
  */
17
30
  export declare const getMetaMaskExtensionWalletProviderKey: ({ chain }: GetMetaMaskExtensionWalletProviderKeyParams, client?: DynamicClient) => string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"getMetaMaskExtensionWalletProviderKey.d.ts","sourceRoot":"","sources":["../../src/getMetaMaskExtensionWalletProviderKey/getMetaMaskExtensionWalletProviderKey.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AASrE,KAAK,2CAA2C,GAAG;IACjD,oCAAoC;IACpC,KAAK,EAAE,KAAK,CAAC;CACd,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qCAAqC,cACrC,2CAA2C,WAC9C,aAAa,KACpB,MAAM,GAAG,SAaX,CAAC"}
1
+ {"version":3,"file":"getMetaMaskExtensionWalletProviderKey.d.ts","sourceRoot":"","sources":["../../src/getMetaMaskExtensionWalletProviderKey/getMetaMaskExtensionWalletProviderKey.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AASrE,KAAK,2CAA2C,GAAG;IACjD,oCAAoC;IACpC,KAAK,EAAE,KAAK,CAAC;CACd,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,qCAAqC,cACrC,2CAA2C,WAC9C,aAAa,KACpB,MAAM,GAAG,SAaX,CAAC"}
package/dist/index.cjs CHANGED
@@ -5,7 +5,7 @@ let _dynamic_labs_sdk_api_core = require("@dynamic-labs/sdk-api-core");
5
5
 
6
6
  //#region package.json
7
7
  var name = "@dynamic-labs-sdk/metamask";
8
- var version = "1.17.1";
8
+ var version = "1.19.0";
9
9
 
10
10
  //#endregion
11
11
  //#region src/clearMetaMaskSessionStorage/clearMetaMaskSessionStorage.ts
@@ -16,6 +16,15 @@ const METAMASK_SDK_IDB_NAME = "mmconnect-kv-store";
16
16
  * 10-second resume timeout reviving a dead pairing. Safe in SSR (no-op) and
17
17
  * when the DB is held open by another tab (resolves on `blocked`).
18
18
  *
19
+ * @example
20
+ * ```ts
21
+ * await clearMetaMaskSessionStorage();
22
+ * // Next connectWithMetaMaskUri call will emit a fresh URI immediately.
23
+ * ```
24
+ *
25
+ * @returns A promise that resolves once the database is deleted (or immediately in SSR).
26
+ * @see connectWithMetaMaskUri
27
+ * @see getMetaMaskExtensionWalletProviderKey
19
28
  * @notInstrumented
20
29
  */
21
30
  const clearMetaMaskSessionStorage = () => {
@@ -58,6 +67,19 @@ const METAMASK_NAME_NEEDLE = "metamask";
58
67
  * the connection through the announced provider; fall back to the chain's
59
68
  * `connectWithMetaMaskUri<Chain>` helper when `undefined`.
60
69
  *
70
+ * @example
71
+ * ```ts
72
+ * const key = getMetaMaskExtensionWalletProviderKey({ chain: 'EVM' });
73
+ * if (key) {
74
+ * await connectWithWalletProvider({ walletProviderKey: key });
75
+ * }
76
+ * ```
77
+ *
78
+ * @param params.chain - Chain to scope the lookup to.
79
+ * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
80
+ * @returns The wallet provider key string, or `undefined` if no MetaMask extension is announced.
81
+ * @see connectWithMetaMaskUri
82
+ * @see clearMetaMaskSessionStorage
61
83
  * @notInstrumented
62
84
  */
63
85
  const getMetaMaskExtensionWalletProviderKey = ({ chain }, client = (0, _dynamic_labs_sdk_client_core.getDefaultClient)()) => {
@@ -75,6 +97,26 @@ const getMetaMaskExtensionWalletProviderKey = ({ chain }, client = (0, _dynamic_
75
97
  * specific wallet provider only after pairing is approved; the provider
76
98
  * therefore never appears in the wallet picker (no `connect` method).
77
99
  *
100
+ * @example
101
+ * ```ts
102
+ * const { uri, approval } = await connectWithMetaMaskUri({
103
+ * chain: 'EVM',
104
+ * getController: (client) => getEvmMetaMaskController(client),
105
+ * walletProviderBuilder: (client) => buildEvmWalletProvider(client),
106
+ * });
107
+ * // Render QR code with `uri`, then await approval()
108
+ * ```
109
+ *
110
+ * @param params.chain - Chain being connected; used to scope the extension-installed lookup.
111
+ * @param params.getController - Returns the chain-specific MetaMaskController for the pairing.
112
+ * @param params.walletProviderBuilder - Builds the chain-specific WalletProvider after pairing approval.
113
+ * @param [params.addToDynamicWalletAccounts] - Whether to add the wallet to the client. Defaults to `true`.
114
+ * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
115
+ * @returns An object with `uri` (the pairing URI) and `approval` (async function resolving to wallet accounts).
116
+ * @throws {MetaMaskDisplayUriMissingError} If `connect` settles before a display_uri is emitted.
117
+ * @throws {NoAddressFoundError} If no address is returned after pairing approval.
118
+ * @see clearMetaMaskSessionStorage
119
+ * @see getMetaMaskExtensionWalletProviderKey
78
120
  * @notInstrumented
79
121
  */
80
122
  const connectWithMetaMaskUri = async ({ addToDynamicWalletAccounts = true, chain, getController, walletProviderBuilder }, client = (0, _dynamic_labs_sdk_client_core.getDefaultClient)()) => {
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["BaseError","WalletProviderEnum","uri: string","WalletProviderPriority","NoAddressFoundError","BaseError"],"sources":["../package.json","../src/clearMetaMaskSessionStorage/clearMetaMaskSessionStorage.ts","../src/errors/MetaMaskDisplayUriMissingError/MetaMaskDisplayUriMissingError.ts","../src/getMetaMaskExtensionWalletProviderKey/getMetaMaskExtensionWalletProviderKey.ts","../src/connectWithMetaMaskUri/connectWithMetaMaskUri.ts","../src/errors/MetaMaskWalletNotConnectedError/MetaMaskWalletNotConnectedError.ts","../src/exports/index.ts"],"sourcesContent":["","// 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\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 * @notInstrumented\n */\nexport const clearMetaMaskSessionStorage = (): 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 // `onerror` / `onblocked` fire when a concurrent tab holds the\n // DB open. We still resolve so the consumer's connect flow is\n // not stalled indefinitely; the next tab close drops the lock\n // and subsequent runs reach the empty database. The Promise\n // executor already ignores subsequent resolve calls, so no\n // extra guard is needed when multiple lifecycle events fire on\n // the same request.\n request.onerror = () => resolve();\n request.onblocked = () => resolve();\n } catch {\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 * @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 * @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":";;;;;;;;;;;ACIA,MAAM,wBAAwB;;;;;;;;;AAU9B,MAAa,oCAAmD;AAC9D,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;AAQnC,WAAQ,gBAAgB,SAAS;AACjC,WAAQ,kBAAkB,SAAS;UAC7B;AACN,YAAS;;GAEX;;;;;ACjCJ,IAAa,iCAAb,cAAoDA,mCAAU;CAC5D,cAAc;AACZ,QAAM;GACJ,OAAO;GACP,MAAM;GACN,SAAS;GACT,MAAM;GACN,cACE;GACH,CAAC;;;;;;ACJN,MAAM,uBAAuB;;;;;;;;;;;;AAkB7B,MAAa,yCACX,EAAE,SACF,8DAA0C,KACnB;AAYvB,qEAX4C,OAAO,CAAC,eAAe,CAE3C,MACrB,aACC,SAAS,UAAU,SACnB,SAAS,uBAAuBC,8CAAmB,oBACnD,SAAS,SAAS,aACd,aAAa,CACd,SAAS,qBAAqB,CACpC,EAEa;;;;;;;;;;;;;;;;ACQhB,MAAa,yBAAyB,OACpC,EACE,6BAA6B,MAC7B,OACA,eACA,yBAEF,8DAA0C,KACK;CAC/C,MAAM,eAAe,sCAAsC,EAAE,OAAO,EAAE,OAAO;AAE7E,KAAI,iBAAiB,OACnB,4CAAQ,OAAO,CAAC,OAAO,KACrB,kDAAkD,MAAM,uBAAuB,aAAa,2FAA2F,aAAa,oCACrM;CAGH,MAAM,aAAa,MAAM,cAAc,OAAO;CAE9C,MAAM,wEAA6C;CAEnD,MAAM,cAAc,WAAW,cAAc,eAAe;AAC1D,cAAY,QAAQ,WAAW;GAC/B;CAEF,MAAM,iBAAiB,WAAW,SAAS;AAK3C,gBACG,WAAW;AACV,cAAY,OAAO,IAAI,gCAAgC,CAAC;GACxD,CACD,OAAO,UAAmB;AACzB,cAAY,OAAO,MAAM;GACzB;CAEJ,IAAIC;AACJ,KAAI;AACF,QAAM,MAAM,YAAY;WAChB;AACR,eAAa;;CAGf,MAAM,WAAW,YAA0D;AACzE,QAAM;EAEN,MAAM,iBAAiB,MAAM,sBAAsB,OAAO;AAE1D,+DAA0B,OAAO,CAAC,SAAS;GACzC,UAAUC,qDAAuB;GACjC;GACD,CAAC;EAEF,MAAM,EAAE,cAAc,MAAM,eAAe,uBAAuB;EAIlE,MAAM,cAAc,UAAU;AAE9B,MAAI,gBAAgB,OAClB,OAAM,IAAIC,8CAAqB;AAyBjC,SAAO,EAAE,wFARP;GACE;GACA,gBAAgB,CAhBiB;IACnC,SAAS;IACT,OAAO,eAAe;IACtB,6DAA0B;KACxB,SAAS;KACT,OAAO,eAAe;KACtB,mBAAmB,eAAe;KACnC,CAAC;IACF,gBAAgB;IAChB,sBAAsB;IACtB,mBAAmB,eAAe;IACnC,CAKkC;GAC/B,mBAAmB,eAAe;GACnC,EACD,OACD,EAEwB;;AAG3B,QAAO;EAAE;EAAU;EAAK;;;;;ACxI1B,IAAa,kCAAb,cAAqDC,mCAAU;CAC7D,cAAc;AACZ,QAAM;GACJ,OAAO;GACP,MAAM;GACN,SAAS;GACT,MAAM;GACN,cACE;GACH,CAAC;;;;;;mECPe,MAAM,QAAQ"}
1
+ {"version":3,"file":"index.cjs","names":["BaseError","WalletProviderEnum","uri: string","WalletProviderPriority","NoAddressFoundError","BaseError"],"sources":["../package.json","../src/clearMetaMaskSessionStorage/clearMetaMaskSessionStorage.ts","../src/errors/MetaMaskDisplayUriMissingError/MetaMaskDisplayUriMissingError.ts","../src/getMetaMaskExtensionWalletProviderKey/getMetaMaskExtensionWalletProviderKey.ts","../src/connectWithMetaMaskUri/connectWithMetaMaskUri.ts","../src/errors/MetaMaskWalletNotConnectedError/MetaMaskWalletNotConnectedError.ts","../src/exports/index.ts"],"sourcesContent":["","// 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\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();\n * // Next connectWithMetaMaskUri call will emit a fresh URI immediately.\n * ```\n *\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 = (): 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 // `onerror` / `onblocked` fire when a concurrent tab holds the\n // DB open. We still resolve so the consumer's connect flow is\n // not stalled indefinitely; the next tab close drops the lock\n // and subsequent runs reach the empty database. The Promise\n // executor already ignores subsequent resolve calls, so no\n // extra guard is needed when multiple lifecycle events fire on\n // the same request.\n request.onerror = () => resolve();\n request.onblocked = () => resolve();\n } catch {\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":";;;;;;;;;;;ACIA,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;AAmB9B,MAAa,oCAAmD;AAC9D,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;AAQnC,WAAQ,gBAAgB,SAAS;AACjC,WAAQ,kBAAkB,SAAS;UAC7B;AACN,YAAS;;GAEX;;;;;AC1CJ,IAAa,iCAAb,cAAoDA,mCAAU;CAC5D,cAAc;AACZ,QAAM;GACJ,OAAO;GACP,MAAM;GACN,SAAS;GACT,MAAM;GACN,cACE;GACH,CAAC;;;;;;ACJN,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;AA+B7B,MAAa,yCACX,EAAE,SACF,8DAA0C,KACnB;AAYvB,qEAX4C,OAAO,CAAC,eAAe,CAE3C,MACrB,aACC,SAAS,UAAU,SACnB,SAAS,uBAAuBC,8CAAmB,oBACnD,SAAS,SAAS,aACd,aAAa,CACd,SAAS,qBAAqB,CACpC,EAEa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACehB,MAAa,yBAAyB,OACpC,EACE,6BAA6B,MAC7B,OACA,eACA,yBAEF,8DAA0C,KACK;CAC/C,MAAM,eAAe,sCAAsC,EAAE,OAAO,EAAE,OAAO;AAE7E,KAAI,iBAAiB,OACnB,4CAAQ,OAAO,CAAC,OAAO,KACrB,kDAAkD,MAAM,uBAAuB,aAAa,2FAA2F,aAAa,oCACrM;CAGH,MAAM,aAAa,MAAM,cAAc,OAAO;CAE9C,MAAM,wEAA6C;CAEnD,MAAM,cAAc,WAAW,cAAc,eAAe;AAC1D,cAAY,QAAQ,WAAW;GAC/B;CAEF,MAAM,iBAAiB,WAAW,SAAS;AAK3C,gBACG,WAAW;AACV,cAAY,OAAO,IAAI,gCAAgC,CAAC;GACxD,CACD,OAAO,UAAmB;AACzB,cAAY,OAAO,MAAM;GACzB;CAEJ,IAAIC;AACJ,KAAI;AACF,QAAM,MAAM,YAAY;WAChB;AACR,eAAa;;CAGf,MAAM,WAAW,YAA0D;AACzE,QAAM;EAEN,MAAM,iBAAiB,MAAM,sBAAsB,OAAO;AAE1D,+DAA0B,OAAO,CAAC,SAAS;GACzC,UAAUC,qDAAuB;GACjC;GACD,CAAC;EAEF,MAAM,EAAE,cAAc,MAAM,eAAe,uBAAuB;EAIlE,MAAM,cAAc,UAAU;AAE9B,MAAI,gBAAgB,OAClB,OAAM,IAAIC,8CAAqB;AAyBjC,SAAO,EAAE,wFARP;GACE;GACA,gBAAgB,CAhBiB;IACnC,SAAS;IACT,OAAO,eAAe;IACtB,6DAA0B;KACxB,SAAS;KACT,OAAO,eAAe;KACtB,mBAAmB,eAAe;KACnC,CAAC;IACF,gBAAgB;IAChB,sBAAsB;IACtB,mBAAmB,eAAe;IACnC,CAKkC;GAC/B,mBAAmB,eAAe;GACnC,EACD,OACD,EAEwB;;AAG3B,QAAO;EAAE;EAAU;EAAK;;;;;AC5J1B,IAAa,kCAAb,cAAqDC,mCAAU;CAC7D,cAAc;AACZ,QAAM;GACJ,OAAO;GACP,MAAM;GACN,SAAS;GACT,MAAM;GACN,cACE;GACH,CAAC;;;;;;mECPe,MAAM,QAAQ"}
package/dist/index.esm.js CHANGED
@@ -5,7 +5,7 @@ import { WalletProviderEnum } from "@dynamic-labs/sdk-api-core";
5
5
 
6
6
  //#region package.json
7
7
  var name = "@dynamic-labs-sdk/metamask";
8
- var version = "1.17.1";
8
+ var version = "1.19.0";
9
9
 
10
10
  //#endregion
11
11
  //#region src/clearMetaMaskSessionStorage/clearMetaMaskSessionStorage.ts
@@ -16,6 +16,15 @@ const METAMASK_SDK_IDB_NAME = "mmconnect-kv-store";
16
16
  * 10-second resume timeout reviving a dead pairing. Safe in SSR (no-op) and
17
17
  * when the DB is held open by another tab (resolves on `blocked`).
18
18
  *
19
+ * @example
20
+ * ```ts
21
+ * await clearMetaMaskSessionStorage();
22
+ * // Next connectWithMetaMaskUri call will emit a fresh URI immediately.
23
+ * ```
24
+ *
25
+ * @returns A promise that resolves once the database is deleted (or immediately in SSR).
26
+ * @see connectWithMetaMaskUri
27
+ * @see getMetaMaskExtensionWalletProviderKey
19
28
  * @notInstrumented
20
29
  */
21
30
  const clearMetaMaskSessionStorage = () => {
@@ -58,6 +67,19 @@ const METAMASK_NAME_NEEDLE = "metamask";
58
67
  * the connection through the announced provider; fall back to the chain's
59
68
  * `connectWithMetaMaskUri<Chain>` helper when `undefined`.
60
69
  *
70
+ * @example
71
+ * ```ts
72
+ * const key = getMetaMaskExtensionWalletProviderKey({ chain: 'EVM' });
73
+ * if (key) {
74
+ * await connectWithWalletProvider({ walletProviderKey: key });
75
+ * }
76
+ * ```
77
+ *
78
+ * @param params.chain - Chain to scope the lookup to.
79
+ * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
80
+ * @returns The wallet provider key string, or `undefined` if no MetaMask extension is announced.
81
+ * @see connectWithMetaMaskUri
82
+ * @see clearMetaMaskSessionStorage
61
83
  * @notInstrumented
62
84
  */
63
85
  const getMetaMaskExtensionWalletProviderKey = ({ chain }, client = getDefaultClient()) => {
@@ -75,6 +97,26 @@ const getMetaMaskExtensionWalletProviderKey = ({ chain }, client = getDefaultCli
75
97
  * specific wallet provider only after pairing is approved; the provider
76
98
  * therefore never appears in the wallet picker (no `connect` method).
77
99
  *
100
+ * @example
101
+ * ```ts
102
+ * const { uri, approval } = await connectWithMetaMaskUri({
103
+ * chain: 'EVM',
104
+ * getController: (client) => getEvmMetaMaskController(client),
105
+ * walletProviderBuilder: (client) => buildEvmWalletProvider(client),
106
+ * });
107
+ * // Render QR code with `uri`, then await approval()
108
+ * ```
109
+ *
110
+ * @param params.chain - Chain being connected; used to scope the extension-installed lookup.
111
+ * @param params.getController - Returns the chain-specific MetaMaskController for the pairing.
112
+ * @param params.walletProviderBuilder - Builds the chain-specific WalletProvider after pairing approval.
113
+ * @param [params.addToDynamicWalletAccounts] - Whether to add the wallet to the client. Defaults to `true`.
114
+ * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
115
+ * @returns An object with `uri` (the pairing URI) and `approval` (async function resolving to wallet accounts).
116
+ * @throws {MetaMaskDisplayUriMissingError} If `connect` settles before a display_uri is emitted.
117
+ * @throws {NoAddressFoundError} If no address is returned after pairing approval.
118
+ * @see clearMetaMaskSessionStorage
119
+ * @see getMetaMaskExtensionWalletProviderKey
78
120
  * @notInstrumented
79
121
  */
80
122
  const connectWithMetaMaskUri = async ({ addToDynamicWalletAccounts = true, chain, getController, walletProviderBuilder }, client = getDefaultClient()) => {
@@ -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":["","// 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\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 * @notInstrumented\n */\nexport const clearMetaMaskSessionStorage = (): 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 // `onerror` / `onblocked` fire when a concurrent tab holds the\n // DB open. We still resolve so the consumer's connect flow is\n // not stalled indefinitely; the next tab close drops the lock\n // and subsequent runs reach the empty database. The Promise\n // executor already ignores subsequent resolve calls, so no\n // extra guard is needed when multiple lifecycle events fire on\n // the same request.\n request.onerror = () => resolve();\n request.onblocked = () => resolve();\n } catch {\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 * @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 * @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":";;;;;;;;;;;ACIA,MAAM,wBAAwB;;;;;;;;;AAU9B,MAAa,oCAAmD;AAC9D,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;AAQnC,WAAQ,gBAAgB,SAAS;AACjC,WAAQ,kBAAkB,SAAS;UAC7B;AACN,YAAS;;GAEX;;;;;ACjCJ,IAAa,iCAAb,cAAoD,UAAU;CAC5D,cAAc;AACZ,QAAM;GACJ,OAAO;GACP,MAAM;GACN,SAAS;GACT,MAAM;GACN,cACE;GACH,CAAC;;;;;;ACJN,MAAM,uBAAuB;;;;;;;;;;;;AAkB7B,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;;;;;;;;;;;;;;;;ACQhB,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;;;;;ACxI1B,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":["../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":["","// 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\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();\n * // Next connectWithMetaMaskUri call will emit a fresh URI immediately.\n * ```\n *\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 = (): 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 // `onerror` / `onblocked` fire when a concurrent tab holds the\n // DB open. We still resolve so the consumer's connect flow is\n // not stalled indefinitely; the next tab close drops the lock\n // and subsequent runs reach the empty database. The Promise\n // executor already ignores subsequent resolve calls, so no\n // extra guard is needed when multiple lifecycle events fire on\n // the same request.\n request.onerror = () => resolve();\n request.onblocked = () => resolve();\n } catch {\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":";;;;;;;;;;;ACIA,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;AAmB9B,MAAa,oCAAmD;AAC9D,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;AAQnC,WAAQ,gBAAgB,SAAS;AACjC,WAAQ,kBAAkB,SAAS;UAC7B;AACN,YAAS;;GAEX;;;;;AC1CJ,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"}