import { z } from 'zod'; import { parseAtomicXmr } from './xmr-amount.ts'; const uuid = z.string().uuid(); const hex = z.string().regex(/^[a-f0-9]{64}$/); const atomic = z.string().max(22).refine(value => { try { parseAtomicXmr(value); return true; } catch { return false; } }); const positiveAtomic = atomic.refine(value => BigInt(value) > 0n); export const mainnetWithdrawalRequestSchema = z.object({ version: z.literal(1), network: z.literal('wikideck-randomx-mainnet-1'), chainId: hex, custodianId: uuid, beneficiary: hex, publicKey: z.string().min(1).max(256), requestId: uuid, destination: z.string().length(95), amountAtomicXmr: positiveAtomic, maxFeeAtomicXmr: atomic, expiresAt: z.number().int().nonnegative().safe(), signature: z.string().min(1).max(256), }).strict(); export type MainnetWithdrawalRequest = z.infer; export type MainnetWithdrawalRequestUnsigned = Omit; export const mainnetWithdrawalCancellationSchema = z.object({ version: z.literal(1), network: z.literal('wikideck-randomx-mainnet-1'), chainId: hex, custodianId: uuid, beneficiary: hex, publicKey: z.string().min(1).max(256), cancellationId: uuid, withdrawalRequestId: uuid, expiresAt: z.number().int().nonnegative().safe(), signature: z.string().min(1).max(256), }).strict(); export type MainnetWithdrawalCancellation = z.infer; export type MainnetWithdrawalCancellationUnsigned = Omit; export function mainnetWithdrawalMessage(request: MainnetWithdrawalRequestUnsigned): string { return JSON.stringify(['wikideck-mainnet-withdrawal-request-v1', request.version, request.network, request.chainId, request.custodianId, request.beneficiary, request.publicKey, request.requestId, request.destination, request.amountAtomicXmr, request.maxFeeAtomicXmr, request.expiresAt]); } export function mainnetWithdrawalCancellationMessage(request: MainnetWithdrawalCancellationUnsigned): string { return JSON.stringify(['wikideck-mainnet-withdrawal-cancel-v1', request.version, request.network, request.chainId, request.custodianId, request.beneficiary, request.publicKey, request.cancellationId, request.withdrawalRequestId, request.expiresAt]); } export const mainnetCustodyBalanceRequestSchema = z.object({ version: z.literal(1), network: z.literal('wikideck-randomx-mainnet-1'), chainId: hex, custodianId: uuid, beneficiary: hex, publicKey: z.string().min(1).max(256), nonce: uuid, expiresAt: z.number().int().nonnegative().safe(), signature: z.string().min(1).max(256), }).strict(); export type MainnetCustodyBalanceRequest = z.infer; export type MainnetCustodyBalanceRequestUnsigned = Omit; export function mainnetCustodyBalanceMessage(request: MainnetCustodyBalanceRequestUnsigned): string { return JSON.stringify(['wikideck-mainnet-custody-balance-v1', request.version, request.network, request.chainId, request.custodianId, request.beneficiary, request.publicKey, request.nonce, request.expiresAt]); }