@pafi-dev/trading 0.1.3 → 0.1.4

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.
Files changed (2) hide show
  1. package/README.md +44 -20
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -72,37 +72,61 @@ show a soft "unavailable" UI state without 500-ing.
72
72
 
73
73
  #### Frontend "quote review" pattern
74
74
 
75
- The mobile / web client should refresh `/quote` whenever the user types a
76
- new amount, so the swap CTA always shows the exact USDT they will
77
- receive (after the operator gas fee in USDT). Example: poll
78
- `GET /quote?chainId&pointToken&amount` on a 400 ms debounce after each
79
- keystroke and render a card with `pointAmount → estimatedUsdtOut −
80
- gasFeeUsdt = netUsdtOut` plus the `exchangeRate`.
75
+ Quotes are pure on-chain reads (Uniswap V4 Quoter via Base RPC) **no
76
+ auth, no issuer-side state, nothing to proxy through the issuer
77
+ backend.** Call `handleQuote` directly from the browser / React Native.
81
78
 
82
79
  ```tsx
83
- const [quote, setQuote] = useState<QuoteResponseDto | null>(null);
80
+ import { TradingHandlers, fetchPafiPools } from "@pafi-dev/trading";
81
+ import { createPublicClient, http, formatUnits } from "viem";
82
+ import { base } from "viem/chains";
83
+
84
+ const trading = new TradingHandlers({
85
+ provider: createPublicClient({ chain: base, transport: http(RPC_URL) }),
86
+ chainId: 8453,
87
+ });
84
88
 
85
89
  useEffect(() => {
86
- if (!token || amount <= 0n) return setQuote(null);
90
+ if (amount <= 0n) return setQuote(null);
87
91
  const t = setTimeout(async () => {
88
- const url = `${API}/quote?chainId=8453&pointToken=${POINT_TOKEN}&amount=${amount}`;
89
- const res = await fetch(url, { headers: { Authorization: `Bearer ${token}` } });
90
- setQuote(await res.json());
92
+ const pools = await fetchPafiPools(8453, POINT_TOKEN);
93
+ const result = await trading.handleQuote({
94
+ chainId: 8453,
95
+ pointTokenAddress: POINT_TOKEN,
96
+ amount,
97
+ pools,
98
+ });
99
+ setQuote(result);
91
100
  }, 400);
92
101
  return () => clearTimeout(t);
93
- }, [amount, token]);
102
+ }, [amount]);
94
103
 
95
- // quote.estimatedUsdtOut → "you will receive ~Y USDT"
96
- // quote.gasFeeUsdt → "operator gas fee deducted from output"
97
- // quote.netUsdtOut → "actually credited to your wallet"
98
- // quote.exchangeRate → "1 PT ${rate} USDT"
99
- // quote.quoteError render warning, hide the Swap CTA
104
+ // Render:
105
+ // In: formatUnits(amount, 18) PT
106
+ // You receive: formatUnits(quote.estimatedUsdtOut, 6) USDT
107
+ // Rate: estimatedUsdtOut · 1e18 / amount / 1e6 USDT per 1 PT
108
+ // On `quote.quoteError === "QUOTE_UNAVAILABLE"` hide the Swap CTA.
100
109
  ```
101
110
 
102
- A working implementation lives in
111
+ Why client-direct (no `GET /quote` HTTP hop):
112
+
113
+ - The quoter is stateless and reads from the public RPC — there's no
114
+ secret to hide and nothing to validate against an issuer's database.
115
+ - One fewer round-trip on every keystroke (debounce hits the Quoter
116
+ directly, ~150 ms vs. ~400 ms via a backend proxy).
117
+ - The quote stays internally consistent with the swap path that
118
+ `handleSwap` will pick — both use the same `findBestQuote()` call
119
+ under the hood with the same `pools` array, so what the user sees in
120
+ the review card is what they get on submit.
121
+
122
+ > **Operator fee in USDT** is **NOT** part of the quote — it's an
123
+ > issuer-policy concern decided at swap-build time. If you want a
124
+ > "net out after fee" preview, fetch the issuer's gas-fee endpoint
125
+ > separately and subtract on the client.
126
+
127
+ Reference implementation lives in
103
128
  [`privy-pimlico-eip7702-example/app/components/WalletPanel.tsx`](https://github.com/pacific-finance/pafi-backend/blob/main/privy-pimlico-eip7702-example/app/components/WalletPanel.tsx)
104
- (search for `Quote review`). It reuses the same `/quote` endpoint the
105
- issuer backend exposes — no extra SDK call needed on the client.
129
+ (search for `Quote review`).
106
130
 
107
131
  ---
108
132
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pafi-dev/trading",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Stateless on-chain trading handlers for PAFI — swap, quote, perp deposit",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",