UNPKG

opstack-kit-chains

Version:
97 lines 3.75 kB
import { BytesSizeMismatchError } from '../errors/abi.js'; import { InvalidAddressError } from '../errors/address.js'; import { isAddress } from './address/isAddress.js'; import { size } from './data/size.js'; import { numberToHex } from './encoding/toHex.js'; import { bytesRegex, integerRegex } from './regex.js'; import { hashDomain, } from './signature/hashTypedData.js'; import { stringify } from './stringify.js'; export 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 stringify({ domain, message, primaryType, types }); } export 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(integerRegex); if (integerMatch && (typeof value === 'number' || typeof value === 'bigint')) { const [_type, base, size_] = integerMatch; // If number cannot be cast to a sized hex value, it is out of range // and will throw. numberToHex(value, { signed: base === 'int', size: Number.parseInt(size_) / 8, }); } if (type === 'address' && typeof value === 'string' && !isAddress(value)) throw new InvalidAddressError({ address: value }); const bytesMatch = type.match(bytesRegex); if (bytesMatch) { const [_type, size_] = bytesMatch; if (size_ && size(value) !== Number.parseInt(size_)) throw new BytesSizeMismatchError({ expectedSize: Number.parseInt(size_), givenSize: size(value), }); } const struct = types[type]; if (struct) validateData(struct, value); } }; // Validate domain types. if (types.EIP712Domain && domain) validateData(types.EIP712Domain, domain); // Validate message types. if (primaryType !== 'EIP712Domain') validateData(types[primaryType], message); } export function getTypesForEIP712Domain({ domain, }) { return [ typeof domain?.name === 'string' && { name: 'name', type: 'string' }, domain?.version && { name: 'version', type: 'string' }, typeof domain?.chainId === 'number' && { name: 'chainId', type: 'uint256', }, domain?.verifyingContract && { name: 'verifyingContract', type: 'address', }, domain?.salt && { name: 'salt', type: 'bytes32' }, ].filter(Boolean); } export function domainSeparator({ domain }) { return hashDomain({ domain, types: { EIP712Domain: getTypesForEIP712Domain({ domain }), }, }); } //# sourceMappingURL=typedData.js.map