Files
2026-10-19 21:47:38 -04:00

25 lines
1.2 KiB
TypeScript
Executable File

import { z } from 'zod';
import { NETWORK, CONSENSUS } from './testnet.ts';
const hex = z.string().regex(/^[a-f0-9]{64}$/);
const signature = z.string().regex(/^[A-Za-z0-9+/]+={0,2}$/).length(88);
const leg = z.object({ cardHash: hex, sequence: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER) }).strict();
export const tradeOfferSchema = z.object({
format: z.literal('wikideck-trade-offer'),
version: z.literal(1),
network: z.literal(NETWORK),
chainId: hex,
proposer: hex,
counterparty: hex,
offered: z.array(leg).min(1).max(CONSENSUS.maxTradeCards),
requested: z.array(leg).min(1).max(CONSENSUS.maxTradeCards),
proposerPublicKey: z.string().regex(/^[A-Za-z0-9+/]+={0,2}$/).max(256),
proposerSignature: signature,
}).strict().superRefine((offer, ctx) => {
if (offer.proposer === offer.counterparty) ctx.addIssue({ code: 'custom', message: 'Trade parties must differ' });
const ids = [...offer.offered, ...offer.requested].map(item => item.cardHash);
if (new Set(ids).size !== ids.length) ctx.addIssue({ code: 'custom', message: 'Each NFT may appear only once in a trade' });
});
export type TradeOffer = z.infer<typeof tradeOfferSchema>;