Mensagem de erro
invalid signature length
Também aparece como
- Error: invalid signature length
viem (TypeScript) — recoverMessageAddress / recoverAddress / recoverTypedDataAddress / recoverPublicKey
O que significa
As funções de recuperação do viem aceitam uma assinatura em hex ou em bytes de exatamente 65 bytes (r‖s‖v) e param com este `Error` simples para qualquer outro comprimento — inclusive a forma compacta de 64 bytes da EIP-2098, que o viem só aceita por meio de funções auxiliares de conversão explícita. Nada foi recuperado; a assinatura está em outro formato ou nem é uma assinatura de EOA.
Por que acontece
Uma assinatura compacta de 64 bytes (EIP-2098)
comumAlgumas carteiras, relayers e contratos armazenam assinaturas na forma compacta (yParity embutido em s). O ethers a aceita diretamente; as funções `recover*` do viem, não.
Uma assinatura de conta inteligente
comumAssinaturas ERC-1271 e ERC-6492 do Safe, da carteira Coinbase Smart Wallet ou de outras contas inteligentes têm mais de 65 bytes e não permitem recuperar um endereço; elas precisam ser verificadas no contrato da conta.
Codificação Base64 ou hex duplo
ocasionalUma assinatura transportada em base64, ou uma string hex codificada de novo como hex, fica com o comprimento errado quando o viem a lê.
Como corrigir
- 1.
Converter assinaturas compactas antes da recuperação
A combinação de `parseCompactSignature` e `compactSignatureToSignature` converte a forma de 64 bytes na 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 carteiras em geral
Um cliente público verifica assinaturas de EOA localmente e assinaturas de contas inteligentes via ERC-1271/ERC-6492, então o mesmo código funciona para qualquer tipo de carteira.
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 });