@dynamic-labs-sdk/solana 1.31.0 → 1.31.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 (87) hide show
  1. package/README.md +22 -0
  2. package/dist/{createWalletProviderFromSolanaStandardWallet-CpSgF7IN.esm.js → addSolanaWalletStandardExtension-CQAVpxFG.esm.js} +56 -4
  3. package/dist/addSolanaWalletStandardExtension-CQAVpxFG.esm.js.map +1 -0
  4. package/dist/{createWalletProviderFromSolanaStandardWallet-CCkxOmSK.cjs → addSolanaWalletStandardExtension-DTQS5msv.cjs} +56 -10
  5. package/dist/addSolanaWalletStandardExtension-DTQS5msv.cjs.map +1 -0
  6. package/dist/{addWaasSolanaExtension-DCOgxPMc.esm.js → addWaasSolanaExtension-CBNPkfTZ.esm.js} +2 -2
  7. package/dist/{addWaasSolanaExtension-DCOgxPMc.esm.js.map → addWaasSolanaExtension-CBNPkfTZ.esm.js.map} +1 -1
  8. package/dist/{addWaasSolanaExtension-CEDmaSAh.cjs → addWaasSolanaExtension-DwpmCWwW.cjs} +2 -2
  9. package/dist/{addWaasSolanaExtension-CEDmaSAh.cjs.map → addWaasSolanaExtension-DwpmCWwW.cjs.map} +1 -1
  10. package/dist/errors/MetaMaskDirectConnectNotSupportedError/MetaMaskDirectConnectNotSupportedError.d.ts +14 -0
  11. package/dist/errors/MetaMaskDirectConnectNotSupportedError/MetaMaskDirectConnectNotSupportedError.d.ts.map +1 -0
  12. package/dist/errors/MetaMaskDirectConnectNotSupportedError/index.d.ts +2 -0
  13. package/dist/errors/MetaMaskDirectConnectNotSupportedError/index.d.ts.map +1 -0
  14. package/dist/exports/metamask.d.ts +3 -0
  15. package/dist/exports/metamask.d.ts.map +1 -1
  16. package/dist/index.cjs +3 -4
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.esm.js +3 -4
  19. package/dist/index.esm.js.map +1 -1
  20. package/dist/metamask/addMetaMaskSolanaExtension/addMetaMaskSolanaExtension.d.ts +23 -0
  21. package/dist/metamask/addMetaMaskSolanaExtension/addMetaMaskSolanaExtension.d.ts.map +1 -0
  22. package/dist/metamask/addMetaMaskSolanaExtension/index.d.ts +2 -0
  23. package/dist/metamask/addMetaMaskSolanaExtension/index.d.ts.map +1 -0
  24. package/dist/metamask/connectWithMetaMaskUriSolana/connectWithMetaMaskUriSolana.d.ts.map +1 -1
  25. package/dist/metamask/createMetaMaskSolanaWalletProvider/createMetaMaskSolanaWalletProvider.d.ts +26 -6
  26. package/dist/metamask/createMetaMaskSolanaWalletProvider/createMetaMaskSolanaWalletProvider.d.ts.map +1 -1
  27. package/dist/metamask/getMetaMaskSolanaSdkWalletProviderKey/getMetaMaskSolanaSdkWalletProviderKey.d.ts +17 -0
  28. package/dist/metamask/getMetaMaskSolanaSdkWalletProviderKey/getMetaMaskSolanaSdkWalletProviderKey.d.ts.map +1 -0
  29. package/dist/metamask/getMetaMaskSolanaSdkWalletProviderKey/index.d.ts +2 -0
  30. package/dist/metamask/getMetaMaskSolanaSdkWalletProviderKey/index.d.ts.map +1 -0
  31. package/dist/metamask/registerMetaMaskSolanaUriConnectionStarter/index.d.ts +2 -0
  32. package/dist/metamask/registerMetaMaskSolanaUriConnectionStarter/index.d.ts.map +1 -0
  33. package/dist/metamask/registerMetaMaskSolanaUriConnectionStarter/registerMetaMaskSolanaUriConnectionStarter.d.ts +22 -0
  34. package/dist/metamask/registerMetaMaskSolanaUriConnectionStarter/registerMetaMaskSolanaUriConnectionStarter.d.ts.map +1 -0
  35. package/dist/metamask/warnMetaMaskSolanaIntegrationIncomplete/index.d.ts +2 -0
  36. package/dist/metamask/warnMetaMaskSolanaIntegrationIncomplete/index.d.ts.map +1 -0
  37. package/dist/metamask/warnMetaMaskSolanaIntegrationIncomplete/warnMetaMaskSolanaIntegrationIncomplete.d.ts +18 -0
  38. package/dist/metamask/warnMetaMaskSolanaIntegrationIncomplete/warnMetaMaskSolanaIntegrationIncomplete.d.ts.map +1 -0
  39. package/dist/metamask.cjs +289 -136
  40. package/dist/metamask.cjs.map +1 -1
  41. package/dist/metamask.esm.js +291 -141
  42. package/dist/metamask.esm.js.map +1 -1
  43. package/dist/{solanaTransferAmount-DFbb8Fnf.cjs → solanaTransferAmount-4hvpXzRi.cjs} +2 -2
  44. package/dist/{solanaTransferAmount-DFbb8Fnf.cjs.map → solanaTransferAmount-4hvpXzRi.cjs.map} +1 -1
  45. package/dist/{solanaTransferAmount-BmcJvD2x.esm.js → solanaTransferAmount-C-2Ct-ry.esm.js} +2 -2
  46. package/dist/{solanaTransferAmount-BmcJvD2x.esm.js.map → solanaTransferAmount-C-2Ct-ry.esm.js.map} +1 -1
  47. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  48. package/dist/waas.cjs +2 -2
  49. package/dist/waas.esm.js +2 -2
  50. package/dist/walletConnect/addWalletConnectSolanaExtension/addWalletConnectSolanaExtension.d.ts.map +1 -1
  51. package/dist/walletConnect/registerWalletConnectSolanaUriConnectionStarter/index.d.ts +2 -0
  52. package/dist/walletConnect/registerWalletConnectSolanaUriConnectionStarter/index.d.ts.map +1 -0
  53. package/dist/walletConnect/registerWalletConnectSolanaUriConnectionStarter/registerWalletConnectSolanaUriConnectionStarter.d.ts +19 -0
  54. package/dist/walletConnect/registerWalletConnectSolanaUriConnectionStarter/registerWalletConnectSolanaUriConnectionStarter.d.ts.map +1 -0
  55. package/dist/walletConnect.cjs +40 -13
  56. package/dist/walletConnect.cjs.map +1 -1
  57. package/dist/walletConnect.esm.js +41 -14
  58. package/dist/walletConnect.esm.js.map +1 -1
  59. package/dist/walletStandard.cjs +2 -3
  60. package/dist/walletStandard.cjs.map +1 -1
  61. package/dist/walletStandard.esm.js +2 -3
  62. package/dist/walletStandard.esm.js.map +1 -1
  63. package/package.json +5 -6
  64. package/dist/addSolanaWalletStandardExtension-BG3AkPK9.esm.js +0 -59
  65. package/dist/addSolanaWalletStandardExtension-BG3AkPK9.esm.js.map +0 -1
  66. package/dist/addSolanaWalletStandardExtension-C2xw3bYp.cjs +0 -65
  67. package/dist/addSolanaWalletStandardExtension-C2xw3bYp.cjs.map +0 -1
  68. package/dist/createWalletProviderFromSolanaStandardWallet-CCkxOmSK.cjs.map +0 -1
  69. package/dist/createWalletProviderFromSolanaStandardWallet-CpSgF7IN.esm.js.map +0 -1
  70. package/dist/metamask/metamask.types.d.ts +0 -14
  71. package/dist/metamask/metamask.types.d.ts.map +0 -1
  72. package/dist/metamask/utils/createMetaMaskSolanaController/createMetaMaskSolanaController.d.ts +0 -20
  73. package/dist/metamask/utils/createMetaMaskSolanaController/createMetaMaskSolanaController.d.ts.map +0 -1
  74. package/dist/metamask/utils/createMetaMaskSolanaController/index.d.ts +0 -2
  75. package/dist/metamask/utils/createMetaMaskSolanaController/index.d.ts.map +0 -1
  76. package/dist/metamask/utils/getOrCreateMetaMaskSolanaController/getOrCreateMetaMaskSolanaController.d.ts +0 -20
  77. package/dist/metamask/utils/getOrCreateMetaMaskSolanaController/getOrCreateMetaMaskSolanaController.d.ts.map +0 -1
  78. package/dist/metamask/utils/getOrCreateMetaMaskSolanaController/index.d.ts +0 -2
  79. package/dist/metamask/utils/getOrCreateMetaMaskSolanaController/index.d.ts.map +0 -1
  80. package/dist/metamask/utils/getSolanaNetworkFromCluster/getSolanaNetworkFromCluster.d.ts +0 -18
  81. package/dist/metamask/utils/getSolanaNetworkFromCluster/getSolanaNetworkFromCluster.d.ts.map +0 -1
  82. package/dist/metamask/utils/getSolanaNetworkFromCluster/index.d.ts +0 -3
  83. package/dist/metamask/utils/getSolanaNetworkFromCluster/index.d.ts.map +0 -1
  84. package/dist/metamask/utils/getSupportedNetworks/getSupportedNetworks.d.ts +0 -16
  85. package/dist/metamask/utils/getSupportedNetworks/getSupportedNetworks.d.ts.map +0 -1
  86. package/dist/metamask/utils/getSupportedNetworks/index.d.ts +0 -2
  87. package/dist/metamask/utils/getSupportedNetworks/index.d.ts.map +0 -1
package/dist/metamask.cjs CHANGED
@@ -1,181 +1,301 @@
1
1
  const require_chunk = require('./chunk-CbDLau6x.cjs');
2
- const require_solanaTransferAmount = require('./solanaTransferAmount-DFbb8Fnf.cjs');
3
- const require_createWalletProviderFromSolanaStandardWallet = require('./createWalletProviderFromSolanaStandardWallet-CCkxOmSK.cjs');
2
+ const require_solanaTransferAmount = require('./solanaTransferAmount-4hvpXzRi.cjs');
4
3
  let _dynamic_labs_sdk_assert_package_version = require("@dynamic-labs-sdk/assert-package-version");
5
4
  let _dynamic_labs_sdk_client_core = require("@dynamic-labs-sdk/client/core");
6
5
  let _dynamic_labs_sdk_client = require("@dynamic-labs-sdk/client");
6
+ let _solana_web3_js = require("@solana/web3.js");
7
7
  let _dynamic_labs_sdk_api_core = require("@dynamic-labs/sdk-api-core");
8
+ let _dynamic_labs_sdk_metamask_core = require("@dynamic-labs-sdk/metamask/core");
9
+ let _dynamic_labs_sdk_wallet_connect_core = require("@dynamic-labs-sdk/wallet-connect/core");
8
10
  let _dynamic_labs_sdk_metamask = require("@dynamic-labs-sdk/metamask");
9
- let _metamask_connect_solana = require("@metamask/connect-solana");
10
11
 
11
- //#region src/metamask/utils/getSolanaNetworkFromCluster/getSolanaNetworkFromCluster.ts
12
+ //#region src/errors/MetaMaskDirectConnectNotSupportedError/MetaMaskDirectConnectNotSupportedError.ts
12
13
  /**
13
- * Maps a Dynamic network `cluster` (e.g. `mainnet-beta`, `devnet`,
14
- * `testnet`) to the `mainnet | devnet | testnet` key shape expected by
15
- * `@metamask/connect-solana`'s `createSolanaClient`. Returns `undefined` for
16
- * clusters that do not correspond to one of MetaMask's supported Solana
17
- * networks so callers can skip them. Used by `getSupportedNetworks` to build
18
- * the SDK's `supportedNetworks` map.
19
- *
20
- * @notInstrumented
14
+ * Thrown when `connect()` is called directly on the MetaMask SDK placeholder
15
+ * wallet provider (the entry `addMetaMaskSolanaExtension` registers so
16
+ * MetaMask still shows up in the wallet picker when no browser extension is
17
+ * installed). That placeholder has no generic connect flow of its own --
18
+ * connecting requires the QR / deeplink pairing flow, so callers must drive
19
+ * `connectWithMetaMaskUriSolana` (or `connectAndVerifyWithMetaMaskUriSolana`)
20
+ * instead of the picker's default connect.
21
21
  */
22
- const getSolanaNetworkFromCluster = ({ cluster }) => {
23
- if (cluster === void 0) return;
24
- if (cluster.includes("mainnet")) return "mainnet";
25
- if (cluster.includes("devnet")) return "devnet";
26
- if (cluster.includes("testnet")) return "testnet";
22
+ var MetaMaskDirectConnectNotSupportedError = class extends _dynamic_labs_sdk_client.BaseError {
23
+ constructor() {
24
+ super({
25
+ cause: null,
26
+ code: "metamask_direct_connect_not_supported",
27
+ docsUrl: null,
28
+ name: "MetaMaskDirectConnectNotSupportedError",
29
+ shortMessage: "MetaMask cannot be connected directly; call connectWithMetaMaskUriSolana (or connectAndVerifyWithMetaMaskUriSolana) to get a QR/URI pairing flow instead"
30
+ });
31
+ }
27
32
  };
28
33
 
29
34
  //#endregion
30
- //#region src/metamask/utils/getSupportedNetworks/getSupportedNetworks.ts
35
+ //#region src/metamask/getMetaMaskSolanaSdkWalletProviderKey/getMetaMaskSolanaSdkWalletProviderKey.ts
36
+ const METAMASK_SOLANA_SDK_DISPLAY_NAME = "MetaMask";
31
37
  /**
32
- * Builds the `supportedNetworks` map required by
33
- * `@metamask/connect-solana`'s `createSolanaClient`, keyed by the SDK's
34
- * `mainnet | devnet | testnet` network names and valued with the first
35
- * configured RPC URL for each. Sources the configured SOL networks from the
36
- * Dynamic client's project settings. Throws when no SOL network is
37
- * configured, mirroring the EVM `getSupportedNetworks` contract.
38
+ * Deterministic wallet provider key for the MetaMask SDK's connect-less
39
+ * Solana placeholder. Computed without building the wallet provider itself,
40
+ * so `addMetaMaskSolanaExtension` can check for a matching wallet account
41
+ * before paying the cost of `createMetaMaskSolanaWalletProvider`.
38
42
  *
43
+ * @example
44
+ * ```ts
45
+ * const key = getMetaMaskSolanaSdkWalletProviderKey();
46
+ * ```
47
+ * @returns The deterministic wallet provider key.
48
+ * @see createMetaMaskSolanaWalletProvider
49
+ * @see reconcileMetaMaskWalletProvider
39
50
  * @notInstrumented
40
51
  */
41
- const getSupportedNetworks = (client) => {
42
- const solanaNetworks = (0, _dynamic_labs_sdk_client.getNetworksData)(client).filter((network) => network.chain === "SOL");
43
- (0, _dynamic_labs_sdk_client_core.assertNonEmptyArray)(solanaNetworks, "No SOL networks have been configured. Make sure to add at least one Solana network to your project settings in the Dynamic Dashboard.");
44
- const supportedNetworks = {};
45
- for (const network of solanaNetworks) {
46
- const solanaNetwork = getSolanaNetworkFromCluster({ cluster: network.cluster });
47
- if (solanaNetwork !== void 0 && supportedNetworks[solanaNetwork] === void 0) supportedNetworks[solanaNetwork] = network.rpcUrls.http[0];
48
- }
49
- return supportedNetworks;
50
- };
52
+ const getMetaMaskSolanaSdkWalletProviderKey = () => (0, _dynamic_labs_sdk_client_core.formatWalletProviderKey)({
53
+ chain: "SOL",
54
+ displayName: METAMASK_SOLANA_SDK_DISPLAY_NAME,
55
+ walletProviderType: _dynamic_labs_sdk_api_core.WalletProviderEnum.QrCode
56
+ });
51
57
 
52
58
  //#endregion
53
- //#region src/metamask/utils/createMetaMaskSolanaController/createMetaMaskSolanaController.ts
59
+ //#region src/metamask/createMetaMaskSolanaWalletProvider/createMetaMaskSolanaWalletProvider.ts
60
+ const METAMASK_DISPLAY_NAME = "MetaMask";
61
+ const METAMASK_ICON = `${_dynamic_labs_sdk_client_core.DYNAMIC_ICONIC_SPRITE_URL}#metamask`;
54
62
  /**
55
- * Builds a fully-initialised `MetaMaskSolanaController` for the given Dynamic
56
- * client. Drives the `@metamask/connect-solana` SDK through its Wallet
57
- * Standard surface so consumers render their own QR / deep-link UI, and
58
- * subscribes to the SDK core's `display_uri` event at construction time so
59
- * the first URI emission cannot be lost to a subscription race. The wallet
60
- * is created with `skipAutoRegister` so this URI-pairing client does not
61
- * register itself into the global Wallet Standard registry an announced
62
- * MetaMask extension is discovered independently. Dapp metadata is sourced
63
- * from the client's `getAppMetadata`. Browser-only.
64
- * The MetaMask SDK's own verbose logging is tied to the Dynamic client's log
65
- * level, so turning on `debug` logging for the Dynamic SDK also surfaces
66
- * MetaMask's internal SDK trace output.
63
+ * Builds the `SolanaWalletProvider` registered AFTER a successful MetaMask
64
+ * SDK URI pairing. Unlike the EVM facade, MetaMask does not expose a typed
65
+ * RPC surface for Solana, so this drives `invokeMethod` directly against the
66
+ * documented `signMessage` / `signTransaction` / `signAndSendTransaction`
67
+ * methods (see https://docs.metamask.io/metamask-connect/multichain/guides/sign-transactions/
68
+ * and .../send-transactions/), scoped to `solana:<genesisHash>` per CAIP-2
69
+ * MetaMask's multichain session grants every configured network as its own
70
+ * scope up front, so "the active network" is tracked in Dynamic's own
71
+ * last-known-network registry rather than asked of the SDK. Drops `connect`
72
+ * so the provider is filtered out of the wallet picker by
73
+ * `getAvailableWalletProvidersData` mirroring how WalletConnect URI
74
+ * sessions register a signing-only provider.
75
+ *
76
+ * MetaMask's multichain API does not document a batch-signing method for
77
+ * Solana, so `signAllTransactions` signs each transaction with its own
78
+ * `signTransaction` call (sequential wallet prompts) rather than one batch
79
+ * approval.
80
+ *
81
+ * `getConnectedAddresses` and `switchActiveNetwork` route through
82
+ * `resolveActiveMetaMaskScope`/`assertMetaMaskNetworkIsGranted` rather than
83
+ * the registry directly, since every configured network is requested as an
84
+ * *optional* scope -- MetaMask may grant an account for only a subset (see
85
+ * their JSDoc).
86
+ *
87
+ * `switchActiveNetwork`/`disconnectWalletAccount` are local, Dynamic-side
88
+ * actions with no live wallet event to bridge, so they emit `networkChanged`/
89
+ * `disconnected` themselves via `metaMaskEvents` -- otherwise `events` would
90
+ * never fire for MetaMask at all.
67
91
  *
68
92
  * @notInstrumented
69
93
  */
70
- const createMetaMaskSolanaController = async (client) => {
71
- const supportedNetworks = getSupportedNetworks(client);
72
- const { appName, appLogoUrl, appUniversalLink, appNativeLink } = (0, _dynamic_labs_sdk_client_core.getAppMetadata)(client);
73
- const { logger } = (0, _dynamic_labs_sdk_client_core.getCore)(client);
74
- await (0, _dynamic_labs_sdk_metamask.clearMetaMaskSessionStorage)(client);
75
- const listeners = /* @__PURE__ */ new Set();
76
- let latestDisplayUri;
77
- const sdk = await (0, _metamask_connect_solana.createSolanaClient)({
78
- api: { supportedNetworks },
79
- dapp: {
80
- iconUrl: appLogoUrl,
81
- name: appName,
82
- nativeScheme: (0, _dynamic_labs_sdk_client_core.getNativeLinkScheme)({ nativeLink: appNativeLink }),
83
- url: appUniversalLink ?? ""
84
- },
85
- debug: logger.isEnabled("debug"),
86
- skipAutoRegister: true
87
- });
88
- sdk.core.on("display_uri", (uri) => {
89
- latestDisplayUri = uri;
90
- for (const listener of listeners) listener(uri);
91
- });
92
- sdk.core.on("stateChanged", (status) => {
93
- if (status === "connected" || status === "disconnected") latestDisplayUri = void 0;
94
+ const createMetaMaskSolanaWalletProvider = (client) => {
95
+ const metaMaskClientInstanceManager = (0, _dynamic_labs_sdk_metamask_core.getOrCreateMetaMaskClientInstanceManager)(client);
96
+ const serializeTransaction = (transaction) => (0, _dynamic_labs_sdk_client_core.getBuffer)().from(transaction.serialize({
97
+ requireAllSignatures: false,
98
+ verifySignatures: false
99
+ })).toString("base64");
100
+ const deserializeTransaction = ({ base64Transaction, original }) => {
101
+ const bytes = (0, _dynamic_labs_sdk_client_core.getBuffer)().from(base64Transaction, "base64");
102
+ return require_solanaTransferAmount.isVersionedTransaction(original) ? _solana_web3_js.VersionedTransaction.deserialize(bytes) : _solana_web3_js.Transaction.from(bytes);
103
+ };
104
+ const walletProviderKey = getMetaMaskSolanaSdkWalletProviderKey();
105
+ const metaMaskEvents = (0, _dynamic_labs_sdk_metamask_core.createMetaMaskWalletProviderEventEmitter)();
106
+ const getActiveScope = async () => {
107
+ const { networkId } = await (0, _dynamic_labs_sdk_client_core.getActiveNetworkIdFromLastKnownRegistry)({
108
+ client,
109
+ walletProviderKey
110
+ });
111
+ const network = (0, _dynamic_labs_sdk_client.getNetworksData)(client).find((candidate) => candidate.chain === "SOL" && candidate.networkId === networkId);
112
+ (0, _dynamic_labs_sdk_client_core.assertDefined)(network?.genesisHash, `No configured SOL network with a genesis hash matches active network id "${networkId}"`);
113
+ return `solana:${network.genesisHash}`;
114
+ };
115
+ const getConnectedAddresses = async () => {
116
+ const { accounts } = await (0, _dynamic_labs_sdk_metamask_core.resolveActiveMetaMaskScope)({
117
+ chain: "SOL",
118
+ metaMaskClient: await metaMaskClientInstanceManager.getMetaMaskClient(),
119
+ walletProviderKey
120
+ }, client);
121
+ return { addresses: accounts.map((account) => (0, _dynamic_labs_sdk_wallet_connect_core.splitCaip10Token)(account).address) };
122
+ };
123
+ const getActiveNetworkId = async () => (0, _dynamic_labs_sdk_client_core.getActiveNetworkIdFromLastKnownRegistry)({
124
+ client,
125
+ walletProviderKey
94
126
  });
95
- latestDisplayUri = void 0;
96
- const onDisplayUri = (listener) => {
97
- listeners.add(listener);
98
- if (latestDisplayUri !== void 0) listener(latestDisplayUri);
99
- return () => {
100
- listeners.delete(listener);
101
- };
127
+ const switchActiveNetwork = async ({ networkId }) => {
128
+ await (0, _dynamic_labs_sdk_metamask_core.assertMetaMaskNetworkIsGranted)({
129
+ chain: "SOL",
130
+ metaMaskClient: await metaMaskClientInstanceManager.getMetaMaskClient(),
131
+ networkId
132
+ }, client);
133
+ const { networkId: previousNetworkId } = await (0, _dynamic_labs_sdk_client_core.getActiveNetworkIdFromLastKnownRegistry)({
134
+ client,
135
+ walletProviderKey
136
+ });
137
+ await (0, _dynamic_labs_sdk_client_core.switchActiveNetworkInLastKnownRegistry)({
138
+ client,
139
+ networkId,
140
+ walletProviderKey
141
+ });
142
+ if (networkId !== previousNetworkId) metaMaskEvents.emitNetworkChanged({ networkId });
102
143
  };
103
- let inFlightConnect = null;
104
- const connect = () => {
105
- if (inFlightConnect) return inFlightConnect;
106
- inFlightConnect = (async () => {
107
- try {
108
- if (sdk.core.status === "connecting") try {
109
- await sdk.disconnect();
110
- } catch (error) {
111
- (0, _dynamic_labs_sdk_client_core.getCore)(client).logger.debug("[metamask] pre-connect disconnect rejected (expected when aborting a pairing the wallet never accepted)", error);
144
+ const signMessage = async ({ message, walletAccount }) => {
145
+ (0, _dynamic_labs_sdk_client_core.assertDefined)(walletAccount, "Wallet account is required");
146
+ const scope = await getActiveScope();
147
+ return { signature: (await (await metaMaskClientInstanceManager.getMetaMaskClient()).invokeMethod({
148
+ request: {
149
+ method: "signMessage",
150
+ params: {
151
+ account: { address: walletAccount.address },
152
+ message: (0, _dynamic_labs_sdk_client_core.getBuffer)().from(message, "utf-8").toString("base64")
112
153
  }
113
- await require_createWalletProviderFromSolanaStandardWallet.getFeaturesForSolanaStandardWallet(sdk.getWallet())["standard:connect"].connect();
114
- } finally {
115
- inFlightConnect = null;
116
- }
117
- })();
118
- return inFlightConnect;
154
+ },
155
+ scope
156
+ })).signature };
157
+ };
158
+ const signTransaction = async ({ transaction, walletAccount }) => {
159
+ const scope = await getActiveScope();
160
+ return { signedTransaction: deserializeTransaction({
161
+ base64Transaction: (await (await metaMaskClientInstanceManager.getMetaMaskClient()).invokeMethod({
162
+ request: {
163
+ method: "signTransaction",
164
+ params: {
165
+ account: { address: walletAccount.address },
166
+ scope,
167
+ transaction: serializeTransaction(transaction)
168
+ }
169
+ },
170
+ scope
171
+ })).signedTransaction,
172
+ original: transaction
173
+ }) };
174
+ };
175
+ const signAllTransactions = async ({ transactions, walletAccount }) => {
176
+ const signedTransactions = [];
177
+ for (const transaction of transactions) {
178
+ const { signedTransaction } = await signTransaction({
179
+ transaction,
180
+ walletAccount
181
+ });
182
+ signedTransactions.push(signedTransaction);
183
+ }
184
+ return { signedTransactions };
185
+ };
186
+ const signAndSendTransaction = async ({ transaction, walletAccount }) => {
187
+ const scope = await getActiveScope();
188
+ return { signature: (await (await metaMaskClientInstanceManager.getMetaMaskClient()).invokeMethod({
189
+ request: {
190
+ method: "signAndSendTransaction",
191
+ params: {
192
+ account: { address: walletAccount.address },
193
+ scope,
194
+ transaction: serializeTransaction(transaction)
195
+ }
196
+ },
197
+ scope
198
+ })).signature };
199
+ };
200
+ const disconnectWalletAccount = async () => {
201
+ await (0, _dynamic_labs_sdk_metamask_core.disconnectMetaMaskWalletProvider)({
202
+ chain: "SOL",
203
+ walletProviderKey
204
+ }, client);
205
+ metaMaskEvents.emitDisconnected();
206
+ };
207
+ const destroy = async () => {
208
+ metaMaskEvents.cleanupEventEmitter();
119
209
  };
120
210
  return {
121
- clearCachedDisplayUri: () => {
122
- latestDisplayUri = void 0;
211
+ chain: "SOL",
212
+ confirmTransaction: (args) => require_solanaTransferAmount.solanaConfirmTransaction(args, client),
213
+ connect: async () => {
214
+ throw new MetaMaskDirectConnectNotSupportedError();
123
215
  },
124
- connect,
125
- getLatestDisplayUri: () => latestDisplayUri,
126
- onDisplayUri,
127
- sdk
216
+ destroy,
217
+ disconnectWalletAccount,
218
+ get events() {
219
+ return metaMaskEvents.getEventEmitter();
220
+ },
221
+ executeSwapTransaction: (args) => require_solanaTransferAmount.solanaExecuteSwapTransaction(args, client),
222
+ getActiveNetworkId,
223
+ getConnectedAddresses,
224
+ groupKey: (0, _dynamic_labs_sdk_client_core.formatWalletProviderGroupKey)(METAMASK_DISPLAY_NAME),
225
+ key: walletProviderKey,
226
+ metadata: {
227
+ displayName: METAMASK_DISPLAY_NAME,
228
+ icon: METAMASK_ICON
229
+ },
230
+ signAllTransactions,
231
+ signAndSendTransaction,
232
+ signMessage,
233
+ signTransaction,
234
+ switchActiveNetwork,
235
+ transferAmount: (args) => require_solanaTransferAmount.solanaTransferAmount(args, client),
236
+ walletProviderType: _dynamic_labs_sdk_api_core.WalletProviderEnum.QrCode
128
237
  };
129
238
  };
130
239
 
131
240
  //#endregion
132
- //#region src/metamask/utils/getOrCreateMetaMaskSolanaController/getOrCreateMetaMaskSolanaController.ts
133
- const RUNTIME_SERVICE_KEY = "metaMaskSolanaController";
241
+ //#region src/metamask/addMetaMaskSolanaExtension/addMetaMaskSolanaExtension.ts
242
+ const METAMASK_SOLANA_EXTENSION_KEY = "metaMaskSolana";
134
243
  /**
135
- * Per-`DynamicClient` accessor for the lazily-constructed MetaMask Solana
136
- * controller. Wraps `createMetaMaskSolanaController` with the standard
137
- * `runtimeServices` cache so every caller the Wallet Standard
138
- * wallet-provider builder, the `display_uri` subscription helper, and the
139
- * `connectWithMetaMaskUriSolana` URI-returning helper — shares the same
140
- * controller (and therefore the same SDK instance, display-URI cache, and
141
- * listener registry) per Dynamic client.
244
+ * Integrates MetaMask Connect (MetaMask's multichain SDK) with the Dynamic
245
+ * client for Solana, letting users connect MetaMask on platforms where the
246
+ * browser extension isn't availablee.g. scanning a QR code, or opening
247
+ * the MetaMask mobile app from a website or React Native app. Call this
248
+ * once during setup.
142
249
  *
143
- * The cache is **per-Dynamic-client, not per-SDK-instance**:
144
- * `@metamask/connect-solana`'s `createSolanaClient` builds on the shared
145
- * MultichainCore singleton, so when multiple Dynamic clients coexist they
146
- * end up sharing the same MetaMask session regardless of this cache. The
147
- * wrapper exists to own the controller's `display_uri` cache and listener
148
- * registry per Dynamic client, which the SDK itself does not expose.
250
+ * @example
251
+ * ```ts
252
+ * const client = createDynamicClient({ environmentId: '...' });
149
253
  *
254
+ * addMetaMaskSolanaExtension(client);
255
+ * ```
256
+ * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
257
+ * @returns void
258
+ * @see connectWithMetaMaskUriSolana
259
+ * @see addSolanaWalletStandardExtension
150
260
  * @notInstrumented
151
261
  */
152
- const getOrCreateMetaMaskSolanaController = (0, _dynamic_labs_sdk_client_core.createRuntimeServiceAccessKey)(RUNTIME_SERVICE_KEY, (client) => createMetaMaskSolanaController(client));
262
+ const addMetaMaskSolanaExtension = (client = (0, _dynamic_labs_sdk_client_core.getDefaultClient)()) => {
263
+ if ((0, _dynamic_labs_sdk_client_core.hasExtension)({ extensionKey: METAMASK_SOLANA_EXTENSION_KEY }, client)) return;
264
+ require_solanaTransferAmount.registerSolanaNetworkProviderBuilder(client);
265
+ (0, _dynamic_labs_sdk_client_core.registerExtension)({ extensionKey: METAMASK_SOLANA_EXTENSION_KEY }, client);
266
+ (0, _dynamic_labs_sdk_metamask_core.reconcileMetaMaskWalletProvider)({
267
+ walletProviderBuilder: createMetaMaskSolanaWalletProvider,
268
+ walletProviderKey: getMetaMaskSolanaSdkWalletProviderKey()
269
+ }, client);
270
+ };
153
271
 
154
272
  //#endregion
155
- //#region src/metamask/createMetaMaskSolanaWalletProvider/createMetaMaskSolanaWalletProvider.ts
273
+ //#region src/metamask/warnMetaMaskSolanaIntegrationIncomplete/warnMetaMaskSolanaIntegrationIncomplete.ts
156
274
  /**
157
- * Builds the `SolanaWalletProvider` registered AFTER a successful MetaMask
158
- * SDK URI pairing. Wraps the paired Wallet Standard wallet exposed by
159
- * `@metamask/connect-solana` behind the Dynamic Solana provider facade and
160
- * classifies it as `QrCode` so its key does not collide with an announced
161
- * MetaMask browser-extension provider for the same wallet name. Drops
162
- * `connect` so the provider is filtered out of the wallet picker by
163
- * `getAvailableWalletProvidersData` — mirroring how WalletConnect URI
164
- * sessions register a signing-only provider.
275
+ * Warns when `addMetaMaskSolanaExtension()` hasn't been added, since a
276
+ * wallet connected via `connectWithMetaMaskUriSolana` without it won't be
277
+ * restored after a page reload.
165
278
  *
279
+ * @example
280
+ * ```ts
281
+ * warnMetaMaskSolanaIntegrationIncomplete(client);
282
+ * ```
283
+ * @param client - The Dynamic client instance.
284
+ * @returns void
285
+ * @see connectWithMetaMaskUriSolana
286
+ * @see addMetaMaskSolanaExtension
166
287
  * @notInstrumented
167
288
  */
168
- const createMetaMaskSolanaWalletProvider = async (client) => {
169
- const walletStandardWallet = (await getOrCreateMetaMaskSolanaController(client)).sdk.getWallet();
170
- if (walletStandardWallet.accounts.length === 0) throw new _dynamic_labs_sdk_metamask.MetaMaskWalletNotConnectedError();
171
- return {
172
- ...require_createWalletProviderFromSolanaStandardWallet.createWalletProviderFromSolanaStandardWallet({
173
- dynamicClient: client,
174
- walletProviderType: _dynamic_labs_sdk_api_core.WalletProviderEnum.QrCode,
175
- walletStandardWallet
176
- }),
177
- connect: void 0
178
- };
289
+ const warnMetaMaskSolanaIntegrationIncomplete = (client) => {
290
+ if ((0, _dynamic_labs_sdk_client_core.hasExtension)({ extensionKey: METAMASK_SOLANA_EXTENSION_KEY }, client)) return;
291
+ (0, _dynamic_labs_sdk_client_core.getCore)(client).logger.warn(`MetaMask integration is incomplete: addMetaMaskSolanaExtension() is missing. Add it during setup:
292
+
293
+ import { addMetaMaskSolanaExtension } from '@dynamic-labs-sdk/solana/metamask';
294
+ import { createDynamicClient } from '@dynamic-labs-sdk/client';
295
+
296
+ const client = createDynamicClient({ environmentId: '...' });
297
+
298
+ addMetaMaskSolanaExtension(client);`);
179
299
  };
180
300
 
181
301
  //#endregion
@@ -190,11 +310,11 @@ const createMetaMaskSolanaWalletProvider = async (client) => {
190
310
  * @notInstrumented
191
311
  */
192
312
  const connectWithMetaMaskUriSolana = ({ addToDynamicWalletAccounts = true } = {}, client = (0, _dynamic_labs_sdk_client.getDefaultClient)()) => {
313
+ warnMetaMaskSolanaIntegrationIncomplete(client);
193
314
  require_solanaTransferAmount.registerSolanaNetworkProviderBuilder(client);
194
315
  return (0, _dynamic_labs_sdk_metamask.connectWithMetaMaskUri)({
195
316
  addToDynamicWalletAccounts,
196
317
  chain: "SOL",
197
- getController: getOrCreateMetaMaskSolanaController,
198
318
  walletProviderBuilder: createMetaMaskSolanaWalletProvider
199
319
  }, client);
200
320
  };
@@ -245,18 +365,51 @@ const connectAndVerifyWithMetaMaskUriSolana = async (client = (0, _dynamic_labs_
245
365
  */
246
366
  const getMetaMaskSolanaExtensionWalletProviderKey = (client = (0, _dynamic_labs_sdk_client.getDefaultClient)()) => (0, _dynamic_labs_sdk_metamask.getMetaMaskExtensionWalletProviderKey)({ chain: "SOL" }, client);
247
367
 
368
+ //#endregion
369
+ //#region src/metamask/registerMetaMaskSolanaUriConnectionStarter/registerMetaMaskSolanaUriConnectionStarter.ts
370
+ /**
371
+ * Registers the MetaMask SDK URI pairing for Solana with the client, so higher
372
+ * level connection APIs can mint a MetaMask URI for Solana without depending on
373
+ * this package.
374
+ *
375
+ * Call it during app setup to opt into the MetaMask URI path — it is kept out
376
+ * of the Solana extension so apps that never pair with MetaMask over a URI
377
+ * don't bundle the MetaMask SDK.
378
+ *
379
+ * @example
380
+ * ```ts
381
+ * registerMetaMaskSolanaUriConnectionStarter();
382
+ * ```
383
+ *
384
+ * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
385
+ * @returns Nothing.
386
+ * @see connectWithMetaMaskUriSolana
387
+ * @see getUriConnectionStarterRegistry
388
+ * @notInstrumented
389
+ */
390
+ const registerMetaMaskSolanaUriConnectionStarter = (client = (0, _dynamic_labs_sdk_client.getDefaultClient)()) => {
391
+ (0, _dynamic_labs_sdk_client_core.getUriConnectionStarterRegistry)(client).register({
392
+ chain: "SOL",
393
+ start: ({ addToDynamicWalletAccounts }) => connectWithMetaMaskUriSolana({ addToDynamicWalletAccounts }, client),
394
+ type: "metamaskSdkUri"
395
+ });
396
+ };
397
+
248
398
  //#endregion
249
399
  //#region src/exports/metamask.ts
250
400
  (0, _dynamic_labs_sdk_assert_package_version.assertPackageVersion)(require_solanaTransferAmount.name, require_solanaTransferAmount.version);
251
401
 
252
402
  //#endregion
403
+ exports.MetaMaskDirectConnectNotSupportedError = MetaMaskDirectConnectNotSupportedError;
253
404
  Object.defineProperty(exports, 'MetaMaskDisplayUriMissingError', {
254
405
  enumerable: true,
255
406
  get: function () {
256
407
  return _dynamic_labs_sdk_metamask.MetaMaskDisplayUriMissingError;
257
408
  }
258
409
  });
410
+ exports.addMetaMaskSolanaExtension = addMetaMaskSolanaExtension;
259
411
  exports.connectAndVerifyWithMetaMaskUriSolana = connectAndVerifyWithMetaMaskUriSolana;
260
412
  exports.connectWithMetaMaskUriSolana = connectWithMetaMaskUriSolana;
261
413
  exports.getMetaMaskSolanaExtensionWalletProviderKey = getMetaMaskSolanaExtensionWalletProviderKey;
414
+ exports.registerMetaMaskSolanaUriConnectionStarter = registerMetaMaskSolanaUriConnectionStarter;
262
415
  //# sourceMappingURL=metamask.cjs.map