68 lines
2.2 KiB
TypeScript
68 lines
2.2 KiB
TypeScript
import Z, { z } from 'zod';
|
|
|
|
/**
|
|
* Zod schemas for invitation validation.
|
|
*
|
|
* IMPORTANT: We use .passthrough() on all object schemas to preserve fields
|
|
* that aren't explicitly defined. This is critical because:
|
|
* 1. Invitations are signed based on stringify(commit.data)
|
|
* 2. If we strip fields, the signature verification will fail
|
|
* 3. The actual XOInvitation types have many more fields than we validate here
|
|
*/
|
|
|
|
const variableSchema = z.object({
|
|
variableIdentifier: z.string(),
|
|
roleIdentifier: z.string().optional(),
|
|
value: z.number().or(z.string()).or(z.boolean()).or(z.bigint()),
|
|
}).passthrough();
|
|
|
|
const mergesWithSchema = z.object({
|
|
commitIdentifier: z.string(),
|
|
index: z.number(),
|
|
}).passthrough();
|
|
|
|
const inputSchema = z.object({
|
|
inputIdentifier: z.string().optional(),
|
|
transactionIndex: z.number().optional(),
|
|
roleIdentifier: z.string().optional(),
|
|
mergesWith: mergesWithSchema.optional(),
|
|
// Additional fields preserved via passthrough:
|
|
// outpointTransactionHash, outpointIndex, sequenceNumber, unlockingBytecode, etc.
|
|
}).passthrough();
|
|
|
|
const outputSchema = z.object({
|
|
outputIdentifier: z.string().optional(),
|
|
roleIdentifier: z.string().optional(),
|
|
secretIdentifier: z.string().optional(),
|
|
transactionIndex: z.number().optional(),
|
|
mergesWith: mergesWithSchema.optional(),
|
|
// Additional fields preserved via passthrough:
|
|
// valueSatoshis, lockingBytecode, token, etc.
|
|
}).passthrough();
|
|
|
|
const dataSchema = z.object({
|
|
transactionVersion: z.number().optional(),
|
|
transactionLocktime: z.number().optional(),
|
|
variables: z.array(variableSchema).optional(),
|
|
inputs: z.array(inputSchema).optional(),
|
|
outputs: z.array(outputSchema).optional(),
|
|
}).passthrough();
|
|
|
|
const commitSchema = z.object({
|
|
commitIdentifier: z.string(),
|
|
previousCommitIdentifier: z.string().or(z.undefined()),
|
|
entityIdentifier: z.string(),
|
|
data: dataSchema,
|
|
signature: z.string(),
|
|
expiresAtTimestamp: z.number(),
|
|
}).passthrough();
|
|
|
|
export const parseInvitation = z.object({
|
|
invitationIdentifier: z.string(),
|
|
commits: z.array(commitSchema),
|
|
createdAtTimestamp: z.number(),
|
|
templateIdentifier: z.string(),
|
|
actionIdentifier: z.string(),
|
|
}).passthrough();
|
|
|
|
export type InvitationSchema = Z.infer<typeof parseInvitation>; |