@klappay/types 3.1.1 → 3.2.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/README.md +1 -1
- package/dist/index.d.mts +19 -1
- package/dist/index.d.ts +19 -1
- package/dist/index.js +202 -187
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +201 -187
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -310,62 +310,75 @@ var GetChargeQrCodeQuerySchema = z9.object({
|
|
|
310
310
|
network: NetworkSchema.optional()
|
|
311
311
|
});
|
|
312
312
|
|
|
313
|
-
// src/
|
|
313
|
+
// src/charge-check.ts
|
|
314
314
|
import { z as z10 } from "zod";
|
|
315
|
-
var
|
|
315
|
+
var CheckChargeRequestSchema = z10.object({
|
|
316
|
+
txHash: z10.string().regex(/^0x[0-9a-fA-F]{64}$/, "must be a 32-byte transaction hash").optional().describe(
|
|
317
|
+
"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."
|
|
318
|
+
),
|
|
319
|
+
network: NetworkSchema.optional().describe(
|
|
320
|
+
"Which network `txHash` is on \u2014 required together with `txHash`, since a transaction hash alone doesn't identify a chain. Must be one of the networks this charge actually accepts payment on, or `422 payment_pair_not_accepted`."
|
|
321
|
+
)
|
|
322
|
+
}).refine((data) => Boolean(data.txHash) === Boolean(data.network), {
|
|
323
|
+
message: "`txHash` and `network` must be provided together, or both omitted"
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
// src/distributions.ts
|
|
327
|
+
import { z as z11 } from "zod";
|
|
328
|
+
var SplitDistributionStatusSchema = z11.enum(["pending", "processing", "completed", "failed"]).describe(
|
|
316
329
|
"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."
|
|
317
330
|
);
|
|
318
|
-
var PendingDistributionRecipientSchema =
|
|
319
|
-
address:
|
|
320
|
-
percentAllocation:
|
|
331
|
+
var PendingDistributionRecipientSchema = z11.object({
|
|
332
|
+
address: z11.string().describe("On-chain recipient address."),
|
|
333
|
+
percentAllocation: z11.number().describe("This recipient's share of the split, as a percentage (e.g. `99.0991` = 99.0991%).")
|
|
321
334
|
});
|
|
322
|
-
var PendingDistributionSchema =
|
|
323
|
-
splitAddress:
|
|
335
|
+
var PendingDistributionSchema = z11.object({
|
|
336
|
+
splitAddress: z11.string().describe("The on-chain 0xSplits address to call `distribute()` on."),
|
|
324
337
|
network: NetworkSchema,
|
|
325
338
|
token: TokenSchema,
|
|
326
|
-
recipients:
|
|
339
|
+
recipients: z11.array(PendingDistributionRecipientSchema).describe(
|
|
327
340
|
"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."
|
|
328
341
|
),
|
|
329
|
-
distributorFeePercent:
|
|
342
|
+
distributorFeePercent: z11.number().describe(
|
|
330
343
|
"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."
|
|
331
344
|
),
|
|
332
|
-
estimatedRewardAmount:
|
|
345
|
+
estimatedRewardAmount: z11.number().describe(
|
|
333
346
|
"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."
|
|
334
347
|
),
|
|
335
|
-
availableSince:
|
|
336
|
-
graceEndsAt:
|
|
348
|
+
availableSince: z11.string().datetime().describe("When this distribution entered its grace period."),
|
|
349
|
+
graceEndsAt: z11.string().datetime().describe(
|
|
337
350
|
"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."
|
|
338
351
|
)
|
|
339
352
|
});
|
|
340
353
|
var PaginatedPendingDistributionsSchema = paginatedSchema(PendingDistributionSchema);
|
|
341
|
-
var ListenPendingDistributionsQuerySchema =
|
|
342
|
-
limit:
|
|
354
|
+
var ListenPendingDistributionsQuerySchema = z11.object({
|
|
355
|
+
limit: z11.coerce.number().int().min(0).max(PAGINATION_LIMIT_MAX).default(0).describe(
|
|
343
356
|
"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."
|
|
344
357
|
)
|
|
345
358
|
});
|
|
346
|
-
var PendingDistributionEventSchema =
|
|
347
|
-
|
|
348
|
-
type:
|
|
359
|
+
var PendingDistributionEventSchema = z11.discriminatedUnion("type", [
|
|
360
|
+
z11.object({
|
|
361
|
+
type: z11.literal("distribution.available"),
|
|
349
362
|
distribution: PendingDistributionSchema
|
|
350
363
|
}),
|
|
351
|
-
|
|
352
|
-
type:
|
|
353
|
-
splitAddress:
|
|
364
|
+
z11.object({
|
|
365
|
+
type: z11.literal("distribution.claimed"),
|
|
366
|
+
splitAddress: z11.string().describe("No longer claimable \u2014 either settled by someone, or picked up by the worker.")
|
|
354
367
|
})
|
|
355
368
|
]);
|
|
356
369
|
|
|
357
370
|
// src/metrics.ts
|
|
358
|
-
import { z as
|
|
359
|
-
var MetricsResourceSchema =
|
|
371
|
+
import { z as z12 } from "zod";
|
|
372
|
+
var MetricsResourceSchema = z12.enum(["charges", "transactions", "distributions"]).describe(
|
|
360
373
|
"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."
|
|
361
374
|
);
|
|
362
|
-
var MetricsAggregationSchema =
|
|
375
|
+
var MetricsAggregationSchema = z12.enum(["count", "sum", "avg", "min", "max"]).describe(
|
|
363
376
|
"`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."
|
|
364
377
|
);
|
|
365
|
-
var MetricsFilterOperatorSchema =
|
|
378
|
+
var MetricsFilterOperatorSchema = z12.enum(["eq", "neq", "in", "gt", "gte", "lt", "lte"]).describe(
|
|
366
379
|
"`in` expects an array value (max 50 entries); every other operator expects a single scalar."
|
|
367
380
|
);
|
|
368
|
-
var MetricsDateGranularitySchema =
|
|
381
|
+
var MetricsDateGranularitySchema = z12.enum(["day", "week", "month", "year"]).describe(
|
|
369
382
|
"Bucket width for a `date_bucket` `groupBy` entry \u2014 Postgres `date_trunc` semantics (UTC)."
|
|
370
383
|
);
|
|
371
384
|
var metricsQueryEnvironmentSchema = EnvironmentSchema.describe(
|
|
@@ -378,151 +391,151 @@ var METRICS_QUERY_MAX_GROUP_BY = 3;
|
|
|
378
391
|
var METRICS_QUERY_MAX_FILTERS = 20;
|
|
379
392
|
var METRICS_QUERY_MAX_METRICS = 10;
|
|
380
393
|
var METRIC_ALIAS_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
381
|
-
var metricAliasSchema =
|
|
394
|
+
var metricAliasSchema = z12.string().min(1).max(64).regex(
|
|
382
395
|
METRIC_ALIAS_PATTERN,
|
|
383
396
|
"Must start with a letter or underscore, and contain only letters, digits, and underscores \u2014 this becomes a SQL column alias."
|
|
384
397
|
).optional();
|
|
385
|
-
var MetricsFilterValueSchema =
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
398
|
+
var MetricsFilterValueSchema = z12.union([
|
|
399
|
+
z12.string().max(255),
|
|
400
|
+
z12.number(),
|
|
401
|
+
z12.boolean(),
|
|
402
|
+
z12.array(z12.union([z12.string().max(255), z12.number()])).min(1).max(50)
|
|
390
403
|
]);
|
|
391
|
-
var orderBySchema =
|
|
392
|
-
key:
|
|
404
|
+
var orderBySchema = z12.object({
|
|
405
|
+
key: z12.string().min(1).max(64).regex(
|
|
393
406
|
METRIC_ALIAS_PATTERN,
|
|
394
407
|
"Must start with a letter or underscore, and contain only letters, digits, and underscores \u2014 every valid output column name already looks like this."
|
|
395
408
|
).describe(
|
|
396
409
|
"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."
|
|
397
410
|
),
|
|
398
|
-
direction:
|
|
411
|
+
direction: z12.enum(["asc", "desc"])
|
|
399
412
|
}).describe(
|
|
400
413
|
"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."
|
|
401
414
|
);
|
|
402
|
-
var limitSchema =
|
|
415
|
+
var limitSchema = z12.number().int().min(1).max(METRICS_QUERY_MAX_ROW_LIMIT).default(METRICS_QUERY_DEFAULT_ROW_LIMIT).describe(
|
|
403
416
|
`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.`
|
|
404
417
|
);
|
|
405
|
-
var ChargesQueryFieldSchema =
|
|
418
|
+
var ChargesQueryFieldSchema = z12.enum(["status", "source", "apiKeyId", "currency", "isOverpaid", "externalRef"]).describe(
|
|
406
419
|
"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."
|
|
407
420
|
);
|
|
408
|
-
var ChargesMetricFieldSchema =
|
|
421
|
+
var ChargesMetricFieldSchema = z12.enum(["amount", "amountReceived", "feePercent"]).describe(
|
|
409
422
|
"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%."
|
|
410
423
|
);
|
|
411
|
-
var ChargesDateFieldSchema =
|
|
424
|
+
var ChargesDateFieldSchema = z12.enum(["createdAt", "confirmedAt", "lastActivityAt", "expiresAt"]).describe(
|
|
412
425
|
"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."
|
|
413
426
|
);
|
|
414
|
-
var ChargesFilterSchema =
|
|
427
|
+
var ChargesFilterSchema = z12.object({
|
|
415
428
|
field: ChargesQueryFieldSchema,
|
|
416
429
|
operator: MetricsFilterOperatorSchema,
|
|
417
430
|
value: MetricsFilterValueSchema
|
|
418
431
|
});
|
|
419
|
-
var ChargesGroupBySchema =
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
type:
|
|
432
|
+
var ChargesGroupBySchema = z12.union([
|
|
433
|
+
z12.object({ type: z12.literal("field"), field: ChargesQueryFieldSchema }),
|
|
434
|
+
z12.object({
|
|
435
|
+
type: z12.literal("date_bucket"),
|
|
423
436
|
field: ChargesDateFieldSchema,
|
|
424
437
|
granularity: MetricsDateGranularitySchema
|
|
425
438
|
})
|
|
426
439
|
]);
|
|
427
|
-
var ChargesMetricSchema =
|
|
440
|
+
var ChargesMetricSchema = z12.object({
|
|
428
441
|
aggregation: MetricsAggregationSchema,
|
|
429
442
|
field: ChargesMetricFieldSchema.optional(),
|
|
430
443
|
alias: metricAliasSchema
|
|
431
444
|
});
|
|
432
|
-
var ChargesMetricsQuerySchema =
|
|
433
|
-
resource:
|
|
445
|
+
var ChargesMetricsQuerySchema = z12.object({
|
|
446
|
+
resource: z12.literal("charges"),
|
|
434
447
|
environment: metricsQueryEnvironmentSchema,
|
|
435
|
-
dateRange:
|
|
448
|
+
dateRange: z12.object({
|
|
436
449
|
field: ChargesDateFieldSchema,
|
|
437
|
-
from:
|
|
438
|
-
to:
|
|
450
|
+
from: z12.string().max(64).datetime(),
|
|
451
|
+
to: z12.string().max(64).datetime()
|
|
439
452
|
}),
|
|
440
|
-
groupBy:
|
|
441
|
-
metrics:
|
|
442
|
-
filters:
|
|
453
|
+
groupBy: z12.array(ChargesGroupBySchema).max(METRICS_QUERY_MAX_GROUP_BY).default([]),
|
|
454
|
+
metrics: z12.array(ChargesMetricSchema).min(1).max(METRICS_QUERY_MAX_METRICS),
|
|
455
|
+
filters: z12.array(ChargesFilterSchema).max(METRICS_QUERY_MAX_FILTERS).default([]),
|
|
443
456
|
orderBy: orderBySchema.optional(),
|
|
444
457
|
limit: limitSchema
|
|
445
458
|
});
|
|
446
|
-
var TransactionsQueryFieldSchema =
|
|
459
|
+
var TransactionsQueryFieldSchema = z12.enum(["network", "token", "source", "causedTransition"]).describe(
|
|
447
460
|
"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)."
|
|
448
461
|
);
|
|
449
|
-
var TransactionsMetricFieldSchema =
|
|
450
|
-
var TransactionsDateFieldSchema =
|
|
451
|
-
var TransactionsFilterSchema =
|
|
462
|
+
var TransactionsMetricFieldSchema = z12.enum(["amount"]).describe("The transfer amount, in the charge's `currency` units.");
|
|
463
|
+
var TransactionsDateFieldSchema = z12.enum(["detectedAt"]).describe("When Klappay detected this transfer on-chain (not when it was mined).");
|
|
464
|
+
var TransactionsFilterSchema = z12.object({
|
|
452
465
|
field: TransactionsQueryFieldSchema,
|
|
453
466
|
operator: MetricsFilterOperatorSchema,
|
|
454
467
|
value: MetricsFilterValueSchema
|
|
455
468
|
});
|
|
456
|
-
var TransactionsGroupBySchema =
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
type:
|
|
469
|
+
var TransactionsGroupBySchema = z12.union([
|
|
470
|
+
z12.object({ type: z12.literal("field"), field: TransactionsQueryFieldSchema }),
|
|
471
|
+
z12.object({
|
|
472
|
+
type: z12.literal("date_bucket"),
|
|
460
473
|
field: TransactionsDateFieldSchema,
|
|
461
474
|
granularity: MetricsDateGranularitySchema
|
|
462
475
|
})
|
|
463
476
|
]);
|
|
464
|
-
var TransactionsMetricSchema =
|
|
477
|
+
var TransactionsMetricSchema = z12.object({
|
|
465
478
|
aggregation: MetricsAggregationSchema,
|
|
466
479
|
field: TransactionsMetricFieldSchema.optional(),
|
|
467
480
|
alias: metricAliasSchema
|
|
468
481
|
});
|
|
469
|
-
var TransactionsMetricsQuerySchema =
|
|
470
|
-
resource:
|
|
482
|
+
var TransactionsMetricsQuerySchema = z12.object({
|
|
483
|
+
resource: z12.literal("transactions"),
|
|
471
484
|
environment: metricsQueryEnvironmentSchema,
|
|
472
|
-
dateRange:
|
|
485
|
+
dateRange: z12.object({
|
|
473
486
|
field: TransactionsDateFieldSchema,
|
|
474
|
-
from:
|
|
475
|
-
to:
|
|
487
|
+
from: z12.string().max(64).datetime(),
|
|
488
|
+
to: z12.string().max(64).datetime()
|
|
476
489
|
}),
|
|
477
|
-
groupBy:
|
|
478
|
-
metrics:
|
|
479
|
-
filters:
|
|
490
|
+
groupBy: z12.array(TransactionsGroupBySchema).max(METRICS_QUERY_MAX_GROUP_BY).default([]),
|
|
491
|
+
metrics: z12.array(TransactionsMetricSchema).min(1).max(METRICS_QUERY_MAX_METRICS),
|
|
492
|
+
filters: z12.array(TransactionsFilterSchema).max(METRICS_QUERY_MAX_FILTERS).default([]),
|
|
480
493
|
orderBy: orderBySchema.optional(),
|
|
481
494
|
limit: limitSchema
|
|
482
495
|
});
|
|
483
|
-
var DistributionsQueryFieldSchema =
|
|
496
|
+
var DistributionsQueryFieldSchema = z12.enum(["status", "network", "token", "distributorAddress"]).describe(
|
|
484
497
|
"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."
|
|
485
498
|
);
|
|
486
|
-
var DistributionsMetricFieldSchema =
|
|
499
|
+
var DistributionsMetricFieldSchema = z12.enum(["attempts"]).describe(
|
|
487
500
|
"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."
|
|
488
501
|
);
|
|
489
|
-
var DistributionsDateFieldSchema =
|
|
502
|
+
var DistributionsDateFieldSchema = z12.enum(["createdAt", "processingStartedAt", "completedAt"]).describe(
|
|
490
503
|
"`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."
|
|
491
504
|
);
|
|
492
|
-
var DistributionsFilterSchema =
|
|
505
|
+
var DistributionsFilterSchema = z12.object({
|
|
493
506
|
field: DistributionsQueryFieldSchema,
|
|
494
507
|
operator: MetricsFilterOperatorSchema,
|
|
495
508
|
value: MetricsFilterValueSchema
|
|
496
509
|
});
|
|
497
|
-
var DistributionsGroupBySchema =
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
type:
|
|
510
|
+
var DistributionsGroupBySchema = z12.union([
|
|
511
|
+
z12.object({ type: z12.literal("field"), field: DistributionsQueryFieldSchema }),
|
|
512
|
+
z12.object({
|
|
513
|
+
type: z12.literal("date_bucket"),
|
|
501
514
|
field: DistributionsDateFieldSchema,
|
|
502
515
|
granularity: MetricsDateGranularitySchema
|
|
503
516
|
})
|
|
504
517
|
]);
|
|
505
|
-
var DistributionsMetricSchema =
|
|
518
|
+
var DistributionsMetricSchema = z12.object({
|
|
506
519
|
aggregation: MetricsAggregationSchema,
|
|
507
520
|
field: DistributionsMetricFieldSchema.optional(),
|
|
508
521
|
alias: metricAliasSchema
|
|
509
522
|
});
|
|
510
|
-
var DistributionsMetricsQuerySchema =
|
|
511
|
-
resource:
|
|
523
|
+
var DistributionsMetricsQuerySchema = z12.object({
|
|
524
|
+
resource: z12.literal("distributions"),
|
|
512
525
|
environment: metricsQueryEnvironmentSchema,
|
|
513
|
-
dateRange:
|
|
526
|
+
dateRange: z12.object({
|
|
514
527
|
field: DistributionsDateFieldSchema,
|
|
515
|
-
from:
|
|
516
|
-
to:
|
|
528
|
+
from: z12.string().max(64).datetime(),
|
|
529
|
+
to: z12.string().max(64).datetime()
|
|
517
530
|
}),
|
|
518
|
-
groupBy:
|
|
519
|
-
metrics:
|
|
520
|
-
filters:
|
|
531
|
+
groupBy: z12.array(DistributionsGroupBySchema).max(METRICS_QUERY_MAX_GROUP_BY).default([]),
|
|
532
|
+
metrics: z12.array(DistributionsMetricSchema).min(1).max(METRICS_QUERY_MAX_METRICS),
|
|
533
|
+
filters: z12.array(DistributionsFilterSchema).max(METRICS_QUERY_MAX_FILTERS).default([]),
|
|
521
534
|
orderBy: orderBySchema.optional(),
|
|
522
535
|
limit: limitSchema
|
|
523
536
|
});
|
|
524
537
|
var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
|
|
525
|
-
var MetricsQuerySchema =
|
|
538
|
+
var MetricsQuerySchema = z12.discriminatedUnion("resource", [
|
|
526
539
|
ChargesMetricsQuerySchema,
|
|
527
540
|
TransactionsMetricsQuerySchema,
|
|
528
541
|
DistributionsMetricsQuerySchema
|
|
@@ -531,7 +544,7 @@ var MetricsQuerySchema = z11.discriminatedUnion("resource", [
|
|
|
531
544
|
const to = new Date(input.dateRange.to);
|
|
532
545
|
if (from >= to) {
|
|
533
546
|
ctx.addIssue({
|
|
534
|
-
code:
|
|
547
|
+
code: z12.ZodIssueCode.custom,
|
|
535
548
|
message: "`dateRange.from` must be before `dateRange.to`.",
|
|
536
549
|
path: ["dateRange", "from"]
|
|
537
550
|
});
|
|
@@ -539,7 +552,7 @@ var MetricsQuerySchema = z11.discriminatedUnion("resource", [
|
|
|
539
552
|
const spanDays = (to.getTime() - from.getTime()) / ONE_DAY_MS;
|
|
540
553
|
if (spanDays > MAX_METRICS_QUERY_DATE_RANGE_DAYS) {
|
|
541
554
|
ctx.addIssue({
|
|
542
|
-
code:
|
|
555
|
+
code: z12.ZodIssueCode.custom,
|
|
543
556
|
message: `\`dateRange\` cannot span more than ${MAX_METRICS_QUERY_DATE_RANGE_DAYS} days.`,
|
|
544
557
|
path: ["dateRange", "to"]
|
|
545
558
|
});
|
|
@@ -547,7 +560,7 @@ var MetricsQuerySchema = z11.discriminatedUnion("resource", [
|
|
|
547
560
|
const dateBucketCount = input.groupBy.filter((entry) => entry.type === "date_bucket").length;
|
|
548
561
|
if (dateBucketCount > 1) {
|
|
549
562
|
ctx.addIssue({
|
|
550
|
-
code:
|
|
563
|
+
code: z12.ZodIssueCode.custom,
|
|
551
564
|
message: "At most one `date_bucket` entry is allowed in `groupBy`.",
|
|
552
565
|
path: ["groupBy"]
|
|
553
566
|
});
|
|
@@ -555,7 +568,7 @@ var MetricsQuerySchema = z11.discriminatedUnion("resource", [
|
|
|
555
568
|
input.metrics.forEach((metric, index) => {
|
|
556
569
|
if (metric.aggregation !== "count" && metric.field === void 0) {
|
|
557
570
|
ctx.addIssue({
|
|
558
|
-
code:
|
|
571
|
+
code: z12.ZodIssueCode.custom,
|
|
559
572
|
message: "`field` is required unless `aggregation` is `count`.",
|
|
560
573
|
path: ["metrics", index, "field"]
|
|
561
574
|
});
|
|
@@ -564,7 +577,7 @@ var MetricsQuerySchema = z11.discriminatedUnion("resource", [
|
|
|
564
577
|
const aliases = input.metrics.map((metric) => metric.alias).filter((alias) => alias !== void 0);
|
|
565
578
|
if (new Set(aliases).size !== aliases.length) {
|
|
566
579
|
ctx.addIssue({
|
|
567
|
-
code:
|
|
580
|
+
code: z12.ZodIssueCode.custom,
|
|
568
581
|
message: "Every `metrics[].alias` must be unique.",
|
|
569
582
|
path: ["metrics"]
|
|
570
583
|
});
|
|
@@ -573,32 +586,32 @@ var MetricsQuerySchema = z11.discriminatedUnion("resource", [
|
|
|
573
586
|
input.metrics.forEach((metric, index) => {
|
|
574
587
|
if (metric.alias !== void 0 && reservedNames.has(metric.alias)) {
|
|
575
588
|
ctx.addIssue({
|
|
576
|
-
code:
|
|
589
|
+
code: z12.ZodIssueCode.custom,
|
|
577
590
|
message: `\`alias\` "${metric.alias}" collides with a \`groupBy\` field name (or the reserved word "bucket") \u2014 choose a different alias.`,
|
|
578
591
|
path: ["metrics", index, "alias"]
|
|
579
592
|
});
|
|
580
593
|
}
|
|
581
594
|
});
|
|
582
595
|
});
|
|
583
|
-
var MetricsQueryResultRowSchema =
|
|
584
|
-
|
|
585
|
-
|
|
596
|
+
var MetricsQueryResultRowSchema = z12.record(
|
|
597
|
+
z12.string(),
|
|
598
|
+
z12.union([z12.string(), z12.number(), z12.boolean(), z12.null()])
|
|
586
599
|
);
|
|
587
|
-
var MetricsQueryResultSchema =
|
|
588
|
-
data:
|
|
589
|
-
meta:
|
|
600
|
+
var MetricsQueryResultSchema = z12.object({
|
|
601
|
+
data: z12.array(MetricsQueryResultRowSchema),
|
|
602
|
+
meta: z12.object({
|
|
590
603
|
resource: MetricsResourceSchema,
|
|
591
604
|
environment: EnvironmentSchema,
|
|
592
|
-
rowCount:
|
|
593
|
-
truncated:
|
|
605
|
+
rowCount: z12.number().int().describe("Number of rows in `data`."),
|
|
606
|
+
truncated: z12.boolean().describe(
|
|
594
607
|
"`true` if more rows matched than `limit` allowed \u2014 `data` holds only the first `limit`."
|
|
595
608
|
)
|
|
596
609
|
})
|
|
597
610
|
});
|
|
598
611
|
|
|
599
612
|
// src/webhook-events.ts
|
|
600
|
-
import { z as
|
|
601
|
-
var ChargeWebhookEventTypeSchema =
|
|
613
|
+
import { z as z13 } from "zod";
|
|
614
|
+
var ChargeWebhookEventTypeSchema = z13.enum([
|
|
602
615
|
"charge.created",
|
|
603
616
|
"charge.partially_paid",
|
|
604
617
|
"charge.confirmed",
|
|
@@ -610,14 +623,14 @@ var ChargeWebhookEventTypeSchema = z12.enum([
|
|
|
610
623
|
]).describe(
|
|
611
624
|
'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`.'
|
|
612
625
|
);
|
|
613
|
-
var WebhookDeliveryEventTypeSchema =
|
|
626
|
+
var WebhookDeliveryEventTypeSchema = z13.enum(["webhook.delivery_failed", "webhook.delivery_recovered", "webhook.endpoint_unhealthy"]).describe(
|
|
614
627
|
"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`)."
|
|
615
628
|
);
|
|
616
|
-
var WebhookEventTypeSchema =
|
|
629
|
+
var WebhookEventTypeSchema = z13.union([
|
|
617
630
|
ChargeWebhookEventTypeSchema,
|
|
618
631
|
WebhookDeliveryEventTypeSchema
|
|
619
632
|
]);
|
|
620
|
-
var WebhookCategorySchema =
|
|
633
|
+
var WebhookCategorySchema = z13.enum(["payments", "webhooks"]).describe(
|
|
621
634
|
"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."
|
|
622
635
|
);
|
|
623
636
|
function buildCategoryMap() {
|
|
@@ -645,101 +658,101 @@ var TriggerableChargeEventSchema = ChargeWebhookEventTypeSchema.exclude([
|
|
|
645
658
|
);
|
|
646
659
|
|
|
647
660
|
// src/webhooks.ts
|
|
648
|
-
import { z as
|
|
661
|
+
import { z as z14 } from "zod";
|
|
649
662
|
var WEBHOOK_EVENTS_WILDCARD = "*";
|
|
650
|
-
var CreateWebhookSchema =
|
|
651
|
-
url:
|
|
663
|
+
var CreateWebhookSchema = z14.object({
|
|
664
|
+
url: z14.string().max(2048).url().describe(
|
|
652
665
|
"Must be HTTPS and resolve to a public address \u2014 private/internal IPs are rejected."
|
|
653
666
|
),
|
|
654
|
-
events:
|
|
667
|
+
events: z14.array(z14.union([WebhookEventTypeSchema, z14.literal(WEBHOOK_EVENTS_WILDCARD)])).max(Object.keys(EVENT_CATEGORY_MAP).length + 1).default([]).describe(
|
|
655
668
|
'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.'
|
|
656
669
|
),
|
|
657
|
-
eventCategories:
|
|
670
|
+
eventCategories: z14.array(WebhookCategorySchema).max(WebhookCategorySchema.options.length).default([]).describe(
|
|
658
671
|
"Subscribe to every event in these categories. At least one of `events` or `eventCategories` is required."
|
|
659
672
|
),
|
|
660
|
-
excludeEvents:
|
|
673
|
+
excludeEvents: z14.array(WebhookEventTypeSchema).max(Object.keys(EVENT_CATEGORY_MAP).length).default([]).describe(
|
|
661
674
|
'Event types to exclude even if selected via `events: ["*"]` or `eventCategories`.'
|
|
662
675
|
)
|
|
663
676
|
}).refine((v) => v.events.length > 0 || v.eventCategories.length > 0, {
|
|
664
677
|
message: "must select at least one event via `events` or `eventCategories`",
|
|
665
678
|
path: ["events"]
|
|
666
679
|
});
|
|
667
|
-
var WebhookSchema =
|
|
668
|
-
id:
|
|
680
|
+
var WebhookSchema = z14.object({
|
|
681
|
+
id: z14.string(),
|
|
669
682
|
environment: EnvironmentSchema.nullable().describe(
|
|
670
683
|
"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)."
|
|
671
684
|
),
|
|
672
|
-
url:
|
|
673
|
-
events:
|
|
674
|
-
eventCategories:
|
|
675
|
-
excludeEvents:
|
|
676
|
-
isWildcard:
|
|
677
|
-
secret:
|
|
685
|
+
url: z14.string(),
|
|
686
|
+
events: z14.array(WebhookEventTypeSchema),
|
|
687
|
+
eventCategories: z14.array(WebhookCategorySchema),
|
|
688
|
+
excludeEvents: z14.array(WebhookEventTypeSchema),
|
|
689
|
+
isWildcard: z14.boolean(),
|
|
690
|
+
secret: z14.string().describe(
|
|
678
691
|
"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."
|
|
679
692
|
),
|
|
680
|
-
createdAt:
|
|
693
|
+
createdAt: z14.string().datetime()
|
|
681
694
|
});
|
|
682
695
|
var WebhookListItemSchema = WebhookSchema.omit({ secret: true }).extend({
|
|
683
|
-
hint:
|
|
696
|
+
hint: z14.string().describe("A truncated, safe-to-display form of the secret (e.g. `whsec_...ab12`).")
|
|
684
697
|
});
|
|
685
|
-
var WebhookPayloadSchema =
|
|
686
|
-
id:
|
|
698
|
+
var WebhookPayloadSchema = z14.object({
|
|
699
|
+
id: z14.string().describe(
|
|
687
700
|
"Unique id for this specific delivery \u2014 also sent as the `X-Klappay-Delivery` header."
|
|
688
701
|
),
|
|
689
702
|
event: WebhookEventTypeSchema,
|
|
690
|
-
createdAt:
|
|
691
|
-
data:
|
|
703
|
+
createdAt: z14.string().datetime(),
|
|
704
|
+
data: z14.unknown().describe(
|
|
692
705
|
"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."
|
|
693
706
|
)
|
|
694
707
|
});
|
|
695
|
-
var WebhookDeliveryStatusSchema =
|
|
696
|
-
var WebhookDeliverySchema =
|
|
697
|
-
id:
|
|
698
|
-
webhookId:
|
|
708
|
+
var WebhookDeliveryStatusSchema = z14.enum(["pending", "delivered", "failed"]);
|
|
709
|
+
var WebhookDeliverySchema = z14.object({
|
|
710
|
+
id: z14.string(),
|
|
711
|
+
webhookId: z14.string(),
|
|
699
712
|
event: WebhookEventTypeSchema,
|
|
700
713
|
status: WebhookDeliveryStatusSchema.describe(
|
|
701
714
|
"`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."
|
|
702
715
|
),
|
|
703
|
-
attempts:
|
|
704
|
-
responseCode:
|
|
716
|
+
attempts: z14.number(),
|
|
717
|
+
responseCode: z14.number().nullable().describe(
|
|
705
718
|
"HTTP status your endpoint returned on the most recent attempt. `null` if every attempt failed to connect at all."
|
|
706
719
|
),
|
|
707
|
-
nextRetryAt:
|
|
708
|
-
deliveredAt:
|
|
709
|
-
createdAt:
|
|
720
|
+
nextRetryAt: z14.string().datetime().nullable(),
|
|
721
|
+
deliveredAt: z14.string().datetime().nullable(),
|
|
722
|
+
createdAt: z14.string().datetime()
|
|
710
723
|
});
|
|
711
724
|
var ListWebhookDeliveriesSchema = PaginationQuerySchema;
|
|
712
725
|
var PaginatedWebhookDeliveriesSchema = paginatedSchema(WebhookDeliverySchema);
|
|
713
726
|
|
|
714
727
|
// src/recipients.ts
|
|
715
|
-
import { z as
|
|
728
|
+
import { z as z15 } from "zod";
|
|
716
729
|
var EVM_ADDRESS_REGEX = /^0x[0-9a-fA-F]{40}$/;
|
|
717
|
-
var CreateRecipientSchema =
|
|
718
|
-
address:
|
|
719
|
-
label:
|
|
730
|
+
var CreateRecipientSchema = z15.object({
|
|
731
|
+
address: z15.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."),
|
|
732
|
+
label: z15.string().min(1).max(64).optional().describe('Free-form label for your own bookkeeping (e.g. `"supplier"`) \u2014 never interpreted.')
|
|
720
733
|
});
|
|
721
|
-
var RecipientSchema =
|
|
722
|
-
id:
|
|
734
|
+
var RecipientSchema = z15.object({
|
|
735
|
+
id: z15.string().describe(
|
|
723
736
|
"Klappay-generated id, e.g. `rc_...` \u2014 this, not the raw address, is what a charge's `splitRecipients[].recipientId` references."
|
|
724
737
|
),
|
|
725
738
|
environment: EnvironmentSchema,
|
|
726
|
-
address:
|
|
727
|
-
label:
|
|
728
|
-
payout:
|
|
739
|
+
address: z15.string(),
|
|
740
|
+
label: z15.string().nullable(),
|
|
741
|
+
payout: z15.boolean().describe(
|
|
729
742
|
"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`."
|
|
730
743
|
),
|
|
731
|
-
createdAt:
|
|
744
|
+
createdAt: z15.string().datetime()
|
|
732
745
|
});
|
|
733
|
-
var SetRecipientPayoutSchema =
|
|
734
|
-
payout:
|
|
746
|
+
var SetRecipientPayoutSchema = z15.object({
|
|
747
|
+
payout: z15.boolean().describe("New payout-eligibility value for this recipient.")
|
|
735
748
|
});
|
|
736
749
|
|
|
737
750
|
// src/timeline.ts
|
|
738
|
-
import { z as
|
|
739
|
-
var TransactionSourceSchema =
|
|
751
|
+
import { z as z16 } from "zod";
|
|
752
|
+
var TransactionSourceSchema = z16.enum(["moralis_webhook", "reconciliation_job", "sandbox"]).describe(
|
|
740
753
|
"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)."
|
|
741
754
|
);
|
|
742
|
-
var TimelineEventTypeSchema =
|
|
755
|
+
var TimelineEventTypeSchema = z16.enum([
|
|
743
756
|
"charge.created",
|
|
744
757
|
"charge.expired",
|
|
745
758
|
"transaction.detected",
|
|
@@ -750,11 +763,11 @@ var TimelineEventTypeSchema = z15.enum([
|
|
|
750
763
|
]).describe(
|
|
751
764
|
"`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)."
|
|
752
765
|
);
|
|
753
|
-
var TimelineEventSchema =
|
|
766
|
+
var TimelineEventSchema = z16.object({
|
|
754
767
|
type: TimelineEventTypeSchema,
|
|
755
|
-
at:
|
|
756
|
-
txHash:
|
|
757
|
-
amount:
|
|
768
|
+
at: z16.string().datetime(),
|
|
769
|
+
txHash: z16.string().optional().describe("Present for `transaction.detected` and `split.distributed` events only."),
|
|
770
|
+
amount: z16.number().optional().describe(
|
|
758
771
|
"Present for `transaction.detected` events only \u2014 the amount that specific transfer carried."
|
|
759
772
|
),
|
|
760
773
|
source: TransactionSourceSchema.optional().describe(
|
|
@@ -766,102 +779,102 @@ var TimelineEventSchema = z15.object({
|
|
|
766
779
|
network: NetworkSchema.optional().describe(
|
|
767
780
|
"Present for `transaction.detected` and `split.distributed` events \u2014 which network this specific transfer, or settlement, used."
|
|
768
781
|
),
|
|
769
|
-
causedTransition:
|
|
782
|
+
causedTransition: z16.boolean().optional().describe(
|
|
770
783
|
"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."
|
|
771
784
|
),
|
|
772
785
|
event: WebhookEventTypeSchema.optional().describe(
|
|
773
786
|
"Present for `webhook.*` events only \u2014 which event type this delivery was for."
|
|
774
787
|
),
|
|
775
|
-
responseCode:
|
|
788
|
+
responseCode: z16.number().nullable().optional().describe(
|
|
776
789
|
"Present for `webhook.*` events only \u2014 HTTP status your endpoint returned, or `null` if the request never connected."
|
|
777
790
|
),
|
|
778
|
-
attempts:
|
|
791
|
+
attempts: z16.number().optional().describe(
|
|
779
792
|
"Present for `webhook.*` events only \u2014 how many delivery attempts have been made so far."
|
|
780
793
|
)
|
|
781
794
|
});
|
|
782
795
|
|
|
783
796
|
// src/health.ts
|
|
784
|
-
import { z as
|
|
785
|
-
var HealthSchema =
|
|
786
|
-
status:
|
|
797
|
+
import { z as z17 } from "zod";
|
|
798
|
+
var HealthSchema = z17.object({
|
|
799
|
+
status: z17.enum(["ok", "error"]).describe(
|
|
787
800
|
"`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."
|
|
788
801
|
),
|
|
789
|
-
version:
|
|
790
|
-
timestamp:
|
|
791
|
-
db:
|
|
792
|
-
pendingWebhooks:
|
|
793
|
-
oldestPendingChargeAgeSeconds:
|
|
794
|
-
lastMoralisEventAgeSeconds:
|
|
802
|
+
version: z17.string(),
|
|
803
|
+
timestamp: z17.string().datetime(),
|
|
804
|
+
db: z17.enum(["ok", "error"]).describe("Result of a real database connectivity check, not just a process-alive check."),
|
|
805
|
+
pendingWebhooks: z17.number().describe("Count of webhook deliveries still awaiting a successful attempt."),
|
|
806
|
+
oldestPendingChargeAgeSeconds: z17.number().nullable().describe("Age of the oldest still-unpaid charge, in seconds. `null` if there are none."),
|
|
807
|
+
lastMoralisEventAgeSeconds: z17.number().nullable().describe(
|
|
795
808
|
"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."
|
|
796
809
|
)
|
|
797
810
|
});
|
|
798
811
|
|
|
799
812
|
// src/sandbox.ts
|
|
800
|
-
import { z as
|
|
801
|
-
var SandboxTriggerSchema =
|
|
813
|
+
import { z as z18 } from "zod";
|
|
814
|
+
var SandboxTriggerSchema = z18.object({
|
|
802
815
|
event: TriggerableChargeEventSchema,
|
|
803
|
-
amount:
|
|
816
|
+
amount: z18.number().positive().max(CHARGE_AMOUNT_MAX).optional().describe(
|
|
804
817
|
"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."
|
|
805
818
|
)
|
|
806
819
|
});
|
|
807
820
|
|
|
808
821
|
// src/capabilities.ts
|
|
809
|
-
import { z as
|
|
810
|
-
var CapabilitiesSchema =
|
|
811
|
-
acceptedPayments:
|
|
822
|
+
import { z as z19 } from "zod";
|
|
823
|
+
var CapabilitiesSchema = z19.object({
|
|
824
|
+
acceptedPayments: z19.array(AcceptedPaymentSchema).describe(
|
|
812
825
|
"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."
|
|
813
826
|
)
|
|
814
827
|
});
|
|
815
828
|
|
|
816
829
|
// src/swap.ts
|
|
817
|
-
import { z as
|
|
818
|
-
var CreateSwapQuoteSchema =
|
|
830
|
+
import { z as z20 } from "zod";
|
|
831
|
+
var CreateSwapQuoteSchema = z20.object({
|
|
819
832
|
inputToken: AltTokenSchema.describe(
|
|
820
833
|
"Which alt-cryptocurrency the payer wants to send \u2014 must be one of this charge's `swapAlternatives`, or `422 token_not_supported`."
|
|
821
834
|
),
|
|
822
835
|
inputNetwork: NetworkSchema.describe(
|
|
823
836
|
"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."
|
|
824
837
|
),
|
|
825
|
-
takerAddress:
|
|
838
|
+
takerAddress: z20.string().regex(/^0x[0-9a-fA-F]{40}$/, "must be a 20-byte hex address").describe(
|
|
826
839
|
"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."
|
|
827
840
|
)
|
|
828
841
|
});
|
|
829
|
-
var SwapQuoteSchema =
|
|
842
|
+
var SwapQuoteSchema = z20.object({
|
|
830
843
|
inputToken: AltTokenSchema,
|
|
831
844
|
inputNetwork: NetworkSchema,
|
|
832
|
-
inputAmount:
|
|
845
|
+
inputAmount: z20.number().describe(
|
|
833
846
|
"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."
|
|
834
847
|
),
|
|
835
848
|
outputToken: TokenSchema.describe(
|
|
836
849
|
"Which of this charge's `acceptedPayments` tokens the swap resolves to."
|
|
837
850
|
),
|
|
838
851
|
outputNetwork: NetworkSchema,
|
|
839
|
-
outputAmount:
|
|
852
|
+
outputAmount: z20.number().describe(
|
|
840
853
|
"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`."
|
|
841
854
|
),
|
|
842
|
-
fees:
|
|
843
|
-
klappayFee:
|
|
855
|
+
fees: z20.object({
|
|
856
|
+
klappayFee: z20.number().describe(
|
|
844
857
|
"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`."
|
|
845
858
|
),
|
|
846
|
-
zeroExFee:
|
|
859
|
+
zeroExFee: z20.number().nullable().describe(
|
|
847
860
|
"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."
|
|
848
861
|
)
|
|
849
862
|
}).describe(
|
|
850
863
|
"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`."
|
|
851
864
|
),
|
|
852
|
-
expiresAt:
|
|
865
|
+
expiresAt: z20.string().datetime().describe(
|
|
853
866
|
"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."
|
|
854
867
|
),
|
|
855
|
-
transaction:
|
|
856
|
-
to:
|
|
857
|
-
data:
|
|
858
|
-
value:
|
|
868
|
+
transaction: z20.object({
|
|
869
|
+
to: z20.string().describe("Contract address the payer's wallet must send this transaction to."),
|
|
870
|
+
data: z20.string().describe("Calldata \u2014 opaque, must be sent unmodified."),
|
|
871
|
+
value: z20.string().describe(
|
|
859
872
|
"Native currency (ETH/BNB/MATIC/AVAX) to attach, in wei \u2014 `\"0\"` when `inputToken` isn't this network's native currency."
|
|
860
873
|
)
|
|
861
874
|
}).describe(
|
|
862
875
|
"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."
|
|
863
876
|
),
|
|
864
|
-
permit2:
|
|
877
|
+
permit2: z20.object({ eip712: z20.record(z20.unknown()) }).nullish().describe(
|
|
865
878
|
"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."
|
|
866
879
|
)
|
|
867
880
|
});
|
|
@@ -887,6 +900,7 @@ export {
|
|
|
887
900
|
ChargesDateFieldSchema,
|
|
888
901
|
ChargesMetricFieldSchema,
|
|
889
902
|
ChargesQueryFieldSchema,
|
|
903
|
+
CheckChargeRequestSchema,
|
|
890
904
|
CheckoutProductSchema,
|
|
891
905
|
CreateChargeSchema,
|
|
892
906
|
CreateRecipientSchema,
|