import { type EIP712Message, type EIP712Types, type Permission, type PermitSignaturePrimaryType } from './types.js'; const PermitSignatureAllFields = [ { name: 'issuer', type: 'address' }, { name: 'expiration', type: 'uint64' }, { name: 'recipient', type: 'address' }, { name: 'validatorId', type: 'uint256' }, { name: 'validatorContract', type: 'address' }, { name: 'sealingKey', type: 'bytes32' }, { name: 'issuerSignature', type: 'bytes' }, ] as const; type PermitSignatureFieldOption = (typeof PermitSignatureAllFields)[number]['name']; export const SignatureTypes = { PermissionedV2IssuerSelf: [ 'issuer', 'expiration', 'recipient', 'validatorId', 'validatorContract', 'sealingKey', ] satisfies PermitSignatureFieldOption[], PermissionedV2IssuerShared: [ 'issuer', 'expiration', 'recipient', 'validatorId', 'validatorContract', ] satisfies PermitSignatureFieldOption[], PermissionedV2Recipient: ['sealingKey', 'issuerSignature'] satisfies PermitSignatureFieldOption[], } as const; /** * Get signature types and message for EIP712 signing */ export const getSignatureTypesAndMessage = ( primaryType: PermitSignaturePrimaryType, fields: T[] | readonly T[], values: Pick & Partial ): { types: EIP712Types; primaryType: string; message: EIP712Message } => { const types = { [primaryType]: PermitSignatureAllFields.filter((fieldType) => fields.includes(fieldType.name as T)), }; const message: Record = {} as Record< T, string | string[] | number | number[] >; fields.forEach((field) => { if (field in values) { message[field] = values[field]; } }); return { types, primaryType, message: message as EIP712Message }; }; /** * Signature utilities for permit operations */ export const SignatureUtils = { /** * Get signature parameters for a permit */ getSignatureParams: (permit: Permission, primaryType: PermitSignaturePrimaryType) => { return getSignatureTypesAndMessage(primaryType, SignatureTypes[primaryType], permit); }, /** * Determine the required signature type based on permit type */ getPrimaryType: (permitType: 'self' | 'sharing' | 'recipient'): PermitSignaturePrimaryType => { if (permitType === 'self') return 'PermissionedV2IssuerSelf'; if (permitType === 'sharing') return 'PermissionedV2IssuerShared'; if (permitType === 'recipient') return 'PermissionedV2Recipient'; throw new Error(`Unknown permit type: ${permitType}`); }, };