エラーメッセージ
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 進数です。
発生する理由
dApp が chainId をハードコードしている
よくあるユーザーが Polygon、Base、Arbitrum などで接続しているのに、`chainId: 1`(またはテストネットワークの ID)でドメインを組み立てているケースです。そのチェーンにいないすべてのユーザーで、署名リクエストが失敗します。
dApp がチェーンを読み取った後でユーザーがネットワークを切り替えた
よくあるdApp が接続時にチェーン ID をキャッシュし、`chainChanged` を監視していませんでした。次の署名リクエストには古い値が入ります。
chainId が文字列で、想定と異なる値として解釈される
ときどきMetaMask が文字列のチェーン ID を 16 進数として解釈するのは、`0x` プレフィックスが付いている場合だけです。`"89"` は 10 進数の 89 であり、Polygon の 0x89(137)ではありません。
修正方法
- 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.
または、ウォレットを必要なチェーンに切り替える
注文や 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 });