跳到主要内容
ecdsa.com
viem (TypeScript)Web3 钱包与签名

错误信息

invalid signature length

也可能输出为

  • Error: invalid signature length

viem (TypeScript) — recoverMessageAddress / recoverAddress / recoverTypedDataAddress / recoverPublicKey

含义

viem 的恢复函数只接受恰好 65 字节(r‖s‖v)的十六进制或字节数组签名,遇到其他长度一律抛出这个普通的 `Error`——包括 64 字节的 EIP-2098 紧凑形式,viem 只能通过显式的转换辅助函数支持这种形式。此时没有恢复出任何东西;签名要么是另一种格式,要么根本不是 EOA 签名。

原因

修复方法

  1. 1.

    恢复前先转换紧凑签名

    `parseCompactSignature` 加上 `compactSignatureToSignature` 可以把 64 字节形式转换为 65 字节形式。

    ts
    import { compactSignatureToSignature, parseCompactSignature, recoverMessageAddress, serializeSignature, size } from "viem";
    
    const sig = size(signature) === 64
      ? serializeSignature(compactSignatureToSignature(parseCompactSignature(signature)))
      : signature;
    const signer = await recoverMessageAddress({ message, signature: sig });
  2. 2.

    对各类钱包统一使用 publicClient.verifyMessage

    公共客户端会在本地验证 EOA 签名,并通过 ERC-1271/ERC-6492 验证智能账户签名,因此同一套代码适用于所有类型的钱包。

    ts
    import { createPublicClient, http } from "viem";
    import { mainnet } from "viem/chains";
    
    // Handles EOAs, ERC-1271 smart accounts and ERC-6492 (undeployed) accounts.
    const client = createPublicClient({ chain: mainnet, transport: http(process.env.RPC_URL) });
    const valid = await client.verifyMessage({ address, message, signature });

相关错误

浏览完整的签名错误库