@klappay/types 3.7.0 → 4.0.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
@@ -35,6 +35,7 @@ __export(index_exports, {
35
35
  CHECKOUT_PRODUCTS_MAX: () => CHECKOUT_PRODUCTS_MAX,
36
36
  CONFLICTING_SCOPE_PAIRS: () => CONFLICTING_SCOPE_PAIRS,
37
37
  CapabilitiesSchema: () => CapabilitiesSchema,
38
+ ChargeFeePayerSchema: () => ChargeFeePayerSchema,
38
39
  ChargeSchema: () => ChargeSchema,
39
40
  ChargeStatusSchema: () => ChargeStatusSchema,
40
41
  ChargeWebhookEventTypeSchema: () => ChargeWebhookEventTypeSchema,
@@ -44,6 +45,7 @@ __export(index_exports, {
44
45
  CheckChargeRequestSchema: () => CheckChargeRequestSchema,
45
46
  CheckChargeResponseSchema: () => CheckChargeResponseSchema,
46
47
  CheckoutProductSchema: () => CheckoutProductSchema,
48
+ ConfirmationProgressSchema: () => ConfirmationProgressSchema,
47
49
  CreateChargeSchema: () => CreateChargeSchema,
48
50
  CreateRecipientSchema: () => CreateRecipientSchema,
49
51
  CreateSwapQuoteSchema: () => CreateSwapQuoteSchema,
@@ -384,6 +386,9 @@ var ChargeStatusSchema = import_zod10.z.enum(["pending", "partially_paid", "conf
384
386
  var SettlementStatusSchema = import_zod10.z.enum(["pending", "completed", "failed"]).describe(
385
387
  "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."
386
388
  );
389
+ var ChargeFeePayerSchema = import_zod10.z.enum(["merchant", "payer"]).describe(
390
+ "Who ends up covering Klappay's `feePercent`. `merchant` (default): `amount` is exactly what you asked for, and Klappay's fee is deducted from your own payout \u2014 you net `amount * (1 - feePercent / 100)`. `payer` : `amount` is grossed up at creation time so that, after the same fee deduction, you still net the amount you originally requested \u2014 the payer sees and sends the larger, fee-inclusive total. Frozen at creation like every other fee input; does not change how `feeAmount`/`merchantAmount` are computed on read, only what `amount` was set to in the first place."
391
+ );
387
392
  var CHARGE_EXPIRES_IN_MIN_SECONDS = 60;
388
393
  var CHARGE_EXPIRES_IN_MAX_SECONDS = 3600;
389
394
  var CHARGE_ACCEPTED_PAYMENTS_MAX = 14;
@@ -453,8 +458,9 @@ var SplitRecipientsInputSchema = import_zod10.z.array(SplitRecipientInputSchema)
453
458
  var CHARGE_AMOUNT_MAX = 999999999999;
454
459
  var CreateChargeSchema = import_zod10.z.object({
455
460
  amount: import_zod10.z.number().positive().max(CHARGE_AMOUNT_MAX).describe(
456
- "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."
461
+ "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. With `feePayer: 'payer'` (see below), this is your own desired net amount, not the total the payer ends up sending \u2014 the response's `amount` is grossed up to cover `feePercent`, while `merchantAmount` on the response echoes back this exact value."
457
462
  ),
463
+ feePayer: ChargeFeePayerSchema.optional().default("merchant"),
458
464
  currency: import_zod10.z.literal("USD").default("USD").describe("Always `USD` today \u2014 the only supported currency."),
459
465
  acceptedPayments: AcceptedPaymentsSchema,
460
466
  expiresIn: import_zod10.z.number().int().min(CHARGE_EXPIRES_IN_MIN_SECONDS).max(CHARGE_EXPIRES_IN_MAX_SECONDS).describe(
@@ -480,7 +486,17 @@ var CreateChargeSchema = import_zod10.z.object({
480
486
  });
481
487
  var ChargeSchema = import_zod10.z.object({
482
488
  id: import_zod10.z.string().describe("Klappay-generated id, e.g. `ch_...`. Use this to look up the charge later."),
483
- amount: import_zod10.z.number().describe("The amount originally requested, in `currency` units (up to 6 decimal places)."),
489
+ amount: import_zod10.z.number().describe(
490
+ "The exact total the payer must send, in `currency` units (up to 6 decimal places). With `feePayer: 'merchant'` (the default) this is exactly what you requested at creation. With `feePayer: 'payer'` this is grossed up to cover `feePercent` \u2014 see `merchantAmount` for what you requested/will actually net."
491
+ ),
492
+ feePayer: ChargeFeePayerSchema,
493
+ feePercent: import_zod10.z.number().describe(
494
+ "Klappay's fee for this charge, as a percent of `amount` (e.g. `2` = 2%) \u2014 includes any escrow surcharge if this charge is an escrow. Frozen at creation; see `feeAmount`/`merchantAmount` for the actual amounts this works out to."
495
+ ),
496
+ feeAmount: import_zod10.z.number().describe("`amount * feePercent / 100`, in `currency` units \u2014 Klappay's cut of this charge."),
497
+ merchantAmount: import_zod10.z.number().describe(
498
+ "`amount - feeAmount`, in `currency` units \u2014 what you actually net once the payout settles, regardless of `feePayer` (this is always what the split delivers to you; `feePayer` only affects what `amount` was set to at creation)."
499
+ ),
484
500
  amountReceived: import_zod10.z.number().nullable().describe(
485
501
  "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`."
486
502
  ),
@@ -561,9 +577,28 @@ var GetChargeQrCodeQuerySchema = import_zod10.z.object({
561
577
  });
562
578
 
563
579
  // src/charge-check.ts
580
+ var import_zod12 = require("zod");
581
+
582
+ // src/confirmation-progress.ts
564
583
  var import_zod11 = require("zod");
565
- var CheckChargeRequestSchema = import_zod11.z.object({
566
- txHash: import_zod11.z.string().regex(/^0x[0-9a-fA-F]{64}$/, "must be a 32-byte transaction hash").optional().describe(
584
+ var ConfirmationProgressSchema = import_zod11.z.object({
585
+ network: NetworkSchema.describe("Which network the transfer was seen on."),
586
+ blocksSeen: import_zod11.z.number().int().min(0).describe(
587
+ "How many blocks have passed since the transfer's own block, as of this update \u2014 a raw block count, not seconds. Grows toward `blocksRequired` as the network's blocks keep arriving."
588
+ ),
589
+ blocksRequired: import_zod11.z.number().int().min(1).describe(
590
+ "This network's minimum confirmation depth (a fixed, per-network constant) \u2014 the transfer is only credited once `blocksSeen` reaches this value."
591
+ ),
592
+ percent: import_zod11.z.number().int().min(0).max(99).describe(
593
+ '`blocksSeen`/`blocksRequired` as a rounded-down 0-99 percentage, for a progress bar. Never reaches 100 by construction \u2014 once a transfer is deep enough it is credited immediately and this stops being reported at all (the charge event itself is the "done" signal).'
594
+ )
595
+ }).describe(
596
+ "How close an already-detected transfer is to being trusted as final and credited, before its network's minimum confirmation depth is reached (see `docs/payments.md`'s \"Confirmation depth\" section). Only ever present for a transfer that's been seen on-chain but isn't deep enough yet \u2014 absent/null once it's credited (the charge's own status change is what signals that) or if nothing has been detected at all."
597
+ );
598
+
599
+ // src/charge-check.ts
600
+ var CheckChargeRequestSchema = import_zod12.z.object({
601
+ txHash: import_zod12.z.string().regex(/^0x[0-9a-fA-F]{64}$/, "must be a 32-byte transaction hash").optional().describe(
567
602
  "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."
568
603
  ),
569
604
  network: NetworkSchema.optional().describe(
@@ -573,67 +608,70 @@ var CheckChargeRequestSchema = import_zod11.z.object({
573
608
  message: "`txHash` and `network` must be provided together, or both omitted"
574
609
  });
575
610
  var CheckChargeResponseSchema = ChargeSchema.extend({
576
- transactionSender: import_zod11.z.string().nullable().describe(
611
+ transactionSender: import_zod12.z.string().nullable().describe(
577
612
  "The `txHash` transaction's own sender (`from`) \u2014 who actually signed and submitted it on-chain, which stays the payer's own wallet even when the transaction swaps through a router/aggregator on the way to paying, unlike the credited transfer's `from` (which can be the router/pool contract, not the payer). `null` unless `txHash`/`network` was passed in the request and a successful receipt was found for it \u2014 a hint-less background scan, an unaccepted network, or a not-found/reverted transaction all leave this `null`."
613
+ ),
614
+ confirmationProgress: ConfirmationProgressSchema.nullable().describe(
615
+ "Present when this check found a real matching transfer on-chain that has not yet reached its network's required confirmation depth \u2014 use it to render a progress bar while waiting. `null` when nothing new was found, when the charge is already terminal (this check short-circuits with no RPC call), or once the transfer is deep enough to have already been credited (the charge's own `status` field is the signal for that, not this one)."
578
616
  )
579
617
  });
580
618
 
581
619
  // src/distributions.ts
582
- var import_zod12 = require("zod");
583
- var SplitDistributionStatusSchema = import_zod12.z.enum(["pending", "processing", "completed", "failed"]).describe(
620
+ var import_zod13 = require("zod");
621
+ var SplitDistributionStatusSchema = import_zod13.z.enum(["pending", "processing", "completed", "failed"]).describe(
584
622
  "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."
585
623
  );
586
- var PendingDistributionRecipientSchema = import_zod12.z.object({
587
- address: import_zod12.z.string().describe("On-chain recipient address."),
588
- percentAllocation: import_zod12.z.number().describe("This recipient's share of the split, as a percentage (e.g. `99.0991` = 99.0991%).")
624
+ var PendingDistributionRecipientSchema = import_zod13.z.object({
625
+ address: import_zod13.z.string().describe("On-chain recipient address."),
626
+ percentAllocation: import_zod13.z.number().describe("This recipient's share of the split, as a percentage (e.g. `99.0991` = 99.0991%).")
589
627
  });
590
- var PendingDistributionSchema = import_zod12.z.object({
591
- splitAddress: import_zod12.z.string().describe("The on-chain 0xSplits address to call `distribute()` on."),
628
+ var PendingDistributionSchema = import_zod13.z.object({
629
+ splitAddress: import_zod13.z.string().describe("The on-chain 0xSplits address to call `distribute()` on."),
592
630
  network: NetworkSchema,
593
631
  token: TokenSchema,
594
- recipients: import_zod12.z.array(PendingDistributionRecipientSchema).describe(
632
+ recipients: import_zod13.z.array(PendingDistributionRecipientSchema).describe(
595
633
  "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."
596
634
  ),
597
- distributorFeePercent: import_zod12.z.number().describe(
635
+ distributorFeePercent: import_zod13.z.number().describe(
598
636
  "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."
599
637
  ),
600
- estimatedRewardAmount: import_zod12.z.number().describe(
638
+ estimatedRewardAmount: import_zod13.z.number().describe(
601
639
  "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."
602
640
  ),
603
- availableSince: import_zod12.z.string().datetime().describe("When this distribution entered its grace period."),
604
- graceEndsAt: import_zod12.z.string().datetime().describe(
641
+ availableSince: import_zod13.z.string().datetime().describe("When this distribution entered its grace period."),
642
+ graceEndsAt: import_zod13.z.string().datetime().describe(
605
643
  "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."
606
644
  )
607
645
  });
608
646
  var PaginatedPendingDistributionsSchema = paginatedSchema(PendingDistributionSchema);
609
- var ListenPendingDistributionsQuerySchema = import_zod12.z.object({
610
- limit: import_zod12.z.coerce.number().int().min(0).max(PAGINATION_LIMIT_MAX).default(0).describe(
647
+ var ListenPendingDistributionsQuerySchema = import_zod13.z.object({
648
+ limit: import_zod13.z.coerce.number().int().min(0).max(PAGINATION_LIMIT_MAX).default(0).describe(
611
649
  "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."
612
650
  )
613
651
  });
614
- var PendingDistributionEventSchema = import_zod12.z.discriminatedUnion("type", [
615
- import_zod12.z.object({
616
- type: import_zod12.z.literal("distribution.available"),
652
+ var PendingDistributionEventSchema = import_zod13.z.discriminatedUnion("type", [
653
+ import_zod13.z.object({
654
+ type: import_zod13.z.literal("distribution.available"),
617
655
  distribution: PendingDistributionSchema
618
656
  }),
619
- import_zod12.z.object({
620
- type: import_zod12.z.literal("distribution.claimed"),
621
- splitAddress: import_zod12.z.string().describe("No longer claimable \u2014 either settled by someone, or picked up by the worker.")
657
+ import_zod13.z.object({
658
+ type: import_zod13.z.literal("distribution.claimed"),
659
+ splitAddress: import_zod13.z.string().describe("No longer claimable \u2014 either settled by someone, or picked up by the worker.")
622
660
  })
623
661
  ]);
624
662
 
625
663
  // src/metrics.ts
626
- var import_zod13 = require("zod");
627
- var MetricsResourceSchema = import_zod13.z.enum(["charges", "transactions", "distributions"]).describe(
664
+ var import_zod14 = require("zod");
665
+ var MetricsResourceSchema = import_zod14.z.enum(["charges", "transactions", "distributions"]).describe(
628
666
  "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."
629
667
  );
630
- var MetricsAggregationSchema = import_zod13.z.enum(["count", "sum", "avg", "min", "max"]).describe(
668
+ var MetricsAggregationSchema = import_zod14.z.enum(["count", "sum", "avg", "min", "max"]).describe(
631
669
  "`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."
632
670
  );
633
- var MetricsFilterOperatorSchema = import_zod13.z.enum(["eq", "neq", "in", "gt", "gte", "lt", "lte"]).describe(
671
+ var MetricsFilterOperatorSchema = import_zod14.z.enum(["eq", "neq", "in", "gt", "gte", "lt", "lte"]).describe(
634
672
  "`in` expects an array value (max 50 entries); every other operator expects a single scalar."
635
673
  );
636
- var MetricsDateGranularitySchema = import_zod13.z.enum(["day", "week", "month", "year"]).describe(
674
+ var MetricsDateGranularitySchema = import_zod14.z.enum(["day", "week", "month", "year"]).describe(
637
675
  "Bucket width for a `date_bucket` `groupBy` entry \u2014 Postgres `date_trunc` semantics (UTC)."
638
676
  );
639
677
  var metricsQueryEnvironmentSchema = EnvironmentSchema.describe(
@@ -646,31 +684,31 @@ var METRICS_QUERY_MAX_GROUP_BY = 3;
646
684
  var METRICS_QUERY_MAX_FILTERS = 20;
647
685
  var METRICS_QUERY_MAX_METRICS = 10;
648
686
  var METRIC_ALIAS_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
649
- var metricAliasSchema = import_zod13.z.string().min(1).max(64).regex(
687
+ var metricAliasSchema = import_zod14.z.string().min(1).max(64).regex(
650
688
  METRIC_ALIAS_PATTERN,
651
689
  "Must start with a letter or underscore, and contain only letters, digits, and underscores \u2014 this becomes a SQL column alias."
652
690
  ).optional();
653
- var MetricsFilterValueSchema = import_zod13.z.union([
654
- import_zod13.z.string().max(255),
655
- import_zod13.z.number(),
656
- import_zod13.z.boolean(),
657
- import_zod13.z.array(import_zod13.z.union([import_zod13.z.string().max(255), import_zod13.z.number()])).min(1).max(50)
691
+ var MetricsFilterValueSchema = import_zod14.z.union([
692
+ import_zod14.z.string().max(255),
693
+ import_zod14.z.number(),
694
+ import_zod14.z.boolean(),
695
+ import_zod14.z.array(import_zod14.z.union([import_zod14.z.string().max(255), import_zod14.z.number()])).min(1).max(50)
658
696
  ]);
659
- var orderBySchema = import_zod13.z.object({
660
- key: import_zod13.z.string().min(1).max(64).regex(
697
+ var orderBySchema = import_zod14.z.object({
698
+ key: import_zod14.z.string().min(1).max(64).regex(
661
699
  METRIC_ALIAS_PATTERN,
662
700
  "Must start with a letter or underscore, and contain only letters, digits, and underscores \u2014 every valid output column name already looks like this."
663
701
  ).describe(
664
702
  "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."
665
703
  ),
666
- direction: import_zod13.z.enum(["asc", "desc"])
704
+ direction: import_zod14.z.enum(["asc", "desc"])
667
705
  }).describe(
668
706
  "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."
669
707
  );
670
- var limitSchema = import_zod13.z.number().int().min(1).max(METRICS_QUERY_MAX_ROW_LIMIT).default(METRICS_QUERY_DEFAULT_ROW_LIMIT).describe(
708
+ var limitSchema = import_zod14.z.number().int().min(1).max(METRICS_QUERY_MAX_ROW_LIMIT).default(METRICS_QUERY_DEFAULT_ROW_LIMIT).describe(
671
709
  `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.`
672
710
  );
673
- var ChargesQueryFieldSchema = import_zod13.z.enum([
711
+ var ChargesQueryFieldSchema = import_zod14.z.enum([
674
712
  "status",
675
713
  "source",
676
714
  "apiKeyId",
@@ -681,124 +719,124 @@ var ChargesQueryFieldSchema = import_zod13.z.enum([
681
719
  ]).describe(
682
720
  "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)."
683
721
  );
684
- var ChargesMetricFieldSchema = import_zod13.z.enum(["amount", "amountReceived", "feePercent", "escrowFeePercent"]).describe(
722
+ var ChargesMetricFieldSchema = import_zod14.z.enum(["amount", "amountReceived", "feePercent", "escrowFeePercent"]).describe(
685
723
  "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`."
686
724
  );
687
- var ChargesDateFieldSchema = import_zod13.z.enum(["createdAt", "confirmedAt", "lastActivityAt", "expiresAt", "escrowReleasedAt"]).describe(
725
+ var ChargesDateFieldSchema = import_zod14.z.enum(["createdAt", "confirmedAt", "lastActivityAt", "expiresAt", "escrowReleasedAt"]).describe(
688
726
  "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."
689
727
  );
690
- var ChargesFilterSchema = import_zod13.z.object({
728
+ var ChargesFilterSchema = import_zod14.z.object({
691
729
  field: ChargesQueryFieldSchema,
692
730
  operator: MetricsFilterOperatorSchema,
693
731
  value: MetricsFilterValueSchema
694
732
  });
695
- var ChargesGroupBySchema = import_zod13.z.union([
696
- import_zod13.z.object({ type: import_zod13.z.literal("field"), field: ChargesQueryFieldSchema }),
697
- import_zod13.z.object({
698
- type: import_zod13.z.literal("date_bucket"),
733
+ var ChargesGroupBySchema = import_zod14.z.union([
734
+ import_zod14.z.object({ type: import_zod14.z.literal("field"), field: ChargesQueryFieldSchema }),
735
+ import_zod14.z.object({
736
+ type: import_zod14.z.literal("date_bucket"),
699
737
  field: ChargesDateFieldSchema,
700
738
  granularity: MetricsDateGranularitySchema
701
739
  })
702
740
  ]);
703
- var ChargesMetricSchema = import_zod13.z.object({
741
+ var ChargesMetricSchema = import_zod14.z.object({
704
742
  aggregation: MetricsAggregationSchema,
705
743
  field: ChargesMetricFieldSchema.optional(),
706
744
  alias: metricAliasSchema
707
745
  });
708
- var ChargesMetricsQuerySchema = import_zod13.z.object({
709
- resource: import_zod13.z.literal("charges"),
746
+ var ChargesMetricsQuerySchema = import_zod14.z.object({
747
+ resource: import_zod14.z.literal("charges"),
710
748
  environment: metricsQueryEnvironmentSchema,
711
- dateRange: import_zod13.z.object({
749
+ dateRange: import_zod14.z.object({
712
750
  field: ChargesDateFieldSchema,
713
- from: import_zod13.z.string().max(64).datetime(),
714
- to: import_zod13.z.string().max(64).datetime()
751
+ from: import_zod14.z.string().max(64).datetime(),
752
+ to: import_zod14.z.string().max(64).datetime()
715
753
  }),
716
- groupBy: import_zod13.z.array(ChargesGroupBySchema).max(METRICS_QUERY_MAX_GROUP_BY).default([]),
717
- metrics: import_zod13.z.array(ChargesMetricSchema).min(1).max(METRICS_QUERY_MAX_METRICS),
718
- filters: import_zod13.z.array(ChargesFilterSchema).max(METRICS_QUERY_MAX_FILTERS).default([]),
754
+ groupBy: import_zod14.z.array(ChargesGroupBySchema).max(METRICS_QUERY_MAX_GROUP_BY).default([]),
755
+ metrics: import_zod14.z.array(ChargesMetricSchema).min(1).max(METRICS_QUERY_MAX_METRICS),
756
+ filters: import_zod14.z.array(ChargesFilterSchema).max(METRICS_QUERY_MAX_FILTERS).default([]),
719
757
  orderBy: orderBySchema.optional(),
720
758
  limit: limitSchema
721
759
  });
722
- var TransactionsQueryFieldSchema = import_zod13.z.enum(["network", "token", "source", "causedTransition"]).describe(
760
+ var TransactionsQueryFieldSchema = import_zod14.z.enum(["network", "token", "source", "causedTransition"]).describe(
723
761
  "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)."
724
762
  );
725
- var TransactionsMetricFieldSchema = import_zod13.z.enum(["amount"]).describe("The transfer amount, in the charge's `currency` units.");
726
- var TransactionsDateFieldSchema = import_zod13.z.enum(["detectedAt"]).describe("When Klappay detected this transfer on-chain (not when it was mined).");
727
- var TransactionsFilterSchema = import_zod13.z.object({
763
+ var TransactionsMetricFieldSchema = import_zod14.z.enum(["amount"]).describe("The transfer amount, in the charge's `currency` units.");
764
+ var TransactionsDateFieldSchema = import_zod14.z.enum(["detectedAt"]).describe("When Klappay detected this transfer on-chain (not when it was mined).");
765
+ var TransactionsFilterSchema = import_zod14.z.object({
728
766
  field: TransactionsQueryFieldSchema,
729
767
  operator: MetricsFilterOperatorSchema,
730
768
  value: MetricsFilterValueSchema
731
769
  });
732
- var TransactionsGroupBySchema = import_zod13.z.union([
733
- import_zod13.z.object({ type: import_zod13.z.literal("field"), field: TransactionsQueryFieldSchema }),
734
- import_zod13.z.object({
735
- type: import_zod13.z.literal("date_bucket"),
770
+ var TransactionsGroupBySchema = import_zod14.z.union([
771
+ import_zod14.z.object({ type: import_zod14.z.literal("field"), field: TransactionsQueryFieldSchema }),
772
+ import_zod14.z.object({
773
+ type: import_zod14.z.literal("date_bucket"),
736
774
  field: TransactionsDateFieldSchema,
737
775
  granularity: MetricsDateGranularitySchema
738
776
  })
739
777
  ]);
740
- var TransactionsMetricSchema = import_zod13.z.object({
778
+ var TransactionsMetricSchema = import_zod14.z.object({
741
779
  aggregation: MetricsAggregationSchema,
742
780
  field: TransactionsMetricFieldSchema.optional(),
743
781
  alias: metricAliasSchema
744
782
  });
745
- var TransactionsMetricsQuerySchema = import_zod13.z.object({
746
- resource: import_zod13.z.literal("transactions"),
783
+ var TransactionsMetricsQuerySchema = import_zod14.z.object({
784
+ resource: import_zod14.z.literal("transactions"),
747
785
  environment: metricsQueryEnvironmentSchema,
748
- dateRange: import_zod13.z.object({
786
+ dateRange: import_zod14.z.object({
749
787
  field: TransactionsDateFieldSchema,
750
- from: import_zod13.z.string().max(64).datetime(),
751
- to: import_zod13.z.string().max(64).datetime()
788
+ from: import_zod14.z.string().max(64).datetime(),
789
+ to: import_zod14.z.string().max(64).datetime()
752
790
  }),
753
- groupBy: import_zod13.z.array(TransactionsGroupBySchema).max(METRICS_QUERY_MAX_GROUP_BY).default([]),
754
- metrics: import_zod13.z.array(TransactionsMetricSchema).min(1).max(METRICS_QUERY_MAX_METRICS),
755
- filters: import_zod13.z.array(TransactionsFilterSchema).max(METRICS_QUERY_MAX_FILTERS).default([]),
791
+ groupBy: import_zod14.z.array(TransactionsGroupBySchema).max(METRICS_QUERY_MAX_GROUP_BY).default([]),
792
+ metrics: import_zod14.z.array(TransactionsMetricSchema).min(1).max(METRICS_QUERY_MAX_METRICS),
793
+ filters: import_zod14.z.array(TransactionsFilterSchema).max(METRICS_QUERY_MAX_FILTERS).default([]),
756
794
  orderBy: orderBySchema.optional(),
757
795
  limit: limitSchema
758
796
  });
759
- var DistributionsQueryFieldSchema = import_zod13.z.enum(["status", "network", "token", "distributorAddress"]).describe(
797
+ var DistributionsQueryFieldSchema = import_zod14.z.enum(["status", "network", "token", "distributorAddress"]).describe(
760
798
  "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."
761
799
  );
762
- var DistributionsMetricFieldSchema = import_zod13.z.enum(["attempts"]).describe(
800
+ var DistributionsMetricFieldSchema = import_zod14.z.enum(["attempts"]).describe(
763
801
  "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."
764
802
  );
765
- var DistributionsDateFieldSchema = import_zod13.z.enum(["createdAt", "processingStartedAt", "completedAt"]).describe(
803
+ var DistributionsDateFieldSchema = import_zod14.z.enum(["createdAt", "processingStartedAt", "completedAt"]).describe(
766
804
  "`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."
767
805
  );
768
- var DistributionsFilterSchema = import_zod13.z.object({
806
+ var DistributionsFilterSchema = import_zod14.z.object({
769
807
  field: DistributionsQueryFieldSchema,
770
808
  operator: MetricsFilterOperatorSchema,
771
809
  value: MetricsFilterValueSchema
772
810
  });
773
- var DistributionsGroupBySchema = import_zod13.z.union([
774
- import_zod13.z.object({ type: import_zod13.z.literal("field"), field: DistributionsQueryFieldSchema }),
775
- import_zod13.z.object({
776
- type: import_zod13.z.literal("date_bucket"),
811
+ var DistributionsGroupBySchema = import_zod14.z.union([
812
+ import_zod14.z.object({ type: import_zod14.z.literal("field"), field: DistributionsQueryFieldSchema }),
813
+ import_zod14.z.object({
814
+ type: import_zod14.z.literal("date_bucket"),
777
815
  field: DistributionsDateFieldSchema,
778
816
  granularity: MetricsDateGranularitySchema
779
817
  })
780
818
  ]);
781
- var DistributionsMetricSchema = import_zod13.z.object({
819
+ var DistributionsMetricSchema = import_zod14.z.object({
782
820
  aggregation: MetricsAggregationSchema,
783
821
  field: DistributionsMetricFieldSchema.optional(),
784
822
  alias: metricAliasSchema
785
823
  });
786
- var DistributionsMetricsQuerySchema = import_zod13.z.object({
787
- resource: import_zod13.z.literal("distributions"),
824
+ var DistributionsMetricsQuerySchema = import_zod14.z.object({
825
+ resource: import_zod14.z.literal("distributions"),
788
826
  environment: metricsQueryEnvironmentSchema,
789
- dateRange: import_zod13.z.object({
827
+ dateRange: import_zod14.z.object({
790
828
  field: DistributionsDateFieldSchema,
791
- from: import_zod13.z.string().max(64).datetime(),
792
- to: import_zod13.z.string().max(64).datetime()
829
+ from: import_zod14.z.string().max(64).datetime(),
830
+ to: import_zod14.z.string().max(64).datetime()
793
831
  }),
794
- groupBy: import_zod13.z.array(DistributionsGroupBySchema).max(METRICS_QUERY_MAX_GROUP_BY).default([]),
795
- metrics: import_zod13.z.array(DistributionsMetricSchema).min(1).max(METRICS_QUERY_MAX_METRICS),
796
- filters: import_zod13.z.array(DistributionsFilterSchema).max(METRICS_QUERY_MAX_FILTERS).default([]),
832
+ groupBy: import_zod14.z.array(DistributionsGroupBySchema).max(METRICS_QUERY_MAX_GROUP_BY).default([]),
833
+ metrics: import_zod14.z.array(DistributionsMetricSchema).min(1).max(METRICS_QUERY_MAX_METRICS),
834
+ filters: import_zod14.z.array(DistributionsFilterSchema).max(METRICS_QUERY_MAX_FILTERS).default([]),
797
835
  orderBy: orderBySchema.optional(),
798
836
  limit: limitSchema
799
837
  });
800
838
  var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
801
- var MetricsQuerySchema = import_zod13.z.discriminatedUnion("resource", [
839
+ var MetricsQuerySchema = import_zod14.z.discriminatedUnion("resource", [
802
840
  ChargesMetricsQuerySchema,
803
841
  TransactionsMetricsQuerySchema,
804
842
  DistributionsMetricsQuerySchema
@@ -807,7 +845,7 @@ var MetricsQuerySchema = import_zod13.z.discriminatedUnion("resource", [
807
845
  const to = new Date(input.dateRange.to);
808
846
  if (from >= to) {
809
847
  ctx.addIssue({
810
- code: import_zod13.z.ZodIssueCode.custom,
848
+ code: import_zod14.z.ZodIssueCode.custom,
811
849
  message: "`dateRange.from` must be before `dateRange.to`.",
812
850
  path: ["dateRange", "from"]
813
851
  });
@@ -815,7 +853,7 @@ var MetricsQuerySchema = import_zod13.z.discriminatedUnion("resource", [
815
853
  const spanDays = (to.getTime() - from.getTime()) / ONE_DAY_MS;
816
854
  if (spanDays > MAX_METRICS_QUERY_DATE_RANGE_DAYS) {
817
855
  ctx.addIssue({
818
- code: import_zod13.z.ZodIssueCode.custom,
856
+ code: import_zod14.z.ZodIssueCode.custom,
819
857
  message: `\`dateRange\` cannot span more than ${MAX_METRICS_QUERY_DATE_RANGE_DAYS} days.`,
820
858
  path: ["dateRange", "to"]
821
859
  });
@@ -823,7 +861,7 @@ var MetricsQuerySchema = import_zod13.z.discriminatedUnion("resource", [
823
861
  const dateBucketCount = input.groupBy.filter((entry) => entry.type === "date_bucket").length;
824
862
  if (dateBucketCount > 1) {
825
863
  ctx.addIssue({
826
- code: import_zod13.z.ZodIssueCode.custom,
864
+ code: import_zod14.z.ZodIssueCode.custom,
827
865
  message: "At most one `date_bucket` entry is allowed in `groupBy`.",
828
866
  path: ["groupBy"]
829
867
  });
@@ -831,7 +869,7 @@ var MetricsQuerySchema = import_zod13.z.discriminatedUnion("resource", [
831
869
  input.metrics.forEach((metric, index) => {
832
870
  if (metric.aggregation !== "count" && metric.field === void 0) {
833
871
  ctx.addIssue({
834
- code: import_zod13.z.ZodIssueCode.custom,
872
+ code: import_zod14.z.ZodIssueCode.custom,
835
873
  message: "`field` is required unless `aggregation` is `count`.",
836
874
  path: ["metrics", index, "field"]
837
875
  });
@@ -840,7 +878,7 @@ var MetricsQuerySchema = import_zod13.z.discriminatedUnion("resource", [
840
878
  const aliases = input.metrics.map((metric) => metric.alias).filter((alias) => alias !== void 0);
841
879
  if (new Set(aliases).size !== aliases.length) {
842
880
  ctx.addIssue({
843
- code: import_zod13.z.ZodIssueCode.custom,
881
+ code: import_zod14.z.ZodIssueCode.custom,
844
882
  message: "Every `metrics[].alias` must be unique.",
845
883
  path: ["metrics"]
846
884
  });
@@ -849,32 +887,32 @@ var MetricsQuerySchema = import_zod13.z.discriminatedUnion("resource", [
849
887
  input.metrics.forEach((metric, index) => {
850
888
  if (metric.alias !== void 0 && reservedNames.has(metric.alias)) {
851
889
  ctx.addIssue({
852
- code: import_zod13.z.ZodIssueCode.custom,
890
+ code: import_zod14.z.ZodIssueCode.custom,
853
891
  message: `\`alias\` "${metric.alias}" collides with a \`groupBy\` field name (or the reserved word "bucket") \u2014 choose a different alias.`,
854
892
  path: ["metrics", index, "alias"]
855
893
  });
856
894
  }
857
895
  });
858
896
  });
859
- var MetricsQueryResultRowSchema = import_zod13.z.record(
860
- import_zod13.z.string(),
861
- import_zod13.z.union([import_zod13.z.string(), import_zod13.z.number(), import_zod13.z.boolean(), import_zod13.z.null()])
897
+ var MetricsQueryResultRowSchema = import_zod14.z.record(
898
+ import_zod14.z.string(),
899
+ import_zod14.z.union([import_zod14.z.string(), import_zod14.z.number(), import_zod14.z.boolean(), import_zod14.z.null()])
862
900
  );
863
- var MetricsQueryResultSchema = import_zod13.z.object({
864
- data: import_zod13.z.array(MetricsQueryResultRowSchema),
865
- meta: import_zod13.z.object({
901
+ var MetricsQueryResultSchema = import_zod14.z.object({
902
+ data: import_zod14.z.array(MetricsQueryResultRowSchema),
903
+ meta: import_zod14.z.object({
866
904
  resource: MetricsResourceSchema,
867
905
  environment: EnvironmentSchema,
868
- rowCount: import_zod13.z.number().int().describe("Number of rows in `data`."),
869
- truncated: import_zod13.z.boolean().describe(
906
+ rowCount: import_zod14.z.number().int().describe("Number of rows in `data`."),
907
+ truncated: import_zod14.z.boolean().describe(
870
908
  "`true` if more rows matched than `limit` allowed \u2014 `data` holds only the first `limit`."
871
909
  )
872
910
  })
873
911
  });
874
912
 
875
913
  // src/webhook-events.ts
876
- var import_zod14 = require("zod");
877
- var ChargeWebhookEventTypeSchema = import_zod14.z.enum([
914
+ var import_zod15 = require("zod");
915
+ var ChargeWebhookEventTypeSchema = import_zod15.z.enum([
878
916
  "charge.created",
879
917
  "charge.partially_paid",
880
918
  "charge.confirmed",
@@ -888,14 +926,14 @@ var ChargeWebhookEventTypeSchema = import_zod14.z.enum([
888
926
  ]).describe(
889
927
  '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`). `charge.escrow_released` fires once an escrow-configured charge\'s funds have been moved out of its Safe to the split address by `POST /v1/charges/{id}/release` \u2014 a normal `charge.settled` still follows once the split itself finishes distributing. `charge.escrow_refunded` fires once an escrow-configured charge\'s funds have been moved out of its Safe back to the payer by `POST /v1/charges/{id}/refund` \u2014 mutually exclusive with `charge.escrow_released`, an escrow charge only ever emits one of the two. Every event in this category carries the full `Charge` object as `data`.'
890
928
  );
891
- var WebhookDeliveryEventTypeSchema = import_zod14.z.enum(["webhook.delivery_failed", "webhook.delivery_recovered", "webhook.endpoint_unhealthy"]).describe(
929
+ var WebhookDeliveryEventTypeSchema = import_zod15.z.enum(["webhook.delivery_failed", "webhook.delivery_recovered", "webhook.endpoint_unhealthy"]).describe(
892
930
  "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`)."
893
931
  );
894
- var WebhookEventTypeSchema = import_zod14.z.union([
932
+ var WebhookEventTypeSchema = import_zod15.z.union([
895
933
  ChargeWebhookEventTypeSchema,
896
934
  WebhookDeliveryEventTypeSchema
897
935
  ]);
898
- var WebhookCategorySchema = import_zod14.z.enum(["payments", "webhooks"]).describe(
936
+ var WebhookCategorySchema = import_zod15.z.enum(["payments", "webhooks"]).describe(
899
937
  "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."
900
938
  );
901
939
  function buildCategoryMap() {
@@ -925,116 +963,119 @@ var TriggerableChargeEventSchema = ChargeWebhookEventTypeSchema.exclude([
925
963
  );
926
964
 
927
965
  // src/webhooks.ts
928
- var import_zod15 = require("zod");
966
+ var import_zod16 = require("zod");
929
967
  var WEBHOOK_EVENTS_WILDCARD = "*";
930
- var CreateWebhookSchema = import_zod15.z.object({
931
- url: import_zod15.z.string().max(2048).url().describe(
968
+ var CreateWebhookSchema = import_zod16.z.object({
969
+ url: import_zod16.z.string().max(2048).url().describe(
932
970
  "Must be HTTPS and resolve to a public address \u2014 private/internal IPs are rejected."
933
971
  ),
934
- 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(
972
+ events: import_zod16.z.array(import_zod16.z.union([WebhookEventTypeSchema, import_zod16.z.literal(WEBHOOK_EVENTS_WILDCARD)])).max(Object.keys(EVENT_CATEGORY_MAP).length + 1).default([]).describe(
935
973
  '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.'
936
974
  ),
937
- eventCategories: import_zod15.z.array(WebhookCategorySchema).max(WebhookCategorySchema.options.length).default([]).describe(
975
+ eventCategories: import_zod16.z.array(WebhookCategorySchema).max(WebhookCategorySchema.options.length).default([]).describe(
938
976
  "Subscribe to every event in these categories. At least one of `events` or `eventCategories` is required."
939
977
  ),
940
- excludeEvents: import_zod15.z.array(WebhookEventTypeSchema).max(Object.keys(EVENT_CATEGORY_MAP).length).default([]).describe(
978
+ excludeEvents: import_zod16.z.array(WebhookEventTypeSchema).max(Object.keys(EVENT_CATEGORY_MAP).length).default([]).describe(
941
979
  'Event types to exclude even if selected via `events: ["*"]` or `eventCategories`.'
942
980
  )
943
981
  }).refine((v) => v.events.length > 0 || v.eventCategories.length > 0, {
944
982
  message: "must select at least one event via `events` or `eventCategories`",
945
983
  path: ["events"]
946
984
  });
947
- var WebhookSchema = import_zod15.z.object({
948
- id: import_zod15.z.string(),
985
+ var WebhookSchema = import_zod16.z.object({
986
+ id: import_zod16.z.string(),
949
987
  environment: EnvironmentSchema.nullable().describe(
950
988
  "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)."
951
989
  ),
952
- url: import_zod15.z.string(),
953
- events: import_zod15.z.array(WebhookEventTypeSchema),
954
- eventCategories: import_zod15.z.array(WebhookCategorySchema),
955
- excludeEvents: import_zod15.z.array(WebhookEventTypeSchema),
956
- isWildcard: import_zod15.z.boolean(),
957
- secret: import_zod15.z.string().describe(
990
+ url: import_zod16.z.string(),
991
+ events: import_zod16.z.array(WebhookEventTypeSchema),
992
+ eventCategories: import_zod16.z.array(WebhookCategorySchema),
993
+ excludeEvents: import_zod16.z.array(WebhookEventTypeSchema),
994
+ isWildcard: import_zod16.z.boolean(),
995
+ secret: import_zod16.z.string().describe(
958
996
  "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."
959
997
  ),
960
- createdAt: import_zod15.z.string().datetime()
998
+ createdAt: import_zod16.z.string().datetime()
961
999
  });
962
1000
  var WebhookListItemSchema = WebhookSchema.omit({ secret: true }).extend({
963
- hint: import_zod15.z.string().describe("A truncated, safe-to-display form of the secret (e.g. `whsec_...ab12`).")
1001
+ hint: import_zod16.z.string().describe("A truncated, safe-to-display form of the secret (e.g. `whsec_...ab12`).")
964
1002
  });
965
- var WebhookPayloadSchema = import_zod15.z.object({
966
- id: import_zod15.z.string().describe(
1003
+ var WebhookPayloadSchema = import_zod16.z.object({
1004
+ id: import_zod16.z.string().describe(
967
1005
  "Unique id for this specific delivery \u2014 also sent as the `X-Klappay-Delivery` header."
968
1006
  ),
969
1007
  event: WebhookEventTypeSchema,
970
- createdAt: import_zod15.z.string().datetime(),
971
- data: import_zod15.z.unknown().describe(
1008
+ createdAt: import_zod16.z.string().datetime(),
1009
+ data: import_zod16.z.unknown().describe(
972
1010
  "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."
973
1011
  )
974
1012
  });
975
- var WebhookDeliveryStatusSchema = import_zod15.z.enum(["pending", "delivered", "failed"]);
976
- var WebhookDeliverySchema = import_zod15.z.object({
977
- id: import_zod15.z.string(),
978
- webhookId: import_zod15.z.string(),
1013
+ var WebhookDeliveryStatusSchema = import_zod16.z.enum(["pending", "delivered", "failed"]);
1014
+ var WebhookDeliverySchema = import_zod16.z.object({
1015
+ id: import_zod16.z.string(),
1016
+ webhookId: import_zod16.z.string(),
979
1017
  event: WebhookEventTypeSchema,
980
1018
  status: WebhookDeliveryStatusSchema.describe(
981
1019
  "`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."
982
1020
  ),
983
- attempts: import_zod15.z.number(),
984
- responseCode: import_zod15.z.number().nullable().describe(
1021
+ attempts: import_zod16.z.number(),
1022
+ responseCode: import_zod16.z.number().nullable().describe(
985
1023
  "HTTP status your endpoint returned on the most recent attempt. `null` if every attempt failed to connect at all."
986
1024
  ),
987
- nextRetryAt: import_zod15.z.string().datetime().nullable(),
988
- deliveredAt: import_zod15.z.string().datetime().nullable(),
989
- createdAt: import_zod15.z.string().datetime()
1025
+ nextRetryAt: import_zod16.z.string().datetime().nullable(),
1026
+ deliveredAt: import_zod16.z.string().datetime().nullable(),
1027
+ createdAt: import_zod16.z.string().datetime()
990
1028
  });
991
1029
  var ListWebhookDeliveriesSchema = PaginationQuerySchema;
992
1030
  var PaginatedWebhookDeliveriesSchema = paginatedSchema(WebhookDeliverySchema);
993
1031
 
994
1032
  // src/recipients.ts
995
- var import_zod16 = require("zod");
1033
+ var import_zod17 = require("zod");
996
1034
  var EVM_ADDRESS_REGEX = /^0x[0-9a-fA-F]{40}$/;
997
- var CreateRecipientSchema = import_zod16.z.object({
998
- 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."),
999
- label: import_zod16.z.string().min(1).max(64).optional().describe('Free-form label for your own bookkeeping (e.g. `"supplier"`) \u2014 never interpreted.')
1035
+ var CreateRecipientSchema = import_zod17.z.object({
1036
+ address: import_zod17.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."),
1037
+ label: import_zod17.z.string().min(1).max(64).optional().describe('Free-form label for your own bookkeeping (e.g. `"supplier"`) \u2014 never interpreted.')
1000
1038
  });
1001
- var RecipientSchema = import_zod16.z.object({
1002
- id: import_zod16.z.string().describe(
1039
+ var RecipientSchema = import_zod17.z.object({
1040
+ id: import_zod17.z.string().describe(
1003
1041
  "Klappay-generated id, e.g. `rc_...` \u2014 this, not the raw address, is what a charge's `splitRecipients[].recipientId` references."
1004
1042
  ),
1005
1043
  environment: EnvironmentSchema,
1006
- address: import_zod16.z.string(),
1007
- label: import_zod16.z.string().nullable(),
1008
- payout: import_zod16.z.boolean().describe(
1044
+ address: import_zod17.z.string(),
1045
+ label: import_zod17.z.string().nullable(),
1046
+ payout: import_zod17.z.boolean().describe(
1009
1047
  "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`."
1010
1048
  ),
1011
- createdAt: import_zod16.z.string().datetime()
1049
+ createdAt: import_zod17.z.string().datetime()
1012
1050
  });
1013
- var SetRecipientPayoutSchema = import_zod16.z.object({
1014
- payout: import_zod16.z.boolean().describe("New payout-eligibility value for this recipient.")
1051
+ var SetRecipientPayoutSchema = import_zod17.z.object({
1052
+ payout: import_zod17.z.boolean().describe("New payout-eligibility value for this recipient.")
1015
1053
  });
1016
1054
 
1017
1055
  // src/timeline.ts
1018
- var import_zod17 = require("zod");
1019
- var TransactionSourceSchema = import_zod17.z.enum(["moralis_webhook", "reconciliation_job", "sandbox"]).describe(
1020
- "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)."
1056
+ var import_zod18 = require("zod");
1057
+ var TransactionSourceSchema = import_zod18.z.enum(["contract_watcher", "reconciliation_job", "sandbox"]).describe(
1058
+ "How this transfer was detected: `contract_watcher` (the normal path \u2014 a real-time on-chain event subscription), `reconciliation_job` (a fallback poller caught it after the watcher missed or delayed it), or `sandbox` (simulated via `POST /v1/sandbox/charges/{id}/trigger`, no real on-chain transfer)."
1021
1059
  );
1022
- var TimelineEventTypeSchema = import_zod17.z.enum([
1060
+ var TimelineEventTypeSchema = import_zod18.z.enum([
1023
1061
  "charge.created",
1024
1062
  "charge.expired",
1025
1063
  "transaction.detected",
1026
1064
  "split.distributed",
1027
1065
  "webhook.dispatched",
1028
1066
  "webhook.delivered",
1029
- "webhook.failed"
1067
+ "webhook.failed",
1068
+ "transfer.reclaimed"
1030
1069
  ]).describe(
1031
- "`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)."
1070
+ "`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). `transfer.reclaimed`: an on-chain transfer was detected but never reached its network's required confirmation depth before vanishing (reverted, or dropped from the canonical chain) \u2014 see `txHash` below for which transfer."
1032
1071
  );
1033
- var TimelineEventSchema = import_zod17.z.object({
1072
+ var TimelineEventSchema = import_zod18.z.object({
1034
1073
  type: TimelineEventTypeSchema,
1035
- at: import_zod17.z.string().datetime(),
1036
- txHash: import_zod17.z.string().optional().describe("Present for `transaction.detected` and `split.distributed` events only."),
1037
- amount: import_zod17.z.number().optional().describe(
1074
+ at: import_zod18.z.string().datetime(),
1075
+ txHash: import_zod18.z.string().optional().describe(
1076
+ "Present for `transaction.detected`, `split.distributed`, and `transfer.reclaimed` events only."
1077
+ ),
1078
+ amount: import_zod18.z.number().optional().describe(
1038
1079
  "Present for `transaction.detected` events only \u2014 the amount that specific transfer carried."
1039
1080
  ),
1040
1081
  source: TransactionSourceSchema.optional().describe(
@@ -1046,102 +1087,102 @@ var TimelineEventSchema = import_zod17.z.object({
1046
1087
  network: NetworkSchema.optional().describe(
1047
1088
  "Present for `transaction.detected` and `split.distributed` events \u2014 which network this specific transfer, or settlement, used."
1048
1089
  ),
1049
- causedTransition: import_zod17.z.boolean().optional().describe(
1090
+ causedTransition: import_zod18.z.boolean().optional().describe(
1050
1091
  "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."
1051
1092
  ),
1052
1093
  event: WebhookEventTypeSchema.optional().describe(
1053
1094
  "Present for `webhook.*` events only \u2014 which event type this delivery was for."
1054
1095
  ),
1055
- responseCode: import_zod17.z.number().nullable().optional().describe(
1096
+ responseCode: import_zod18.z.number().nullable().optional().describe(
1056
1097
  "Present for `webhook.*` events only \u2014 HTTP status your endpoint returned, or `null` if the request never connected."
1057
1098
  ),
1058
- attempts: import_zod17.z.number().optional().describe(
1099
+ attempts: import_zod18.z.number().optional().describe(
1059
1100
  "Present for `webhook.*` events only \u2014 how many delivery attempts have been made so far."
1060
1101
  )
1061
1102
  });
1062
1103
 
1063
1104
  // src/health.ts
1064
- var import_zod18 = require("zod");
1065
- var HealthSchema = import_zod18.z.object({
1066
- status: import_zod18.z.enum(["ok", "error"]).describe(
1105
+ var import_zod19 = require("zod");
1106
+ var HealthSchema = import_zod19.z.object({
1107
+ status: import_zod19.z.enum(["ok", "error"]).describe(
1067
1108
  "`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."
1068
1109
  ),
1069
- version: import_zod18.z.string(),
1070
- timestamp: import_zod18.z.string().datetime(),
1071
- db: import_zod18.z.enum(["ok", "error"]).describe("Result of a real database connectivity check, not just a process-alive check."),
1072
- pendingWebhooks: import_zod18.z.number().describe("Count of webhook deliveries still awaiting a successful attempt."),
1073
- oldestPendingChargeAgeSeconds: import_zod18.z.number().nullable().describe("Age of the oldest still-unpaid charge, in seconds. `null` if there are none."),
1074
- lastMoralisEventAgeSeconds: import_zod18.z.number().nullable().describe(
1110
+ version: import_zod19.z.string(),
1111
+ timestamp: import_zod19.z.string().datetime(),
1112
+ db: import_zod19.z.enum(["ok", "error"]).describe("Result of a real database connectivity check, not just a process-alive check."),
1113
+ pendingWebhooks: import_zod19.z.number().describe("Count of webhook deliveries still awaiting a successful attempt."),
1114
+ oldestPendingChargeAgeSeconds: import_zod19.z.number().nullable().describe("Age of the oldest still-unpaid charge, in seconds. `null` if there are none."),
1115
+ lastContractWatcherEventAgeSeconds: import_zod19.z.number().nullable().describe(
1075
1116
  "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."
1076
1117
  )
1077
1118
  });
1078
1119
 
1079
1120
  // src/sandbox.ts
1080
- var import_zod19 = require("zod");
1081
- var SandboxTriggerSchema = import_zod19.z.object({
1121
+ var import_zod20 = require("zod");
1122
+ var SandboxTriggerSchema = import_zod20.z.object({
1082
1123
  event: TriggerableChargeEventSchema,
1083
- amount: import_zod19.z.number().positive().max(CHARGE_AMOUNT_MAX).optional().describe(
1124
+ amount: import_zod20.z.number().positive().max(CHARGE_AMOUNT_MAX).optional().describe(
1084
1125
  "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."
1085
1126
  )
1086
1127
  });
1087
1128
 
1088
1129
  // src/capabilities.ts
1089
- var import_zod20 = require("zod");
1090
- var CapabilitiesSchema = import_zod20.z.object({
1091
- acceptedPayments: import_zod20.z.array(AcceptedPaymentSchema).describe(
1130
+ var import_zod21 = require("zod");
1131
+ var CapabilitiesSchema = import_zod21.z.object({
1132
+ acceptedPayments: import_zod21.z.array(AcceptedPaymentSchema).describe(
1092
1133
  "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."
1093
1134
  )
1094
1135
  });
1095
1136
 
1096
1137
  // src/swap.ts
1097
- var import_zod21 = require("zod");
1098
- var CreateSwapQuoteSchema = import_zod21.z.object({
1138
+ var import_zod22 = require("zod");
1139
+ var CreateSwapQuoteSchema = import_zod22.z.object({
1099
1140
  inputToken: AltTokenSchema.describe(
1100
1141
  "Which alt-cryptocurrency the payer wants to send \u2014 must be one of this charge's `swapAlternatives`, or `422 token_not_supported`."
1101
1142
  ),
1102
1143
  inputNetwork: NetworkSchema.describe(
1103
1144
  "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."
1104
1145
  ),
1105
- takerAddress: import_zod21.z.string().regex(/^0x[0-9a-fA-F]{40}$/, "must be a 20-byte hex address").describe(
1146
+ takerAddress: import_zod22.z.string().regex(/^0x[0-9a-fA-F]{40}$/, "must be a 20-byte hex address").describe(
1106
1147
  "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."
1107
1148
  )
1108
1149
  });
1109
- var SwapQuoteSchema = import_zod21.z.object({
1150
+ var SwapQuoteSchema = import_zod22.z.object({
1110
1151
  inputToken: AltTokenSchema,
1111
1152
  inputNetwork: NetworkSchema,
1112
- inputAmount: import_zod21.z.number().describe(
1153
+ inputAmount: import_zod22.z.number().describe(
1113
1154
  "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."
1114
1155
  ),
1115
1156
  outputToken: TokenSchema.describe(
1116
1157
  "Which of this charge's `acceptedPayments` tokens the swap resolves to."
1117
1158
  ),
1118
1159
  outputNetwork: NetworkSchema,
1119
- outputAmount: import_zod21.z.number().describe(
1160
+ outputAmount: import_zod22.z.number().describe(
1120
1161
  "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`."
1121
1162
  ),
1122
- fees: import_zod21.z.object({
1123
- klappayFee: import_zod21.z.number().describe(
1163
+ fees: import_zod22.z.object({
1164
+ klappayFee: import_zod22.z.number().describe(
1124
1165
  "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`."
1125
1166
  ),
1126
- zeroExFee: import_zod21.z.number().nullable().describe(
1167
+ zeroExFee: import_zod22.z.number().nullable().describe(
1127
1168
  "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."
1128
1169
  )
1129
1170
  }).describe(
1130
1171
  "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`."
1131
1172
  ),
1132
- expiresAt: import_zod21.z.string().datetime().describe(
1173
+ expiresAt: import_zod22.z.string().datetime().describe(
1133
1174
  "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."
1134
1175
  ),
1135
- transaction: import_zod21.z.object({
1136
- to: import_zod21.z.string().describe("Contract address the payer's wallet must send this transaction to."),
1137
- data: import_zod21.z.string().describe("Calldata \u2014 opaque, must be sent unmodified."),
1138
- value: import_zod21.z.string().describe(
1176
+ transaction: import_zod22.z.object({
1177
+ to: import_zod22.z.string().describe("Contract address the payer's wallet must send this transaction to."),
1178
+ data: import_zod22.z.string().describe("Calldata \u2014 opaque, must be sent unmodified."),
1179
+ value: import_zod22.z.string().describe(
1139
1180
  "Native currency (ETH/BNB/MATIC/AVAX) to attach, in wei \u2014 `\"0\"` when `inputToken` isn't this network's native currency."
1140
1181
  )
1141
1182
  }).describe(
1142
1183
  "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."
1143
1184
  ),
1144
- permit2: import_zod21.z.object({ eip712: import_zod21.z.record(import_zod21.z.unknown()) }).nullish().describe(
1185
+ permit2: import_zod22.z.object({ eip712: import_zod22.z.record(import_zod22.z.unknown()) }).nullish().describe(
1145
1186
  "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."
1146
1187
  )
1147
1188
  });
@@ -1162,6 +1203,7 @@ var SwapQuoteSchema = import_zod21.z.object({
1162
1203
  CHECKOUT_PRODUCTS_MAX,
1163
1204
  CONFLICTING_SCOPE_PAIRS,
1164
1205
  CapabilitiesSchema,
1206
+ ChargeFeePayerSchema,
1165
1207
  ChargeSchema,
1166
1208
  ChargeStatusSchema,
1167
1209
  ChargeWebhookEventTypeSchema,
@@ -1171,6 +1213,7 @@ var SwapQuoteSchema = import_zod21.z.object({
1171
1213
  CheckChargeRequestSchema,
1172
1214
  CheckChargeResponseSchema,
1173
1215
  CheckoutProductSchema,
1216
+ ConfirmationProgressSchema,
1174
1217
  CreateChargeSchema,
1175
1218
  CreateRecipientSchema,
1176
1219
  CreateSwapQuoteSchema,