@oasisprotocol/privana-sdk 0.5.7 → 0.5.8

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
@@ -225,6 +225,7 @@ Notes:
225
225
  | `useDeposit` | Deposit tokens |
226
226
  | `useDepositVerification` | Run checkDeposit + status polling against an existing on-chain transfer (used by `useDeposit` and `useFiatOnRamp`) |
227
227
  | `useFiatOnRamp` | MoonPay on-ramp with provider-neutral recovery, verification, credit, and locking (from `/on-ramp` sub-export) |
228
+ | `useTransakOnRamp` | Explicit Transak session launch and hardened iframe over the same shared recovery and credit core |
228
229
  | `useWithdraw` | Withdraw tokens |
229
230
  | `useLockFunds` | Lock funds for a recipient |
230
231
  | `useUnlockFunds` | Unlock expired locks |
@@ -242,20 +243,47 @@ Notes:
242
243
  The fiat on-ramp lets users buy tokens with a card and have them credited to
243
244
  their Privana balance in one flow. An internal provider-neutral core owns
244
245
  recovery, receipt verification, `/deposits/check`, credit, and optional
245
- post-credit locking. MoonPay launch and widget behavior live in a thin adapter.
246
+ post-credit locking. MoonPay and Transak launch and widget behavior live in thin
247
+ provider-specific adapters.
248
+
249
+ The SDK product modals select one provider, token, and provider-side asset at
250
+ the `PrivanaProvider` boundary:
251
+
252
+ ```tsx
253
+ <PrivanaProvider
254
+ networkConfig={networkConfig}
255
+ onRamp={{
256
+ provider: 'transak',
257
+ tokenId: '0x...',
258
+ providerAssetCode: 'usdc',
259
+ }}
260
+ >
261
+ <App />
262
+ </PrivanaProvider>
263
+ ```
264
+
265
+ An explicit configuration locks card purchases to that token and fails closed
266
+ if the provider, token, or asset is invalid. When `onRamp` is omitted, the
267
+ product modal preserves its existing MoonPay behavior using
268
+ `networkConfig.moonpayApiKey` and the token's MoonPay mapping.
269
+
270
+ For Transak, the product modal requires a target at least 5% above Privana's
271
+ on-chain minimum. This margin reduces the risk that provider estimate movement
272
+ delivers a paid purchase below the amount that Privana can verify.
246
273
 
247
274
  **The provider delivers the purchased token directly to the server-derived
248
275
  Privana deposit address. Provider orders, amounts, events, and webhooks are
249
- correlation hints only; the matching on-chain transfer remains authoritative.**
276
+ correlation hints only. One unambiguous matching on-chain transfer, including
277
+ its exact receipt log index, remains authoritative.**
250
278
 
251
279
  Exported from a separate entry point so consumers who don't use the on-ramp
252
280
  don't pay the bundle cost of `@moonpay/moonpay-react`:
253
281
 
254
282
  ```tsx
255
- import { FiatOnRampForm, useFiatOnRamp } from '@oasisprotocol/privana-sdk/on-ramp'
283
+ import { FiatOnRampForm, useFiatOnRamp, useTransakOnRamp } from '@oasisprotocol/privana-sdk/on-ramp'
256
284
  ```
257
285
 
258
- ### Setup
286
+ ### MoonPay setup
259
287
 
260
288
  The SDK ships `@moonpay/moonpay-react` as a regular dependency, so it lands in
261
289
  your `node_modules` automatically. If you import `<MoonPayProvider>` directly
@@ -307,8 +335,8 @@ The form:
307
335
  reconcile both ids during provider reads,
308
336
  - treats MoonPay events as wake-up hints, polls the authenticated pending read
309
337
  for the provider transaction and on-chain hash, derives the delivered amount
310
- from matching receipt logs, then triggers Privana verification
311
- (`checkDeposit` + status polling).
338
+ and exact log index from one unambiguous matching receipt log, then triggers
339
+ Privana verification (`checkDeposit` + status polling).
312
340
 
313
341
  ### `useFiatOnRamp` for custom UI
314
342
 
@@ -337,6 +365,58 @@ const {
337
365
  } = useFiatOnRamp({ tokenId, onCredited, onError })
338
366
  ```
339
367
 
368
+ ### `useTransakOnRamp` for a Transak checkout
369
+
370
+ Transak credentials and session creation remain in the backend. Call `launch`
371
+ only from an explicit user action; it creates the signed intent and then requests
372
+ one five-minute, single-use session. The hook keeps the opaque URL in memory and
373
+ returns a hardened iframe as `widget`:
374
+
375
+ ```tsx
376
+ import { useTransakOnRamp } from '@oasisprotocol/privana-sdk/on-ramp'
377
+
378
+ function TransakCheckout({ tokenId }) {
379
+ const {
380
+ widget,
381
+ isLaunching,
382
+ isWidgetOpen,
383
+ launch,
384
+ recreateSession,
385
+ closeWidget,
386
+ pending,
387
+ finishPendingVerification,
388
+ } = useTransakOnRamp({ tokenId, onCredited, onError })
389
+
390
+ return (
391
+ <>
392
+ <button
393
+ disabled={isLaunching || isWidgetOpen}
394
+ onClick={() => void launch({ providerAssetCode: 'usdc' }).catch(() => undefined)}
395
+ >
396
+ Buy with card
397
+ </button>
398
+ {widget}
399
+ </>
400
+ )
401
+ }
402
+ ```
403
+
404
+ Before each session request, including an authenticated retry or explicit
405
+ reopen, the SDK sends only the SHA-256 hash of the signed intent to the
406
+ same-origin `/__onramp-ip-attest` Worker and passes its fresh opaque claim to
407
+ the backend. The host must deploy that route on its Transak-approved origin.
408
+
409
+ `recreateSession()` retries the current unresolved intent only when its session
410
+ failed or expired before the provider iframe became interactive. After the
411
+ provider UI activates or order evidence exists, the adapter refuses to create a
412
+ second provider order under that intent. Unmount the direct hook to abandon its
413
+ local checkout UI; durable signed-intent recovery remains available. The
414
+ adapter uses the backend URL byte-for-byte, preserves the browser `Referer`, and
415
+ accepts messages only from the current iframe at the exact documented Transak
416
+ origin. Widget messages are polling hints only. Authenticated
417
+ `/onramp/pending` reads and the matching on-chain ERC-20 transfer remain the
418
+ recovery and credit path.
419
+
340
420
  ### Pending / recovery
341
421
 
342
422
  If the user closes or reloads between launch and verification, the SDK reloads
@@ -348,9 +428,10 @@ signature is required for deposit verification.
348
428
 
349
429
  ### Required backend endpoints
350
430
 
351
- The `useFiatOnRamp` hook + form call:
431
+ The provider adapters call:
352
432
 
353
433
  - `POST /v1/accounting/onramp/sign-url` — HMAC-signs the MoonPay widget URL
434
+ - `POST /v1/accounting/onramp/session` — creates a short-lived opaque Transak widget URL
354
435
  - `POST /v1/accounting/onramp/intent` — mints a signed provider/user/wallet/token/chain/asset intent
355
436
  - `POST /v1/accounting/onramp/{transaction_id}` — validates and echoes MoonPay compatibility metadata without becoming order state
356
437
  - `GET /v1/accounting/onramp/pending` — bounded provider reads for completed, strictly admitted transactions awaiting verification