Mensaje de error
ambiguous primary types or unused types: "EIP712Domain", "Mail"
También se muestra como
- ambiguous primary types or unused types
Los nombres de la lista son tus tipos sin referencias. `err.message` añade el valor completo de `types` y la versión de ethers; `err.code` es `INVALID_ARGUMENT`.
ethers v6 (JavaScript) — TypedDataEncoder used by signTypedData / verifyTypedData
Qué significa
ethers deduce el tipo principal de los datos tipados EIP-712 como el único tipo al que no hace referencia ningún otro. En tu objeto `types` hay varios tipos sin referencias, así que no puede saber cuál se está firmando; en la práctica, el que sobra casi siempre es `EIP712Domain`. ethers construye el tipo de dominio por su cuenta a partir del argumento `domain` y no debe recibirlo en `types`, mientras que el formato JSON de `eth_signTypedData_v4` (MetaMask, WalletConnect) sí lo incluye.
Por qué ocurre
EIP712Domain incluido en types
frecuenteLos datos tipados copiados de una solicitud de billetera, de un backend que genera cargas útiles de `eth_signTypedData_v4` o de un archivo de datos de prueba incluyen `EIP712Domain`. ethers lo trata como un segundo tipo raíz.
Un tipo al que nada hace referencia
ocasionalLas definiciones de estructuras sobrantes (por ejemplo, de una versión anterior del mensaje) también son raíces y hacen ambiguo el tipo principal.
Dos estructuras independientes en un mismo objeto
ocasionalTipos de mensajes distintos (Order y Cancel) combinados en un mismo objeto `types`. Pasa solo los tipos del mensaje que firmas.
Cómo solucionarlo
- 1.
Quitar EIP712Domain antes de llamar a ethers
Sácalo con una desestructuración; la firma es idéntica a la que produce una billetera para la carga útil v4, porque el tipo de dominio se deriva de los mismos 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.
Comprobar el tipo principal deducido
`TypedDataEncoder.from(types).primaryType` lanza el mismo error o devuelve el tipo cuyo hash calculará ethers: una comprobación rápida para las pruebas.
js import { TypedDataEncoder } from "ethers"; // Inspect what ethers considers the primary type before signing. console.log(TypedDataEncoder.from(types).primaryType);