Paid-sale workflow

This commit is contained in:
2026-10-20 17:38:34 -04:00
parent 621611ecd9
commit ca8ff48628
11 changed files with 414 additions and 13 deletions
+5 -2
View File
@@ -12,6 +12,7 @@ export const saleTermsSchema = z.object({ protocol: z.literal(SALE_CANDIDATE), n
chainId: hex, policyDigest: hex, custodianId: z.string().uuid(), orderId: z.string().uuid(),
cardHash: hex, sequence: height, seller: hex, buyer: hex, host: hex,
priceAtomicXmr: amount, feeBps: z.number().int().min(0).max(5000),
hostFeeAddress: z.string().regex(/^[1-9A-HJ-NP-Za-km-z]{95}$/).optional(),
lockUntilHeight: height, expiresHeight: height }).strict();
export type SaleTerms = z.infer<typeof saleTermsSchema>;
export const saleSignatureSchema = z.object({ publicKey: z.string().min(1).max(256),
@@ -28,10 +29,12 @@ export const saleTransactionSchema = z.discriminatedUnion('type', [
]);
export type SaleTransaction = z.infer<typeof saleTransactionSchema>;
export function saleTermsMessage(t: SaleTerms): string {
return JSON.stringify([SALE_CANDIDATE, 'terms', t.network, t.chainId, t.policyDigest,
const tuple: unknown[] = [SALE_CANDIDATE, 'terms', t.network, t.chainId, t.policyDigest,
t.custodianId, t.orderId, t.cardHash, t.sequence, t.seller, t.buyer, t.host,
'XMR', t.priceAtomicXmr, t.feeBps, ADDITIONAL_MARKET_FEE.bps, ADDITIONAL_MARKET_FEE.address,
t.lockUntilHeight, t.expiresHeight]);
t.lockUntilHeight, t.expiresHeight];
if (t.hostFeeAddress !== undefined) tuple.push(['host-fee-recipient-v1', t.hostFeeAddress]);
return JSON.stringify(tuple);
}
export function saleCompletionMessage(t: Pick<Extract<SaleTransaction, { type: 'sale-complete' }>, 'chainId' | 'saleId' | 'reservationDigest'>): string {
return JSON.stringify([SALE_CANDIDATE, 'complete-funded-reservation', t.chainId, t.saleId, t.reservationDigest]);