@metamask/connect-solana 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,17 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0]
11
+
12
+ ### Added
13
+
14
+ - Initial release
15
+
16
+ [Unreleased]: https://github.com/MetaMask/connect-monorepo/compare/@metamask/connect-solana@0.1.0...HEAD
17
+ [0.1.0]: https://github.com/MetaMask/connect-monorepo/releases/tag/@metamask/connect-solana@0.1.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MetaMask
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,136 @@
1
+ # `@metamask/connect-solana`
2
+
3
+ > Solana wallet-standard integration for connecting to MetaMask via the Multichain API.
4
+
5
+ `@metamask/connect-solana` provides a seamless way to integrate MetaMask as a Solana wallet in your dapp using the [wallet-standard](https://github.com/wallet-standard/wallet-standard) protocol. It wraps `@metamask/solana-wallet-standard` with MetaMask Connect to handle wallet discovery and session management automatically.
6
+
7
+ ## Features
8
+
9
+ - **Wallet Standard Compatible** - Automatically registers MetaMask with the wallet-standard registry
10
+ - **Seamless Integration** - Works with `@solana/wallet-adapter-react` out of the box
11
+ - **Session Management** - Handles session creation and revocation internally
12
+ - **Cross-Platform Support** - Works with browser extensions and mobile applications
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ yarn add @metamask/connect-solana
18
+ ```
19
+
20
+ or
21
+
22
+ ```bash
23
+ npm install @metamask/connect-solana
24
+ ```
25
+
26
+ ## Quick Start
27
+
28
+ ```typescript
29
+ import { createSolanaClient } from '@metamask/connect-solana';
30
+
31
+ // Create a Solana client
32
+ const client = await createSolanaClient({
33
+ dapp: {
34
+ name: 'My Solana DApp',
35
+ url: 'https://mydapp.com',
36
+ },
37
+ });
38
+
39
+ // Register MetaMask with the wallet-standard registry
40
+ // This makes MetaMask automatically discoverable by Solana dapps
41
+ await client.registerWallet();
42
+ ```
43
+
44
+ ## Usage with Solana Wallet Adapter
45
+
46
+ The most common use case is integrating with `@solana/wallet-adapter-react`:
47
+
48
+ ```tsx
49
+ import {
50
+ ConnectionProvider,
51
+ WalletProvider,
52
+ } from '@solana/wallet-adapter-react';
53
+ import {
54
+ WalletModalProvider,
55
+ WalletMultiButton,
56
+ } from '@solana/wallet-adapter-react-ui';
57
+ import { createSolanaClient } from '@metamask/connect-solana';
58
+ import { useEffect } from 'react';
59
+
60
+ import '@solana/wallet-adapter-react-ui/styles.css';
61
+
62
+ function App() {
63
+ useEffect(() => {
64
+ // Register MetaMask wallet on app initialization
65
+ createSolanaClient({
66
+ dapp: {
67
+ name: 'My Solana DApp',
68
+ url: window.location.origin,
69
+ },
70
+ }).then((client) => {
71
+ client.registerWallet();
72
+ });
73
+ }, []);
74
+
75
+ return (
76
+ <ConnectionProvider endpoint="https://api.devnet.solana.com">
77
+ <WalletProvider wallets={[]} autoConnect>
78
+ <WalletModalProvider>
79
+ <WalletMultiButton />
80
+ {/* Your app content */}
81
+ </WalletModalProvider>
82
+ </WalletProvider>
83
+ </ConnectionProvider>
84
+ );
85
+ }
86
+ ```
87
+
88
+ ## API Reference
89
+
90
+ ### `createSolanaClient(options)`
91
+
92
+ Creates a new Solana client instance.
93
+
94
+ #### Parameters
95
+
96
+ - `options.dapp.name` (required) - The name of your dapp
97
+ - `options.dapp.url` (optional) - The URL of your dapp
98
+ - `options.dapp.iconUrl` (optional) - The icon URL of your dapp
99
+ - `options.api.supportedNetworks` (optional) - Map of CAIP chain IDs to RPC URLs
100
+ - `options.debug` (optional) - Enable debug logging
101
+
102
+ #### Returns
103
+
104
+ A `SolanaClient` object with:
105
+
106
+ - `core` - The underlying MultichainCore instance
107
+ - `getWallet(walletName?)` - Returns a wallet-standard compatible wallet
108
+ - `registerWallet(walletName?)` - Registers the wallet with the wallet-standard registry
109
+ - `disconnect()` - Disconnects and revokes the session
110
+
111
+ ## TypeScript
112
+
113
+ This package is written in TypeScript and includes full type definitions.
114
+
115
+ ## Development
116
+
117
+ This package is part of the MetaMask Connect monorepo. From the repo root:
118
+
119
+ ```bash
120
+ # Build the package
121
+ yarn workspace @metamask/connect-solana run build
122
+
123
+ # Run tests
124
+ yarn workspace @metamask/connect-solana run test
125
+
126
+ # Run linting
127
+ yarn workspace @metamask/connect-solana run lint
128
+ ```
129
+
130
+ ## Contributing
131
+
132
+ This package is part of a monorepo. Instructions for contributing can be found in the [monorepo README](https://github.com/MetaMask/connect-monorepo#readme).
133
+
134
+ ## License
135
+
136
+ MIT
@@ -0,0 +1,80 @@
1
+ var __async = (__this, __arguments, generator) => {
2
+ return new Promise((resolve, reject) => {
3
+ var fulfilled = (value) => {
4
+ try {
5
+ step(generator.next(value));
6
+ } catch (e) {
7
+ reject(e);
8
+ }
9
+ };
10
+ var rejected = (value) => {
11
+ try {
12
+ step(generator.throw(value));
13
+ } catch (e) {
14
+ reject(e);
15
+ }
16
+ };
17
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
18
+ step((generator = generator.apply(__this, __arguments)).next());
19
+ });
20
+ };
21
+
22
+ // src/connect.ts
23
+ import { createMultichainClient } from "@metamask/connect-multichain";
24
+ import {
25
+ getWalletStandard,
26
+ registerSolanaWalletStandard
27
+ } from "@metamask/solana-wallet-standard";
28
+
29
+ // src/networks.ts
30
+ var SOLANA_CAIP_IDS = {
31
+ mainnet: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
32
+ devnet: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
33
+ testnet: "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z"
34
+ };
35
+ function convertNetworksToCAIP(networks) {
36
+ return Object.entries(networks).reduce(
37
+ (acc, [network, rpcUrl]) => {
38
+ const caipId = SOLANA_CAIP_IDS[network];
39
+ if (caipId && rpcUrl) {
40
+ acc[caipId] = rpcUrl;
41
+ }
42
+ return acc;
43
+ },
44
+ {}
45
+ );
46
+ }
47
+
48
+ // src/connect.ts
49
+ function createSolanaClient(options) {
50
+ return __async(this, null, function* () {
51
+ var _a, _b;
52
+ const defaultNetworks = {
53
+ mainnet: "https://api.mainnet-beta.solana.com"
54
+ };
55
+ const supportedNetworks = convertNetworksToCAIP(
56
+ (_b = (_a = options.api) == null ? void 0 : _a.supportedNetworks) != null ? _b : defaultNetworks
57
+ );
58
+ const core = yield createMultichainClient({
59
+ dapp: options.dapp,
60
+ api: {
61
+ supportedNetworks
62
+ }
63
+ });
64
+ const client = core.provider;
65
+ return {
66
+ core,
67
+ getWallet: (walletName) => getWalletStandard({ client, walletName }),
68
+ registerWallet: (walletName = "MetaMask Connect") => __async(null, null, function* () {
69
+ return registerSolanaWalletStandard({ client, walletName });
70
+ }),
71
+ disconnect: () => __async(null, null, function* () {
72
+ return yield core.disconnect();
73
+ })
74
+ };
75
+ });
76
+ }
77
+ export {
78
+ createSolanaClient
79
+ };
80
+ //# sourceMappingURL=connect-solana.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/connect.ts","../../../src/networks.ts"],"sourcesContent":["import { createMultichainClient } from '@metamask/connect-multichain';\nimport {\n getWalletStandard,\n registerSolanaWalletStandard,\n} from '@metamask/solana-wallet-standard';\n\nimport { convertNetworksToCAIP } from './networks';\nimport type {\n SolanaClient,\n SolanaConnectOptions,\n SolanaSupportedNetworks,\n} from './types';\n\n/**\n * Creates a new Solana client for connecting to MetaMask via wallet-standard.\n *\n * This function initializes the MultichainSDK and provides methods to get or register\n * a wallet-standard compatible wallet. The wallet handles session creation internally\n * when users connect through the Solana wallet adapter UI.\n *\n * @param options - Configuration options for the Solana client\n * @param options.dapp - Dapp identification and branding settings\n * @param options.api - Optional API configuration with supported networks\n * @param options.api.supportedNetworks - Record mapping network names (mainnet, devnet, testnet) to RPC URLs\n * @param options.debug - Enable debug logging\n * @returns A promise that resolves to the Solana client instance\n *\n * @example\n * ```typescript\n * import { createSolanaClient } from '@metamask/connect-solana';\n *\n * const client = await createSolanaClient({\n * dapp: {\n * name: 'My Solana DApp',\n * url: 'https://mydapp.com',\n * },\n * api: {\n * supportedNetworks: {\n * mainnet: 'https://api.mainnet-beta.solana.com',\n * devnet: 'https://api.devnet.solana.com',\n * },\n * },\n * });\n *\n * // Register the wallet to make it discoverable by Solana dapps\n * await client.registerWallet();\n *\n * // Or get the wallet instance directly\n * const wallet = client.getWallet();\n * ```\n */\nexport async function createSolanaClient(\n options: SolanaConnectOptions,\n): Promise<SolanaClient> {\n const defaultNetworks: SolanaSupportedNetworks = {\n mainnet: 'https://api.mainnet-beta.solana.com',\n };\n\n const supportedNetworks = convertNetworksToCAIP(\n options.api?.supportedNetworks ?? defaultNetworks,\n );\n\n const core = await createMultichainClient({\n dapp: options.dapp,\n api: {\n supportedNetworks,\n },\n });\n\n const client = core.provider;\n\n return {\n core,\n getWallet: (walletName?: string) =>\n getWalletStandard({ client, walletName }),\n registerWallet: async (walletName = 'MetaMask Connect') =>\n registerSolanaWalletStandard({ client, walletName }),\n disconnect: async () => await core.disconnect(),\n };\n}\n","import type { SolanaNetwork, SolanaSupportedNetworks } from './types';\n\n/**\n * CAIP-2 chain IDs for Solana networks.\n * The reference is the first 32 characters of the Base58-encoded genesis hash.\n */\nexport const SOLANA_CAIP_IDS: Record<SolanaNetwork, string> = {\n mainnet: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',\n devnet: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',\n testnet: 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z',\n};\n\n/**\n * Converts a record of network names to RPC URLs into a record of CAIP IDs to RPC URLs.\n *\n * @param networks - A record of network names to RPC URLs\n * @returns A record of CAIP IDs to RPC URLs\n */\nexport function convertNetworksToCAIP(\n networks: SolanaSupportedNetworks,\n): Record<string, string> {\n return Object.entries(networks).reduce<Record<string, string>>(\n (acc, [network, rpcUrl]) => {\n const caipId = SOLANA_CAIP_IDS[network as SolanaNetwork];\n if (caipId && rpcUrl) {\n acc[caipId] = rpcUrl;\n }\n return acc;\n },\n {},\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,8BAA8B;AACvC;AAAA,EACE;AAAA,EACA;AAAA,OACK;;;ACEA,IAAM,kBAAiD;AAAA,EAC5D,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AACX;AAQO,SAAS,sBACd,UACwB;AACxB,SAAO,OAAO,QAAQ,QAAQ,EAAE;AAAA,IAC9B,CAAC,KAAK,CAAC,SAAS,MAAM,MAAM;AAC1B,YAAM,SAAS,gBAAgB,OAAwB;AACvD,UAAI,UAAU,QAAQ;AACpB,YAAI,MAAM,IAAI;AAAA,MAChB;AACA,aAAO;AAAA,IACT;AAAA,IACA,CAAC;AAAA,EACH;AACF;;;ADoBA,SAAsB,mBACpB,SACuB;AAAA;AArDzB;AAsDE,UAAM,kBAA2C;AAAA,MAC/C,SAAS;AAAA,IACX;AAEA,UAAM,oBAAoB;AAAA,OACxB,mBAAQ,QAAR,mBAAa,sBAAb,YAAkC;AAAA,IACpC;AAEA,UAAM,OAAO,MAAM,uBAAuB;AAAA,MACxC,MAAM,QAAQ;AAAA,MACd,KAAK;AAAA,QACH;AAAA,MACF;AAAA,IACF,CAAC;AAED,UAAM,SAAS,KAAK;AAEpB,WAAO;AAAA,MACL;AAAA,MACA,WAAW,CAAC,eACV,kBAAkB,EAAE,QAAQ,WAAW,CAAC;AAAA,MAC1C,gBAAgB,CAAO,aAAa,uBAAoB;AACtD,4CAA6B,EAAE,QAAQ,WAAW,CAAC;AAAA;AAAA,MACrD,YAAY,MAAS;AAAG,qBAAM,KAAK,WAAW;AAAA;AAAA,IAChD;AAAA,EACF;AAAA;","names":[]}
@@ -0,0 +1,102 @@
1
+ import { MultichainOptions, MultichainCore } from '@metamask/connect-multichain';
2
+ import { Wallet } from '@wallet-standard/base';
3
+
4
+ /**
5
+ * Solana network names supported by the client.
6
+ */
7
+ type SolanaNetwork = 'mainnet' | 'devnet' | 'testnet';
8
+ /**
9
+ * A record mapping Solana network names to their RPC URLs.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const networks: SolanaSupportedNetworks = {
14
+ * mainnet: 'https://api.mainnet-beta.solana.com',
15
+ * devnet: 'https://api.devnet.solana.com',
16
+ * };
17
+ * ```
18
+ */
19
+ type SolanaSupportedNetworks = Partial<Record<SolanaNetwork, string>>;
20
+ /**
21
+ * Configuration options for creating a Solana client.
22
+ *
23
+ * Derived from MultichainOptions to ensure consistency with the core SDK.
24
+ */
25
+ type SolanaConnectOptions = Pick<MultichainOptions, 'dapp'> & {
26
+ /**
27
+ * Optional API configuration.
28
+ * Maps network names (mainnet, devnet, testnet) to RPC URLs.
29
+ */
30
+ api?: {
31
+ supportedNetworks?: SolanaSupportedNetworks;
32
+ };
33
+ /** Enable debug logging */
34
+ debug?: boolean;
35
+ };
36
+ /**
37
+ * The Solana client instance returned by createSolanaClient.
38
+ */
39
+ type SolanaClient = {
40
+ /** The underlying MultichainCore instance */
41
+ core: MultichainCore;
42
+ /**
43
+ * Gets a wallet-standard compatible wallet instance.
44
+ *
45
+ * @param walletName - Optional custom name for the wallet
46
+ * @returns The wallet instance
47
+ */
48
+ getWallet: (walletName?: string) => Wallet;
49
+ /**
50
+ * Registers the MetaMask wallet with the wallet-standard registry.
51
+ * This makes MetaMask automatically discoverable by Solana dapps.
52
+ *
53
+ * @param walletName - Optional custom name for the wallet
54
+ */
55
+ registerWallet: (walletName?: string) => Promise<void>;
56
+ /**
57
+ * Disconnects from the wallet and revokes the session.
58
+ */
59
+ disconnect: () => Promise<void>;
60
+ };
61
+
62
+ /**
63
+ * Creates a new Solana client for connecting to MetaMask via wallet-standard.
64
+ *
65
+ * This function initializes the MultichainSDK and provides methods to get or register
66
+ * a wallet-standard compatible wallet. The wallet handles session creation internally
67
+ * when users connect through the Solana wallet adapter UI.
68
+ *
69
+ * @param options - Configuration options for the Solana client
70
+ * @param options.dapp - Dapp identification and branding settings
71
+ * @param options.api - Optional API configuration with supported networks
72
+ * @param options.api.supportedNetworks - Record mapping network names (mainnet, devnet, testnet) to RPC URLs
73
+ * @param options.debug - Enable debug logging
74
+ * @returns A promise that resolves to the Solana client instance
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * import { createSolanaClient } from '@metamask/connect-solana';
79
+ *
80
+ * const client = await createSolanaClient({
81
+ * dapp: {
82
+ * name: 'My Solana DApp',
83
+ * url: 'https://mydapp.com',
84
+ * },
85
+ * api: {
86
+ * supportedNetworks: {
87
+ * mainnet: 'https://api.mainnet-beta.solana.com',
88
+ * devnet: 'https://api.devnet.solana.com',
89
+ * },
90
+ * },
91
+ * });
92
+ *
93
+ * // Register the wallet to make it discoverable by Solana dapps
94
+ * await client.registerWallet();
95
+ *
96
+ * // Or get the wallet instance directly
97
+ * const wallet = client.getWallet();
98
+ * ```
99
+ */
100
+ declare function createSolanaClient(options: SolanaConnectOptions): Promise<SolanaClient>;
101
+
102
+ export { type SolanaClient, type SolanaConnectOptions, type SolanaNetwork, type SolanaSupportedNetworks, createSolanaClient };
package/package.json ADDED
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "@metamask/connect-solana",
3
+ "version": "0.1.0",
4
+ "description": "Solana Layer for MetaMask Connect",
5
+ "keywords": [
6
+ "MetaMask",
7
+ "Solana"
8
+ ],
9
+ "homepage": "https://github.com/MetaMask/connect-monorepo/tree/main/packages/connect-solana#readme",
10
+ "bugs": {
11
+ "url": "https://github.com/MetaMask/connect-monorepo/issues"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/MetaMask/connect-monorepo.git"
16
+ },
17
+ "license": "MIT",
18
+ "sideEffects": false,
19
+ "exports": {
20
+ ".": {
21
+ "import": {
22
+ "types": "./dist/types/index.d.ts",
23
+ "default": "./dist/browser/es/connect-solana.mjs"
24
+ },
25
+ "require": {
26
+ "types": "./dist/types/index.d.ts",
27
+ "default": "./dist/browser/es/connect-solana.mjs"
28
+ },
29
+ "default": "./dist/browser/es/connect-solana.mjs"
30
+ },
31
+ "./package.json": "./package.json"
32
+ },
33
+ "main": "./dist/browser/es/connect-solana.mjs",
34
+ "module": "./dist/browser/es/connect-solana.mjs",
35
+ "browser": "./dist/browser/es/connect-solana.mjs",
36
+ "types": "./dist/types/index.d.ts",
37
+ "files": [
38
+ "dist/"
39
+ ],
40
+ "scripts": {
41
+ "build": "yarn tsup",
42
+ "build:docs": "typedoc",
43
+ "changelog:format": "../../scripts/format-changelog.sh @metamask/connect-solana",
44
+ "changelog:update": "../../scripts/update-changelog.sh @metamask/connect-solana",
45
+ "changelog:validate": "../../scripts/validate-changelog.sh @metamask/connect-solana",
46
+ "clean": "npx rimraf ./dist",
47
+ "dev": "tsup --watch",
48
+ "publish:preview": "yarn npm publish --tag preview",
49
+ "since-latest-release": "../../scripts/since-latest-release.sh",
50
+ "test": "vitest run",
51
+ "test:ci": "vitest run --coverage --coverage.reporter=text --silent",
52
+ "test:unit": "vitest run",
53
+ "test:verbose": "vitest run --reporter=verbose",
54
+ "test:watch": "vitest watch"
55
+ },
56
+ "dependencies": {
57
+ "@metamask/connect-multichain": "^0.5.3",
58
+ "@metamask/solana-wallet-standard": "^0.6.0",
59
+ "@wallet-standard/base": "^1.1.0"
60
+ },
61
+ "devDependencies": {
62
+ "@metamask/auto-changelog": "^3.4.4",
63
+ "@types/jsdom": "^21.1.7",
64
+ "@vitest/coverage-v8": "^3.2.4",
65
+ "jsdom": "^26.1.0",
66
+ "prettier": "^3.3.3",
67
+ "tsup": "^8.4.0",
68
+ "typedoc": "^0.28.14",
69
+ "typedoc-plugin-missing-exports": "^4.1.2",
70
+ "typescript": "^5.9.3",
71
+ "vitest": "^3.1.2"
72
+ },
73
+ "engines": {
74
+ "node": ">=20.19.0"
75
+ },
76
+ "publishConfig": {
77
+ "access": "public",
78
+ "registry": "https://registry.npmjs.org/"
79
+ }
80
+ }