@oasisprotocol/privana-sdk 0.2.1 → 0.4.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
@@ -216,23 +216,143 @@ A customizable button that opens the wallet modal.
216
216
 
217
217
  ## Hooks
218
218
 
219
- | Hook | Description |
220
- | ----------------------- | -------------------------------------- |
221
- | `useHostedRedirectAuth` | Hosted redirect auth for widget apps |
222
- | `useBalance` | Get token balance (available + locked) |
223
- | `useBatchBalances` | Get multiple token balances |
224
- | `useDeposit` | Deposit tokens |
225
- | `useWithdraw` | Withdraw tokens |
226
- | `useLockFunds` | Lock funds for a recipient |
227
- | `useUnlockFunds` | Unlock expired locks |
228
- | `useTransfer` | Transfer tokens |
229
- | `useLockedFunds` | Get list of locked funds |
230
- | `useTotalLockedBalance` | Get total locked balance for one token |
231
- | `useHistory` | Get authenticated account activity |
232
- | `usePendingWithdrawals` | Get pending withdrawal requests |
233
- | `useExpiredLocks` | Get expired locks that can be claimed |
234
- | `useTokenList` | List all registered tokens |
235
- | `useTokenInfo` | Get info for a single token |
219
+ | Hook | Description |
220
+ | ------------------------ | ------------------------------------------------------------------------------------------------------------------ |
221
+ | `useHostedRedirectAuth` | Hosted redirect auth for widget apps |
222
+ | `useBalance` | Get token balance (available + locked) |
223
+ | `useBatchBalances` | Get multiple token balances |
224
+ | `useDeposit` | Deposit tokens |
225
+ | `useDepositVerification` | Run checkDeposit + status polling against an existing on-chain transfer (used by `useDeposit` and `useFiatOnRamp`) |
226
+ | `useFiatOnRamp` | Buy crypto via MoonPay; delivered straight to the Privana deposit address (from `/on-ramp` sub-export) |
227
+ | `useWithdraw` | Withdraw tokens |
228
+ | `useLockFunds` | Lock funds for a recipient |
229
+ | `useUnlockFunds` | Unlock expired locks |
230
+ | `useTransfer` | Transfer tokens |
231
+ | `useLockedFunds` | Get list of locked funds |
232
+ | `useTotalLockedBalance` | Get total locked balance for one token |
233
+ | `useHistory` | Get authenticated account activity |
234
+ | `usePendingWithdrawals` | Get pending withdrawal requests |
235
+ | `useExpiredLocks` | Get expired locks that can be claimed |
236
+ | `useTokenList` | List all registered tokens |
237
+ | `useTokenInfo` | Get info for a single token |
238
+
239
+ ## Fiat On-Ramp
240
+
241
+ The fiat on-ramp lets users buy tokens with a card and have them credited to
242
+ their Privana balance in one flow. **MoonPay delivers the purchased token
243
+ directly to the user's Privana deposit address**.
244
+
245
+ Exported from a separate entry point so consumers who don't use the on-ramp
246
+ don't pay the bundle cost of `@moonpay/moonpay-react`:
247
+
248
+ ```tsx
249
+ import { FiatOnRampForm, useFiatOnRamp } from '@oasisprotocol/privana-sdk/on-ramp'
250
+ ```
251
+
252
+ ### Setup
253
+
254
+ The SDK ships `@moonpay/moonpay-react` as a regular dependency, so it lands in
255
+ your `node_modules` automatically. If you import `<MoonPayProvider>` directly
256
+ (see below) you may also want to declare it in your own `package.json` to keep
257
+ your dependency surface explicit:
258
+
259
+ ```bash
260
+ npm install @moonpay/moonpay-react
261
+ ```
262
+
263
+ Wrap your app in `<MoonPayProvider>` (only on routes that use the on-ramp,
264
+ to keep MoonPay out of unrelated bundles):
265
+
266
+ ```tsx
267
+ import { MoonPayProvider } from '@moonpay/moonpay-react'
268
+ ;<MoonPayProvider apiKey={import.meta.env.VITE_MOONPAY_API_KEY} debug={import.meta.env.DEV}>
269
+ {/* on-ramp routes */}
270
+ </MoonPayProvider>
271
+ ```
272
+
273
+ ### Quick start with `<FiatOnRampForm>`
274
+
275
+ ```tsx
276
+ import { FiatOnRampForm } from '@oasisprotocol/privana-sdk/on-ramp'
277
+ ;<FiatOnRampForm
278
+ tokenId="0x..." // Privana token id (e.g. USDC on Base)
279
+ currencyCode="usdc_base" // MoonPay currency code; test/live is controlled by the apiKey (pk_test_* → testnet, pk_live_* → mainnet)
280
+ baseCurrencyCode="usd" // optional, defaults to "usd"
281
+ defaultBaseCurrencyAmount="100" // optional pre-fill (MoonPay still lets the user edit)
282
+ onCredited={(txHash) => console.log('credited', txHash)}
283
+ onError={(err) => console.error(err)}
284
+ />
285
+ ```
286
+
287
+ The form:
288
+
289
+ - fetches the user's Privana deposit address and passes it to MoonPay as the
290
+ destination,
291
+ - sets `externalCustomerId = address.toLowerCase()` so the backend can bind the
292
+ MoonPay transaction to the SIWE-authenticated user,
293
+ - creates a backend on-ramp intent (`POST /onramp/intent`) and passes its id to
294
+ MoonPay as `externalTransactionId` so the webhook can correlate later,
295
+ - gates the "Buy" button on the configured token's minimum deposit (input-time
296
+ check) and double-checks the delivered amount before triggering verification,
297
+ - on MoonPay's `transaction_created`, fire-and-forget calls
298
+ `POST /onramp/{id}` with the MoonPay transaction id so the backend can
299
+ reconcile both ids once the delivery webhook lands,
300
+ - listens for MoonPay's `transaction_completed` event, waits up to 120s for
301
+ the backend webhook to surface the on-chain tx hash, then triggers Privana
302
+ verification (`checkDeposit` + status polling).
303
+
304
+ ### `useFiatOnRamp` for custom UI
305
+
306
+ If you need a different shell around the MoonPay widget, use the hook
307
+ directly and wire MoonPay's widget callbacks yourself:
308
+
309
+ ```tsx
310
+ import { MoonPayBuyWidget } from '@moonpay/moonpay-react'
311
+ import { useFiatOnRamp } from '@oasisprotocol/privana-sdk/on-ramp'
312
+
313
+ const {
314
+ status, // 'idle' | 'awaiting-purchase' | 'awaiting-delivery' | 'verifying' | 'credited' | 'failed'
315
+ activeIntentId, // pass to MoonPay as externalTransactionId
316
+ pending, // recovery list (completed-but-unverified)
317
+ error,
318
+ depositAddress, // pass to MoonPay as walletAddress
319
+ minDepositBaseUnits, // for input validation
320
+ selectedToken, // resolved token config (decimals/symbol for the configured tokenId)
321
+ prepareOnRampIntent, // call before opening the widget
322
+ signUrl, // wire to onUrlSignatureRequested
323
+ handleTransactionCreated, // wire to onTransactionCreated
324
+ handleTransactionCompleted, // wire to onTransactionCompleted
325
+ handleWidgetClosed, // call from onClose / onCloseOverlay
326
+ finishPendingVerification, // call from the recovery CTA
327
+ refreshPending, // manual refresh of the pending list
328
+ } = useFiatOnRamp({ tokenId, onCredited, onError })
329
+ ```
330
+
331
+ ### Pending / recovery
332
+
333
+ If the user closes the tab between MoonPay completion and verification, the
334
+ backend has already received the webhook and the row appears in `pending`.
335
+ Render the list with a "Finish verification" CTA that calls
336
+ `finishPendingVerification(record)` — no wallet signature required, just the
337
+ verification poll.
338
+
339
+ ### Required backend endpoints
340
+
341
+ The `useFiatOnRamp` hook + form call:
342
+
343
+ - `POST /v1/accounting/onramp/sign-url` — HMAC-signs the MoonPay widget URL
344
+ - `POST /v1/accounting/onramp/intent` — creates the Privana intent row that ties a MoonPay transaction to the SIWE'd user + Privana token
345
+ - `POST /v1/accounting/onramp/{transaction_id}` — upserts MoonPay transaction metadata (fire-and-forget on `transaction_created`)
346
+ - `GET /v1/accounting/onramp/pending` — completed MoonPay txs awaiting verification
347
+
348
+ And the existing deposit verification endpoints:
349
+
350
+ - `POST /v1/accounting/deposits/check`
351
+ - `GET /v1/accounting/deposits/status/{id}`
352
+
353
+ MoonPay → backend webhook (`POST /v1/accounting/onramp/webhook`) is what
354
+ populates the pending list with the on-chain tx hash. Configure that URL in
355
+ your MoonPay dashboard.
236
356
 
237
357
  ## License
238
358