@provex/react 1.2.3

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 ADDED
@@ -0,0 +1,441 @@
1
+ # @provex/react
2
+
3
+ Portable React buy-flow component and hooks for the Provex protocol. Framework-agnostic (no Chakra, no styled-components) — works in any React app.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @provex/react @provex/indexer-client react viem
9
+ # or
10
+ yarn add @provex/react @provex/indexer-client react viem
11
+ ```
12
+
13
+ ### Peer Dependencies
14
+
15
+ | Package | Version |
16
+ |---------|---------|
17
+ | `react` | `^18.0.0` |
18
+ | `viem` | `^2.0.0` |
19
+ | `wagmi` | `^2.0.0` (optional — only needed for `useWagmiWallet`) |
20
+
21
+ ## Quick Start
22
+
23
+ ### 1. Wrap your app with ProvexProvider
24
+
25
+ ```tsx
26
+ import { ProvexProvider } from '@provex/react'
27
+ import { createPonderAdapter } from '@provex/indexer-client'
28
+ import { pulsechain } from 'viem/chains'
29
+
30
+ const indexer = createPonderAdapter()
31
+
32
+ function App() {
33
+ return (
34
+ <ProvexProvider
35
+ config={{
36
+ apiUrl: 'https://app.provex.com',
37
+ chain: pulsechain, // viem Chain object
38
+ }}
39
+ indexer={indexer}
40
+ >
41
+ <YourApp />
42
+ </ProvexProvider>
43
+ )
44
+ }
45
+ ```
46
+
47
+ ### 2. Add the buy widget
48
+
49
+ **With wagmi (easiest):**
50
+
51
+ ```tsx
52
+ import { ProvexBuyWagmi } from '@provex/react'
53
+ import '@provex/react/styles'
54
+
55
+ function BuyPage() {
56
+ return (
57
+ <ProvexBuyWagmi
58
+ onIntentSignaled={(hash, chainId) => console.log('Order placed:', hash)}
59
+ onComplete={(hash, chainId) => console.log('Purchase complete:', hash)}
60
+ />
61
+ )
62
+ }
63
+ ```
64
+
65
+ `ProvexBuyWagmi` reads the connected wallet from wagmi context automatically. Your app just needs `WagmiProvider` and `ProvexProvider` above it.
66
+
67
+ **With any wallet:**
68
+
69
+ ```tsx
70
+ import { ProvexBuy } from '@provex/react'
71
+ import '@provex/react/styles'
72
+
73
+ function BuyPage() {
74
+ const wallet = {
75
+ address: connectedAddress,
76
+ sendTransaction: async (tx) => {
77
+ // Your wallet's sendTransaction implementation
78
+ return txHash
79
+ },
80
+ }
81
+
82
+ return (
83
+ <ProvexBuy
84
+ wallet={wallet}
85
+ onComplete={(hash, chainId) => console.log('Done!', hash)}
86
+ />
87
+ )
88
+ }
89
+ ```
90
+
91
+ ## Three Layers
92
+
93
+ Use whichever layer matches your needs:
94
+
95
+ | Layer | Export | Use case |
96
+ |-------|--------|----------|
97
+ | 3 | `<ProvexBuy>` / `<ProvexBuyWagmi>` | Drop-in widget, zero UI code |
98
+ | 2 | `<ProvexBuyProvider>` + phase components | Custom layout, same state machine |
99
+ | 1 | `useProvexBuy()` | Fully custom UI, just the state machine |
100
+
101
+ ### Layer 2 — Custom layout
102
+
103
+ ```tsx
104
+ import {
105
+ ProvexBuyProvider,
106
+ BrowsePhase,
107
+ CommittedPhase,
108
+ ProvingPhase,
109
+ CompletePhase,
110
+ } from '@provex/react'
111
+
112
+ function CustomBuy({ wallet }) {
113
+ return (
114
+ <ProvexBuyProvider wallet={wallet} onComplete={handleDone}>
115
+ <div className="my-layout">
116
+ <BrowsePhase />
117
+ <CommittedPhase />
118
+ <ProvingPhase />
119
+ <CompletePhase />
120
+ </div>
121
+ </ProvexBuyProvider>
122
+ )
123
+ }
124
+ ```
125
+
126
+ ### Layer 1 — Headless hook
127
+
128
+ ```tsx
129
+ import { useProvexBuy } from '@provex/react'
130
+
131
+ function CustomBuy({ wallet }) {
132
+ const {
133
+ phase,
134
+ amount, setAmount,
135
+ deposits, selectedDeposit,
136
+ rate, rateDisplay,
137
+ canSubmit, validationMessage,
138
+ submitOrder, confirmPayment, reset,
139
+ } = useProvexBuy({ wallet })
140
+
141
+ // Render your own UI using the state machine
142
+ }
143
+ ```
144
+
145
+ ## ProveXClient (Framework-Agnostic)
146
+
147
+ For Node.js, serverless, or non-React apps, use the core client directly:
148
+
149
+ ```ts
150
+ import { createProveXClient } from '@provex/react'
151
+ import { pulsechain } from 'viem/chains'
152
+
153
+ const client = createProveXClient({
154
+ chain: pulsechain,
155
+ wallet: myWalletAdapter,
156
+ })
157
+
158
+ // Create a deposit
159
+ const { hash } = await client.createDeposit({
160
+ token: USDC_ADDRESS,
161
+ amount: 1000_000000n,
162
+ paymentMethods: [
163
+ { provider: 'venmo', payeeId: '@myvenmo', currencies: [{ code: 'USD', minRate: 0n }] },
164
+ ],
165
+ })
166
+
167
+ // Signal intent (buy side)
168
+ const { intentHash } = await client.signalIntent({
169
+ deposit: { escrow: '0x...', localId: 1n },
170
+ paymentMethod: paymentMethodHash,
171
+ tokenAmount: 100_000000n,
172
+ toAddress: buyerAddress,
173
+ fiatCurrencyCode: currencyHash,
174
+ conversionRate: rate,
175
+ })
176
+
177
+ // Prepare-only mode (for smart accounts, relayers, multisigs)
178
+ const prepared = await client.addFunds.prepare({ depositId: 1n, amount: 500_000000n })
179
+ // → { to, data, value, chainId } — hand to Safe SDK, Privy, etc.
180
+ ```
181
+
182
+ ## Hooks API
183
+
184
+ ### useDeposits
185
+
186
+ Fetch available deposits matching a payment method and token.
187
+
188
+ ```tsx
189
+ import { useDeposits, getRate } from '@provex/react'
190
+
191
+ const { deposits, isLoading, getMatchableDeposits } = useDeposits({
192
+ token: usdcToken,
193
+ paymentMethod: 'venmo',
194
+ })
195
+
196
+ const matches = getMatchableDeposits('100') // $100
197
+ ```
198
+
199
+ ### useSignalIntent
200
+
201
+ Signal intent to buy tokens (lock USDC in escrow).
202
+
203
+ ```tsx
204
+ import { useSignalIntent } from '@provex/react'
205
+
206
+ const { startOrder, status, message, isLoading } = useSignalIntent({
207
+ wallet,
208
+ chainId: 369,
209
+ deposit: selectedDeposit,
210
+ onSuccess: (intentHash) => navigate(`/verify/${intentHash}`),
211
+ })
212
+ ```
213
+
214
+ ### useReputation
215
+
216
+ Fetch the connected user's reputation tier and cooldown status.
217
+
218
+ ```tsx
219
+ import { useReputation, getTierDisplayInfo } from '@provex/react'
220
+
221
+ const { reputation, isLoading } = useReputation({
222
+ address: walletAddress,
223
+ chainId: 369,
224
+ })
225
+
226
+ const tierInfo = getTierDisplayInfo(reputation.tier)
227
+ ```
228
+
229
+ ### useReputationLimits
230
+
231
+ Calculate trading limits based on reputation and payment method.
232
+
233
+ ```tsx
234
+ import { useReputationLimits } from '@provex/react'
235
+
236
+ const { effectiveCap, isOnCooldown, cooldownRemaining } = useReputationLimits({
237
+ chainId: 369,
238
+ selectedPaymentMethod: 'venmo',
239
+ tier: reputation.tier,
240
+ amountInInt: parseUnits('100', { decimals: 2 }),
241
+ })
242
+ ```
243
+
244
+ ### useProtocolFees
245
+
246
+ Read protocol fees from the on-chain Orchestrator contract.
247
+
248
+ ```tsx
249
+ import { useProtocolFees } from '@provex/react'
250
+
251
+ const { feeInfo, isLoading } = useProtocolFees({
252
+ chainId: 8453,
253
+ escrowAddress: '0x...',
254
+ })
255
+ ```
256
+
257
+ ### usePayeeDetails
258
+
259
+ Fetch intent details and payee information for the verification flow.
260
+
261
+ ```tsx
262
+ import { usePayeeDetails } from '@provex/react'
263
+
264
+ const { intent, intentStatus, payeeDetails, isFetching } = usePayeeDetails({
265
+ intentHash: '0xabc...',
266
+ chainId: 369,
267
+ })
268
+ ```
269
+
270
+ ### useWagmiWallet
271
+
272
+ Bridge wagmi's wallet to the `WalletAdapter` interface.
273
+
274
+ ```tsx
275
+ import { useWagmiWallet } from '@provex/react'
276
+
277
+ const wallet = useWagmiWallet()
278
+ // Returns WalletAdapter | null (null when disconnected)
279
+ ```
280
+
281
+ ## WalletAdapter Interface
282
+
283
+ The `WalletAdapter` decouples @provex/react from any specific wallet SDK.
284
+
285
+ ```ts
286
+ interface WalletAdapter {
287
+ address?: `0x${string}`
288
+ sendTransaction(tx: {
289
+ to: `0x${string}`
290
+ data: `0x${string}`
291
+ value?: bigint
292
+ chainId: number
293
+ maxFeePerGas?: bigint
294
+ maxPriorityFeePerGas?: bigint
295
+ }): Promise<`0x${string}`>
296
+ readContract?(params: {
297
+ address: `0x${string}`
298
+ abi: readonly unknown[]
299
+ functionName: string
300
+ args?: readonly unknown[]
301
+ chainId?: number
302
+ }): Promise<unknown>
303
+ }
304
+ ```
305
+
306
+ Only `sendTransaction` is required. `readContract` is optional — the client falls back to public RPC.
307
+
308
+ ## IndexerAdapter
309
+
310
+ The `IndexerAdapter` decouples data fetching from any specific indexer backend. Use `createPonderAdapter()` from `@provex/indexer-client` for the standard Provex setup, or implement your own against The Graph, a REST API, or direct RPC.
311
+
312
+ ```ts
313
+ import { createPonderAdapter } from '@provex/indexer-client'
314
+
315
+ const indexer = createPonderAdapter()
316
+ ```
317
+
318
+ ## Styling
319
+
320
+ ### Default Stylesheet
321
+
322
+ Import the built-in styles for a functional baseline:
323
+
324
+ ```tsx
325
+ import '@provex/react/styles'
326
+ ```
327
+
328
+ ### CSS Custom Properties
329
+
330
+ Override any CSS variable on the `[data-provex-root]` selector:
331
+
332
+ ```css
333
+ [data-provex-root] {
334
+ --provex-color-bg: #0f0f23;
335
+ --provex-color-primary: #00d4aa;
336
+ --provex-color-text: #ffffff;
337
+ --provex-border-radius: 12px;
338
+ --provex-max-width: 480px;
339
+ }
340
+ ```
341
+
342
+ Available variables:
343
+
344
+ | Variable | Default (light) | Description |
345
+ |----------|----------------|-------------|
346
+ | `--provex-color-bg` | `#ffffff` | Background color |
347
+ | `--provex-color-surface` | `#f8f9fa` | Surface/card color |
348
+ | `--provex-color-border` | `#e2e8f0` | Border color |
349
+ | `--provex-color-text` | `#1a202c` | Primary text color |
350
+ | `--provex-color-text-secondary` | `#718096` | Secondary text |
351
+ | `--provex-color-primary` | `#3b82f6` | Primary accent |
352
+ | `--provex-color-primary-hover` | `#2563eb` | Hover state |
353
+ | `--provex-color-success` | `#10b981` | Success color |
354
+ | `--provex-color-error` | `#ef4444` | Error color |
355
+ | `--provex-space-*` | various | Spacing (xs, sm, md, lg, xl) |
356
+ | `--provex-font-family` | system stack | Font family |
357
+ | `--provex-font-size-*` | various | Font sizes (sm, md, lg, xl) |
358
+ | `--provex-border-radius` | `0.5rem` | Border radius |
359
+ | `--provex-max-width` | `420px` | Max component width |
360
+
361
+ ### Theme Prop
362
+
363
+ Pass theme overrides directly to the widget:
364
+
365
+ ```tsx
366
+ <ProvexBuy
367
+ wallet={wallet}
368
+ theme={{
369
+ accent: '#00d4aa',
370
+ background: '#0f0f23',
371
+ text: '#ffffff',
372
+ radius: '12px',
373
+ }}
374
+ />
375
+ ```
376
+
377
+ ### className Prop
378
+
379
+ Pass a `className` to the root element for framework-specific styling:
380
+
381
+ ```tsx
382
+ <ProvexBuy wallet={wallet} className="my-custom-buy-widget" />
383
+ ```
384
+
385
+ ### Data Attributes
386
+
387
+ All elements use `data-provex-*` attributes for CSS targeting:
388
+
389
+ ```css
390
+ [data-provex-button="buy"] { ... }
391
+ [data-provex-input="amount"] { ... }
392
+ [data-provex-phase="browse"] { ... }
393
+ [data-provex-phase="committed"] { ... }
394
+ [data-provex-phase="complete"] { ... }
395
+ [data-provex-message="error"] { ... }
396
+ [data-provex-message="validation"] { ... }
397
+ ```
398
+
399
+ ### Dark Mode
400
+
401
+ The default stylesheet responds to `prefers-color-scheme: dark` automatically. To force a theme, override the CSS variables.
402
+
403
+ ## Configuration
404
+
405
+ ### ProvexConfig
406
+
407
+ ```ts
408
+ interface ProvexConfig {
409
+ apiUrl: string // Provex backend API URL
410
+ chain: Chain // viem Chain object (from viem/chains)
411
+ }
412
+ ```
413
+
414
+ ### ProvexProviderProps
415
+
416
+ ```ts
417
+ interface ProvexProviderProps {
418
+ config: ProvexConfig
419
+ indexer: IndexerAdapter // Data source (use createPonderAdapter())
420
+ queryClient?: QueryClient // Optional external React Query client
421
+ children: React.ReactNode
422
+ }
423
+ ```
424
+
425
+ ### BuyProps
426
+
427
+ ```ts
428
+ interface BuyProps {
429
+ wallet: WalletAdapter
430
+ onIntentSignaled?: (intentHash: string, chainId: number) => void
431
+ onComplete?: (intentHash: string, chainId: number) => void
432
+ paymentMethods?: ProviderKey[]
433
+ className?: string
434
+ style?: React.CSSProperties
435
+ theme?: ProvexTheme
436
+ }
437
+ ```
438
+
439
+ ## License
440
+
441
+ Private — Provex Protocol