For AI agents: a documentation index is available at /llms.txt. A markdown version of this page is available at the same URL with .md appended (or via Accept: text/markdown).
Skip to main content

Connect to EVM - Node.js quickstart

Get started with MetaMask Connect EVM 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.

No polyfills required

Node.js has native support for Buffer, crypto, stream, and other modules that require polyfilling in browser or React Native environments.

Prerequisites​

Steps​

1. Install MetaMask Connect EVM​

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

npm install @metamask/connect-evm

2. Initialize MetaMask Connect EVM​

Create a file (index.mjs) and initialize the client using createEVMClient. In Node.js, there is no window.location, so you must set dapp.url explicitly:

index.mjs
import { createEVMClient, getInfuraRpcUrls } from '@metamask/connect-evm'

const evmClient = await createEVMClient({
dapp: {
name: 'My Node.js App',
url: 'https://myapp.com',
},
api: {
supportedNetworks: getInfuraRpcUrls({
infuraApiKey: 'YOUR_INFURA_API_KEY',
}),
},
})
Async client

createEVMClient returns a promise. Always await it before using the client.

3. Connect to MetaMask​

Call connect to start the connection flow. A QR code appears in the terminal. Scan it with the MetaMask mobile app:

try {
const { accounts, chainId } = await evmClient.connect({
chainIds: ['0x1'],
})
console.log('Connected account:', accounts[0])
console.log('Active chain:', chainId)
} catch (error) {
if (error.code === 4001) {
console.log('User rejected the connection request')
} else if (error.code === -32002) {
console.log('Connection request already pending')
} else {
console.error('Connection failed:', error)
}
}

4. Use the provider​

Get the EIP-1193 provider and make JSON-RPC requests:

const provider = evmClient.getProvider()

const balance = await provider.request({
method: 'eth_getBalance',
params: [accounts[0], 'latest'],
})
console.log('Balance (wei):', balance)

5. Sign a message​

Use personal_sign to request a signature from the connected wallet:

const message = '0x' + Buffer.from('Hello from Node.js!', 'utf8').toString('hex')

const signature = await provider.request({
method: 'personal_sign',
params: [message, accounts[0]],
})
console.log('Signature:', signature)

6. Disconnect​

await evmClient.disconnect()
console.log('Disconnected')

Listen for events​

Use eventHandlers in the client configuration to react to connection state changes:

const evmClient = await createEVMClient({
dapp: {
name: 'My Node.js App',
url: 'https://myapp.com',
},
api: {
supportedNetworks: getInfuraRpcUrls({
infuraApiKey: 'YOUR_INFURA_API_KEY',
}),
},
eventHandlers: {
connect: ({ accounts, chainId }) => {
console.log('Connected:', accounts, 'on chain', chainId)
},
disconnect: () => {
console.log('Disconnected')
},
accountsChanged: accounts => {
console.log('Accounts changed:', accounts)
},
chainChanged: chainId => {
console.log('Chain changed:', chainId)
},
},
})

Full example​

index.mjs
import { createEVMClient, getInfuraRpcUrls } from '@metamask/connect-evm'

const evmClient = await createEVMClient({
dapp: {
name: 'My Node.js App',
url: 'https://myapp.com',
},
api: {
supportedNetworks: getInfuraRpcUrls({
infuraApiKey: 'YOUR_INFURA_API_KEY',
}),
},
})

// Connect — scan the QR code with the MetaMask mobile app
const { accounts, chainId } = await evmClient.connect({ chainIds: ['0x1'] })
console.log('Connected:', accounts[0], 'on', chainId)

// Get balance
const provider = evmClient.getProvider()
const balance = await provider.request({
method: 'eth_getBalance',
params: [accounts[0], 'latest'],
})
console.log('Balance:', balance)

// Sign a message
const message = '0x' + Buffer.from('Hello from Node.js!', 'utf8').toString('hex')
const signature = await provider.request({
method: 'personal_sign',
params: [message, accounts[0]],
})
console.log('Signature:', signature)

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

Run it with:

node index.mjs

Next steps​