@klappay/types 4.1.0 → 5.1.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.mjs CHANGED
@@ -4,14 +4,21 @@ import {
4
4
  CHAIN_IDS,
5
5
  EVM_NETWORKS,
6
6
  NETWORK_EXPLORERS,
7
+ NETWORK_FAMILIES,
7
8
  NETWORK_LABELS,
8
9
  OPERATIONAL_NETWORKS,
10
+ SplitAddressSchema,
9
11
  TOKEN_ADDRESSES,
10
12
  TOKEN_DECIMALS,
11
13
  TOKEN_DEPLOYMENTS,
14
+ addressesEqual,
12
15
  getTokenDeployment,
13
- isPaymentDeploymentEnabled
14
- } from "./chunk-WKIOAEJ3.mjs";
16
+ isEvmAddress,
17
+ isPaymentDeploymentEnabled,
18
+ isSplitAddress,
19
+ isTronAddress,
20
+ tronAddress
21
+ } from "./chunk-UEXXRQL3.mjs";
15
22
 
16
23
  // src/errors.ts
17
24
  import { z } from "zod";
@@ -68,7 +75,7 @@ function findConflictingScopes(scopes) {
68
75
 
69
76
  // src/networks.ts
70
77
  import { z as z4 } from "zod";
71
- var NetworkSchema = z4.enum(["base", "optimism", "polygon", "ethereum", "arbitrum", "avalanche", "bnb"]).describe("The blockchain a charge/payment is on.");
78
+ var NetworkSchema = z4.enum(["base", "optimism", "polygon", "ethereum", "arbitrum", "avalanche", "bnb", "tron", "arc"]).describe("The blockchain a charge/payment is on.");
72
79
 
73
80
  // src/pagination.ts
74
81
  import { z as z5 } from "zod";
@@ -99,8 +106,8 @@ var TokenSchema = z6.enum(["USDC", "USDT"]).describe(
99
106
 
100
107
  // src/alt-tokens.ts
101
108
  import { z as z7 } from "zod";
102
- var AltTokenSchema = z7.enum(["ETH", "BNB", "MATIC", "AVAX", "BTC"]).describe(
103
- "A non-stablecoin cryptocurrency Klappay trusts as swap input for a charge, via the 0x Swap API \u2014 swapped to one of the charge's `acceptedPayments` tokens before it ever reaches the merchant, so the merchant always receives USDC/USDT regardless of what the payer sent. Only a network's own native currency, plus `BTC` (wrapped) on the networks with deep, reputably-custodied liquidity, is trusted today (see `ALT_TOKEN_ADDRESSES`) \u2014 never assume every value here is available on every network."
109
+ var AltTokenSchema = z7.enum(["ETH", "BNB", "POL", "AVAX", "BTC", "LINK", "ARB", "OP", "CBETH"]).describe(
110
+ "A non-stablecoin cryptocurrency Klappay trusts as swap input for a charge, via the 0x Swap API \u2014 swapped to one of the charge's `acceptedPayments` tokens before it ever reaches the merchant, so the merchant always receives USDC/USDT regardless of what the payer sent. Trusted on a given network only when it has deep, reputably-issued/custodied liquidity there: each network's own native currency, `BTC` (wrapped) on the networks with a trusted deployment, `LINK` (Chainlink's own official per-chain deployment, except Avalanche's bridged `LINK.e`), and a small set of chain-specific blue chips (`ARB` on Arbitrum, `OP` on Optimism, `CBETH` on Base) \u2014 see `ALT_TOKEN_ADDRESSES` for the authoritative per-network list, never assume every value here is available on every network. `POL` replaced `MATIC` as Polygon's native currency name (Polygon's own token migration, 2024) \u2014 this schema tracks the network's current native asset, not the deprecated ticker."
104
111
  );
105
112
  var SwapAlternativeSchema = z7.object({
106
113
  token: AltTokenSchema,
@@ -178,7 +185,7 @@ var ChargeFeePayerSchema = z11.enum(["merchant", "payer"]).describe(
178
185
  );
179
186
  var CHARGE_EXPIRES_IN_MIN_SECONDS = 60;
180
187
  var CHARGE_EXPIRES_IN_MAX_SECONDS = 3600;
181
- var CHARGE_ACCEPTED_PAYMENTS_MAX = 14;
188
+ var CHARGE_ACCEPTED_PAYMENTS_MAX = 18;
182
189
  var AcceptedPaymentSchema = z11.object({
183
190
  token: TokenSchema,
184
191
  network: NetworkSchema
@@ -203,12 +210,21 @@ var AcceptedPaymentsSchema = z11.array(AcceptedPaymentSchema).min(1, "At least o
203
210
  });
204
211
  }
205
212
  });
213
+ const families = new Set(pairs.map((pair) => NETWORK_FAMILIES[pair.network]));
214
+ if (families.size > 1) {
215
+ ctx.addIssue({
216
+ code: z11.ZodIssueCode.custom,
217
+ message: `acceptedPayments mixes networks from different split families (${[...families].sort().join(", ")}) \u2014 every network in this list must share the same underlying split factory, so a charge can only ever accept networks from one family at a time.`
218
+ });
219
+ }
206
220
  }).describe(
207
- `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\`.`
221
+ `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\`. Every network listed must also share the same split family (which networks are grouped together is an implementation detail, not part of this API's contract) \u2014 a charge predicts one split address up front and reuses it across every accepted network, which is only safe within one family; mixing families is rejected with \`400 validation_error\`.`
208
222
  );
209
223
  var CHARGE_SPLIT_RECIPIENTS_MAX = 5;
210
224
  var SplitRecipientSchema = z11.object({
211
- address: z11.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."),
225
+ address: SplitAddressSchema.describe(
226
+ "Address to send a slice of this charge to \u2014 an EVM 0x... address or a TRON T... address, matching whichever network family the charge accepts (acceptedPayments can only ever list networks from one split family at a time, so this always matches that same family)."
227
+ ),
212
228
  percent: z11.number().positive().max(100).describe(
213
229
  "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."
214
230
  ),
@@ -268,8 +284,21 @@ var CreateChargeSchema = z11.object({
268
284
  ),
269
285
  splitRecipients: SplitRecipientsInputSchema.optional(),
270
286
  escrow: EscrowConfigSchema.optional().describe(
271
- "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."
287
+ "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. **Requires every accepted network to be EVM** (Safe \u2014 the underlying custody contract \u2014 isn't deployed on Tron, and can never be; it's not an EVM chain) \u2014 rejected with `400 validation_error` otherwise."
272
288
  )
289
+ }).superRefine((data, ctx) => {
290
+ if (!data.escrow) return;
291
+ const evmNetworks = EVM_NETWORKS;
292
+ const hasUnsupportedNetwork = data.acceptedPayments.some(
293
+ (pair) => !evmNetworks.includes(pair.network)
294
+ );
295
+ if (hasUnsupportedNetwork) {
296
+ ctx.addIssue({
297
+ code: z11.ZodIssueCode.custom,
298
+ message: "Escrow is not supported for this charge's network \u2014 Safe (the underlying custody contract) isn't an EVM chain there. Remove `escrow`, or accept payment on an EVM network instead.",
299
+ path: ["escrow"]
300
+ });
301
+ }
273
302
  });
274
303
  var ChargeSchema = z11.object({
275
304
  id: z11.string().describe("Klappay-generated id, e.g. `ch_...`. Use this to look up the charge later."),
@@ -488,6 +517,7 @@ var MetricsFilterValueSchema = z15.union([
488
517
  z15.string().max(255),
489
518
  z15.number(),
490
519
  z15.boolean(),
520
+ z15.null(),
491
521
  z15.array(z15.union([z15.string().max(255), z15.number()])).min(1).max(50)
492
522
  ]);
493
523
  var orderBySchema = z15.object({
@@ -827,9 +857,10 @@ var PaginatedWebhookDeliveriesSchema = paginatedSchema(WebhookDeliverySchema);
827
857
 
828
858
  // src/recipients.ts
829
859
  import { z as z18 } from "zod";
830
- var EVM_ADDRESS_REGEX = /^0x[0-9a-fA-F]{40}$/;
831
860
  var CreateRecipientSchema = z18.object({
832
- address: z18.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."),
861
+ address: SplitAddressSchema.describe(
862
+ "Address to register as a trusted split recipient for your organization \u2014 an EVM 0x... address or a TRON T... address."
863
+ ),
833
864
  label: z18.string().min(1).max(64).optional().describe('Free-form label for your own bookkeeping (e.g. `"supplier"`) \u2014 never interpreted.')
834
865
  });
835
866
  var RecipientSchema = z18.object({
@@ -844,14 +875,15 @@ var RecipientSchema = z18.object({
844
875
  ),
845
876
  createdAt: z18.string().datetime()
846
877
  });
878
+ var PaginatedRecipientsSchema = paginatedSchema(RecipientSchema);
847
879
  var SetRecipientPayoutSchema = z18.object({
848
880
  payout: z18.boolean().describe("New payout-eligibility value for this recipient.")
849
881
  });
850
882
 
851
883
  // src/timeline.ts
852
884
  import { z as z19 } from "zod";
853
- var TransactionSourceSchema = z19.enum(["contract_watcher", "reconciliation_job", "sandbox"]).describe(
854
- "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)."
885
+ var TransactionSourceSchema = z19.enum(["contract_watcher", "reconciliation_job", "sandbox", "tron_watcher"]).describe(
886
+ "How this transfer was detected: `contract_watcher` (the normal path for EVM networks \u2014 a real-time WebSocket log subscription), `tron_watcher` (the TRON equivalent \u2014 a real-time ZeroMQ event subscription against a self-hosted node, a different underlying mechanism since TRON has no WebSocket log 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)."
855
887
  );
856
888
  var TimelineEventTypeSchema = z19.enum([
857
889
  "charge.created",
@@ -985,13 +1017,13 @@ var SwapQuoteSchema = z23.object({
985
1017
  to: z23.string().describe("Contract address the payer's wallet must send this transaction to."),
986
1018
  data: z23.string().describe("Calldata \u2014 opaque, must be sent unmodified."),
987
1019
  value: z23.string().describe(
988
- "Native currency (ETH/BNB/MATIC/AVAX) to attach, in wei \u2014 `\"0\"` when `inputToken` isn't this network's native currency."
1020
+ "Native currency (ETH/BNB/POL/AVAX) to attach, in wei \u2014 `\"0\"` when `inputToken` isn't this network's native currency."
989
1021
  )
990
1022
  }).describe(
991
1023
  "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."
992
1024
  ),
993
1025
  permit2: z23.object({ eip712: z23.record(z23.unknown()) }).nullish().describe(
994
- "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."
1026
+ "Present only when `inputToken` is an ERC-20 (BTC, LINK, or a chain-specific blue chip like ARB/OP/CBETH) \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/POL/AVAX) \u2014 `transaction` is then ready to sign and send directly, no extra step."
995
1027
  )
996
1028
  });
997
1029
  export {
@@ -1054,6 +1086,7 @@ export {
1054
1086
  MetricsQuerySchema,
1055
1087
  MetricsResourceSchema,
1056
1088
  NETWORK_EXPLORERS,
1089
+ NETWORK_FAMILIES,
1057
1090
  NETWORK_LABELS,
1058
1091
  NetworkSchema,
1059
1092
  OPERATIONAL_NETWORKS,
@@ -1062,6 +1095,7 @@ export {
1062
1095
  PAGINATION_LIMIT_MIN,
1063
1096
  PaginatedChargesSchema,
1064
1097
  PaginatedPendingDistributionsSchema,
1098
+ PaginatedRecipientsSchema,
1065
1099
  PaginatedWebhookDeliveriesSchema,
1066
1100
  PaginationQuerySchema,
1067
1101
  PendingDistributionEventSchema,
@@ -1073,6 +1107,7 @@ export {
1073
1107
  SandboxTriggerSchema,
1074
1108
  SetRecipientPayoutSchema,
1075
1109
  SettlementStatusSchema,
1110
+ SplitAddressSchema,
1076
1111
  SplitDistributionStatusSchema,
1077
1112
  SplitRecipientInputSchema,
1078
1113
  SplitRecipientSchema,
@@ -1099,10 +1134,15 @@ export {
1099
1134
  WebhookListItemSchema,
1100
1135
  WebhookPayloadSchema,
1101
1136
  WebhookSchema,
1137
+ addressesEqual,
1102
1138
  findConflictingScopes,
1103
1139
  getTokenDeployment,
1140
+ isEvmAddress,
1104
1141
  isPaymentDeploymentEnabled,
1142
+ isSplitAddress,
1143
+ isTronAddress,
1105
1144
  listSwapAlternatives,
1106
- paginatedSchema
1145
+ paginatedSchema,
1146
+ tronAddress
1107
1147
  };
1108
1148
  //# sourceMappingURL=index.mjs.map