Skip to content

Latest commit

 

History

History
246 lines (208 loc) · 6.91 KB

File metadata and controls

246 lines (208 loc) · 6.91 KB
description toc_max_heading_level sidebar_custom_props
Use the Multichain API.
4
flask_only
true

Interact with multiple networks

:::flaskOnly :::

You can use the Multichain API to interact with multiple blockchain networks in MetaMask simultaneously. The API allows you to target specific chains as part of each method call, eliminating the need to detect and switch networks before executing signatures and transactions.

:::note See also

Prerequisites

Install MetaMask Flask.

Steps

1. Set up your project

Establish a connection to MetaMask Flask and set up basic message handling using the wallet_notify event:

// Initialize the connection to Flask.
const EXTENSION_ID = "ljfoeinjpaedjfecbmggjgodbgkmjkjk"; // Flask extension ID
const extensionPort = chrome.runtime.connect(EXTENSION_ID)

// Set up message listener for events.
extensionPort.onMessage.addListener((msg) => {
  // Format wallet_notify events to be able to read them later.
  if (msg.data.method === "wallet_notify") {
    console.log("wallet_notify:", {
      scope: msg.data.params.scope,
      method: msg.data.params.notification.method,
      subscription: msg.data.params.notification.params.subscription,
      number: msg.data.params.notification.params.result.number
    })
    return;
  }
  console.log(msg.data)
})

2. Manage sessions

To interact with multiple networks simultaneously, you'll create and manage CAIP-25 multichain sessions with MetaMask.

2.1. Check existing sessions

Before creating a new session, check if one already exists using the wallet_getSession method. For example:

extensionPort.postMessage({
  type: "caip-x",
  data: {
    jsonrpc: "2.0",
      method: "wallet_getSession",
      params: {}
  }
});

If the result returns an empty sessionScopes parameter, then a multichain session is not active and you must create a new session.

2.2. Create a new session

Create a new session using the wallet_createSession method. Specify which chains and methods your dapp needs access to, using the optionalScopes parameter. For example:

extensionPort.postMessage({
  type: "caip-x",
  data: {
    jsonrpc: "2.0",
    method: "wallet_createSession",
    params: {
      optionalScopes: {
        "wallet:eip155": { // General Ethereum wallet functions
          methods: ["wallet_addEthereumChain"],
          notifications: [],
          accounts: []
        },
        "eip155:1": { // Ethereum Mainnet
          methods: [
            "personal_sign",
            "eth_blockNumber",
            "eth_gasPrice",
            "eth_getBalance",
            "eth_getTransactionCount",
            "eth_sendTransaction",
            "eth_subscribe"
          ],
          notifications: ["eth_subscription"],
          accounts: []
        },
        "eip155:59141": { // Linea Sepolia
          methods: [
            "personal_sign",
            "eth_blockNumber",
            "eth_gasPrice",
            "eth_getBalance",
            "eth_getTransactionCount",
            "eth_sendTransaction", 
            "eth_subscribe"
          ],
          notifications: ["eth_subscription"],
          accounts: []
        }
      }
    }
  }
});

In optionalScopes:

  • Request access to networks that your dapp intends to interact with. If a requested network is not configured by the MetaMask user, you might need to add the network.
  • For each network, request access to Wallet API methods that your dapp expects to call at any time. The methods listed in the sessionScope of each Multichain API response indicate which wallet capabilities your dapp can use during the session.

2.3. Check for session changes

To ensure your dapp responds appropriately to changes in the wallet session, such as network or account updates, check for session changes using the wallet_sessionChanged event. Based on the event data, you can determine whether your dapp needs to request additional permissions using wallet_createSession.

extensionPort.onMessage.addListener((msg) => {
  // Check for wallet_sessionChanged events.
  if (msg.data.method === "wallet_sessionChanged") {
    // Update permissions if required.
  }
});

3. Invoke Wallet API methods

You can invoke a subset of the Wallet JSON-RPC API methods on a specified chain using the wallet_invokeMethod Multichain API method. The following are example Wallet API functionalities that are compatible with the Multichain API.

3.1. Sign in with Ethereum

You can implement Sign-In with Ethereum (SIWE) by invoking personal_sign. For example:

// Specify an account that the signature will be requested for.
const address = "0xAddress";
const message = `Sign-in request for ${address} at ${new Date().toLocaleString()}`;

// Invoke the personal_sign Wallet API method.
const sign = await extensionPort.postMessage({
  type: "caip-x",
  data: {
    "jsonrpc": "2.0",
    method: "wallet_invokeMethod",
    params: {
      scope: "eip155:1",
      request: {
        method: "personal_sign",
        params: [message, address],
      }
    }
  }
})

3.2. Check balances

You can read gas token balances by invoking eth_getBalance. For example:

extensionPort.postMessage({
  type: "caip-x",
  data: {
    jsonrpc: "2.0",
    method: "wallet_invokeMethod",
    params: {
      scope: "eip155:1",
      request: {
        method: "eth_getBalance",
        params: ["0xAddress", "latest"],
      }
    }
  }
});

3.3. Send transactions

You can send transactions on a specific network, by invoking eth_sendTransaction. For example:

return extensionPort.postMessage({
  type: "caip-x",
  data: {
    jsonrpc: "2.0",
    method: "wallet_invokeMethod",
    params: {
      // Specify a chain ID where the user has sufficient gas.
      scope: "eip155:1",
      request: {
        method: "eth_sendTransaction",
        params: [{
          from: "0xFromAccount",
          to: "0xToAccount",
          value: "0x0",
          gasLimit: "0x5028",
          maxPriorityFeePerGas: "0x3b9aca00",
          maxFeePerGas: "0x2540be400",
        }]
      }
    }
  }
});