Mensagem de erro
Invalid yParityOrV value
Também aparece como
- Error: Invalid yParityOrV value
O comportamento muda de uma biblioteca para outra: o ethers 6 normaliza valores no estilo da EIP-155 (35 ou mais) e recupera a mesma assinatura sem reclamar (como mostra a reprodução); para outros valores inesperados, como 5, ele lança “invalid v”. Por isso, um código que migra do ethers para o viem pode começar a falhar com assinaturas que antes passavam na verificação.
viem (TypeScript) — recoverAddress / recoverMessageAddress / recoverPublicKey
O que significa
O último byte da assinatura (o identificador de recuperação) não é um dos valores que o viem aceita: 0 ou 1 (`yParity`) ou 27 ou 28 (o `v` legado). Assinaturas de mensagens e de dados tipados sempre usam um desses; outros valores vêm de convenções de assinatura de transações ou de erros na ordem dos bytes. O viem para antes da recuperação.
Por que acontece
O v de uma transação EIP-155 usado em uma mensagem
comumTransações legadas codificam a cadeia no v (`chainId * 2 + 35 + yParity`, por exemplo, 37/38 na mainnet). Um código que reaproveita funções auxiliares de assinatura de transações para mensagens, ou que lê o v de uma transação, produz valores que o viem rejeita.
Carteira de hardware ou biblioteca retorna o v de outra forma
ocasionalAlgumas integrações de signatários retornam o bit de recuperação como 0/1 em um campo separado, ou somam 27 duas vezes. A assinatura concatenada então termina com um byte inesperado.
Componentes concatenados na ordem errada
ocasionalMontar a assinatura como v‖r‖s (como algumas APIs a retornam) em vez de r‖s‖v coloca um byte aleatório de s na posição do v.
Como corrigir
- 1.
Normalizar o v antes da recuperação
Converta os valores EIP-155 e 0/1 em 27/28 (ou em yParity 0/1) e garanta que a assinatura seja montada como r‖s‖v.
ts import { hexToNumber, numberToHex, type Hex } from "viem"; // Message signatures carry v = 27/28 (or 0/1); map EIP-155 style values back. function normaliseV(signature: Hex): Hex { let v = hexToNumber(`0x${signature.slice(130)}`); if (v >= 35) v = ((v - 35) % 2) + 27; // EIP-155: chainId * 2 + 35 + yParity if (v === 0 || v === 1) v += 27; return `${signature.slice(0, 130)}${numberToHex(v).slice(2)}` as Hex; }