@zkp2p/cash 0.1.9 → 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/README.md CHANGED
@@ -106,9 +106,14 @@ cashout. Every Peer Cash transaction, including approves, carries ERC-8021
106
106
  attribution: `peer-cash` first, your own `referrer` code(s) after it.
107
107
 
108
108
  `capabilities()` presents Zelle as one platform. A cashout with
109
- `receive.platform: 'zelle'` automatically attaches the generic Zelle method
110
- and its Chase, Bank of America, and Citi buyer routes to the deposit; the payee
111
- handle and public API remain bank-agnostic.
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.
112
117
 
113
118
  The default/minimal flow is unchanged: pass Base USDC base units to
114
119
  `estimate()` and `cashout()`. For any other source asset, pass `source` to
@@ -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.8).
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'` (undefined if the catalog doesn't know the hash). */
101
- platform?: string;
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'`. */
@@ -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.8).
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'` (undefined if the catalog doesn't know the hash). */
101
- platform?: string;
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'`. */
package/dist/index.cjs CHANGED
@@ -303,35 +303,41 @@ function toPricing(tuple) {
303
303
  };
304
304
  }
305
305
  function derivePayouts(paymentMethods, currencies, catalog) {
306
- return paymentMethods.flatMap((method) => {
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
- platform = void 0;
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
- ...platform !== void 0 ? { platform } : {},
321
+ platform,
320
322
  platformHash,
321
323
  payeeHash: method.payeeDetailsHash ?? "",
322
324
  active: method.active ?? true
323
325
  };
324
- if (tuples.length === 0) return [{ ...base2, pricing: toPricing(void 0) }];
325
- return tuples.map((tuple) => {
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
- return {
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 currenciesByPlatform = /* @__PURE__ */ new Map();
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 = `${basePlatformForMethod(method)}:${currency}`;
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);
@@ -961,7 +940,7 @@ async function readFillStatsSample(client, environment) {
961
940
  }
962
941
  function fillEtaFromSample(sample, input) {
963
942
  const currency = input.currency.toUpperCase();
964
- const seconds = input.platform ? sample.stats[`${basePlatformForMethod(input.platform)}:${currency}`]?.medianFillSeconds : sample.medianFillSecondsByCurrency.get(currency);
943
+ const seconds = input.platform ? sample.stats[`${input.platform}:${currency}`]?.medianFillSeconds : sample.medianFillSecondsByCurrency.get(currency);
965
944
  return {
966
945
  ...seconds !== void 0 ? { seconds } : {},
967
946
  label: etaLabel(seconds)
@@ -1658,7 +1637,6 @@ function createCashClient(options) {
1658
1637
  }
1659
1638
  function validatePayout(input) {
1660
1639
  const { receive } = input;
1661
- const catalog = sdk.getPaymentMethodsCatalog(BASE_CHAIN_ID, environment);
1662
1640
  const platform = buildCapabilities(environment).platforms.find(
1663
1641
  (capability) => capability.platform === receive.platform
1664
1642
  );
@@ -1669,13 +1647,14 @@ function createCashClient(options) {
1669
1647
  if (!platform.currencies.includes(receive.currency)) {
1670
1648
  throw errors.unsupportedPlatformCurrency(receive.platform, receive.currency);
1671
1649
  }
1672
- const paymentMethods = paymentMethodsForPlatform(receive.platform, catalog);
1673
1650
  return {
1674
- payouts: paymentMethods.map((processorName) => ({
1675
- processorName,
1676
- currency: receive.currency,
1677
- payeeData: receive.payee
1678
- }))
1651
+ payouts: [
1652
+ {
1653
+ processorName: receive.platform,
1654
+ currency: receive.currency,
1655
+ payeeData: receive.payee
1656
+ }
1657
+ ]
1679
1658
  };
1680
1659
  }
1681
1660
  function validateDepositInput(amount, input, payoutInput = validatePayout(input)) {
@@ -1692,6 +1671,9 @@ function createCashClient(options) {
1692
1671
  ...range ? { intentAmountRange: range } : {}
1693
1672
  };
1694
1673
  }
1674
+ function isCashPayoutSet(payouts) {
1675
+ return payouts.length === 1 && payouts.every((payout) => payout.pricing.marketRate && payout.pricing.spreadBps === 0);
1676
+ }
1695
1677
  async function buildDepositParams(client, depositInput) {
1696
1678
  try {
1697
1679
  return await prepareCashDepositParams(client, depositInput);
@@ -1746,9 +1728,10 @@ function createCashClient(options) {
1746
1728
  deposit.currencies ?? [],
1747
1729
  sdk.getPaymentMethodsCatalog(BASE_CHAIN_ID, environment)
1748
1730
  );
1731
+ if (!isCashPayoutSet(payouts)) throw errors.orderNotFound(compositeId);
1749
1732
  return deriveCashOrder(compositeId, deposit.intents ?? [], {
1750
1733
  ...depositOrderOptions(deposit),
1751
- ...payouts.length > 0 ? { payouts } : {}
1734
+ payouts
1752
1735
  });
1753
1736
  }
1754
1737
  function escrowContext(depositId) {
@@ -2195,7 +2178,7 @@ function createCashClient(options) {
2195
2178
  deposit.currencies ?? [],
2196
2179
  catalog
2197
2180
  );
2198
- if (payouts.length !== 1 || !payouts.every((payout) => payout.pricing.marketRate && payout.pricing.spreadBps === 0)) {
2181
+ if (!isCashPayoutSet(payouts)) {
2199
2182
  return [];
2200
2183
  }
2201
2184
  return [
@@ -2464,7 +2447,7 @@ var cashPayoutPricingJsonSchema = zod.z.object({
2464
2447
  marketRate: zod.z.boolean()
2465
2448
  });
2466
2449
  var cashPayoutInfoJsonSchema = zod.z.object({
2467
- platform: zod.z.string().optional(),
2450
+ platform: zod.z.string(),
2468
2451
  platformHash: zod.z.string(),
2469
2452
  currency: zod.z.string().optional(),
2470
2453
  currencyHash: zod.z.string().optional(),
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, 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-BhOytyHE.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, H as EstimateOptions, M as MIN_CASHOUT_AMOUNT, O as OrdersOptions, J as RECOMMENDED_MIN_CASHOUT_AMOUNT, K as RelayOptions, L as RelayQuoteInput, N as RelaySourceInput, Q as RelayTransaction, S as SignerOptions, U as WatchOptions, V as WithdrawOptions, X as buildCapabilities, Y as createCashClient } from './createCashClient-BhOytyHE.cjs';
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-CTEXn9FF.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, H as EstimateOptions, M as MIN_CASHOUT_AMOUNT, O as OrdersOptions, J as RECOMMENDED_MIN_CASHOUT_AMOUNT, K as RelayOptions, L as RelayQuoteInput, N as RelaySourceInput, Q as RelayTransaction, S as SignerOptions, U as WatchOptions, V as WithdrawOptions, X as buildCapabilities, Y as createCashClient } from './createCashClient-CTEXn9FF.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';
@@ -219,7 +219,9 @@ interface MethodCurrencyLike {
219
219
  /**
220
220
  * Decode a deposit's payment methods + currency tuples into payout legs.
221
221
  * Pure - the environment arrives via the catalog. One leg per
222
- * (method, currency) pair; cash orders create exactly one in v1.
222
+ * (method, currency) pair; cash orders create exactly one in v1. If any
223
+ * method is absent from the active catalog, reject the whole set instead of
224
+ * partially reclassifying a mixed historical deposit.
223
225
  */
224
226
  declare function derivePayouts(paymentMethods: ReadonlyArray<PaymentMethodLike>, currencies: ReadonlyArray<MethodCurrencyLike>, catalog: PaymentMethodCatalog): CashPayoutInfo[];
225
227
 
@@ -725,7 +727,7 @@ declare const cashPayoutPricingJsonSchema: z.ZodObject<{
725
727
  oracleRate?: number | undefined;
726
728
  }>;
727
729
  declare const cashPayoutInfoJsonSchema: z.ZodObject<{
728
- platform: z.ZodOptional<z.ZodString>;
730
+ platform: z.ZodString;
729
731
  platformHash: z.ZodString;
730
732
  currency: z.ZodOptional<z.ZodString>;
731
733
  currencyHash: z.ZodOptional<z.ZodString>;
@@ -754,6 +756,7 @@ declare const cashPayoutInfoJsonSchema: z.ZodObject<{
754
756
  oracleRate?: number | undefined;
755
757
  }>;
756
758
  }, "strip", z.ZodTypeAny, {
759
+ platform: string;
757
760
  pricing: {
758
761
  marketRate: boolean;
759
762
  spreadBps?: number | undefined;
@@ -767,8 +770,8 @@ declare const cashPayoutInfoJsonSchema: z.ZodObject<{
767
770
  active: boolean;
768
771
  currency?: string | undefined;
769
772
  currencyHash?: string | undefined;
770
- platform?: string | undefined;
771
773
  }, {
774
+ platform: string;
772
775
  pricing: {
773
776
  marketRate: boolean;
774
777
  spreadBps?: number | undefined;
@@ -782,7 +785,6 @@ declare const cashPayoutInfoJsonSchema: z.ZodObject<{
782
785
  active: boolean;
783
786
  currency?: string | undefined;
784
787
  currencyHash?: string | undefined;
785
- platform?: string | undefined;
786
788
  }>;
787
789
  declare const cashBuyerProfileJsonSchema: z.ZodObject<{
788
790
  address: z.ZodString;
@@ -890,7 +892,7 @@ declare const cashOrderJsonSchema: z.ZodObject<{
890
892
  updatedAt: z.ZodOptional<z.ZodNumber>;
891
893
  intentCount: z.ZodOptional<z.ZodNumber>;
892
894
  payouts: z.ZodOptional<z.ZodArray<z.ZodObject<{
893
- platform: z.ZodOptional<z.ZodString>;
895
+ platform: z.ZodString;
894
896
  platformHash: z.ZodString;
895
897
  currency: z.ZodOptional<z.ZodString>;
896
898
  currencyHash: z.ZodOptional<z.ZodString>;
@@ -919,6 +921,7 @@ declare const cashOrderJsonSchema: z.ZodObject<{
919
921
  oracleRate?: number | undefined;
920
922
  }>;
921
923
  }, "strip", z.ZodTypeAny, {
924
+ platform: string;
922
925
  pricing: {
923
926
  marketRate: boolean;
924
927
  spreadBps?: number | undefined;
@@ -932,8 +935,8 @@ declare const cashOrderJsonSchema: z.ZodObject<{
932
935
  active: boolean;
933
936
  currency?: string | undefined;
934
937
  currencyHash?: string | undefined;
935
- platform?: string | undefined;
936
938
  }, {
939
+ platform: string;
937
940
  pricing: {
938
941
  marketRate: boolean;
939
942
  spreadBps?: number | undefined;
@@ -947,7 +950,6 @@ declare const cashOrderJsonSchema: z.ZodObject<{
947
950
  active: boolean;
948
951
  currency?: string | undefined;
949
952
  currencyHash?: string | undefined;
950
- platform?: string | undefined;
951
953
  }>, "many">>;
952
954
  successRateBps: z.ZodOptional<z.ZodNumber>;
953
955
  isInFlight: z.ZodBoolean;
@@ -986,6 +988,7 @@ declare const cashOrderJsonSchema: z.ZodObject<{
986
988
  updatedAt?: number | undefined;
987
989
  successRateBps?: number | undefined;
988
990
  payouts?: {
991
+ platform: string;
989
992
  pricing: {
990
993
  marketRate: boolean;
991
994
  spreadBps?: number | undefined;
@@ -999,7 +1002,6 @@ declare const cashOrderJsonSchema: z.ZodObject<{
999
1002
  active: boolean;
1000
1003
  currency?: string | undefined;
1001
1004
  currencyHash?: string | undefined;
1002
- platform?: string | undefined;
1003
1005
  }[] | undefined;
1004
1006
  primaryIntentHash?: string | undefined;
1005
1007
  matchedAt?: number | undefined;
@@ -1040,6 +1042,7 @@ declare const cashOrderJsonSchema: z.ZodObject<{
1040
1042
  updatedAt?: number | undefined;
1041
1043
  successRateBps?: number | undefined;
1042
1044
  payouts?: {
1045
+ platform: string;
1043
1046
  pricing: {
1044
1047
  marketRate: boolean;
1045
1048
  spreadBps?: number | undefined;
@@ -1053,7 +1056,6 @@ declare const cashOrderJsonSchema: z.ZodObject<{
1053
1056
  active: boolean;
1054
1057
  currency?: string | undefined;
1055
1058
  currencyHash?: string | undefined;
1056
- platform?: string | undefined;
1057
1059
  }[] | undefined;
1058
1060
  primaryIntentHash?: string | undefined;
1059
1061
  matchedAt?: number | undefined;
@@ -1811,7 +1813,7 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
1811
1813
  updatedAt: z.ZodOptional<z.ZodNumber>;
1812
1814
  intentCount: z.ZodOptional<z.ZodNumber>;
1813
1815
  payouts: z.ZodOptional<z.ZodArray<z.ZodObject<{
1814
- platform: z.ZodOptional<z.ZodString>;
1816
+ platform: z.ZodString;
1815
1817
  platformHash: z.ZodString;
1816
1818
  currency: z.ZodOptional<z.ZodString>;
1817
1819
  currencyHash: z.ZodOptional<z.ZodString>;
@@ -1840,6 +1842,7 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
1840
1842
  oracleRate?: number | undefined;
1841
1843
  }>;
1842
1844
  }, "strip", z.ZodTypeAny, {
1845
+ platform: string;
1843
1846
  pricing: {
1844
1847
  marketRate: boolean;
1845
1848
  spreadBps?: number | undefined;
@@ -1853,8 +1856,8 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
1853
1856
  active: boolean;
1854
1857
  currency?: string | undefined;
1855
1858
  currencyHash?: string | undefined;
1856
- platform?: string | undefined;
1857
1859
  }, {
1860
+ platform: string;
1858
1861
  pricing: {
1859
1862
  marketRate: boolean;
1860
1863
  spreadBps?: number | undefined;
@@ -1868,7 +1871,6 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
1868
1871
  active: boolean;
1869
1872
  currency?: string | undefined;
1870
1873
  currencyHash?: string | undefined;
1871
- platform?: string | undefined;
1872
1874
  }>, "many">>;
1873
1875
  successRateBps: z.ZodOptional<z.ZodNumber>;
1874
1876
  isInFlight: z.ZodBoolean;
@@ -1907,6 +1909,7 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
1907
1909
  updatedAt?: number | undefined;
1908
1910
  successRateBps?: number | undefined;
1909
1911
  payouts?: {
1912
+ platform: string;
1910
1913
  pricing: {
1911
1914
  marketRate: boolean;
1912
1915
  spreadBps?: number | undefined;
@@ -1920,7 +1923,6 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
1920
1923
  active: boolean;
1921
1924
  currency?: string | undefined;
1922
1925
  currencyHash?: string | undefined;
1923
- platform?: string | undefined;
1924
1926
  }[] | undefined;
1925
1927
  primaryIntentHash?: string | undefined;
1926
1928
  matchedAt?: number | undefined;
@@ -1961,6 +1963,7 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
1961
1963
  updatedAt?: number | undefined;
1962
1964
  successRateBps?: number | undefined;
1963
1965
  payouts?: {
1966
+ platform: string;
1964
1967
  pricing: {
1965
1968
  marketRate: boolean;
1966
1969
  spreadBps?: number | undefined;
@@ -1974,7 +1977,6 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
1974
1977
  active: boolean;
1975
1978
  currency?: string | undefined;
1976
1979
  currencyHash?: string | undefined;
1977
- platform?: string | undefined;
1978
1980
  }[] | undefined;
1979
1981
  primaryIntentHash?: string | undefined;
1980
1982
  matchedAt?: number | undefined;
@@ -2108,6 +2110,7 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
2108
2110
  updatedAt?: number | undefined;
2109
2111
  successRateBps?: number | undefined;
2110
2112
  payouts?: {
2113
+ platform: string;
2111
2114
  pricing: {
2112
2115
  marketRate: boolean;
2113
2116
  spreadBps?: number | undefined;
@@ -2121,7 +2124,6 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
2121
2124
  active: boolean;
2122
2125
  currency?: string | undefined;
2123
2126
  currencyHash?: string | undefined;
2124
- platform?: string | undefined;
2125
2127
  }[] | undefined;
2126
2128
  primaryIntentHash?: string | undefined;
2127
2129
  matchedAt?: number | undefined;
@@ -2185,6 +2187,7 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
2185
2187
  updatedAt?: number | undefined;
2186
2188
  successRateBps?: number | undefined;
2187
2189
  payouts?: {
2190
+ platform: string;
2188
2191
  pricing: {
2189
2192
  marketRate: boolean;
2190
2193
  spreadBps?: number | undefined;
@@ -2198,7 +2201,6 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
2198
2201
  active: boolean;
2199
2202
  currency?: string | undefined;
2200
2203
  currencyHash?: string | undefined;
2201
- platform?: string | undefined;
2202
2204
  }[] | undefined;
2203
2205
  primaryIntentHash?: string | undefined;
2204
2206
  matchedAt?: number | undefined;
@@ -2708,8 +2710,8 @@ declare const cashCapabilitiesJsonSchema: z.ZodObject<{
2708
2710
  decimals: number;
2709
2711
  };
2710
2712
  };
2711
- currencies: string[];
2712
2713
  environment: "production" | "preproduction" | "staging";
2714
+ currencies: string[];
2713
2715
  platforms: {
2714
2716
  platform: string;
2715
2717
  currencies: string[];
@@ -2779,8 +2781,8 @@ declare const cashCapabilitiesJsonSchema: z.ZodObject<{
2779
2781
  decimals: number;
2780
2782
  };
2781
2783
  };
2782
- currencies: string[];
2783
2784
  environment: "production" | "preproduction" | "staging";
2785
+ currencies: string[];
2784
2786
  platforms: {
2785
2787
  platform: string;
2786
2788
  currencies: string[];
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, 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-BhOytyHE.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, H as EstimateOptions, M as MIN_CASHOUT_AMOUNT, O as OrdersOptions, J as RECOMMENDED_MIN_CASHOUT_AMOUNT, K as RelayOptions, L as RelayQuoteInput, N as RelaySourceInput, Q as RelayTransaction, S as SignerOptions, U as WatchOptions, V as WithdrawOptions, X as buildCapabilities, Y as createCashClient } from './createCashClient-BhOytyHE.js';
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-CTEXn9FF.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, H as EstimateOptions, M as MIN_CASHOUT_AMOUNT, O as OrdersOptions, J as RECOMMENDED_MIN_CASHOUT_AMOUNT, K as RelayOptions, L as RelayQuoteInput, N as RelaySourceInput, Q as RelayTransaction, S as SignerOptions, U as WatchOptions, V as WithdrawOptions, X as buildCapabilities, Y as createCashClient } from './createCashClient-CTEXn9FF.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';
@@ -219,7 +219,9 @@ interface MethodCurrencyLike {
219
219
  /**
220
220
  * Decode a deposit's payment methods + currency tuples into payout legs.
221
221
  * Pure - the environment arrives via the catalog. One leg per
222
- * (method, currency) pair; cash orders create exactly one in v1.
222
+ * (method, currency) pair; cash orders create exactly one in v1. If any
223
+ * method is absent from the active catalog, reject the whole set instead of
224
+ * partially reclassifying a mixed historical deposit.
223
225
  */
224
226
  declare function derivePayouts(paymentMethods: ReadonlyArray<PaymentMethodLike>, currencies: ReadonlyArray<MethodCurrencyLike>, catalog: PaymentMethodCatalog): CashPayoutInfo[];
225
227
 
@@ -725,7 +727,7 @@ declare const cashPayoutPricingJsonSchema: z.ZodObject<{
725
727
  oracleRate?: number | undefined;
726
728
  }>;
727
729
  declare const cashPayoutInfoJsonSchema: z.ZodObject<{
728
- platform: z.ZodOptional<z.ZodString>;
730
+ platform: z.ZodString;
729
731
  platformHash: z.ZodString;
730
732
  currency: z.ZodOptional<z.ZodString>;
731
733
  currencyHash: z.ZodOptional<z.ZodString>;
@@ -754,6 +756,7 @@ declare const cashPayoutInfoJsonSchema: z.ZodObject<{
754
756
  oracleRate?: number | undefined;
755
757
  }>;
756
758
  }, "strip", z.ZodTypeAny, {
759
+ platform: string;
757
760
  pricing: {
758
761
  marketRate: boolean;
759
762
  spreadBps?: number | undefined;
@@ -767,8 +770,8 @@ declare const cashPayoutInfoJsonSchema: z.ZodObject<{
767
770
  active: boolean;
768
771
  currency?: string | undefined;
769
772
  currencyHash?: string | undefined;
770
- platform?: string | undefined;
771
773
  }, {
774
+ platform: string;
772
775
  pricing: {
773
776
  marketRate: boolean;
774
777
  spreadBps?: number | undefined;
@@ -782,7 +785,6 @@ declare const cashPayoutInfoJsonSchema: z.ZodObject<{
782
785
  active: boolean;
783
786
  currency?: string | undefined;
784
787
  currencyHash?: string | undefined;
785
- platform?: string | undefined;
786
788
  }>;
787
789
  declare const cashBuyerProfileJsonSchema: z.ZodObject<{
788
790
  address: z.ZodString;
@@ -890,7 +892,7 @@ declare const cashOrderJsonSchema: z.ZodObject<{
890
892
  updatedAt: z.ZodOptional<z.ZodNumber>;
891
893
  intentCount: z.ZodOptional<z.ZodNumber>;
892
894
  payouts: z.ZodOptional<z.ZodArray<z.ZodObject<{
893
- platform: z.ZodOptional<z.ZodString>;
895
+ platform: z.ZodString;
894
896
  platformHash: z.ZodString;
895
897
  currency: z.ZodOptional<z.ZodString>;
896
898
  currencyHash: z.ZodOptional<z.ZodString>;
@@ -919,6 +921,7 @@ declare const cashOrderJsonSchema: z.ZodObject<{
919
921
  oracleRate?: number | undefined;
920
922
  }>;
921
923
  }, "strip", z.ZodTypeAny, {
924
+ platform: string;
922
925
  pricing: {
923
926
  marketRate: boolean;
924
927
  spreadBps?: number | undefined;
@@ -932,8 +935,8 @@ declare const cashOrderJsonSchema: z.ZodObject<{
932
935
  active: boolean;
933
936
  currency?: string | undefined;
934
937
  currencyHash?: string | undefined;
935
- platform?: string | undefined;
936
938
  }, {
939
+ platform: string;
937
940
  pricing: {
938
941
  marketRate: boolean;
939
942
  spreadBps?: number | undefined;
@@ -947,7 +950,6 @@ declare const cashOrderJsonSchema: z.ZodObject<{
947
950
  active: boolean;
948
951
  currency?: string | undefined;
949
952
  currencyHash?: string | undefined;
950
- platform?: string | undefined;
951
953
  }>, "many">>;
952
954
  successRateBps: z.ZodOptional<z.ZodNumber>;
953
955
  isInFlight: z.ZodBoolean;
@@ -986,6 +988,7 @@ declare const cashOrderJsonSchema: z.ZodObject<{
986
988
  updatedAt?: number | undefined;
987
989
  successRateBps?: number | undefined;
988
990
  payouts?: {
991
+ platform: string;
989
992
  pricing: {
990
993
  marketRate: boolean;
991
994
  spreadBps?: number | undefined;
@@ -999,7 +1002,6 @@ declare const cashOrderJsonSchema: z.ZodObject<{
999
1002
  active: boolean;
1000
1003
  currency?: string | undefined;
1001
1004
  currencyHash?: string | undefined;
1002
- platform?: string | undefined;
1003
1005
  }[] | undefined;
1004
1006
  primaryIntentHash?: string | undefined;
1005
1007
  matchedAt?: number | undefined;
@@ -1040,6 +1042,7 @@ declare const cashOrderJsonSchema: z.ZodObject<{
1040
1042
  updatedAt?: number | undefined;
1041
1043
  successRateBps?: number | undefined;
1042
1044
  payouts?: {
1045
+ platform: string;
1043
1046
  pricing: {
1044
1047
  marketRate: boolean;
1045
1048
  spreadBps?: number | undefined;
@@ -1053,7 +1056,6 @@ declare const cashOrderJsonSchema: z.ZodObject<{
1053
1056
  active: boolean;
1054
1057
  currency?: string | undefined;
1055
1058
  currencyHash?: string | undefined;
1056
- platform?: string | undefined;
1057
1059
  }[] | undefined;
1058
1060
  primaryIntentHash?: string | undefined;
1059
1061
  matchedAt?: number | undefined;
@@ -1811,7 +1813,7 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
1811
1813
  updatedAt: z.ZodOptional<z.ZodNumber>;
1812
1814
  intentCount: z.ZodOptional<z.ZodNumber>;
1813
1815
  payouts: z.ZodOptional<z.ZodArray<z.ZodObject<{
1814
- platform: z.ZodOptional<z.ZodString>;
1816
+ platform: z.ZodString;
1815
1817
  platformHash: z.ZodString;
1816
1818
  currency: z.ZodOptional<z.ZodString>;
1817
1819
  currencyHash: z.ZodOptional<z.ZodString>;
@@ -1840,6 +1842,7 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
1840
1842
  oracleRate?: number | undefined;
1841
1843
  }>;
1842
1844
  }, "strip", z.ZodTypeAny, {
1845
+ platform: string;
1843
1846
  pricing: {
1844
1847
  marketRate: boolean;
1845
1848
  spreadBps?: number | undefined;
@@ -1853,8 +1856,8 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
1853
1856
  active: boolean;
1854
1857
  currency?: string | undefined;
1855
1858
  currencyHash?: string | undefined;
1856
- platform?: string | undefined;
1857
1859
  }, {
1860
+ platform: string;
1858
1861
  pricing: {
1859
1862
  marketRate: boolean;
1860
1863
  spreadBps?: number | undefined;
@@ -1868,7 +1871,6 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
1868
1871
  active: boolean;
1869
1872
  currency?: string | undefined;
1870
1873
  currencyHash?: string | undefined;
1871
- platform?: string | undefined;
1872
1874
  }>, "many">>;
1873
1875
  successRateBps: z.ZodOptional<z.ZodNumber>;
1874
1876
  isInFlight: z.ZodBoolean;
@@ -1907,6 +1909,7 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
1907
1909
  updatedAt?: number | undefined;
1908
1910
  successRateBps?: number | undefined;
1909
1911
  payouts?: {
1912
+ platform: string;
1910
1913
  pricing: {
1911
1914
  marketRate: boolean;
1912
1915
  spreadBps?: number | undefined;
@@ -1920,7 +1923,6 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
1920
1923
  active: boolean;
1921
1924
  currency?: string | undefined;
1922
1925
  currencyHash?: string | undefined;
1923
- platform?: string | undefined;
1924
1926
  }[] | undefined;
1925
1927
  primaryIntentHash?: string | undefined;
1926
1928
  matchedAt?: number | undefined;
@@ -1961,6 +1963,7 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
1961
1963
  updatedAt?: number | undefined;
1962
1964
  successRateBps?: number | undefined;
1963
1965
  payouts?: {
1966
+ platform: string;
1964
1967
  pricing: {
1965
1968
  marketRate: boolean;
1966
1969
  spreadBps?: number | undefined;
@@ -1974,7 +1977,6 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
1974
1977
  active: boolean;
1975
1978
  currency?: string | undefined;
1976
1979
  currencyHash?: string | undefined;
1977
- platform?: string | undefined;
1978
1980
  }[] | undefined;
1979
1981
  primaryIntentHash?: string | undefined;
1980
1982
  matchedAt?: number | undefined;
@@ -2108,6 +2110,7 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
2108
2110
  updatedAt?: number | undefined;
2109
2111
  successRateBps?: number | undefined;
2110
2112
  payouts?: {
2113
+ platform: string;
2111
2114
  pricing: {
2112
2115
  marketRate: boolean;
2113
2116
  spreadBps?: number | undefined;
@@ -2121,7 +2124,6 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
2121
2124
  active: boolean;
2122
2125
  currency?: string | undefined;
2123
2126
  currencyHash?: string | undefined;
2124
- platform?: string | undefined;
2125
2127
  }[] | undefined;
2126
2128
  primaryIntentHash?: string | undefined;
2127
2129
  matchedAt?: number | undefined;
@@ -2185,6 +2187,7 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
2185
2187
  updatedAt?: number | undefined;
2186
2188
  successRateBps?: number | undefined;
2187
2189
  payouts?: {
2190
+ platform: string;
2188
2191
  pricing: {
2189
2192
  marketRate: boolean;
2190
2193
  spreadBps?: number | undefined;
@@ -2198,7 +2201,6 @@ declare const cashoutResultJsonSchema: z.ZodObject<{
2198
2201
  active: boolean;
2199
2202
  currency?: string | undefined;
2200
2203
  currencyHash?: string | undefined;
2201
- platform?: string | undefined;
2202
2204
  }[] | undefined;
2203
2205
  primaryIntentHash?: string | undefined;
2204
2206
  matchedAt?: number | undefined;
@@ -2708,8 +2710,8 @@ declare const cashCapabilitiesJsonSchema: z.ZodObject<{
2708
2710
  decimals: number;
2709
2711
  };
2710
2712
  };
2711
- currencies: string[];
2712
2713
  environment: "production" | "preproduction" | "staging";
2714
+ currencies: string[];
2713
2715
  platforms: {
2714
2716
  platform: string;
2715
2717
  currencies: string[];
@@ -2779,8 +2781,8 @@ declare const cashCapabilitiesJsonSchema: z.ZodObject<{
2779
2781
  decimals: number;
2780
2782
  };
2781
2783
  };
2782
- currencies: string[];
2783
2784
  environment: "production" | "preproduction" | "staging";
2785
+ currencies: string[];
2784
2786
  platforms: {
2785
2787
  platform: string;
2786
2788
  currencies: string[];
package/dist/index.js CHANGED
@@ -287,35 +287,41 @@ function toPricing(tuple) {
287
287
  };
288
288
  }
289
289
  function derivePayouts(paymentMethods, currencies, catalog) {
290
- return paymentMethods.flatMap((method) => {
290
+ const payouts = [];
291
+ for (const method of paymentMethods) {
291
292
  const platformHash = method.paymentMethodHash ?? "";
292
293
  if (!platformHash) return [];
293
294
  let platform;
294
295
  try {
295
296
  platform = resolvePaymentMethodNameFromHash(platformHash, catalog);
296
297
  } catch {
297
- platform = void 0;
298
+ return [];
298
299
  }
300
+ if (!platform) return [];
299
301
  const tuples = currencies.filter(
300
302
  (c) => (c.paymentMethodHash ?? "").toLowerCase() === platformHash.toLowerCase()
301
303
  );
302
304
  const base2 = {
303
- ...platform !== void 0 ? { platform } : {},
305
+ platform,
304
306
  platformHash,
305
307
  payeeHash: method.payeeDetailsHash ?? "",
306
308
  active: method.active ?? true
307
309
  };
308
- if (tuples.length === 0) return [{ ...base2, pricing: toPricing(void 0) }];
309
- return tuples.map((tuple) => {
310
+ if (tuples.length === 0) {
311
+ payouts.push({ ...base2, pricing: toPricing(void 0) });
312
+ continue;
313
+ }
314
+ for (const tuple of tuples) {
310
315
  const currency = tuple.currencyCode != null ? getCurrencyCodeFromHash(tuple.currencyCode) : void 0;
311
- return {
316
+ payouts.push({
312
317
  ...base2,
313
318
  ...currency !== void 0 ? { currency } : {},
314
319
  ...tuple.currencyCode != null ? { currencyHash: tuple.currencyCode } : {},
315
320
  pricing: toPricing(tuple)
316
- };
317
- });
318
- });
321
+ });
322
+ }
323
+ }
324
+ return payouts;
319
325
  }
320
326
 
321
327
  // src/engine/buyerProfile.ts
@@ -387,26 +393,6 @@ function parseCompositeDepositId(compositeId) {
387
393
  const onchainDepositId = BigInt(rawDepositId);
388
394
  return { escrowAddress: canonicalEscrowAddress, onchainDepositId };
389
395
  }
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
410
396
  var MIN_CASHOUT_AMOUNT = 10000n;
411
397
  var RECOMMENDED_MIN_CASHOUT_AMOUNT = 1000000n;
412
398
  var PAYEE_HINTS = {
@@ -425,20 +411,13 @@ var PAYEE_HINTS = {
425
411
  var IDENTITY_ATTESTATION_PLATFORMS = /* @__PURE__ */ new Set(["wise", "paypal"]);
426
412
  function buildCapabilities(environment) {
427
413
  const catalog = getPaymentMethodsCatalog(BASE_CHAIN_ID, environment);
428
- const currenciesByPlatform = /* @__PURE__ */ new Map();
429
- for (const [method, entry] of Object.entries(catalog)) {
430
- const platform = basePlatformForMethod(method);
414
+ const platforms = Object.entries(catalog).map(([platform, entry]) => {
431
415
  const currencies2 = (entry.currencies ?? []).map((hash) => getCurrencyCodeFromHash(hash)).filter(
432
416
  (code) => code != null && isMarketRateSupported(code)
433
417
  );
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]) => {
439
418
  return {
440
419
  platform,
441
- currencies: [...currencies2].sort(),
420
+ currencies: [...new Set(currencies2)].sort(),
442
421
  payeeHint: PAYEE_HINTS[platform] ?? "Your payment handle for this platform",
443
422
  requiresIdentityAttestation: IDENTITY_ATTESTATION_PLATFORMS.has(platform)
444
423
  };
@@ -517,7 +496,7 @@ function computeFillStatsSample(deposits, nowSeconds, environment) {
517
496
  }
518
497
  const currency = normalizeCurrencyCode(intent.fiatCurrency);
519
498
  if (!method || !currency) continue;
520
- const pair = `${basePlatformForMethod(method)}:${currency}`;
499
+ const pair = `${method}:${currency}`;
521
500
  fillCounts.set(pair, (fillCounts.get(pair) ?? 0) + 1);
522
501
  if (createdAt === void 0 || createdAt < windowStart || fulfilledAt < createdAt) continue;
523
502
  const previousPairFill = firstFillByPair.get(pair);
@@ -582,7 +561,7 @@ async function readFillStatsSample(client, environment) {
582
561
  }
583
562
  function fillEtaFromSample(sample, input) {
584
563
  const currency = input.currency.toUpperCase();
585
- const seconds = input.platform ? sample.stats[`${basePlatformForMethod(input.platform)}:${currency}`]?.medianFillSeconds : sample.medianFillSecondsByCurrency.get(currency);
564
+ const seconds = input.platform ? sample.stats[`${input.platform}:${currency}`]?.medianFillSeconds : sample.medianFillSecondsByCurrency.get(currency);
586
565
  return {
587
566
  ...seconds !== void 0 ? { seconds } : {},
588
567
  label: etaLabel(seconds)
@@ -1279,7 +1258,6 @@ function createCashClient(options) {
1279
1258
  }
1280
1259
  function validatePayout(input) {
1281
1260
  const { receive } = input;
1282
- const catalog = getPaymentMethodsCatalog(BASE_CHAIN_ID, environment);
1283
1261
  const platform = buildCapabilities(environment).platforms.find(
1284
1262
  (capability) => capability.platform === receive.platform
1285
1263
  );
@@ -1290,13 +1268,14 @@ function createCashClient(options) {
1290
1268
  if (!platform.currencies.includes(receive.currency)) {
1291
1269
  throw errors.unsupportedPlatformCurrency(receive.platform, receive.currency);
1292
1270
  }
1293
- const paymentMethods = paymentMethodsForPlatform(receive.platform, catalog);
1294
1271
  return {
1295
- payouts: paymentMethods.map((processorName) => ({
1296
- processorName,
1297
- currency: receive.currency,
1298
- payeeData: receive.payee
1299
- }))
1272
+ payouts: [
1273
+ {
1274
+ processorName: receive.platform,
1275
+ currency: receive.currency,
1276
+ payeeData: receive.payee
1277
+ }
1278
+ ]
1300
1279
  };
1301
1280
  }
1302
1281
  function validateDepositInput(amount, input, payoutInput = validatePayout(input)) {
@@ -1313,6 +1292,9 @@ function createCashClient(options) {
1313
1292
  ...range ? { intentAmountRange: range } : {}
1314
1293
  };
1315
1294
  }
1295
+ function isCashPayoutSet(payouts) {
1296
+ return payouts.length === 1 && payouts.every((payout) => payout.pricing.marketRate && payout.pricing.spreadBps === 0);
1297
+ }
1316
1298
  async function buildDepositParams(client, depositInput) {
1317
1299
  try {
1318
1300
  return await prepareCashDepositParams(client, depositInput);
@@ -1367,9 +1349,10 @@ function createCashClient(options) {
1367
1349
  deposit.currencies ?? [],
1368
1350
  getPaymentMethodsCatalog(BASE_CHAIN_ID, environment)
1369
1351
  );
1352
+ if (!isCashPayoutSet(payouts)) throw errors.orderNotFound(compositeId);
1370
1353
  return deriveCashOrder(compositeId, deposit.intents ?? [], {
1371
1354
  ...depositOrderOptions(deposit),
1372
- ...payouts.length > 0 ? { payouts } : {}
1355
+ payouts
1373
1356
  });
1374
1357
  }
1375
1358
  function escrowContext(depositId) {
@@ -1816,7 +1799,7 @@ function createCashClient(options) {
1816
1799
  deposit.currencies ?? [],
1817
1800
  catalog
1818
1801
  );
1819
- if (payouts.length !== 1 || !payouts.every((payout) => payout.pricing.marketRate && payout.pricing.spreadBps === 0)) {
1802
+ if (!isCashPayoutSet(payouts)) {
1820
1803
  return [];
1821
1804
  }
1822
1805
  return [
@@ -2085,7 +2068,7 @@ var cashPayoutPricingJsonSchema = z.object({
2085
2068
  marketRate: z.boolean()
2086
2069
  });
2087
2070
  var cashPayoutInfoJsonSchema = z.object({
2088
- platform: z.string().optional(),
2071
+ platform: z.string(),
2089
2072
  platformHash: z.string(),
2090
2073
  currency: z.string().optional(),
2091
2074
  currencyHash: z.string().optional(),
package/dist/react.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { CurrencyType } from '@zkp2p/sdk';
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-BhOytyHE.cjs';
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-CTEXn9FF.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 { 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-BhOytyHE.js';
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-CTEXn9FF.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.9"};
5
+ version: "0.2.0"};
6
6
 
7
7
  // src/tools/index.ts
8
8
  var bigintString = {
package/dist/tools.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // package.json
2
2
  var package_default = {
3
- version: "0.1.9"};
3
+ version: "0.2.0"};
4
4
 
5
5
  // src/tools/index.ts
6
6
  var bigintString = {
@@ -130,8 +130,8 @@ measure buyer signal to fulfillment; that would miss the buyer-arrival wait
130
130
  that users actually care about. The public shape is small: `{ seconds, label }`.
131
131
 
132
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
133
+ `Record<"platform:currency", { fills, medianFillSeconds? }>`. Generic Zelle
134
+ fills are reported as `zelle:USD`. Consumers own thresholding; the recommended
135
135
  gate is `fills >= 10 && medianFillSeconds <= 48h`, with a fail-open fallback to
136
136
  the full capability catalog when the read fails or filtering would empty it.
137
137
  Medians are per-deposit first-fill latencies, never means or censored cohorts.
@@ -195,6 +195,11 @@ platform, currency, payee hash, and a pricing proof (`spreadBps: 0`,
195
195
  `kind: 'oracle_chainlink'`, `marketRate: true`): the zero-spread claim is a
196
196
  queryable fact, not marketing copy.
197
197
 
198
+ Reconstruction is fail-closed: every payment method on the indexed deposit
199
+ must resolve through the active SDK catalog, and the result must be exactly
200
+ one zero-spread oracle payout. `orders()` excludes unsupported or mixed rows;
201
+ `order()` returns `ORDER_NOT_FOUND` rather than partially reclassifying them.
202
+
198
203
  ## Who is this buyer?
199
204
 
200
205
  `buyer(address)` aggregates the matched buyer's full intent history into a
package/llms.txt CHANGED
@@ -29,8 +29,8 @@ Key facts:
29
29
  - Progressive UIs can call estimate(input, { includeEta: false }) so the
30
30
  oracle rate is not blocked by indexer history, then load the exact pair from
31
31
  fillStats() separately.
32
- - capabilities() exposes one Zelle platform. A zelle cashout internally attaches
33
- the generic method plus Chase, Bank of America, and Citi buyer routes.
32
+ - capabilities() exposes one Zelle platform. A zelle cashout attaches only the
33
+ generic Zelle payment method to the on-chain deposit.
34
34
  - Resume any order from its depositId alone (composite escrow_onchainId).
35
35
  - One unwind verb: withdraw(depositId) - prunes expired intents automatically;
36
36
  pass amount for a partial withdrawal of the unlocked balance.
@@ -56,6 +56,8 @@ Key facts:
56
56
  payment id, released USDC, and fill latency after the proof.
57
57
  - Orders carry their payout legs (platform, currency, payee hash) plus a
58
58
  verifiable pricing proof (spreadBps: 0, oracle kind) from indexed data.
59
+ - Order reads fail closed when any deposit method is absent from the active
60
+ catalog; mixed historical deposits are never partially reclassified.
59
61
  - buyer(address) aggregates a buyer's track record (fulfilled/pruned/success
60
62
  rate) from their full intent history.
61
63
  - Default path is same-chain Base USDC. Optional `source` on `cashout()` runs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zkp2p/cash",
3
- "version": "0.1.9",
3
+ "version": "0.2.0",
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)",
@@ -106,7 +106,7 @@
106
106
  },
107
107
  "dependencies": {
108
108
  "@relayprotocol/relay-sdk": "^6.1.3",
109
- "@zkp2p/sdk": "^0.8.1",
109
+ "@zkp2p/sdk": "^0.9.0",
110
110
  "zod": "^3.25.76"
111
111
  },
112
112
  "peerDependencies": {