Developers · Apps

Build a sell-USDC flow users can actually finish.

A good off-ramp app is mostly boring state management: collect the route, let the wallet sign, recover extension-gated payment methods, show a deposit link, and reconcile lifecycle events after the tab closes.

01

Frontend path

  1. 01Collect amount, payment platform, fiat currency, and payout identifier.
  2. 02Show the provider's current policy boundary and require the user to confirm account, region, and transaction eligibility.
  3. 03Pass the connected viem WalletClient to useOfframp() or createOfframp({ walletClient }).
  4. 04Surface progress states: approving, registering, depositing, confirming, delegating, restricting, resuming, done.
  5. 05For an eligible extension-gated route, catch EXTENSION_REGISTRATION_REQUIRED and drive usePeerExtensionRegistration(platform).
  6. 06Call deposits(address) on page load so a refresh does not strand an in-flight seller.
02

State you should store

FieldReason
depositIdPrimary handle for close(), OTC links, and support
txHashProof that the user signed and broadcast the deposit transaction
platform + currencyRoute display, support, and analytics segmentation
identifier labelHuman-readable payout reference; do not store secrets
integratorIdStable attribution for product telemetry and support
03

UX constraints

  • The SDK targets Base mainnet; there is no public sandbox. Test with the 1 USDC minimum.
  • Every SDK-created deposit delegates pricing to the Delegate vault. Do not present manual rate controls for this path.
  • Fiat stays outside the SDK. The buyer and seller settle directly inside the selected payment app.
  • Reconcile narrow owner state with deposits(); use Peerlytics API for broader market data, deposits, intents, and analytics.

Common questions

Should a wallet app use the standalone function or the React hook?

Use the React hook when you want built-in loading, progress, error, and result state. Use createOfframp({ walletClient }) when your app has its own state machine.

What should I show when PayPal or Wise fails registration?

First show the policy boundary: Wise prohibits P2P crypto-sale receipts and PayPal may require preapproval. Only for an eligible provider flow should you catch EXTENSION_REGISTRATION_REQUIRED, connect the extension, complete usePeerExtensionRegistration(), and retry.