30 lines
997 B
TypeScript
30 lines
997 B
TypeScript
import z from "zod";
|
|
|
|
/**
|
|
* Boundary schema for `MoneyLike`. Amount is `bigint` (minor units —
|
|
* cents, pence, satoshi, lamports). JSON cannot natively carry bigints,
|
|
* so the schema accepts either a JSON-number, a numeric string, or a
|
|
* bigint literal and coerces via `BigInt()`. Currency is a 3-8 char
|
|
* ISO 4217 code (or caller-registered identifier — `BTC`, `USDC`,
|
|
* `LAMPORTS`).
|
|
*/
|
|
export const MoneySchema = z.object({
|
|
amount: z.preprocess((val) => {
|
|
if (typeof val === "bigint") return val;
|
|
if (typeof val === "number" && Number.isFinite(val)) {
|
|
return BigInt(Math.trunc(val));
|
|
}
|
|
if (typeof val === "string" && /^-?\d+$/.test(val)) {
|
|
return BigInt(val);
|
|
}
|
|
return val;
|
|
}, z.bigint().nonnegative()),
|
|
currency: z
|
|
.string()
|
|
.min(3)
|
|
.max(8)
|
|
.regex(/^[A-Z0-9]+$/u, "currency must be uppercase letters or digits"),
|
|
});
|
|
|
|
export type Money = z.infer<typeof MoneySchema>;
|