@klappay/types 3.2.0 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -54,6 +54,7 @@ __export(index_exports, {
54
54
  EVM_NETWORKS: () => EVM_NETWORKS,
55
55
  EnvironmentSchema: () => EnvironmentSchema,
56
56
  ErrorPayloadSchema: () => ErrorPayloadSchema,
57
+ EscrowConfigSchema: () => EscrowConfigSchema,
57
58
  GetChargeQrCodeQuerySchema: () => GetChargeQrCodeQuerySchema,
58
59
  HealthSchema: () => HealthSchema,
59
60
  KlappayCheckoutMetadataSchema: () => KlappayCheckoutMetadataSchema,
@@ -89,6 +90,7 @@ __export(index_exports, {
89
90
  PendingDistributionRecipientSchema: () => PendingDistributionRecipientSchema,
90
91
  PendingDistributionSchema: () => PendingDistributionSchema,
91
92
  RecipientSchema: () => RecipientSchema,
93
+ ReleaseEscrowRequestSchema: () => ReleaseEscrowRequestSchema,
92
94
  SandboxTriggerSchema: () => SandboxTriggerSchema,
93
95
  SetRecipientPayoutSchema: () => SetRecipientPayoutSchema,
94
96
  SettlementStatusSchema: () => SettlementStatusSchema,
@@ -332,7 +334,7 @@ function listSwapAlternatives(networks) {
332
334
  }
333
335
 
334
336
  // src/charges.ts
335
- var import_zod9 = require("zod");
337
+ var import_zod10 = require("zod");
336
338
 
337
339
  // src/checkout-metadata.ts
338
340
  var import_zod8 = require("zod");
@@ -355,27 +357,40 @@ var MetadataWithKlappaySchema = import_zod8.z.object({ klappay: KlappayCheckoutM
355
357
  "Arbitrary key/value data, returned as-is on every read. Put whatever you want in here \u2014 none of it is validated, except the `klappay` key, which is reserved for Klappay: if present, it must match `KlappayCheckoutMetadataSchema` exactly, or the whole request is rejected with `400 validation_error`."
356
358
  );
357
359
 
360
+ // src/escrow.ts
361
+ var import_zod9 = require("zod");
362
+ var EscrowConfigSchema = import_zod9.z.object({
363
+ releaserAddress: import_zod9.z.string().regex(/^0x[0-9a-fA-F]{40}$/, "must be a 20-byte hex address").optional().describe(
364
+ "The only address ever authorized to release this charge's escrowed funds \u2014 set once at creation, immutable after. Klappay never holds a key with any release authority of its own; every release requires a signature from this address, verified on-chain, never taken on faith. Omit to default to the API key's own `payoutAddress` \u2014 the common case where the merchant releasing their own charge is the same wallet they already get paid to. Pass an explicit address only when the releaser is a different party (e.g. an operational key distinct from the payout wallet). Not validated against anything else \u2014 any well-formed address is accepted, since Klappay never custodies these funds."
365
+ )
366
+ });
367
+ var ReleaseEscrowRequestSchema = import_zod9.z.object({
368
+ signature: import_zod9.z.string().regex(/^0x[0-9a-fA-F]+$/, "must be hex-encoded signature bytes").describe(
369
+ "The Safe transaction signature authorizing this release, produced by signing the escrow's predetermined release transaction (destination and amount are fixed at escrow creation, never client-supplied here) with the private key behind this charge's `escrowReleaserAddress` \u2014 never anything Klappay can produce itself. Independently verified on-chain before anything moves; a mismatched, malformed, or missing signature is rejected, never trusted at face value."
370
+ )
371
+ });
372
+
358
373
  // src/charges.ts
359
- var ChargeStatusSchema = import_zod9.z.enum(["pending", "partially_paid", "confirmed", "expired", "underpaid"]).describe(
374
+ var ChargeStatusSchema = import_zod10.z.enum(["pending", "partially_paid", "confirmed", "expired", "underpaid"]).describe(
360
375
  "Payment progress, from the payer side. `pending`: created, nothing received yet. `partially_paid`: some funds received, less than `amount`. `confirmed`: full amount received (or more \u2014 see `isOverpaid`). `expired`: `expiresAt` passed with zero funds received. `underpaid`: `expiresAt` passed while `partially_paid`. Every status is reached automatically, on its own timeline \u2014 there is no merchant-initiated cancellation. This never reflects whether funds actually reached the merchant \u2014 see `settlementStatus` for that."
361
376
  );
362
- var SettlementStatusSchema = import_zod9.z.enum(["pending", "completed", "failed"]).describe(
377
+ var SettlementStatusSchema = import_zod10.z.enum(["pending", "completed", "failed"]).describe(
363
378
  "Progress of the payout to the merchant's wallet, a separate step from `status` \u2014 `status: confirmed` only means the payment was detected on-chain, not that the merchant has been paid yet. `pending`: payment detected, payout not yet attempted. `completed`: the merchant's wallet has the funds. `failed`: the payout attempt failed and retries were exhausted (rare; contact support). `null` on the parent `Charge` means no payout has been attempted yet \u2014 nothing has been received, or the charge is still in progress."
364
379
  );
365
380
  var CHARGE_EXPIRES_IN_MIN_SECONDS = 60;
366
381
  var CHARGE_EXPIRES_IN_MAX_SECONDS = 3600;
367
382
  var CHARGE_ACCEPTED_PAYMENTS_MAX = 14;
368
- var AcceptedPaymentSchema = import_zod9.z.object({
383
+ var AcceptedPaymentSchema = import_zod10.z.object({
369
384
  token: TokenSchema,
370
385
  network: NetworkSchema
371
386
  });
372
- var AcceptedPaymentsSchema = import_zod9.z.array(AcceptedPaymentSchema).min(1, "At least one accepted payment is required.").max(CHARGE_ACCEPTED_PAYMENTS_MAX).superRefine((pairs, ctx) => {
387
+ var AcceptedPaymentsSchema = import_zod10.z.array(AcceptedPaymentSchema).min(1, "At least one accepted payment is required.").max(CHARGE_ACCEPTED_PAYMENTS_MAX).superRefine((pairs, ctx) => {
373
388
  const seen = /* @__PURE__ */ new Set();
374
389
  pairs.forEach((pair, index) => {
375
390
  const key = `${pair.token}:${pair.network}`;
376
391
  if (seen.has(key)) {
377
392
  ctx.addIssue({
378
- code: import_zod9.z.ZodIssueCode.custom,
393
+ code: import_zod10.z.ZodIssueCode.custom,
379
394
  message: `Duplicate accepted payment: ${pair.token} on ${pair.network}.`,
380
395
  path: [index]
381
396
  });
@@ -383,7 +398,7 @@ var AcceptedPaymentsSchema = import_zod9.z.array(AcceptedPaymentSchema).min(1, "
383
398
  seen.add(key);
384
399
  if (!OPERATIONAL_NETWORKS.includes(pair.network)) {
385
400
  ctx.addIssue({
386
- code: import_zod9.z.ZodIssueCode.custom,
401
+ code: import_zod10.z.ZodIssueCode.custom,
387
402
  message: `Network "${pair.network}" isn't live yet \u2014 only ${OPERATIONAL_NETWORKS.join(", ")} today.`,
388
403
  path: [index, "network"]
389
404
  });
@@ -393,32 +408,32 @@ var AcceptedPaymentsSchema = import_zod9.z.array(AcceptedPaymentSchema).min(1, "
393
408
  `Every \`(token, network)\` pair the payer is allowed to pay with \u2014 at least one, up to ${CHARGE_ACCEPTED_PAYMENTS_MAX}. This list is also the only restriction knob: the payer can use any combination of the pairs listed here, and every transfer on one of them is credited and sums toward the charge total (see \`paidWith\`) \u2014 e.g. a charge accepting USDC and USDT can be confirmed by $9 in USDC plus $1 in USDT, or by USDC arriving on two different accepted networks. To require payment in one specific token on one specific network, list only that single pair \u2014 a transfer on any pair not in this list is still recorded (for audit) but never credited. Each network must be live (see \`GET /v1/networks\` for the current matrix) \u2014 an unconfigured \`(token, network)\` combination for your environment is rejected with \`422 token_not_supported\`.`
394
409
  );
395
410
  var CHARGE_SPLIT_RECIPIENTS_MAX = 5;
396
- var SplitRecipientSchema = import_zod9.z.object({
397
- address: import_zod9.z.string().regex(/^0x[0-9a-fA-F]{40}$/, "must be a 20-byte hex address").describe("EVM address to send a slice of this charge to."),
398
- percent: import_zod9.z.number().positive().max(100).describe(
411
+ var SplitRecipientSchema = import_zod10.z.object({
412
+ address: import_zod10.z.string().regex(/^0x[0-9a-fA-F]{40}$/, "must be a 20-byte hex address").describe("EVM address to send a slice of this charge to."),
413
+ percent: import_zod10.z.number().positive().max(100).describe(
399
414
  "Percent of *your own* net share (i.e. of `100 - feePercent`, not of the charge's gross `amount`) to route to this address instead of your own payout wallet. Klappay's fee is computed on the gross amount first and is never diluted by how you choose to split what's left \u2014 see `docs/payments.md`'s \"Settling the payout\" section for the exact math."
400
415
  ),
401
- label: import_zod9.z.string().min(1).max(64).optional().describe(
416
+ label: import_zod10.z.string().min(1).max(64).optional().describe(
402
417
  'Free-form label for your own bookkeeping (e.g. `"supplier"`, `"sales rep"`) \u2014 echoed back unchanged, never interpreted by Klappay.'
403
418
  )
404
419
  });
405
- var SplitRecipientInputSchema = import_zod9.z.object({
406
- recipientId: import_zod9.z.string().describe(
420
+ var SplitRecipientInputSchema = import_zod10.z.object({
421
+ recipientId: import_zod10.z.string().describe(
407
422
  "id of a `Recipient` you already registered via `POST /v1/recipients` (not a raw address) \u2014 see `recipients:write`/`charges:split_write` scopes. A leaked `charges:write`-only key can never redirect payout to a brand new address this way, only reference one already trusted."
408
423
  ),
409
- percent: import_zod9.z.number().positive().max(100).describe(
424
+ percent: import_zod10.z.number().positive().max(100).describe(
410
425
  "Percent of *your own* net share (i.e. of `100 - feePercent`, not of the charge's gross `amount`) to route to this recipient instead of your own payout wallet. Klappay's fee is computed on the gross amount first and is never diluted by how you choose to split what's left \u2014 see `docs/payments.md`'s \"Settling the payout\" section for the exact math."
411
426
  ),
412
- label: import_zod9.z.string().min(1).max(64).optional().describe(
427
+ label: import_zod10.z.string().min(1).max(64).optional().describe(
413
428
  'Free-form label for your own bookkeeping (e.g. `"supplier"`, `"sales rep"`) \u2014 echoed back unchanged, never interpreted by Klappay. Independent of the label the recipient was registered with.'
414
429
  )
415
430
  });
416
- var SplitRecipientsInputSchema = import_zod9.z.array(SplitRecipientInputSchema).max(CHARGE_SPLIT_RECIPIENTS_MAX).superRefine((recipients, ctx) => {
431
+ var SplitRecipientsInputSchema = import_zod10.z.array(SplitRecipientInputSchema).max(CHARGE_SPLIT_RECIPIENTS_MAX).superRefine((recipients, ctx) => {
417
432
  const seen = /* @__PURE__ */ new Set();
418
433
  recipients.forEach((recipient, index) => {
419
434
  if (seen.has(recipient.recipientId)) {
420
435
  ctx.addIssue({
421
- code: import_zod9.z.ZodIssueCode.custom,
436
+ code: import_zod10.z.ZodIssueCode.custom,
422
437
  message: `Duplicate split recipientId: ${recipient.recipientId}.`,
423
438
  path: [index, "recipientId"]
424
439
  });
@@ -429,82 +444,91 @@ var SplitRecipientsInputSchema = import_zod9.z.array(SplitRecipientInputSchema).
429
444
  `Optional extra recipients for this charge's split \u2014 e.g. a supplier or the sales rep who closed the deal \u2014 up to ${CHARGE_SPLIT_RECIPIENTS_MAX}, each referenced by \`recipientId\` (see \`POST /v1/recipients\`), never a raw address. Requires the \`charges:split_write\` scope in addition to \`charges:write\`. Frozen at creation exactly like everything else that shapes the split address; cannot be changed afterward. The sum of every \`percent\` here must fit within \`100 - feePercent\` (your own net share) \u2014 a request that doesn't is rejected with \`422 split_recipients_exceed_available_percent\`.`
430
445
  );
431
446
  var CHARGE_AMOUNT_MAX = 999999999999;
432
- var CreateChargeSchema = import_zod9.z.object({
433
- amount: import_zod9.z.number().positive().max(CHARGE_AMOUNT_MAX).describe(
447
+ var CreateChargeSchema = import_zod10.z.object({
448
+ amount: import_zod10.z.number().positive().max(CHARGE_AMOUNT_MAX).describe(
434
449
  "Amount to charge, in `currency` units (e.g. `49.9` = $49.90) \u2014 up to 6 decimal places; anything more precise is silently truncated. Required \u2014 every charge has a target amount, the first credited transfer that reaches it confirms the charge."
435
450
  ),
436
- currency: import_zod9.z.literal("USD").default("USD").describe("Always `USD` today \u2014 the only supported currency."),
451
+ currency: import_zod10.z.literal("USD").default("USD").describe("Always `USD` today \u2014 the only supported currency."),
437
452
  acceptedPayments: AcceptedPaymentsSchema,
438
- expiresIn: import_zod9.z.number().int().min(CHARGE_EXPIRES_IN_MIN_SECONDS).max(CHARGE_EXPIRES_IN_MAX_SECONDS).describe(
453
+ expiresIn: import_zod10.z.number().int().min(CHARGE_EXPIRES_IN_MIN_SECONDS).max(CHARGE_EXPIRES_IN_MAX_SECONDS).describe(
439
454
  "Seconds, not minutes or milliseconds \u2014 how long the charge stays open before it expires. Required, min 60, max 3600 (60 minutes) \u2014 sized off the slowest chain Klappay supports today (Ethereum mainnet, where a safely-confirmed transfer takes up to ~15 minutes), leaving real margin for payer-side delay (gas spikes, wallet friction) on top of that. Cannot be extended or shortened after creation."
440
455
  ),
441
- idempotencyKey: import_zod9.z.string().min(1).max(255).optional().describe(
456
+ idempotencyKey: import_zod10.z.string().min(1).max(255).optional().describe(
442
457
  "Scoped to your tenant. Replaying the same key returns the original charge unchanged instead of creating a duplicate \u2014 safe to retry a request after a timeout without double-charging."
443
458
  ),
444
- externalRef: import_zod9.z.string().min(1).max(255).optional().describe(
459
+ externalRef: import_zod10.z.string().min(1).max(255).optional().describe(
445
460
  "An opaque correlation id from your own system (e.g. an order id) \u2014 echoed back on the charge and in every webhook payload. Not interpreted or validated by Klappay."
446
461
  ),
447
- source: import_zod9.z.string().min(1).max(64).optional().describe(
462
+ source: import_zod10.z.string().min(1).max(64).optional().describe(
448
463
  'Free-form label for what created this charge (e.g. `"checkout"`, `"invoice"`) \u2014 useful if you create charges from more than one flow and want to tell them apart later. Not a fixed enum; use whatever values make sense to you.'
449
464
  ),
450
465
  metadata: MetadataWithKlappaySchema.optional(),
451
- redirectUrl: import_zod9.z.string().url().refine((value) => /^https?:\/\//.test(value), "must use http or https").optional().describe(
466
+ redirectUrl: import_zod10.z.string().url().refine((value) => /^https?:\/\//.test(value), "must use http or https").optional().describe(
452
467
  "Where to send the payer once this charge resolves, if you use Klappay's hosted checkout page (see `checkoutUrl` on the read shape) \u2014 ignored otherwise. Must be `http(s)` \u2014 a browser will navigate here, so `javascript:`/`data:` and other non-navigational schemes are rejected. Otherwise not validated beyond being well-formed; what happens at that destination is yours to build."
453
468
  ),
454
- splitRecipients: SplitRecipientsInputSchema.optional()
469
+ splitRecipients: SplitRecipientsInputSchema.optional(),
470
+ escrow: EscrowConfigSchema.optional().describe(
471
+ "Configure this charge as an escrow instead of a normal payment. Funds land in a dedicated, non-custodial Safe (not the usual split address) and only `releaserAddress` (or, if omitted, your API key's own `payoutAddress`) can ever release them \u2014 via `POST /v1/charges/{id}/release`, signed on their end, never something Klappay can trigger or redirect. Omit this field entirely for a normal charge."
472
+ )
455
473
  });
456
- var ChargeSchema = import_zod9.z.object({
457
- id: import_zod9.z.string().describe("Klappay-generated id, e.g. `ch_...`. Use this to look up the charge later."),
458
- amount: import_zod9.z.number().describe("The amount originally requested, in `currency` units (up to 6 decimal places)."),
459
- amountReceived: import_zod9.z.number().nullable().describe(
474
+ var ChargeSchema = import_zod10.z.object({
475
+ id: import_zod10.z.string().describe("Klappay-generated id, e.g. `ch_...`. Use this to look up the charge later."),
476
+ amount: import_zod10.z.number().describe("The amount originally requested, in `currency` units (up to 6 decimal places)."),
477
+ amountReceived: import_zod10.z.number().nullable().describe(
460
478
  "Cumulative amount actually received on-chain so far, in `currency` units (up to 6 decimal places). `null` until the first transfer arrives. Can exceed `amount` \u2014 see `isOverpaid`."
461
479
  ),
462
- isOverpaid: import_zod9.z.boolean().describe(
480
+ isOverpaid: import_zod10.z.boolean().describe(
463
481
  "`true` if `amountReceived` ended up greater than `amount`. Klappay never refunds the difference automatically \u2014 see the docs for why."
464
482
  ),
465
- currency: import_zod9.z.string().describe("Always `USD` today \u2014 the only supported currency."),
466
- acceptedPayments: import_zod9.z.array(AcceptedPaymentSchema).describe(
483
+ currency: import_zod10.z.string().describe("Always `USD` today \u2014 the only supported currency."),
484
+ acceptedPayments: import_zod10.z.array(AcceptedPaymentSchema).describe(
467
485
  "Every `(token, network)` pair this charge was configured to accept, unchanged after creation."
468
486
  ),
469
- paidWith: import_zod9.z.array(AcceptedPaymentSchema).describe(
487
+ paidWith: import_zod10.z.array(AcceptedPaymentSchema).describe(
470
488
  "Every distinct `(token, network)` pair that has actually contributed a credited transfer so far \u2014 empty until the first one arrives. Can hold more than one entry: a charge accepting several pairs can be paid across a combination of them, and every entry here sums toward `amountReceived`."
471
489
  ),
472
- swapAlternatives: import_zod9.z.array(SwapAlternativeSchema).describe(
490
+ swapAlternatives: import_zod10.z.array(SwapAlternativeSchema).describe(
473
491
  "Every `(token, network)` pair the payer can pay with instead, via `POST /v1/charges/{id}/quote` \u2014 derived from the networks in `acceptedPayments` (e.g. a charge accepting USDC on both Base and Optimism lists `ETH` on Base and `ETH` on Optimism separately, since they're different networks the payer has to choose between, not one merged option). Pass an entry's `token`/`network` straight through as `inputToken`/`inputNetwork`. Recomputed on every read against Klappay's current trusted list, not frozen at creation \u2014 empty if this charge's networks have no trusted alt-token, if swap-to-pay isn't configured on this deployment, or if `environment` is `test` (0x, who powers the swap, has no testnet support at all \u2014 `POST /v1/charges/{id}/quote` always rejects a test-environment charge with `422 swap_test_environment_unsupported`)."
474
492
  ),
475
- address: import_zod9.z.string().describe(
493
+ address: import_zod10.z.string().describe(
476
494
  "The on-chain address the payer must send funds to \u2014 identical across every accepted network (0xSplits addresses are chain-agnostic). Unique per charge, predicted at creation time \u2014 funds sent here go directly to the merchant, Klappay never custodies them."
477
495
  ),
478
496
  status: ChargeStatusSchema,
479
497
  settlementStatus: SettlementStatusSchema.nullable(),
480
498
  environment: EnvironmentSchema,
481
- apiKeyId: import_zod9.z.string().nullable().describe(
499
+ apiKeyId: import_zod10.z.string().nullable().describe(
482
500
  "Which of your API keys created this charge. `null` for a charge created before this field existed."
483
501
  ),
484
- txHash: import_zod9.z.string().nullable().describe(
502
+ txHash: import_zod10.z.string().nullable().describe(
485
503
  "Transaction hash of the most recent transfer detected for this charge. `null` until a payment is detected."
486
504
  ),
487
- externalRef: import_zod9.z.string().nullable(),
488
- source: import_zod9.z.string().nullable(),
505
+ externalRef: import_zod10.z.string().nullable(),
506
+ source: import_zod10.z.string().nullable(),
489
507
  metadata: MetadataWithKlappaySchema.nullable(),
490
- redirectUrl: import_zod9.z.string().nullable().describe("Echoes the `redirectUrl` set at creation, if any. `null` if none was set."),
491
- checkoutUrl: import_zod9.z.string().nullable().describe(
508
+ redirectUrl: import_zod10.z.string().nullable().describe("Echoes the `redirectUrl` set at creation, if any. `null` if none was set."),
509
+ checkoutUrl: import_zod10.z.string().nullable().describe(
492
510
  "Link to Klappay's hosted checkout page for this charge. `null` if this deployment has no hosted checkout configured \u2014 build your own payment UI from `address`/`acceptedPayments` instead."
493
511
  ),
494
- splitRecipients: import_zod9.z.array(SplitRecipientSchema).describe("Echoes whatever extra split recipients were set at creation \u2014 empty array if none."),
495
- createdAt: import_zod9.z.string().datetime(),
496
- expiresAt: import_zod9.z.string().datetime().describe(
512
+ splitRecipients: import_zod10.z.array(SplitRecipientSchema).describe("Echoes whatever extra split recipients were set at creation \u2014 empty array if none."),
513
+ createdAt: import_zod10.z.string().datetime(),
514
+ expiresAt: import_zod10.z.string().datetime().describe(
497
515
  "When this charge stops accepting payment, if still `pending`/`partially_paid` by then."
498
516
  ),
499
- confirmedAt: import_zod9.z.string().datetime().nullable().describe("When `status` first reached `confirmed`. `null` until then."),
500
- settledAt: import_zod9.z.string().datetime().nullable().describe(
517
+ confirmedAt: import_zod10.z.string().datetime().nullable().describe("When `status` first reached `confirmed`. `null` until then."),
518
+ settledAt: import_zod10.z.string().datetime().nullable().describe(
501
519
  "When `settlementStatus` first reached `completed` \u2014 the merchant's wallet actually has the funds. `null` until then, including while `settlementStatus` is `pending`/`failed`."
502
520
  ),
503
- lastActivityAt: import_zod9.z.string().datetime().describe(
521
+ lastActivityAt: import_zod10.z.string().datetime().describe(
504
522
  "When a transfer was last credited toward this charge, or `createdAt` if none has arrived yet."
523
+ ),
524
+ escrow: import_zod10.z.object({
525
+ releaserAddress: import_zod10.z.string().describe("The only address that can ever release this escrow \u2014 never Klappay."),
526
+ releasedAt: import_zod10.z.string().datetime().nullable().describe("When the release actually executed on-chain. `null` until then.")
527
+ }).nullable().describe(
528
+ "Present only when this charge was created as an escrow (see `escrow` on the create request) \u2014 `null` for a normal charge."
505
529
  )
506
530
  });
507
- var ListChargesSchema = import_zod9.z.object({
531
+ var ListChargesSchema = import_zod10.z.object({
508
532
  status: ChargeStatusSchema.optional(),
509
533
  token: TokenSchema.optional().describe(
510
534
  "Filters on `paidWith.token` \u2014 the pair actually paid, not accepted."
@@ -513,13 +537,13 @@ var ListChargesSchema = import_zod9.z.object({
513
537
  "Filters on `paidWith.network` \u2014 the pair actually paid, not accepted."
514
538
  ),
515
539
  environment: EnvironmentSchema.optional(),
516
- since: import_zod9.z.string().datetime().optional().describe(
540
+ since: import_zod10.z.string().datetime().optional().describe(
517
541
  "Only return charges created at or after this timestamp (filters on `createdAt`, not on when the status last changed). If polling as a fallback for missed webhooks, use a window at least as wide as the longest `expiresIn` your charges use, or you can miss a long-lived charge that changed status outside a narrower window."
518
542
  ),
519
- isOverpaid: import_zod9.z.enum(["true", "false"]).transform((v) => v === "true").optional()
543
+ isOverpaid: import_zod10.z.enum(["true", "false"]).transform((v) => v === "true").optional()
520
544
  }).extend(PaginationQuerySchema.shape);
521
545
  var PaginatedChargesSchema = paginatedSchema(ChargeSchema);
522
- var GetChargeQrCodeQuerySchema = import_zod9.z.object({
546
+ var GetChargeQrCodeQuerySchema = import_zod10.z.object({
523
547
  token: TokenSchema.optional().describe(
524
548
  "Which accepted `(token, network)` pair to encode in the QR \u2014 required if `acceptedPayments` has more than one pair, since there is no single unambiguous default to fall back to. Ignored (and unnecessary) when the charge accepts exactly one pair."
525
549
  ),
@@ -527,9 +551,9 @@ var GetChargeQrCodeQuerySchema = import_zod9.z.object({
527
551
  });
528
552
 
529
553
  // src/charge-check.ts
530
- var import_zod10 = require("zod");
531
- var CheckChargeRequestSchema = import_zod10.z.object({
532
- txHash: import_zod10.z.string().regex(/^0x[0-9a-fA-F]{64}$/, "must be a 32-byte transaction hash").optional().describe(
554
+ var import_zod11 = require("zod");
555
+ var CheckChargeRequestSchema = import_zod11.z.object({
556
+ txHash: import_zod11.z.string().regex(/^0x[0-9a-fA-F]{64}$/, "must be a 32-byte transaction hash").optional().describe(
533
557
  "The on-chain transaction hash to verify directly, if you already have it \u2014 e.g. right after a swap-to-pay or wallet-connect transaction is sent. Costs a single RPC call instead of scanning a block range, so the check resolves faster and cheaper. Omit to fall back to scanning recent transfers to this charge's address, the same lookup the background reconciliation pass runs. Never trusted at face value \u2014 whatever this transaction actually contains on-chain is what gets credited, regardless of any amount/token implied elsewhere."
534
558
  ),
535
559
  network: NetworkSchema.optional().describe(
@@ -540,61 +564,61 @@ var CheckChargeRequestSchema = import_zod10.z.object({
540
564
  });
541
565
 
542
566
  // src/distributions.ts
543
- var import_zod11 = require("zod");
544
- var SplitDistributionStatusSchema = import_zod11.z.enum(["pending", "processing", "completed", "failed"]).describe(
567
+ var import_zod12 = require("zod");
568
+ var SplitDistributionStatusSchema = import_zod12.z.enum(["pending", "processing", "completed", "failed"]).describe(
545
569
  "Status of one payout attempt to the merchant, for a single `(token, network)` pair \u2014 a charge that settles across more than one pair has one of these per pair. `pending`: queued, not yet claimed by a distributor. `processing`: a distributor (Klappay's own worker, or anyone racing to call `distribute()` first, see `PendingDistributionSchema`) has claimed it and is submitting the on-chain transaction. `completed`: the merchant's wallet has the funds. `failed`: every automatic retry was exhausted."
546
570
  );
547
- var PendingDistributionRecipientSchema = import_zod11.z.object({
548
- address: import_zod11.z.string().describe("On-chain recipient address."),
549
- percentAllocation: import_zod11.z.number().describe("This recipient's share of the split, as a percentage (e.g. `99.0991` = 99.0991%).")
571
+ var PendingDistributionRecipientSchema = import_zod12.z.object({
572
+ address: import_zod12.z.string().describe("On-chain recipient address."),
573
+ percentAllocation: import_zod12.z.number().describe("This recipient's share of the split, as a percentage (e.g. `99.0991` = 99.0991%).")
550
574
  });
551
- var PendingDistributionSchema = import_zod11.z.object({
552
- splitAddress: import_zod11.z.string().describe("The on-chain 0xSplits address to call `distribute()` on."),
575
+ var PendingDistributionSchema = import_zod12.z.object({
576
+ splitAddress: import_zod12.z.string().describe("The on-chain 0xSplits address to call `distribute()` on."),
553
577
  network: NetworkSchema,
554
578
  token: TokenSchema,
555
- recipients: import_zod11.z.array(PendingDistributionRecipientSchema).describe(
579
+ recipients: import_zod12.z.array(PendingDistributionRecipientSchema).describe(
556
580
  "The exact recipient list to pass to `distribute()` \u2014 the split contract only stores a hash of this config, so the caller must supply the identical array to prove it matches. Always present, never reconstructed from partial data."
557
581
  ),
558
- distributorFeePercent: import_zod11.z.number().describe(
582
+ distributorFeePercent: import_zod12.z.number().describe(
559
583
  "Percentage of the split balance paid to whoever calls `distribute()` first (e.g. `0.1` = 0.1%). Frozen at charge creation, same for every distribution today."
560
584
  ),
561
- estimatedRewardAmount: import_zod11.z.number().describe(
585
+ estimatedRewardAmount: import_zod12.z.number().describe(
562
586
  "Estimate only, in the charge's `currency` units, based on the amount Klappay detected on-chain \u2014 not a live read of the split's current balance. Read the balance yourself before submitting a transaction; a stale estimate is harmless (see the docs), never a reason to skip that check."
563
587
  ),
564
- availableSince: import_zod11.z.string().datetime().describe("When this distribution entered its grace period."),
565
- graceEndsAt: import_zod11.z.string().datetime().describe(
588
+ availableSince: import_zod12.z.string().datetime().describe("When this distribution entered its grace period."),
589
+ graceEndsAt: import_zod12.z.string().datetime().describe(
566
590
  "When Klappay's own worker may claim this distribution. Racing to call `distribute()` after this timestamp is possible but increasingly likely to lose to the worker."
567
591
  )
568
592
  });
569
593
  var PaginatedPendingDistributionsSchema = paginatedSchema(PendingDistributionSchema);
570
- var ListenPendingDistributionsQuerySchema = import_zod11.z.object({
571
- limit: import_zod11.z.coerce.number().int().min(0).max(PAGINATION_LIMIT_MAX).default(0).describe(
594
+ var ListenPendingDistributionsQuerySchema = import_zod12.z.object({
595
+ limit: import_zod12.z.coerce.number().int().min(0).max(PAGINATION_LIMIT_MAX).default(0).describe(
572
596
  "How many currently-claimable distributions to emit as an initial snapshot right after connecting \u2014 each as a synthetic `distribution.available` event \u2014 before continuing with real-time deltas. `0` (the default, same as omitting it) sends no snapshot at all, matching this endpoint's original behavior: connect first, then call `GET /v1/distributions/pending` yourself to bootstrap. Not a page \u2014 there is no cursor for this snapshot, so if more than `limit` are claimable at connect time, the excess is simply not sent; call `GET /v1/distributions/pending` directly for a complete, paginated listing."
573
597
  )
574
598
  });
575
- var PendingDistributionEventSchema = import_zod11.z.discriminatedUnion("type", [
576
- import_zod11.z.object({
577
- type: import_zod11.z.literal("distribution.available"),
599
+ var PendingDistributionEventSchema = import_zod12.z.discriminatedUnion("type", [
600
+ import_zod12.z.object({
601
+ type: import_zod12.z.literal("distribution.available"),
578
602
  distribution: PendingDistributionSchema
579
603
  }),
580
- import_zod11.z.object({
581
- type: import_zod11.z.literal("distribution.claimed"),
582
- splitAddress: import_zod11.z.string().describe("No longer claimable \u2014 either settled by someone, or picked up by the worker.")
604
+ import_zod12.z.object({
605
+ type: import_zod12.z.literal("distribution.claimed"),
606
+ splitAddress: import_zod12.z.string().describe("No longer claimable \u2014 either settled by someone, or picked up by the worker.")
583
607
  })
584
608
  ]);
585
609
 
586
610
  // src/metrics.ts
587
- var import_zod12 = require("zod");
588
- var MetricsResourceSchema = import_zod12.z.enum(["charges", "transactions", "distributions"]).describe(
611
+ var import_zod13 = require("zod");
612
+ var MetricsResourceSchema = import_zod13.z.enum(["charges", "transactions", "distributions"]).describe(
589
613
  "Which underlying dataset to query. `charges`: one row per charge. `transactions`: one row per detected on-chain transfer \u2014 a charge paid in installments has more than one. `distributions`: one row per payout attempt to the merchant, one per `(token, network)` pair a charge settled across."
590
614
  );
591
- var MetricsAggregationSchema = import_zod12.z.enum(["count", "sum", "avg", "min", "max"]).describe(
615
+ var MetricsAggregationSchema = import_zod13.z.enum(["count", "sum", "avg", "min", "max"]).describe(
592
616
  "`count` counts matching rows and never takes `field`. `sum`/`avg`/`min`/`max` require `field` to be set to one of the resource\u2019s numeric fields."
593
617
  );
594
- var MetricsFilterOperatorSchema = import_zod12.z.enum(["eq", "neq", "in", "gt", "gte", "lt", "lte"]).describe(
618
+ var MetricsFilterOperatorSchema = import_zod13.z.enum(["eq", "neq", "in", "gt", "gte", "lt", "lte"]).describe(
595
619
  "`in` expects an array value (max 50 entries); every other operator expects a single scalar."
596
620
  );
597
- var MetricsDateGranularitySchema = import_zod12.z.enum(["day", "week", "month", "year"]).describe(
621
+ var MetricsDateGranularitySchema = import_zod13.z.enum(["day", "week", "month", "year"]).describe(
598
622
  "Bucket width for a `date_bucket` `groupBy` entry \u2014 Postgres `date_trunc` semantics (UTC)."
599
623
  );
600
624
  var metricsQueryEnvironmentSchema = EnvironmentSchema.describe(
@@ -607,151 +631,159 @@ var METRICS_QUERY_MAX_GROUP_BY = 3;
607
631
  var METRICS_QUERY_MAX_FILTERS = 20;
608
632
  var METRICS_QUERY_MAX_METRICS = 10;
609
633
  var METRIC_ALIAS_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
610
- var metricAliasSchema = import_zod12.z.string().min(1).max(64).regex(
634
+ var metricAliasSchema = import_zod13.z.string().min(1).max(64).regex(
611
635
  METRIC_ALIAS_PATTERN,
612
636
  "Must start with a letter or underscore, and contain only letters, digits, and underscores \u2014 this becomes a SQL column alias."
613
637
  ).optional();
614
- var MetricsFilterValueSchema = import_zod12.z.union([
615
- import_zod12.z.string().max(255),
616
- import_zod12.z.number(),
617
- import_zod12.z.boolean(),
618
- import_zod12.z.array(import_zod12.z.union([import_zod12.z.string().max(255), import_zod12.z.number()])).min(1).max(50)
638
+ var MetricsFilterValueSchema = import_zod13.z.union([
639
+ import_zod13.z.string().max(255),
640
+ import_zod13.z.number(),
641
+ import_zod13.z.boolean(),
642
+ import_zod13.z.array(import_zod13.z.union([import_zod13.z.string().max(255), import_zod13.z.number()])).min(1).max(50)
619
643
  ]);
620
- var orderBySchema = import_zod12.z.object({
621
- key: import_zod12.z.string().min(1).max(64).regex(
644
+ var orderBySchema = import_zod13.z.object({
645
+ key: import_zod13.z.string().min(1).max(64).regex(
622
646
  METRIC_ALIAS_PATTERN,
623
647
  "Must start with a letter or underscore, and contain only letters, digits, and underscores \u2014 every valid output column name already looks like this."
624
648
  ).describe(
625
649
  "An output column name from this same query \u2014 either a `groupBy` field name, or a metric\u2019s `alias` (or its default name: `${aggregation}` for `count`, `${aggregation}_${field}` otherwise, e.g. `sum_amount`). Must match `^[a-zA-Z_][a-zA-Z0-9_]*$` \u2014 every real output column name already does, so this only ever rejects a value that could never have been one."
626
650
  ),
627
- direction: import_zod12.z.enum(["asc", "desc"])
651
+ direction: import_zod13.z.enum(["asc", "desc"])
628
652
  }).describe(
629
653
  "Sort the result rows by any output column \u2014 including the bucket field itself for a `date_bucket` query (e.g. `createdAt`). Omit to get ascending-by-bucket order for a date-bucketed query, or implementation-defined (not guaranteed stable) order otherwise."
630
654
  );
631
- var limitSchema = import_zod12.z.number().int().min(1).max(METRICS_QUERY_MAX_ROW_LIMIT).default(METRICS_QUERY_DEFAULT_ROW_LIMIT).describe(
655
+ var limitSchema = import_zod13.z.number().int().min(1).max(METRICS_QUERY_MAX_ROW_LIMIT).default(METRICS_QUERY_DEFAULT_ROW_LIMIT).describe(
632
656
  `Max rows to return, ${1}\u2013${METRICS_QUERY_MAX_ROW_LIMIT}, default ${METRICS_QUERY_DEFAULT_ROW_LIMIT}. If more rows matched, \`meta.truncated\` is \`true\` on the response \u2014 narrow the query instead of just raising this.`
633
657
  );
634
- var ChargesQueryFieldSchema = import_zod12.z.enum(["status", "source", "apiKeyId", "currency", "isOverpaid", "externalRef"]).describe(
635
- "A `Charge` field to filter or group by \u2014 see `ChargeStatusSchema` for `status`'s own possible values (charges.md). `source`/`externalRef` are free-form strings your own integration set at creation, not a fixed enum."
658
+ var ChargesQueryFieldSchema = import_zod13.z.enum([
659
+ "status",
660
+ "source",
661
+ "apiKeyId",
662
+ "currency",
663
+ "isOverpaid",
664
+ "externalRef",
665
+ "escrowReleaserAddress"
666
+ ]).describe(
667
+ "A `Charge` field to filter or group by \u2014 see `ChargeStatusSchema` for `status`'s own possible values (charges.md). `source`/`externalRef` are free-form strings your own integration set at creation, not a fixed enum. `escrowReleaserAddress` is `null` for a normal charge \u2014 filter `escrowReleaserAddress` with operator `neq`/value `null` to isolate escrow-configured charges (see `escrow` in charges.md)."
636
668
  );
637
- var ChargesMetricFieldSchema = import_zod12.z.enum(["amount", "amountReceived", "feePercent"]).describe(
638
- "A `Charge` numeric field to aggregate. `amount`/`amountReceived` are decimal currency amounts (requested vs. actually received \u2014 see `charges.md`). `feePercent` is the platform fee frozen on the charge at creation, e.g. `1.5` means 1.5%."
669
+ var ChargesMetricFieldSchema = import_zod13.z.enum(["amount", "amountReceived", "feePercent", "escrowFeePercent"]).describe(
670
+ "A `Charge` numeric field to aggregate. `amount`/`amountReceived` are decimal currency amounts (requested vs. actually received \u2014 see `charges.md`). `feePercent` is the platform fee frozen on the charge at creation, e.g. `1.5` means 1.5%. `escrowFeePercent` is the additional escrow-specific fee component, only present on escrow-configured charges \u2014 see `docs/payments.md`."
639
671
  );
640
- var ChargesDateFieldSchema = import_zod12.z.enum(["createdAt", "confirmedAt", "lastActivityAt", "expiresAt"]).describe(
641
- "A `Charge` timestamp to filter/bucket by. `confirmedAt` is `null` until the charge reaches `confirmed` \u2014 a `dateRange`/`date_bucket` on it implicitly excludes every charge that never confirmed. `expiresAt` is always present (set at creation), useful for e.g. finding charges expiring soon or measuring how close to expiry charges typically resolve."
672
+ var ChargesDateFieldSchema = import_zod13.z.enum(["createdAt", "confirmedAt", "lastActivityAt", "expiresAt", "escrowReleasedAt"]).describe(
673
+ "A `Charge` timestamp to filter/bucket by. `confirmedAt` is `null` until the charge reaches `confirmed` \u2014 a `dateRange`/`date_bucket` on it implicitly excludes every charge that never confirmed. `expiresAt` is always present (set at creation), useful for e.g. finding charges expiring soon or measuring how close to expiry charges typically resolve. `escrowReleasedAt` is `null` until an escrow-configured charge is actually released \u2014 same implicit-exclusion behavior as `confirmedAt`, scoped to escrow charges only."
642
674
  );
643
- var ChargesFilterSchema = import_zod12.z.object({
675
+ var ChargesFilterSchema = import_zod13.z.object({
644
676
  field: ChargesQueryFieldSchema,
645
677
  operator: MetricsFilterOperatorSchema,
646
678
  value: MetricsFilterValueSchema
647
679
  });
648
- var ChargesGroupBySchema = import_zod12.z.union([
649
- import_zod12.z.object({ type: import_zod12.z.literal("field"), field: ChargesQueryFieldSchema }),
650
- import_zod12.z.object({
651
- type: import_zod12.z.literal("date_bucket"),
680
+ var ChargesGroupBySchema = import_zod13.z.union([
681
+ import_zod13.z.object({ type: import_zod13.z.literal("field"), field: ChargesQueryFieldSchema }),
682
+ import_zod13.z.object({
683
+ type: import_zod13.z.literal("date_bucket"),
652
684
  field: ChargesDateFieldSchema,
653
685
  granularity: MetricsDateGranularitySchema
654
686
  })
655
687
  ]);
656
- var ChargesMetricSchema = import_zod12.z.object({
688
+ var ChargesMetricSchema = import_zod13.z.object({
657
689
  aggregation: MetricsAggregationSchema,
658
690
  field: ChargesMetricFieldSchema.optional(),
659
691
  alias: metricAliasSchema
660
692
  });
661
- var ChargesMetricsQuerySchema = import_zod12.z.object({
662
- resource: import_zod12.z.literal("charges"),
693
+ var ChargesMetricsQuerySchema = import_zod13.z.object({
694
+ resource: import_zod13.z.literal("charges"),
663
695
  environment: metricsQueryEnvironmentSchema,
664
- dateRange: import_zod12.z.object({
696
+ dateRange: import_zod13.z.object({
665
697
  field: ChargesDateFieldSchema,
666
- from: import_zod12.z.string().max(64).datetime(),
667
- to: import_zod12.z.string().max(64).datetime()
698
+ from: import_zod13.z.string().max(64).datetime(),
699
+ to: import_zod13.z.string().max(64).datetime()
668
700
  }),
669
- groupBy: import_zod12.z.array(ChargesGroupBySchema).max(METRICS_QUERY_MAX_GROUP_BY).default([]),
670
- metrics: import_zod12.z.array(ChargesMetricSchema).min(1).max(METRICS_QUERY_MAX_METRICS),
671
- filters: import_zod12.z.array(ChargesFilterSchema).max(METRICS_QUERY_MAX_FILTERS).default([]),
701
+ groupBy: import_zod13.z.array(ChargesGroupBySchema).max(METRICS_QUERY_MAX_GROUP_BY).default([]),
702
+ metrics: import_zod13.z.array(ChargesMetricSchema).min(1).max(METRICS_QUERY_MAX_METRICS),
703
+ filters: import_zod13.z.array(ChargesFilterSchema).max(METRICS_QUERY_MAX_FILTERS).default([]),
672
704
  orderBy: orderBySchema.optional(),
673
705
  limit: limitSchema
674
706
  });
675
- var TransactionsQueryFieldSchema = import_zod12.z.enum(["network", "token", "source", "causedTransition"]).describe(
707
+ var TransactionsQueryFieldSchema = import_zod13.z.enum(["network", "token", "source", "causedTransition"]).describe(
676
708
  "A `Transaction` field to filter or group by \u2014 see `NetworkSchema`/`TokenSchema`/`TransactionSourceSchema` for their possible values. `causedTransition` is `true` only for the transfer(s) that actually flipped the charge's `status` \u2014 a charge paid in installments can have more than one; filtering/grouping on it excludes no-op duplicate transfers (see `TimelineEvent.causedTransition` in charges.md for the full explanation)."
677
709
  );
678
- var TransactionsMetricFieldSchema = import_zod12.z.enum(["amount"]).describe("The transfer amount, in the charge's `currency` units.");
679
- var TransactionsDateFieldSchema = import_zod12.z.enum(["detectedAt"]).describe("When Klappay detected this transfer on-chain (not when it was mined).");
680
- var TransactionsFilterSchema = import_zod12.z.object({
710
+ var TransactionsMetricFieldSchema = import_zod13.z.enum(["amount"]).describe("The transfer amount, in the charge's `currency` units.");
711
+ var TransactionsDateFieldSchema = import_zod13.z.enum(["detectedAt"]).describe("When Klappay detected this transfer on-chain (not when it was mined).");
712
+ var TransactionsFilterSchema = import_zod13.z.object({
681
713
  field: TransactionsQueryFieldSchema,
682
714
  operator: MetricsFilterOperatorSchema,
683
715
  value: MetricsFilterValueSchema
684
716
  });
685
- var TransactionsGroupBySchema = import_zod12.z.union([
686
- import_zod12.z.object({ type: import_zod12.z.literal("field"), field: TransactionsQueryFieldSchema }),
687
- import_zod12.z.object({
688
- type: import_zod12.z.literal("date_bucket"),
717
+ var TransactionsGroupBySchema = import_zod13.z.union([
718
+ import_zod13.z.object({ type: import_zod13.z.literal("field"), field: TransactionsQueryFieldSchema }),
719
+ import_zod13.z.object({
720
+ type: import_zod13.z.literal("date_bucket"),
689
721
  field: TransactionsDateFieldSchema,
690
722
  granularity: MetricsDateGranularitySchema
691
723
  })
692
724
  ]);
693
- var TransactionsMetricSchema = import_zod12.z.object({
725
+ var TransactionsMetricSchema = import_zod13.z.object({
694
726
  aggregation: MetricsAggregationSchema,
695
727
  field: TransactionsMetricFieldSchema.optional(),
696
728
  alias: metricAliasSchema
697
729
  });
698
- var TransactionsMetricsQuerySchema = import_zod12.z.object({
699
- resource: import_zod12.z.literal("transactions"),
730
+ var TransactionsMetricsQuerySchema = import_zod13.z.object({
731
+ resource: import_zod13.z.literal("transactions"),
700
732
  environment: metricsQueryEnvironmentSchema,
701
- dateRange: import_zod12.z.object({
733
+ dateRange: import_zod13.z.object({
702
734
  field: TransactionsDateFieldSchema,
703
- from: import_zod12.z.string().max(64).datetime(),
704
- to: import_zod12.z.string().max(64).datetime()
735
+ from: import_zod13.z.string().max(64).datetime(),
736
+ to: import_zod13.z.string().max(64).datetime()
705
737
  }),
706
- groupBy: import_zod12.z.array(TransactionsGroupBySchema).max(METRICS_QUERY_MAX_GROUP_BY).default([]),
707
- metrics: import_zod12.z.array(TransactionsMetricSchema).min(1).max(METRICS_QUERY_MAX_METRICS),
708
- filters: import_zod12.z.array(TransactionsFilterSchema).max(METRICS_QUERY_MAX_FILTERS).default([]),
738
+ groupBy: import_zod13.z.array(TransactionsGroupBySchema).max(METRICS_QUERY_MAX_GROUP_BY).default([]),
739
+ metrics: import_zod13.z.array(TransactionsMetricSchema).min(1).max(METRICS_QUERY_MAX_METRICS),
740
+ filters: import_zod13.z.array(TransactionsFilterSchema).max(METRICS_QUERY_MAX_FILTERS).default([]),
709
741
  orderBy: orderBySchema.optional(),
710
742
  limit: limitSchema
711
743
  });
712
- var DistributionsQueryFieldSchema = import_zod12.z.enum(["status", "network", "token", "distributorAddress"]).describe(
744
+ var DistributionsQueryFieldSchema = import_zod13.z.enum(["status", "network", "token", "distributorAddress"]).describe(
713
745
  "A `SplitDistribution` field to filter or group by \u2014 see `SplitDistributionStatusSchema`/`NetworkSchema`/`TokenSchema` for their possible values. `distributorAddress` is the public on-chain address that actually called `distribute()` for a `completed` distribution \u2014 Klappay's own operator address if settled by Klappay's own worker, a community keeper's address if settled externally (or `null` on the rare case that lookup failed), `null` for every non-`completed` status."
714
746
  );
715
- var DistributionsMetricFieldSchema = import_zod12.z.enum(["attempts"]).describe(
747
+ var DistributionsMetricFieldSchema = import_zod13.z.enum(["attempts"]).describe(
716
748
  "How many times a payout was attempted for this settlement so far \u2014 incremented on every attempt, whether it succeeded or is being retried after failing. A high `attempts` alongside `status: 'failed'` means every automatic retry was exhausted."
717
749
  );
718
- var DistributionsDateFieldSchema = import_zod12.z.enum(["createdAt", "processingStartedAt", "completedAt"]).describe(
750
+ var DistributionsDateFieldSchema = import_zod13.z.enum(["createdAt", "processingStartedAt", "completedAt"]).describe(
719
751
  "`createdAt`: when this settlement was queued. `processingStartedAt`: when a worker began its most recent attempt at the payout \u2014 `null` until the first attempt, then overwritten on every subsequent retry, so it reflects the *latest* attempt's start, not the first. `completedAt`: when it actually paid out \u2014 `null` until `status` reaches `completed`, so a `dateRange`/`date_bucket` on it implicitly excludes every distribution still pending/processing/failed."
720
752
  );
721
- var DistributionsFilterSchema = import_zod12.z.object({
753
+ var DistributionsFilterSchema = import_zod13.z.object({
722
754
  field: DistributionsQueryFieldSchema,
723
755
  operator: MetricsFilterOperatorSchema,
724
756
  value: MetricsFilterValueSchema
725
757
  });
726
- var DistributionsGroupBySchema = import_zod12.z.union([
727
- import_zod12.z.object({ type: import_zod12.z.literal("field"), field: DistributionsQueryFieldSchema }),
728
- import_zod12.z.object({
729
- type: import_zod12.z.literal("date_bucket"),
758
+ var DistributionsGroupBySchema = import_zod13.z.union([
759
+ import_zod13.z.object({ type: import_zod13.z.literal("field"), field: DistributionsQueryFieldSchema }),
760
+ import_zod13.z.object({
761
+ type: import_zod13.z.literal("date_bucket"),
730
762
  field: DistributionsDateFieldSchema,
731
763
  granularity: MetricsDateGranularitySchema
732
764
  })
733
765
  ]);
734
- var DistributionsMetricSchema = import_zod12.z.object({
766
+ var DistributionsMetricSchema = import_zod13.z.object({
735
767
  aggregation: MetricsAggregationSchema,
736
768
  field: DistributionsMetricFieldSchema.optional(),
737
769
  alias: metricAliasSchema
738
770
  });
739
- var DistributionsMetricsQuerySchema = import_zod12.z.object({
740
- resource: import_zod12.z.literal("distributions"),
771
+ var DistributionsMetricsQuerySchema = import_zod13.z.object({
772
+ resource: import_zod13.z.literal("distributions"),
741
773
  environment: metricsQueryEnvironmentSchema,
742
- dateRange: import_zod12.z.object({
774
+ dateRange: import_zod13.z.object({
743
775
  field: DistributionsDateFieldSchema,
744
- from: import_zod12.z.string().max(64).datetime(),
745
- to: import_zod12.z.string().max(64).datetime()
776
+ from: import_zod13.z.string().max(64).datetime(),
777
+ to: import_zod13.z.string().max(64).datetime()
746
778
  }),
747
- groupBy: import_zod12.z.array(DistributionsGroupBySchema).max(METRICS_QUERY_MAX_GROUP_BY).default([]),
748
- metrics: import_zod12.z.array(DistributionsMetricSchema).min(1).max(METRICS_QUERY_MAX_METRICS),
749
- filters: import_zod12.z.array(DistributionsFilterSchema).max(METRICS_QUERY_MAX_FILTERS).default([]),
779
+ groupBy: import_zod13.z.array(DistributionsGroupBySchema).max(METRICS_QUERY_MAX_GROUP_BY).default([]),
780
+ metrics: import_zod13.z.array(DistributionsMetricSchema).min(1).max(METRICS_QUERY_MAX_METRICS),
781
+ filters: import_zod13.z.array(DistributionsFilterSchema).max(METRICS_QUERY_MAX_FILTERS).default([]),
750
782
  orderBy: orderBySchema.optional(),
751
783
  limit: limitSchema
752
784
  });
753
785
  var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
754
- var MetricsQuerySchema = import_zod12.z.discriminatedUnion("resource", [
786
+ var MetricsQuerySchema = import_zod13.z.discriminatedUnion("resource", [
755
787
  ChargesMetricsQuerySchema,
756
788
  TransactionsMetricsQuerySchema,
757
789
  DistributionsMetricsQuerySchema
@@ -760,7 +792,7 @@ var MetricsQuerySchema = import_zod12.z.discriminatedUnion("resource", [
760
792
  const to = new Date(input.dateRange.to);
761
793
  if (from >= to) {
762
794
  ctx.addIssue({
763
- code: import_zod12.z.ZodIssueCode.custom,
795
+ code: import_zod13.z.ZodIssueCode.custom,
764
796
  message: "`dateRange.from` must be before `dateRange.to`.",
765
797
  path: ["dateRange", "from"]
766
798
  });
@@ -768,7 +800,7 @@ var MetricsQuerySchema = import_zod12.z.discriminatedUnion("resource", [
768
800
  const spanDays = (to.getTime() - from.getTime()) / ONE_DAY_MS;
769
801
  if (spanDays > MAX_METRICS_QUERY_DATE_RANGE_DAYS) {
770
802
  ctx.addIssue({
771
- code: import_zod12.z.ZodIssueCode.custom,
803
+ code: import_zod13.z.ZodIssueCode.custom,
772
804
  message: `\`dateRange\` cannot span more than ${MAX_METRICS_QUERY_DATE_RANGE_DAYS} days.`,
773
805
  path: ["dateRange", "to"]
774
806
  });
@@ -776,7 +808,7 @@ var MetricsQuerySchema = import_zod12.z.discriminatedUnion("resource", [
776
808
  const dateBucketCount = input.groupBy.filter((entry) => entry.type === "date_bucket").length;
777
809
  if (dateBucketCount > 1) {
778
810
  ctx.addIssue({
779
- code: import_zod12.z.ZodIssueCode.custom,
811
+ code: import_zod13.z.ZodIssueCode.custom,
780
812
  message: "At most one `date_bucket` entry is allowed in `groupBy`.",
781
813
  path: ["groupBy"]
782
814
  });
@@ -784,7 +816,7 @@ var MetricsQuerySchema = import_zod12.z.discriminatedUnion("resource", [
784
816
  input.metrics.forEach((metric, index) => {
785
817
  if (metric.aggregation !== "count" && metric.field === void 0) {
786
818
  ctx.addIssue({
787
- code: import_zod12.z.ZodIssueCode.custom,
819
+ code: import_zod13.z.ZodIssueCode.custom,
788
820
  message: "`field` is required unless `aggregation` is `count`.",
789
821
  path: ["metrics", index, "field"]
790
822
  });
@@ -793,7 +825,7 @@ var MetricsQuerySchema = import_zod12.z.discriminatedUnion("resource", [
793
825
  const aliases = input.metrics.map((metric) => metric.alias).filter((alias) => alias !== void 0);
794
826
  if (new Set(aliases).size !== aliases.length) {
795
827
  ctx.addIssue({
796
- code: import_zod12.z.ZodIssueCode.custom,
828
+ code: import_zod13.z.ZodIssueCode.custom,
797
829
  message: "Every `metrics[].alias` must be unique.",
798
830
  path: ["metrics"]
799
831
  });
@@ -802,32 +834,32 @@ var MetricsQuerySchema = import_zod12.z.discriminatedUnion("resource", [
802
834
  input.metrics.forEach((metric, index) => {
803
835
  if (metric.alias !== void 0 && reservedNames.has(metric.alias)) {
804
836
  ctx.addIssue({
805
- code: import_zod12.z.ZodIssueCode.custom,
837
+ code: import_zod13.z.ZodIssueCode.custom,
806
838
  message: `\`alias\` "${metric.alias}" collides with a \`groupBy\` field name (or the reserved word "bucket") \u2014 choose a different alias.`,
807
839
  path: ["metrics", index, "alias"]
808
840
  });
809
841
  }
810
842
  });
811
843
  });
812
- var MetricsQueryResultRowSchema = import_zod12.z.record(
813
- import_zod12.z.string(),
814
- import_zod12.z.union([import_zod12.z.string(), import_zod12.z.number(), import_zod12.z.boolean(), import_zod12.z.null()])
844
+ var MetricsQueryResultRowSchema = import_zod13.z.record(
845
+ import_zod13.z.string(),
846
+ import_zod13.z.union([import_zod13.z.string(), import_zod13.z.number(), import_zod13.z.boolean(), import_zod13.z.null()])
815
847
  );
816
- var MetricsQueryResultSchema = import_zod12.z.object({
817
- data: import_zod12.z.array(MetricsQueryResultRowSchema),
818
- meta: import_zod12.z.object({
848
+ var MetricsQueryResultSchema = import_zod13.z.object({
849
+ data: import_zod13.z.array(MetricsQueryResultRowSchema),
850
+ meta: import_zod13.z.object({
819
851
  resource: MetricsResourceSchema,
820
852
  environment: EnvironmentSchema,
821
- rowCount: import_zod12.z.number().int().describe("Number of rows in `data`."),
822
- truncated: import_zod12.z.boolean().describe(
853
+ rowCount: import_zod13.z.number().int().describe("Number of rows in `data`."),
854
+ truncated: import_zod13.z.boolean().describe(
823
855
  "`true` if more rows matched than `limit` allowed \u2014 `data` holds only the first `limit`."
824
856
  )
825
857
  })
826
858
  });
827
859
 
828
860
  // src/webhook-events.ts
829
- var import_zod13 = require("zod");
830
- var ChargeWebhookEventTypeSchema = import_zod13.z.enum([
861
+ var import_zod14 = require("zod");
862
+ var ChargeWebhookEventTypeSchema = import_zod14.z.enum([
831
863
  "charge.created",
832
864
  "charge.partially_paid",
833
865
  "charge.confirmed",
@@ -839,14 +871,14 @@ var ChargeWebhookEventTypeSchema = import_zod13.z.enum([
839
871
  ]).describe(
840
872
  'Note the distinction between `charge.confirmed` and `charge.settled`: `confirmed` means the payment was detected on-chain; `settled` means the merchant\'s wallet actually received the funds \u2014 a separate, later step. Subscribe to `confirmed` if you only need "will I get paid," or `settled` if you need "has the money actually arrived." `charge.overpaid` fires alongside `charge.confirmed`/`charge.partially_paid` whenever the cumulative amount received ends up above `amount` (see `Charge.isOverpaid`). Every event in this category carries the full `Charge` object as `data`.'
841
873
  );
842
- var WebhookDeliveryEventTypeSchema = import_zod13.z.enum(["webhook.delivery_failed", "webhook.delivery_recovered", "webhook.endpoint_unhealthy"]).describe(
874
+ var WebhookDeliveryEventTypeSchema = import_zod14.z.enum(["webhook.delivery_failed", "webhook.delivery_recovered", "webhook.endpoint_unhealthy"]).describe(
843
875
  "Meta-events about the health of your own webhook endpoints \u2014 useful for monitoring without polling `GET /v1/webhooks/{id}/deliveries`. `webhook.endpoint_unhealthy` fires once when a webhook's failure rate over the trailing 24h crosses 20%, and `webhook.delivery_recovered` fires once when a delivery to that webhook next succeeds. `data` for every event in this category: `{ webhookId, url, failureRatio? }` (`failureRatio` only present on `webhook.endpoint_unhealthy`)."
844
876
  );
845
- var WebhookEventTypeSchema = import_zod13.z.union([
877
+ var WebhookEventTypeSchema = import_zod14.z.union([
846
878
  ChargeWebhookEventTypeSchema,
847
879
  WebhookDeliveryEventTypeSchema
848
880
  ]);
849
- var WebhookCategorySchema = import_zod13.z.enum(["payments", "webhooks"]).describe(
881
+ var WebhookCategorySchema = import_zod14.z.enum(["payments", "webhooks"]).describe(
850
882
  "Subscribe to every event in a category via `eventCategories` instead of listing events one by one \u2014 new events added to a category later arrive automatically, no subscription update needed."
851
883
  );
852
884
  function buildCategoryMap() {
@@ -874,101 +906,101 @@ var TriggerableChargeEventSchema = ChargeWebhookEventTypeSchema.exclude([
874
906
  );
875
907
 
876
908
  // src/webhooks.ts
877
- var import_zod14 = require("zod");
909
+ var import_zod15 = require("zod");
878
910
  var WEBHOOK_EVENTS_WILDCARD = "*";
879
- var CreateWebhookSchema = import_zod14.z.object({
880
- url: import_zod14.z.string().max(2048).url().describe(
911
+ var CreateWebhookSchema = import_zod15.z.object({
912
+ url: import_zod15.z.string().max(2048).url().describe(
881
913
  "Must be HTTPS and resolve to a public address \u2014 private/internal IPs are rejected."
882
914
  ),
883
- events: import_zod14.z.array(import_zod14.z.union([WebhookEventTypeSchema, import_zod14.z.literal(WEBHOOK_EVENTS_WILDCARD)])).max(Object.keys(EVENT_CATEGORY_MAP).length + 1).default([]).describe(
915
+ events: import_zod15.z.array(import_zod15.z.union([WebhookEventTypeSchema, import_zod15.z.literal(WEBHOOK_EVENTS_WILDCARD)])).max(Object.keys(EVENT_CATEGORY_MAP).length + 1).default([]).describe(
884
916
  'Individual event types to receive, or `"*"` for every event (combine with `excludeEvents` to opt back out of specific ones). Omit in favor of `eventCategories` if you want whole categories instead.'
885
917
  ),
886
- eventCategories: import_zod14.z.array(WebhookCategorySchema).max(WebhookCategorySchema.options.length).default([]).describe(
918
+ eventCategories: import_zod15.z.array(WebhookCategorySchema).max(WebhookCategorySchema.options.length).default([]).describe(
887
919
  "Subscribe to every event in these categories. At least one of `events` or `eventCategories` is required."
888
920
  ),
889
- excludeEvents: import_zod14.z.array(WebhookEventTypeSchema).max(Object.keys(EVENT_CATEGORY_MAP).length).default([]).describe(
921
+ excludeEvents: import_zod15.z.array(WebhookEventTypeSchema).max(Object.keys(EVENT_CATEGORY_MAP).length).default([]).describe(
890
922
  'Event types to exclude even if selected via `events: ["*"]` or `eventCategories`.'
891
923
  )
892
924
  }).refine((v) => v.events.length > 0 || v.eventCategories.length > 0, {
893
925
  message: "must select at least one event via `events` or `eventCategories`",
894
926
  path: ["events"]
895
927
  });
896
- var WebhookSchema = import_zod14.z.object({
897
- id: import_zod14.z.string(),
928
+ var WebhookSchema = import_zod15.z.object({
929
+ id: import_zod15.z.string(),
898
930
  environment: EnvironmentSchema.nullable().describe(
899
931
  "Which environment's API key created this webhook \u2014 `live` or `test`. Every event is only ever delivered to a webhook whose `environment` matches the event's own (or to a webhook with `environment: null`, which receives every environment \u2014 the case for every webhook created before this field existed)."
900
932
  ),
901
- url: import_zod14.z.string(),
902
- events: import_zod14.z.array(WebhookEventTypeSchema),
903
- eventCategories: import_zod14.z.array(WebhookCategorySchema),
904
- excludeEvents: import_zod14.z.array(WebhookEventTypeSchema),
905
- isWildcard: import_zod14.z.boolean(),
906
- secret: import_zod14.z.string().describe(
933
+ url: import_zod15.z.string(),
934
+ events: import_zod15.z.array(WebhookEventTypeSchema),
935
+ eventCategories: import_zod15.z.array(WebhookCategorySchema),
936
+ excludeEvents: import_zod15.z.array(WebhookEventTypeSchema),
937
+ isWildcard: import_zod15.z.boolean(),
938
+ secret: import_zod15.z.string().describe(
907
939
  "The signing secret, used to verify the `X-Klappay-Signature` header on every delivery. Returned in full only this once \u2014 store it now, it is not recoverable afterward. Header format: `t=<unix-seconds>,v1=<hex-encoded HMAC-SHA256>`. Compute the expected signature as `HMAC-SHA256(secret, \"${t}.${raw request body}\")` (hex-encoded) and compare it to `v1` using a constant-time comparison; as a replay-protection measure, also reject if `t` is too far from the current time \u2014 Klappay does not enforce or check any particular tolerance server-side, so the exact threshold is entirely the receiver's own policy call. An official SDK's `constructEvent()`/`verifySignature()` do this for you, defaulting to a 300-second tolerance, overridable via `constructEvent`'s `toleranceSeconds` option \u2014 see github.com/klappay for available SDKs."
908
940
  ),
909
- createdAt: import_zod14.z.string().datetime()
941
+ createdAt: import_zod15.z.string().datetime()
910
942
  });
911
943
  var WebhookListItemSchema = WebhookSchema.omit({ secret: true }).extend({
912
- hint: import_zod14.z.string().describe("A truncated, safe-to-display form of the secret (e.g. `whsec_...ab12`).")
944
+ hint: import_zod15.z.string().describe("A truncated, safe-to-display form of the secret (e.g. `whsec_...ab12`).")
913
945
  });
914
- var WebhookPayloadSchema = import_zod14.z.object({
915
- id: import_zod14.z.string().describe(
946
+ var WebhookPayloadSchema = import_zod15.z.object({
947
+ id: import_zod15.z.string().describe(
916
948
  "Unique id for this specific delivery \u2014 also sent as the `X-Klappay-Delivery` header."
917
949
  ),
918
950
  event: WebhookEventTypeSchema,
919
- createdAt: import_zod14.z.string().datetime(),
920
- data: import_zod14.z.unknown().describe(
951
+ createdAt: import_zod15.z.string().datetime(),
952
+ data: import_zod15.z.unknown().describe(
921
953
  "Event-specific data. Charge events (`charge.*`) carry the full `Charge` object; webhook-delivery events carry a smaller, event-specific object \u2014 see `WebhookEventDataMap`/`TypedWebhookPayload` for the exact shape per event, or docs/webhooks.md."
922
954
  )
923
955
  });
924
- var WebhookDeliveryStatusSchema = import_zod14.z.enum(["pending", "delivered", "failed"]);
925
- var WebhookDeliverySchema = import_zod14.z.object({
926
- id: import_zod14.z.string(),
927
- webhookId: import_zod14.z.string(),
956
+ var WebhookDeliveryStatusSchema = import_zod15.z.enum(["pending", "delivered", "failed"]);
957
+ var WebhookDeliverySchema = import_zod15.z.object({
958
+ id: import_zod15.z.string(),
959
+ webhookId: import_zod15.z.string(),
928
960
  event: WebhookEventTypeSchema,
929
961
  status: WebhookDeliveryStatusSchema.describe(
930
962
  "`pending`: still retrying. `delivered`: got a 2xx response. `failed`: retries exhausted (5 attempts over ~24h) \u2014 use `POST /v1/webhooks/{id}/deliveries/{deliveryId}/retry` to try again manually."
931
963
  ),
932
- attempts: import_zod14.z.number(),
933
- responseCode: import_zod14.z.number().nullable().describe(
964
+ attempts: import_zod15.z.number(),
965
+ responseCode: import_zod15.z.number().nullable().describe(
934
966
  "HTTP status your endpoint returned on the most recent attempt. `null` if every attempt failed to connect at all."
935
967
  ),
936
- nextRetryAt: import_zod14.z.string().datetime().nullable(),
937
- deliveredAt: import_zod14.z.string().datetime().nullable(),
938
- createdAt: import_zod14.z.string().datetime()
968
+ nextRetryAt: import_zod15.z.string().datetime().nullable(),
969
+ deliveredAt: import_zod15.z.string().datetime().nullable(),
970
+ createdAt: import_zod15.z.string().datetime()
939
971
  });
940
972
  var ListWebhookDeliveriesSchema = PaginationQuerySchema;
941
973
  var PaginatedWebhookDeliveriesSchema = paginatedSchema(WebhookDeliverySchema);
942
974
 
943
975
  // src/recipients.ts
944
- var import_zod15 = require("zod");
976
+ var import_zod16 = require("zod");
945
977
  var EVM_ADDRESS_REGEX = /^0x[0-9a-fA-F]{40}$/;
946
- var CreateRecipientSchema = import_zod15.z.object({
947
- address: import_zod15.z.string().regex(EVM_ADDRESS_REGEX, "must be a 20-byte hex address").describe("EVM address to register as a trusted split recipient for your organization."),
948
- label: import_zod15.z.string().min(1).max(64).optional().describe('Free-form label for your own bookkeeping (e.g. `"supplier"`) \u2014 never interpreted.')
978
+ var CreateRecipientSchema = import_zod16.z.object({
979
+ address: import_zod16.z.string().regex(EVM_ADDRESS_REGEX, "must be a 20-byte hex address").describe("EVM address to register as a trusted split recipient for your organization."),
980
+ label: import_zod16.z.string().min(1).max(64).optional().describe('Free-form label for your own bookkeeping (e.g. `"supplier"`) \u2014 never interpreted.')
949
981
  });
950
- var RecipientSchema = import_zod15.z.object({
951
- id: import_zod15.z.string().describe(
982
+ var RecipientSchema = import_zod16.z.object({
983
+ id: import_zod16.z.string().describe(
952
984
  "Klappay-generated id, e.g. `rc_...` \u2014 this, not the raw address, is what a charge's `splitRecipients[].recipientId` references."
953
985
  ),
954
986
  environment: EnvironmentSchema,
955
- address: import_zod15.z.string(),
956
- label: import_zod15.z.string().nullable(),
957
- payout: import_zod15.z.boolean().describe(
987
+ address: import_zod16.z.string(),
988
+ label: import_zod16.z.string().nullable(),
989
+ payout: import_zod16.z.boolean().describe(
958
990
  "Whether this recipient is eligible to be used as an API key's `payoutAddress` (in addition to being referenceable in a split, which every non-revoked recipient already is). Set via `PATCH /v1/recipients/{id}` \u2014 requires the `recipients:manage_payout` scope, deliberately separate from `recipients:write`."
959
991
  ),
960
- createdAt: import_zod15.z.string().datetime()
992
+ createdAt: import_zod16.z.string().datetime()
961
993
  });
962
- var SetRecipientPayoutSchema = import_zod15.z.object({
963
- payout: import_zod15.z.boolean().describe("New payout-eligibility value for this recipient.")
994
+ var SetRecipientPayoutSchema = import_zod16.z.object({
995
+ payout: import_zod16.z.boolean().describe("New payout-eligibility value for this recipient.")
964
996
  });
965
997
 
966
998
  // src/timeline.ts
967
- var import_zod16 = require("zod");
968
- var TransactionSourceSchema = import_zod16.z.enum(["moralis_webhook", "reconciliation_job", "sandbox"]).describe(
999
+ var import_zod17 = require("zod");
1000
+ var TransactionSourceSchema = import_zod17.z.enum(["moralis_webhook", "reconciliation_job", "sandbox"]).describe(
969
1001
  "How this transfer was detected: `moralis_webhook` (the normal path), `reconciliation_job` (a fallback poller caught it after the webhook was missed or delayed), or `sandbox` (simulated via `POST /v1/sandbox/charges/{id}/trigger`, no real on-chain transfer)."
970
1002
  );
971
- var TimelineEventTypeSchema = import_zod16.z.enum([
1003
+ var TimelineEventTypeSchema = import_zod17.z.enum([
972
1004
  "charge.created",
973
1005
  "charge.expired",
974
1006
  "transaction.detected",
@@ -979,11 +1011,11 @@ var TimelineEventTypeSchema = import_zod16.z.enum([
979
1011
  ]).describe(
980
1012
  "`charge.created`: the charge was created. `charge.expired`: `expiresAt` passed with no full payment. `transaction.detected`: a raw on-chain transfer was seen (see the `event`-shaped fields below for details \u2014 a charge can have more than one, e.g. a partial payment followed by the rest). `split.distributed`: a payout to the merchant completed on-chain, for one contributing `(token, network)` pair \u2014 a charge settled across more than one pair emits one of these per pair (see the `token`/`network` fields below). `webhook.dispatched`/`webhook.delivered`/`webhook.failed`: one specific delivery *attempt* for one webhook subscription \u2014 `failed` here means this single attempt failed, not that all retries were exhausted (see `WebhookDeliveryStatusSchema` for the exhausted-all-retries state)."
981
1013
  );
982
- var TimelineEventSchema = import_zod16.z.object({
1014
+ var TimelineEventSchema = import_zod17.z.object({
983
1015
  type: TimelineEventTypeSchema,
984
- at: import_zod16.z.string().datetime(),
985
- txHash: import_zod16.z.string().optional().describe("Present for `transaction.detected` and `split.distributed` events only."),
986
- amount: import_zod16.z.number().optional().describe(
1016
+ at: import_zod17.z.string().datetime(),
1017
+ txHash: import_zod17.z.string().optional().describe("Present for `transaction.detected` and `split.distributed` events only."),
1018
+ amount: import_zod17.z.number().optional().describe(
987
1019
  "Present for `transaction.detected` events only \u2014 the amount that specific transfer carried."
988
1020
  ),
989
1021
  source: TransactionSourceSchema.optional().describe(
@@ -995,102 +1027,102 @@ var TimelineEventSchema = import_zod16.z.object({
995
1027
  network: NetworkSchema.optional().describe(
996
1028
  "Present for `transaction.detected` and `split.distributed` events \u2014 which network this specific transfer, or settlement, used."
997
1029
  ),
998
- causedTransition: import_zod16.z.boolean().optional().describe(
1030
+ causedTransition: import_zod17.z.boolean().optional().describe(
999
1031
  "Present for `transaction.detected` events only. `true` if this specific transfer changed the charge's status (e.g. PENDING\u2192CONFIRMED) \u2014 a charge paid in installments can have more than one such event."
1000
1032
  ),
1001
1033
  event: WebhookEventTypeSchema.optional().describe(
1002
1034
  "Present for `webhook.*` events only \u2014 which event type this delivery was for."
1003
1035
  ),
1004
- responseCode: import_zod16.z.number().nullable().optional().describe(
1036
+ responseCode: import_zod17.z.number().nullable().optional().describe(
1005
1037
  "Present for `webhook.*` events only \u2014 HTTP status your endpoint returned, or `null` if the request never connected."
1006
1038
  ),
1007
- attempts: import_zod16.z.number().optional().describe(
1039
+ attempts: import_zod17.z.number().optional().describe(
1008
1040
  "Present for `webhook.*` events only \u2014 how many delivery attempts have been made so far."
1009
1041
  )
1010
1042
  });
1011
1043
 
1012
1044
  // src/health.ts
1013
- var import_zod17 = require("zod");
1014
- var HealthSchema = import_zod17.z.object({
1015
- status: import_zod17.z.enum(["ok", "error"]).describe(
1045
+ var import_zod18 = require("zod");
1046
+ var HealthSchema = import_zod18.z.object({
1047
+ status: import_zod18.z.enum(["ok", "error"]).describe(
1016
1048
  "`error` when the database connectivity check fails \u2014 the HTTP status code mirrors this (503 instead of 200), so a plain uptime check (not just a JSON-aware one) still catches a DB outage."
1017
1049
  ),
1018
- version: import_zod17.z.string(),
1019
- timestamp: import_zod17.z.string().datetime(),
1020
- db: import_zod17.z.enum(["ok", "error"]).describe("Result of a real database connectivity check, not just a process-alive check."),
1021
- pendingWebhooks: import_zod17.z.number().describe("Count of webhook deliveries still awaiting a successful attempt."),
1022
- oldestPendingChargeAgeSeconds: import_zod17.z.number().nullable().describe("Age of the oldest still-unpaid charge, in seconds. `null` if there are none."),
1023
- lastMoralisEventAgeSeconds: import_zod17.z.number().nullable().describe(
1050
+ version: import_zod18.z.string(),
1051
+ timestamp: import_zod18.z.string().datetime(),
1052
+ db: import_zod18.z.enum(["ok", "error"]).describe("Result of a real database connectivity check, not just a process-alive check."),
1053
+ pendingWebhooks: import_zod18.z.number().describe("Count of webhook deliveries still awaiting a successful attempt."),
1054
+ oldestPendingChargeAgeSeconds: import_zod18.z.number().nullable().describe("Age of the oldest still-unpaid charge, in seconds. `null` if there are none."),
1055
+ lastMoralisEventAgeSeconds: import_zod18.z.number().nullable().describe(
1024
1056
  "Seconds since the last on-chain payment notification was received \u2014 a cheap signal for whether payment detection is currently working. `null` if none have ever been received."
1025
1057
  )
1026
1058
  });
1027
1059
 
1028
1060
  // src/sandbox.ts
1029
- var import_zod18 = require("zod");
1030
- var SandboxTriggerSchema = import_zod18.z.object({
1061
+ var import_zod19 = require("zod");
1062
+ var SandboxTriggerSchema = import_zod19.z.object({
1031
1063
  event: TriggerableChargeEventSchema,
1032
- amount: import_zod18.z.number().positive().max(CHARGE_AMOUNT_MAX).optional().describe(
1064
+ amount: import_zod19.z.number().positive().max(CHARGE_AMOUNT_MAX).optional().describe(
1033
1065
  "Used with `charge.partially_paid` (amount to simulate as received so far \u2014 must be less than the charge amount, defaults to half of it if omitted) and with `charge.overpaid` (amount received \u2014 must be greater than the charge amount, defaults to 1.5x it if omitted). Ignored for every other event."
1034
1066
  )
1035
1067
  });
1036
1068
 
1037
1069
  // src/capabilities.ts
1038
- var import_zod19 = require("zod");
1039
- var CapabilitiesSchema = import_zod19.z.object({
1040
- acceptedPayments: import_zod19.z.array(AcceptedPaymentSchema).describe(
1070
+ var import_zod20 = require("zod");
1071
+ var CapabilitiesSchema = import_zod20.z.object({
1072
+ acceptedPayments: import_zod20.z.array(AcceptedPaymentSchema).describe(
1041
1073
  "Every `(token, network)` pair actually configured for your environment right now \u2014 read straight from the same lookup `POST /v1/charges` validates `acceptedPayments` against, so it can never list a pair that charge creation would then reject. Use this to build a picker UI instead of hardcoding the matrix client-side."
1042
1074
  )
1043
1075
  });
1044
1076
 
1045
1077
  // src/swap.ts
1046
- var import_zod20 = require("zod");
1047
- var CreateSwapQuoteSchema = import_zod20.z.object({
1078
+ var import_zod21 = require("zod");
1079
+ var CreateSwapQuoteSchema = import_zod21.z.object({
1048
1080
  inputToken: AltTokenSchema.describe(
1049
1081
  "Which alt-cryptocurrency the payer wants to send \u2014 must be one of this charge's `swapAlternatives`, or `422 token_not_supported`."
1050
1082
  ),
1051
1083
  inputNetwork: NetworkSchema.describe(
1052
1084
  "Which network the payer will send `inputToken` on. Also picks which of this charge's `acceptedPayments` pairs the swap resolves to \u2014 a charge accepting USDC on both Base and Optimism resolves to whichever `inputNetwork` you pass. If the charge accepts more than one token on that same network, Klappay breaks the tie using its own trust ranking for that network (e.g. USDT over USDC on BNB Chain, where \"USDC\" is a third-party Binance-Peg token, not Circle's) \u2014 never a token the charge doesn't actually accept."
1053
1085
  ),
1054
- takerAddress: import_zod20.z.string().regex(/^0x[0-9a-fA-F]{40}$/, "must be a 20-byte hex address").describe(
1086
+ takerAddress: import_zod21.z.string().regex(/^0x[0-9a-fA-F]{40}$/, "must be a 20-byte hex address").describe(
1055
1087
  "The payer's own wallet address \u2014 the account that will sign and submit the swap transaction. Not validated against anything else; any well-formed address is accepted, since Klappay never custodies these funds."
1056
1088
  )
1057
1089
  });
1058
- var SwapQuoteSchema = import_zod20.z.object({
1090
+ var SwapQuoteSchema = import_zod21.z.object({
1059
1091
  inputToken: AltTokenSchema,
1060
1092
  inputNetwork: NetworkSchema,
1061
- inputAmount: import_zod20.z.number().describe(
1093
+ inputAmount: import_zod21.z.number().describe(
1062
1094
  "The ceiling of `inputToken` the payer needs available to sign for, in whole units (not wei/base units) \u2014 not necessarily the exact final cost. Any `inputToken` beyond what the swap actually needs (price moved favorably, less slippage than budgeted) is swapped back and refunded to the payer automatically, in the same transaction \u2014 never a separate step or a Klappay-side refund."
1063
1095
  ),
1064
1096
  outputToken: TokenSchema.describe(
1065
1097
  "Which of this charge's `acceptedPayments` tokens the swap resolves to."
1066
1098
  ),
1067
1099
  outputNetwork: NetworkSchema,
1068
- outputAmount: import_zod20.z.number().describe(
1100
+ outputAmount: import_zod21.z.number().describe(
1069
1101
  "The exact remaining amount owed on this charge (`amount - amountReceived`), in `currency` units \u2014 always what the merchant's split address receives, regardless of `inputAmount`."
1070
1102
  ),
1071
- fees: import_zod20.z.object({
1072
- klappayFee: import_zod20.z.number().describe(
1103
+ fees: import_zod21.z.object({
1104
+ klappayFee: import_zod21.z.number().describe(
1073
1105
  "Klappay's own swap fee (1% today), in `outputToken` units \u2014 paid by the payer, on top of `inputAmount`, separate from the merchant's own `feePercent`. Never subtracted from `outputAmount`."
1074
1106
  ),
1075
- zeroExFee: import_zod20.z.number().nullable().describe(
1107
+ zeroExFee: import_zod21.z.number().nullable().describe(
1076
1108
  "0x's own protocol fee for this specific token pair, in `outputToken` units, or `null` when this pair isn't currently one 0x charges on. Also paid by the payer on top of `inputAmount`, also never subtracted from `outputAmount` \u2014 Klappay never sees this fee, it goes straight to 0x."
1077
1109
  )
1078
1110
  }).describe(
1079
1111
  "Every fee the payer is charged for using swap-to-pay, broken out by who collects it \u2014 both already reflected in `inputAmount`, shown here separately for transparency. Neither ever reduces `outputAmount`."
1080
1112
  ),
1081
- expiresAt: import_zod20.z.string().datetime().describe(
1113
+ expiresAt: import_zod21.z.string().datetime().describe(
1082
1114
  "When this quote's price is no longer safely valid \u2014 a rough guide for the payer's UI countdown only. The actual price guarantee is enforced on-chain by the swap transaction itself (a signed Permit2 deadline, or a minimum-output check for a native-currency sell), not by this timestamp \u2014 submitting after it expires either reverts on-chain or simply gets re-quoted at the current price, never silently executes at a stale rate."
1083
1115
  ),
1084
- transaction: import_zod20.z.object({
1085
- to: import_zod20.z.string().describe("Contract address the payer's wallet must send this transaction to."),
1086
- data: import_zod20.z.string().describe("Calldata \u2014 opaque, must be sent unmodified."),
1087
- value: import_zod20.z.string().describe(
1116
+ transaction: import_zod21.z.object({
1117
+ to: import_zod21.z.string().describe("Contract address the payer's wallet must send this transaction to."),
1118
+ data: import_zod21.z.string().describe("Calldata \u2014 opaque, must be sent unmodified."),
1119
+ value: import_zod21.z.string().describe(
1088
1120
  "Native currency (ETH/BNB/MATIC/AVAX) to attach, in wei \u2014 `\"0\"` when `inputToken` isn't this network's native currency."
1089
1121
  )
1090
1122
  }).describe(
1091
1123
  "Pass this directly to the payer's wallet (e.g. viem/ethers `sendTransaction`) \u2014 Klappay never touches the payer's private key or submits anything on their behalf. If `permit2` is present on this response, sign that first and append the signature to this `data` before sending; if `permit2` is absent, send `transaction` as-is with no extra step."
1092
1124
  ),
1093
- permit2: import_zod20.z.object({ eip712: import_zod20.z.record(import_zod20.z.unknown()) }).nullish().describe(
1125
+ permit2: import_zod21.z.object({ eip712: import_zod21.z.record(import_zod21.z.unknown()) }).nullish().describe(
1094
1126
  "Present only when `inputToken` is an ERC-20 (today, only `BTC`) \u2014 the payer's wallet must sign this EIP-712 message and append the signature to `transaction.data` before sending, since an ERC-20 sell needs a Permit2 allowance signature that a native-currency sell doesn't. `null` (never omitted, in a genuine 0x-backed quote) when `inputToken` is a network's own native currency (ETH/BNB/MATIC/AVAX) \u2014 `transaction` is then ready to sign and send directly, no extra step."
1095
1127
  )
1096
1128
  });
@@ -1130,6 +1162,7 @@ var SwapQuoteSchema = import_zod20.z.object({
1130
1162
  EVM_NETWORKS,
1131
1163
  EnvironmentSchema,
1132
1164
  ErrorPayloadSchema,
1165
+ EscrowConfigSchema,
1133
1166
  GetChargeQrCodeQuerySchema,
1134
1167
  HealthSchema,
1135
1168
  KlappayCheckoutMetadataSchema,
@@ -1165,6 +1198,7 @@ var SwapQuoteSchema = import_zod20.z.object({
1165
1198
  PendingDistributionRecipientSchema,
1166
1199
  PendingDistributionSchema,
1167
1200
  RecipientSchema,
1201
+ ReleaseEscrowRequestSchema,
1168
1202
  SandboxTriggerSchema,
1169
1203
  SetRecipientPayoutSchema,
1170
1204
  SettlementStatusSchema,