@zkp2p/cash 0.1.7 → 0.1.8
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/AGENTS.md +6 -3
- package/README.md +12 -3
- package/dist/{createCashClient-jUA_GNdh.d.cts → createCashClient-BIzOLHjF.d.cts} +16 -1
- package/dist/{createCashClient-jUA_GNdh.d.ts → createCashClient-BIzOLHjF.d.ts} +16 -1
- package/dist/index.cjs +163 -48
- package/dist/index.d.cts +28 -5
- package/dist/index.d.ts +28 -5
- package/dist/index.js +160 -49
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/tools.cjs +10 -1
- package/dist/tools.d.cts +8 -0
- package/dist/tools.d.ts +8 -0
- package/dist/tools.js +10 -1
- package/docs/lifecycle-and-recovery.md +11 -4
- package/llms.txt +7 -3
- package/package.json +4 -2
package/AGENTS.md
CHANGED
|
@@ -54,6 +54,9 @@ const relayCaps = await cash.capabilities({ includeRelaySources: true });
|
|
|
54
54
|
// 2. Estimate - idempotent, cacheable, no side effects. Includes rolling ETA.
|
|
55
55
|
const est = await cash.estimate({ amount: usdc(500), currency: 'EUR' });
|
|
56
56
|
|
|
57
|
+
// Optional: raw demand + speed evidence per offered platform:currency pair.
|
|
58
|
+
const stats = await cash.fillStats();
|
|
59
|
+
|
|
57
60
|
// 3. Execute.
|
|
58
61
|
const { depositId } = await cash.cashout(
|
|
59
62
|
{
|
|
@@ -101,9 +104,9 @@ console.log(routed.source?.transactions?.origin, routed.source?.transactions?.de
|
|
|
101
104
|
binding rate resolves at the oracle when a buyer fills. Do not display or
|
|
102
105
|
log it as a locked price.
|
|
103
106
|
- **Do not invent an ETA.** Use `estimate().eta`: `{ seconds, label }` backed
|
|
104
|
-
by rolling 30-day
|
|
105
|
-
|
|
106
|
-
|
|
107
|
+
by the same rolling 30-day, intent-attributed pair sample as `fillStats()`,
|
|
108
|
+
measured from deposit creation to first fill. Use `order.explain()` for live
|
|
109
|
+
order state.
|
|
107
110
|
- **Do not hardcode Relay source assets.** Use Relay SDK-backed EVM
|
|
108
111
|
`capabilities({ includeRelaySources: true })` and `cashout({ source, ... })`.
|
|
109
112
|
Destination is always Base USDC. Non-Base source chains require
|
package/README.md
CHANGED
|
@@ -76,6 +76,7 @@ console.log(source?.transactions?.origin, source?.transactions?.destination);
|
|
|
76
76
|
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
|
77
77
|
| `capabilities()` | Sync discovery: Base USDC destination/default source, platforms × currencies × payee hints × amount bounds |
|
|
78
78
|
| `capabilities({ includeRelaySources: true })` | Async discovery: adds live Relay SDK EVM source chains/tokens |
|
|
79
|
+
| `fillStats()` | Raw 30-day fill counts and median first-fill time per `platform:currency` pair |
|
|
79
80
|
| `quoteSource(input)` / `executeSourceQuote(quote, { signer })` | Relay SDK EVM source routing into Base USDC before cashout |
|
|
80
81
|
| `relayStatus(requestId)` | Relay request status from the Relay SDK request path |
|
|
81
82
|
| `estimate({ amount, currency })` | Base USDC oracle estimate plus simple recent-fill ETA |
|
|
@@ -97,6 +98,11 @@ must execute and confirm its Relay route before preparing the Base-USDC
|
|
|
97
98
|
cashout. Every Peer Cash transaction, including approves, carries ERC-8021
|
|
98
99
|
attribution: `peer-cash` first, your own `referrer` code(s) after it.
|
|
99
100
|
|
|
101
|
+
`capabilities()` presents Zelle as one platform. A cashout with
|
|
102
|
+
`receive.platform: 'zelle'` automatically attaches the generic Zelle method
|
|
103
|
+
and its Chase, Bank of America, and Citi buyer routes to the deposit; the payee
|
|
104
|
+
handle and public API remain bank-agnostic.
|
|
105
|
+
|
|
100
106
|
The default/minimal flow is unchanged: pass Base USDC base units to
|
|
101
107
|
`estimate()` and `cashout()`. For any other source asset, pass `source` to
|
|
102
108
|
`cashout()` with a source-chain signer. The SDK settles the Base allowance,
|
|
@@ -172,9 +178,12 @@ awaiting-buyer ──────────► matched ───────
|
|
|
172
178
|
fills. `estimate()` says "approximately"; nothing in this API pretends to
|
|
173
179
|
lock a price.
|
|
174
180
|
- **ETA is historical.** `estimate().eta` is just `{ seconds, label }`, backed
|
|
175
|
-
by rolling 30-day
|
|
176
|
-
|
|
177
|
-
|
|
181
|
+
by the same rolling 30-day, intent-attributed pair sampler as `fillStats()`,
|
|
182
|
+
measured from deposit creation to the first fulfilled fill through the pair.
|
|
183
|
+
- **Availability thresholds belong to the consumer.** `fillStats()` returns raw
|
|
184
|
+
evidence. A recommended gate is `fills >= 10 && medianFillSeconds <= 48h`.
|
|
185
|
+
Fail open to the full `capabilities()` catalog when stats are unavailable or
|
|
186
|
+
the gate would empty the offered catalog.
|
|
178
187
|
- **Everything is resumable.** An order is reconstructed from the chain by
|
|
179
188
|
`depositId` alone. Close the tab, switch devices, crash the process - then
|
|
180
189
|
call `order(depositId)`.
|
|
@@ -357,6 +357,14 @@ interface CashCapabilities {
|
|
|
357
357
|
}
|
|
358
358
|
declare function buildCapabilities(environment: RuntimeEnv): CashCapabilities;
|
|
359
359
|
|
|
360
|
+
interface CashPairFillStats {
|
|
361
|
+
/** Fulfilled intents through this pair inside the rolling 30-day window. */
|
|
362
|
+
fills: number;
|
|
363
|
+
/** Median deposit-to-first-fill seconds, sampled once per deposit for this pair. */
|
|
364
|
+
medianFillSeconds?: number;
|
|
365
|
+
}
|
|
366
|
+
/** Raw demand and speed evidence keyed by `basePlatform:currencyCode`. */
|
|
367
|
+
type CashFillStats = Record<string, CashPairFillStats>;
|
|
360
368
|
interface CashFillEta {
|
|
361
369
|
/** Simple headline ETA from recent deposits. Undefined when no recent sample exists. */
|
|
362
370
|
seconds?: number;
|
|
@@ -581,6 +589,13 @@ interface CashClient {
|
|
|
581
589
|
capabilities(options: {
|
|
582
590
|
includeRelaySources: true;
|
|
583
591
|
}): Promise<CashCapabilities>;
|
|
592
|
+
/**
|
|
593
|
+
* 0c - Raw 30-day demand and first-fill speed evidence keyed by
|
|
594
|
+
* `platform:currency`. A recommended consumer gate is `fills >= 10 &&
|
|
595
|
+
* medianFillSeconds <= 48h`; fail open to the full capability catalog when
|
|
596
|
+
* stats are unavailable or the gate would remove every pair.
|
|
597
|
+
*/
|
|
598
|
+
fillStats(): Promise<CashFillStats>;
|
|
584
599
|
/** Relay-only source discovery helper. */
|
|
585
600
|
sourceCapabilities(): Promise<CashSourceCapabilities>;
|
|
586
601
|
/** Quote any Relay-supported EVM source asset into Base USDC. */
|
|
@@ -640,4 +655,4 @@ interface CashClient {
|
|
|
640
655
|
}
|
|
641
656
|
declare function createCashClient(options: CashClientOptions): CashClient;
|
|
642
657
|
|
|
643
|
-
export { type
|
|
658
|
+
export { type CashPlatformCapability as A, type CashPreparedStepKind as B, type CashPayoutInfo as C, type CashoutInput as D, type CashoutOptions as E, type CuratorPayeeDataInput as F, type EstimateInput as G, RECOMMENDED_MIN_CASHOUT_AMOUNT as H, type IntentStatus as I, type RelayOptions as J, type RelayQuoteInput as K, type RelaySourceInput as L, MIN_CASHOUT_AMOUNT as M, type RelayTransaction as N, type OrdersOptions as O, type PrepareResult as P, type WatchOptions as Q, type RelayExecutionResult as R, type SignerOptions as S, type TopUpResult as T, type WithdrawOptions as U, buildCapabilities as V, type WithdrawResult as W, createCashClient as X, type IntentEntity as a, type CashBuyerProfile as b, type CashDepositInput as c, type CreateDepositParamsArg as d, type CashOrder as e, type CashFill as f, type CashCapabilities as g, type CashoutResult as h, type CashEstimate as i, type CashFillStats as j, type CashPreparedStep as k, type RelayQuote as l, type RelayStatus as m, type CashSourceCapabilities as n, CASH_ATTRIBUTION_CODE as o, type CashAsset as p, type CashChain as q, type CashClient as r, type CashClientOptions as s, type CashFillEta as t, type CashLeg as u, type CashNextAction as v, type CashOrderState as w, type CashPairFillStats as x, type CashPayout as y, type CashPayoutPricing as z };
|
|
@@ -357,6 +357,14 @@ interface CashCapabilities {
|
|
|
357
357
|
}
|
|
358
358
|
declare function buildCapabilities(environment: RuntimeEnv): CashCapabilities;
|
|
359
359
|
|
|
360
|
+
interface CashPairFillStats {
|
|
361
|
+
/** Fulfilled intents through this pair inside the rolling 30-day window. */
|
|
362
|
+
fills: number;
|
|
363
|
+
/** Median deposit-to-first-fill seconds, sampled once per deposit for this pair. */
|
|
364
|
+
medianFillSeconds?: number;
|
|
365
|
+
}
|
|
366
|
+
/** Raw demand and speed evidence keyed by `basePlatform:currencyCode`. */
|
|
367
|
+
type CashFillStats = Record<string, CashPairFillStats>;
|
|
360
368
|
interface CashFillEta {
|
|
361
369
|
/** Simple headline ETA from recent deposits. Undefined when no recent sample exists. */
|
|
362
370
|
seconds?: number;
|
|
@@ -581,6 +589,13 @@ interface CashClient {
|
|
|
581
589
|
capabilities(options: {
|
|
582
590
|
includeRelaySources: true;
|
|
583
591
|
}): Promise<CashCapabilities>;
|
|
592
|
+
/**
|
|
593
|
+
* 0c - Raw 30-day demand and first-fill speed evidence keyed by
|
|
594
|
+
* `platform:currency`. A recommended consumer gate is `fills >= 10 &&
|
|
595
|
+
* medianFillSeconds <= 48h`; fail open to the full capability catalog when
|
|
596
|
+
* stats are unavailable or the gate would remove every pair.
|
|
597
|
+
*/
|
|
598
|
+
fillStats(): Promise<CashFillStats>;
|
|
584
599
|
/** Relay-only source discovery helper. */
|
|
585
600
|
sourceCapabilities(): Promise<CashSourceCapabilities>;
|
|
586
601
|
/** Quote any Relay-supported EVM source asset into Base USDC. */
|
|
@@ -640,4 +655,4 @@ interface CashClient {
|
|
|
640
655
|
}
|
|
641
656
|
declare function createCashClient(options: CashClientOptions): CashClient;
|
|
642
657
|
|
|
643
|
-
export { type
|
|
658
|
+
export { type CashPlatformCapability as A, type CashPreparedStepKind as B, type CashPayoutInfo as C, type CashoutInput as D, type CashoutOptions as E, type CuratorPayeeDataInput as F, type EstimateInput as G, RECOMMENDED_MIN_CASHOUT_AMOUNT as H, type IntentStatus as I, type RelayOptions as J, type RelayQuoteInput as K, type RelaySourceInput as L, MIN_CASHOUT_AMOUNT as M, type RelayTransaction as N, type OrdersOptions as O, type PrepareResult as P, type WatchOptions as Q, type RelayExecutionResult as R, type SignerOptions as S, type TopUpResult as T, type WithdrawOptions as U, buildCapabilities as V, type WithdrawResult as W, createCashClient as X, type IntentEntity as a, type CashBuyerProfile as b, type CashDepositInput as c, type CreateDepositParamsArg as d, type CashOrder as e, type CashFill as f, type CashCapabilities as g, type CashoutResult as h, type CashEstimate as i, type CashFillStats as j, type CashPreparedStep as k, type RelayQuote as l, type RelayStatus as m, type CashSourceCapabilities as n, CASH_ATTRIBUTION_CODE as o, type CashAsset as p, type CashChain as q, type CashClient as r, type CashClientOptions as s, type CashFillEta as t, type CashLeg as u, type CashNextAction as v, type CashOrderState as w, type CashPairFillStats as x, type CashPayout as y, type CashPayoutPricing as z };
|
package/dist/index.cjs
CHANGED
|
@@ -403,6 +403,26 @@ function parseCompositeDepositId(compositeId) {
|
|
|
403
403
|
const onchainDepositId = BigInt(rawDepositId);
|
|
404
404
|
return { escrowAddress: canonicalEscrowAddress, onchainDepositId };
|
|
405
405
|
}
|
|
406
|
+
|
|
407
|
+
// src/client/platformGroups.ts
|
|
408
|
+
var PLATFORM_METHOD_GROUPS = {
|
|
409
|
+
zelle: ["zelle", "zelle-chase", "zelle-bofa", "zelle-citi"]
|
|
410
|
+
};
|
|
411
|
+
var METHOD_TO_BASE_PLATFORM = new Map(
|
|
412
|
+
Object.entries(PLATFORM_METHOD_GROUPS).flatMap(
|
|
413
|
+
([platform, methods]) => methods.map((method) => [method, platform])
|
|
414
|
+
)
|
|
415
|
+
);
|
|
416
|
+
function basePlatformForMethod(method) {
|
|
417
|
+
return METHOD_TO_BASE_PLATFORM.get(method) ?? method;
|
|
418
|
+
}
|
|
419
|
+
function paymentMethodsForPlatform(platform, catalog) {
|
|
420
|
+
const configured = PLATFORM_METHOD_GROUPS[platform];
|
|
421
|
+
const methods = configured ?? [platform];
|
|
422
|
+
return methods.filter((method) => catalog[method] !== void 0);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// src/client/capabilities.ts
|
|
406
426
|
var MIN_CASHOUT_AMOUNT = 10000n;
|
|
407
427
|
var RECOMMENDED_MIN_CASHOUT_AMOUNT = 1000000n;
|
|
408
428
|
var PAYEE_HINTS = {
|
|
@@ -421,13 +441,20 @@ var PAYEE_HINTS = {
|
|
|
421
441
|
var IDENTITY_ATTESTATION_PLATFORMS = /* @__PURE__ */ new Set(["wise", "paypal"]);
|
|
422
442
|
function buildCapabilities(environment) {
|
|
423
443
|
const catalog = sdk.getPaymentMethodsCatalog(BASE_CHAIN_ID, environment);
|
|
424
|
-
const
|
|
444
|
+
const currenciesByPlatform = /* @__PURE__ */ new Map();
|
|
445
|
+
for (const [method, entry] of Object.entries(catalog)) {
|
|
446
|
+
const platform = basePlatformForMethod(method);
|
|
425
447
|
const currencies2 = (entry.currencies ?? []).map((hash) => sdk.getCurrencyCodeFromHash(hash)).filter(
|
|
426
448
|
(code) => code != null && isMarketRateSupported(code)
|
|
427
449
|
);
|
|
450
|
+
const aggregate = currenciesByPlatform.get(platform) ?? /* @__PURE__ */ new Set();
|
|
451
|
+
for (const currency of currencies2) aggregate.add(currency);
|
|
452
|
+
currenciesByPlatform.set(platform, aggregate);
|
|
453
|
+
}
|
|
454
|
+
const platforms = [...currenciesByPlatform.entries()].map(([platform, currencies2]) => {
|
|
428
455
|
return {
|
|
429
456
|
platform,
|
|
430
|
-
currencies: [...
|
|
457
|
+
currencies: [...currencies2].sort(),
|
|
431
458
|
payeeHint: PAYEE_HINTS[platform] ?? "Your payment handle for this platform",
|
|
432
459
|
requiresIdentityAttestation: IDENTITY_ATTESTATION_PLATFORMS.has(platform)
|
|
433
460
|
};
|
|
@@ -809,11 +836,8 @@ function mapChainError(verb, err, context = {}) {
|
|
|
809
836
|
}
|
|
810
837
|
return errors.chainCallFailed(verb, err);
|
|
811
838
|
}
|
|
812
|
-
var
|
|
813
|
-
var
|
|
814
|
-
var ETA_PAGE_LIMIT = 250;
|
|
815
|
-
var ETA_MAX_DEPOSIT_SCAN = 2e3;
|
|
816
|
-
var FULFILLED = /* @__PURE__ */ new Set(["FULFILLED", "MANUALLY_RELEASED"]);
|
|
839
|
+
var FILL_STATS_WINDOW_SECONDS = 30 * 24 * 60 * 60;
|
|
840
|
+
var FILL_STATS_PAGE_LIMIT = 250;
|
|
817
841
|
function toUnixSeconds2(value) {
|
|
818
842
|
if (value === null || value === void 0 || value === "") return void 0;
|
|
819
843
|
if (value instanceof Date) {
|
|
@@ -824,12 +848,22 @@ function toUnixSeconds2(value) {
|
|
|
824
848
|
const parsed = Date.parse(value);
|
|
825
849
|
if (Number.isFinite(parsed)) return Math.floor(parsed / 1e3);
|
|
826
850
|
}
|
|
827
|
-
const
|
|
828
|
-
return Number.isFinite(
|
|
851
|
+
const numeric = Number(value);
|
|
852
|
+
return Number.isFinite(numeric) && numeric > 0 ? numeric : void 0;
|
|
853
|
+
}
|
|
854
|
+
function normalizeCurrencyCode(value) {
|
|
855
|
+
const raw = value?.trim();
|
|
856
|
+
if (!raw) return void 0;
|
|
857
|
+
if (!raw.toLowerCase().startsWith("0x")) return raw.toUpperCase();
|
|
858
|
+
try {
|
|
859
|
+
return sdk.getCurrencyCodeFromHash(raw)?.toUpperCase();
|
|
860
|
+
} catch {
|
|
861
|
+
return void 0;
|
|
862
|
+
}
|
|
829
863
|
}
|
|
830
864
|
function median(values) {
|
|
831
865
|
if (values.length === 0) return void 0;
|
|
832
|
-
const sorted = [...values].sort((
|
|
866
|
+
const sorted = [...values].sort((left, right) => left - right);
|
|
833
867
|
const mid = Math.floor(sorted.length / 2);
|
|
834
868
|
return sorted.length % 2 === 1 ? sorted[mid] : Math.round((sorted[mid - 1] + sorted[mid]) / 2);
|
|
835
869
|
}
|
|
@@ -841,47 +875,97 @@ function etaLabel(seconds) {
|
|
|
841
875
|
const hours = Math.max(1, Math.round(minutes / 60));
|
|
842
876
|
return `Usually starts in about ${hours} hr`;
|
|
843
877
|
}
|
|
844
|
-
function
|
|
845
|
-
const
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
);
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
878
|
+
function computeFillStatsSample(deposits, nowSeconds, environment) {
|
|
879
|
+
const catalog = sdk.getPaymentMethodsCatalog(BASE_CHAIN_ID, environment);
|
|
880
|
+
const windowStart = nowSeconds - FILL_STATS_WINDOW_SECONDS;
|
|
881
|
+
const fillCounts = /* @__PURE__ */ new Map();
|
|
882
|
+
const latenciesByPair = /* @__PURE__ */ new Map();
|
|
883
|
+
const latenciesByCurrency = /* @__PURE__ */ new Map();
|
|
884
|
+
for (const deposit of deposits) {
|
|
885
|
+
const createdAt = toUnixSeconds2(deposit.createdAt ?? deposit.timestamp);
|
|
886
|
+
const firstFillByPair = /* @__PURE__ */ new Map();
|
|
887
|
+
const firstFillByCurrency = /* @__PURE__ */ new Map();
|
|
888
|
+
for (const intent of deposit.intents ?? []) {
|
|
889
|
+
const fulfilledAt = toUnixSeconds2(intent.fulfillTimestamp);
|
|
890
|
+
if (fulfilledAt === void 0 || fulfilledAt < windowStart) continue;
|
|
891
|
+
let method;
|
|
892
|
+
try {
|
|
893
|
+
method = intent.paymentMethodHash ? sdk.resolvePaymentMethodNameFromHash(intent.paymentMethodHash, catalog) : void 0;
|
|
894
|
+
} catch {
|
|
895
|
+
method = void 0;
|
|
896
|
+
}
|
|
897
|
+
const currency = normalizeCurrencyCode(intent.fiatCurrency);
|
|
898
|
+
if (!method || !currency) continue;
|
|
899
|
+
const pair = `${basePlatformForMethod(method)}:${currency}`;
|
|
900
|
+
fillCounts.set(pair, (fillCounts.get(pair) ?? 0) + 1);
|
|
901
|
+
if (createdAt === void 0 || createdAt < windowStart || fulfilledAt < createdAt) continue;
|
|
902
|
+
const previousPairFill = firstFillByPair.get(pair);
|
|
903
|
+
if (previousPairFill === void 0 || fulfilledAt < previousPairFill) {
|
|
904
|
+
firstFillByPair.set(pair, fulfilledAt);
|
|
905
|
+
}
|
|
906
|
+
const previousCurrencyFill = firstFillByCurrency.get(currency);
|
|
907
|
+
if (previousCurrencyFill === void 0 || fulfilledAt < previousCurrencyFill) {
|
|
908
|
+
firstFillByCurrency.set(currency, fulfilledAt);
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
if (createdAt === void 0) continue;
|
|
912
|
+
for (const [pair, firstFill] of firstFillByPair) {
|
|
913
|
+
const latencies = latenciesByPair.get(pair) ?? [];
|
|
914
|
+
latencies.push(firstFill - createdAt);
|
|
915
|
+
latenciesByPair.set(pair, latencies);
|
|
916
|
+
}
|
|
917
|
+
for (const [currency, firstFill] of firstFillByCurrency) {
|
|
918
|
+
const latencies = latenciesByCurrency.get(currency) ?? [];
|
|
919
|
+
latencies.push(firstFill - createdAt);
|
|
920
|
+
latenciesByCurrency.set(currency, latencies);
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
const stats = {};
|
|
924
|
+
for (const [pair, fills] of fillCounts) {
|
|
925
|
+
const medianFillSeconds = median(latenciesByPair.get(pair) ?? []);
|
|
926
|
+
stats[pair] = {
|
|
927
|
+
fills,
|
|
928
|
+
...medianFillSeconds !== void 0 ? { medianFillSeconds } : {}
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
const medianFillSecondsByCurrency = /* @__PURE__ */ new Map();
|
|
932
|
+
for (const [currency, latencies] of latenciesByCurrency) {
|
|
933
|
+
const value = median(latencies);
|
|
934
|
+
if (value !== void 0) medianFillSecondsByCurrency.set(currency, value);
|
|
935
|
+
}
|
|
936
|
+
return { stats, medianFillSecondsByCurrency };
|
|
853
937
|
}
|
|
854
|
-
async function
|
|
938
|
+
async function readFillStatsSample(client, environment) {
|
|
855
939
|
const now = Math.floor(Date.now() / 1e3);
|
|
856
|
-
const windowStart = now -
|
|
940
|
+
const windowStart = now - FILL_STATS_WINDOW_SECONDS;
|
|
857
941
|
const deposits = [];
|
|
858
|
-
for (let offset = 0;
|
|
942
|
+
for (let offset = 0; ; offset += FILL_STATS_PAGE_LIMIT) {
|
|
859
943
|
const page = await client.indexer.getDepositsWithRelations(
|
|
860
944
|
{ chainId: BASE_CHAIN_ID },
|
|
861
|
-
{
|
|
945
|
+
{
|
|
946
|
+
limit: FILL_STATS_PAGE_LIMIT,
|
|
947
|
+
offset,
|
|
948
|
+
orderBy: "updatedAt",
|
|
949
|
+
orderDirection: "desc"
|
|
950
|
+
},
|
|
862
951
|
{ includeIntents: true, intentStatuses: ["FULFILLED", "MANUALLY_RELEASED"] }
|
|
863
952
|
);
|
|
864
953
|
deposits.push(...page);
|
|
865
|
-
if (page.length <
|
|
866
|
-
const
|
|
867
|
-
...page.map((deposit) => toUnixSeconds2(deposit.
|
|
954
|
+
if (page.length < FILL_STATS_PAGE_LIMIT) break;
|
|
955
|
+
const oldestUpdatedAt = Math.min(
|
|
956
|
+
...page.map((deposit) => toUnixSeconds2(deposit.updatedAt) ?? Infinity)
|
|
868
957
|
);
|
|
869
|
-
if (
|
|
958
|
+
if (oldestUpdatedAt < windowStart) break;
|
|
870
959
|
}
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
).sort((a, b) => a.fulfilledAt - b.fulfilledAt);
|
|
881
|
-
if (fulfilled.length === 0) continue;
|
|
882
|
-
firstFillLatencies.push(fulfilled[0].fulfilledAt - createdAt);
|
|
883
|
-
}
|
|
884
|
-
const seconds = median(firstFillLatencies);
|
|
960
|
+
return computeFillStatsSample(deposits, now, environment);
|
|
961
|
+
}
|
|
962
|
+
async function readFillStats(client, environment) {
|
|
963
|
+
return (await readFillStatsSample(client, environment)).stats;
|
|
964
|
+
}
|
|
965
|
+
async function readFillEta(client, input) {
|
|
966
|
+
const sample = await readFillStatsSample(client, input.environment);
|
|
967
|
+
const currency = input.currency.toUpperCase();
|
|
968
|
+
const seconds = input.platform ? sample.stats[`${basePlatformForMethod(input.platform)}:${currency}`]?.medianFillSeconds : sample.medianFillSecondsByCurrency.get(currency);
|
|
885
969
|
return {
|
|
886
970
|
...seconds !== void 0 ? { seconds } : {},
|
|
887
971
|
label: etaLabel(seconds)
|
|
@@ -1549,6 +1633,7 @@ function createCashClient(options) {
|
|
|
1549
1633
|
}
|
|
1550
1634
|
function validatePayout(input) {
|
|
1551
1635
|
const { receive } = input;
|
|
1636
|
+
const catalog = sdk.getPaymentMethodsCatalog(BASE_CHAIN_ID, environment);
|
|
1552
1637
|
const platform = buildCapabilities(environment).platforms.find(
|
|
1553
1638
|
(capability) => capability.platform === receive.platform
|
|
1554
1639
|
);
|
|
@@ -1559,14 +1644,13 @@ function createCashClient(options) {
|
|
|
1559
1644
|
if (!platform.currencies.includes(receive.currency)) {
|
|
1560
1645
|
throw errors.unsupportedPlatformCurrency(receive.platform, receive.currency);
|
|
1561
1646
|
}
|
|
1647
|
+
const paymentMethods = paymentMethodsForPlatform(receive.platform, catalog);
|
|
1562
1648
|
return {
|
|
1563
|
-
payouts:
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
}
|
|
1569
|
-
]
|
|
1649
|
+
payouts: paymentMethods.map((processorName) => ({
|
|
1650
|
+
processorName,
|
|
1651
|
+
currency: receive.currency,
|
|
1652
|
+
payeeData: receive.payee
|
|
1653
|
+
}))
|
|
1570
1654
|
};
|
|
1571
1655
|
}
|
|
1572
1656
|
function validateDepositInput(amount, input, payoutInput = validatePayout(input)) {
|
|
@@ -1844,6 +1928,13 @@ function createCashClient(options) {
|
|
|
1844
1928
|
...options.relay ? { relay: options.relay } : {}
|
|
1845
1929
|
});
|
|
1846
1930
|
},
|
|
1931
|
+
async fillStats() {
|
|
1932
|
+
try {
|
|
1933
|
+
return await readFillStats(readClient, environment);
|
|
1934
|
+
} catch (err) {
|
|
1935
|
+
throw errors.indexerUnavailable("fill stats", err);
|
|
1936
|
+
}
|
|
1937
|
+
},
|
|
1847
1938
|
async cashout(input, opts) {
|
|
1848
1939
|
const client = await signingClient("cashout", opts);
|
|
1849
1940
|
const owner = opts.signer.account.address;
|
|
@@ -2443,6 +2534,11 @@ var cashEstimateJsonSchema = zod.z.object({
|
|
|
2443
2534
|
label: zod.z.string()
|
|
2444
2535
|
}).optional()
|
|
2445
2536
|
});
|
|
2537
|
+
var cashPairFillStatsJsonSchema = zod.z.object({
|
|
2538
|
+
fills: zod.z.number().int().nonnegative(),
|
|
2539
|
+
medianFillSeconds: zod.z.number().int().nonnegative().optional()
|
|
2540
|
+
}).strict();
|
|
2541
|
+
var cashFillStatsJsonSchema = zod.z.record(zod.z.string(), cashPairFillStatsJsonSchema);
|
|
2446
2542
|
var preparedTransactionJsonSchema = zod.z.object({
|
|
2447
2543
|
to: zod.z.string(),
|
|
2448
2544
|
data: zod.z.string(),
|
|
@@ -2747,6 +2843,21 @@ function estimateFromJson(json) {
|
|
|
2747
2843
|
} : void 0
|
|
2748
2844
|
});
|
|
2749
2845
|
}
|
|
2846
|
+
function fillStatsToJson(stats) {
|
|
2847
|
+
return cashFillStatsJsonSchema.parse(stats);
|
|
2848
|
+
}
|
|
2849
|
+
function fillStatsFromJson(json) {
|
|
2850
|
+
const parsed = cashFillStatsJsonSchema.parse(json);
|
|
2851
|
+
return Object.fromEntries(
|
|
2852
|
+
Object.entries(parsed).map(([pair, stats]) => [
|
|
2853
|
+
pair,
|
|
2854
|
+
{
|
|
2855
|
+
fills: stats.fills,
|
|
2856
|
+
...stats.medianFillSeconds !== void 0 ? { medianFillSeconds: stats.medianFillSeconds } : {}
|
|
2857
|
+
}
|
|
2858
|
+
])
|
|
2859
|
+
);
|
|
2860
|
+
}
|
|
2750
2861
|
function cashAssetFromJson(asset) {
|
|
2751
2862
|
return {
|
|
2752
2863
|
chainId: asset.chainId,
|
|
@@ -3055,9 +3166,11 @@ exports.cashErrorRecoveryJsonSchema = cashErrorRecoveryJsonSchema;
|
|
|
3055
3166
|
exports.cashErrorToJson = cashErrorToJson;
|
|
3056
3167
|
exports.cashEstimateJsonSchema = cashEstimateJsonSchema;
|
|
3057
3168
|
exports.cashFillJsonSchema = cashFillJsonSchema;
|
|
3169
|
+
exports.cashFillStatsJsonSchema = cashFillStatsJsonSchema;
|
|
3058
3170
|
exports.cashNextActionSchema = cashNextActionSchema;
|
|
3059
3171
|
exports.cashOrderJsonSchema = cashOrderJsonSchema;
|
|
3060
3172
|
exports.cashOrderStateSchema = cashOrderStateSchema;
|
|
3173
|
+
exports.cashPairFillStatsJsonSchema = cashPairFillStatsJsonSchema;
|
|
3061
3174
|
exports.cashPayoutInfoJsonSchema = cashPayoutInfoJsonSchema;
|
|
3062
3175
|
exports.cashPayoutPricingJsonSchema = cashPayoutPricingJsonSchema;
|
|
3063
3176
|
exports.cashPreparedStepJsonSchema = cashPreparedStepJsonSchema;
|
|
@@ -3077,6 +3190,8 @@ exports.explainOrder = explainOrder;
|
|
|
3077
3190
|
exports.fiatFromUsdc = fiatFromUsdc;
|
|
3078
3191
|
exports.fiatToNumber = fiatToNumber;
|
|
3079
3192
|
exports.fillFromJson = fillFromJson;
|
|
3193
|
+
exports.fillStatsFromJson = fillStatsFromJson;
|
|
3194
|
+
exports.fillStatsToJson = fillStatsToJson;
|
|
3080
3195
|
exports.fillToJson = fillToJson;
|
|
3081
3196
|
exports.formatUsdc = formatUsdc;
|
|
3082
3197
|
exports.intentStatusSchema = intentStatusSchema;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { I as IntentStatus, C as CashPayoutInfo, a as IntentEntity, b as CashBuyerProfile, c as CashDepositInput, d as CreateDepositParamsArg, e as CashOrder, f as CashFill, g as CashCapabilities, h as CashoutResult, i as CashEstimate, P as PrepareResult,
|
|
2
|
-
export {
|
|
1
|
+
import { I as IntentStatus, C as CashPayoutInfo, a as IntentEntity, b as CashBuyerProfile, c as CashDepositInput, d as CreateDepositParamsArg, e as CashOrder, f as CashFill, g as CashCapabilities, h as CashoutResult, i as CashEstimate, j as CashFillStats, P as PrepareResult, k as CashPreparedStep, R as RelayExecutionResult, l as RelayQuote, m as RelayStatus, n as CashSourceCapabilities, T as TopUpResult, W as WithdrawResult } from './createCashClient-BIzOLHjF.cjs';
|
|
2
|
+
export { o as CASH_ATTRIBUTION_CODE, p as CashAsset, q as CashChain, r as CashClient, s as CashClientOptions, t as CashFillEta, u as CashLeg, v as CashNextAction, w as CashOrderState, x as CashPairFillStats, y as CashPayout, z as CashPayoutPricing, A as CashPlatformCapability, B as CashPreparedStepKind, D as CashoutInput, E as CashoutOptions, F as CuratorPayeeDataInput, G as EstimateInput, M as MIN_CASHOUT_AMOUNT, O as OrdersOptions, H as RECOMMENDED_MIN_CASHOUT_AMOUNT, J as RelayOptions, K as RelayQuoteInput, L as RelaySourceInput, N as RelayTransaction, S as SignerOptions, Q as WatchOptions, U as WithdrawOptions, V as buildCapabilities, X as createCashClient } from './createCashClient-BIzOLHjF.cjs';
|
|
3
3
|
import { PaymentMethodCatalog, CurrencyType, OracleAdapterOverrides, OnchainCurrency, Zkp2pClient, PreparedTransaction } from '@zkp2p/sdk';
|
|
4
4
|
export { CurrencyType, PreparedTransaction, RuntimeEnv } from '@zkp2p/sdk';
|
|
5
5
|
import { Log, Abi } from 'viem';
|
|
@@ -1432,6 +1432,26 @@ declare const cashEstimateJsonSchema: z.ZodObject<{
|
|
|
1432
1432
|
seconds?: number | undefined;
|
|
1433
1433
|
} | undefined;
|
|
1434
1434
|
}>;
|
|
1435
|
+
declare const cashPairFillStatsJsonSchema: z.ZodObject<{
|
|
1436
|
+
fills: z.ZodNumber;
|
|
1437
|
+
medianFillSeconds: z.ZodOptional<z.ZodNumber>;
|
|
1438
|
+
}, "strict", z.ZodTypeAny, {
|
|
1439
|
+
fills: number;
|
|
1440
|
+
medianFillSeconds?: number | undefined;
|
|
1441
|
+
}, {
|
|
1442
|
+
fills: number;
|
|
1443
|
+
medianFillSeconds?: number | undefined;
|
|
1444
|
+
}>;
|
|
1445
|
+
declare const cashFillStatsJsonSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
1446
|
+
fills: z.ZodNumber;
|
|
1447
|
+
medianFillSeconds: z.ZodOptional<z.ZodNumber>;
|
|
1448
|
+
}, "strict", z.ZodTypeAny, {
|
|
1449
|
+
fills: number;
|
|
1450
|
+
medianFillSeconds?: number | undefined;
|
|
1451
|
+
}, {
|
|
1452
|
+
fills: number;
|
|
1453
|
+
medianFillSeconds?: number | undefined;
|
|
1454
|
+
}>>;
|
|
1435
1455
|
declare const preparedTransactionJsonSchema: z.ZodObject<{
|
|
1436
1456
|
to: z.ZodString;
|
|
1437
1457
|
data: z.ZodString;
|
|
@@ -2688,8 +2708,8 @@ declare const cashCapabilitiesJsonSchema: z.ZodObject<{
|
|
|
2688
2708
|
decimals: number;
|
|
2689
2709
|
};
|
|
2690
2710
|
};
|
|
2691
|
-
environment: "production" | "preproduction" | "staging";
|
|
2692
2711
|
currencies: string[];
|
|
2712
|
+
environment: "production" | "preproduction" | "staging";
|
|
2693
2713
|
platforms: {
|
|
2694
2714
|
platform: string;
|
|
2695
2715
|
currencies: string[];
|
|
@@ -2759,8 +2779,8 @@ declare const cashCapabilitiesJsonSchema: z.ZodObject<{
|
|
|
2759
2779
|
decimals: number;
|
|
2760
2780
|
};
|
|
2761
2781
|
};
|
|
2762
|
-
environment: "production" | "preproduction" | "staging";
|
|
2763
2782
|
currencies: string[];
|
|
2783
|
+
environment: "production" | "preproduction" | "staging";
|
|
2764
2784
|
platforms: {
|
|
2765
2785
|
platform: string;
|
|
2766
2786
|
currencies: string[];
|
|
@@ -3707,6 +3727,7 @@ declare const cashErrorJsonSchema: z.ZodObject<{
|
|
|
3707
3727
|
type CashOrderJson = z.infer<typeof cashOrderJsonSchema>;
|
|
3708
3728
|
type CashFillJson = z.infer<typeof cashFillJsonSchema>;
|
|
3709
3729
|
type CashEstimateJson = z.infer<typeof cashEstimateJsonSchema>;
|
|
3730
|
+
type CashFillStatsJson = z.infer<typeof cashFillStatsJsonSchema>;
|
|
3710
3731
|
type PreparedTransactionJson = z.infer<typeof preparedTransactionJsonSchema>;
|
|
3711
3732
|
type CashoutResultJson = z.infer<typeof cashoutResultJsonSchema>;
|
|
3712
3733
|
type PrepareResultJson = z.infer<typeof prepareResultJsonSchema>;
|
|
@@ -3739,6 +3760,8 @@ declare function orderToJson(order: CashOrder): CashOrderJson;
|
|
|
3739
3760
|
declare function orderFromJson(json: unknown): CashOrder;
|
|
3740
3761
|
declare function estimateToJson(estimate: CashEstimate): CashEstimateJson;
|
|
3741
3762
|
declare function estimateFromJson(json: unknown): CashEstimate;
|
|
3763
|
+
declare function fillStatsToJson(stats: CashFillStats): CashFillStatsJson;
|
|
3764
|
+
declare function fillStatsFromJson(json: unknown): CashFillStats;
|
|
3742
3765
|
declare function relayQuoteToJson(quote: RelayQuote): RelayQuoteJson;
|
|
3743
3766
|
declare function relayQuoteFromJson(json: unknown): RelayQuote;
|
|
3744
3767
|
declare function sourceCapabilitiesToJson(capabilities: CashSourceCapabilities): CashSourceCapabilitiesJson;
|
|
@@ -3766,4 +3789,4 @@ declare function capabilitiesFromJson(json: unknown): CashCapabilities;
|
|
|
3766
3789
|
declare function cashErrorToJson(error: CashErrorShape): CashErrorJson;
|
|
3767
3790
|
declare function cashErrorFromJson(json: unknown): CashError;
|
|
3768
3791
|
|
|
3769
|
-
export { BASE_CHAIN_ID, BASE_USDC_ADDRESS, CASH_ORDER_POLL_INTERVAL_MS, CASH_ORDER_STATUSES, CASH_RETAIN_ON_EMPTY, type CashAssetJson, CashBuyerProfile, type CashBuyerProfileJson, CashCapabilities, type CashCapabilitiesJson, type CashChainJson, CashDepositInput, CashError, type CashErrorCode, type CashErrorJson, type CashErrorRecovery, type CashErrorRecoveryJson, type CashErrorShape, CashEstimate, type CashEstimateJson, CashFill, type CashFillJson, CashOrder, type CashOrderData, type CashOrderJson, CashPayoutInfo, type CashPayoutInfoJson, CashPreparedStep, type CashPreparedStepJson, CashSourceCapabilities, type CashSourceCapabilitiesJson, CashoutResult, type CashoutResultJson, type DeriveCashOrderOptions, MARKET_SPREAD_BPS, type MethodCurrencyLike, ORACLE_MIN_CONVERSION_RATE_SENTINEL, type PaymentMethodLike, PrepareResult, type PrepareResultJson, type PreparedTransactionJson, RATE_PRECISION, RelayExecutionResult, type RelayExecutionResultJson, RelayQuote, type RelayQuoteJson, RelayStatus, type RelayStatusJson, type RelayTransactionJson, type RelayTransactionsJson, type ResolvedCashDeposit, TopUpResult, type TopUpResultJson, USDC_DECIMALS, WithdrawResult, type WithdrawResultJson, bigintString, buildIntentAmountRange, buildMarketRateCurrencyOverride, buyerProfileFromJson, buyerProfileToJson, capabilitiesFromJson, capabilitiesToJson, cashAssetJsonSchema, cashBuyerProfileJsonSchema, cashCapabilitiesJsonSchema, cashChainJsonSchema, cashErrorFromJson, cashErrorJsonSchema, cashErrorRecoveryJsonSchema, cashErrorToJson, cashEstimateJsonSchema, cashFillJsonSchema, cashNextActionSchema, cashOrderJsonSchema, cashOrderStateSchema, cashPayoutInfoJsonSchema, cashPayoutPricingJsonSchema, cashPreparedStepJsonSchema, cashSourceCapabilitiesJsonSchema, cashoutResultFromJson, cashoutResultJsonSchema, cashoutResultToJson, centsToNumber, deriveBuyerProfile, deriveCashOrder, derivePayouts, errors, estimateFromJson, estimateToJson, explainOrder, fiatFromUsdc, fiatToNumber, fillFromJson, fillToJson, formatUsdc, intentStatusSchema, isCashError, isFillLive, isMarketRateSupported, nonNegativeBigintString, orderFromJson, orderToJson, parseCompositeDepositId, prepareCashDepositParams, prepareResultFromJson, prepareResultJsonSchema, prepareResultToJson, preparedStepFromJson, preparedStepToJson, preparedTransactionJsonSchema, preparedTxFromJson, preparedTxToJson, rateToNumber, relayExecutionResultFromJson, relayExecutionResultJsonSchema, relayExecutionResultToJson, relayQuoteFromJson, relayQuoteJsonSchema, relayQuoteToJson, relayStatusFromJson, relayStatusJsonSchema, relayStatusToJson, relayTransactionJsonSchema, relayTransactionsJsonSchema, resolveCashDepositId, sourceCapabilitiesFromJson, sourceCapabilitiesToJson, topUpResultFromJson, topUpResultJsonSchema, topUpResultToJson, usdc, withExplain, withdrawResultFromJson, withdrawResultJsonSchema, withdrawResultToJson };
|
|
3792
|
+
export { BASE_CHAIN_ID, BASE_USDC_ADDRESS, CASH_ORDER_POLL_INTERVAL_MS, CASH_ORDER_STATUSES, CASH_RETAIN_ON_EMPTY, type CashAssetJson, CashBuyerProfile, type CashBuyerProfileJson, CashCapabilities, type CashCapabilitiesJson, type CashChainJson, CashDepositInput, CashError, type CashErrorCode, type CashErrorJson, type CashErrorRecovery, type CashErrorRecoveryJson, type CashErrorShape, CashEstimate, type CashEstimateJson, CashFill, type CashFillJson, CashFillStats, type CashFillStatsJson, CashOrder, type CashOrderData, type CashOrderJson, CashPayoutInfo, type CashPayoutInfoJson, CashPreparedStep, type CashPreparedStepJson, CashSourceCapabilities, type CashSourceCapabilitiesJson, CashoutResult, type CashoutResultJson, type DeriveCashOrderOptions, MARKET_SPREAD_BPS, type MethodCurrencyLike, ORACLE_MIN_CONVERSION_RATE_SENTINEL, type PaymentMethodLike, PrepareResult, type PrepareResultJson, type PreparedTransactionJson, RATE_PRECISION, RelayExecutionResult, type RelayExecutionResultJson, RelayQuote, type RelayQuoteJson, RelayStatus, type RelayStatusJson, type RelayTransactionJson, type RelayTransactionsJson, type ResolvedCashDeposit, TopUpResult, type TopUpResultJson, USDC_DECIMALS, WithdrawResult, type WithdrawResultJson, bigintString, buildIntentAmountRange, buildMarketRateCurrencyOverride, buyerProfileFromJson, buyerProfileToJson, capabilitiesFromJson, capabilitiesToJson, cashAssetJsonSchema, cashBuyerProfileJsonSchema, cashCapabilitiesJsonSchema, cashChainJsonSchema, cashErrorFromJson, cashErrorJsonSchema, cashErrorRecoveryJsonSchema, cashErrorToJson, cashEstimateJsonSchema, cashFillJsonSchema, cashFillStatsJsonSchema, cashNextActionSchema, cashOrderJsonSchema, cashOrderStateSchema, cashPairFillStatsJsonSchema, cashPayoutInfoJsonSchema, cashPayoutPricingJsonSchema, cashPreparedStepJsonSchema, cashSourceCapabilitiesJsonSchema, cashoutResultFromJson, cashoutResultJsonSchema, cashoutResultToJson, centsToNumber, deriveBuyerProfile, deriveCashOrder, derivePayouts, errors, estimateFromJson, estimateToJson, explainOrder, fiatFromUsdc, fiatToNumber, fillFromJson, fillStatsFromJson, fillStatsToJson, fillToJson, formatUsdc, intentStatusSchema, isCashError, isFillLive, isMarketRateSupported, nonNegativeBigintString, orderFromJson, orderToJson, parseCompositeDepositId, prepareCashDepositParams, prepareResultFromJson, prepareResultJsonSchema, prepareResultToJson, preparedStepFromJson, preparedStepToJson, preparedTransactionJsonSchema, preparedTxFromJson, preparedTxToJson, rateToNumber, relayExecutionResultFromJson, relayExecutionResultJsonSchema, relayExecutionResultToJson, relayQuoteFromJson, relayQuoteJsonSchema, relayQuoteToJson, relayStatusFromJson, relayStatusJsonSchema, relayStatusToJson, relayTransactionJsonSchema, relayTransactionsJsonSchema, resolveCashDepositId, sourceCapabilitiesFromJson, sourceCapabilitiesToJson, topUpResultFromJson, topUpResultJsonSchema, topUpResultToJson, usdc, withExplain, withdrawResultFromJson, withdrawResultJsonSchema, withdrawResultToJson };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { I as IntentStatus, C as CashPayoutInfo, a as IntentEntity, b as CashBuyerProfile, c as CashDepositInput, d as CreateDepositParamsArg, e as CashOrder, f as CashFill, g as CashCapabilities, h as CashoutResult, i as CashEstimate, P as PrepareResult,
|
|
2
|
-
export {
|
|
1
|
+
import { I as IntentStatus, C as CashPayoutInfo, a as IntentEntity, b as CashBuyerProfile, c as CashDepositInput, d as CreateDepositParamsArg, e as CashOrder, f as CashFill, g as CashCapabilities, h as CashoutResult, i as CashEstimate, j as CashFillStats, P as PrepareResult, k as CashPreparedStep, R as RelayExecutionResult, l as RelayQuote, m as RelayStatus, n as CashSourceCapabilities, T as TopUpResult, W as WithdrawResult } from './createCashClient-BIzOLHjF.js';
|
|
2
|
+
export { o as CASH_ATTRIBUTION_CODE, p as CashAsset, q as CashChain, r as CashClient, s as CashClientOptions, t as CashFillEta, u as CashLeg, v as CashNextAction, w as CashOrderState, x as CashPairFillStats, y as CashPayout, z as CashPayoutPricing, A as CashPlatformCapability, B as CashPreparedStepKind, D as CashoutInput, E as CashoutOptions, F as CuratorPayeeDataInput, G as EstimateInput, M as MIN_CASHOUT_AMOUNT, O as OrdersOptions, H as RECOMMENDED_MIN_CASHOUT_AMOUNT, J as RelayOptions, K as RelayQuoteInput, L as RelaySourceInput, N as RelayTransaction, S as SignerOptions, Q as WatchOptions, U as WithdrawOptions, V as buildCapabilities, X as createCashClient } from './createCashClient-BIzOLHjF.js';
|
|
3
3
|
import { PaymentMethodCatalog, CurrencyType, OracleAdapterOverrides, OnchainCurrency, Zkp2pClient, PreparedTransaction } from '@zkp2p/sdk';
|
|
4
4
|
export { CurrencyType, PreparedTransaction, RuntimeEnv } from '@zkp2p/sdk';
|
|
5
5
|
import { Log, Abi } from 'viem';
|
|
@@ -1432,6 +1432,26 @@ declare const cashEstimateJsonSchema: z.ZodObject<{
|
|
|
1432
1432
|
seconds?: number | undefined;
|
|
1433
1433
|
} | undefined;
|
|
1434
1434
|
}>;
|
|
1435
|
+
declare const cashPairFillStatsJsonSchema: z.ZodObject<{
|
|
1436
|
+
fills: z.ZodNumber;
|
|
1437
|
+
medianFillSeconds: z.ZodOptional<z.ZodNumber>;
|
|
1438
|
+
}, "strict", z.ZodTypeAny, {
|
|
1439
|
+
fills: number;
|
|
1440
|
+
medianFillSeconds?: number | undefined;
|
|
1441
|
+
}, {
|
|
1442
|
+
fills: number;
|
|
1443
|
+
medianFillSeconds?: number | undefined;
|
|
1444
|
+
}>;
|
|
1445
|
+
declare const cashFillStatsJsonSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
1446
|
+
fills: z.ZodNumber;
|
|
1447
|
+
medianFillSeconds: z.ZodOptional<z.ZodNumber>;
|
|
1448
|
+
}, "strict", z.ZodTypeAny, {
|
|
1449
|
+
fills: number;
|
|
1450
|
+
medianFillSeconds?: number | undefined;
|
|
1451
|
+
}, {
|
|
1452
|
+
fills: number;
|
|
1453
|
+
medianFillSeconds?: number | undefined;
|
|
1454
|
+
}>>;
|
|
1435
1455
|
declare const preparedTransactionJsonSchema: z.ZodObject<{
|
|
1436
1456
|
to: z.ZodString;
|
|
1437
1457
|
data: z.ZodString;
|
|
@@ -2688,8 +2708,8 @@ declare const cashCapabilitiesJsonSchema: z.ZodObject<{
|
|
|
2688
2708
|
decimals: number;
|
|
2689
2709
|
};
|
|
2690
2710
|
};
|
|
2691
|
-
environment: "production" | "preproduction" | "staging";
|
|
2692
2711
|
currencies: string[];
|
|
2712
|
+
environment: "production" | "preproduction" | "staging";
|
|
2693
2713
|
platforms: {
|
|
2694
2714
|
platform: string;
|
|
2695
2715
|
currencies: string[];
|
|
@@ -2759,8 +2779,8 @@ declare const cashCapabilitiesJsonSchema: z.ZodObject<{
|
|
|
2759
2779
|
decimals: number;
|
|
2760
2780
|
};
|
|
2761
2781
|
};
|
|
2762
|
-
environment: "production" | "preproduction" | "staging";
|
|
2763
2782
|
currencies: string[];
|
|
2783
|
+
environment: "production" | "preproduction" | "staging";
|
|
2764
2784
|
platforms: {
|
|
2765
2785
|
platform: string;
|
|
2766
2786
|
currencies: string[];
|
|
@@ -3707,6 +3727,7 @@ declare const cashErrorJsonSchema: z.ZodObject<{
|
|
|
3707
3727
|
type CashOrderJson = z.infer<typeof cashOrderJsonSchema>;
|
|
3708
3728
|
type CashFillJson = z.infer<typeof cashFillJsonSchema>;
|
|
3709
3729
|
type CashEstimateJson = z.infer<typeof cashEstimateJsonSchema>;
|
|
3730
|
+
type CashFillStatsJson = z.infer<typeof cashFillStatsJsonSchema>;
|
|
3710
3731
|
type PreparedTransactionJson = z.infer<typeof preparedTransactionJsonSchema>;
|
|
3711
3732
|
type CashoutResultJson = z.infer<typeof cashoutResultJsonSchema>;
|
|
3712
3733
|
type PrepareResultJson = z.infer<typeof prepareResultJsonSchema>;
|
|
@@ -3739,6 +3760,8 @@ declare function orderToJson(order: CashOrder): CashOrderJson;
|
|
|
3739
3760
|
declare function orderFromJson(json: unknown): CashOrder;
|
|
3740
3761
|
declare function estimateToJson(estimate: CashEstimate): CashEstimateJson;
|
|
3741
3762
|
declare function estimateFromJson(json: unknown): CashEstimate;
|
|
3763
|
+
declare function fillStatsToJson(stats: CashFillStats): CashFillStatsJson;
|
|
3764
|
+
declare function fillStatsFromJson(json: unknown): CashFillStats;
|
|
3742
3765
|
declare function relayQuoteToJson(quote: RelayQuote): RelayQuoteJson;
|
|
3743
3766
|
declare function relayQuoteFromJson(json: unknown): RelayQuote;
|
|
3744
3767
|
declare function sourceCapabilitiesToJson(capabilities: CashSourceCapabilities): CashSourceCapabilitiesJson;
|
|
@@ -3766,4 +3789,4 @@ declare function capabilitiesFromJson(json: unknown): CashCapabilities;
|
|
|
3766
3789
|
declare function cashErrorToJson(error: CashErrorShape): CashErrorJson;
|
|
3767
3790
|
declare function cashErrorFromJson(json: unknown): CashError;
|
|
3768
3791
|
|
|
3769
|
-
export { BASE_CHAIN_ID, BASE_USDC_ADDRESS, CASH_ORDER_POLL_INTERVAL_MS, CASH_ORDER_STATUSES, CASH_RETAIN_ON_EMPTY, type CashAssetJson, CashBuyerProfile, type CashBuyerProfileJson, CashCapabilities, type CashCapabilitiesJson, type CashChainJson, CashDepositInput, CashError, type CashErrorCode, type CashErrorJson, type CashErrorRecovery, type CashErrorRecoveryJson, type CashErrorShape, CashEstimate, type CashEstimateJson, CashFill, type CashFillJson, CashOrder, type CashOrderData, type CashOrderJson, CashPayoutInfo, type CashPayoutInfoJson, CashPreparedStep, type CashPreparedStepJson, CashSourceCapabilities, type CashSourceCapabilitiesJson, CashoutResult, type CashoutResultJson, type DeriveCashOrderOptions, MARKET_SPREAD_BPS, type MethodCurrencyLike, ORACLE_MIN_CONVERSION_RATE_SENTINEL, type PaymentMethodLike, PrepareResult, type PrepareResultJson, type PreparedTransactionJson, RATE_PRECISION, RelayExecutionResult, type RelayExecutionResultJson, RelayQuote, type RelayQuoteJson, RelayStatus, type RelayStatusJson, type RelayTransactionJson, type RelayTransactionsJson, type ResolvedCashDeposit, TopUpResult, type TopUpResultJson, USDC_DECIMALS, WithdrawResult, type WithdrawResultJson, bigintString, buildIntentAmountRange, buildMarketRateCurrencyOverride, buyerProfileFromJson, buyerProfileToJson, capabilitiesFromJson, capabilitiesToJson, cashAssetJsonSchema, cashBuyerProfileJsonSchema, cashCapabilitiesJsonSchema, cashChainJsonSchema, cashErrorFromJson, cashErrorJsonSchema, cashErrorRecoveryJsonSchema, cashErrorToJson, cashEstimateJsonSchema, cashFillJsonSchema, cashNextActionSchema, cashOrderJsonSchema, cashOrderStateSchema, cashPayoutInfoJsonSchema, cashPayoutPricingJsonSchema, cashPreparedStepJsonSchema, cashSourceCapabilitiesJsonSchema, cashoutResultFromJson, cashoutResultJsonSchema, cashoutResultToJson, centsToNumber, deriveBuyerProfile, deriveCashOrder, derivePayouts, errors, estimateFromJson, estimateToJson, explainOrder, fiatFromUsdc, fiatToNumber, fillFromJson, fillToJson, formatUsdc, intentStatusSchema, isCashError, isFillLive, isMarketRateSupported, nonNegativeBigintString, orderFromJson, orderToJson, parseCompositeDepositId, prepareCashDepositParams, prepareResultFromJson, prepareResultJsonSchema, prepareResultToJson, preparedStepFromJson, preparedStepToJson, preparedTransactionJsonSchema, preparedTxFromJson, preparedTxToJson, rateToNumber, relayExecutionResultFromJson, relayExecutionResultJsonSchema, relayExecutionResultToJson, relayQuoteFromJson, relayQuoteJsonSchema, relayQuoteToJson, relayStatusFromJson, relayStatusJsonSchema, relayStatusToJson, relayTransactionJsonSchema, relayTransactionsJsonSchema, resolveCashDepositId, sourceCapabilitiesFromJson, sourceCapabilitiesToJson, topUpResultFromJson, topUpResultJsonSchema, topUpResultToJson, usdc, withExplain, withdrawResultFromJson, withdrawResultJsonSchema, withdrawResultToJson };
|
|
3792
|
+
export { BASE_CHAIN_ID, BASE_USDC_ADDRESS, CASH_ORDER_POLL_INTERVAL_MS, CASH_ORDER_STATUSES, CASH_RETAIN_ON_EMPTY, type CashAssetJson, CashBuyerProfile, type CashBuyerProfileJson, CashCapabilities, type CashCapabilitiesJson, type CashChainJson, CashDepositInput, CashError, type CashErrorCode, type CashErrorJson, type CashErrorRecovery, type CashErrorRecoveryJson, type CashErrorShape, CashEstimate, type CashEstimateJson, CashFill, type CashFillJson, CashFillStats, type CashFillStatsJson, CashOrder, type CashOrderData, type CashOrderJson, CashPayoutInfo, type CashPayoutInfoJson, CashPreparedStep, type CashPreparedStepJson, CashSourceCapabilities, type CashSourceCapabilitiesJson, CashoutResult, type CashoutResultJson, type DeriveCashOrderOptions, MARKET_SPREAD_BPS, type MethodCurrencyLike, ORACLE_MIN_CONVERSION_RATE_SENTINEL, type PaymentMethodLike, PrepareResult, type PrepareResultJson, type PreparedTransactionJson, RATE_PRECISION, RelayExecutionResult, type RelayExecutionResultJson, RelayQuote, type RelayQuoteJson, RelayStatus, type RelayStatusJson, type RelayTransactionJson, type RelayTransactionsJson, type ResolvedCashDeposit, TopUpResult, type TopUpResultJson, USDC_DECIMALS, WithdrawResult, type WithdrawResultJson, bigintString, buildIntentAmountRange, buildMarketRateCurrencyOverride, buyerProfileFromJson, buyerProfileToJson, capabilitiesFromJson, capabilitiesToJson, cashAssetJsonSchema, cashBuyerProfileJsonSchema, cashCapabilitiesJsonSchema, cashChainJsonSchema, cashErrorFromJson, cashErrorJsonSchema, cashErrorRecoveryJsonSchema, cashErrorToJson, cashEstimateJsonSchema, cashFillJsonSchema, cashFillStatsJsonSchema, cashNextActionSchema, cashOrderJsonSchema, cashOrderStateSchema, cashPairFillStatsJsonSchema, cashPayoutInfoJsonSchema, cashPayoutPricingJsonSchema, cashPreparedStepJsonSchema, cashSourceCapabilitiesJsonSchema, cashoutResultFromJson, cashoutResultJsonSchema, cashoutResultToJson, centsToNumber, deriveBuyerProfile, deriveCashOrder, derivePayouts, errors, estimateFromJson, estimateToJson, explainOrder, fiatFromUsdc, fiatToNumber, fillFromJson, fillStatsFromJson, fillStatsToJson, fillToJson, formatUsdc, intentStatusSchema, isCashError, isFillLive, isMarketRateSupported, nonNegativeBigintString, orderFromJson, orderToJson, parseCompositeDepositId, prepareCashDepositParams, prepareResultFromJson, prepareResultJsonSchema, prepareResultToJson, preparedStepFromJson, preparedStepToJson, preparedTransactionJsonSchema, preparedTxFromJson, preparedTxToJson, rateToNumber, relayExecutionResultFromJson, relayExecutionResultJsonSchema, relayExecutionResultToJson, relayQuoteFromJson, relayQuoteJsonSchema, relayQuoteToJson, relayStatusFromJson, relayStatusJsonSchema, relayStatusToJson, relayTransactionJsonSchema, relayTransactionsJsonSchema, resolveCashDepositId, sourceCapabilitiesFromJson, sourceCapabilitiesToJson, topUpResultFromJson, topUpResultJsonSchema, topUpResultToJson, usdc, withExplain, withdrawResultFromJson, withdrawResultJsonSchema, withdrawResultToJson };
|
package/dist/index.js
CHANGED
|
@@ -387,6 +387,26 @@ function parseCompositeDepositId(compositeId) {
|
|
|
387
387
|
const onchainDepositId = BigInt(rawDepositId);
|
|
388
388
|
return { escrowAddress: canonicalEscrowAddress, onchainDepositId };
|
|
389
389
|
}
|
|
390
|
+
|
|
391
|
+
// src/client/platformGroups.ts
|
|
392
|
+
var PLATFORM_METHOD_GROUPS = {
|
|
393
|
+
zelle: ["zelle", "zelle-chase", "zelle-bofa", "zelle-citi"]
|
|
394
|
+
};
|
|
395
|
+
var METHOD_TO_BASE_PLATFORM = new Map(
|
|
396
|
+
Object.entries(PLATFORM_METHOD_GROUPS).flatMap(
|
|
397
|
+
([platform, methods]) => methods.map((method) => [method, platform])
|
|
398
|
+
)
|
|
399
|
+
);
|
|
400
|
+
function basePlatformForMethod(method) {
|
|
401
|
+
return METHOD_TO_BASE_PLATFORM.get(method) ?? method;
|
|
402
|
+
}
|
|
403
|
+
function paymentMethodsForPlatform(platform, catalog) {
|
|
404
|
+
const configured = PLATFORM_METHOD_GROUPS[platform];
|
|
405
|
+
const methods = configured ?? [platform];
|
|
406
|
+
return methods.filter((method) => catalog[method] !== void 0);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// src/client/capabilities.ts
|
|
390
410
|
var MIN_CASHOUT_AMOUNT = 10000n;
|
|
391
411
|
var RECOMMENDED_MIN_CASHOUT_AMOUNT = 1000000n;
|
|
392
412
|
var PAYEE_HINTS = {
|
|
@@ -405,13 +425,20 @@ var PAYEE_HINTS = {
|
|
|
405
425
|
var IDENTITY_ATTESTATION_PLATFORMS = /* @__PURE__ */ new Set(["wise", "paypal"]);
|
|
406
426
|
function buildCapabilities(environment) {
|
|
407
427
|
const catalog = getPaymentMethodsCatalog(BASE_CHAIN_ID, environment);
|
|
408
|
-
const
|
|
428
|
+
const currenciesByPlatform = /* @__PURE__ */ new Map();
|
|
429
|
+
for (const [method, entry] of Object.entries(catalog)) {
|
|
430
|
+
const platform = basePlatformForMethod(method);
|
|
409
431
|
const currencies2 = (entry.currencies ?? []).map((hash) => getCurrencyCodeFromHash(hash)).filter(
|
|
410
432
|
(code) => code != null && isMarketRateSupported(code)
|
|
411
433
|
);
|
|
434
|
+
const aggregate = currenciesByPlatform.get(platform) ?? /* @__PURE__ */ new Set();
|
|
435
|
+
for (const currency of currencies2) aggregate.add(currency);
|
|
436
|
+
currenciesByPlatform.set(platform, aggregate);
|
|
437
|
+
}
|
|
438
|
+
const platforms = [...currenciesByPlatform.entries()].map(([platform, currencies2]) => {
|
|
412
439
|
return {
|
|
413
440
|
platform,
|
|
414
|
-
currencies: [...
|
|
441
|
+
currencies: [...currencies2].sort(),
|
|
415
442
|
payeeHint: PAYEE_HINTS[platform] ?? "Your payment handle for this platform",
|
|
416
443
|
requiresIdentityAttestation: IDENTITY_ATTESTATION_PLATFORMS.has(platform)
|
|
417
444
|
};
|
|
@@ -430,11 +457,8 @@ function buildCapabilities(environment) {
|
|
|
430
457
|
pricing: { kind: "oracle-market-rate", spreadBps: 0 }
|
|
431
458
|
};
|
|
432
459
|
}
|
|
433
|
-
var
|
|
434
|
-
var
|
|
435
|
-
var ETA_PAGE_LIMIT = 250;
|
|
436
|
-
var ETA_MAX_DEPOSIT_SCAN = 2e3;
|
|
437
|
-
var FULFILLED = /* @__PURE__ */ new Set(["FULFILLED", "MANUALLY_RELEASED"]);
|
|
460
|
+
var FILL_STATS_WINDOW_SECONDS = 30 * 24 * 60 * 60;
|
|
461
|
+
var FILL_STATS_PAGE_LIMIT = 250;
|
|
438
462
|
function toUnixSeconds2(value) {
|
|
439
463
|
if (value === null || value === void 0 || value === "") return void 0;
|
|
440
464
|
if (value instanceof Date) {
|
|
@@ -445,12 +469,22 @@ function toUnixSeconds2(value) {
|
|
|
445
469
|
const parsed = Date.parse(value);
|
|
446
470
|
if (Number.isFinite(parsed)) return Math.floor(parsed / 1e3);
|
|
447
471
|
}
|
|
448
|
-
const
|
|
449
|
-
return Number.isFinite(
|
|
472
|
+
const numeric = Number(value);
|
|
473
|
+
return Number.isFinite(numeric) && numeric > 0 ? numeric : void 0;
|
|
474
|
+
}
|
|
475
|
+
function normalizeCurrencyCode(value) {
|
|
476
|
+
const raw = value?.trim();
|
|
477
|
+
if (!raw) return void 0;
|
|
478
|
+
if (!raw.toLowerCase().startsWith("0x")) return raw.toUpperCase();
|
|
479
|
+
try {
|
|
480
|
+
return getCurrencyCodeFromHash(raw)?.toUpperCase();
|
|
481
|
+
} catch {
|
|
482
|
+
return void 0;
|
|
483
|
+
}
|
|
450
484
|
}
|
|
451
485
|
function median(values) {
|
|
452
486
|
if (values.length === 0) return void 0;
|
|
453
|
-
const sorted = [...values].sort((
|
|
487
|
+
const sorted = [...values].sort((left, right) => left - right);
|
|
454
488
|
const mid = Math.floor(sorted.length / 2);
|
|
455
489
|
return sorted.length % 2 === 1 ? sorted[mid] : Math.round((sorted[mid - 1] + sorted[mid]) / 2);
|
|
456
490
|
}
|
|
@@ -462,47 +496,97 @@ function etaLabel(seconds) {
|
|
|
462
496
|
const hours = Math.max(1, Math.round(minutes / 60));
|
|
463
497
|
return `Usually starts in about ${hours} hr`;
|
|
464
498
|
}
|
|
465
|
-
function
|
|
466
|
-
const
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
);
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
499
|
+
function computeFillStatsSample(deposits, nowSeconds, environment) {
|
|
500
|
+
const catalog = getPaymentMethodsCatalog(BASE_CHAIN_ID, environment);
|
|
501
|
+
const windowStart = nowSeconds - FILL_STATS_WINDOW_SECONDS;
|
|
502
|
+
const fillCounts = /* @__PURE__ */ new Map();
|
|
503
|
+
const latenciesByPair = /* @__PURE__ */ new Map();
|
|
504
|
+
const latenciesByCurrency = /* @__PURE__ */ new Map();
|
|
505
|
+
for (const deposit of deposits) {
|
|
506
|
+
const createdAt = toUnixSeconds2(deposit.createdAt ?? deposit.timestamp);
|
|
507
|
+
const firstFillByPair = /* @__PURE__ */ new Map();
|
|
508
|
+
const firstFillByCurrency = /* @__PURE__ */ new Map();
|
|
509
|
+
for (const intent of deposit.intents ?? []) {
|
|
510
|
+
const fulfilledAt = toUnixSeconds2(intent.fulfillTimestamp);
|
|
511
|
+
if (fulfilledAt === void 0 || fulfilledAt < windowStart) continue;
|
|
512
|
+
let method;
|
|
513
|
+
try {
|
|
514
|
+
method = intent.paymentMethodHash ? resolvePaymentMethodNameFromHash(intent.paymentMethodHash, catalog) : void 0;
|
|
515
|
+
} catch {
|
|
516
|
+
method = void 0;
|
|
517
|
+
}
|
|
518
|
+
const currency = normalizeCurrencyCode(intent.fiatCurrency);
|
|
519
|
+
if (!method || !currency) continue;
|
|
520
|
+
const pair = `${basePlatformForMethod(method)}:${currency}`;
|
|
521
|
+
fillCounts.set(pair, (fillCounts.get(pair) ?? 0) + 1);
|
|
522
|
+
if (createdAt === void 0 || createdAt < windowStart || fulfilledAt < createdAt) continue;
|
|
523
|
+
const previousPairFill = firstFillByPair.get(pair);
|
|
524
|
+
if (previousPairFill === void 0 || fulfilledAt < previousPairFill) {
|
|
525
|
+
firstFillByPair.set(pair, fulfilledAt);
|
|
526
|
+
}
|
|
527
|
+
const previousCurrencyFill = firstFillByCurrency.get(currency);
|
|
528
|
+
if (previousCurrencyFill === void 0 || fulfilledAt < previousCurrencyFill) {
|
|
529
|
+
firstFillByCurrency.set(currency, fulfilledAt);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
if (createdAt === void 0) continue;
|
|
533
|
+
for (const [pair, firstFill] of firstFillByPair) {
|
|
534
|
+
const latencies = latenciesByPair.get(pair) ?? [];
|
|
535
|
+
latencies.push(firstFill - createdAt);
|
|
536
|
+
latenciesByPair.set(pair, latencies);
|
|
537
|
+
}
|
|
538
|
+
for (const [currency, firstFill] of firstFillByCurrency) {
|
|
539
|
+
const latencies = latenciesByCurrency.get(currency) ?? [];
|
|
540
|
+
latencies.push(firstFill - createdAt);
|
|
541
|
+
latenciesByCurrency.set(currency, latencies);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
const stats = {};
|
|
545
|
+
for (const [pair, fills] of fillCounts) {
|
|
546
|
+
const medianFillSeconds = median(latenciesByPair.get(pair) ?? []);
|
|
547
|
+
stats[pair] = {
|
|
548
|
+
fills,
|
|
549
|
+
...medianFillSeconds !== void 0 ? { medianFillSeconds } : {}
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
const medianFillSecondsByCurrency = /* @__PURE__ */ new Map();
|
|
553
|
+
for (const [currency, latencies] of latenciesByCurrency) {
|
|
554
|
+
const value = median(latencies);
|
|
555
|
+
if (value !== void 0) medianFillSecondsByCurrency.set(currency, value);
|
|
556
|
+
}
|
|
557
|
+
return { stats, medianFillSecondsByCurrency };
|
|
474
558
|
}
|
|
475
|
-
async function
|
|
559
|
+
async function readFillStatsSample(client, environment) {
|
|
476
560
|
const now = Math.floor(Date.now() / 1e3);
|
|
477
|
-
const windowStart = now -
|
|
561
|
+
const windowStart = now - FILL_STATS_WINDOW_SECONDS;
|
|
478
562
|
const deposits = [];
|
|
479
|
-
for (let offset = 0;
|
|
563
|
+
for (let offset = 0; ; offset += FILL_STATS_PAGE_LIMIT) {
|
|
480
564
|
const page = await client.indexer.getDepositsWithRelations(
|
|
481
565
|
{ chainId: BASE_CHAIN_ID },
|
|
482
|
-
{
|
|
566
|
+
{
|
|
567
|
+
limit: FILL_STATS_PAGE_LIMIT,
|
|
568
|
+
offset,
|
|
569
|
+
orderBy: "updatedAt",
|
|
570
|
+
orderDirection: "desc"
|
|
571
|
+
},
|
|
483
572
|
{ includeIntents: true, intentStatuses: ["FULFILLED", "MANUALLY_RELEASED"] }
|
|
484
573
|
);
|
|
485
574
|
deposits.push(...page);
|
|
486
|
-
if (page.length <
|
|
487
|
-
const
|
|
488
|
-
...page.map((deposit) => toUnixSeconds2(deposit.
|
|
575
|
+
if (page.length < FILL_STATS_PAGE_LIMIT) break;
|
|
576
|
+
const oldestUpdatedAt = Math.min(
|
|
577
|
+
...page.map((deposit) => toUnixSeconds2(deposit.updatedAt) ?? Infinity)
|
|
489
578
|
);
|
|
490
|
-
if (
|
|
579
|
+
if (oldestUpdatedAt < windowStart) break;
|
|
491
580
|
}
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
).sort((a, b) => a.fulfilledAt - b.fulfilledAt);
|
|
502
|
-
if (fulfilled.length === 0) continue;
|
|
503
|
-
firstFillLatencies.push(fulfilled[0].fulfilledAt - createdAt);
|
|
504
|
-
}
|
|
505
|
-
const seconds = median(firstFillLatencies);
|
|
581
|
+
return computeFillStatsSample(deposits, now, environment);
|
|
582
|
+
}
|
|
583
|
+
async function readFillStats(client, environment) {
|
|
584
|
+
return (await readFillStatsSample(client, environment)).stats;
|
|
585
|
+
}
|
|
586
|
+
async function readFillEta(client, input) {
|
|
587
|
+
const sample = await readFillStatsSample(client, input.environment);
|
|
588
|
+
const currency = input.currency.toUpperCase();
|
|
589
|
+
const seconds = input.platform ? sample.stats[`${basePlatformForMethod(input.platform)}:${currency}`]?.medianFillSeconds : sample.medianFillSecondsByCurrency.get(currency);
|
|
506
590
|
return {
|
|
507
591
|
...seconds !== void 0 ? { seconds } : {},
|
|
508
592
|
label: etaLabel(seconds)
|
|
@@ -1170,6 +1254,7 @@ function createCashClient(options) {
|
|
|
1170
1254
|
}
|
|
1171
1255
|
function validatePayout(input) {
|
|
1172
1256
|
const { receive } = input;
|
|
1257
|
+
const catalog = getPaymentMethodsCatalog(BASE_CHAIN_ID, environment);
|
|
1173
1258
|
const platform = buildCapabilities(environment).platforms.find(
|
|
1174
1259
|
(capability) => capability.platform === receive.platform
|
|
1175
1260
|
);
|
|
@@ -1180,14 +1265,13 @@ function createCashClient(options) {
|
|
|
1180
1265
|
if (!platform.currencies.includes(receive.currency)) {
|
|
1181
1266
|
throw errors.unsupportedPlatformCurrency(receive.platform, receive.currency);
|
|
1182
1267
|
}
|
|
1268
|
+
const paymentMethods = paymentMethodsForPlatform(receive.platform, catalog);
|
|
1183
1269
|
return {
|
|
1184
|
-
payouts:
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
}
|
|
1190
|
-
]
|
|
1270
|
+
payouts: paymentMethods.map((processorName) => ({
|
|
1271
|
+
processorName,
|
|
1272
|
+
currency: receive.currency,
|
|
1273
|
+
payeeData: receive.payee
|
|
1274
|
+
}))
|
|
1191
1275
|
};
|
|
1192
1276
|
}
|
|
1193
1277
|
function validateDepositInput(amount, input, payoutInput = validatePayout(input)) {
|
|
@@ -1465,6 +1549,13 @@ function createCashClient(options) {
|
|
|
1465
1549
|
...options.relay ? { relay: options.relay } : {}
|
|
1466
1550
|
});
|
|
1467
1551
|
},
|
|
1552
|
+
async fillStats() {
|
|
1553
|
+
try {
|
|
1554
|
+
return await readFillStats(readClient, environment);
|
|
1555
|
+
} catch (err) {
|
|
1556
|
+
throw errors.indexerUnavailable("fill stats", err);
|
|
1557
|
+
}
|
|
1558
|
+
},
|
|
1468
1559
|
async cashout(input, opts) {
|
|
1469
1560
|
const client = await signingClient("cashout", opts);
|
|
1470
1561
|
const owner = opts.signer.account.address;
|
|
@@ -2064,6 +2155,11 @@ var cashEstimateJsonSchema = z.object({
|
|
|
2064
2155
|
label: z.string()
|
|
2065
2156
|
}).optional()
|
|
2066
2157
|
});
|
|
2158
|
+
var cashPairFillStatsJsonSchema = z.object({
|
|
2159
|
+
fills: z.number().int().nonnegative(),
|
|
2160
|
+
medianFillSeconds: z.number().int().nonnegative().optional()
|
|
2161
|
+
}).strict();
|
|
2162
|
+
var cashFillStatsJsonSchema = z.record(z.string(), cashPairFillStatsJsonSchema);
|
|
2067
2163
|
var preparedTransactionJsonSchema = z.object({
|
|
2068
2164
|
to: z.string(),
|
|
2069
2165
|
data: z.string(),
|
|
@@ -2368,6 +2464,21 @@ function estimateFromJson(json) {
|
|
|
2368
2464
|
} : void 0
|
|
2369
2465
|
});
|
|
2370
2466
|
}
|
|
2467
|
+
function fillStatsToJson(stats) {
|
|
2468
|
+
return cashFillStatsJsonSchema.parse(stats);
|
|
2469
|
+
}
|
|
2470
|
+
function fillStatsFromJson(json) {
|
|
2471
|
+
const parsed = cashFillStatsJsonSchema.parse(json);
|
|
2472
|
+
return Object.fromEntries(
|
|
2473
|
+
Object.entries(parsed).map(([pair, stats]) => [
|
|
2474
|
+
pair,
|
|
2475
|
+
{
|
|
2476
|
+
fills: stats.fills,
|
|
2477
|
+
...stats.medianFillSeconds !== void 0 ? { medianFillSeconds: stats.medianFillSeconds } : {}
|
|
2478
|
+
}
|
|
2479
|
+
])
|
|
2480
|
+
);
|
|
2481
|
+
}
|
|
2371
2482
|
function cashAssetFromJson(asset) {
|
|
2372
2483
|
return {
|
|
2373
2484
|
chainId: asset.chainId,
|
|
@@ -2645,4 +2756,4 @@ function cashErrorFromJson(json) {
|
|
|
2645
2756
|
});
|
|
2646
2757
|
}
|
|
2647
2758
|
|
|
2648
|
-
export { CASH_ATTRIBUTION_CODE, MIN_CASHOUT_AMOUNT, RATE_PRECISION, RECOMMENDED_MIN_CASHOUT_AMOUNT, bigintString, buildCapabilities, buildIntentAmountRange, buildMarketRateCurrencyOverride, buyerProfileFromJson, buyerProfileToJson, capabilitiesFromJson, capabilitiesToJson, cashAssetJsonSchema, cashBuyerProfileJsonSchema, cashCapabilitiesJsonSchema, cashChainJsonSchema, cashErrorFromJson, cashErrorJsonSchema, cashErrorRecoveryJsonSchema, cashErrorToJson, cashEstimateJsonSchema, cashFillJsonSchema, cashNextActionSchema, cashOrderJsonSchema, cashOrderStateSchema, cashPayoutInfoJsonSchema, cashPayoutPricingJsonSchema, cashPreparedStepJsonSchema, cashSourceCapabilitiesJsonSchema, cashoutResultFromJson, cashoutResultJsonSchema, cashoutResultToJson, centsToNumber, createCashClient, deriveBuyerProfile, deriveCashOrder, derivePayouts, estimateFromJson, estimateToJson, explainOrder, fiatFromUsdc, fiatToNumber, fillFromJson, fillToJson, formatUsdc, intentStatusSchema, isFillLive, isMarketRateSupported, nonNegativeBigintString, orderFromJson, orderToJson, parseCompositeDepositId, prepareCashDepositParams, prepareResultFromJson, prepareResultJsonSchema, prepareResultToJson, preparedStepFromJson, preparedStepToJson, preparedTransactionJsonSchema, preparedTxFromJson, preparedTxToJson, rateToNumber, relayExecutionResultFromJson, relayExecutionResultJsonSchema, relayExecutionResultToJson, relayQuoteFromJson, relayQuoteJsonSchema, relayQuoteToJson, relayStatusFromJson, relayStatusJsonSchema, relayStatusToJson, relayTransactionJsonSchema, relayTransactionsJsonSchema, resolveCashDepositId, sourceCapabilitiesFromJson, sourceCapabilitiesToJson, topUpResultFromJson, topUpResultJsonSchema, topUpResultToJson, usdc, withExplain, withdrawResultFromJson, withdrawResultJsonSchema, withdrawResultToJson };
|
|
2759
|
+
export { CASH_ATTRIBUTION_CODE, MIN_CASHOUT_AMOUNT, RATE_PRECISION, RECOMMENDED_MIN_CASHOUT_AMOUNT, bigintString, buildCapabilities, buildIntentAmountRange, buildMarketRateCurrencyOverride, buyerProfileFromJson, buyerProfileToJson, capabilitiesFromJson, capabilitiesToJson, cashAssetJsonSchema, cashBuyerProfileJsonSchema, cashCapabilitiesJsonSchema, cashChainJsonSchema, cashErrorFromJson, cashErrorJsonSchema, cashErrorRecoveryJsonSchema, cashErrorToJson, cashEstimateJsonSchema, cashFillJsonSchema, cashFillStatsJsonSchema, cashNextActionSchema, cashOrderJsonSchema, cashOrderStateSchema, cashPairFillStatsJsonSchema, cashPayoutInfoJsonSchema, cashPayoutPricingJsonSchema, cashPreparedStepJsonSchema, cashSourceCapabilitiesJsonSchema, cashoutResultFromJson, cashoutResultJsonSchema, cashoutResultToJson, centsToNumber, createCashClient, deriveBuyerProfile, deriveCashOrder, derivePayouts, estimateFromJson, estimateToJson, explainOrder, fiatFromUsdc, fiatToNumber, fillFromJson, fillStatsFromJson, fillStatsToJson, fillToJson, formatUsdc, intentStatusSchema, isFillLive, isMarketRateSupported, nonNegativeBigintString, orderFromJson, orderToJson, parseCompositeDepositId, prepareCashDepositParams, prepareResultFromJson, prepareResultJsonSchema, prepareResultToJson, preparedStepFromJson, preparedStepToJson, preparedTransactionJsonSchema, preparedTxFromJson, preparedTxToJson, rateToNumber, relayExecutionResultFromJson, relayExecutionResultJsonSchema, relayExecutionResultToJson, relayQuoteFromJson, relayQuoteJsonSchema, relayQuoteToJson, relayStatusFromJson, relayStatusJsonSchema, relayStatusToJson, relayTransactionJsonSchema, relayTransactionsJsonSchema, resolveCashDepositId, sourceCapabilitiesFromJson, sourceCapabilitiesToJson, topUpResultFromJson, topUpResultJsonSchema, topUpResultToJson, usdc, withExplain, withdrawResultFromJson, withdrawResultJsonSchema, withdrawResultToJson };
|
package/dist/react.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CurrencyType } from '@zkp2p/sdk';
|
|
2
|
-
import {
|
|
2
|
+
import { r as CashClient, G as EstimateInput, i as CashEstimate, E as CashoutOptions, h as CashoutResult, D as CashoutInput, T as TopUpResult, W as WithdrawResult, e as CashOrder } from './createCashClient-BIzOLHjF.cjs';
|
|
3
3
|
import { WalletClient } from 'viem';
|
|
4
4
|
import '@relayprotocol/relay-sdk';
|
|
5
5
|
|
package/dist/react.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CurrencyType } from '@zkp2p/sdk';
|
|
2
|
-
import {
|
|
2
|
+
import { r as CashClient, G as EstimateInput, i as CashEstimate, E as CashoutOptions, h as CashoutResult, D as CashoutInput, T as TopUpResult, W as WithdrawResult, e as CashOrder } from './createCashClient-BIzOLHjF.js';
|
|
3
3
|
import { WalletClient } from 'viem';
|
|
4
4
|
import '@relayprotocol/relay-sdk';
|
|
5
5
|
|
package/dist/tools.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// package.json
|
|
4
4
|
var package_default = {
|
|
5
|
-
version: "0.1.
|
|
5
|
+
version: "0.1.8"};
|
|
6
6
|
|
|
7
7
|
// src/tools/index.ts
|
|
8
8
|
var bigintString = {
|
|
@@ -112,6 +112,15 @@ var builtInCashTools = [
|
|
|
112
112
|
additionalProperties: false
|
|
113
113
|
}
|
|
114
114
|
},
|
|
115
|
+
{
|
|
116
|
+
name: "cash_fill_stats",
|
|
117
|
+
description: "Read raw 30-day demand and first-fill speed evidence for every observed platform:currency pair. Consumers should apply their own threshold and fail open to cash_capabilities when stats are unavailable or filtering would empty the catalog.",
|
|
118
|
+
inputSchema: {
|
|
119
|
+
type: "object",
|
|
120
|
+
properties: {},
|
|
121
|
+
additionalProperties: false
|
|
122
|
+
}
|
|
123
|
+
},
|
|
115
124
|
{
|
|
116
125
|
name: "cash_cashout",
|
|
117
126
|
description: "Start a Base-USDC cash-out using the custody-separated prepare path. Returns UNSIGNED transactions plus same-index steps [approve, createDeposit]; signing and ordered submission stay host-side. For another source asset, complete cash_source_quote and cash_source_status first, then pass the guaranteed Base USDC output amount here.",
|
package/dist/tools.d.cts
CHANGED
|
@@ -135,6 +135,14 @@ declare const builtInCashTools: readonly [{
|
|
|
135
135
|
readonly required: readonly ["amount", "currency"];
|
|
136
136
|
readonly additionalProperties: false;
|
|
137
137
|
};
|
|
138
|
+
}, {
|
|
139
|
+
readonly name: "cash_fill_stats";
|
|
140
|
+
readonly description: "Read raw 30-day demand and first-fill speed evidence for every observed platform:currency pair. Consumers should apply their own threshold and fail open to cash_capabilities when stats are unavailable or filtering would empty the catalog.";
|
|
141
|
+
readonly inputSchema: {
|
|
142
|
+
readonly type: "object";
|
|
143
|
+
readonly properties: {};
|
|
144
|
+
readonly additionalProperties: false;
|
|
145
|
+
};
|
|
138
146
|
}, {
|
|
139
147
|
readonly name: "cash_cashout";
|
|
140
148
|
readonly description: "Start a Base-USDC cash-out using the custody-separated prepare path. Returns UNSIGNED transactions plus same-index steps [approve, createDeposit]; signing and ordered submission stay host-side. For another source asset, complete cash_source_quote and cash_source_status first, then pass the guaranteed Base USDC output amount here.";
|
package/dist/tools.d.ts
CHANGED
|
@@ -135,6 +135,14 @@ declare const builtInCashTools: readonly [{
|
|
|
135
135
|
readonly required: readonly ["amount", "currency"];
|
|
136
136
|
readonly additionalProperties: false;
|
|
137
137
|
};
|
|
138
|
+
}, {
|
|
139
|
+
readonly name: "cash_fill_stats";
|
|
140
|
+
readonly description: "Read raw 30-day demand and first-fill speed evidence for every observed platform:currency pair. Consumers should apply their own threshold and fail open to cash_capabilities when stats are unavailable or filtering would empty the catalog.";
|
|
141
|
+
readonly inputSchema: {
|
|
142
|
+
readonly type: "object";
|
|
143
|
+
readonly properties: {};
|
|
144
|
+
readonly additionalProperties: false;
|
|
145
|
+
};
|
|
138
146
|
}, {
|
|
139
147
|
readonly name: "cash_cashout";
|
|
140
148
|
readonly description: "Start a Base-USDC cash-out using the custody-separated prepare path. Returns UNSIGNED transactions plus same-index steps [approve, createDeposit]; signing and ordered submission stay host-side. For another source asset, complete cash_source_quote and cash_source_status first, then pass the guaranteed Base USDC output amount here.";
|
package/dist/tools.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
|
-
version: "0.1.
|
|
3
|
+
version: "0.1.8"};
|
|
4
4
|
|
|
5
5
|
// src/tools/index.ts
|
|
6
6
|
var bigintString = {
|
|
@@ -110,6 +110,15 @@ var builtInCashTools = [
|
|
|
110
110
|
additionalProperties: false
|
|
111
111
|
}
|
|
112
112
|
},
|
|
113
|
+
{
|
|
114
|
+
name: "cash_fill_stats",
|
|
115
|
+
description: "Read raw 30-day demand and first-fill speed evidence for every observed platform:currency pair. Consumers should apply their own threshold and fail open to cash_capabilities when stats are unavailable or filtering would empty the catalog.",
|
|
116
|
+
inputSchema: {
|
|
117
|
+
type: "object",
|
|
118
|
+
properties: {},
|
|
119
|
+
additionalProperties: false
|
|
120
|
+
}
|
|
121
|
+
},
|
|
113
122
|
{
|
|
114
123
|
name: "cash_cashout",
|
|
115
124
|
description: "Start a Base-USDC cash-out using the custody-separated prepare path. Returns UNSIGNED transactions plus same-index steps [approve, createDeposit]; signing and ordered submission stay host-side. For another source asset, complete cash_source_quote and cash_source_status first, then pass the guaranteed Base USDC output amount here.",
|
|
@@ -124,10 +124,17 @@ passes through `delivering` until the last one completes. `filledAmount`,
|
|
|
124
124
|
## The ETA principle
|
|
125
125
|
|
|
126
126
|
`estimate().eta` is historical, not a promise. It uses rolling 30-day indexer
|
|
127
|
-
data from deposit/order creation to the first fulfilled fill
|
|
128
|
-
|
|
129
|
-
buyer
|
|
130
|
-
`{ seconds, label }`.
|
|
127
|
+
data from deposit/order creation to the first fulfilled fill through the
|
|
128
|
+
intent's actual platform and currency pair. It deliberately does **not**
|
|
129
|
+
measure buyer signal to fulfillment; that would miss the buyer-arrival wait
|
|
130
|
+
that users actually care about. The public shape is small: `{ seconds, label }`.
|
|
131
|
+
|
|
132
|
+
`fillStats()` exposes the sampler's raw evidence for catalog filtering as
|
|
133
|
+
`Record<"platform:currency", { fills, medianFillSeconds? }>`. Bank-scoped Zelle
|
|
134
|
+
methods aggregate to `zelle:USD`. Consumers own thresholding; the recommended
|
|
135
|
+
gate is `fills >= 10 && medianFillSeconds <= 48h`, with a fail-open fallback to
|
|
136
|
+
the full capability catalog when the read fails or filtering would empty it.
|
|
137
|
+
Medians are per-deposit first-fill latencies, never means or censored cohorts.
|
|
131
138
|
|
|
132
139
|
- **Buyer arrival time is market-driven.** A deposit at market rate should
|
|
133
140
|
fill fast, but the ETA is only a recent historical sample.
|
package/llms.txt
CHANGED
|
@@ -19,9 +19,13 @@ Key facts:
|
|
|
19
19
|
source.amount is Relay's guaranteed minimum Base USDC output and the exact
|
|
20
20
|
order deposit amount, not the route's actual output.
|
|
21
21
|
- There is NO locked fiat quote. estimate() reads the oracle; the binding rate
|
|
22
|
-
resolves at fill time. ETA is `{ seconds, label }` from rolling
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
resolves at fill time. ETA is `{ seconds, label }` from the same rolling
|
|
23
|
+
30-day, intent-attributed pair sampler as fillStats(), not a guarantee.
|
|
24
|
+
- fillStats() returns raw `{ fills, medianFillSeconds? }` evidence keyed by
|
|
25
|
+
`platform:currency`. Recommended consumer gate: fills >= 10 and median <=
|
|
26
|
+
48h; fail open to capabilities() if unavailable or filtering empties it.
|
|
27
|
+
- capabilities() exposes one Zelle platform. A zelle cashout internally attaches
|
|
28
|
+
the generic method plus Chase, Bank of America, and Citi buyer routes.
|
|
25
29
|
- Resume any order from its depositId alone (composite escrow_onchainId).
|
|
26
30
|
- One unwind verb: withdraw(depositId) - prunes expired intents automatically;
|
|
27
31
|
pass amount for a partial withdrawal of the unlocked balance.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zkp2p/cash",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Peer Cash - offramp-only SDK for routing crypto to Base USDC, then cashing out to fiat at the live oracle market rate.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Peer (https://peer.xyz)",
|
|
@@ -92,13 +92,15 @@
|
|
|
92
92
|
"scripts": {
|
|
93
93
|
"build": "tsup",
|
|
94
94
|
"typecheck": "tsc --noEmit",
|
|
95
|
-
"lint": "eslint src test examples",
|
|
95
|
+
"lint": "eslint src test examples scripts",
|
|
96
96
|
"format": "prettier --write .",
|
|
97
97
|
"format:check": "prettier --check .",
|
|
98
98
|
"test": "vitest run",
|
|
99
99
|
"test:watch": "vitest",
|
|
100
100
|
"audit": "bun audit --production",
|
|
101
101
|
"pack:check": "bun scripts/check-packed-package.ts",
|
|
102
|
+
"verify:production-crosschain-relay": "bun scripts/verify-production-crosschain-relay.ts",
|
|
103
|
+
"verify:production-maker": "bun scripts/verify-production-maker.ts",
|
|
102
104
|
"prepack": "bun run build",
|
|
103
105
|
"ci": "bun run typecheck && bun run lint && bun run format:check && bun run test && bun run audit && bun run build && bun run pack:check"
|
|
104
106
|
},
|