> For the complete documentation index, see [llms.txt](/llms.txt).

# Connect to Solana - Node.js quickstart

Get started with MetaMask Connect Solana in a Node.js application. The SDK displays a QR code in the terminal that you scan with the MetaMask mobile app to establish a connection.

Wallet Standard is browser-only

[Wallet Standard](https://github.com/wallet-standard/wallet-standard) features (`getWallet`, `wallet.features[...]`) are designed for browser environments. In Node.js, use the multichain core directly via `client.core.connect` and `client.core.invokeMethod` to interact with Solana.

## Prerequisites

- [Node.js](https://nodejs.org/) version 20 or later installed.
- A package manager installed, such as [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm), [Yarn](https://yarnpkg.com/), or [pnpm](https://pnpm.io/installation).
- The [MetaMask mobile app](https://metamask.io/download/) installed on your phone.
- An [Infura API key](https://docs.infura.io/dashboard/get-started/create-api) from the [Infura dashboard](https://app.infura.io).

## Steps

### 1. Install MetaMask Connect Solana

Install the Solana client in an existing Node.js project:

**npm**

```bash
npm install @metamask/connect-solana

```

**Yarn**

```bash
yarn add @metamask/connect-solana

```

**pnpm**

```bash
pnpm add @metamask/connect-solana

```

**Bun**

```bash
bun add @metamask/connect-solana

```

### 2. Initialize MetaMask Connect Solana

Create a file (`index.mjs`) and initialize the client using [createSolanaClient](/metamask-connect/solana/reference/methods/#createsolanaclient). In Node.js, there is no `window.location`, so you must set `dapp.url` explicitly. The `supportedNetworks` map uses network names (`mainnet`, `devnet`) as keys:

index.mjs

```javascript
import { createSolanaClient, getInfuraRpcUrls } from '@metamask/connect-solana'

const SOLANA_MAINNET = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'

const solanaClient = await createSolanaClient({
  dapp: {
    name: 'My Node.js Solana App',
    url: 'https://myapp.com',
  },
  api: {
    supportedNetworks: getInfuraRpcUrls({
      infuraApiKey: 'YOUR_INFURA_API_KEY',
      networks: ['mainnet'],
    }),
  },
})

```

Async client

`createSolanaClient` returns a promise. Always `await` it before using the client. The client uses a singleton multichain core under the hood; calling it multiple times returns the same underlying session.

### 3. Connect to MetaMask

Register a [wallet_sessionChanged](/metamask-connect/multichain/reference/api/#wallet%5Fsessionchanged) listener to capture session data, then connect with a Solana scope. A QR code appears in the terminal. Scan it with the MetaMask mobile app:

```javascript
let session
solanaClient.core.on('wallet_sessionChanged', s => {
  session = s
})

await solanaClient.core.connect([SOLANA_MAINNET], [])

const accounts = session?.sessionScopes?.[SOLANA_MAINNET]?.accounts ?? []
const address = accounts[0]?.split(':').pop()
console.log('Connected:', address)

```

### 4. Sign a message

Use [invokeMethod](/metamask-connect/multichain/reference/methods/#invokemethod) to call the `signMessage` method on the Solana scope:

```javascript
const message = Buffer.from('Hello from Node.js!', 'utf8').toString('base64')

const result = await solanaClient.core.invokeMethod({
  scope: SOLANA_MAINNET,
  request: {
    method: 'signMessage',
    params: {
      account: { address },
      message,
    },
  },
})
console.log('Signature:', result.signature)

```

### 5. Disconnect

Use [disconnect](/metamask-connect/solana/reference/methods/#disconnect) to revoke the Solana scopes. Any EVM or other scopes in the same multichain session stay active.

```javascript
await solanaClient.disconnect()
console.log('Disconnected')

```

## Listen for session events

[Step 3](#3-connect-to-metamask) captures the session with a minimal `wallet_sessionChanged` listener. For production use, expand the handler to track account changes throughout the session lifecycle:

```javascript
solanaClient.core.on('wallet_sessionChanged', session => {
  if (session?.sessionScopes) {
    const solanaAccounts = session.sessionScopes[SOLANA_MAINNET]?.accounts ?? []
    console.log('Solana accounts:', solanaAccounts)
  } else {
    console.log('Session ended')
  }
})

```

## Solana CAIP-2 scope reference

| Network | CAIP-2 scope                              |
| ------- | ----------------------------------------- |
| Mainnet | `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` |
| Devnet  | `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1` |
| Testnet | `solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z` |

note

Devnet and testnet are supported only in the MetaMask browser extension. On mobile (including the QR code flow in this quickstart), only Solana mainnet is supported.

## Full example

index.mjs

```javascript
import { createSolanaClient, getInfuraRpcUrls } from '@metamask/connect-solana'

const SOLANA_MAINNET = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'

const solanaClient = await createSolanaClient({
  dapp: {
    name: 'My Node.js Solana App',
    url: 'https://myapp.com',
  },
  api: {
    supportedNetworks: getInfuraRpcUrls({
      infuraApiKey: 'YOUR_INFURA_API_KEY',
      networks: ['mainnet'],
    }),
  },
})

// Capture session data via event before connecting
let session
solanaClient.core.on('wallet_sessionChanged', s => {
  session = s
})

// Connect — scan the QR code with the MetaMask mobile app
await solanaClient.core.connect([SOLANA_MAINNET], [])

const accounts = session?.sessionScopes?.[SOLANA_MAINNET]?.accounts ?? []
const address = accounts[0]?.split(':').pop()
console.log('Connected:', address)

// Sign a message
const message = Buffer.from('Hello from Node.js!', 'utf8').toString('base64')
const result = await solanaClient.core.invokeMethod({
  scope: SOLANA_MAINNET,
  request: {
    method: 'signMessage',
    params: {
      account: { address },
      message,
    },
  },
})
console.log('Signature:', result.signature)

// Disconnect
await solanaClient.disconnect()
console.log('Disconnected')

```

Run it with:

```bash
node index.mjs

```

## Next steps

- [Send a legacy Solana transaction.](/metamask-connect/solana/guides/send-transactions/legacy/)
- [Send a versioned Solana transaction.](/metamask-connect/solana/guides/send-transactions/versioned/)
- [Sign a Solana message.](/metamask-connect/solana/guides/sign-data/sign-message/)
- [Use the multichain client](/metamask-connect/multichain/quickstart/nodejs/) to connect to both EVM and Solana from a single session.
