UNPKG

viem

Version:

TypeScript Interface for Ethereum

119 lines 4.69 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.serializeTypedData = serializeTypedData; exports.validateTypedData = validateTypedData; exports.getTypesForEIP712Domain = getTypesForEIP712Domain; exports.domainSeparator = domainSeparator; const abi_js_1 = require("../errors/abi.js"); const address_js_1 = require("../errors/address.js"); const typedData_js_1 = require("../errors/typedData.js"); const isAddress_js_1 = require("./address/isAddress.js"); const size_js_1 = require("./data/size.js"); const toHex_js_1 = require("./encoding/toHex.js"); const regex_js_1 = require("./regex.js"); const hashTypedData_js_1 = require("./signature/hashTypedData.js"); const stringify_js_1 = require("./stringify.js"); function serializeTypedData(parameters) { const { domain: domain_, message: message_, primaryType, types, } = parameters; const normalizeData = (struct, data_) => { const data = { ...data_ }; for (const param of struct) { const { name, type } = param; if (type === 'address') data[name] = data[name].toLowerCase(); } return data; }; const domain = (() => { if (!types.EIP712Domain) return {}; if (!domain_) return {}; return normalizeData(types.EIP712Domain, domain_); })(); const message = (() => { if (primaryType === 'EIP712Domain') return undefined; return normalizeData(types[primaryType], message_); })(); return (0, stringify_js_1.stringify)({ domain, message, primaryType, types }); } function validateTypedData(parameters) { const { domain, message, primaryType, types } = parameters; const validateData = (struct, data) => { for (const param of struct) { const { name, type } = param; const value = data[name]; const integerMatch = type.match(regex_js_1.integerRegex); if (integerMatch && (typeof value === 'number' || typeof value === 'bigint')) { const [_type, base, size_] = integerMatch; (0, toHex_js_1.numberToHex)(value, { signed: base === 'int', size: Number.parseInt(size_) / 8, }); } if (type === 'address' && typeof value === 'string' && !(0, isAddress_js_1.isAddress)(value)) throw new address_js_1.InvalidAddressError({ address: value }); const bytesMatch = type.match(regex_js_1.bytesRegex); if (bytesMatch) { const [_type, size_] = bytesMatch; if (size_ && (0, size_js_1.size)(value) !== Number.parseInt(size_)) throw new abi_js_1.BytesSizeMismatchError({ expectedSize: Number.parseInt(size_), givenSize: (0, size_js_1.size)(value), }); } const struct = types[type]; if (struct) { validateReference(type); validateData(struct, value); } } }; if (types.EIP712Domain && domain) { if (typeof domain !== 'object') throw new typedData_js_1.InvalidDomainError({ domain }); validateData(types.EIP712Domain, domain); } if (primaryType !== 'EIP712Domain') { if (types[primaryType]) validateData(types[primaryType], message); else throw new typedData_js_1.InvalidPrimaryTypeError({ primaryType, types }); } } function getTypesForEIP712Domain({ domain, }) { return [ typeof domain?.name === 'string' && { name: 'name', type: 'string' }, domain?.version && { name: 'version', type: 'string' }, (typeof domain?.chainId === 'number' || typeof domain?.chainId === 'bigint') && { name: 'chainId', type: 'uint256', }, domain?.verifyingContract && { name: 'verifyingContract', type: 'address', }, domain?.salt && { name: 'salt', type: 'bytes32' }, ].filter(Boolean); } function domainSeparator({ domain }) { return (0, hashTypedData_js_1.hashDomain)({ domain, types: { EIP712Domain: getTypesForEIP712Domain({ domain }), }, }); } function validateReference(type) { if (type === 'address' || type === 'bool' || type === 'string' || type.startsWith('bytes') || type.startsWith('uint') || type.startsWith('int')) throw new typedData_js_1.InvalidStructTypeError({ type }); } //# sourceMappingURL=typedData.js.map