Mensagem de erro
Invalid primary type `Email` must be one of `["EIP712Domain","Mail"]`.
Os nomes entre crases são o seu `primaryType` e os tipos disponíveis. O viem 2.57 lança o erro com `err.name` “BaseError”; `err.shortMessage` é o texto acima, e `err.message` acrescenta uma dica, um link para a documentação (“typeddatainvalidprimarytypeerror”) e a versão do viem.
viem (TypeScript) — hashTypedData / signTypedData / verifyTypedData / recoverTypedDataAddress
O que significa
O `primaryType` que você passou não é uma chave de `types` (o viem acrescenta `EIP712Domain` à lista que exibe). A EIP-712 calcula o hash da mensagem como uma instância do tipo primário, então o viem se recusa a adivinhar. Os dados tipados em si podem estar corretos; o que não existe neles é o nome da struct que está sendo assinada.
Por que acontece
A struct foi renomeada de um dos lados
comumO contrato ou o back-end renomeou `Mail` para `Email` (ou `Order` para `OrderV2`), e o front-end ainda envia o nome antigo — ou o contrário. Como o nome do tipo faz parte do hash do tipo, os dois lados precisam mudar juntos de qualquer forma.
primaryType omitido ou indefinido
ocasionalPayloads montados dinamicamente (por exemplo, a partir de JSON) em que `primaryType` nunca foi definido produzem `Invalid primary type \`undefined\``.
Diferença entre maiúsculas e minúsculas
ocasional`mail` versus `Mail`: na EIP-712, os nomes de tipo diferenciam maiúsculas de minúsculas.
Como corrigir
- 1.
Declarar os tipos com as const
Com `as const`, os tipos do viem transformam `primaryType` em uma união dos nomes das suas structs, então uma divergência falha na compilação, e não no momento da assinatura.
ts const types = { Mail: [ { name: "to", type: "address" }, { name: "contents", type: "string" }, ], } as const; // "as const" lets TypeScript reject a wrong primaryType at compile time const signature = await walletClient.signTypedData({ account, domain, types, primaryType: "Mail", message });