本文へスキップ
ecdsa.com
MetaMask (eth_signTypedData_v3/v4)Web3 ウォレットと署名

エラーメッセージ

Provided chainId "1" must match the active chainId "137"

別の表記

  • Cannot sign messages for chainId "1", because MetaMask is switching networks.

dApps は、これを `eth_signTypedData_v4` からの JSON-RPC エラーとして受け取ります(MetaMask はこのテキストとともにコード -32603 を返します)。数値は、ドメインのチェーン ID とウォレットのチェーン ID です。MetaMask がネットワークを切り替えている間は、リクエストが「Cannot sign messages for chainId …, because MetaMask is switching networks.」で失敗します。

MetaMask (eth_signTypedData_v3/v4) — validation in @metamask/signature-controller

このエラーの意味

型付きデータの EIP-712 `domain.chainId` が、ウォレットが現在接続しているネットワークと異なるため、MetaMask は署名リクエストの表示を拒否しています。このルールはユーザーを守るためのものです。チェーン ID は署名される内容の一部であり、別のチェーン向けの署名はそのチェーンでリプレイされるおそれがあります。最初の数値は dApp の `domain.chainId`、2 番目はウォレットのアクティブなチェーンで、どちらも 10 進数です。

発生する理由

修正方法

  1. 1.

    ウォレットの現在のチェーンからドメインを組み立てる

    署名の直前にチェーン ID を読み取り、そのチェーンにデプロイされている検証用コントラクトを選んでください。

    ts
    const chainId = await walletClient.getChainId();          // viem
    // const chainId = Number(await provider.send("eth_chainId", []));  // ethers / raw EIP-1193
    const domain = { name: "Example DEX", version: "1", chainId, verifyingContract: dexAddressFor(chainId) };
  2. 2.

    または、ウォレットを必要なチェーンに切り替える

    注文や permit が 1 つのチェーンでしか有効でない場合は、まずネットワークの切り替えを要求し(`wallet_switchEthereumChain`)、その後で署名してください。

    ts
    // If the signature is only valid on one chain (the verifying contract lives there), ask the wallet to switch.
    await walletClient.switchChain({ id: 1 });
    const signature = await walletClient.signTypedData({ account, domain, types, primaryType: "Order", message });

関連するエラー

署名エラーデータベースをすべて見る