Mensaje de error
invalid signature length
También se muestra como
- Error: invalid signature length
viem (TypeScript) — recoverMessageAddress / recoverAddress / recoverTypedDataAddress / recoverPublicKey
Qué significa
Las funciones de recuperación de viem aceptan una firma en hex o en bytes de exactamente 65 bytes (r‖s‖v) y, con cualquier otra longitud, se detienen con este `Error` genérico, incluida la forma compacta de 64 bytes de EIP-2098, que viem solo admite mediante funciones auxiliares de conversión explícitas. No se recuperó nada: la firma está en otro formato o ni siquiera es la firma de una EOA (cuenta de propiedad externa).
Por qué ocurre
Una firma compacta de 64 bytes (EIP-2098)
frecuenteAlgunas billeteras, relayers y contratos guardan las firmas en la forma compacta (con yParity integrado en s). ethers la acepta directamente; las funciones `recover*` de viem, no.
Una firma de cuenta inteligente
frecuenteLas firmas ERC-1271 y ERC-6492 de Safe, Coinbase Smart Wallet u otras cuentas inteligentes miden más de 65 bytes y no permiten recuperar una dirección; hay que comprobarlas contra el contrato de la cuenta.
Codificación Base64 o hex doble
ocasionalUna firma transportada en base64, o una cadena hex codificada otra vez como hex, tiene una longitud incorrecta cuando viem la lee.
Cómo solucionarlo
- 1.
Convertir las firmas compactas antes de recuperar
`parseCompactSignature` junto con `compactSignatureToSignature` convierte la forma de 64 bytes en la de 65 bytes.
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.
Usar publicClient.verifyMessage para billeteras en general
Un cliente público verifica las firmas de EOA localmente y las de cuentas inteligentes mediante ERC-1271/ERC-6492, así que el mismo código funciona con cualquier tipo de billetera.
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 });