跳到主要内容
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。在 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`,第二个是钱包当前的活动链,都是十进制。

原因

修复方法

  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 只在某一条链上有效,就先请求切换网络(`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 });

相关错误

浏览完整的签名错误库