@zkp2p/cash 0.1.8 → 0.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/AGENTS.md +6 -1
- package/README.md +20 -5
- package/dist/{createCashClient-BIzOLHjF.d.cts → createCashClient-CTEXn9FF.d.cts} +12 -5
- package/dist/{createCashClient-BIzOLHjF.d.ts → createCashClient-CTEXn9FF.d.ts} +12 -5
- package/dist/index.cjs +70 -61
- package/dist/index.d.cts +22 -20
- package/dist/index.d.ts +22 -20
- package/dist/index.js +70 -61
- package/dist/react.cjs +14 -10
- package/dist/react.d.cts +4 -2
- package/dist/react.d.ts +4 -2
- package/dist/react.js +14 -10
- package/dist/tools.cjs +1 -1
- package/dist/tools.js +1 -1
- package/docs/lifecycle-and-recovery.md +12 -2
- package/llms.txt +9 -2
- package/package.json +2 -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
|
+
// Progressive UI: do not let indexer-backed history hold up the oracle rate.
|
|
58
|
+
const rateOnly = await cash.estimate({ amount: usdc(500), currency: 'EUR' }, { includeEta: false });
|
|
59
|
+
|
|
57
60
|
// Optional: raw demand + speed evidence per offered platform:currency pair.
|
|
58
61
|
const stats = await cash.fillStats();
|
|
59
62
|
|
|
@@ -106,7 +109,9 @@ console.log(routed.source?.transactions?.origin, routed.source?.transactions?.de
|
|
|
106
109
|
- **Do not invent an ETA.** Use `estimate().eta`: `{ seconds, label }` backed
|
|
107
110
|
by the same rolling 30-day, intent-attributed pair sample as `fillStats()`,
|
|
108
111
|
measured from deposit creation to first fill. Use `order.explain()` for live
|
|
109
|
-
order state.
|
|
112
|
+
order state. For progressive UIs, call `estimate(..., { includeEta: false })`
|
|
113
|
+
and load `fillStats()["platform:CURRENCY"]` separately. The SDK caches the
|
|
114
|
+
raw snapshot for 15 minutes, but never substitutes another pair's data.
|
|
110
115
|
- **Do not hardcode Relay source assets.** Use Relay SDK-backed EVM
|
|
111
116
|
`capabilities({ includeRelaySources: true })` and `cashout({ source, ... })`.
|
|
112
117
|
Destination is always Base USDC. Non-Base source chains require
|
package/README.md
CHANGED
|
@@ -34,6 +34,13 @@ const est = await cash.estimate({ amount: usdc(1000), currency: 'USD' });
|
|
|
34
34
|
// { rate: 1, receiveAmount: 1000, kind: 'oracle-estimate', eta: { seconds, label } }
|
|
35
35
|
// "≈", never a locked quote. Base USDC remains the default source.
|
|
36
36
|
|
|
37
|
+
// Progressive UI: render rate/receive first, then resolve the exact pair ETA.
|
|
38
|
+
const rateOnly = await cash.estimate(
|
|
39
|
+
{ amount: usdc(1000), currency: 'USD' },
|
|
40
|
+
{ includeEta: false },
|
|
41
|
+
);
|
|
42
|
+
const pairStats = (await cash.fillStats())['venmo:USD'];
|
|
43
|
+
|
|
37
44
|
const { depositId } = await cash.cashout(
|
|
38
45
|
{
|
|
39
46
|
amount: usdc(1000),
|
|
@@ -76,10 +83,10 @@ console.log(source?.transactions?.origin, source?.transactions?.destination);
|
|
|
76
83
|
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
|
77
84
|
| `capabilities()` | Sync discovery: Base USDC destination/default source, platforms × currencies × payee hints × amount bounds |
|
|
78
85
|
| `capabilities({ includeRelaySources: true })` | Async discovery: adds live Relay SDK EVM source chains/tokens |
|
|
79
|
-
| `fillStats()` |
|
|
86
|
+
| `fillStats()` | Cached 30-day fill counts and median first-fill time per exact `platform:currency` pair |
|
|
80
87
|
| `quoteSource(input)` / `executeSourceQuote(quote, { signer })` | Relay SDK EVM source routing into Base USDC before cashout |
|
|
81
88
|
| `relayStatus(requestId)` | Relay request status from the Relay SDK request path |
|
|
82
|
-
| `estimate({ amount, currency })`
|
|
89
|
+
| `estimate({ amount, currency }, { includeEta? })` | Base USDC oracle estimate; optionally skip the historical ETA for progressive rendering |
|
|
83
90
|
| `cashout(input, { signer })` | Registers your payee, creates the protocol-held order, returns the `depositId` |
|
|
84
91
|
| `order(depositId)` / `orders(owner)` | Resume any order from its id alone; list all orders for a wallet |
|
|
85
92
|
| `watch(depositId)` | Async iterator: yields on every state change until terminal, abort, or timeout |
|
|
@@ -99,9 +106,14 @@ cashout. Every Peer Cash transaction, including approves, carries ERC-8021
|
|
|
99
106
|
attribution: `peer-cash` first, your own `referrer` code(s) after it.
|
|
100
107
|
|
|
101
108
|
`capabilities()` presents Zelle as one platform. A cashout with
|
|
102
|
-
`receive.platform: 'zelle'`
|
|
103
|
-
|
|
104
|
-
|
|
109
|
+
`receive.platform: 'zelle'` attaches only the generic Zelle payment method to
|
|
110
|
+
the deposit. Bank-specific capture routing is outside this maker-side SDK and
|
|
111
|
+
never changes the on-chain payment method.
|
|
112
|
+
|
|
113
|
+
Order reads fail closed against the same active catalog. If any method on an
|
|
114
|
+
indexed deposit is unsupported, `orders()` excludes the whole deposit and
|
|
115
|
+
`order()` returns `ORDER_NOT_FOUND`; Peer Cash never partially reclassifies a
|
|
116
|
+
mixed historical deposit.
|
|
105
117
|
|
|
106
118
|
The default/minimal flow is unchanged: pass Base USDC base units to
|
|
107
119
|
`estimate()` and `cashout()`. For any other source asset, pass `source` to
|
|
@@ -180,6 +192,9 @@ awaiting-buyer ──────────► matched ───────
|
|
|
180
192
|
- **ETA is historical.** `estimate().eta` is just `{ seconds, label }`, backed
|
|
181
193
|
by the same rolling 30-day, intent-attributed pair sampler as `fillStats()`,
|
|
182
194
|
measured from deposit creation to the first fulfilled fill through the pair.
|
|
195
|
+
The raw snapshot is cached for 15 minutes per client and each ETA is still
|
|
196
|
+
resolved from its exact normalized `platform:currency` key. Use
|
|
197
|
+
`{ includeEta: false }` when rate and receive amount should render first.
|
|
183
198
|
- **Availability thresholds belong to the consumer.** `fillStats()` returns raw
|
|
184
199
|
evidence. A recommended gate is `fills >= 10 && medianFillSeconds <= 48h`.
|
|
185
200
|
Fail open to the full `capabilities()` catalog when stats are unavailable or
|
|
@@ -3,7 +3,7 @@ import { IndexerIntentStatus, Zkp2pClient, IndexerIntent, CurrencyType, Prepared
|
|
|
3
3
|
import { Execute, RelayClient, RelayChain, ProgressData } from '@relayprotocol/relay-sdk';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Name-mapping shim over the published `@zkp2p/sdk` (^0.
|
|
6
|
+
* Name-mapping shim over the published `@zkp2p/sdk` (^0.9).
|
|
7
7
|
*
|
|
8
8
|
* The reference implementation imported these from internal SDK paths; the
|
|
9
9
|
* published package exports them under indexer-prefixed names, and one type
|
|
@@ -97,8 +97,8 @@ interface CashPayoutPricing {
|
|
|
97
97
|
}
|
|
98
98
|
/** One payout leg reconstructed from the chain - platform, currency, payee hash, pricing. */
|
|
99
99
|
interface CashPayoutInfo {
|
|
100
|
-
/** Decoded platform id, e.g. `'venmo'
|
|
101
|
-
platform
|
|
100
|
+
/** Decoded active platform id, e.g. `'venmo'`. */
|
|
101
|
+
platform: string;
|
|
102
102
|
/** Raw payment method hash (bytes32). */
|
|
103
103
|
platformHash: string;
|
|
104
104
|
/** Decoded fiat currency code, e.g. `'USD'`. */
|
|
@@ -401,6 +401,13 @@ interface EstimateInput {
|
|
|
401
401
|
tradeType?: 'EXACT_INPUT' | 'EXACT_OUTPUT' | 'EXPECTED_OUTPUT';
|
|
402
402
|
};
|
|
403
403
|
}
|
|
404
|
+
interface EstimateOptions {
|
|
405
|
+
/**
|
|
406
|
+
* Include the historical indexer-backed ETA. Disable for progressive UIs
|
|
407
|
+
* that render the oracle rate first and load pair fill stats separately.
|
|
408
|
+
*/
|
|
409
|
+
includeEta?: boolean;
|
|
410
|
+
}
|
|
404
411
|
interface CashEstimate {
|
|
405
412
|
/** Always `'oracle-estimate'` - there is no committed quote in Peer Cash. */
|
|
406
413
|
kind: 'oracle-estimate';
|
|
@@ -612,7 +619,7 @@ interface CashClient {
|
|
|
612
619
|
/** Track Relay execution status by quote/request id. */
|
|
613
620
|
relayStatus(requestId: string): Promise<RelayStatus>;
|
|
614
621
|
/** 1 - Estimate: currency + amount only. No payee, no side effects, no expiry. */
|
|
615
|
-
estimate(input: EstimateInput): Promise<CashEstimate>;
|
|
622
|
+
estimate(input: EstimateInput, options?: EstimateOptions): Promise<CashEstimate>;
|
|
616
623
|
/** 2 - Cash out: payee registration + deposit params + submission happen here. */
|
|
617
624
|
cashout(input: CashoutInput, opts: CashoutOptions): Promise<CashoutResult>;
|
|
618
625
|
/** 2b - Unsigned path: `txs[]` for agent wallets, AA, server keys, policy layers. */
|
|
@@ -655,4 +662,4 @@ interface CashClient {
|
|
|
655
662
|
}
|
|
656
663
|
declare function createCashClient(options: CashClientOptions): CashClient;
|
|
657
664
|
|
|
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,
|
|
665
|
+
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, type EstimateOptions as H, type IntentStatus as I, RECOMMENDED_MIN_CASHOUT_AMOUNT as J, type RelayOptions as K, type RelayQuoteInput as L, MIN_CASHOUT_AMOUNT as M, type RelaySourceInput as N, type OrdersOptions as O, type PrepareResult as P, type RelayTransaction as Q, type RelayExecutionResult as R, type SignerOptions as S, type TopUpResult as T, type WatchOptions as U, type WithdrawOptions as V, type WithdrawResult as W, buildCapabilities as X, createCashClient as Y, 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 };
|
|
@@ -3,7 +3,7 @@ import { IndexerIntentStatus, Zkp2pClient, IndexerIntent, CurrencyType, Prepared
|
|
|
3
3
|
import { Execute, RelayClient, RelayChain, ProgressData } from '@relayprotocol/relay-sdk';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Name-mapping shim over the published `@zkp2p/sdk` (^0.
|
|
6
|
+
* Name-mapping shim over the published `@zkp2p/sdk` (^0.9).
|
|
7
7
|
*
|
|
8
8
|
* The reference implementation imported these from internal SDK paths; the
|
|
9
9
|
* published package exports them under indexer-prefixed names, and one type
|
|
@@ -97,8 +97,8 @@ interface CashPayoutPricing {
|
|
|
97
97
|
}
|
|
98
98
|
/** One payout leg reconstructed from the chain - platform, currency, payee hash, pricing. */
|
|
99
99
|
interface CashPayoutInfo {
|
|
100
|
-
/** Decoded platform id, e.g. `'venmo'
|
|
101
|
-
platform
|
|
100
|
+
/** Decoded active platform id, e.g. `'venmo'`. */
|
|
101
|
+
platform: string;
|
|
102
102
|
/** Raw payment method hash (bytes32). */
|
|
103
103
|
platformHash: string;
|
|
104
104
|
/** Decoded fiat currency code, e.g. `'USD'`. */
|
|
@@ -401,6 +401,13 @@ interface EstimateInput {
|
|
|
401
401
|
tradeType?: 'EXACT_INPUT' | 'EXACT_OUTPUT' | 'EXPECTED_OUTPUT';
|
|
402
402
|
};
|
|
403
403
|
}
|
|
404
|
+
interface EstimateOptions {
|
|
405
|
+
/**
|
|
406
|
+
* Include the historical indexer-backed ETA. Disable for progressive UIs
|
|
407
|
+
* that render the oracle rate first and load pair fill stats separately.
|
|
408
|
+
*/
|
|
409
|
+
includeEta?: boolean;
|
|
410
|
+
}
|
|
404
411
|
interface CashEstimate {
|
|
405
412
|
/** Always `'oracle-estimate'` - there is no committed quote in Peer Cash. */
|
|
406
413
|
kind: 'oracle-estimate';
|
|
@@ -612,7 +619,7 @@ interface CashClient {
|
|
|
612
619
|
/** Track Relay execution status by quote/request id. */
|
|
613
620
|
relayStatus(requestId: string): Promise<RelayStatus>;
|
|
614
621
|
/** 1 - Estimate: currency + amount only. No payee, no side effects, no expiry. */
|
|
615
|
-
estimate(input: EstimateInput): Promise<CashEstimate>;
|
|
622
|
+
estimate(input: EstimateInput, options?: EstimateOptions): Promise<CashEstimate>;
|
|
616
623
|
/** 2 - Cash out: payee registration + deposit params + submission happen here. */
|
|
617
624
|
cashout(input: CashoutInput, opts: CashoutOptions): Promise<CashoutResult>;
|
|
618
625
|
/** 2b - Unsigned path: `txs[]` for agent wallets, AA, server keys, policy layers. */
|
|
@@ -655,4 +662,4 @@ interface CashClient {
|
|
|
655
662
|
}
|
|
656
663
|
declare function createCashClient(options: CashClientOptions): CashClient;
|
|
657
664
|
|
|
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,
|
|
665
|
+
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, type EstimateOptions as H, type IntentStatus as I, RECOMMENDED_MIN_CASHOUT_AMOUNT as J, type RelayOptions as K, type RelayQuoteInput as L, MIN_CASHOUT_AMOUNT as M, type RelaySourceInput as N, type OrdersOptions as O, type PrepareResult as P, type RelayTransaction as Q, type RelayExecutionResult as R, type SignerOptions as S, type TopUpResult as T, type WatchOptions as U, type WithdrawOptions as V, type WithdrawResult as W, buildCapabilities as X, createCashClient as Y, 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
|
@@ -303,35 +303,41 @@ function toPricing(tuple) {
|
|
|
303
303
|
};
|
|
304
304
|
}
|
|
305
305
|
function derivePayouts(paymentMethods, currencies, catalog) {
|
|
306
|
-
|
|
306
|
+
const payouts = [];
|
|
307
|
+
for (const method of paymentMethods) {
|
|
307
308
|
const platformHash = method.paymentMethodHash ?? "";
|
|
308
309
|
if (!platformHash) return [];
|
|
309
310
|
let platform;
|
|
310
311
|
try {
|
|
311
312
|
platform = sdk.resolvePaymentMethodNameFromHash(platformHash, catalog);
|
|
312
313
|
} catch {
|
|
313
|
-
|
|
314
|
+
return [];
|
|
314
315
|
}
|
|
316
|
+
if (!platform) return [];
|
|
315
317
|
const tuples = currencies.filter(
|
|
316
318
|
(c) => (c.paymentMethodHash ?? "").toLowerCase() === platformHash.toLowerCase()
|
|
317
319
|
);
|
|
318
320
|
const base2 = {
|
|
319
|
-
|
|
321
|
+
platform,
|
|
320
322
|
platformHash,
|
|
321
323
|
payeeHash: method.payeeDetailsHash ?? "",
|
|
322
324
|
active: method.active ?? true
|
|
323
325
|
};
|
|
324
|
-
if (tuples.length === 0)
|
|
325
|
-
|
|
326
|
+
if (tuples.length === 0) {
|
|
327
|
+
payouts.push({ ...base2, pricing: toPricing(void 0) });
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
for (const tuple of tuples) {
|
|
326
331
|
const currency = tuple.currencyCode != null ? sdk.getCurrencyCodeFromHash(tuple.currencyCode) : void 0;
|
|
327
|
-
|
|
332
|
+
payouts.push({
|
|
328
333
|
...base2,
|
|
329
334
|
...currency !== void 0 ? { currency } : {},
|
|
330
335
|
...tuple.currencyCode != null ? { currencyHash: tuple.currencyCode } : {},
|
|
331
336
|
pricing: toPricing(tuple)
|
|
332
|
-
};
|
|
333
|
-
}
|
|
334
|
-
}
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return payouts;
|
|
335
341
|
}
|
|
336
342
|
|
|
337
343
|
// src/engine/buyerProfile.ts
|
|
@@ -403,26 +409,6 @@ function parseCompositeDepositId(compositeId) {
|
|
|
403
409
|
const onchainDepositId = BigInt(rawDepositId);
|
|
404
410
|
return { escrowAddress: canonicalEscrowAddress, onchainDepositId };
|
|
405
411
|
}
|
|
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
|
|
426
412
|
var MIN_CASHOUT_AMOUNT = 10000n;
|
|
427
413
|
var RECOMMENDED_MIN_CASHOUT_AMOUNT = 1000000n;
|
|
428
414
|
var PAYEE_HINTS = {
|
|
@@ -441,20 +427,13 @@ var PAYEE_HINTS = {
|
|
|
441
427
|
var IDENTITY_ATTESTATION_PLATFORMS = /* @__PURE__ */ new Set(["wise", "paypal"]);
|
|
442
428
|
function buildCapabilities(environment) {
|
|
443
429
|
const catalog = sdk.getPaymentMethodsCatalog(BASE_CHAIN_ID, environment);
|
|
444
|
-
const
|
|
445
|
-
for (const [method, entry] of Object.entries(catalog)) {
|
|
446
|
-
const platform = basePlatformForMethod(method);
|
|
430
|
+
const platforms = Object.entries(catalog).map(([platform, entry]) => {
|
|
447
431
|
const currencies2 = (entry.currencies ?? []).map((hash) => sdk.getCurrencyCodeFromHash(hash)).filter(
|
|
448
432
|
(code) => code != null && isMarketRateSupported(code)
|
|
449
433
|
);
|
|
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]) => {
|
|
455
434
|
return {
|
|
456
435
|
platform,
|
|
457
|
-
currencies: [...currencies2].sort(),
|
|
436
|
+
currencies: [...new Set(currencies2)].sort(),
|
|
458
437
|
payeeHint: PAYEE_HINTS[platform] ?? "Your payment handle for this platform",
|
|
459
438
|
requiresIdentityAttestation: IDENTITY_ATTESTATION_PLATFORMS.has(platform)
|
|
460
439
|
};
|
|
@@ -896,7 +875,7 @@ function computeFillStatsSample(deposits, nowSeconds, environment) {
|
|
|
896
875
|
}
|
|
897
876
|
const currency = normalizeCurrencyCode(intent.fiatCurrency);
|
|
898
877
|
if (!method || !currency) continue;
|
|
899
|
-
const pair = `${
|
|
878
|
+
const pair = `${method}:${currency}`;
|
|
900
879
|
fillCounts.set(pair, (fillCounts.get(pair) ?? 0) + 1);
|
|
901
880
|
if (createdAt === void 0 || createdAt < windowStart || fulfilledAt < createdAt) continue;
|
|
902
881
|
const previousPairFill = firstFillByPair.get(pair);
|
|
@@ -959,18 +938,18 @@ async function readFillStatsSample(client, environment) {
|
|
|
959
938
|
}
|
|
960
939
|
return computeFillStatsSample(deposits, now, environment);
|
|
961
940
|
}
|
|
962
|
-
|
|
963
|
-
return (await readFillStatsSample(client, environment)).stats;
|
|
964
|
-
}
|
|
965
|
-
async function readFillEta(client, input) {
|
|
966
|
-
const sample = await readFillStatsSample(client, input.environment);
|
|
941
|
+
function fillEtaFromSample(sample, input) {
|
|
967
942
|
const currency = input.currency.toUpperCase();
|
|
968
|
-
const seconds = input.platform ? sample.stats[`${
|
|
943
|
+
const seconds = input.platform ? sample.stats[`${input.platform}:${currency}`]?.medianFillSeconds : sample.medianFillSecondsByCurrency.get(currency);
|
|
969
944
|
return {
|
|
970
945
|
...seconds !== void 0 ? { seconds } : {},
|
|
971
946
|
label: etaLabel(seconds)
|
|
972
947
|
};
|
|
973
948
|
}
|
|
949
|
+
async function readFillEta(client, input) {
|
|
950
|
+
const sample = await readFillStatsSample(client, input.environment);
|
|
951
|
+
return fillEtaFromSample(sample, input);
|
|
952
|
+
}
|
|
974
953
|
var RELAY_API_URL = relaySdk.MAINNET_RELAY_API;
|
|
975
954
|
var NATIVE_TOKEN_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
976
955
|
var BASE_USDC_ASSET = {
|
|
@@ -1506,13 +1485,18 @@ async function readEstimate(publicClient, input, context = {}) {
|
|
|
1506
1485
|
}
|
|
1507
1486
|
} : {}
|
|
1508
1487
|
};
|
|
1509
|
-
if (context.
|
|
1488
|
+
if (context.includeEta !== false && context.environment) {
|
|
1510
1489
|
try {
|
|
1511
|
-
|
|
1490
|
+
const etaInput = {
|
|
1512
1491
|
environment: context.environment,
|
|
1513
1492
|
currency,
|
|
1514
1493
|
...input.platform ? { platform: input.platform } : {}
|
|
1515
|
-
}
|
|
1494
|
+
};
|
|
1495
|
+
if (context.etaReader) {
|
|
1496
|
+
estimate.eta = await context.etaReader(etaInput);
|
|
1497
|
+
} else if (context.indexerClient) {
|
|
1498
|
+
estimate.eta = await readFillEta(context.indexerClient, etaInput);
|
|
1499
|
+
}
|
|
1516
1500
|
} catch {
|
|
1517
1501
|
}
|
|
1518
1502
|
}
|
|
@@ -1521,6 +1505,7 @@ async function readEstimate(publicClient, input, context = {}) {
|
|
|
1521
1505
|
|
|
1522
1506
|
// src/client/createCashClient.ts
|
|
1523
1507
|
var DEFAULT_RPC_URL = "https://mainnet.base.org";
|
|
1508
|
+
var FILL_STATS_CACHE_MS = 15 * 60 * 1e3;
|
|
1524
1509
|
var CASH_ATTRIBUTION_CODE = "peer-cash";
|
|
1525
1510
|
var DEFAULT_CURATOR_URLS = {
|
|
1526
1511
|
preproduction: "https://api-preprod.zkp2p.xyz",
|
|
@@ -1619,6 +1604,25 @@ function createCashClient(options) {
|
|
|
1619
1604
|
});
|
|
1620
1605
|
}
|
|
1621
1606
|
const readClient = buildSdkClient(viem.createWalletClient({ chain: chains.base, transport }));
|
|
1607
|
+
let fillStatsCache = null;
|
|
1608
|
+
let fillStatsRequest = null;
|
|
1609
|
+
async function getFillStatsSample() {
|
|
1610
|
+
if (fillStatsCache && fillStatsCache.expiresAt > Date.now()) {
|
|
1611
|
+
return fillStatsCache.sample;
|
|
1612
|
+
}
|
|
1613
|
+
if (fillStatsRequest) return fillStatsRequest;
|
|
1614
|
+
fillStatsRequest = readFillStatsSample(readClient, environment);
|
|
1615
|
+
try {
|
|
1616
|
+
const sample = await fillStatsRequest;
|
|
1617
|
+
fillStatsCache = {
|
|
1618
|
+
sample,
|
|
1619
|
+
expiresAt: Date.now() + FILL_STATS_CACHE_MS
|
|
1620
|
+
};
|
|
1621
|
+
return sample;
|
|
1622
|
+
} finally {
|
|
1623
|
+
fillStatsRequest = null;
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1622
1626
|
const signingClients = /* @__PURE__ */ new WeakMap();
|
|
1623
1627
|
async function signingClient(verb, opts) {
|
|
1624
1628
|
const signer = opts?.signer;
|
|
@@ -1633,7 +1637,6 @@ function createCashClient(options) {
|
|
|
1633
1637
|
}
|
|
1634
1638
|
function validatePayout(input) {
|
|
1635
1639
|
const { receive } = input;
|
|
1636
|
-
const catalog = sdk.getPaymentMethodsCatalog(BASE_CHAIN_ID, environment);
|
|
1637
1640
|
const platform = buildCapabilities(environment).platforms.find(
|
|
1638
1641
|
(capability) => capability.platform === receive.platform
|
|
1639
1642
|
);
|
|
@@ -1644,13 +1647,14 @@ function createCashClient(options) {
|
|
|
1644
1647
|
if (!platform.currencies.includes(receive.currency)) {
|
|
1645
1648
|
throw errors.unsupportedPlatformCurrency(receive.platform, receive.currency);
|
|
1646
1649
|
}
|
|
1647
|
-
const paymentMethods = paymentMethodsForPlatform(receive.platform, catalog);
|
|
1648
1650
|
return {
|
|
1649
|
-
payouts:
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1651
|
+
payouts: [
|
|
1652
|
+
{
|
|
1653
|
+
processorName: receive.platform,
|
|
1654
|
+
currency: receive.currency,
|
|
1655
|
+
payeeData: receive.payee
|
|
1656
|
+
}
|
|
1657
|
+
]
|
|
1654
1658
|
};
|
|
1655
1659
|
}
|
|
1656
1660
|
function validateDepositInput(amount, input, payoutInput = validatePayout(input)) {
|
|
@@ -1667,6 +1671,9 @@ function createCashClient(options) {
|
|
|
1667
1671
|
...range ? { intentAmountRange: range } : {}
|
|
1668
1672
|
};
|
|
1669
1673
|
}
|
|
1674
|
+
function isCashPayoutSet(payouts) {
|
|
1675
|
+
return payouts.length === 1 && payouts.every((payout) => payout.pricing.marketRate && payout.pricing.spreadBps === 0);
|
|
1676
|
+
}
|
|
1670
1677
|
async function buildDepositParams(client, depositInput) {
|
|
1671
1678
|
try {
|
|
1672
1679
|
return await prepareCashDepositParams(client, depositInput);
|
|
@@ -1721,9 +1728,10 @@ function createCashClient(options) {
|
|
|
1721
1728
|
deposit.currencies ?? [],
|
|
1722
1729
|
sdk.getPaymentMethodsCatalog(BASE_CHAIN_ID, environment)
|
|
1723
1730
|
);
|
|
1731
|
+
if (!isCashPayoutSet(payouts)) throw errors.orderNotFound(compositeId);
|
|
1724
1732
|
return deriveCashOrder(compositeId, deposit.intents ?? [], {
|
|
1725
1733
|
...depositOrderOptions(deposit),
|
|
1726
|
-
|
|
1734
|
+
payouts
|
|
1727
1735
|
});
|
|
1728
1736
|
}
|
|
1729
1737
|
function escrowContext(depositId) {
|
|
@@ -1921,16 +1929,17 @@ function createCashClient(options) {
|
|
|
1921
1929
|
async relayStatus(requestId) {
|
|
1922
1930
|
return readRelayStatus(requestId, options.relay);
|
|
1923
1931
|
},
|
|
1924
|
-
async estimate(input) {
|
|
1932
|
+
async estimate(input, estimateOptions) {
|
|
1925
1933
|
return readEstimate(readClient.publicClient, input, {
|
|
1926
|
-
indexerClient: readClient,
|
|
1927
1934
|
environment,
|
|
1935
|
+
...estimateOptions?.includeEta !== void 0 ? { includeEta: estimateOptions.includeEta } : {},
|
|
1936
|
+
etaReader: async (etaInput) => fillEtaFromSample(await getFillStatsSample(), etaInput),
|
|
1928
1937
|
...options.relay ? { relay: options.relay } : {}
|
|
1929
1938
|
});
|
|
1930
1939
|
},
|
|
1931
1940
|
async fillStats() {
|
|
1932
1941
|
try {
|
|
1933
|
-
return await
|
|
1942
|
+
return (await getFillStatsSample()).stats;
|
|
1934
1943
|
} catch (err) {
|
|
1935
1944
|
throw errors.indexerUnavailable("fill stats", err);
|
|
1936
1945
|
}
|
|
@@ -2169,7 +2178,7 @@ function createCashClient(options) {
|
|
|
2169
2178
|
deposit.currencies ?? [],
|
|
2170
2179
|
catalog
|
|
2171
2180
|
);
|
|
2172
|
-
if (
|
|
2181
|
+
if (!isCashPayoutSet(payouts)) {
|
|
2173
2182
|
return [];
|
|
2174
2183
|
}
|
|
2175
2184
|
return [
|
|
@@ -2438,7 +2447,7 @@ var cashPayoutPricingJsonSchema = zod.z.object({
|
|
|
2438
2447
|
marketRate: zod.z.boolean()
|
|
2439
2448
|
});
|
|
2440
2449
|
var cashPayoutInfoJsonSchema = zod.z.object({
|
|
2441
|
-
platform: zod.z.string()
|
|
2450
|
+
platform: zod.z.string(),
|
|
2442
2451
|
platformHash: zod.z.string(),
|
|
2443
2452
|
currency: zod.z.string().optional(),
|
|
2444
2453
|
currencyHash: zod.z.string().optional(),
|