@zkp2p/cash 0.6.3-rc.2 → 0.7.0-rc.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 CHANGED
@@ -7,8 +7,8 @@
7
7
  You are integrating Peer Cash: an offramp that routes Relay-supported EVM
8
8
  assets or NEAR Intents 1Click external deposits into Base USDC, then converts
9
9
  Base USDC to fiat (Venmo, Revolut, Wise, Alipay, Zelle, ...) at a zero-spread
10
- Chainlink market rate. Existing corridors bind at intent signal; Alipay/CNY
11
- fixes a fresh Ethereum Chainlink snapshot during deposit preparation; UPI/INR uses Polygon Chainlink. The user whose USDC you
10
+ oracle market rate. Every corridor, including Alipay/CNY and UPI/INR, binds
11
+ the Base oracle at intent signal. The user whose USDC you
12
12
  manage is the **maker**; a buyer pays them fiat and proves it with TEE-TLS; the
13
13
  protocol releases the USDC. Funds are held by the protocol, and only the maker
14
14
  can withdraw an unmatched deposit.
@@ -200,10 +200,8 @@ const route = await cash.nearIntentsStatus({
200
200
  ## Rules that prevent wrong behavior
201
201
 
202
202
  - **Respect the declared binding point.** `estimate()` is
203
- `kind: 'oracle-estimate'`. Its `binding` is `intent-signal` for existing
204
- on-chain oracle corridors and `deposit-creation` for Alipay/CNY and UPI/INR. Do not call
205
- an estimate locked before that point. Once a creation-time corridor is prepared, its fresh
206
- Chainlink snapshot is the on-chain maker floor.
203
+ `kind: 'oracle-estimate'` with `binding: 'intent-signal'` for every currency.
204
+ The estimate is approximate; each buyer's signal binds the live oracle rate.
207
205
  - **Do not invent an ETA.** Use `estimate().eta`: `{ seconds, label }` backed
208
206
  by the same rolling 30-day, intent-attributed pair sample as `fillStats()`,
209
207
  measured from deposit creation to first fill. Use `order.explain()` for live
@@ -340,13 +338,11 @@ wallet. Never wait on a buyer - buyer-side is out of your scope:
340
338
  If step 4 ever fails with funds stuck, stop and escalate - do not retry
341
339
  blindly.
342
340
 
343
- UPI/INR reads the live Chainlink Polygon mainnet proxy
344
- `0xDA0F8Df6F5dB15b346f4B8D1156722027E194E60` (chain 137), inverts
345
- USD per INR, and rounds the creation-time maker floor up. Configure its
346
- read-only RPC with `upiCreationRateRpcUrl` or `upiCreationRateTransport`.
347
- Alipay/CNY retains the Ethereum registry and `creationRateRpcUrl` /
348
- `creationRateTransport`. UPI rejects the wrong chain, invalid rounds, and
349
- observations older than 24 hours; market closures do not bypass freshness.
341
+ UPI/INR and Alipay/CNY use ZKP2P-operated AggregatorV3-compatible feeds on Base,
342
+ through the SDK's Chainlink oracle adapter with `invert: true` and zero spread.
343
+ The SDK feed catalog supplies the addresses and determines oracle availability;
344
+ Cash adds no currency exceptions. Estimates read through the normal Base
345
+ `transport` / `rpcUrl`; deposits float until each buyer signals an intent.
350
346
  UPI is available in production, preproduction, and staging without a feature flag.
351
347
 
352
348
  ## Optional Venmo receipt linking
package/README.md CHANGED
@@ -2,10 +2,9 @@
2
2
 
3
3
  Route Relay-supported EVM assets or NEAR Intents 1Click external deposits into
4
4
  Base USDC, then cash out to fiat on Venmo, Revolut, Wise, Alipay, Zelle, and
5
- more at a zero-spread Chainlink market rate with no centralized off-ramp
6
- provider. Existing corridors bind the live oracle when a buyer signals;
7
- Alipay/CNY and UPI/INR fix fresh Chainlink snapshots when the SDK prepares
8
- the deposit (Ethereum for CNY; Polygon for INR).
5
+ more at a zero-spread on-chain oracle market rate with no centralized off-ramp
6
+ provider. Every corridor, including Alipay/CNY and UPI/INR, binds the live
7
+ Base oracle when a buyer signals.
9
8
 
10
9
  Peer Cash is an **offramp-only** SDK for the [ZKP2P](https://peer.xyz)
11
10
  protocol. The cashing-out user is the maker: their USDC becomes a deposit in
@@ -79,14 +78,14 @@ const widestReach = await cash.cashout(
79
78
  { signer },
80
79
  );
81
80
 
82
- // Alipay/CNY is the explicit creation-time exception. New Alipay payees need
81
+ // Alipay/CNY uses the same signal-time oracle path. New Alipay payees need
83
82
  // the identity attestation prepared by first-party Peer web.
84
83
  const alipayEstimate = await cash.estimate({
85
84
  amount: usdc(1000),
86
85
  platform: 'alipay',
87
86
  currency: 'CNY',
88
87
  });
89
- // alipayEstimate.binding === 'deposit-creation'
88
+ // alipayEstimate.binding === 'intent-signal'
90
89
 
91
90
  for await (const order of cash.watch(depositId)) {
92
91
  console.log(order.state, order.explain());
@@ -96,8 +95,8 @@ for await (const order of cash.watch(depositId)) {
96
95
 
97
96
  ### Staging and preproduction UPI cash-out
98
97
 
99
- UPI requires the canonical UPI/INR catalog from `@zkp2p/sdk` 0.14.2-rc.1
100
- or its approved successor; a missing catalog entry keeps the corridor disabled.
98
+ UPI requires the canonical UPI/INR catalog and INR oracle config from the
99
+ pinned `@zkp2p/sdk` 0.14.5-rc.2; missing oracle support disables the corridor.
101
100
  UPI is available in every environment without an opt-in. Any valid UPI ID from any bank can receive a cash-out. The seller
102
101
  does not connect a bank account, install an extension, or complete a separate
103
102
  registration flow:
@@ -120,21 +119,30 @@ Buyers pay and verify through Amazon Pay using standard UPI. UPI Lite and
120
119
  merchant payments are unsupported. The seller may receive at a valid UPI ID
121
120
  from any bank.
122
121
 
123
- INR pricing uses the [Chainlink Polygon INR/USD feed](https://data.chain.link/feeds/polygon/mainnet/inr-usd),
124
- inverted into INR per USDC and fixed at deposit preparation. The SDK rejects
125
- invalid rounds and readings older than 24 hours, including market-hour gaps.
126
- Only oracle reads use Polygon; funds and transactions stay on Base. Override
127
- the Polygon reader with `upiCreationRateTransport` or `upiCreationRateRpcUrl`.
128
- The existing `creationRateTransport`/`creationRateRpcUrl` options remain Ethereum-only for CNY.
122
+ UPI/INR and Alipay/CNY use ZKP2P-operated AggregatorV3-compatible feeds on Base,
123
+ through the SDK's Chainlink oracle adapter with `invert: true` and zero spread.
124
+ The SDK feed catalog supplies the addresses and determines oracle availability;
125
+ Cash adds no currency exceptions. Estimates read through the normal Base
126
+ `transport` / `rpcUrl`; deposits float until each buyer signals an intent.
127
+ UPI is available in production, preproduction, and staging without a feature flag.
128
+
129
+ With `@zkp2p/sdk` 0.14.5-rc.2, Express Cash intentionally also offers
130
+ Wise/INR, Wise/CNY, and Revolut/CNY because corridor support derives from
131
+ oracle availability and each platform's currency catalog. The exact INR/CNY
132
+ corridor set in production, preproduction, and staging is UPI/INR, Wise/INR,
133
+ Alipay/CNY, Wise/CNY, and Revolut/CNY. All five use zero-spread oracle pricing
134
+ bound at intent signal; currencies without an oracle config remain unsupported.
135
+
136
+ See [the INR/CNY migration notes](docs/lifecycle-and-recovery.md#inrcny-oracle-migration-breaking) before upgrading an existing integration.
129
137
 
130
138
  ## Pick the right SDK
131
139
 
132
140
  Peer Cash and the general ZKP2P SDK serve different integration depths:
133
141
 
134
- | Package | Use it when | Boundary |
135
- | ------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
136
- | `@zkp2p/cash` | Cash-out is the product | Offramp only. The user is always the maker, the destination is Base USDC, pricing is zero-spread Chainlink (signal-time by default; creation-time for Alipay/CNY and UPI/INR), and the SDK owns the resumable order lifecycle. |
137
- | `@zkp2p/sdk` | You are composing directly with the Peer protocol | General maker and taker operations, deposits, intents, proofs, quotes, vaults, rate managers, referrals, hooks, and API helpers. Your application owns the workflow and protocol choices. |
142
+ | Package | Use it when | Boundary |
143
+ | ------------- | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
144
+ | `@zkp2p/cash` | Cash-out is the product | Offramp only. The user is always the maker, the destination is Base USDC, pricing is zero-spread Base oracles at intent signal, and the SDK owns the resumable order lifecycle. |
145
+ | `@zkp2p/sdk` | You are composing directly with the Peer protocol | General maker and taker operations, deposits, intents, proofs, quotes, vaults, rate managers, referrals, hooks, and API helpers. Your application owns the workflow and protocol choices. |
138
146
 
139
147
  Peer Cash is a narrow facade over `@zkp2p/sdk`, not a replacement for it. It
140
148
  cannot express custom spreads, buyer-side proof flows, vaults, disputes, or
@@ -524,15 +532,10 @@ awaiting-buyer ──────────► matched ───────
524
532
  returned ◄─────────────────┘
525
533
  ```
526
534
 
527
- - **You are the maker.** Pricing is zero-spread. Existing corridors resolve
528
- from the on-chain Chainlink oracle when a buyer signals an intent.
529
- - **Alipay/CNY binds earlier.** Base has no CNY oracle adapter, so the SDK reads
530
- Chainlink CNY/USD on Ethereum, rejects stale or invalid data, and fixes the
531
- resulting CNY-per-USDC maker floor when it prepares the deposit. A buyer may
532
- signal at that floor or a better rate for the maker.
533
- - **Read `binding`.** `estimate().binding` is `intent-signal` by default and
534
- `deposit-creation` for Alipay/CNY and UPI/INR. An estimate remains approximate until its
535
- stated binding point.
535
+ - **You are the maker.** Every corridor uses the live Base oracle with zero
536
+ spread when a buyer signals an intent, including Alipay/CNY and UPI/INR.
537
+ - **Read `binding`.** `estimate().binding` is `intent-signal`. An estimate
538
+ remains approximate; each signal binds the then-current rate.
536
539
  - **ETA is historical.** `estimate().eta` is just `{ seconds, label }`, backed
537
540
  by the same rolling 30-day, intent-attributed pair sampler as `fillStats()`,
538
541
  measured from deposit creation to the first fulfilled fill through the pair.
@@ -314,10 +314,7 @@ declare const BASE_CHAIN_ID = 8453;
314
314
  declare const BASE_USDC_ADDRESS: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913";
315
315
  /** USDC has 6 decimals. */
316
316
  declare const USDC_DECIMALS = 6;
317
- /**
318
- * Signal-time oracle corridors use zero spread. Alipay/CNY instead fixes a
319
- * fresh creation-time snapshot because Base has no CNY oracle adapter.
320
- */
317
+ /** Every corridor uses the signal-time oracle rate with zero spread. */
321
318
  declare const MARKET_SPREAD_BPS = 0;
322
319
  /**
323
320
  * EscrowV2 rejects a zero `minConversionRate` even when an oracle-backed rate
@@ -475,10 +472,6 @@ declare const RECOMMENDED_MIN_CASHOUT_AMOUNT = 1000000n;
475
472
  type CashCorridorPricing = {
476
473
  kind: 'oracle-at-intent-signal';
477
474
  spreadBps: 0;
478
- } | {
479
- kind: 'fixed-at-deposit-creation';
480
- source: 'chainlink-ethereum';
481
- spreadBps: 0;
482
475
  };
483
476
  interface CashPlatformCapability {
484
477
  /** Platform id, e.g. `'venmo'` - the value `receive.platform` accepts. */
@@ -548,7 +541,7 @@ interface CashCapabilities {
548
541
  recommendedMin: bigint;
549
542
  max: null;
550
543
  };
551
- /** Default pricing for corridors without a platform-level creation-time exception. */
544
+ /** Pricing for every supported corridor. */
552
545
  pricing: {
553
546
  kind: 'oracle-market-rate';
554
547
  spreadBps: 0;
@@ -578,9 +571,7 @@ interface CashFillEta {
578
571
  * Estimate - currency + amount only. No payee, no side effects, no expiry,
579
572
  * idempotent, cacheable.
580
573
  *
581
- * Existing corridors read the same Chainlink feed the protocol uses when an
582
- * intent is signaled. Creation-rate corridors read Chainlink on Ethereum (CNY)
583
- * or Polygon (INR), fixing the fresh snapshot when preparing the deposit.
574
+ * Reads the same Base oracle feed the protocol uses when an intent is signaled.
584
575
  */
585
576
 
586
577
  interface EstimateInput {
@@ -591,7 +582,7 @@ interface EstimateInput {
591
582
  amount: bigint;
592
583
  /** Target fiat currency. */
593
584
  currency: CurrencyType;
594
- /** Optional payout platform for pricing semantics and pair-specific ETA sampling. */
585
+ /** Optional payout platform for pair-specific ETA sampling. */
595
586
  platform?: string;
596
587
  /** Optional Relay EVM source asset. Omit for the current Base USDC default path. */
597
588
  source?: RelaySourceInput & {
@@ -614,7 +605,7 @@ interface CashEstimate {
614
605
  /** Always `'oracle-estimate'`; inspect `binding` for when it becomes a maker floor. */
615
606
  kind: 'oracle-estimate';
616
607
  /** When this estimate becomes the deposit's binding maker floor. */
617
- binding?: 'intent-signal' | 'deposit-creation';
608
+ binding?: 'intent-signal';
618
609
  currency: CurrencyType;
619
610
  /** Base USDC amount that Peer Cash would deposit after any source routing. */
620
611
  amount: bigint;
@@ -691,14 +682,6 @@ interface CashClientOptions {
691
682
  };
692
683
  /** Optional ZKP2P API key. */
693
684
  apiKey?: string;
694
- /** Ethereum transport used only to snapshot Alipay/CNY's creation-time rate. */
695
- creationRateTransport?: Transport;
696
- /** Convenience alternative to `creationRateTransport`. */
697
- creationRateRpcUrl?: string;
698
- /** Polygon transport used only to snapshot UPI/INR's creation-time rate. */
699
- upiCreationRateTransport?: Transport;
700
- /** Convenience alternative to `upiCreationRateTransport`; requires Polygon mainnet. */
701
- upiCreationRateRpcUrl?: string;
702
685
  /** Relay API configuration for source assets outside Base USDC. */
703
686
  relay?: RelayOptions;
704
687
  /** NEAR Intents 1Click configuration for externally funded source routes. */
@@ -314,10 +314,7 @@ declare const BASE_CHAIN_ID = 8453;
314
314
  declare const BASE_USDC_ADDRESS: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913";
315
315
  /** USDC has 6 decimals. */
316
316
  declare const USDC_DECIMALS = 6;
317
- /**
318
- * Signal-time oracle corridors use zero spread. Alipay/CNY instead fixes a
319
- * fresh creation-time snapshot because Base has no CNY oracle adapter.
320
- */
317
+ /** Every corridor uses the signal-time oracle rate with zero spread. */
321
318
  declare const MARKET_SPREAD_BPS = 0;
322
319
  /**
323
320
  * EscrowV2 rejects a zero `minConversionRate` even when an oracle-backed rate
@@ -475,10 +472,6 @@ declare const RECOMMENDED_MIN_CASHOUT_AMOUNT = 1000000n;
475
472
  type CashCorridorPricing = {
476
473
  kind: 'oracle-at-intent-signal';
477
474
  spreadBps: 0;
478
- } | {
479
- kind: 'fixed-at-deposit-creation';
480
- source: 'chainlink-ethereum';
481
- spreadBps: 0;
482
475
  };
483
476
  interface CashPlatformCapability {
484
477
  /** Platform id, e.g. `'venmo'` - the value `receive.platform` accepts. */
@@ -548,7 +541,7 @@ interface CashCapabilities {
548
541
  recommendedMin: bigint;
549
542
  max: null;
550
543
  };
551
- /** Default pricing for corridors without a platform-level creation-time exception. */
544
+ /** Pricing for every supported corridor. */
552
545
  pricing: {
553
546
  kind: 'oracle-market-rate';
554
547
  spreadBps: 0;
@@ -578,9 +571,7 @@ interface CashFillEta {
578
571
  * Estimate - currency + amount only. No payee, no side effects, no expiry,
579
572
  * idempotent, cacheable.
580
573
  *
581
- * Existing corridors read the same Chainlink feed the protocol uses when an
582
- * intent is signaled. Creation-rate corridors read Chainlink on Ethereum (CNY)
583
- * or Polygon (INR), fixing the fresh snapshot when preparing the deposit.
574
+ * Reads the same Base oracle feed the protocol uses when an intent is signaled.
584
575
  */
585
576
 
586
577
  interface EstimateInput {
@@ -591,7 +582,7 @@ interface EstimateInput {
591
582
  amount: bigint;
592
583
  /** Target fiat currency. */
593
584
  currency: CurrencyType;
594
- /** Optional payout platform for pricing semantics and pair-specific ETA sampling. */
585
+ /** Optional payout platform for pair-specific ETA sampling. */
595
586
  platform?: string;
596
587
  /** Optional Relay EVM source asset. Omit for the current Base USDC default path. */
597
588
  source?: RelaySourceInput & {
@@ -614,7 +605,7 @@ interface CashEstimate {
614
605
  /** Always `'oracle-estimate'`; inspect `binding` for when it becomes a maker floor. */
615
606
  kind: 'oracle-estimate';
616
607
  /** When this estimate becomes the deposit's binding maker floor. */
617
- binding?: 'intent-signal' | 'deposit-creation';
608
+ binding?: 'intent-signal';
618
609
  currency: CurrencyType;
619
610
  /** Base USDC amount that Peer Cash would deposit after any source routing. */
620
611
  amount: bigint;
@@ -691,14 +682,6 @@ interface CashClientOptions {
691
682
  };
692
683
  /** Optional ZKP2P API key. */
693
684
  apiKey?: string;
694
- /** Ethereum transport used only to snapshot Alipay/CNY's creation-time rate. */
695
- creationRateTransport?: Transport;
696
- /** Convenience alternative to `creationRateTransport`. */
697
- creationRateRpcUrl?: string;
698
- /** Polygon transport used only to snapshot UPI/INR's creation-time rate. */
699
- upiCreationRateTransport?: Transport;
700
- /** Convenience alternative to `upiCreationRateTransport`; requires Polygon mainnet. */
701
- upiCreationRateRpcUrl?: string;
702
685
  /** Relay API configuration for source assets outside Base USDC. */
703
686
  relay?: RelayOptions;
704
687
  /** NEAR Intents 1Click configuration for externally funded source routes. */