Сообщение об ошибке
Invalid primary type `Email` must be one of `["EIP712Domain","Mail"]`.
Имена в обратных кавычках — это ваш `primaryType` и доступные типы. viem 2.57 выбрасывает эту ошибку с `err.name` «BaseError»; `err.shortMessage` — текст выше, а `err.message` добавляет подсказку, ссылку на документацию («typeddatainvalidprimarytypeerror») и версию viem.
viem (TypeScript) — hashTypedData / signTypedData / verifyTypedData / recoverTypedDataAddress
Что это означает
Переданного вами `primaryType` нет среди ключей `types` (viem добавляет `EIP712Domain` в показываемый список). EIP-712 хеширует сообщение как экземпляр основного типа, поэтому viem не пытается угадать. Сами типизированные данные могут быть в порядке, но в них нет имени структуры, которую вы подписываете.
Почему это происходит
Структуру переименовали на одной из сторон
частоВ контракте или на бэкенде `Mail` переименовали в `Email` (или `Order` в `OrderV2`), а фронтенд всё ещё отправляет старое имя, или наоборот. Имя типа входит в хеш типа, поэтому обе стороны в любом случае должны меняться одновременно.
primaryType не указан или равен undefined
иногдаПолезная нагрузка, собранная динамически (например, из JSON), в которой `primaryType` так и не задали, приводит к `Invalid primary type \`undefined\``.
Другой регистр букв
иногда`mail` и `Mail`: в EIP-712 имена типов чувствительны к регистру.
Как исправить
- 1.
Объявите типы через as const
С `as const` типы viem превращают `primaryType` в объединение имён ваших структур, поэтому несовпадение даёт ошибку при компиляции, а не при подписи.
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 });