Message d’erreur
Invalid yParityOrV value
Également affiché sous la forme
- Error: Invalid yParityOrV value
Le comportement diffère selon les bibliothèques : ethers 6 normalise les valeurs de style EIP-155 (35 et plus) et récupère la même signature sans erreur (comme le montre la reproduction) ; pour d’autres valeurs inattendues, comme 5, il lève « invalid v ». Du code qui passe d’ethers à viem peut donc se mettre à échouer sur des signatures qui étaient vérifiées auparavant.
viem (TypeScript) — recoverAddress / recoverMessageAddress / recoverPublicKey
Ce que cela signifie
Le dernier octet de la signature (l’identifiant de récupération) ne fait pas partie des valeurs que viem accepte : 0 ou 1 (`yParity`), ou 27 ou 28 (`v` historique). Les signatures de messages et de données typées utilisent toujours l’une de ces valeurs ; les autres valeurs proviennent des conventions de signature des transactions ou d’erreurs d’ordre des octets. viem s’arrête avant la récupération.
Pourquoi cela se produit
Un v de transaction EIP-155 utilisé pour un message
fréquenteLes transactions historiques (legacy) encodent la chaîne dans v (`chainId * 2 + 35 + yParity`, par exemple 37/38 sur le réseau principal). Du code qui réutilise des fonctions utilitaires de signature de transactions pour des messages, ou qui lit v dans une transaction, produit des valeurs que viem rejette.
Un portefeuille matériel ou une bibliothèque renvoie v différemment
occasionnelleCertaines intégrations de signataires renvoient le bit de récupération sous forme de 0/1 dans un champ séparé, ou ajoutent 27 deux fois. La signature concaténée se termine alors par un octet inattendu.
Composantes concaténées dans le mauvais ordre
occasionnelleAssembler la signature sous la forme v‖r‖s (comme la renvoient certaines API) au lieu de r‖s‖v place un octet aléatoire de s à la position de v.
Comment corriger l’erreur
- 1.
Normaliser v avant la récupération
Convertissez les valeurs EIP-155 et 0/1 en 27/28 (ou en yParity 0/1), et assurez-vous que la signature est assemblée sous la forme 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; }