25 lines
1.2 KiB
TypeScript
Executable File
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>;
|