@dynamic-labs-sdk/solana 1.26.0 → 1.27.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/{addSolanaWalletStandardExtension-BIIbTjuM.esm.js → addSolanaWalletStandardExtension-C7S6Ur5b.esm.js} +3 -3
  2. package/dist/{addSolanaWalletStandardExtension-BIIbTjuM.esm.js.map → addSolanaWalletStandardExtension-C7S6Ur5b.esm.js.map} +1 -1
  3. package/dist/{addSolanaWalletStandardExtension-Bi497uRz.cjs → addSolanaWalletStandardExtension-DSPBdINK.cjs} +3 -3
  4. package/dist/{addSolanaWalletStandardExtension-Bi497uRz.cjs.map → addSolanaWalletStandardExtension-DSPBdINK.cjs.map} +1 -1
  5. package/dist/{addWaasSolanaExtension-DNLz40xg.esm.js → addWaasSolanaExtension-B4P3dvTl.esm.js} +2 -2
  6. package/dist/{addWaasSolanaExtension-DNLz40xg.esm.js.map → addWaasSolanaExtension-B4P3dvTl.esm.js.map} +1 -1
  7. package/dist/{addWaasSolanaExtension-B7wwa-j0.cjs → addWaasSolanaExtension-ChtGFgNU.cjs} +2 -2
  8. package/dist/{addWaasSolanaExtension-B7wwa-j0.cjs.map → addWaasSolanaExtension-ChtGFgNU.cjs.map} +1 -1
  9. package/dist/{createWalletProviderFromSolanaStandardWallet-Dxqecq1I.esm.js → createWalletProviderFromSolanaStandardWallet-BzisQSvU.esm.js} +2 -2
  10. package/dist/{createWalletProviderFromSolanaStandardWallet-Dxqecq1I.esm.js.map → createWalletProviderFromSolanaStandardWallet-BzisQSvU.esm.js.map} +1 -1
  11. package/dist/{createWalletProviderFromSolanaStandardWallet-DO1j4Mzn.cjs → createWalletProviderFromSolanaStandardWallet-Cf7GbzHy.cjs} +2 -2
  12. package/dist/{createWalletProviderFromSolanaStandardWallet-DO1j4Mzn.cjs.map → createWalletProviderFromSolanaStandardWallet-Cf7GbzHy.cjs.map} +1 -1
  13. package/dist/index.cjs +4 -4
  14. package/dist/index.esm.js +4 -4
  15. package/dist/metamask/utils/createMetaMaskSolanaController/createMetaMaskSolanaController.d.ts +3 -0
  16. package/dist/metamask/utils/createMetaMaskSolanaController/createMetaMaskSolanaController.d.ts.map +1 -1
  17. package/dist/metamask.cjs +8 -4
  18. package/dist/metamask.cjs.map +1 -1
  19. package/dist/metamask.esm.js +8 -4
  20. package/dist/metamask.esm.js.map +1 -1
  21. package/dist/{solanaTransferAmount-BCiUGR02.esm.js → solanaTransferAmount-BqgJ6ZGp.esm.js} +2 -2
  22. package/dist/{solanaTransferAmount-BCiUGR02.esm.js.map → solanaTransferAmount-BqgJ6ZGp.esm.js.map} +1 -1
  23. package/dist/{solanaTransferAmount-3WcOVJ65.cjs → solanaTransferAmount-C76BeL3A.cjs} +2 -2
  24. package/dist/{solanaTransferAmount-3WcOVJ65.cjs.map → solanaTransferAmount-C76BeL3A.cjs.map} +1 -1
  25. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  26. package/dist/waas.cjs +2 -2
  27. package/dist/waas.esm.js +2 -2
  28. package/dist/walletConnect.cjs +1 -1
  29. package/dist/walletConnect.esm.js +1 -1
  30. package/dist/walletStandard.cjs +3 -3
  31. package/dist/walletStandard.esm.js +3 -3
  32. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"metamask.cjs","names":["supportedNetworks: MetaMaskSupportedNetworks","latestDisplayUri: string | undefined","inFlightConnect: Promise<void> | null","getFeaturesForSolanaStandardWallet","MetaMaskWalletNotConnectedError","createWalletProviderFromSolanaStandardWallet","WalletProviderEnum","packageName","packageVersion"],"sources":["../src/metamask/utils/getSolanaNetworkFromCluster/getSolanaNetworkFromCluster.ts","../src/metamask/utils/getSupportedNetworks/getSupportedNetworks.ts","../src/metamask/utils/createMetaMaskSolanaController/createMetaMaskSolanaController.ts","../src/metamask/utils/getOrCreateMetaMaskSolanaController/getOrCreateMetaMaskSolanaController.ts","../src/metamask/createMetaMaskSolanaWalletProvider/createMetaMaskSolanaWalletProvider.ts","../src/metamask/connectWithMetaMaskUriSolana/connectWithMetaMaskUriSolana.ts","../src/metamask/connectAndVerifyWithMetaMaskUriSolana/connectAndVerifyWithMetaMaskUriSolana.ts","../src/metamask/getMetaMaskSolanaExtensionWalletProviderKey/getMetaMaskSolanaExtensionWalletProviderKey.ts","../src/exports/metamask.ts"],"sourcesContent":["import type { SolanaNetwork } from '@metamask/connect-solana';\n\n/** Parameters for {@link getSolanaNetworkFromCluster}. */\nexport type GetSolanaNetworkFromClusterParams = {\n /** The Dynamic network `cluster` (e.g. `mainnet-beta`, `devnet`, `testnet`). */\n cluster: string | undefined;\n};\n\n/**\n * Maps a Dynamic network `cluster` (e.g. `mainnet-beta`, `devnet`,\n * `testnet`) to the `mainnet | devnet | testnet` key shape expected by\n * `@metamask/connect-solana`'s `createSolanaClient`. Returns `undefined` for\n * clusters that do not correspond to one of MetaMask's supported Solana\n * networks so callers can skip them. Used by `getSupportedNetworks` to build\n * the SDK's `supportedNetworks` map.\n *\n * @notInstrumented\n */\nexport const getSolanaNetworkFromCluster = ({\n cluster,\n}: GetSolanaNetworkFromClusterParams): SolanaNetwork | undefined => {\n if (cluster === undefined) {\n return undefined;\n }\n\n if (cluster.includes('mainnet')) {\n return 'mainnet';\n }\n\n if (cluster.includes('devnet')) {\n return 'devnet';\n }\n\n if (cluster.includes('testnet')) {\n return 'testnet';\n }\n\n return undefined;\n};\n","import type { DynamicClient } from '@dynamic-labs-sdk/client';\nimport { getNetworksData } from '@dynamic-labs-sdk/client';\nimport { assertNonEmptyArray } from '@dynamic-labs-sdk/client/core';\nimport type { SolanaNetwork } from '@metamask/connect-solana';\n\nimport { getSolanaNetworkFromCluster } from '../getSolanaNetworkFromCluster';\n\ntype MetaMaskSupportedNetworks = Partial<Record<SolanaNetwork, string>>;\n\n/**\n * Builds the `supportedNetworks` map required by\n * `@metamask/connect-solana`'s `createSolanaClient`, keyed by the SDK's\n * `mainnet | devnet | testnet` network names and valued with the first\n * configured RPC URL for each. Sources the configured SOL networks from the\n * Dynamic client's project settings. Throws when no SOL network is\n * configured, mirroring the EVM `getSupportedNetworks` contract.\n *\n * @notInstrumented\n */\nexport const getSupportedNetworks = (\n client: DynamicClient\n): MetaMaskSupportedNetworks => {\n const solanaNetworks = getNetworksData(client).filter(\n (network) => network.chain === 'SOL'\n );\n\n assertNonEmptyArray(\n solanaNetworks,\n 'No SOL networks have been configured. Make sure to add at least one Solana network to your project settings in the Dynamic Dashboard.'\n );\n\n const supportedNetworks: MetaMaskSupportedNetworks = {};\n\n for (const network of solanaNetworks) {\n const solanaNetwork = getSolanaNetworkFromCluster({\n cluster: network.cluster,\n });\n\n // Skip clusters MetaMask does not recognise, and keep the first RPC URL\n // seen for a given network so earlier-configured networks take priority.\n if (\n solanaNetwork !== undefined &&\n supportedNetworks[solanaNetwork] === undefined\n ) {\n supportedNetworks[solanaNetwork] = network.rpcUrls.http[0];\n }\n }\n\n return supportedNetworks;\n};\n","import type { DynamicClient } from '@dynamic-labs-sdk/client';\nimport {\n getAppMetadata,\n getCore,\n getNativeLinkScheme,\n} from '@dynamic-labs-sdk/client/core';\nimport { clearMetaMaskSessionStorage } from '@dynamic-labs-sdk/metamask';\nimport type { DisplayUriListener } from '@dynamic-labs-sdk/metamask';\nimport { createSolanaClient } from '@metamask/connect-solana';\n\nimport { getFeaturesForSolanaStandardWallet } from '../../../walletStandard/utils/getFeaturesForSolanaStandardWallet';\nimport type { MetaMaskSolanaController } from '../../metamask.types';\nimport { getSupportedNetworks } from '../getSupportedNetworks';\n\n/**\n * Builds a fully-initialised `MetaMaskSolanaController` for the given Dynamic\n * client. Drives the `@metamask/connect-solana` SDK through its Wallet\n * Standard surface so consumers render their own QR / deep-link UI, and\n * subscribes to the SDK core's `display_uri` event at construction time so\n * the first URI emission cannot be lost to a subscription race. The wallet\n * is created with `skipAutoRegister` so this URI-pairing client does not\n * register itself into the global Wallet Standard registry — an announced\n * MetaMask extension is discovered independently. Dapp metadata is sourced\n * from the client's `getAppMetadata`. Browser-only.\n *\n * @notInstrumented\n */\nexport const createMetaMaskSolanaController = async (\n client: DynamicClient\n): Promise<MetaMaskSolanaController> => {\n const supportedNetworks = getSupportedNetworks(client);\n const { appName, appLogoUrl, appUniversalLink, appNativeLink } =\n getAppMetadata(client);\n\n // Drop any IndexedDB session state left behind by a previous tab, page\n // reload, or abandoned pairing before the SDK initialises. The SDK's\n // auto-recovery path otherwise picks up a stale transport descriptor and\n // spends its (non-configurable) 10-second resume timeout on every\n // controller construction trying to revive a relay session that no longer\n // exists, surfacing as a long QR skeleton delay on every page reload that\n // follows an abandoned pairing.\n await clearMetaMaskSessionStorage();\n\n const listeners = new Set<DisplayUriListener>();\n let latestDisplayUri: string | undefined;\n\n const sdk = await createSolanaClient({\n api: { supportedNetworks },\n dapp: {\n iconUrl: appLogoUrl,\n name: appName,\n nativeScheme: getNativeLinkScheme({ nativeLink: appNativeLink }),\n url: appUniversalLink ?? '',\n },\n debug: false,\n skipAutoRegister: true,\n });\n\n sdk.core.on('display_uri', (uri) => {\n latestDisplayUri = uri;\n for (const listener of listeners) {\n listener(uri);\n }\n });\n\n // A terminal connection state means any cached URI is for a pairing that is\n // either complete or torn down, so it must not be replayed to late\n // subscribers.\n sdk.core.on('stateChanged', (status) => {\n if (status === 'connected' || status === 'disconnected') {\n latestDisplayUri = undefined;\n }\n });\n\n // Defensive cleanup: even though we cleared IndexedDB before constructing\n // the SDK, an in-flight `display_uri` emission could theoretically race the\n // storage delete on slow devices. Clearing the cache here guarantees late\n // subscribers cannot replay an URI that originated from any pairing attempt\n // prior to this construction.\n latestDisplayUri = undefined;\n\n const onDisplayUri = (listener: DisplayUriListener): (() => void) => {\n listeners.add(listener);\n if (latestDisplayUri !== undefined) {\n listener(latestDisplayUri);\n }\n return () => {\n listeners.delete(listener);\n };\n };\n\n // Tracks an in-flight `connect` call so that overlapping invocations (most\n // commonly React's StrictMode double-invocation of effects, or a hook that\n // re-runs while the user is still scanning) await the same underlying\n // pairing instead of racing two connect calls against each other.\n let inFlightConnect: Promise<void> | null = null;\n\n const connect = (): Promise<void> => {\n if (inFlightConnect) {\n return inFlightConnect;\n }\n\n inFlightConnect = (async () => {\n try {\n // If a previous pairing was cancelled mid-flight the SDK can be left\n // in `connecting` state with a dead transport descriptor; tear it\n // down so the next connect issues a fresh URI synchronously instead\n // of waiting for the SDK's (non-configurable) 10-second resume\n // timeout.\n if (sdk.core.status === 'connecting') {\n try {\n await sdk.disconnect();\n } catch (error) {\n getCore(client).logger.debug(\n '[metamask] pre-connect disconnect rejected (expected when aborting a pairing the wallet never accepted)',\n error\n );\n }\n }\n\n const features = getFeaturesForSolanaStandardWallet(sdk.getWallet());\n\n await features['standard:connect'].connect();\n } finally {\n inFlightConnect = null;\n }\n })();\n\n return inFlightConnect;\n };\n\n return {\n clearCachedDisplayUri: () => {\n latestDisplayUri = undefined;\n },\n connect,\n getLatestDisplayUri: () => latestDisplayUri,\n onDisplayUri,\n sdk,\n };\n};\n","import { createRuntimeServiceAccessKey } from '@dynamic-labs-sdk/client/core';\n\nimport { createMetaMaskSolanaController } from '../createMetaMaskSolanaController';\n\nconst RUNTIME_SERVICE_KEY = 'metaMaskSolanaController';\n\n/**\n * Per-`DynamicClient` accessor for the lazily-constructed MetaMask Solana\n * controller. Wraps `createMetaMaskSolanaController` with the standard\n * `runtimeServices` cache so every caller — the Wallet Standard\n * wallet-provider builder, the `display_uri` subscription helper, and the\n * `connectWithMetaMaskUriSolana` URI-returning helper — shares the same\n * controller (and therefore the same SDK instance, display-URI cache, and\n * listener registry) per Dynamic client.\n *\n * The cache is **per-Dynamic-client, not per-SDK-instance**:\n * `@metamask/connect-solana`'s `createSolanaClient` builds on the shared\n * MultichainCore singleton, so when multiple Dynamic clients coexist they\n * end up sharing the same MetaMask session regardless of this cache. The\n * wrapper exists to own the controller's `display_uri` cache and listener\n * registry per Dynamic client, which the SDK itself does not expose.\n *\n * @notInstrumented\n */\nexport const getOrCreateMetaMaskSolanaController = createRuntimeServiceAccessKey(\n RUNTIME_SERVICE_KEY,\n (client) => createMetaMaskSolanaController(client)\n);\n","import type { DynamicClient } from '@dynamic-labs-sdk/client';\nimport { MetaMaskWalletNotConnectedError } from '@dynamic-labs-sdk/metamask';\nimport { WalletProviderEnum } from '@dynamic-labs/sdk-api-core';\n\nimport type { SolanaWalletProvider } from '../../SolanaWalletProvider.types';\nimport { createWalletProviderFromSolanaStandardWallet } from '../../walletStandard/utils/createWalletProviderFromSolanaStandardWallet';\nimport { getOrCreateMetaMaskSolanaController } from '../utils/getOrCreateMetaMaskSolanaController';\n\n/**\n * Builds the `SolanaWalletProvider` registered AFTER a successful MetaMask\n * SDK URI pairing. Wraps the paired Wallet Standard wallet exposed by\n * `@metamask/connect-solana` behind the Dynamic Solana provider facade and\n * classifies it as `QrCode` so its key does not collide with an announced\n * MetaMask browser-extension provider for the same wallet name. Drops\n * `connect` so the provider is filtered out of the wallet picker by\n * `getAvailableWalletProvidersData` — mirroring how WalletConnect URI\n * sessions register a signing-only provider.\n *\n * @notInstrumented\n */\nexport const createMetaMaskSolanaWalletProvider = async (\n client: DynamicClient\n): Promise<SolanaWalletProvider> => {\n const controller = await getOrCreateMetaMaskSolanaController(client);\n\n const walletStandardWallet = controller.sdk.getWallet();\n\n // The provider is only meaningful once the URI pairing has produced a\n // connected account; guard so a premature or out-of-order call raises a\n // readable error instead of building a provider around an empty wallet.\n if (walletStandardWallet.accounts.length === 0) {\n throw new MetaMaskWalletNotConnectedError();\n }\n\n const walletProvider = createWalletProviderFromSolanaStandardWallet({\n dynamicClient: client,\n walletProviderType: WalletProviderEnum.QrCode,\n walletStandardWallet,\n });\n\n return {\n ...walletProvider,\n connect: undefined,\n };\n};\n","import { getDefaultClient } from '@dynamic-labs-sdk/client';\nimport type { WalletProviderUriConnectionResult } from '@dynamic-labs-sdk/client';\nimport { connectWithMetaMaskUri } from '@dynamic-labs-sdk/metamask';\n\nimport { registerSolanaNetworkProviderBuilder } from '../../registerSolanaNetworkProviderBuilder';\nimport { createMetaMaskSolanaWalletProvider } from '../createMetaMaskSolanaWalletProvider';\nimport { getOrCreateMetaMaskSolanaController } from '../utils/getOrCreateMetaMaskSolanaController';\n\nexport type ConnectWithMetaMaskUriSolanaParams = {\n /** Whether to add the connected wallet account to the Dynamic client. Defaults to `true`. */\n addToDynamicWalletAccounts?: boolean;\n};\n\n/**\n * Drives a MetaMask SDK URI pairing for Solana and returns `{ approval, uri }`\n * so consumers can render the QR / hand the URI to a deeplink. The resulting\n * wallet provider registers for signing only and is never surfaced in the\n * wallet picker. When the MetaMask extension is announced via Wallet Standard,\n * prefer routing through `getMetaMaskSolanaExtensionWalletProviderKey` instead.\n *\n * @notInstrumented\n */\nexport const connectWithMetaMaskUriSolana = (\n { addToDynamicWalletAccounts = true }: ConnectWithMetaMaskUriSolanaParams = {},\n client = getDefaultClient()\n): Promise<WalletProviderUriConnectionResult> => {\n registerSolanaNetworkProviderBuilder(client);\n\n return connectWithMetaMaskUri(\n {\n addToDynamicWalletAccounts,\n chain: 'SOL',\n getController: getOrCreateMetaMaskSolanaController,\n walletProviderBuilder: createMetaMaskSolanaWalletProvider,\n },\n client\n );\n};\n","import {\n type WalletAccount,\n type WalletProviderUriConnectionResult,\n getDefaultClient,\n verifyWalletAccount,\n} from '@dynamic-labs-sdk/client';\n\nimport { connectWithMetaMaskUriSolana } from '../connectWithMetaMaskUriSolana';\n\n/**\n * Drives a MetaMask SDK URI pairing for Solana and verifies ownership of the\n * paired wallet account through message signing, returning `{ approval, uri }`\n * so consumers can render the QR / hand the URI to a deeplink.\n *\n * Builds on `connectWithMetaMaskUriSolana` (rather than the chain-agnostic\n * connector directly) so the Solana-specific wiring stays defined in one\n * place, then wraps its `approval` to add the verification round-trip. The\n * pairing is driven with `addToDynamicWalletAccounts: false` so the account\n * lands as a verified credential instead of an unverified entry.\n *\n * The MetaMask SDK does not expose a single-round-trip authenticate\n * primitive, so this drives two sequential interactions on the wallet side:\n * the user first approves the pairing, then approves a sign-in message.\n *\n * @notInstrumented\n */\nexport const connectAndVerifyWithMetaMaskUriSolana = async (\n client = getDefaultClient()\n): Promise<WalletProviderUriConnectionResult> => {\n const { approval, uri } = await connectWithMetaMaskUriSolana(\n { addToDynamicWalletAccounts: false },\n client\n );\n\n const verifiedApproval = async (): Promise<{\n walletAccounts: WalletAccount[];\n }> => {\n const { walletAccounts } = await approval();\n\n // MetaMask SDK exposes a single active address per pairing, mirroring how\n // the underlying connect helper materializes a single account from\n // `addresses[0]`. Verify it directly.\n const [walletAccount] = walletAccounts;\n\n if (walletAccount) {\n await verifyWalletAccount({ walletAccount }, client);\n }\n\n return { walletAccounts };\n };\n\n return { approval: verifiedApproval, uri };\n};\n","import { getDefaultClient } from '@dynamic-labs-sdk/client';\nimport { getMetaMaskExtensionWalletProviderKey } from '@dynamic-labs-sdk/metamask';\n\n/**\n * Returns the wallet provider key of the MetaMask browser extension announced\n * for Solana via Wallet Standard, or `undefined` when none is announced. Pass\n * the returned key to `connectWithWalletProvider` to route through the\n * announced provider; fall back to `connectWithMetaMaskUriSolana` when\n * `undefined`.\n *\n * @notInstrumented\n */\nexport const getMetaMaskSolanaExtensionWalletProviderKey = (\n client = getDefaultClient()\n): string | undefined =>\n getMetaMaskExtensionWalletProviderKey({ chain: 'SOL' }, client);\n","import { assertPackageVersion } from '@dynamic-labs-sdk/assert-package-version';\n\nimport {\n name as packageName,\n version as packageVersion,\n} from '../../package.json';\nassertPackageVersion(packageName, packageVersion);\n\nexport { connectAndVerifyWithMetaMaskUriSolana } from '../metamask/connectAndVerifyWithMetaMaskUriSolana';\nexport { connectWithMetaMaskUriSolana } from '../metamask/connectWithMetaMaskUriSolana';\nexport type { ConnectWithMetaMaskUriSolanaParams } from '../metamask/connectWithMetaMaskUriSolana/connectWithMetaMaskUriSolana';\nexport { getMetaMaskSolanaExtensionWalletProviderKey } from '../metamask/getMetaMaskSolanaExtensionWalletProviderKey';\nexport { MetaMaskDisplayUriMissingError } from '@dynamic-labs-sdk/metamask';\n"],"mappings":"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"}
1
+ {"version":3,"file":"metamask.cjs","names":["supportedNetworks: MetaMaskSupportedNetworks","latestDisplayUri: string | undefined","inFlightConnect: Promise<void> | null","getFeaturesForSolanaStandardWallet","MetaMaskWalletNotConnectedError","createWalletProviderFromSolanaStandardWallet","WalletProviderEnum","packageName","packageVersion"],"sources":["../src/metamask/utils/getSolanaNetworkFromCluster/getSolanaNetworkFromCluster.ts","../src/metamask/utils/getSupportedNetworks/getSupportedNetworks.ts","../src/metamask/utils/createMetaMaskSolanaController/createMetaMaskSolanaController.ts","../src/metamask/utils/getOrCreateMetaMaskSolanaController/getOrCreateMetaMaskSolanaController.ts","../src/metamask/createMetaMaskSolanaWalletProvider/createMetaMaskSolanaWalletProvider.ts","../src/metamask/connectWithMetaMaskUriSolana/connectWithMetaMaskUriSolana.ts","../src/metamask/connectAndVerifyWithMetaMaskUriSolana/connectAndVerifyWithMetaMaskUriSolana.ts","../src/metamask/getMetaMaskSolanaExtensionWalletProviderKey/getMetaMaskSolanaExtensionWalletProviderKey.ts","../src/exports/metamask.ts"],"sourcesContent":["import type { SolanaNetwork } from '@metamask/connect-solana';\n\n/** Parameters for {@link getSolanaNetworkFromCluster}. */\nexport type GetSolanaNetworkFromClusterParams = {\n /** The Dynamic network `cluster` (e.g. `mainnet-beta`, `devnet`, `testnet`). */\n cluster: string | undefined;\n};\n\n/**\n * Maps a Dynamic network `cluster` (e.g. `mainnet-beta`, `devnet`,\n * `testnet`) to the `mainnet | devnet | testnet` key shape expected by\n * `@metamask/connect-solana`'s `createSolanaClient`. Returns `undefined` for\n * clusters that do not correspond to one of MetaMask's supported Solana\n * networks so callers can skip them. Used by `getSupportedNetworks` to build\n * the SDK's `supportedNetworks` map.\n *\n * @notInstrumented\n */\nexport const getSolanaNetworkFromCluster = ({\n cluster,\n}: GetSolanaNetworkFromClusterParams): SolanaNetwork | undefined => {\n if (cluster === undefined) {\n return undefined;\n }\n\n if (cluster.includes('mainnet')) {\n return 'mainnet';\n }\n\n if (cluster.includes('devnet')) {\n return 'devnet';\n }\n\n if (cluster.includes('testnet')) {\n return 'testnet';\n }\n\n return undefined;\n};\n","import type { DynamicClient } from '@dynamic-labs-sdk/client';\nimport { getNetworksData } from '@dynamic-labs-sdk/client';\nimport { assertNonEmptyArray } from '@dynamic-labs-sdk/client/core';\nimport type { SolanaNetwork } from '@metamask/connect-solana';\n\nimport { getSolanaNetworkFromCluster } from '../getSolanaNetworkFromCluster';\n\ntype MetaMaskSupportedNetworks = Partial<Record<SolanaNetwork, string>>;\n\n/**\n * Builds the `supportedNetworks` map required by\n * `@metamask/connect-solana`'s `createSolanaClient`, keyed by the SDK's\n * `mainnet | devnet | testnet` network names and valued with the first\n * configured RPC URL for each. Sources the configured SOL networks from the\n * Dynamic client's project settings. Throws when no SOL network is\n * configured, mirroring the EVM `getSupportedNetworks` contract.\n *\n * @notInstrumented\n */\nexport const getSupportedNetworks = (\n client: DynamicClient\n): MetaMaskSupportedNetworks => {\n const solanaNetworks = getNetworksData(client).filter(\n (network) => network.chain === 'SOL'\n );\n\n assertNonEmptyArray(\n solanaNetworks,\n 'No SOL networks have been configured. Make sure to add at least one Solana network to your project settings in the Dynamic Dashboard.'\n );\n\n const supportedNetworks: MetaMaskSupportedNetworks = {};\n\n for (const network of solanaNetworks) {\n const solanaNetwork = getSolanaNetworkFromCluster({\n cluster: network.cluster,\n });\n\n // Skip clusters MetaMask does not recognise, and keep the first RPC URL\n // seen for a given network so earlier-configured networks take priority.\n if (\n solanaNetwork !== undefined &&\n supportedNetworks[solanaNetwork] === undefined\n ) {\n supportedNetworks[solanaNetwork] = network.rpcUrls.http[0];\n }\n }\n\n return supportedNetworks;\n};\n","import type { DynamicClient } from '@dynamic-labs-sdk/client';\nimport {\n getAppMetadata,\n getCore,\n getNativeLinkScheme,\n} from '@dynamic-labs-sdk/client/core';\nimport { clearMetaMaskSessionStorage } from '@dynamic-labs-sdk/metamask';\nimport type { DisplayUriListener } from '@dynamic-labs-sdk/metamask';\nimport { createSolanaClient } from '@metamask/connect-solana';\n\nimport { getFeaturesForSolanaStandardWallet } from '../../../walletStandard/utils/getFeaturesForSolanaStandardWallet';\nimport type { MetaMaskSolanaController } from '../../metamask.types';\nimport { getSupportedNetworks } from '../getSupportedNetworks';\n\n/**\n * Builds a fully-initialised `MetaMaskSolanaController` for the given Dynamic\n * client. Drives the `@metamask/connect-solana` SDK through its Wallet\n * Standard surface so consumers render their own QR / deep-link UI, and\n * subscribes to the SDK core's `display_uri` event at construction time so\n * the first URI emission cannot be lost to a subscription race. The wallet\n * is created with `skipAutoRegister` so this URI-pairing client does not\n * register itself into the global Wallet Standard registry — an announced\n * MetaMask extension is discovered independently. Dapp metadata is sourced\n * from the client's `getAppMetadata`. Browser-only.\n * The MetaMask SDK's own verbose logging is tied to the Dynamic client's log\n * level, so turning on `debug` logging for the Dynamic SDK also surfaces\n * MetaMask's internal SDK trace output.\n *\n * @notInstrumented\n */\nexport const createMetaMaskSolanaController = async (\n client: DynamicClient\n): Promise<MetaMaskSolanaController> => {\n const supportedNetworks = getSupportedNetworks(client);\n const { appName, appLogoUrl, appUniversalLink, appNativeLink } =\n getAppMetadata(client);\n const { logger } = getCore(client);\n\n // Drop any IndexedDB session state left behind by a previous tab, page\n // reload, or abandoned pairing before the SDK initialises. The SDK's\n // auto-recovery path otherwise picks up a stale transport descriptor and\n // spends its (non-configurable) 10-second resume timeout on every\n // controller construction trying to revive a relay session that no longer\n // exists, surfacing as a long QR skeleton delay on every page reload that\n // follows an abandoned pairing.\n await clearMetaMaskSessionStorage(client);\n\n const listeners = new Set<DisplayUriListener>();\n let latestDisplayUri: string | undefined;\n\n const sdk = await createSolanaClient({\n api: { supportedNetworks },\n dapp: {\n iconUrl: appLogoUrl,\n name: appName,\n nativeScheme: getNativeLinkScheme({ nativeLink: appNativeLink }),\n url: appUniversalLink ?? '',\n },\n // Mirror the Dynamic client's own debug level, so a consumer who turns on\n // Dynamic SDK debug logging also gets MetaMask's internal SDK trace\n // output without a second, MetaMask-specific toggle to remember.\n debug: logger.isEnabled('debug'),\n skipAutoRegister: true,\n });\n\n sdk.core.on('display_uri', (uri) => {\n latestDisplayUri = uri;\n for (const listener of listeners) {\n listener(uri);\n }\n });\n\n // A terminal connection state means any cached URI is for a pairing that is\n // either complete or torn down, so it must not be replayed to late\n // subscribers.\n sdk.core.on('stateChanged', (status) => {\n if (status === 'connected' || status === 'disconnected') {\n latestDisplayUri = undefined;\n }\n });\n\n // Defensive cleanup: even though we cleared IndexedDB before constructing\n // the SDK, an in-flight `display_uri` emission could theoretically race the\n // storage delete on slow devices. Clearing the cache here guarantees late\n // subscribers cannot replay an URI that originated from any pairing attempt\n // prior to this construction.\n latestDisplayUri = undefined;\n\n const onDisplayUri = (listener: DisplayUriListener): (() => void) => {\n listeners.add(listener);\n if (latestDisplayUri !== undefined) {\n listener(latestDisplayUri);\n }\n return () => {\n listeners.delete(listener);\n };\n };\n\n // Tracks an in-flight `connect` call so that overlapping invocations (most\n // commonly React's StrictMode double-invocation of effects, or a hook that\n // re-runs while the user is still scanning) await the same underlying\n // pairing instead of racing two connect calls against each other.\n let inFlightConnect: Promise<void> | null = null;\n\n const connect = (): Promise<void> => {\n if (inFlightConnect) {\n return inFlightConnect;\n }\n\n inFlightConnect = (async () => {\n try {\n // If a previous pairing was cancelled mid-flight the SDK can be left\n // in `connecting` state with a dead transport descriptor; tear it\n // down so the next connect issues a fresh URI synchronously instead\n // of waiting for the SDK's (non-configurable) 10-second resume\n // timeout.\n if (sdk.core.status === 'connecting') {\n try {\n await sdk.disconnect();\n } catch (error) {\n getCore(client).logger.debug(\n '[metamask] pre-connect disconnect rejected (expected when aborting a pairing the wallet never accepted)',\n error\n );\n }\n }\n\n const features = getFeaturesForSolanaStandardWallet(sdk.getWallet());\n\n await features['standard:connect'].connect();\n } finally {\n inFlightConnect = null;\n }\n })();\n\n return inFlightConnect;\n };\n\n return {\n clearCachedDisplayUri: () => {\n latestDisplayUri = undefined;\n },\n connect,\n getLatestDisplayUri: () => latestDisplayUri,\n onDisplayUri,\n sdk,\n };\n};\n","import { createRuntimeServiceAccessKey } from '@dynamic-labs-sdk/client/core';\n\nimport { createMetaMaskSolanaController } from '../createMetaMaskSolanaController';\n\nconst RUNTIME_SERVICE_KEY = 'metaMaskSolanaController';\n\n/**\n * Per-`DynamicClient` accessor for the lazily-constructed MetaMask Solana\n * controller. Wraps `createMetaMaskSolanaController` with the standard\n * `runtimeServices` cache so every caller — the Wallet Standard\n * wallet-provider builder, the `display_uri` subscription helper, and the\n * `connectWithMetaMaskUriSolana` URI-returning helper — shares the same\n * controller (and therefore the same SDK instance, display-URI cache, and\n * listener registry) per Dynamic client.\n *\n * The cache is **per-Dynamic-client, not per-SDK-instance**:\n * `@metamask/connect-solana`'s `createSolanaClient` builds on the shared\n * MultichainCore singleton, so when multiple Dynamic clients coexist they\n * end up sharing the same MetaMask session regardless of this cache. The\n * wrapper exists to own the controller's `display_uri` cache and listener\n * registry per Dynamic client, which the SDK itself does not expose.\n *\n * @notInstrumented\n */\nexport const getOrCreateMetaMaskSolanaController = createRuntimeServiceAccessKey(\n RUNTIME_SERVICE_KEY,\n (client) => createMetaMaskSolanaController(client)\n);\n","import type { DynamicClient } from '@dynamic-labs-sdk/client';\nimport { MetaMaskWalletNotConnectedError } from '@dynamic-labs-sdk/metamask';\nimport { WalletProviderEnum } from '@dynamic-labs/sdk-api-core';\n\nimport type { SolanaWalletProvider } from '../../SolanaWalletProvider.types';\nimport { createWalletProviderFromSolanaStandardWallet } from '../../walletStandard/utils/createWalletProviderFromSolanaStandardWallet';\nimport { getOrCreateMetaMaskSolanaController } from '../utils/getOrCreateMetaMaskSolanaController';\n\n/**\n * Builds the `SolanaWalletProvider` registered AFTER a successful MetaMask\n * SDK URI pairing. Wraps the paired Wallet Standard wallet exposed by\n * `@metamask/connect-solana` behind the Dynamic Solana provider facade and\n * classifies it as `QrCode` so its key does not collide with an announced\n * MetaMask browser-extension provider for the same wallet name. Drops\n * `connect` so the provider is filtered out of the wallet picker by\n * `getAvailableWalletProvidersData` — mirroring how WalletConnect URI\n * sessions register a signing-only provider.\n *\n * @notInstrumented\n */\nexport const createMetaMaskSolanaWalletProvider = async (\n client: DynamicClient\n): Promise<SolanaWalletProvider> => {\n const controller = await getOrCreateMetaMaskSolanaController(client);\n\n const walletStandardWallet = controller.sdk.getWallet();\n\n // The provider is only meaningful once the URI pairing has produced a\n // connected account; guard so a premature or out-of-order call raises a\n // readable error instead of building a provider around an empty wallet.\n if (walletStandardWallet.accounts.length === 0) {\n throw new MetaMaskWalletNotConnectedError();\n }\n\n const walletProvider = createWalletProviderFromSolanaStandardWallet({\n dynamicClient: client,\n walletProviderType: WalletProviderEnum.QrCode,\n walletStandardWallet,\n });\n\n return {\n ...walletProvider,\n connect: undefined,\n };\n};\n","import { getDefaultClient } from '@dynamic-labs-sdk/client';\nimport type { WalletProviderUriConnectionResult } from '@dynamic-labs-sdk/client';\nimport { connectWithMetaMaskUri } from '@dynamic-labs-sdk/metamask';\n\nimport { registerSolanaNetworkProviderBuilder } from '../../registerSolanaNetworkProviderBuilder';\nimport { createMetaMaskSolanaWalletProvider } from '../createMetaMaskSolanaWalletProvider';\nimport { getOrCreateMetaMaskSolanaController } from '../utils/getOrCreateMetaMaskSolanaController';\n\nexport type ConnectWithMetaMaskUriSolanaParams = {\n /** Whether to add the connected wallet account to the Dynamic client. Defaults to `true`. */\n addToDynamicWalletAccounts?: boolean;\n};\n\n/**\n * Drives a MetaMask SDK URI pairing for Solana and returns `{ approval, uri }`\n * so consumers can render the QR / hand the URI to a deeplink. The resulting\n * wallet provider registers for signing only and is never surfaced in the\n * wallet picker. When the MetaMask extension is announced via Wallet Standard,\n * prefer routing through `getMetaMaskSolanaExtensionWalletProviderKey` instead.\n *\n * @notInstrumented\n */\nexport const connectWithMetaMaskUriSolana = (\n { addToDynamicWalletAccounts = true }: ConnectWithMetaMaskUriSolanaParams = {},\n client = getDefaultClient()\n): Promise<WalletProviderUriConnectionResult> => {\n registerSolanaNetworkProviderBuilder(client);\n\n return connectWithMetaMaskUri(\n {\n addToDynamicWalletAccounts,\n chain: 'SOL',\n getController: getOrCreateMetaMaskSolanaController,\n walletProviderBuilder: createMetaMaskSolanaWalletProvider,\n },\n client\n );\n};\n","import {\n type WalletAccount,\n type WalletProviderUriConnectionResult,\n getDefaultClient,\n verifyWalletAccount,\n} from '@dynamic-labs-sdk/client';\n\nimport { connectWithMetaMaskUriSolana } from '../connectWithMetaMaskUriSolana';\n\n/**\n * Drives a MetaMask SDK URI pairing for Solana and verifies ownership of the\n * paired wallet account through message signing, returning `{ approval, uri }`\n * so consumers can render the QR / hand the URI to a deeplink.\n *\n * Builds on `connectWithMetaMaskUriSolana` (rather than the chain-agnostic\n * connector directly) so the Solana-specific wiring stays defined in one\n * place, then wraps its `approval` to add the verification round-trip. The\n * pairing is driven with `addToDynamicWalletAccounts: false` so the account\n * lands as a verified credential instead of an unverified entry.\n *\n * The MetaMask SDK does not expose a single-round-trip authenticate\n * primitive, so this drives two sequential interactions on the wallet side:\n * the user first approves the pairing, then approves a sign-in message.\n *\n * @notInstrumented\n */\nexport const connectAndVerifyWithMetaMaskUriSolana = async (\n client = getDefaultClient()\n): Promise<WalletProviderUriConnectionResult> => {\n const { approval, uri } = await connectWithMetaMaskUriSolana(\n { addToDynamicWalletAccounts: false },\n client\n );\n\n const verifiedApproval = async (): Promise<{\n walletAccounts: WalletAccount[];\n }> => {\n const { walletAccounts } = await approval();\n\n // MetaMask SDK exposes a single active address per pairing, mirroring how\n // the underlying connect helper materializes a single account from\n // `addresses[0]`. Verify it directly.\n const [walletAccount] = walletAccounts;\n\n if (walletAccount) {\n await verifyWalletAccount({ walletAccount }, client);\n }\n\n return { walletAccounts };\n };\n\n return { approval: verifiedApproval, uri };\n};\n","import { getDefaultClient } from '@dynamic-labs-sdk/client';\nimport { getMetaMaskExtensionWalletProviderKey } from '@dynamic-labs-sdk/metamask';\n\n/**\n * Returns the wallet provider key of the MetaMask browser extension announced\n * for Solana via Wallet Standard, or `undefined` when none is announced. Pass\n * the returned key to `connectWithWalletProvider` to route through the\n * announced provider; fall back to `connectWithMetaMaskUriSolana` when\n * `undefined`.\n *\n * @notInstrumented\n */\nexport const getMetaMaskSolanaExtensionWalletProviderKey = (\n client = getDefaultClient()\n): string | undefined =>\n getMetaMaskExtensionWalletProviderKey({ chain: 'SOL' }, client);\n","import { assertPackageVersion } from '@dynamic-labs-sdk/assert-package-version';\n\nimport {\n name as packageName,\n version as packageVersion,\n} from '../../package.json';\nassertPackageVersion(packageName, packageVersion);\n\nexport { connectAndVerifyWithMetaMaskUriSolana } from '../metamask/connectAndVerifyWithMetaMaskUriSolana';\nexport { connectWithMetaMaskUriSolana } from '../metamask/connectWithMetaMaskUriSolana';\nexport type { ConnectWithMetaMaskUriSolanaParams } from '../metamask/connectWithMetaMaskUriSolana/connectWithMetaMaskUriSolana';\nexport { getMetaMaskSolanaExtensionWalletProviderKey } from '../metamask/getMetaMaskSolanaExtensionWalletProviderKey';\nexport { MetaMaskDisplayUriMissingError } from '@dynamic-labs-sdk/metamask';\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { d as registerSolanaNetworkProviderBuilder, f as name, p as version } from "./solanaTransferAmount-BCiUGR02.esm.js";
2
- import { n as getFeaturesForSolanaStandardWallet, t as createWalletProviderFromSolanaStandardWallet } from "./createWalletProviderFromSolanaStandardWallet-Dxqecq1I.esm.js";
1
+ import { d as registerSolanaNetworkProviderBuilder, f as name, p as version } from "./solanaTransferAmount-BqgJ6ZGp.esm.js";
2
+ import { n as getFeaturesForSolanaStandardWallet, t as createWalletProviderFromSolanaStandardWallet } from "./createWalletProviderFromSolanaStandardWallet-BzisQSvU.esm.js";
3
3
  import { assertPackageVersion } from "@dynamic-labs-sdk/assert-package-version";
4
4
  import { assertNonEmptyArray, createRuntimeServiceAccessKey, getAppMetadata, getCore, getNativeLinkScheme } from "@dynamic-labs-sdk/client/core";
5
5
  import { getDefaultClient as getDefaultClient$1, getNetworksData, verifyWalletAccount } from "@dynamic-labs-sdk/client";
@@ -60,13 +60,17 @@ const getSupportedNetworks = (client) => {
60
60
  * register itself into the global Wallet Standard registry — an announced
61
61
  * MetaMask extension is discovered independently. Dapp metadata is sourced
62
62
  * from the client's `getAppMetadata`. Browser-only.
63
+ * The MetaMask SDK's own verbose logging is tied to the Dynamic client's log
64
+ * level, so turning on `debug` logging for the Dynamic SDK also surfaces
65
+ * MetaMask's internal SDK trace output.
63
66
  *
64
67
  * @notInstrumented
65
68
  */
66
69
  const createMetaMaskSolanaController = async (client) => {
67
70
  const supportedNetworks = getSupportedNetworks(client);
68
71
  const { appName, appLogoUrl, appUniversalLink, appNativeLink } = getAppMetadata(client);
69
- await clearMetaMaskSessionStorage();
72
+ const { logger } = getCore(client);
73
+ await clearMetaMaskSessionStorage(client);
70
74
  const listeners = /* @__PURE__ */ new Set();
71
75
  let latestDisplayUri;
72
76
  const sdk = await createSolanaClient({
@@ -77,7 +81,7 @@ const createMetaMaskSolanaController = async (client) => {
77
81
  nativeScheme: getNativeLinkScheme({ nativeLink: appNativeLink }),
78
82
  url: appUniversalLink ?? ""
79
83
  },
80
- debug: false,
84
+ debug: logger.isEnabled("debug"),
81
85
  skipAutoRegister: true
82
86
  });
83
87
  sdk.core.on("display_uri", (uri) => {
@@ -1 +1 @@
1
- {"version":3,"file":"metamask.esm.js","names":["supportedNetworks: MetaMaskSupportedNetworks","latestDisplayUri: string | undefined","inFlightConnect: Promise<void> | null","getDefaultClient","getDefaultClient","getDefaultClient","packageName","packageVersion"],"sources":["../src/metamask/utils/getSolanaNetworkFromCluster/getSolanaNetworkFromCluster.ts","../src/metamask/utils/getSupportedNetworks/getSupportedNetworks.ts","../src/metamask/utils/createMetaMaskSolanaController/createMetaMaskSolanaController.ts","../src/metamask/utils/getOrCreateMetaMaskSolanaController/getOrCreateMetaMaskSolanaController.ts","../src/metamask/createMetaMaskSolanaWalletProvider/createMetaMaskSolanaWalletProvider.ts","../src/metamask/connectWithMetaMaskUriSolana/connectWithMetaMaskUriSolana.ts","../src/metamask/connectAndVerifyWithMetaMaskUriSolana/connectAndVerifyWithMetaMaskUriSolana.ts","../src/metamask/getMetaMaskSolanaExtensionWalletProviderKey/getMetaMaskSolanaExtensionWalletProviderKey.ts","../src/exports/metamask.ts"],"sourcesContent":["import type { SolanaNetwork } from '@metamask/connect-solana';\n\n/** Parameters for {@link getSolanaNetworkFromCluster}. */\nexport type GetSolanaNetworkFromClusterParams = {\n /** The Dynamic network `cluster` (e.g. `mainnet-beta`, `devnet`, `testnet`). */\n cluster: string | undefined;\n};\n\n/**\n * Maps a Dynamic network `cluster` (e.g. `mainnet-beta`, `devnet`,\n * `testnet`) to the `mainnet | devnet | testnet` key shape expected by\n * `@metamask/connect-solana`'s `createSolanaClient`. Returns `undefined` for\n * clusters that do not correspond to one of MetaMask's supported Solana\n * networks so callers can skip them. Used by `getSupportedNetworks` to build\n * the SDK's `supportedNetworks` map.\n *\n * @notInstrumented\n */\nexport const getSolanaNetworkFromCluster = ({\n cluster,\n}: GetSolanaNetworkFromClusterParams): SolanaNetwork | undefined => {\n if (cluster === undefined) {\n return undefined;\n }\n\n if (cluster.includes('mainnet')) {\n return 'mainnet';\n }\n\n if (cluster.includes('devnet')) {\n return 'devnet';\n }\n\n if (cluster.includes('testnet')) {\n return 'testnet';\n }\n\n return undefined;\n};\n","import type { DynamicClient } from '@dynamic-labs-sdk/client';\nimport { getNetworksData } from '@dynamic-labs-sdk/client';\nimport { assertNonEmptyArray } from '@dynamic-labs-sdk/client/core';\nimport type { SolanaNetwork } from '@metamask/connect-solana';\n\nimport { getSolanaNetworkFromCluster } from '../getSolanaNetworkFromCluster';\n\ntype MetaMaskSupportedNetworks = Partial<Record<SolanaNetwork, string>>;\n\n/**\n * Builds the `supportedNetworks` map required by\n * `@metamask/connect-solana`'s `createSolanaClient`, keyed by the SDK's\n * `mainnet | devnet | testnet` network names and valued with the first\n * configured RPC URL for each. Sources the configured SOL networks from the\n * Dynamic client's project settings. Throws when no SOL network is\n * configured, mirroring the EVM `getSupportedNetworks` contract.\n *\n * @notInstrumented\n */\nexport const getSupportedNetworks = (\n client: DynamicClient\n): MetaMaskSupportedNetworks => {\n const solanaNetworks = getNetworksData(client).filter(\n (network) => network.chain === 'SOL'\n );\n\n assertNonEmptyArray(\n solanaNetworks,\n 'No SOL networks have been configured. Make sure to add at least one Solana network to your project settings in the Dynamic Dashboard.'\n );\n\n const supportedNetworks: MetaMaskSupportedNetworks = {};\n\n for (const network of solanaNetworks) {\n const solanaNetwork = getSolanaNetworkFromCluster({\n cluster: network.cluster,\n });\n\n // Skip clusters MetaMask does not recognise, and keep the first RPC URL\n // seen for a given network so earlier-configured networks take priority.\n if (\n solanaNetwork !== undefined &&\n supportedNetworks[solanaNetwork] === undefined\n ) {\n supportedNetworks[solanaNetwork] = network.rpcUrls.http[0];\n }\n }\n\n return supportedNetworks;\n};\n","import type { DynamicClient } from '@dynamic-labs-sdk/client';\nimport {\n getAppMetadata,\n getCore,\n getNativeLinkScheme,\n} from '@dynamic-labs-sdk/client/core';\nimport { clearMetaMaskSessionStorage } from '@dynamic-labs-sdk/metamask';\nimport type { DisplayUriListener } from '@dynamic-labs-sdk/metamask';\nimport { createSolanaClient } from '@metamask/connect-solana';\n\nimport { getFeaturesForSolanaStandardWallet } from '../../../walletStandard/utils/getFeaturesForSolanaStandardWallet';\nimport type { MetaMaskSolanaController } from '../../metamask.types';\nimport { getSupportedNetworks } from '../getSupportedNetworks';\n\n/**\n * Builds a fully-initialised `MetaMaskSolanaController` for the given Dynamic\n * client. Drives the `@metamask/connect-solana` SDK through its Wallet\n * Standard surface so consumers render their own QR / deep-link UI, and\n * subscribes to the SDK core's `display_uri` event at construction time so\n * the first URI emission cannot be lost to a subscription race. The wallet\n * is created with `skipAutoRegister` so this URI-pairing client does not\n * register itself into the global Wallet Standard registry — an announced\n * MetaMask extension is discovered independently. Dapp metadata is sourced\n * from the client's `getAppMetadata`. Browser-only.\n *\n * @notInstrumented\n */\nexport const createMetaMaskSolanaController = async (\n client: DynamicClient\n): Promise<MetaMaskSolanaController> => {\n const supportedNetworks = getSupportedNetworks(client);\n const { appName, appLogoUrl, appUniversalLink, appNativeLink } =\n getAppMetadata(client);\n\n // Drop any IndexedDB session state left behind by a previous tab, page\n // reload, or abandoned pairing before the SDK initialises. The SDK's\n // auto-recovery path otherwise picks up a stale transport descriptor and\n // spends its (non-configurable) 10-second resume timeout on every\n // controller construction trying to revive a relay session that no longer\n // exists, surfacing as a long QR skeleton delay on every page reload that\n // follows an abandoned pairing.\n await clearMetaMaskSessionStorage();\n\n const listeners = new Set<DisplayUriListener>();\n let latestDisplayUri: string | undefined;\n\n const sdk = await createSolanaClient({\n api: { supportedNetworks },\n dapp: {\n iconUrl: appLogoUrl,\n name: appName,\n nativeScheme: getNativeLinkScheme({ nativeLink: appNativeLink }),\n url: appUniversalLink ?? '',\n },\n debug: false,\n skipAutoRegister: true,\n });\n\n sdk.core.on('display_uri', (uri) => {\n latestDisplayUri = uri;\n for (const listener of listeners) {\n listener(uri);\n }\n });\n\n // A terminal connection state means any cached URI is for a pairing that is\n // either complete or torn down, so it must not be replayed to late\n // subscribers.\n sdk.core.on('stateChanged', (status) => {\n if (status === 'connected' || status === 'disconnected') {\n latestDisplayUri = undefined;\n }\n });\n\n // Defensive cleanup: even though we cleared IndexedDB before constructing\n // the SDK, an in-flight `display_uri` emission could theoretically race the\n // storage delete on slow devices. Clearing the cache here guarantees late\n // subscribers cannot replay an URI that originated from any pairing attempt\n // prior to this construction.\n latestDisplayUri = undefined;\n\n const onDisplayUri = (listener: DisplayUriListener): (() => void) => {\n listeners.add(listener);\n if (latestDisplayUri !== undefined) {\n listener(latestDisplayUri);\n }\n return () => {\n listeners.delete(listener);\n };\n };\n\n // Tracks an in-flight `connect` call so that overlapping invocations (most\n // commonly React's StrictMode double-invocation of effects, or a hook that\n // re-runs while the user is still scanning) await the same underlying\n // pairing instead of racing two connect calls against each other.\n let inFlightConnect: Promise<void> | null = null;\n\n const connect = (): Promise<void> => {\n if (inFlightConnect) {\n return inFlightConnect;\n }\n\n inFlightConnect = (async () => {\n try {\n // If a previous pairing was cancelled mid-flight the SDK can be left\n // in `connecting` state with a dead transport descriptor; tear it\n // down so the next connect issues a fresh URI synchronously instead\n // of waiting for the SDK's (non-configurable) 10-second resume\n // timeout.\n if (sdk.core.status === 'connecting') {\n try {\n await sdk.disconnect();\n } catch (error) {\n getCore(client).logger.debug(\n '[metamask] pre-connect disconnect rejected (expected when aborting a pairing the wallet never accepted)',\n error\n );\n }\n }\n\n const features = getFeaturesForSolanaStandardWallet(sdk.getWallet());\n\n await features['standard:connect'].connect();\n } finally {\n inFlightConnect = null;\n }\n })();\n\n return inFlightConnect;\n };\n\n return {\n clearCachedDisplayUri: () => {\n latestDisplayUri = undefined;\n },\n connect,\n getLatestDisplayUri: () => latestDisplayUri,\n onDisplayUri,\n sdk,\n };\n};\n","import { createRuntimeServiceAccessKey } from '@dynamic-labs-sdk/client/core';\n\nimport { createMetaMaskSolanaController } from '../createMetaMaskSolanaController';\n\nconst RUNTIME_SERVICE_KEY = 'metaMaskSolanaController';\n\n/**\n * Per-`DynamicClient` accessor for the lazily-constructed MetaMask Solana\n * controller. Wraps `createMetaMaskSolanaController` with the standard\n * `runtimeServices` cache so every caller — the Wallet Standard\n * wallet-provider builder, the `display_uri` subscription helper, and the\n * `connectWithMetaMaskUriSolana` URI-returning helper — shares the same\n * controller (and therefore the same SDK instance, display-URI cache, and\n * listener registry) per Dynamic client.\n *\n * The cache is **per-Dynamic-client, not per-SDK-instance**:\n * `@metamask/connect-solana`'s `createSolanaClient` builds on the shared\n * MultichainCore singleton, so when multiple Dynamic clients coexist they\n * end up sharing the same MetaMask session regardless of this cache. The\n * wrapper exists to own the controller's `display_uri` cache and listener\n * registry per Dynamic client, which the SDK itself does not expose.\n *\n * @notInstrumented\n */\nexport const getOrCreateMetaMaskSolanaController = createRuntimeServiceAccessKey(\n RUNTIME_SERVICE_KEY,\n (client) => createMetaMaskSolanaController(client)\n);\n","import type { DynamicClient } from '@dynamic-labs-sdk/client';\nimport { MetaMaskWalletNotConnectedError } from '@dynamic-labs-sdk/metamask';\nimport { WalletProviderEnum } from '@dynamic-labs/sdk-api-core';\n\nimport type { SolanaWalletProvider } from '../../SolanaWalletProvider.types';\nimport { createWalletProviderFromSolanaStandardWallet } from '../../walletStandard/utils/createWalletProviderFromSolanaStandardWallet';\nimport { getOrCreateMetaMaskSolanaController } from '../utils/getOrCreateMetaMaskSolanaController';\n\n/**\n * Builds the `SolanaWalletProvider` registered AFTER a successful MetaMask\n * SDK URI pairing. Wraps the paired Wallet Standard wallet exposed by\n * `@metamask/connect-solana` behind the Dynamic Solana provider facade and\n * classifies it as `QrCode` so its key does not collide with an announced\n * MetaMask browser-extension provider for the same wallet name. Drops\n * `connect` so the provider is filtered out of the wallet picker by\n * `getAvailableWalletProvidersData` — mirroring how WalletConnect URI\n * sessions register a signing-only provider.\n *\n * @notInstrumented\n */\nexport const createMetaMaskSolanaWalletProvider = async (\n client: DynamicClient\n): Promise<SolanaWalletProvider> => {\n const controller = await getOrCreateMetaMaskSolanaController(client);\n\n const walletStandardWallet = controller.sdk.getWallet();\n\n // The provider is only meaningful once the URI pairing has produced a\n // connected account; guard so a premature or out-of-order call raises a\n // readable error instead of building a provider around an empty wallet.\n if (walletStandardWallet.accounts.length === 0) {\n throw new MetaMaskWalletNotConnectedError();\n }\n\n const walletProvider = createWalletProviderFromSolanaStandardWallet({\n dynamicClient: client,\n walletProviderType: WalletProviderEnum.QrCode,\n walletStandardWallet,\n });\n\n return {\n ...walletProvider,\n connect: undefined,\n };\n};\n","import { getDefaultClient } from '@dynamic-labs-sdk/client';\nimport type { WalletProviderUriConnectionResult } from '@dynamic-labs-sdk/client';\nimport { connectWithMetaMaskUri } from '@dynamic-labs-sdk/metamask';\n\nimport { registerSolanaNetworkProviderBuilder } from '../../registerSolanaNetworkProviderBuilder';\nimport { createMetaMaskSolanaWalletProvider } from '../createMetaMaskSolanaWalletProvider';\nimport { getOrCreateMetaMaskSolanaController } from '../utils/getOrCreateMetaMaskSolanaController';\n\nexport type ConnectWithMetaMaskUriSolanaParams = {\n /** Whether to add the connected wallet account to the Dynamic client. Defaults to `true`. */\n addToDynamicWalletAccounts?: boolean;\n};\n\n/**\n * Drives a MetaMask SDK URI pairing for Solana and returns `{ approval, uri }`\n * so consumers can render the QR / hand the URI to a deeplink. The resulting\n * wallet provider registers for signing only and is never surfaced in the\n * wallet picker. When the MetaMask extension is announced via Wallet Standard,\n * prefer routing through `getMetaMaskSolanaExtensionWalletProviderKey` instead.\n *\n * @notInstrumented\n */\nexport const connectWithMetaMaskUriSolana = (\n { addToDynamicWalletAccounts = true }: ConnectWithMetaMaskUriSolanaParams = {},\n client = getDefaultClient()\n): Promise<WalletProviderUriConnectionResult> => {\n registerSolanaNetworkProviderBuilder(client);\n\n return connectWithMetaMaskUri(\n {\n addToDynamicWalletAccounts,\n chain: 'SOL',\n getController: getOrCreateMetaMaskSolanaController,\n walletProviderBuilder: createMetaMaskSolanaWalletProvider,\n },\n client\n );\n};\n","import {\n type WalletAccount,\n type WalletProviderUriConnectionResult,\n getDefaultClient,\n verifyWalletAccount,\n} from '@dynamic-labs-sdk/client';\n\nimport { connectWithMetaMaskUriSolana } from '../connectWithMetaMaskUriSolana';\n\n/**\n * Drives a MetaMask SDK URI pairing for Solana and verifies ownership of the\n * paired wallet account through message signing, returning `{ approval, uri }`\n * so consumers can render the QR / hand the URI to a deeplink.\n *\n * Builds on `connectWithMetaMaskUriSolana` (rather than the chain-agnostic\n * connector directly) so the Solana-specific wiring stays defined in one\n * place, then wraps its `approval` to add the verification round-trip. The\n * pairing is driven with `addToDynamicWalletAccounts: false` so the account\n * lands as a verified credential instead of an unverified entry.\n *\n * The MetaMask SDK does not expose a single-round-trip authenticate\n * primitive, so this drives two sequential interactions on the wallet side:\n * the user first approves the pairing, then approves a sign-in message.\n *\n * @notInstrumented\n */\nexport const connectAndVerifyWithMetaMaskUriSolana = async (\n client = getDefaultClient()\n): Promise<WalletProviderUriConnectionResult> => {\n const { approval, uri } = await connectWithMetaMaskUriSolana(\n { addToDynamicWalletAccounts: false },\n client\n );\n\n const verifiedApproval = async (): Promise<{\n walletAccounts: WalletAccount[];\n }> => {\n const { walletAccounts } = await approval();\n\n // MetaMask SDK exposes a single active address per pairing, mirroring how\n // the underlying connect helper materializes a single account from\n // `addresses[0]`. Verify it directly.\n const [walletAccount] = walletAccounts;\n\n if (walletAccount) {\n await verifyWalletAccount({ walletAccount }, client);\n }\n\n return { walletAccounts };\n };\n\n return { approval: verifiedApproval, uri };\n};\n","import { getDefaultClient } from '@dynamic-labs-sdk/client';\nimport { getMetaMaskExtensionWalletProviderKey } from '@dynamic-labs-sdk/metamask';\n\n/**\n * Returns the wallet provider key of the MetaMask browser extension announced\n * for Solana via Wallet Standard, or `undefined` when none is announced. Pass\n * the returned key to `connectWithWalletProvider` to route through the\n * announced provider; fall back to `connectWithMetaMaskUriSolana` when\n * `undefined`.\n *\n * @notInstrumented\n */\nexport const getMetaMaskSolanaExtensionWalletProviderKey = (\n client = getDefaultClient()\n): string | undefined =>\n getMetaMaskExtensionWalletProviderKey({ chain: 'SOL' }, client);\n","import { assertPackageVersion } from '@dynamic-labs-sdk/assert-package-version';\n\nimport {\n name as packageName,\n version as packageVersion,\n} from '../../package.json';\nassertPackageVersion(packageName, packageVersion);\n\nexport { connectAndVerifyWithMetaMaskUriSolana } from '../metamask/connectAndVerifyWithMetaMaskUriSolana';\nexport { connectWithMetaMaskUriSolana } from '../metamask/connectWithMetaMaskUriSolana';\nexport type { ConnectWithMetaMaskUriSolanaParams } from '../metamask/connectWithMetaMaskUriSolana/connectWithMetaMaskUriSolana';\nexport { getMetaMaskSolanaExtensionWalletProviderKey } from '../metamask/getMetaMaskSolanaExtensionWalletProviderKey';\nexport { MetaMaskDisplayUriMissingError } from '@dynamic-labs-sdk/metamask';\n"],"mappings":"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"}
1
+ {"version":3,"file":"metamask.esm.js","names":["supportedNetworks: MetaMaskSupportedNetworks","latestDisplayUri: string | undefined","inFlightConnect: Promise<void> | null","getDefaultClient","getDefaultClient","getDefaultClient","packageName","packageVersion"],"sources":["../src/metamask/utils/getSolanaNetworkFromCluster/getSolanaNetworkFromCluster.ts","../src/metamask/utils/getSupportedNetworks/getSupportedNetworks.ts","../src/metamask/utils/createMetaMaskSolanaController/createMetaMaskSolanaController.ts","../src/metamask/utils/getOrCreateMetaMaskSolanaController/getOrCreateMetaMaskSolanaController.ts","../src/metamask/createMetaMaskSolanaWalletProvider/createMetaMaskSolanaWalletProvider.ts","../src/metamask/connectWithMetaMaskUriSolana/connectWithMetaMaskUriSolana.ts","../src/metamask/connectAndVerifyWithMetaMaskUriSolana/connectAndVerifyWithMetaMaskUriSolana.ts","../src/metamask/getMetaMaskSolanaExtensionWalletProviderKey/getMetaMaskSolanaExtensionWalletProviderKey.ts","../src/exports/metamask.ts"],"sourcesContent":["import type { SolanaNetwork } from '@metamask/connect-solana';\n\n/** Parameters for {@link getSolanaNetworkFromCluster}. */\nexport type GetSolanaNetworkFromClusterParams = {\n /** The Dynamic network `cluster` (e.g. `mainnet-beta`, `devnet`, `testnet`). */\n cluster: string | undefined;\n};\n\n/**\n * Maps a Dynamic network `cluster` (e.g. `mainnet-beta`, `devnet`,\n * `testnet`) to the `mainnet | devnet | testnet` key shape expected by\n * `@metamask/connect-solana`'s `createSolanaClient`. Returns `undefined` for\n * clusters that do not correspond to one of MetaMask's supported Solana\n * networks so callers can skip them. Used by `getSupportedNetworks` to build\n * the SDK's `supportedNetworks` map.\n *\n * @notInstrumented\n */\nexport const getSolanaNetworkFromCluster = ({\n cluster,\n}: GetSolanaNetworkFromClusterParams): SolanaNetwork | undefined => {\n if (cluster === undefined) {\n return undefined;\n }\n\n if (cluster.includes('mainnet')) {\n return 'mainnet';\n }\n\n if (cluster.includes('devnet')) {\n return 'devnet';\n }\n\n if (cluster.includes('testnet')) {\n return 'testnet';\n }\n\n return undefined;\n};\n","import type { DynamicClient } from '@dynamic-labs-sdk/client';\nimport { getNetworksData } from '@dynamic-labs-sdk/client';\nimport { assertNonEmptyArray } from '@dynamic-labs-sdk/client/core';\nimport type { SolanaNetwork } from '@metamask/connect-solana';\n\nimport { getSolanaNetworkFromCluster } from '../getSolanaNetworkFromCluster';\n\ntype MetaMaskSupportedNetworks = Partial<Record<SolanaNetwork, string>>;\n\n/**\n * Builds the `supportedNetworks` map required by\n * `@metamask/connect-solana`'s `createSolanaClient`, keyed by the SDK's\n * `mainnet | devnet | testnet` network names and valued with the first\n * configured RPC URL for each. Sources the configured SOL networks from the\n * Dynamic client's project settings. Throws when no SOL network is\n * configured, mirroring the EVM `getSupportedNetworks` contract.\n *\n * @notInstrumented\n */\nexport const getSupportedNetworks = (\n client: DynamicClient\n): MetaMaskSupportedNetworks => {\n const solanaNetworks = getNetworksData(client).filter(\n (network) => network.chain === 'SOL'\n );\n\n assertNonEmptyArray(\n solanaNetworks,\n 'No SOL networks have been configured. Make sure to add at least one Solana network to your project settings in the Dynamic Dashboard.'\n );\n\n const supportedNetworks: MetaMaskSupportedNetworks = {};\n\n for (const network of solanaNetworks) {\n const solanaNetwork = getSolanaNetworkFromCluster({\n cluster: network.cluster,\n });\n\n // Skip clusters MetaMask does not recognise, and keep the first RPC URL\n // seen for a given network so earlier-configured networks take priority.\n if (\n solanaNetwork !== undefined &&\n supportedNetworks[solanaNetwork] === undefined\n ) {\n supportedNetworks[solanaNetwork] = network.rpcUrls.http[0];\n }\n }\n\n return supportedNetworks;\n};\n","import type { DynamicClient } from '@dynamic-labs-sdk/client';\nimport {\n getAppMetadata,\n getCore,\n getNativeLinkScheme,\n} from '@dynamic-labs-sdk/client/core';\nimport { clearMetaMaskSessionStorage } from '@dynamic-labs-sdk/metamask';\nimport type { DisplayUriListener } from '@dynamic-labs-sdk/metamask';\nimport { createSolanaClient } from '@metamask/connect-solana';\n\nimport { getFeaturesForSolanaStandardWallet } from '../../../walletStandard/utils/getFeaturesForSolanaStandardWallet';\nimport type { MetaMaskSolanaController } from '../../metamask.types';\nimport { getSupportedNetworks } from '../getSupportedNetworks';\n\n/**\n * Builds a fully-initialised `MetaMaskSolanaController` for the given Dynamic\n * client. Drives the `@metamask/connect-solana` SDK through its Wallet\n * Standard surface so consumers render their own QR / deep-link UI, and\n * subscribes to the SDK core's `display_uri` event at construction time so\n * the first URI emission cannot be lost to a subscription race. The wallet\n * is created with `skipAutoRegister` so this URI-pairing client does not\n * register itself into the global Wallet Standard registry — an announced\n * MetaMask extension is discovered independently. Dapp metadata is sourced\n * from the client's `getAppMetadata`. Browser-only.\n * The MetaMask SDK's own verbose logging is tied to the Dynamic client's log\n * level, so turning on `debug` logging for the Dynamic SDK also surfaces\n * MetaMask's internal SDK trace output.\n *\n * @notInstrumented\n */\nexport const createMetaMaskSolanaController = async (\n client: DynamicClient\n): Promise<MetaMaskSolanaController> => {\n const supportedNetworks = getSupportedNetworks(client);\n const { appName, appLogoUrl, appUniversalLink, appNativeLink } =\n getAppMetadata(client);\n const { logger } = getCore(client);\n\n // Drop any IndexedDB session state left behind by a previous tab, page\n // reload, or abandoned pairing before the SDK initialises. The SDK's\n // auto-recovery path otherwise picks up a stale transport descriptor and\n // spends its (non-configurable) 10-second resume timeout on every\n // controller construction trying to revive a relay session that no longer\n // exists, surfacing as a long QR skeleton delay on every page reload that\n // follows an abandoned pairing.\n await clearMetaMaskSessionStorage(client);\n\n const listeners = new Set<DisplayUriListener>();\n let latestDisplayUri: string | undefined;\n\n const sdk = await createSolanaClient({\n api: { supportedNetworks },\n dapp: {\n iconUrl: appLogoUrl,\n name: appName,\n nativeScheme: getNativeLinkScheme({ nativeLink: appNativeLink }),\n url: appUniversalLink ?? '',\n },\n // Mirror the Dynamic client's own debug level, so a consumer who turns on\n // Dynamic SDK debug logging also gets MetaMask's internal SDK trace\n // output without a second, MetaMask-specific toggle to remember.\n debug: logger.isEnabled('debug'),\n skipAutoRegister: true,\n });\n\n sdk.core.on('display_uri', (uri) => {\n latestDisplayUri = uri;\n for (const listener of listeners) {\n listener(uri);\n }\n });\n\n // A terminal connection state means any cached URI is for a pairing that is\n // either complete or torn down, so it must not be replayed to late\n // subscribers.\n sdk.core.on('stateChanged', (status) => {\n if (status === 'connected' || status === 'disconnected') {\n latestDisplayUri = undefined;\n }\n });\n\n // Defensive cleanup: even though we cleared IndexedDB before constructing\n // the SDK, an in-flight `display_uri` emission could theoretically race the\n // storage delete on slow devices. Clearing the cache here guarantees late\n // subscribers cannot replay an URI that originated from any pairing attempt\n // prior to this construction.\n latestDisplayUri = undefined;\n\n const onDisplayUri = (listener: DisplayUriListener): (() => void) => {\n listeners.add(listener);\n if (latestDisplayUri !== undefined) {\n listener(latestDisplayUri);\n }\n return () => {\n listeners.delete(listener);\n };\n };\n\n // Tracks an in-flight `connect` call so that overlapping invocations (most\n // commonly React's StrictMode double-invocation of effects, or a hook that\n // re-runs while the user is still scanning) await the same underlying\n // pairing instead of racing two connect calls against each other.\n let inFlightConnect: Promise<void> | null = null;\n\n const connect = (): Promise<void> => {\n if (inFlightConnect) {\n return inFlightConnect;\n }\n\n inFlightConnect = (async () => {\n try {\n // If a previous pairing was cancelled mid-flight the SDK can be left\n // in `connecting` state with a dead transport descriptor; tear it\n // down so the next connect issues a fresh URI synchronously instead\n // of waiting for the SDK's (non-configurable) 10-second resume\n // timeout.\n if (sdk.core.status === 'connecting') {\n try {\n await sdk.disconnect();\n } catch (error) {\n getCore(client).logger.debug(\n '[metamask] pre-connect disconnect rejected (expected when aborting a pairing the wallet never accepted)',\n error\n );\n }\n }\n\n const features = getFeaturesForSolanaStandardWallet(sdk.getWallet());\n\n await features['standard:connect'].connect();\n } finally {\n inFlightConnect = null;\n }\n })();\n\n return inFlightConnect;\n };\n\n return {\n clearCachedDisplayUri: () => {\n latestDisplayUri = undefined;\n },\n connect,\n getLatestDisplayUri: () => latestDisplayUri,\n onDisplayUri,\n sdk,\n };\n};\n","import { createRuntimeServiceAccessKey } from '@dynamic-labs-sdk/client/core';\n\nimport { createMetaMaskSolanaController } from '../createMetaMaskSolanaController';\n\nconst RUNTIME_SERVICE_KEY = 'metaMaskSolanaController';\n\n/**\n * Per-`DynamicClient` accessor for the lazily-constructed MetaMask Solana\n * controller. Wraps `createMetaMaskSolanaController` with the standard\n * `runtimeServices` cache so every caller — the Wallet Standard\n * wallet-provider builder, the `display_uri` subscription helper, and the\n * `connectWithMetaMaskUriSolana` URI-returning helper — shares the same\n * controller (and therefore the same SDK instance, display-URI cache, and\n * listener registry) per Dynamic client.\n *\n * The cache is **per-Dynamic-client, not per-SDK-instance**:\n * `@metamask/connect-solana`'s `createSolanaClient` builds on the shared\n * MultichainCore singleton, so when multiple Dynamic clients coexist they\n * end up sharing the same MetaMask session regardless of this cache. The\n * wrapper exists to own the controller's `display_uri` cache and listener\n * registry per Dynamic client, which the SDK itself does not expose.\n *\n * @notInstrumented\n */\nexport const getOrCreateMetaMaskSolanaController = createRuntimeServiceAccessKey(\n RUNTIME_SERVICE_KEY,\n (client) => createMetaMaskSolanaController(client)\n);\n","import type { DynamicClient } from '@dynamic-labs-sdk/client';\nimport { MetaMaskWalletNotConnectedError } from '@dynamic-labs-sdk/metamask';\nimport { WalletProviderEnum } from '@dynamic-labs/sdk-api-core';\n\nimport type { SolanaWalletProvider } from '../../SolanaWalletProvider.types';\nimport { createWalletProviderFromSolanaStandardWallet } from '../../walletStandard/utils/createWalletProviderFromSolanaStandardWallet';\nimport { getOrCreateMetaMaskSolanaController } from '../utils/getOrCreateMetaMaskSolanaController';\n\n/**\n * Builds the `SolanaWalletProvider` registered AFTER a successful MetaMask\n * SDK URI pairing. Wraps the paired Wallet Standard wallet exposed by\n * `@metamask/connect-solana` behind the Dynamic Solana provider facade and\n * classifies it as `QrCode` so its key does not collide with an announced\n * MetaMask browser-extension provider for the same wallet name. Drops\n * `connect` so the provider is filtered out of the wallet picker by\n * `getAvailableWalletProvidersData` — mirroring how WalletConnect URI\n * sessions register a signing-only provider.\n *\n * @notInstrumented\n */\nexport const createMetaMaskSolanaWalletProvider = async (\n client: DynamicClient\n): Promise<SolanaWalletProvider> => {\n const controller = await getOrCreateMetaMaskSolanaController(client);\n\n const walletStandardWallet = controller.sdk.getWallet();\n\n // The provider is only meaningful once the URI pairing has produced a\n // connected account; guard so a premature or out-of-order call raises a\n // readable error instead of building a provider around an empty wallet.\n if (walletStandardWallet.accounts.length === 0) {\n throw new MetaMaskWalletNotConnectedError();\n }\n\n const walletProvider = createWalletProviderFromSolanaStandardWallet({\n dynamicClient: client,\n walletProviderType: WalletProviderEnum.QrCode,\n walletStandardWallet,\n });\n\n return {\n ...walletProvider,\n connect: undefined,\n };\n};\n","import { getDefaultClient } from '@dynamic-labs-sdk/client';\nimport type { WalletProviderUriConnectionResult } from '@dynamic-labs-sdk/client';\nimport { connectWithMetaMaskUri } from '@dynamic-labs-sdk/metamask';\n\nimport { registerSolanaNetworkProviderBuilder } from '../../registerSolanaNetworkProviderBuilder';\nimport { createMetaMaskSolanaWalletProvider } from '../createMetaMaskSolanaWalletProvider';\nimport { getOrCreateMetaMaskSolanaController } from '../utils/getOrCreateMetaMaskSolanaController';\n\nexport type ConnectWithMetaMaskUriSolanaParams = {\n /** Whether to add the connected wallet account to the Dynamic client. Defaults to `true`. */\n addToDynamicWalletAccounts?: boolean;\n};\n\n/**\n * Drives a MetaMask SDK URI pairing for Solana and returns `{ approval, uri }`\n * so consumers can render the QR / hand the URI to a deeplink. The resulting\n * wallet provider registers for signing only and is never surfaced in the\n * wallet picker. When the MetaMask extension is announced via Wallet Standard,\n * prefer routing through `getMetaMaskSolanaExtensionWalletProviderKey` instead.\n *\n * @notInstrumented\n */\nexport const connectWithMetaMaskUriSolana = (\n { addToDynamicWalletAccounts = true }: ConnectWithMetaMaskUriSolanaParams = {},\n client = getDefaultClient()\n): Promise<WalletProviderUriConnectionResult> => {\n registerSolanaNetworkProviderBuilder(client);\n\n return connectWithMetaMaskUri(\n {\n addToDynamicWalletAccounts,\n chain: 'SOL',\n getController: getOrCreateMetaMaskSolanaController,\n walletProviderBuilder: createMetaMaskSolanaWalletProvider,\n },\n client\n );\n};\n","import {\n type WalletAccount,\n type WalletProviderUriConnectionResult,\n getDefaultClient,\n verifyWalletAccount,\n} from '@dynamic-labs-sdk/client';\n\nimport { connectWithMetaMaskUriSolana } from '../connectWithMetaMaskUriSolana';\n\n/**\n * Drives a MetaMask SDK URI pairing for Solana and verifies ownership of the\n * paired wallet account through message signing, returning `{ approval, uri }`\n * so consumers can render the QR / hand the URI to a deeplink.\n *\n * Builds on `connectWithMetaMaskUriSolana` (rather than the chain-agnostic\n * connector directly) so the Solana-specific wiring stays defined in one\n * place, then wraps its `approval` to add the verification round-trip. The\n * pairing is driven with `addToDynamicWalletAccounts: false` so the account\n * lands as a verified credential instead of an unverified entry.\n *\n * The MetaMask SDK does not expose a single-round-trip authenticate\n * primitive, so this drives two sequential interactions on the wallet side:\n * the user first approves the pairing, then approves a sign-in message.\n *\n * @notInstrumented\n */\nexport const connectAndVerifyWithMetaMaskUriSolana = async (\n client = getDefaultClient()\n): Promise<WalletProviderUriConnectionResult> => {\n const { approval, uri } = await connectWithMetaMaskUriSolana(\n { addToDynamicWalletAccounts: false },\n client\n );\n\n const verifiedApproval = async (): Promise<{\n walletAccounts: WalletAccount[];\n }> => {\n const { walletAccounts } = await approval();\n\n // MetaMask SDK exposes a single active address per pairing, mirroring how\n // the underlying connect helper materializes a single account from\n // `addresses[0]`. Verify it directly.\n const [walletAccount] = walletAccounts;\n\n if (walletAccount) {\n await verifyWalletAccount({ walletAccount }, client);\n }\n\n return { walletAccounts };\n };\n\n return { approval: verifiedApproval, uri };\n};\n","import { getDefaultClient } from '@dynamic-labs-sdk/client';\nimport { getMetaMaskExtensionWalletProviderKey } from '@dynamic-labs-sdk/metamask';\n\n/**\n * Returns the wallet provider key of the MetaMask browser extension announced\n * for Solana via Wallet Standard, or `undefined` when none is announced. Pass\n * the returned key to `connectWithWalletProvider` to route through the\n * announced provider; fall back to `connectWithMetaMaskUriSolana` when\n * `undefined`.\n *\n * @notInstrumented\n */\nexport const getMetaMaskSolanaExtensionWalletProviderKey = (\n client = getDefaultClient()\n): string | undefined =>\n getMetaMaskExtensionWalletProviderKey({ chain: 'SOL' }, client);\n","import { assertPackageVersion } from '@dynamic-labs-sdk/assert-package-version';\n\nimport {\n name as packageName,\n version as packageVersion,\n} from '../../package.json';\nassertPackageVersion(packageName, packageVersion);\n\nexport { connectAndVerifyWithMetaMaskUriSolana } from '../metamask/connectAndVerifyWithMetaMaskUriSolana';\nexport { connectWithMetaMaskUriSolana } from '../metamask/connectWithMetaMaskUriSolana';\nexport type { ConnectWithMetaMaskUriSolanaParams } from '../metamask/connectWithMetaMaskUriSolana/connectWithMetaMaskUriSolana';\nexport { getMetaMaskSolanaExtensionWalletProviderKey } from '../metamask/getMetaMaskSolanaExtensionWalletProviderKey';\nexport { MetaMaskDisplayUriMissingError } from '@dynamic-labs-sdk/metamask';\n"],"mappings":"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"}
@@ -5,7 +5,7 @@ import { TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID, createAssociatedTokenAccountIn
5
5
 
6
6
  //#region package.json
7
7
  var name = "@dynamic-labs-sdk/solana";
8
- var version = "1.26.0";
8
+ var version = "1.27.2";
9
9
 
10
10
  //#endregion
11
11
  //#region src/utils/fetchSolBalance/fetchSolBalance.ts
@@ -312,4 +312,4 @@ const solanaTransferAmount = async ({ amount, recipient, token, walletAccount },
312
312
 
313
313
  //#endregion
314
314
  export { NotSolanaProviderError as a, isSolanaWalletAccount as c, registerSolanaNetworkProviderBuilder as d, name as f, isSolanaGasSponsorshipEnabled as i, isVersionedTransaction as l, solanaExecuteSwapTransaction as n, isSolanaWalletProvider as o, version as p, signAndSendTransaction as r, solanaConfirmTransaction as s, solanaTransferAmount as t, getSolanaConnection as u };
315
- //# sourceMappingURL=solanaTransferAmount-BCiUGR02.esm.js.map
315
+ //# sourceMappingURL=solanaTransferAmount-BqgJ6ZGp.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"solanaTransferAmount-BCiUGR02.esm.js","names":["getDefaultClient","getDefaultClient","transaction: Transaction | VersionedTransaction","instructions: TransactionInstruction[]"],"sources":["../package.json","../src/utils/fetchSolBalance/fetchSolBalance.ts","../src/utils/createSolanaNetworkProvider/createSolanaNetworkProvider.ts","../src/registerSolanaNetworkProviderBuilder/registerSolanaNetworkProviderBuilder.ts","../src/getSolanaConnection/getSolanaConnection.ts","../src/utils/isVersionedTransaction/isVersionedTransaction.ts","../src/isSolanaWalletAccount/isSolanaWalletAccount.ts","../src/utils/solanaConfirmTransaction/solanaConfirmTransaction.ts","../src/isSolanaWalletProvider/isSolanaWalletProvider.ts","../src/errors/NotSolanaProviderError/NotSolanaProviderError.ts","../src/isSolanaGasSponsorshipEnabled/isSolanaGasSponsorshipEnabled.ts","../src/signAndSendTransaction/signAndSendTransaction.ts","../src/utils/solanaExecuteSwapTransaction/solanaExecuteSwapTransaction.ts","../src/utils/solanaTransferAmount/solanaTransferAmount.ts"],"sourcesContent":["","import type { NetworkData } from '@dynamic-labs-sdk/client';\nimport { Connection, PublicKey } from '@solana/web3.js';\n\n/** @notInstrumented */\nexport const fetchSolBalance = async ({\n address,\n networkData,\n}: {\n address: string;\n networkData: NetworkData;\n}): Promise<string | null> => {\n // Establish a connection to the Solana network using the provided RPC URL.\n const connection = new Connection(networkData.rpcUrls.http[0]);\n\n // Convert the string address into a PublicKey object.\n const publicKey = new PublicKey(address);\n\n // Fetch the balance of the public key. The balance is in lamports.\n const balanceInLamports = await connection.getBalance(publicKey);\n\n // The getBalance method returns the balance in lamports.\n // 1 SOL = 1,000,000,000 lamports.\n const balanceInSol = balanceInLamports / 1_000_000_000;\n\n // Return the balance in SOL as a string\n return balanceInSol.toString();\n};\n","import type { NetworkData } from '@dynamic-labs-sdk/client';\nimport { createBaseNetworkProvider } from '@dynamic-labs-sdk/client/core';\n\nimport type { SolanaNetworkProvider } from '../../SolanaNetworkProvider.types';\nimport { fetchSolBalance } from '../fetchSolBalance';\n\n/** @notInstrumented */\nexport const createSolanaNetworkProvider = (\n networkData: NetworkData\n): SolanaNetworkProvider => ({\n ...createBaseNetworkProvider('SOL', networkData),\n cluster: networkData.cluster,\n genesisHash: networkData.genesisHash,\n getBalance: async ({ address }) => ({\n balance: await fetchSolBalance({\n address,\n networkData,\n }),\n }),\n});\n","import type { DynamicClient } from '@dynamic-labs-sdk/client';\nimport { getNetworkProviderBuilderRegistry } from '@dynamic-labs-sdk/client/core';\n\nimport { createSolanaNetworkProvider } from '../utils/createSolanaNetworkProvider';\n\n/** @notInstrumented */\nexport const registerSolanaNetworkProviderBuilder = (\n client: DynamicClient\n): void => {\n const networkProviderBuilderRegistry =\n getNetworkProviderBuilderRegistry(client);\n\n /**\n * If the Solana network provider builder is already registered, return.\n */\n if (networkProviderBuilderRegistry.get().get('SOL')) {\n return;\n }\n\n networkProviderBuilderRegistry.register({\n builder: createSolanaNetworkProvider,\n chain: 'SOL',\n });\n};\n","import type { NetworkData } from '@dynamic-labs-sdk/client';\nimport type { Commitment, ConnectionConfig } from '@solana/web3.js';\nimport { Connection } from '@solana/web3.js';\n\ntype GetSolanaConnectionOptions = {\n commitmentOrConfig?: Commitment | ConnectionConfig;\n networkData: NetworkData;\n};\n\n/**\n * Returns a new Solana connection for the given network provider.\n *\n * @example\n * ```ts\n * import { getActiveNetworkData } from '@dynamic-labs-sdk/client';\n * import { isSolanaNetworkProvider, getSolanaConnection } from '@dynamic-labs-sdk/solana';\n *\n * const { networkData } = getActiveNetworkData({ walletAccount });\n *\n * if(!networkData) {\n * throw new Error('No network data found');\n * }\n *\n * const connection = getSolanaConnection({\n * networkData,\n * });\n * ```\n *\n * @param params.networkData - Network configuration containing the RPC URL.\n * @param [params.commitmentOrConfig] - Optional Solana commitment level or connection config.\n * @returns A Solana Connection instance.\n * @see isSolanaNetworkProvider\n * @see calculateSolanaTransactionFee\n * @notInstrumented\n */\nexport const getSolanaConnection = ({\n networkData,\n commitmentOrConfig,\n}: GetSolanaConnectionOptions) => {\n return new Connection(networkData.rpcUrls.http[0], commitmentOrConfig);\n};\n","import type { Transaction, VersionedTransaction } from '@solana/web3.js';\n\n/** @notInstrumented */\nexport const isVersionedTransaction = (\n transaction: VersionedTransaction | Transaction\n): transaction is VersionedTransaction => !('instructions' in transaction);\n","import type { WalletAccount } from '@dynamic-labs-sdk/client';\n\nimport type { SolanaWalletAccount } from '../SolanaWalletAccount.types';\n\n/**\n * Type guard function to check if a wallet account is a Solana wallet account.\n *\n * @example\n * ```ts\n * const accounts = getWalletAccounts();\n * const solAccounts = accounts.filter(isSolanaWalletAccount);\n * ```\n *\n * @param walletAccount - The wallet account to check.\n * @returns True if the wallet account is a Solana wallet account, false otherwise.\n * @see isSolanaNetworkProvider\n * @see addSolanaExtension\n * @notInstrumented\n */\nexport const isSolanaWalletAccount = (\n walletAccount: WalletAccount\n): walletAccount is SolanaWalletAccount => walletAccount.chain === 'SOL';\n","import {\n type DynamicClient,\n InvalidParamError,\n getActiveNetworkData,\n} from '@dynamic-labs-sdk/client';\nimport type { ConfirmTransactionParams } from '@dynamic-labs-sdk/client/core';\nimport { assertDefined } from '@dynamic-labs-sdk/client/core';\n\nimport { getSolanaConnection } from '../../getSolanaConnection';\nimport { isSolanaWalletAccount } from '../../isSolanaWalletAccount';\n\n/**\n * Waits for a Solana transaction to be confirmed on-chain.\n *\n * @param params.transactionHash - The transaction signature to wait for.\n * @param params.walletAccount - The Solana wallet account used to resolve the active network.\n * @param client - The Dynamic client instance.\n * @notInstrumented\n */\nexport const solanaConfirmTransaction = async (\n { transactionHash, walletAccount }: ConfirmTransactionParams,\n client: DynamicClient\n): Promise<void> => {\n if (!isSolanaWalletAccount(walletAccount)) {\n throw new InvalidParamError(\n 'Wallet account is not a Solana wallet account'\n );\n }\n\n const { networkData } = await getActiveNetworkData({ walletAccount }, client);\n\n assertDefined(\n networkData,\n `No network data found for wallet account ${walletAccount.address}`\n );\n\n const connection = getSolanaConnection({ networkData });\n\n const { blockhash, lastValidBlockHeight } =\n await connection.getLatestBlockhash();\n\n await connection.confirmTransaction({\n blockhash,\n lastValidBlockHeight,\n signature: transactionHash,\n });\n};\n","import type { WalletProvider } from '@dynamic-labs-sdk/client/core';\n\nimport type { SolanaWalletProvider } from '../SolanaWalletProvider.types';\n\n/** @notInstrumented */\nexport const isSolanaWalletProvider = (\n provider: WalletProvider\n): provider is SolanaWalletProvider => {\n return provider.chain === 'SOL';\n};\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\nexport class NotSolanaProviderError extends BaseError {\n public readonly providerKey: string;\n\n constructor(params: { providerKey: string }) {\n super({\n cause: null,\n code: 'not_solana_provider_error',\n docsUrl: null,\n name: 'NotSolanaProviderError',\n shortMessage: 'Provider is not a Solana wallet provider',\n });\n\n this.providerKey = params.providerKey;\n }\n}\n","import { getDefaultClient } from '@dynamic-labs-sdk/client';\nimport { assertDefined } from '@dynamic-labs-sdk/client/core';\n\n/**\n * Checks if Solana gas sponsorship is enabled for the current project.\n *\n * @example\n * ```ts\n * if (isSolanaGasSponsorshipEnabled()) {\n * await signAndSendSponsoredTransaction({ walletAccount, transaction });\n * }\n * ```\n *\n * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.\n * @returns True if Solana gas sponsorship is enabled, false otherwise.\n * @see signAndSendSponsoredTransaction\n * @see signAndSendTransaction\n * @notInstrumented\n */\nexport const isSolanaGasSponsorshipEnabled = (\n client = getDefaultClient()\n): boolean => {\n assertDefined(client.projectSettings, 'Project settings are not defined');\n\n return (\n client.projectSettings.sdk.embeddedWallets?.svmGasSponsorshipEnabled ??\n false\n );\n};\n","import { getDefaultClient } from '@dynamic-labs-sdk/client';\nimport { getWalletProviderFromWalletAccount } from '@dynamic-labs-sdk/client/core';\nimport type {\n SendOptions,\n Transaction,\n VersionedTransaction,\n} from '@solana/web3.js';\n\nimport type { SolanaWalletAccount } from '../SolanaWalletAccount.types';\nimport { NotSolanaProviderError } from '../errors/NotSolanaProviderError';\nimport { isSolanaGasSponsorshipEnabled } from '../isSolanaGasSponsorshipEnabled';\nimport { isSolanaWalletProvider } from '../isSolanaWalletProvider';\n\ntype SignAndSendTransactionParams = {\n options?: SendOptions;\n /**\n * Controls whether Dynamic's gas sponsorship API is used to pay for this\n * transaction.\n *\n * - `'auto'` (default): the transaction is sponsored when Solana gas\n * sponsorship is enabled in project settings AND the walletAccount is a\n * Dynamic embedded wallet. Otherwise the user pays gas.\n * - `'off'`: the transaction is never sponsored, regardless of project\n * settings or provider capabilities. The user pays gas.\n *\n * To require sponsorship (and throw if unsupported), use\n * `signAndSendSponsoredTransaction` instead.\n *\n * @default 'auto'\n */\n sponsorshipMode?: 'auto' | 'off';\n transaction: Transaction | VersionedTransaction;\n walletAccount: SolanaWalletAccount;\n};\n\n/**\n * Signs and sends a Solana transaction, honoring the project's Solana gas\n * sponsorship setting.\n *\n * When solana gas sponsorship is enabled in project settings and sponsorship\n * is supported by the wallet provider, the transaction is routed through\n * Dynamic's gas sponsorship API.\n * Otherwise it falls back to the provider's standard `signAndSendTransaction`.\n *\n * @example\n * ```ts\n * const { signature } = await signAndSendTransaction({\n * walletAccount: solAccount,\n * transaction,\n * });\n * ```\n *\n * @param params.transaction - The transaction to sign and send.\n * @param params.walletAccount - The wallet account to sign and send the transaction with.\n * @param [params.sponsorshipMode] - Controls gas sponsorship: 'auto' (default) or 'off'.\n * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.\n * @returns An object containing the signature.\n * @throws {NotSolanaProviderError} If the wallet provider is not a Solana provider.\n * @see signAndSendSponsoredTransaction\n * @see signTransaction\n * @notInstrumented\n */\nexport const signAndSendTransaction = async (\n {\n walletAccount,\n transaction,\n sponsorshipMode = 'auto',\n options,\n }: SignAndSendTransactionParams,\n client = getDefaultClient()\n): Promise<{ signature: string }> => {\n const provider = getWalletProviderFromWalletAccount(\n {\n walletAccount,\n },\n client\n );\n\n if (!isSolanaWalletProvider(provider)) {\n throw new NotSolanaProviderError({ providerKey: provider.key });\n }\n\n if (\n sponsorshipMode === 'auto' &&\n isSolanaGasSponsorshipEnabled(client) &&\n provider.signAndSendSponsoredTransaction\n ) {\n return provider.signAndSendSponsoredTransaction({\n options,\n transaction,\n walletAccount,\n });\n }\n\n return provider.signAndSendTransaction({\n options,\n transaction,\n walletAccount,\n });\n};\n","import {\n type DynamicClient,\n InvalidParamError,\n} from '@dynamic-labs-sdk/client';\nimport type {\n ExecuteSwapTransactionParams,\n ExecuteSwapTransactionResult,\n} from '@dynamic-labs-sdk/client/core';\nimport {\n getBuffer,\n getWalletProviderFromWalletAccount,\n} from '@dynamic-labs-sdk/client/core';\nimport { Transaction, VersionedTransaction } from '@solana/web3.js';\n\nimport { isSolanaWalletAccount } from '../../isSolanaWalletAccount';\nimport { isSolanaWalletProvider } from '../../isSolanaWalletProvider';\nimport { signAndSendTransaction } from '../../signAndSendTransaction';\n\n/**\n * Executes a Solana checkout transaction by deserializing the base64-encoded\n * transaction and routing it through `signAndSendTransaction`, which applies\n * the project's gas sponsorship setting when enabled.\n *\n * 1. Validates that the wallet account is a Solana wallet account\n * 2. Extracts and validates the serialized transaction from the signing payload\n * 3. Deserializes the transaction (tries VersionedTransaction first, falls back to Transaction)\n * 4. Signs and sends via `signAndSendTransaction` (sponsored when project settings opt in)\n *\n * @param params.signingPayload - The signing payload containing `serializedTransaction`.\n * @param params.walletAccount - The wallet account used to sign and send the transaction.\n * @param params.onStepChange - Optional callback invoked with `'transaction'` when the send step begins.\n * @param params.sponsorshipMode - `'auto'` (default) sponsors when eligible; `'off'` never sponsors.\n * @param client - The Dynamic client instance.\n * @returns The transaction hash (signature).\n * @notInstrumented\n */\nexport const solanaExecuteSwapTransaction = async (\n {\n onStepChange,\n signingPayload,\n sponsorshipMode = 'auto',\n walletAccount,\n }: ExecuteSwapTransactionParams,\n client: DynamicClient\n): Promise<ExecuteSwapTransactionResult> => {\n const walletProvider = getWalletProviderFromWalletAccount(\n { walletAccount },\n client\n );\n\n if (\n !isSolanaWalletAccount(walletAccount) ||\n !isSolanaWalletProvider(walletProvider)\n ) {\n throw new InvalidParamError(\n 'Wallet account is not a Solana wallet account'\n );\n }\n\n const serializedTransactionData = signingPayload.serializedTransaction;\n\n if (!serializedTransactionData) {\n throw new InvalidParamError(\n 'Signing payload is missing serialized transaction data'\n );\n }\n\n const bytes = new Uint8Array(\n getBuffer().from(serializedTransactionData, 'base64')\n );\n\n let transaction: Transaction | VersionedTransaction;\n\n // Try VersionedTransaction first, fall back to legacy Transaction\n try {\n transaction = VersionedTransaction.deserialize(bytes);\n } catch {\n transaction = Transaction.from(bytes);\n }\n\n onStepChange?.('transaction');\n\n const { signature } = await signAndSendTransaction(\n {\n sponsorshipMode,\n transaction,\n walletAccount,\n },\n client\n );\n\n return { transactionHash: signature };\n};\n","import {\n type DynamicClient,\n InvalidParamError,\n getActiveNetworkData,\n} from '@dynamic-labs-sdk/client';\nimport type { TransferAmountParams } from '@dynamic-labs-sdk/client/core';\nimport {\n assertDefined,\n getWalletProviderFromWalletAccount,\n parseAmountToSmallestUnit,\n} from '@dynamic-labs-sdk/client/core';\nimport {\n TOKEN_2022_PROGRAM_ID,\n TOKEN_PROGRAM_ID,\n createAssociatedTokenAccountInstruction,\n createTransferCheckedInstruction,\n getAssociatedTokenAddress,\n} from '@solana/spl-token';\nimport type { TransactionInstruction } from '@solana/web3.js';\nimport {\n PublicKey,\n SystemProgram,\n TransactionMessage,\n VersionedTransaction,\n} from '@solana/web3.js';\n\nimport { NotSolanaProviderError } from '../../errors/NotSolanaProviderError';\nimport { getSolanaConnection } from '../../getSolanaConnection';\nimport { isSolanaWalletAccount } from '../../isSolanaWalletAccount';\nimport { isSolanaWalletProvider } from '../../isSolanaWalletProvider';\nimport { signAndSendTransaction } from '../../signAndSendTransaction';\nconst DEFAULT_DECIMALS = 9;\n\n/**\n * Transfers native SOL or SPL tokens from one wallet to another.\n *\n * For native SOL, builds a `SystemProgram.transfer` instruction.\n * For SPL tokens, derives associated token accounts, creates the recipient\n * ATA if needed, and builds a `transferChecked` instruction. Supports both\n * standard SPL tokens and Token-2022 tokens by detecting the mint's program.\n * @notInstrumented\n */\nexport const solanaTransferAmount = async (\n { amount, recipient, token, walletAccount }: TransferAmountParams,\n client: DynamicClient\n): Promise<{ transactionHash: string }> => {\n if (!isSolanaWalletAccount(walletAccount)) {\n throw new InvalidParamError(\n 'Wallet account is not a Solana wallet account'\n );\n }\n\n const provider = getWalletProviderFromWalletAccount(\n { walletAccount },\n client\n );\n\n if (!isSolanaWalletProvider(provider)) {\n throw new NotSolanaProviderError({ providerKey: provider.key });\n }\n\n const { networkData } = await getActiveNetworkData({ walletAccount }, client);\n assertDefined(networkData, 'Network data is required');\n\n const connection = getSolanaConnection({ networkData });\n\n const fromPubkey = new PublicKey(walletAccount.address);\n const toPubkey = new PublicKey(recipient);\n\n let instructions: TransactionInstruction[];\n\n if (token) {\n const decimals = token.decimals ?? DEFAULT_DECIMALS;\n const mintPubkey = new PublicKey(token.address);\n\n // Detect Token-2022 vs standard SPL by checking mint account owner\n const mintAccountInfo = await connection.getAccountInfo(mintPubkey);\n const tokenProgramId = mintAccountInfo?.owner.equals(TOKEN_2022_PROGRAM_ID)\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n const senderAta = await getAssociatedTokenAddress(\n mintPubkey,\n fromPubkey,\n false,\n tokenProgramId\n );\n\n const recipientAta = await getAssociatedTokenAddress(\n mintPubkey,\n toPubkey,\n false,\n tokenProgramId\n );\n\n const recipientAccountInfo = await connection.getAccountInfo(recipientAta);\n\n const rawAmount = parseAmountToSmallestUnit({ amount, decimals });\n\n instructions = [];\n\n if (!recipientAccountInfo) {\n instructions.push(\n createAssociatedTokenAccountInstruction(\n fromPubkey,\n recipientAta,\n toPubkey,\n mintPubkey,\n tokenProgramId\n )\n );\n }\n\n instructions.push(\n createTransferCheckedInstruction(\n senderAta,\n mintPubkey,\n recipientAta,\n fromPubkey,\n rawAmount,\n decimals,\n [],\n tokenProgramId\n )\n );\n } else {\n instructions = [\n SystemProgram.transfer({\n fromPubkey,\n lamports: parseAmountToSmallestUnit({ amount, decimals: DEFAULT_DECIMALS }),\n toPubkey,\n }),\n ];\n }\n\n const { blockhash } = await connection.getLatestBlockhash('finalized');\n\n const message = new TransactionMessage({\n instructions,\n payerKey: fromPubkey,\n recentBlockhash: blockhash,\n }).compileToV0Message();\n\n const transaction = new VersionedTransaction(message);\n\n const { signature } = await signAndSendTransaction(\n { transaction, walletAccount },\n client\n );\n\n return { transactionHash: signature };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"solanaTransferAmount-BqgJ6ZGp.esm.js","names":["getDefaultClient","getDefaultClient","transaction: Transaction | VersionedTransaction","instructions: TransactionInstruction[]"],"sources":["../package.json","../src/utils/fetchSolBalance/fetchSolBalance.ts","../src/utils/createSolanaNetworkProvider/createSolanaNetworkProvider.ts","../src/registerSolanaNetworkProviderBuilder/registerSolanaNetworkProviderBuilder.ts","../src/getSolanaConnection/getSolanaConnection.ts","../src/utils/isVersionedTransaction/isVersionedTransaction.ts","../src/isSolanaWalletAccount/isSolanaWalletAccount.ts","../src/utils/solanaConfirmTransaction/solanaConfirmTransaction.ts","../src/isSolanaWalletProvider/isSolanaWalletProvider.ts","../src/errors/NotSolanaProviderError/NotSolanaProviderError.ts","../src/isSolanaGasSponsorshipEnabled/isSolanaGasSponsorshipEnabled.ts","../src/signAndSendTransaction/signAndSendTransaction.ts","../src/utils/solanaExecuteSwapTransaction/solanaExecuteSwapTransaction.ts","../src/utils/solanaTransferAmount/solanaTransferAmount.ts"],"sourcesContent":["","import type { NetworkData } from '@dynamic-labs-sdk/client';\nimport { Connection, PublicKey } from '@solana/web3.js';\n\n/** @notInstrumented */\nexport const fetchSolBalance = async ({\n address,\n networkData,\n}: {\n address: string;\n networkData: NetworkData;\n}): Promise<string | null> => {\n // Establish a connection to the Solana network using the provided RPC URL.\n const connection = new Connection(networkData.rpcUrls.http[0]);\n\n // Convert the string address into a PublicKey object.\n const publicKey = new PublicKey(address);\n\n // Fetch the balance of the public key. The balance is in lamports.\n const balanceInLamports = await connection.getBalance(publicKey);\n\n // The getBalance method returns the balance in lamports.\n // 1 SOL = 1,000,000,000 lamports.\n const balanceInSol = balanceInLamports / 1_000_000_000;\n\n // Return the balance in SOL as a string\n return balanceInSol.toString();\n};\n","import type { NetworkData } from '@dynamic-labs-sdk/client';\nimport { createBaseNetworkProvider } from '@dynamic-labs-sdk/client/core';\n\nimport type { SolanaNetworkProvider } from '../../SolanaNetworkProvider.types';\nimport { fetchSolBalance } from '../fetchSolBalance';\n\n/** @notInstrumented */\nexport const createSolanaNetworkProvider = (\n networkData: NetworkData\n): SolanaNetworkProvider => ({\n ...createBaseNetworkProvider('SOL', networkData),\n cluster: networkData.cluster,\n genesisHash: networkData.genesisHash,\n getBalance: async ({ address }) => ({\n balance: await fetchSolBalance({\n address,\n networkData,\n }),\n }),\n});\n","import type { DynamicClient } from '@dynamic-labs-sdk/client';\nimport { getNetworkProviderBuilderRegistry } from '@dynamic-labs-sdk/client/core';\n\nimport { createSolanaNetworkProvider } from '../utils/createSolanaNetworkProvider';\n\n/** @notInstrumented */\nexport const registerSolanaNetworkProviderBuilder = (\n client: DynamicClient\n): void => {\n const networkProviderBuilderRegistry =\n getNetworkProviderBuilderRegistry(client);\n\n /**\n * If the Solana network provider builder is already registered, return.\n */\n if (networkProviderBuilderRegistry.get().get('SOL')) {\n return;\n }\n\n networkProviderBuilderRegistry.register({\n builder: createSolanaNetworkProvider,\n chain: 'SOL',\n });\n};\n","import type { NetworkData } from '@dynamic-labs-sdk/client';\nimport type { Commitment, ConnectionConfig } from '@solana/web3.js';\nimport { Connection } from '@solana/web3.js';\n\ntype GetSolanaConnectionOptions = {\n commitmentOrConfig?: Commitment | ConnectionConfig;\n networkData: NetworkData;\n};\n\n/**\n * Returns a new Solana connection for the given network provider.\n *\n * @example\n * ```ts\n * import { getActiveNetworkData } from '@dynamic-labs-sdk/client';\n * import { isSolanaNetworkProvider, getSolanaConnection } from '@dynamic-labs-sdk/solana';\n *\n * const { networkData } = getActiveNetworkData({ walletAccount });\n *\n * if(!networkData) {\n * throw new Error('No network data found');\n * }\n *\n * const connection = getSolanaConnection({\n * networkData,\n * });\n * ```\n *\n * @param params.networkData - Network configuration containing the RPC URL.\n * @param [params.commitmentOrConfig] - Optional Solana commitment level or connection config.\n * @returns A Solana Connection instance.\n * @see isSolanaNetworkProvider\n * @see calculateSolanaTransactionFee\n * @notInstrumented\n */\nexport const getSolanaConnection = ({\n networkData,\n commitmentOrConfig,\n}: GetSolanaConnectionOptions) => {\n return new Connection(networkData.rpcUrls.http[0], commitmentOrConfig);\n};\n","import type { Transaction, VersionedTransaction } from '@solana/web3.js';\n\n/** @notInstrumented */\nexport const isVersionedTransaction = (\n transaction: VersionedTransaction | Transaction\n): transaction is VersionedTransaction => !('instructions' in transaction);\n","import type { WalletAccount } from '@dynamic-labs-sdk/client';\n\nimport type { SolanaWalletAccount } from '../SolanaWalletAccount.types';\n\n/**\n * Type guard function to check if a wallet account is a Solana wallet account.\n *\n * @example\n * ```ts\n * const accounts = getWalletAccounts();\n * const solAccounts = accounts.filter(isSolanaWalletAccount);\n * ```\n *\n * @param walletAccount - The wallet account to check.\n * @returns True if the wallet account is a Solana wallet account, false otherwise.\n * @see isSolanaNetworkProvider\n * @see addSolanaExtension\n * @notInstrumented\n */\nexport const isSolanaWalletAccount = (\n walletAccount: WalletAccount\n): walletAccount is SolanaWalletAccount => walletAccount.chain === 'SOL';\n","import {\n type DynamicClient,\n InvalidParamError,\n getActiveNetworkData,\n} from '@dynamic-labs-sdk/client';\nimport type { ConfirmTransactionParams } from '@dynamic-labs-sdk/client/core';\nimport { assertDefined } from '@dynamic-labs-sdk/client/core';\n\nimport { getSolanaConnection } from '../../getSolanaConnection';\nimport { isSolanaWalletAccount } from '../../isSolanaWalletAccount';\n\n/**\n * Waits for a Solana transaction to be confirmed on-chain.\n *\n * @param params.transactionHash - The transaction signature to wait for.\n * @param params.walletAccount - The Solana wallet account used to resolve the active network.\n * @param client - The Dynamic client instance.\n * @notInstrumented\n */\nexport const solanaConfirmTransaction = async (\n { transactionHash, walletAccount }: ConfirmTransactionParams,\n client: DynamicClient\n): Promise<void> => {\n if (!isSolanaWalletAccount(walletAccount)) {\n throw new InvalidParamError(\n 'Wallet account is not a Solana wallet account'\n );\n }\n\n const { networkData } = await getActiveNetworkData({ walletAccount }, client);\n\n assertDefined(\n networkData,\n `No network data found for wallet account ${walletAccount.address}`\n );\n\n const connection = getSolanaConnection({ networkData });\n\n const { blockhash, lastValidBlockHeight } =\n await connection.getLatestBlockhash();\n\n await connection.confirmTransaction({\n blockhash,\n lastValidBlockHeight,\n signature: transactionHash,\n });\n};\n","import type { WalletProvider } from '@dynamic-labs-sdk/client/core';\n\nimport type { SolanaWalletProvider } from '../SolanaWalletProvider.types';\n\n/** @notInstrumented */\nexport const isSolanaWalletProvider = (\n provider: WalletProvider\n): provider is SolanaWalletProvider => {\n return provider.chain === 'SOL';\n};\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\nexport class NotSolanaProviderError extends BaseError {\n public readonly providerKey: string;\n\n constructor(params: { providerKey: string }) {\n super({\n cause: null,\n code: 'not_solana_provider_error',\n docsUrl: null,\n name: 'NotSolanaProviderError',\n shortMessage: 'Provider is not a Solana wallet provider',\n });\n\n this.providerKey = params.providerKey;\n }\n}\n","import { getDefaultClient } from '@dynamic-labs-sdk/client';\nimport { assertDefined } from '@dynamic-labs-sdk/client/core';\n\n/**\n * Checks if Solana gas sponsorship is enabled for the current project.\n *\n * @example\n * ```ts\n * if (isSolanaGasSponsorshipEnabled()) {\n * await signAndSendSponsoredTransaction({ walletAccount, transaction });\n * }\n * ```\n *\n * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.\n * @returns True if Solana gas sponsorship is enabled, false otherwise.\n * @see signAndSendSponsoredTransaction\n * @see signAndSendTransaction\n * @notInstrumented\n */\nexport const isSolanaGasSponsorshipEnabled = (\n client = getDefaultClient()\n): boolean => {\n assertDefined(client.projectSettings, 'Project settings are not defined');\n\n return (\n client.projectSettings.sdk.embeddedWallets?.svmGasSponsorshipEnabled ??\n false\n );\n};\n","import { getDefaultClient } from '@dynamic-labs-sdk/client';\nimport { getWalletProviderFromWalletAccount } from '@dynamic-labs-sdk/client/core';\nimport type {\n SendOptions,\n Transaction,\n VersionedTransaction,\n} from '@solana/web3.js';\n\nimport type { SolanaWalletAccount } from '../SolanaWalletAccount.types';\nimport { NotSolanaProviderError } from '../errors/NotSolanaProviderError';\nimport { isSolanaGasSponsorshipEnabled } from '../isSolanaGasSponsorshipEnabled';\nimport { isSolanaWalletProvider } from '../isSolanaWalletProvider';\n\ntype SignAndSendTransactionParams = {\n options?: SendOptions;\n /**\n * Controls whether Dynamic's gas sponsorship API is used to pay for this\n * transaction.\n *\n * - `'auto'` (default): the transaction is sponsored when Solana gas\n * sponsorship is enabled in project settings AND the walletAccount is a\n * Dynamic embedded wallet. Otherwise the user pays gas.\n * - `'off'`: the transaction is never sponsored, regardless of project\n * settings or provider capabilities. The user pays gas.\n *\n * To require sponsorship (and throw if unsupported), use\n * `signAndSendSponsoredTransaction` instead.\n *\n * @default 'auto'\n */\n sponsorshipMode?: 'auto' | 'off';\n transaction: Transaction | VersionedTransaction;\n walletAccount: SolanaWalletAccount;\n};\n\n/**\n * Signs and sends a Solana transaction, honoring the project's Solana gas\n * sponsorship setting.\n *\n * When solana gas sponsorship is enabled in project settings and sponsorship\n * is supported by the wallet provider, the transaction is routed through\n * Dynamic's gas sponsorship API.\n * Otherwise it falls back to the provider's standard `signAndSendTransaction`.\n *\n * @example\n * ```ts\n * const { signature } = await signAndSendTransaction({\n * walletAccount: solAccount,\n * transaction,\n * });\n * ```\n *\n * @param params.transaction - The transaction to sign and send.\n * @param params.walletAccount - The wallet account to sign and send the transaction with.\n * @param [params.sponsorshipMode] - Controls gas sponsorship: 'auto' (default) or 'off'.\n * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.\n * @returns An object containing the signature.\n * @throws {NotSolanaProviderError} If the wallet provider is not a Solana provider.\n * @see signAndSendSponsoredTransaction\n * @see signTransaction\n * @notInstrumented\n */\nexport const signAndSendTransaction = async (\n {\n walletAccount,\n transaction,\n sponsorshipMode = 'auto',\n options,\n }: SignAndSendTransactionParams,\n client = getDefaultClient()\n): Promise<{ signature: string }> => {\n const provider = getWalletProviderFromWalletAccount(\n {\n walletAccount,\n },\n client\n );\n\n if (!isSolanaWalletProvider(provider)) {\n throw new NotSolanaProviderError({ providerKey: provider.key });\n }\n\n if (\n sponsorshipMode === 'auto' &&\n isSolanaGasSponsorshipEnabled(client) &&\n provider.signAndSendSponsoredTransaction\n ) {\n return provider.signAndSendSponsoredTransaction({\n options,\n transaction,\n walletAccount,\n });\n }\n\n return provider.signAndSendTransaction({\n options,\n transaction,\n walletAccount,\n });\n};\n","import {\n type DynamicClient,\n InvalidParamError,\n} from '@dynamic-labs-sdk/client';\nimport type {\n ExecuteSwapTransactionParams,\n ExecuteSwapTransactionResult,\n} from '@dynamic-labs-sdk/client/core';\nimport {\n getBuffer,\n getWalletProviderFromWalletAccount,\n} from '@dynamic-labs-sdk/client/core';\nimport { Transaction, VersionedTransaction } from '@solana/web3.js';\n\nimport { isSolanaWalletAccount } from '../../isSolanaWalletAccount';\nimport { isSolanaWalletProvider } from '../../isSolanaWalletProvider';\nimport { signAndSendTransaction } from '../../signAndSendTransaction';\n\n/**\n * Executes a Solana checkout transaction by deserializing the base64-encoded\n * transaction and routing it through `signAndSendTransaction`, which applies\n * the project's gas sponsorship setting when enabled.\n *\n * 1. Validates that the wallet account is a Solana wallet account\n * 2. Extracts and validates the serialized transaction from the signing payload\n * 3. Deserializes the transaction (tries VersionedTransaction first, falls back to Transaction)\n * 4. Signs and sends via `signAndSendTransaction` (sponsored when project settings opt in)\n *\n * @param params.signingPayload - The signing payload containing `serializedTransaction`.\n * @param params.walletAccount - The wallet account used to sign and send the transaction.\n * @param params.onStepChange - Optional callback invoked with `'transaction'` when the send step begins.\n * @param params.sponsorshipMode - `'auto'` (default) sponsors when eligible; `'off'` never sponsors.\n * @param client - The Dynamic client instance.\n * @returns The transaction hash (signature).\n * @notInstrumented\n */\nexport const solanaExecuteSwapTransaction = async (\n {\n onStepChange,\n signingPayload,\n sponsorshipMode = 'auto',\n walletAccount,\n }: ExecuteSwapTransactionParams,\n client: DynamicClient\n): Promise<ExecuteSwapTransactionResult> => {\n const walletProvider = getWalletProviderFromWalletAccount(\n { walletAccount },\n client\n );\n\n if (\n !isSolanaWalletAccount(walletAccount) ||\n !isSolanaWalletProvider(walletProvider)\n ) {\n throw new InvalidParamError(\n 'Wallet account is not a Solana wallet account'\n );\n }\n\n const serializedTransactionData = signingPayload.serializedTransaction;\n\n if (!serializedTransactionData) {\n throw new InvalidParamError(\n 'Signing payload is missing serialized transaction data'\n );\n }\n\n const bytes = new Uint8Array(\n getBuffer().from(serializedTransactionData, 'base64')\n );\n\n let transaction: Transaction | VersionedTransaction;\n\n // Try VersionedTransaction first, fall back to legacy Transaction\n try {\n transaction = VersionedTransaction.deserialize(bytes);\n } catch {\n transaction = Transaction.from(bytes);\n }\n\n onStepChange?.('transaction');\n\n const { signature } = await signAndSendTransaction(\n {\n sponsorshipMode,\n transaction,\n walletAccount,\n },\n client\n );\n\n return { transactionHash: signature };\n};\n","import {\n type DynamicClient,\n InvalidParamError,\n getActiveNetworkData,\n} from '@dynamic-labs-sdk/client';\nimport type { TransferAmountParams } from '@dynamic-labs-sdk/client/core';\nimport {\n assertDefined,\n getWalletProviderFromWalletAccount,\n parseAmountToSmallestUnit,\n} from '@dynamic-labs-sdk/client/core';\nimport {\n TOKEN_2022_PROGRAM_ID,\n TOKEN_PROGRAM_ID,\n createAssociatedTokenAccountInstruction,\n createTransferCheckedInstruction,\n getAssociatedTokenAddress,\n} from '@solana/spl-token';\nimport type { TransactionInstruction } from '@solana/web3.js';\nimport {\n PublicKey,\n SystemProgram,\n TransactionMessage,\n VersionedTransaction,\n} from '@solana/web3.js';\n\nimport { NotSolanaProviderError } from '../../errors/NotSolanaProviderError';\nimport { getSolanaConnection } from '../../getSolanaConnection';\nimport { isSolanaWalletAccount } from '../../isSolanaWalletAccount';\nimport { isSolanaWalletProvider } from '../../isSolanaWalletProvider';\nimport { signAndSendTransaction } from '../../signAndSendTransaction';\nconst DEFAULT_DECIMALS = 9;\n\n/**\n * Transfers native SOL or SPL tokens from one wallet to another.\n *\n * For native SOL, builds a `SystemProgram.transfer` instruction.\n * For SPL tokens, derives associated token accounts, creates the recipient\n * ATA if needed, and builds a `transferChecked` instruction. Supports both\n * standard SPL tokens and Token-2022 tokens by detecting the mint's program.\n * @notInstrumented\n */\nexport const solanaTransferAmount = async (\n { amount, recipient, token, walletAccount }: TransferAmountParams,\n client: DynamicClient\n): Promise<{ transactionHash: string }> => {\n if (!isSolanaWalletAccount(walletAccount)) {\n throw new InvalidParamError(\n 'Wallet account is not a Solana wallet account'\n );\n }\n\n const provider = getWalletProviderFromWalletAccount(\n { walletAccount },\n client\n );\n\n if (!isSolanaWalletProvider(provider)) {\n throw new NotSolanaProviderError({ providerKey: provider.key });\n }\n\n const { networkData } = await getActiveNetworkData({ walletAccount }, client);\n assertDefined(networkData, 'Network data is required');\n\n const connection = getSolanaConnection({ networkData });\n\n const fromPubkey = new PublicKey(walletAccount.address);\n const toPubkey = new PublicKey(recipient);\n\n let instructions: TransactionInstruction[];\n\n if (token) {\n const decimals = token.decimals ?? DEFAULT_DECIMALS;\n const mintPubkey = new PublicKey(token.address);\n\n // Detect Token-2022 vs standard SPL by checking mint account owner\n const mintAccountInfo = await connection.getAccountInfo(mintPubkey);\n const tokenProgramId = mintAccountInfo?.owner.equals(TOKEN_2022_PROGRAM_ID)\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n const senderAta = await getAssociatedTokenAddress(\n mintPubkey,\n fromPubkey,\n false,\n tokenProgramId\n );\n\n const recipientAta = await getAssociatedTokenAddress(\n mintPubkey,\n toPubkey,\n false,\n tokenProgramId\n );\n\n const recipientAccountInfo = await connection.getAccountInfo(recipientAta);\n\n const rawAmount = parseAmountToSmallestUnit({ amount, decimals });\n\n instructions = [];\n\n if (!recipientAccountInfo) {\n instructions.push(\n createAssociatedTokenAccountInstruction(\n fromPubkey,\n recipientAta,\n toPubkey,\n mintPubkey,\n tokenProgramId\n )\n );\n }\n\n instructions.push(\n createTransferCheckedInstruction(\n senderAta,\n mintPubkey,\n recipientAta,\n fromPubkey,\n rawAmount,\n decimals,\n [],\n tokenProgramId\n )\n );\n } else {\n instructions = [\n SystemProgram.transfer({\n fromPubkey,\n lamports: parseAmountToSmallestUnit({ amount, decimals: DEFAULT_DECIMALS }),\n toPubkey,\n }),\n ];\n }\n\n const { blockhash } = await connection.getLatestBlockhash('finalized');\n\n const message = new TransactionMessage({\n instructions,\n payerKey: fromPubkey,\n recentBlockhash: blockhash,\n }).compileToV0Message();\n\n const transaction = new VersionedTransaction(message);\n\n const { signature } = await signAndSendTransaction(\n { transaction, walletAccount },\n client\n );\n\n return { transactionHash: signature };\n};\n"],"mappings":"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"}
@@ -6,7 +6,7 @@ let _solana_spl_token = require("@solana/spl-token");
6
6
 
7
7
  //#region package.json
8
8
  var name = "@dynamic-labs-sdk/solana";
9
- var version = "1.26.0";
9
+ var version = "1.27.2";
10
10
 
11
11
  //#endregion
12
12
  //#region src/utils/fetchSolBalance/fetchSolBalance.ts
@@ -390,4 +390,4 @@ Object.defineProperty(exports, 'version', {
390
390
  return version;
391
391
  }
392
392
  });
393
- //# sourceMappingURL=solanaTransferAmount-3WcOVJ65.cjs.map
393
+ //# sourceMappingURL=solanaTransferAmount-C76BeL3A.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"solanaTransferAmount-3WcOVJ65.cjs","names":["Connection","PublicKey","Connection","InvalidParamError","BaseError","InvalidParamError","transaction: Transaction | VersionedTransaction","VersionedTransaction","Transaction","InvalidParamError","PublicKey","instructions: TransactionInstruction[]","TOKEN_2022_PROGRAM_ID","TOKEN_PROGRAM_ID","SystemProgram","VersionedTransaction","TransactionMessage"],"sources":["../package.json","../src/utils/fetchSolBalance/fetchSolBalance.ts","../src/utils/createSolanaNetworkProvider/createSolanaNetworkProvider.ts","../src/registerSolanaNetworkProviderBuilder/registerSolanaNetworkProviderBuilder.ts","../src/getSolanaConnection/getSolanaConnection.ts","../src/utils/isVersionedTransaction/isVersionedTransaction.ts","../src/isSolanaWalletAccount/isSolanaWalletAccount.ts","../src/utils/solanaConfirmTransaction/solanaConfirmTransaction.ts","../src/isSolanaWalletProvider/isSolanaWalletProvider.ts","../src/errors/NotSolanaProviderError/NotSolanaProviderError.ts","../src/isSolanaGasSponsorshipEnabled/isSolanaGasSponsorshipEnabled.ts","../src/signAndSendTransaction/signAndSendTransaction.ts","../src/utils/solanaExecuteSwapTransaction/solanaExecuteSwapTransaction.ts","../src/utils/solanaTransferAmount/solanaTransferAmount.ts"],"sourcesContent":["","import type { NetworkData } from '@dynamic-labs-sdk/client';\nimport { Connection, PublicKey } from '@solana/web3.js';\n\n/** @notInstrumented */\nexport const fetchSolBalance = async ({\n address,\n networkData,\n}: {\n address: string;\n networkData: NetworkData;\n}): Promise<string | null> => {\n // Establish a connection to the Solana network using the provided RPC URL.\n const connection = new Connection(networkData.rpcUrls.http[0]);\n\n // Convert the string address into a PublicKey object.\n const publicKey = new PublicKey(address);\n\n // Fetch the balance of the public key. The balance is in lamports.\n const balanceInLamports = await connection.getBalance(publicKey);\n\n // The getBalance method returns the balance in lamports.\n // 1 SOL = 1,000,000,000 lamports.\n const balanceInSol = balanceInLamports / 1_000_000_000;\n\n // Return the balance in SOL as a string\n return balanceInSol.toString();\n};\n","import type { NetworkData } from '@dynamic-labs-sdk/client';\nimport { createBaseNetworkProvider } from '@dynamic-labs-sdk/client/core';\n\nimport type { SolanaNetworkProvider } from '../../SolanaNetworkProvider.types';\nimport { fetchSolBalance } from '../fetchSolBalance';\n\n/** @notInstrumented */\nexport const createSolanaNetworkProvider = (\n networkData: NetworkData\n): SolanaNetworkProvider => ({\n ...createBaseNetworkProvider('SOL', networkData),\n cluster: networkData.cluster,\n genesisHash: networkData.genesisHash,\n getBalance: async ({ address }) => ({\n balance: await fetchSolBalance({\n address,\n networkData,\n }),\n }),\n});\n","import type { DynamicClient } from '@dynamic-labs-sdk/client';\nimport { getNetworkProviderBuilderRegistry } from '@dynamic-labs-sdk/client/core';\n\nimport { createSolanaNetworkProvider } from '../utils/createSolanaNetworkProvider';\n\n/** @notInstrumented */\nexport const registerSolanaNetworkProviderBuilder = (\n client: DynamicClient\n): void => {\n const networkProviderBuilderRegistry =\n getNetworkProviderBuilderRegistry(client);\n\n /**\n * If the Solana network provider builder is already registered, return.\n */\n if (networkProviderBuilderRegistry.get().get('SOL')) {\n return;\n }\n\n networkProviderBuilderRegistry.register({\n builder: createSolanaNetworkProvider,\n chain: 'SOL',\n });\n};\n","import type { NetworkData } from '@dynamic-labs-sdk/client';\nimport type { Commitment, ConnectionConfig } from '@solana/web3.js';\nimport { Connection } from '@solana/web3.js';\n\ntype GetSolanaConnectionOptions = {\n commitmentOrConfig?: Commitment | ConnectionConfig;\n networkData: NetworkData;\n};\n\n/**\n * Returns a new Solana connection for the given network provider.\n *\n * @example\n * ```ts\n * import { getActiveNetworkData } from '@dynamic-labs-sdk/client';\n * import { isSolanaNetworkProvider, getSolanaConnection } from '@dynamic-labs-sdk/solana';\n *\n * const { networkData } = getActiveNetworkData({ walletAccount });\n *\n * if(!networkData) {\n * throw new Error('No network data found');\n * }\n *\n * const connection = getSolanaConnection({\n * networkData,\n * });\n * ```\n *\n * @param params.networkData - Network configuration containing the RPC URL.\n * @param [params.commitmentOrConfig] - Optional Solana commitment level or connection config.\n * @returns A Solana Connection instance.\n * @see isSolanaNetworkProvider\n * @see calculateSolanaTransactionFee\n * @notInstrumented\n */\nexport const getSolanaConnection = ({\n networkData,\n commitmentOrConfig,\n}: GetSolanaConnectionOptions) => {\n return new Connection(networkData.rpcUrls.http[0], commitmentOrConfig);\n};\n","import type { Transaction, VersionedTransaction } from '@solana/web3.js';\n\n/** @notInstrumented */\nexport const isVersionedTransaction = (\n transaction: VersionedTransaction | Transaction\n): transaction is VersionedTransaction => !('instructions' in transaction);\n","import type { WalletAccount } from '@dynamic-labs-sdk/client';\n\nimport type { SolanaWalletAccount } from '../SolanaWalletAccount.types';\n\n/**\n * Type guard function to check if a wallet account is a Solana wallet account.\n *\n * @example\n * ```ts\n * const accounts = getWalletAccounts();\n * const solAccounts = accounts.filter(isSolanaWalletAccount);\n * ```\n *\n * @param walletAccount - The wallet account to check.\n * @returns True if the wallet account is a Solana wallet account, false otherwise.\n * @see isSolanaNetworkProvider\n * @see addSolanaExtension\n * @notInstrumented\n */\nexport const isSolanaWalletAccount = (\n walletAccount: WalletAccount\n): walletAccount is SolanaWalletAccount => walletAccount.chain === 'SOL';\n","import {\n type DynamicClient,\n InvalidParamError,\n getActiveNetworkData,\n} from '@dynamic-labs-sdk/client';\nimport type { ConfirmTransactionParams } from '@dynamic-labs-sdk/client/core';\nimport { assertDefined } from '@dynamic-labs-sdk/client/core';\n\nimport { getSolanaConnection } from '../../getSolanaConnection';\nimport { isSolanaWalletAccount } from '../../isSolanaWalletAccount';\n\n/**\n * Waits for a Solana transaction to be confirmed on-chain.\n *\n * @param params.transactionHash - The transaction signature to wait for.\n * @param params.walletAccount - The Solana wallet account used to resolve the active network.\n * @param client - The Dynamic client instance.\n * @notInstrumented\n */\nexport const solanaConfirmTransaction = async (\n { transactionHash, walletAccount }: ConfirmTransactionParams,\n client: DynamicClient\n): Promise<void> => {\n if (!isSolanaWalletAccount(walletAccount)) {\n throw new InvalidParamError(\n 'Wallet account is not a Solana wallet account'\n );\n }\n\n const { networkData } = await getActiveNetworkData({ walletAccount }, client);\n\n assertDefined(\n networkData,\n `No network data found for wallet account ${walletAccount.address}`\n );\n\n const connection = getSolanaConnection({ networkData });\n\n const { blockhash, lastValidBlockHeight } =\n await connection.getLatestBlockhash();\n\n await connection.confirmTransaction({\n blockhash,\n lastValidBlockHeight,\n signature: transactionHash,\n });\n};\n","import type { WalletProvider } from '@dynamic-labs-sdk/client/core';\n\nimport type { SolanaWalletProvider } from '../SolanaWalletProvider.types';\n\n/** @notInstrumented */\nexport const isSolanaWalletProvider = (\n provider: WalletProvider\n): provider is SolanaWalletProvider => {\n return provider.chain === 'SOL';\n};\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\nexport class NotSolanaProviderError extends BaseError {\n public readonly providerKey: string;\n\n constructor(params: { providerKey: string }) {\n super({\n cause: null,\n code: 'not_solana_provider_error',\n docsUrl: null,\n name: 'NotSolanaProviderError',\n shortMessage: 'Provider is not a Solana wallet provider',\n });\n\n this.providerKey = params.providerKey;\n }\n}\n","import { getDefaultClient } from '@dynamic-labs-sdk/client';\nimport { assertDefined } from '@dynamic-labs-sdk/client/core';\n\n/**\n * Checks if Solana gas sponsorship is enabled for the current project.\n *\n * @example\n * ```ts\n * if (isSolanaGasSponsorshipEnabled()) {\n * await signAndSendSponsoredTransaction({ walletAccount, transaction });\n * }\n * ```\n *\n * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.\n * @returns True if Solana gas sponsorship is enabled, false otherwise.\n * @see signAndSendSponsoredTransaction\n * @see signAndSendTransaction\n * @notInstrumented\n */\nexport const isSolanaGasSponsorshipEnabled = (\n client = getDefaultClient()\n): boolean => {\n assertDefined(client.projectSettings, 'Project settings are not defined');\n\n return (\n client.projectSettings.sdk.embeddedWallets?.svmGasSponsorshipEnabled ??\n false\n );\n};\n","import { getDefaultClient } from '@dynamic-labs-sdk/client';\nimport { getWalletProviderFromWalletAccount } from '@dynamic-labs-sdk/client/core';\nimport type {\n SendOptions,\n Transaction,\n VersionedTransaction,\n} from '@solana/web3.js';\n\nimport type { SolanaWalletAccount } from '../SolanaWalletAccount.types';\nimport { NotSolanaProviderError } from '../errors/NotSolanaProviderError';\nimport { isSolanaGasSponsorshipEnabled } from '../isSolanaGasSponsorshipEnabled';\nimport { isSolanaWalletProvider } from '../isSolanaWalletProvider';\n\ntype SignAndSendTransactionParams = {\n options?: SendOptions;\n /**\n * Controls whether Dynamic's gas sponsorship API is used to pay for this\n * transaction.\n *\n * - `'auto'` (default): the transaction is sponsored when Solana gas\n * sponsorship is enabled in project settings AND the walletAccount is a\n * Dynamic embedded wallet. Otherwise the user pays gas.\n * - `'off'`: the transaction is never sponsored, regardless of project\n * settings or provider capabilities. The user pays gas.\n *\n * To require sponsorship (and throw if unsupported), use\n * `signAndSendSponsoredTransaction` instead.\n *\n * @default 'auto'\n */\n sponsorshipMode?: 'auto' | 'off';\n transaction: Transaction | VersionedTransaction;\n walletAccount: SolanaWalletAccount;\n};\n\n/**\n * Signs and sends a Solana transaction, honoring the project's Solana gas\n * sponsorship setting.\n *\n * When solana gas sponsorship is enabled in project settings and sponsorship\n * is supported by the wallet provider, the transaction is routed through\n * Dynamic's gas sponsorship API.\n * Otherwise it falls back to the provider's standard `signAndSendTransaction`.\n *\n * @example\n * ```ts\n * const { signature } = await signAndSendTransaction({\n * walletAccount: solAccount,\n * transaction,\n * });\n * ```\n *\n * @param params.transaction - The transaction to sign and send.\n * @param params.walletAccount - The wallet account to sign and send the transaction with.\n * @param [params.sponsorshipMode] - Controls gas sponsorship: 'auto' (default) or 'off'.\n * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.\n * @returns An object containing the signature.\n * @throws {NotSolanaProviderError} If the wallet provider is not a Solana provider.\n * @see signAndSendSponsoredTransaction\n * @see signTransaction\n * @notInstrumented\n */\nexport const signAndSendTransaction = async (\n {\n walletAccount,\n transaction,\n sponsorshipMode = 'auto',\n options,\n }: SignAndSendTransactionParams,\n client = getDefaultClient()\n): Promise<{ signature: string }> => {\n const provider = getWalletProviderFromWalletAccount(\n {\n walletAccount,\n },\n client\n );\n\n if (!isSolanaWalletProvider(provider)) {\n throw new NotSolanaProviderError({ providerKey: provider.key });\n }\n\n if (\n sponsorshipMode === 'auto' &&\n isSolanaGasSponsorshipEnabled(client) &&\n provider.signAndSendSponsoredTransaction\n ) {\n return provider.signAndSendSponsoredTransaction({\n options,\n transaction,\n walletAccount,\n });\n }\n\n return provider.signAndSendTransaction({\n options,\n transaction,\n walletAccount,\n });\n};\n","import {\n type DynamicClient,\n InvalidParamError,\n} from '@dynamic-labs-sdk/client';\nimport type {\n ExecuteSwapTransactionParams,\n ExecuteSwapTransactionResult,\n} from '@dynamic-labs-sdk/client/core';\nimport {\n getBuffer,\n getWalletProviderFromWalletAccount,\n} from '@dynamic-labs-sdk/client/core';\nimport { Transaction, VersionedTransaction } from '@solana/web3.js';\n\nimport { isSolanaWalletAccount } from '../../isSolanaWalletAccount';\nimport { isSolanaWalletProvider } from '../../isSolanaWalletProvider';\nimport { signAndSendTransaction } from '../../signAndSendTransaction';\n\n/**\n * Executes a Solana checkout transaction by deserializing the base64-encoded\n * transaction and routing it through `signAndSendTransaction`, which applies\n * the project's gas sponsorship setting when enabled.\n *\n * 1. Validates that the wallet account is a Solana wallet account\n * 2. Extracts and validates the serialized transaction from the signing payload\n * 3. Deserializes the transaction (tries VersionedTransaction first, falls back to Transaction)\n * 4. Signs and sends via `signAndSendTransaction` (sponsored when project settings opt in)\n *\n * @param params.signingPayload - The signing payload containing `serializedTransaction`.\n * @param params.walletAccount - The wallet account used to sign and send the transaction.\n * @param params.onStepChange - Optional callback invoked with `'transaction'` when the send step begins.\n * @param params.sponsorshipMode - `'auto'` (default) sponsors when eligible; `'off'` never sponsors.\n * @param client - The Dynamic client instance.\n * @returns The transaction hash (signature).\n * @notInstrumented\n */\nexport const solanaExecuteSwapTransaction = async (\n {\n onStepChange,\n signingPayload,\n sponsorshipMode = 'auto',\n walletAccount,\n }: ExecuteSwapTransactionParams,\n client: DynamicClient\n): Promise<ExecuteSwapTransactionResult> => {\n const walletProvider = getWalletProviderFromWalletAccount(\n { walletAccount },\n client\n );\n\n if (\n !isSolanaWalletAccount(walletAccount) ||\n !isSolanaWalletProvider(walletProvider)\n ) {\n throw new InvalidParamError(\n 'Wallet account is not a Solana wallet account'\n );\n }\n\n const serializedTransactionData = signingPayload.serializedTransaction;\n\n if (!serializedTransactionData) {\n throw new InvalidParamError(\n 'Signing payload is missing serialized transaction data'\n );\n }\n\n const bytes = new Uint8Array(\n getBuffer().from(serializedTransactionData, 'base64')\n );\n\n let transaction: Transaction | VersionedTransaction;\n\n // Try VersionedTransaction first, fall back to legacy Transaction\n try {\n transaction = VersionedTransaction.deserialize(bytes);\n } catch {\n transaction = Transaction.from(bytes);\n }\n\n onStepChange?.('transaction');\n\n const { signature } = await signAndSendTransaction(\n {\n sponsorshipMode,\n transaction,\n walletAccount,\n },\n client\n );\n\n return { transactionHash: signature };\n};\n","import {\n type DynamicClient,\n InvalidParamError,\n getActiveNetworkData,\n} from '@dynamic-labs-sdk/client';\nimport type { TransferAmountParams } from '@dynamic-labs-sdk/client/core';\nimport {\n assertDefined,\n getWalletProviderFromWalletAccount,\n parseAmountToSmallestUnit,\n} from '@dynamic-labs-sdk/client/core';\nimport {\n TOKEN_2022_PROGRAM_ID,\n TOKEN_PROGRAM_ID,\n createAssociatedTokenAccountInstruction,\n createTransferCheckedInstruction,\n getAssociatedTokenAddress,\n} from '@solana/spl-token';\nimport type { TransactionInstruction } from '@solana/web3.js';\nimport {\n PublicKey,\n SystemProgram,\n TransactionMessage,\n VersionedTransaction,\n} from '@solana/web3.js';\n\nimport { NotSolanaProviderError } from '../../errors/NotSolanaProviderError';\nimport { getSolanaConnection } from '../../getSolanaConnection';\nimport { isSolanaWalletAccount } from '../../isSolanaWalletAccount';\nimport { isSolanaWalletProvider } from '../../isSolanaWalletProvider';\nimport { signAndSendTransaction } from '../../signAndSendTransaction';\nconst DEFAULT_DECIMALS = 9;\n\n/**\n * Transfers native SOL or SPL tokens from one wallet to another.\n *\n * For native SOL, builds a `SystemProgram.transfer` instruction.\n * For SPL tokens, derives associated token accounts, creates the recipient\n * ATA if needed, and builds a `transferChecked` instruction. Supports both\n * standard SPL tokens and Token-2022 tokens by detecting the mint's program.\n * @notInstrumented\n */\nexport const solanaTransferAmount = async (\n { amount, recipient, token, walletAccount }: TransferAmountParams,\n client: DynamicClient\n): Promise<{ transactionHash: string }> => {\n if (!isSolanaWalletAccount(walletAccount)) {\n throw new InvalidParamError(\n 'Wallet account is not a Solana wallet account'\n );\n }\n\n const provider = getWalletProviderFromWalletAccount(\n { walletAccount },\n client\n );\n\n if (!isSolanaWalletProvider(provider)) {\n throw new NotSolanaProviderError({ providerKey: provider.key });\n }\n\n const { networkData } = await getActiveNetworkData({ walletAccount }, client);\n assertDefined(networkData, 'Network data is required');\n\n const connection = getSolanaConnection({ networkData });\n\n const fromPubkey = new PublicKey(walletAccount.address);\n const toPubkey = new PublicKey(recipient);\n\n let instructions: TransactionInstruction[];\n\n if (token) {\n const decimals = token.decimals ?? DEFAULT_DECIMALS;\n const mintPubkey = new PublicKey(token.address);\n\n // Detect Token-2022 vs standard SPL by checking mint account owner\n const mintAccountInfo = await connection.getAccountInfo(mintPubkey);\n const tokenProgramId = mintAccountInfo?.owner.equals(TOKEN_2022_PROGRAM_ID)\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n const senderAta = await getAssociatedTokenAddress(\n mintPubkey,\n fromPubkey,\n false,\n tokenProgramId\n );\n\n const recipientAta = await getAssociatedTokenAddress(\n mintPubkey,\n toPubkey,\n false,\n tokenProgramId\n );\n\n const recipientAccountInfo = await connection.getAccountInfo(recipientAta);\n\n const rawAmount = parseAmountToSmallestUnit({ amount, decimals });\n\n instructions = [];\n\n if (!recipientAccountInfo) {\n instructions.push(\n createAssociatedTokenAccountInstruction(\n fromPubkey,\n recipientAta,\n toPubkey,\n mintPubkey,\n tokenProgramId\n )\n );\n }\n\n instructions.push(\n createTransferCheckedInstruction(\n senderAta,\n mintPubkey,\n recipientAta,\n fromPubkey,\n rawAmount,\n decimals,\n [],\n tokenProgramId\n )\n );\n } else {\n instructions = [\n SystemProgram.transfer({\n fromPubkey,\n lamports: parseAmountToSmallestUnit({ amount, decimals: DEFAULT_DECIMALS }),\n toPubkey,\n }),\n ];\n }\n\n const { blockhash } = await connection.getLatestBlockhash('finalized');\n\n const message = new TransactionMessage({\n instructions,\n payerKey: fromPubkey,\n recentBlockhash: blockhash,\n }).compileToV0Message();\n\n const transaction = new VersionedTransaction(message);\n\n const { signature } = await signAndSendTransaction(\n { transaction, walletAccount },\n client\n );\n\n return { transactionHash: signature };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"solanaTransferAmount-C76BeL3A.cjs","names":["Connection","PublicKey","Connection","InvalidParamError","BaseError","InvalidParamError","transaction: Transaction | VersionedTransaction","VersionedTransaction","Transaction","InvalidParamError","PublicKey","instructions: TransactionInstruction[]","TOKEN_2022_PROGRAM_ID","TOKEN_PROGRAM_ID","SystemProgram","VersionedTransaction","TransactionMessage"],"sources":["../package.json","../src/utils/fetchSolBalance/fetchSolBalance.ts","../src/utils/createSolanaNetworkProvider/createSolanaNetworkProvider.ts","../src/registerSolanaNetworkProviderBuilder/registerSolanaNetworkProviderBuilder.ts","../src/getSolanaConnection/getSolanaConnection.ts","../src/utils/isVersionedTransaction/isVersionedTransaction.ts","../src/isSolanaWalletAccount/isSolanaWalletAccount.ts","../src/utils/solanaConfirmTransaction/solanaConfirmTransaction.ts","../src/isSolanaWalletProvider/isSolanaWalletProvider.ts","../src/errors/NotSolanaProviderError/NotSolanaProviderError.ts","../src/isSolanaGasSponsorshipEnabled/isSolanaGasSponsorshipEnabled.ts","../src/signAndSendTransaction/signAndSendTransaction.ts","../src/utils/solanaExecuteSwapTransaction/solanaExecuteSwapTransaction.ts","../src/utils/solanaTransferAmount/solanaTransferAmount.ts"],"sourcesContent":["","import type { NetworkData } from '@dynamic-labs-sdk/client';\nimport { Connection, PublicKey } from '@solana/web3.js';\n\n/** @notInstrumented */\nexport const fetchSolBalance = async ({\n address,\n networkData,\n}: {\n address: string;\n networkData: NetworkData;\n}): Promise<string | null> => {\n // Establish a connection to the Solana network using the provided RPC URL.\n const connection = new Connection(networkData.rpcUrls.http[0]);\n\n // Convert the string address into a PublicKey object.\n const publicKey = new PublicKey(address);\n\n // Fetch the balance of the public key. The balance is in lamports.\n const balanceInLamports = await connection.getBalance(publicKey);\n\n // The getBalance method returns the balance in lamports.\n // 1 SOL = 1,000,000,000 lamports.\n const balanceInSol = balanceInLamports / 1_000_000_000;\n\n // Return the balance in SOL as a string\n return balanceInSol.toString();\n};\n","import type { NetworkData } from '@dynamic-labs-sdk/client';\nimport { createBaseNetworkProvider } from '@dynamic-labs-sdk/client/core';\n\nimport type { SolanaNetworkProvider } from '../../SolanaNetworkProvider.types';\nimport { fetchSolBalance } from '../fetchSolBalance';\n\n/** @notInstrumented */\nexport const createSolanaNetworkProvider = (\n networkData: NetworkData\n): SolanaNetworkProvider => ({\n ...createBaseNetworkProvider('SOL', networkData),\n cluster: networkData.cluster,\n genesisHash: networkData.genesisHash,\n getBalance: async ({ address }) => ({\n balance: await fetchSolBalance({\n address,\n networkData,\n }),\n }),\n});\n","import type { DynamicClient } from '@dynamic-labs-sdk/client';\nimport { getNetworkProviderBuilderRegistry } from '@dynamic-labs-sdk/client/core';\n\nimport { createSolanaNetworkProvider } from '../utils/createSolanaNetworkProvider';\n\n/** @notInstrumented */\nexport const registerSolanaNetworkProviderBuilder = (\n client: DynamicClient\n): void => {\n const networkProviderBuilderRegistry =\n getNetworkProviderBuilderRegistry(client);\n\n /**\n * If the Solana network provider builder is already registered, return.\n */\n if (networkProviderBuilderRegistry.get().get('SOL')) {\n return;\n }\n\n networkProviderBuilderRegistry.register({\n builder: createSolanaNetworkProvider,\n chain: 'SOL',\n });\n};\n","import type { NetworkData } from '@dynamic-labs-sdk/client';\nimport type { Commitment, ConnectionConfig } from '@solana/web3.js';\nimport { Connection } from '@solana/web3.js';\n\ntype GetSolanaConnectionOptions = {\n commitmentOrConfig?: Commitment | ConnectionConfig;\n networkData: NetworkData;\n};\n\n/**\n * Returns a new Solana connection for the given network provider.\n *\n * @example\n * ```ts\n * import { getActiveNetworkData } from '@dynamic-labs-sdk/client';\n * import { isSolanaNetworkProvider, getSolanaConnection } from '@dynamic-labs-sdk/solana';\n *\n * const { networkData } = getActiveNetworkData({ walletAccount });\n *\n * if(!networkData) {\n * throw new Error('No network data found');\n * }\n *\n * const connection = getSolanaConnection({\n * networkData,\n * });\n * ```\n *\n * @param params.networkData - Network configuration containing the RPC URL.\n * @param [params.commitmentOrConfig] - Optional Solana commitment level or connection config.\n * @returns A Solana Connection instance.\n * @see isSolanaNetworkProvider\n * @see calculateSolanaTransactionFee\n * @notInstrumented\n */\nexport const getSolanaConnection = ({\n networkData,\n commitmentOrConfig,\n}: GetSolanaConnectionOptions) => {\n return new Connection(networkData.rpcUrls.http[0], commitmentOrConfig);\n};\n","import type { Transaction, VersionedTransaction } from '@solana/web3.js';\n\n/** @notInstrumented */\nexport const isVersionedTransaction = (\n transaction: VersionedTransaction | Transaction\n): transaction is VersionedTransaction => !('instructions' in transaction);\n","import type { WalletAccount } from '@dynamic-labs-sdk/client';\n\nimport type { SolanaWalletAccount } from '../SolanaWalletAccount.types';\n\n/**\n * Type guard function to check if a wallet account is a Solana wallet account.\n *\n * @example\n * ```ts\n * const accounts = getWalletAccounts();\n * const solAccounts = accounts.filter(isSolanaWalletAccount);\n * ```\n *\n * @param walletAccount - The wallet account to check.\n * @returns True if the wallet account is a Solana wallet account, false otherwise.\n * @see isSolanaNetworkProvider\n * @see addSolanaExtension\n * @notInstrumented\n */\nexport const isSolanaWalletAccount = (\n walletAccount: WalletAccount\n): walletAccount is SolanaWalletAccount => walletAccount.chain === 'SOL';\n","import {\n type DynamicClient,\n InvalidParamError,\n getActiveNetworkData,\n} from '@dynamic-labs-sdk/client';\nimport type { ConfirmTransactionParams } from '@dynamic-labs-sdk/client/core';\nimport { assertDefined } from '@dynamic-labs-sdk/client/core';\n\nimport { getSolanaConnection } from '../../getSolanaConnection';\nimport { isSolanaWalletAccount } from '../../isSolanaWalletAccount';\n\n/**\n * Waits for a Solana transaction to be confirmed on-chain.\n *\n * @param params.transactionHash - The transaction signature to wait for.\n * @param params.walletAccount - The Solana wallet account used to resolve the active network.\n * @param client - The Dynamic client instance.\n * @notInstrumented\n */\nexport const solanaConfirmTransaction = async (\n { transactionHash, walletAccount }: ConfirmTransactionParams,\n client: DynamicClient\n): Promise<void> => {\n if (!isSolanaWalletAccount(walletAccount)) {\n throw new InvalidParamError(\n 'Wallet account is not a Solana wallet account'\n );\n }\n\n const { networkData } = await getActiveNetworkData({ walletAccount }, client);\n\n assertDefined(\n networkData,\n `No network data found for wallet account ${walletAccount.address}`\n );\n\n const connection = getSolanaConnection({ networkData });\n\n const { blockhash, lastValidBlockHeight } =\n await connection.getLatestBlockhash();\n\n await connection.confirmTransaction({\n blockhash,\n lastValidBlockHeight,\n signature: transactionHash,\n });\n};\n","import type { WalletProvider } from '@dynamic-labs-sdk/client/core';\n\nimport type { SolanaWalletProvider } from '../SolanaWalletProvider.types';\n\n/** @notInstrumented */\nexport const isSolanaWalletProvider = (\n provider: WalletProvider\n): provider is SolanaWalletProvider => {\n return provider.chain === 'SOL';\n};\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\nexport class NotSolanaProviderError extends BaseError {\n public readonly providerKey: string;\n\n constructor(params: { providerKey: string }) {\n super({\n cause: null,\n code: 'not_solana_provider_error',\n docsUrl: null,\n name: 'NotSolanaProviderError',\n shortMessage: 'Provider is not a Solana wallet provider',\n });\n\n this.providerKey = params.providerKey;\n }\n}\n","import { getDefaultClient } from '@dynamic-labs-sdk/client';\nimport { assertDefined } from '@dynamic-labs-sdk/client/core';\n\n/**\n * Checks if Solana gas sponsorship is enabled for the current project.\n *\n * @example\n * ```ts\n * if (isSolanaGasSponsorshipEnabled()) {\n * await signAndSendSponsoredTransaction({ walletAccount, transaction });\n * }\n * ```\n *\n * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.\n * @returns True if Solana gas sponsorship is enabled, false otherwise.\n * @see signAndSendSponsoredTransaction\n * @see signAndSendTransaction\n * @notInstrumented\n */\nexport const isSolanaGasSponsorshipEnabled = (\n client = getDefaultClient()\n): boolean => {\n assertDefined(client.projectSettings, 'Project settings are not defined');\n\n return (\n client.projectSettings.sdk.embeddedWallets?.svmGasSponsorshipEnabled ??\n false\n );\n};\n","import { getDefaultClient } from '@dynamic-labs-sdk/client';\nimport { getWalletProviderFromWalletAccount } from '@dynamic-labs-sdk/client/core';\nimport type {\n SendOptions,\n Transaction,\n VersionedTransaction,\n} from '@solana/web3.js';\n\nimport type { SolanaWalletAccount } from '../SolanaWalletAccount.types';\nimport { NotSolanaProviderError } from '../errors/NotSolanaProviderError';\nimport { isSolanaGasSponsorshipEnabled } from '../isSolanaGasSponsorshipEnabled';\nimport { isSolanaWalletProvider } from '../isSolanaWalletProvider';\n\ntype SignAndSendTransactionParams = {\n options?: SendOptions;\n /**\n * Controls whether Dynamic's gas sponsorship API is used to pay for this\n * transaction.\n *\n * - `'auto'` (default): the transaction is sponsored when Solana gas\n * sponsorship is enabled in project settings AND the walletAccount is a\n * Dynamic embedded wallet. Otherwise the user pays gas.\n * - `'off'`: the transaction is never sponsored, regardless of project\n * settings or provider capabilities. The user pays gas.\n *\n * To require sponsorship (and throw if unsupported), use\n * `signAndSendSponsoredTransaction` instead.\n *\n * @default 'auto'\n */\n sponsorshipMode?: 'auto' | 'off';\n transaction: Transaction | VersionedTransaction;\n walletAccount: SolanaWalletAccount;\n};\n\n/**\n * Signs and sends a Solana transaction, honoring the project's Solana gas\n * sponsorship setting.\n *\n * When solana gas sponsorship is enabled in project settings and sponsorship\n * is supported by the wallet provider, the transaction is routed through\n * Dynamic's gas sponsorship API.\n * Otherwise it falls back to the provider's standard `signAndSendTransaction`.\n *\n * @example\n * ```ts\n * const { signature } = await signAndSendTransaction({\n * walletAccount: solAccount,\n * transaction,\n * });\n * ```\n *\n * @param params.transaction - The transaction to sign and send.\n * @param params.walletAccount - The wallet account to sign and send the transaction with.\n * @param [params.sponsorshipMode] - Controls gas sponsorship: 'auto' (default) or 'off'.\n * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.\n * @returns An object containing the signature.\n * @throws {NotSolanaProviderError} If the wallet provider is not a Solana provider.\n * @see signAndSendSponsoredTransaction\n * @see signTransaction\n * @notInstrumented\n */\nexport const signAndSendTransaction = async (\n {\n walletAccount,\n transaction,\n sponsorshipMode = 'auto',\n options,\n }: SignAndSendTransactionParams,\n client = getDefaultClient()\n): Promise<{ signature: string }> => {\n const provider = getWalletProviderFromWalletAccount(\n {\n walletAccount,\n },\n client\n );\n\n if (!isSolanaWalletProvider(provider)) {\n throw new NotSolanaProviderError({ providerKey: provider.key });\n }\n\n if (\n sponsorshipMode === 'auto' &&\n isSolanaGasSponsorshipEnabled(client) &&\n provider.signAndSendSponsoredTransaction\n ) {\n return provider.signAndSendSponsoredTransaction({\n options,\n transaction,\n walletAccount,\n });\n }\n\n return provider.signAndSendTransaction({\n options,\n transaction,\n walletAccount,\n });\n};\n","import {\n type DynamicClient,\n InvalidParamError,\n} from '@dynamic-labs-sdk/client';\nimport type {\n ExecuteSwapTransactionParams,\n ExecuteSwapTransactionResult,\n} from '@dynamic-labs-sdk/client/core';\nimport {\n getBuffer,\n getWalletProviderFromWalletAccount,\n} from '@dynamic-labs-sdk/client/core';\nimport { Transaction, VersionedTransaction } from '@solana/web3.js';\n\nimport { isSolanaWalletAccount } from '../../isSolanaWalletAccount';\nimport { isSolanaWalletProvider } from '../../isSolanaWalletProvider';\nimport { signAndSendTransaction } from '../../signAndSendTransaction';\n\n/**\n * Executes a Solana checkout transaction by deserializing the base64-encoded\n * transaction and routing it through `signAndSendTransaction`, which applies\n * the project's gas sponsorship setting when enabled.\n *\n * 1. Validates that the wallet account is a Solana wallet account\n * 2. Extracts and validates the serialized transaction from the signing payload\n * 3. Deserializes the transaction (tries VersionedTransaction first, falls back to Transaction)\n * 4. Signs and sends via `signAndSendTransaction` (sponsored when project settings opt in)\n *\n * @param params.signingPayload - The signing payload containing `serializedTransaction`.\n * @param params.walletAccount - The wallet account used to sign and send the transaction.\n * @param params.onStepChange - Optional callback invoked with `'transaction'` when the send step begins.\n * @param params.sponsorshipMode - `'auto'` (default) sponsors when eligible; `'off'` never sponsors.\n * @param client - The Dynamic client instance.\n * @returns The transaction hash (signature).\n * @notInstrumented\n */\nexport const solanaExecuteSwapTransaction = async (\n {\n onStepChange,\n signingPayload,\n sponsorshipMode = 'auto',\n walletAccount,\n }: ExecuteSwapTransactionParams,\n client: DynamicClient\n): Promise<ExecuteSwapTransactionResult> => {\n const walletProvider = getWalletProviderFromWalletAccount(\n { walletAccount },\n client\n );\n\n if (\n !isSolanaWalletAccount(walletAccount) ||\n !isSolanaWalletProvider(walletProvider)\n ) {\n throw new InvalidParamError(\n 'Wallet account is not a Solana wallet account'\n );\n }\n\n const serializedTransactionData = signingPayload.serializedTransaction;\n\n if (!serializedTransactionData) {\n throw new InvalidParamError(\n 'Signing payload is missing serialized transaction data'\n );\n }\n\n const bytes = new Uint8Array(\n getBuffer().from(serializedTransactionData, 'base64')\n );\n\n let transaction: Transaction | VersionedTransaction;\n\n // Try VersionedTransaction first, fall back to legacy Transaction\n try {\n transaction = VersionedTransaction.deserialize(bytes);\n } catch {\n transaction = Transaction.from(bytes);\n }\n\n onStepChange?.('transaction');\n\n const { signature } = await signAndSendTransaction(\n {\n sponsorshipMode,\n transaction,\n walletAccount,\n },\n client\n );\n\n return { transactionHash: signature };\n};\n","import {\n type DynamicClient,\n InvalidParamError,\n getActiveNetworkData,\n} from '@dynamic-labs-sdk/client';\nimport type { TransferAmountParams } from '@dynamic-labs-sdk/client/core';\nimport {\n assertDefined,\n getWalletProviderFromWalletAccount,\n parseAmountToSmallestUnit,\n} from '@dynamic-labs-sdk/client/core';\nimport {\n TOKEN_2022_PROGRAM_ID,\n TOKEN_PROGRAM_ID,\n createAssociatedTokenAccountInstruction,\n createTransferCheckedInstruction,\n getAssociatedTokenAddress,\n} from '@solana/spl-token';\nimport type { TransactionInstruction } from '@solana/web3.js';\nimport {\n PublicKey,\n SystemProgram,\n TransactionMessage,\n VersionedTransaction,\n} from '@solana/web3.js';\n\nimport { NotSolanaProviderError } from '../../errors/NotSolanaProviderError';\nimport { getSolanaConnection } from '../../getSolanaConnection';\nimport { isSolanaWalletAccount } from '../../isSolanaWalletAccount';\nimport { isSolanaWalletProvider } from '../../isSolanaWalletProvider';\nimport { signAndSendTransaction } from '../../signAndSendTransaction';\nconst DEFAULT_DECIMALS = 9;\n\n/**\n * Transfers native SOL or SPL tokens from one wallet to another.\n *\n * For native SOL, builds a `SystemProgram.transfer` instruction.\n * For SPL tokens, derives associated token accounts, creates the recipient\n * ATA if needed, and builds a `transferChecked` instruction. Supports both\n * standard SPL tokens and Token-2022 tokens by detecting the mint's program.\n * @notInstrumented\n */\nexport const solanaTransferAmount = async (\n { amount, recipient, token, walletAccount }: TransferAmountParams,\n client: DynamicClient\n): Promise<{ transactionHash: string }> => {\n if (!isSolanaWalletAccount(walletAccount)) {\n throw new InvalidParamError(\n 'Wallet account is not a Solana wallet account'\n );\n }\n\n const provider = getWalletProviderFromWalletAccount(\n { walletAccount },\n client\n );\n\n if (!isSolanaWalletProvider(provider)) {\n throw new NotSolanaProviderError({ providerKey: provider.key });\n }\n\n const { networkData } = await getActiveNetworkData({ walletAccount }, client);\n assertDefined(networkData, 'Network data is required');\n\n const connection = getSolanaConnection({ networkData });\n\n const fromPubkey = new PublicKey(walletAccount.address);\n const toPubkey = new PublicKey(recipient);\n\n let instructions: TransactionInstruction[];\n\n if (token) {\n const decimals = token.decimals ?? DEFAULT_DECIMALS;\n const mintPubkey = new PublicKey(token.address);\n\n // Detect Token-2022 vs standard SPL by checking mint account owner\n const mintAccountInfo = await connection.getAccountInfo(mintPubkey);\n const tokenProgramId = mintAccountInfo?.owner.equals(TOKEN_2022_PROGRAM_ID)\n ? TOKEN_2022_PROGRAM_ID\n : TOKEN_PROGRAM_ID;\n\n const senderAta = await getAssociatedTokenAddress(\n mintPubkey,\n fromPubkey,\n false,\n tokenProgramId\n );\n\n const recipientAta = await getAssociatedTokenAddress(\n mintPubkey,\n toPubkey,\n false,\n tokenProgramId\n );\n\n const recipientAccountInfo = await connection.getAccountInfo(recipientAta);\n\n const rawAmount = parseAmountToSmallestUnit({ amount, decimals });\n\n instructions = [];\n\n if (!recipientAccountInfo) {\n instructions.push(\n createAssociatedTokenAccountInstruction(\n fromPubkey,\n recipientAta,\n toPubkey,\n mintPubkey,\n tokenProgramId\n )\n );\n }\n\n instructions.push(\n createTransferCheckedInstruction(\n senderAta,\n mintPubkey,\n recipientAta,\n fromPubkey,\n rawAmount,\n decimals,\n [],\n tokenProgramId\n )\n );\n } else {\n instructions = [\n SystemProgram.transfer({\n fromPubkey,\n lamports: parseAmountToSmallestUnit({ amount, decimals: DEFAULT_DECIMALS }),\n toPubkey,\n }),\n ];\n }\n\n const { blockhash } = await connection.getLatestBlockhash('finalized');\n\n const message = new TransactionMessage({\n instructions,\n payerKey: fromPubkey,\n recentBlockhash: blockhash,\n }).compileToV0Message();\n\n const transaction = new VersionedTransaction(message);\n\n const { signature } = await signAndSendTransaction(\n { transaction, walletAccount },\n client\n );\n\n return { transactionHash: signature };\n};\n"],"mappings":"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"}