
Security News
GPT-6 Astra Attempts Supply Chain Attacks Against Open Source Maintainers in Testing
GPT-6 Astra hits 100% on ExploitBench and finds zero-days autonomously, while independent tests reveal scope violations and monitoring gaps.
@metamask/connect-multichain
Advanced tools
@metamask/connect-multichainCore multichain connectivity library for MetaMask Connect SDK. Supports multiple blockchain networks including EVM chains (Ethereum, Polygon, etc.) and non-EVM chains (Solana, etc.).
This package provides support for connecting to MetaMask and using the CAIP Multichain API which agnostically supports making requests to multiple blockchain ecosystems simultaneously.
yarn add @metamask/connect-multichain
or
npm install @metamask/connect-multichain
import {
createMultichainClient,
getInfuraRpcUrls,
} from '@metamask/connect-multichain';
const client = await createMultichainClient({
dapp: {
name: 'My DApp',
url: 'https://mydapp.com',
},
api: {
supportedNetworks: {
// use the `getInfuraRpcUrls` helper to generate a map of Infura RPC endpoints
...getInfuraRpcUrls({ infuraApiKey: INFURA_API_KEY }),
// or specify your own CAIP Chain ID to rpc endpoint mapping
'eip155:1': 'https://mainnet.example.io/rpc',
'eip155:137': 'https://polygon-mainnet.example.io/rpc',
},
},
});
// Connect to MetaMask with specific chain scopes
await client.connect(['eip155:1', 'eip155:137'], []);
// Invoke methods on specific chains
const blockNumber = await client.invokeMethod({
scope: 'eip155:1',
request: {
method: 'eth_blockNumber',
params: [],
},
});
import { createMultichainClient } from '@metamask/connect-multichain';
const client = await createMultichainClient({
dapp: {
name: 'My Web DApp',
url: 'https://mydapp.com',
iconUrl: 'https://mydapp.com/icon.png',
},
api: {
supportedNetworks: {
'eip155:1': 'https://mainnet.infura.io/v3/YOUR_KEY',
},
},
ui: {
preferExtension: true, // Prefer browser extension over mobile QR
showInstallModal: false, // Show modal to install extension
headless: false, // Set true for custom QR UI
},
});
import { createMultichainClient } from '@metamask/connect-multichain';
const client = await createMultichainClient({
dapp: {
name: 'My Node App',
url: 'https://mydapp.com',
},
api: {
supportedNetworks: {
'eip155:1': 'https://mainnet.infura.io/v3/YOUR_KEY',
},
},
});
// Connect will display QR code in terminal
await client.connect(['eip155:1'], []);
import { Linking } from 'react-native';
import { createMultichainClient } from '@metamask/connect-multichain';
const client = await createMultichainClient({
dapp: {
name: 'My RN App',
url: 'https://mydapp.com',
},
api: {
supportedNetworks: {
'eip155:1': 'https://mainnet.infura.io/v3/YOUR_KEY',
},
},
mobile: {
preferredOpenLink: (deeplink) => {
Linking.openURL(deeplink);
},
},
});
This package is written in TypeScript and includes full type definitions. No additional @types package is required.
createMultichainClient(options)Factory function to create a new Multichain SDK instance.
Singleton:
createMultichainClientreturns a single shared instance per global context. Calling it a second time with different options will merge the newapi.supportedNetworks,versions,ui.*,mobile.*,transport.extensionId, anddebugvalues into the existing instance rather than creating a new one. Thedappvalue is never overwritten on subsequent calls.
| Option | Type | Required | Description |
|---|---|---|---|
dapp.name | string | Yes | Name of your dApp |
api.supportedNetworks | RpcUrlsMap | Yes | Map of CAIP-2 chain IDs to RPC URLs |
dapp.url | string | No | URL of your dApp |
dapp.iconUrl | string | No | Icon URL for your dApp |
dapp.base64Icon | string | No | Base64-encoded icon (alternative to iconUrl) |
storage | StoreClient | No | Custom storage adapter |
ui.factory | BaseModalFactory | No | Custom modal factory |
ui.headless | boolean | No | Run without UI (for custom QR implementations) |
ui.preferExtension | boolean | No | Prefer browser extension (default: true) |
ui.showInstallModal | boolean | No | Show installation modal |
mobile.preferredOpenLink | (deeplink: string, target?: string) => void | No | Custom deeplink handler |
mobile.useDeeplink | boolean | No | Use metamask:// instead of universal links |
analytics.integrationType | string | No | Integration type for analytics |
transport.extensionId | string | No | Custom extension ID |
transport.onNotification | (notification: unknown) => void | No | Notification handler |
versions | Partial<ConnectVersions> | No | Internal: set automatically by createEVMClient / createSolanaClient. Consumers do not need to provide this. |
debug | boolean | No | Enable debug logging |
Promise<MetaMaskConnectMultichain> - A fully initialized SDK instance.
const client = await createMultichainClient({
dapp: { name: 'My DApp', url: 'https://mydapp.com' },
api: {
supportedNetworks: {
'eip155:1': 'https://mainnet.infura.io/v3/KEY',
'eip155:137': 'https://polygon-mainnet.infura.io/v3/KEY',
},
},
});
MetaMaskConnectMultichainThe main SDK class extending MultichainCore.
connect(scopes, caipAccountIds, sessionProperties?, forceRequest?)Connects to MetaMask with specified chain scopes.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
scopes | Scope[] | Yes | Array of CAIP-2 chain identifiers to request permission for |
caipAccountIds | CaipAccountId[] | Yes | Array of CAIP-10 account identifiers to request (pass [] if no specific accounts should be requested) |
sessionProperties | SessionProperties | No | Additional session properties |
forceRequest | boolean | No | Force a new connection request even if already connected |
Returns
Promise<void>
await client.connect(
['eip155:1', 'eip155:137'], // Chain scopes to request
['eip155:1:0x...'], // Specific accounts to request
);
disconnect(scopes?)Disconnects from the wallet. If scopes are provided, only the specified scopes are revoked; if there are remaining scopes, the connection stays alive. If omitted or empty, all scopes are revoked and the connection is fully torn down.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
scopes | Scope[] | No | Array of CAIP-2 chain identifiers to revoke (defaults to all scopes) |
Returns
Promise<void>
// Fully disconnect
await client.disconnect();
// Disconnect only specific scopes
await client.disconnect(['eip155:1']);
invokeMethod(options)Invokes an RPC method on a specific chain.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
options.scope | Scope | Yes | The CAIP-2 chain identifier to invoke the method on |
options.request.method | string | Yes | The RPC method name |
options.request.params | unknown[] | No | The method parameters |
Returns
Promise<Json> - The result of the RPC method call.
const result = await client.invokeMethod({
scope: 'eip155:1',
request: {
method: 'eth_getBalance',
params: ['0x...', 'latest'],
},
});
| Property | Type | Description |
|---|---|---|
status | ConnectionStatus | Connection status ( 'loaded', 'pending', 'connecting', 'connected', 'disconnected') |
provider | MultichainApiClient | Multichain API client |
transport | ExtendedTransport | Active transport layer |
// Session changes
client.on('wallet_sessionChanged', (session) => {
console.log('Session updated:', session);
});
// QR code display (for custom UI)
client.on('display_uri', (uri) => {
console.log('Display QR code:', uri);
});
// Connection state changes
client.on('stateChanged', (status) => {
console.log('Status:', status);
});
MultichainCoreAbstract base class providing core multichain functionality.
on(event, handler)Registers an event handler.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
event | string | Yes | The event name to listen for |
handler | Function | Yes | The callback function to invoke when the event is emitted |
Returns
void
off(event, handler)Removes an event handler.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
event | string | Yes | The event name to stop listening for |
handler | Function | Yes | The callback function to remove |
Returns
void
emit(event, args)Emits an event to all registered handlers.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
event | string | Yes | The event name to emit |
args | any | No | Arguments to pass to the event handlers |
Returns
void
getInfuraRpcUrls(options)Generates Infura RPC URLs for common networks keyed by CAIP Chain ID.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
infuraApiKey | string | Yes | Your Infura API key |
caipChainIds | CaipChainId[] | No | CAIP-2 chain IDs to filter the output |
Returns
A map of CAIP-2 chain IDs to Infura RPC URLs. See https://docs.metamask.io/services
import { getInfuraRpcUrls } from '@metamask/connect-multichain';
// Get all supported Infura RPC URLs
const rpcUrls = getInfuraRpcUrls({ infuraApiKey: 'YOUR_INFURA_KEY' });
// {
// 'eip155:1': 'https://mainnet.infura.io/v3/YOUR_KEY',
// 'eip155:137': 'https://polygon-mainnet.infura.io/v3/YOUR_KEY',
// 'eip155:11155111': 'https://sepolia.infura.io/v3/YOUR_KEY',
// ...
// }
// Filter to specific chains
const filtered = getInfuraRpcUrls({
infuraApiKey: 'YOUR_INFURA_KEY',
caipChainIds: ['eip155:1', 'eip155:137'],
});
// {
// 'eip155:1': 'https://mainnet.infura.io/v3/YOUR_KEY',
// 'eip155:137': 'https://polygon-mainnet.infura.io/v3/YOUR_KEY',
// }
The package exports various error classes for handling specific error conditions:
ProtocolError - Base protocol errorStorageError - Storage operation errorsRpcError - RPC request errorsimport { ProtocolError } from '@metamask/connect-multichain';
try {
await client.connect(['eip155:1'], []);
} catch (error) {
if (error instanceof ProtocolError) {
console.log('Protocol error:', error.code, error.message);
}
}
For custom QR code implementations, use headless mode:
const client = await createMultichainClient({
dapp: { name: 'My DApp' },
api: { supportedNetworks: { 'eip155:1': 'https://...' } },
ui: { headless: true },
});
// Listen for QR code URIs
client.on('display_uri', (uri) => {
// Display your custom QR code with this URI
displayMyCustomQRCode(uri);
});
await client.connect(['eip155:1'], []);
This package is part of a monorepo. Instructions for contributing can be found in the monorepo README.
MIT
FAQs
MetaMask Connect multichain client — CAIP multichain API, session management, and transport negotiation
The npm package @metamask/connect-multichain receives a total of 63,247 weekly downloads. As such, @metamask/connect-multichain popularity was classified as popular.
We found that @metamask/connect-multichain demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 7 open source maintainers collaborating on the project.

Security News
GPT-6 Astra hits 100% on ExploitBench and finds zero-days autonomously, while independent tests reveal scope violations and monitoring gaps.

Product
Socket can now send alerts and supply chain attack notifications to Microsoft Teams, with filters that route the right updates to each channel.

Security News
pnpm 12 rewrites the package manager in Rust, cutting install times by up to 90% while preserving pnpm 11 workflows and lockfiles.