UNPKG

ox

Version:

Ethereum Standard Library

84 lines 2.85 kB
import * as z_Address from './Address.js'; import * as z_Solidity from './Solidity.js'; import * as z from 'zod/mini'; export const Domain = z.object({ chainId: z.optional(z.union([z.number(), z.bigint()])), name: z.optional(z_Solidity.Identifier), salt: z.optional(z.string()), verifyingContract: z.optional(z_Address.Address), version: z.optional(z.string()), }); export const Type = z.union([ z_Solidity.Address, z_Solidity.Bool, z_Solidity.Bytes, z_Solidity.String, z_Solidity.Int, z_Solidity.Array, ]); export const Parameter = z.object({ name: z_Solidity.Identifier, type: z.string(), }); const Raw = z.record(z_Solidity.Identifier, z.readonly(z.array(Parameter))); export const TypedData = z.pipe(Raw, z.transform((value, ctx) => validate(value, ctx))); function validate(typedData, ctx) { for (const key of Object.keys(typedData)) { if (z_Solidity.isType(key)) { ctx.issues.push({ code: 'custom', input: key, message: `Invalid key. ${key} is a solidity type.`, }); return z.NEVER; } validateParameters(key, typedData, ctx); } return typedData; } const typeWithoutTupleRegex = /^(?<type>[a-zA-Z$_][a-zA-Z0-9$_]*?)(?<array>(?:\[\d*?\])+?)?$/; function validateParameters(key, typedData, ctx, ancestors = new Set()) { const value = typedData[key]; if (!value) return; for (const parameter of value) { if (parameter.type === key) { ctx.issues.push({ code: 'custom', input: parameter.type, message: `Invalid type. ${key} is a self reference.`, }); return z.NEVER; } const match = typeWithoutTupleRegex.exec(parameter.type)?.groups; const type = match?.type; if (!type) { ctx.issues.push({ code: 'custom', input: parameter.type, message: `Invalid type. ${key} does not have a type.`, }); return z.NEVER; } if (type in typedData) { if (ancestors.has(type)) { ctx.issues.push({ code: 'custom', input: type, message: `Invalid type. ${type} is a circular reference.`, }); return z.NEVER; } validateParameters(type, typedData, ctx, new Set([...ancestors, type])); } else if (!z_Solidity.isType(type)) { ctx.issues.push({ code: 'custom', input: type, message: `Invalid type. ${type} is not a valid EIP-712 type.`, }); return z.NEVER; } } } //# sourceMappingURL=TypedData.js.map