@dynamic-labs-sdk/metamask 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/errors/MetaMaskWalletNotConnectedError/MetaMaskWalletNotConnectedError.d.ts +5 -0
- package/dist/errors/MetaMaskWalletNotConnectedError/MetaMaskWalletNotConnectedError.d.ts.map +1 -0
- package/dist/errors/MetaMaskWalletNotConnectedError/index.d.ts +2 -0
- package/dist/errors/MetaMaskWalletNotConnectedError/index.d.ts.map +1 -0
- package/dist/exports/index.d.ts +1 -0
- package/dist/exports/index.d.ts.map +1 -1
- package/dist/index.cjs +16 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +16 -2
- package/dist/index.esm.js.map +1 -1
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MetaMaskWalletNotConnectedError.d.ts","sourceRoot":"","sources":["../../../src/errors/MetaMaskWalletNotConnectedError/MetaMaskWalletNotConnectedError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,qBAAa,+BAAgC,SAAQ,SAAS;;CAW7D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/errors/MetaMaskWalletNotConnectedError/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,+BAA+B,EAAE,MAAM,mCAAmC,CAAC"}
|
package/dist/exports/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export { clearMetaMaskSessionStorage } from '../clearMetaMaskSessionStorage';
|
|
|
2
2
|
export { connectWithMetaMaskUri } from '../connectWithMetaMaskUri';
|
|
3
3
|
export type { ConnectWithMetaMaskUriParams } from '../connectWithMetaMaskUri';
|
|
4
4
|
export { MetaMaskDisplayUriMissingError } from '../errors/MetaMaskDisplayUriMissingError';
|
|
5
|
+
export { MetaMaskWalletNotConnectedError } from '../errors/MetaMaskWalletNotConnectedError';
|
|
5
6
|
export { getMetaMaskExtensionWalletProviderKey } from '../getMetaMaskExtensionWalletProviderKey';
|
|
6
7
|
export type { DisplayUriListener, MetaMaskController, } from '../metamask.types';
|
|
7
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/exports/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,YAAY,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,8BAA8B,EAAE,MAAM,0CAA0C,CAAC;AAC1F,OAAO,EAAE,qCAAqC,EAAE,MAAM,0CAA0C,CAAC;AACjG,YAAY,EACV,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/exports/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,YAAY,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,8BAA8B,EAAE,MAAM,0CAA0C,CAAC;AAC1F,OAAO,EAAE,+BAA+B,EAAE,MAAM,2CAA2C,CAAC;AAC5F,OAAO,EAAE,qCAAqC,EAAE,MAAM,0CAA0C,CAAC;AACjG,YAAY,EACV,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,mBAAmB,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.
|
|
8
|
+
var version = "1.5.0";
|
|
9
9
|
|
|
10
10
|
//#endregion
|
|
11
11
|
//#region src/clearMetaMaskSessionStorage/clearMetaMaskSessionStorage.ts
|
|
@@ -130,12 +130,27 @@ const connectWithMetaMaskUri = async ({ addToDynamicWalletAccounts = true, chain
|
|
|
130
130
|
};
|
|
131
131
|
};
|
|
132
132
|
|
|
133
|
+
//#endregion
|
|
134
|
+
//#region src/errors/MetaMaskWalletNotConnectedError/MetaMaskWalletNotConnectedError.ts
|
|
135
|
+
var MetaMaskWalletNotConnectedError = class extends _dynamic_labs_sdk_client.BaseError {
|
|
136
|
+
constructor() {
|
|
137
|
+
super({
|
|
138
|
+
cause: null,
|
|
139
|
+
code: "metamask_wallet_not_connected",
|
|
140
|
+
docsUrl: null,
|
|
141
|
+
name: "MetaMaskWalletNotConnectedError",
|
|
142
|
+
shortMessage: "MetaMask SDK has no connected wallet account. Complete the URI pairing (await the connect approval) before building the MetaMask wallet provider."
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
133
147
|
//#endregion
|
|
134
148
|
//#region src/exports/index.ts
|
|
135
149
|
(0, _dynamic_labs_sdk_assert_package_version.assertPackageVersion)(name, version);
|
|
136
150
|
|
|
137
151
|
//#endregion
|
|
138
152
|
exports.MetaMaskDisplayUriMissingError = MetaMaskDisplayUriMissingError;
|
|
153
|
+
exports.MetaMaskWalletNotConnectedError = MetaMaskWalletNotConnectedError;
|
|
139
154
|
exports.clearMetaMaskSessionStorage = clearMetaMaskSessionStorage;
|
|
140
155
|
exports.connectWithMetaMaskUri = connectWithMetaMaskUri;
|
|
141
156
|
exports.getMetaMaskExtensionWalletProviderKey = getMetaMaskExtensionWalletProviderKey;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["BaseError","WalletProviderEnum","uri: string","WalletProviderPriority","NoAddressFoundError"],"sources":["../package.json","../src/clearMetaMaskSessionStorage/clearMetaMaskSessionStorage.ts","../src/errors/MetaMaskDisplayUriMissingError/MetaMaskDisplayUriMissingError.ts","../src/getMetaMaskExtensionWalletProviderKey/getMetaMaskExtensionWalletProviderKey.ts","../src/connectWithMetaMaskUri/connectWithMetaMaskUri.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 * @not-instrumented\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 * @not-instrumented\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 * @not-instrumented\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 { 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 { 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;;;;;mECtIL,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 * @not-instrumented\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 * @not-instrumented\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 * @not-instrumented\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"}
|
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.
|
|
8
|
+
var version = "1.5.0";
|
|
9
9
|
|
|
10
10
|
//#endregion
|
|
11
11
|
//#region src/clearMetaMaskSessionStorage/clearMetaMaskSessionStorage.ts
|
|
@@ -130,10 +130,24 @@ const connectWithMetaMaskUri = async ({ addToDynamicWalletAccounts = true, chain
|
|
|
130
130
|
};
|
|
131
131
|
};
|
|
132
132
|
|
|
133
|
+
//#endregion
|
|
134
|
+
//#region src/errors/MetaMaskWalletNotConnectedError/MetaMaskWalletNotConnectedError.ts
|
|
135
|
+
var MetaMaskWalletNotConnectedError = class extends BaseError {
|
|
136
|
+
constructor() {
|
|
137
|
+
super({
|
|
138
|
+
cause: null,
|
|
139
|
+
code: "metamask_wallet_not_connected",
|
|
140
|
+
docsUrl: null,
|
|
141
|
+
name: "MetaMaskWalletNotConnectedError",
|
|
142
|
+
shortMessage: "MetaMask SDK has no connected wallet account. Complete the URI pairing (await the connect approval) before building the MetaMask wallet provider."
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
133
147
|
//#endregion
|
|
134
148
|
//#region src/exports/index.ts
|
|
135
149
|
assertPackageVersion(name, version);
|
|
136
150
|
|
|
137
151
|
//#endregion
|
|
138
|
-
export { MetaMaskDisplayUriMissingError, clearMetaMaskSessionStorage, connectWithMetaMaskUri, getMetaMaskExtensionWalletProviderKey };
|
|
152
|
+
export { MetaMaskDisplayUriMissingError, MetaMaskWalletNotConnectedError, clearMetaMaskSessionStorage, connectWithMetaMaskUri, getMetaMaskExtensionWalletProviderKey };
|
|
139
153
|
//# sourceMappingURL=index.esm.js.map
|
package/dist/index.esm.js.map
CHANGED
|
@@ -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/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 * @not-instrumented\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 * @not-instrumented\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 * @not-instrumented\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 { 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 { 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;;;;;ACtI1B,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 * @not-instrumented\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 * @not-instrumented\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 * @not-instrumented\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"}
|