Mensagem de erro
ambiguous primary types or unused types: "EIP712Domain", "Mail"
Também aparece como
- ambiguous primary types or unused types
Os nomes listados são seus tipos não referenciados. `err.message` acrescenta o valor completo de `types` e a versão do ethers; `err.code` é `INVALID_ARGUMENT`.
ethers v6 (JavaScript) — TypedDataEncoder used by signTypedData / verifyTypedData
O que significa
O ethers deduz o tipo primário dos dados tipados EIP-712 como o único tipo que nenhum outro tipo referencia. No seu objeto `types`, vários tipos não são referenciados, então ele não consegue saber qual está sendo assinado — e, na prática, o tipo a mais é quase sempre `EIP712Domain`. O ethers monta sozinho o tipo do domínio a partir do argumento `domain` e não deve recebê-lo em `types`, enquanto o formato JSON do `eth_signTypedData_v4` (MetaMask, WalletConnect) o inclui.
Por que acontece
O EIP712Domain ficou em types
comumDados tipados copiados de uma requisição para a carteira, de um back-end que gera payloads de `eth_signTypedData_v4` ou de uma fixture de teste incluem `EIP712Domain`. O ethers o trata como um segundo tipo raiz.
Um tipo que nada referencia
ocasionalDefinições de struct que sobraram (por exemplo, de uma versão anterior da mensagem) também são raízes e tornam o tipo primário ambíguo.
Duas structs independentes em um só objeto
ocasionalTipos de mensagens diferentes (Order e Cancel) reunidos em um só objeto `types`. Passe apenas os tipos da mensagem que você assina.
Como corrigir
- 1.
Remover o EIP712Domain antes de chamar o ethers
Retire-o com desestruturação; a assinatura é idêntica à que uma carteira gera para o payload v4, porque o tipo do domínio é derivado dos mesmos campos.
js const { EIP712Domain, ...types } = typedData.types; // ethers derives the domain type itself const signature = await signer.signTypedData(typedData.domain, types, typedData.message); const signer2 = verifyTypedData(typedData.domain, types, typedData.message, signature); - 2.
Conferir o tipo primário deduzido
`TypedDataEncoder.from(types).primaryType` lança o mesmo erro ou retorna o tipo cujo hash o ethers vai calcular — uma verificação rápida para testes.
js import { TypedDataEncoder } from "ethers"; // Inspect what ethers considers the primary type before signing. console.log(TypedDataEncoder.from(types).primaryType);