Mensaje de error
Invalid yParityOrV value
También se muestra como
- Error: Invalid yParityOrV value
El comportamiento varía entre bibliotecas: ethers 6 normaliza los valores al estilo EIP-155 (35 o más) y recupera la misma firma sin quejarse (como se ve en la reproducción); con otros valores inesperados, como 5, lanza «invalid v». Por eso, el código que pasa de ethers a viem puede empezar a fallar con firmas que antes se verificaban.
viem (TypeScript) — recoverAddress / recoverMessageAddress / recoverPublicKey
Qué significa
El último byte de la firma (el identificador de recuperación) no es uno de los valores que acepta viem: 0 o 1 (`yParity`), o 27 o 28 (el `v` heredado). Las firmas de mensajes y de datos tipados siempre usan uno de ellos; otros valores provienen de convenciones de firma de transacciones o de errores en el orden de los bytes. viem se detiene antes de la recuperación.
Por qué ocurre
v de transacción EIP-155 usado para un mensaje
frecuenteLas transacciones heredadas codifican la cadena en v (`chainId * 2 + 35 + yParity`, por ejemplo, 37/38 en mainnet). El código que reutiliza funciones auxiliares de firma de transacciones para mensajes, o que lee v de una transacción, produce valores que viem rechaza.
La billetera de hardware o la biblioteca devuelve v de otra forma
ocasionalAlgunas integraciones de firmantes devuelven el bit de recuperación como 0/1 en un campo aparte, o suman 27 dos veces. La firma concatenada termina entonces con un byte inesperado.
Componentes concatenados en el orden incorrecto
ocasionalConstruir la firma como v‖r‖s (tal como la devuelven algunas API) en lugar de r‖s‖v pone un byte arbitrario de s en la posición de v.
Cómo solucionarlo
- 1.
Normalizar v antes de recuperar
Convierte los valores EIP-155 y 0/1 a 27/28 (o a yParity 0/1) y asegúrate de que la firma se ensambla 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; }