> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pods.finance/llms.txt
> Use this file to discover all available pages before exploring further.

# RampWidget Integration

> Integrate Pods RampWidget for Pix fiat on-ramp and off-ramp

Use `RampWidget` to ship Pix fiat on-ramp and off-ramp UX while your host app still owns the wallet
and signing. **On-ramp** has no client-side signing — the user pays a Pix code and Pods settles the
crypto leg server-side. **Off-ramp** prompts the wallet for exactly one signature to send the
on-chain leg, then Pods pays out Pix.

<Note>
  Money-movement routes are available only after the wallet's Ramp KYC profile is `approved`. Pair
  this with the [KycWidget](/widgets/kyc-widget), and see [Set up Pods Ramp](/guides/ramp/setup).
</Note>

## Install

Use the same package set and the shared `PodsWidgetProvider` wrapper as `EarnWidget`, pinned to a
version that includes the ramp widget:

```bash theme={null}
pnpm add pods-sdk@0.2.119 @deframe-sdk/components@0.1.106 @reduxjs/toolkit@^2 react-redux@^9 redux@^5
```

<Note>
  Import `PodsProvider`, `EarnWidget`, `SwapWidget`, and `RampWidget` from `pods-sdk` so they share
  the same React context.
</Note>

## Styles and Theme

`RampWidget` follows the same styling model as `EarnWidget`: import
`@deframe-sdk/components/styles.css` once, keep host CSS scoped to `.pods-widget`, and theme via
`PodsProvider.config.theme`. See [EarnWidget Styles and Theme](/widgets/earn-widget#styles-and-theme).

## Choose a Route

`RampWidget` quotes exactly one crypto leg per instance, so it requires both a `mode`
(`onramp` | `offramp`) and a `rampRouteId`. Build a route picker from `getAvailableRampRoutes()` and
pass the user's choice.

| `rampRouteId`  | Asset | Chain           | Token                                        | Min |
| -------------- | ----- | --------------- | -------------------------------------------- | --- |
| `usdc-base`    | USDC  | Base (`8453`)   | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` | 5   |
| `usdc-monad`   | USDC  | Monad (`143`)   | `0x754704Bc059F8C67012fEd69BC8A327a5aafb603` | 5   |
| `brla-polygon` | BRLA  | Polygon (`137`) | `0xE6A537a407488807F0bbeb0038B79004f19DDDFb` | 5   |

```tsx theme={null}
import { getAvailableRampRoutes } from 'pods-sdk'

// All registered routes, or pass an allowlist: getAvailableRampRoutes(['usdc-base'])
const routes = getAvailableRampRoutes()
// routes[].id is the value you pass to RampWidget as `rampRouteId`
```

## Render the On-ramp

Mount `RampWidget` inside the shared `PodsWidgetProvider` from the Earn guide. On-ramp shows the
Pix payment instructions and has nothing for the user to sign — the crypto lands on
`currentUserWalletAddress` after the Pix payment settles.

```tsx theme={null}
'use client'

import { RampWidget } from 'pods-sdk'
import { PodsWidgetProvider } from './PodsWidgetProvider'

export function OnrampPage({ walletAddress }: { walletAddress: string }) {
  return (
    <PodsWidgetProvider walletAddress={walletAddress}>
      <div className="pods-widget-slot" data-testid="ramp-onramp">
        <RampWidget
          mode="onramp"
          rampRouteId="usdc-base"
          currentUserWalletAddress={walletAddress}
          autoHeight
          onTicketCreated={(ticket) => persist(ticket)}
          onComplete={({ success }) => console.log('onramp', success)}
        />
      </div>
    </PodsWidgetProvider>
  )
}
```

## Render the Off-ramp

Off-ramp collects the amount and the user's Pix key, then prompts the wallet for a **single**
signature. `currentUserWalletAddress` must be an `approved` Ramp wallet.

```tsx theme={null}
<RampWidget
  mode="offramp"
  rampRouteId="usdc-base"
  currentUserWalletAddress={walletAddress}
  autoHeight
  onTicketCreated={(ticket) => persist(ticket)}
  onStatusChange={(status) => syncStore(status)}
  onComplete={({ success, txHashes }) => console.log('offramp', success, txHashes)}
/>
```

## Gate on KYC

The SDK has no account concept, so the host tells the widget whether the wallet still needs
verification. When `isKycRequired` is `true`, the widget renders a "verify first" panel instead of
the amount form, and `onKycRequiredAction` fires when the user acts on it — route them to the
[KycWidget](/widgets/kyc-widget).

```tsx theme={null}
<RampWidget
  mode="onramp"
  rampRouteId="usdc-base"
  currentUserWalletAddress={walletAddress}
  isKycRequired={!kycApproved}
  onKycRequiredAction={() => router.push('/kyc')}
/>
```

## Track and Persist

A quote/bytecode round trip mints a single-use ticket. Persist it so a reactive poller can resume
after a page refresh.

* `onTicketCreated({ actionId, quoteId?, depositAddress? })` — fires once the ticket exists.
* `onStatusChange(status)` — mirrors every status poll into your own store.
* `onComplete({ success, txHashes? })` — fires once, when the flow reaches a terminal state.
* `onRouteChange(routeName)` — adapt host shell/analytics.

## `RampWidget` Props

```ts theme={null}
type RampWidgetProps = {
  mode: 'onramp' | 'offramp'          // required
  rampRouteId: 'usdc-base' | 'usdc-monad' | 'brla-polygon' // required
  currentUserWalletAddress?: string   // originAddress (offramp) / destinationAddress (onramp)
  isKycRequired?: boolean
  onKycRequiredAction?: () => void
  onTicketCreated?: (ticket: { actionId: string; quoteId?: string; depositAddress?: string }) => void
  onStatusChange?: (status: SwapStatusResponse) => void
  onComplete?: (outcome: { success: boolean; txHashes?: string[] }) => void
  onRouteChange?: (routeName: string) => void
  onTrack?: (event: string, props?: Record<string, unknown>) => void
  // Layout
  className?: string
  style?: React.CSSProperties
  height?: string | number
  enableScroll?: boolean
  autoHeight?: boolean
}
```

## API Endpoints Used in Ramp Flows

* `GET /v2/swap/quote` — price the on/off-ramp (origin/destination `fiat` selects the Pix rail)
* `POST /v2/swap/bytecode` — build the executable payload (`pixKey` on off-ramp payout)
* `GET /v2/swap/status/{id}` — track the ticket to a terminal state

Guides:

* [Move money with Pods Ramp](/guides/ramp/quotes)
* [Track Pods Ramp status](/guides/ramp/status)

## Transaction Bridge

Off-ramp signing uses the same `processBytecode` contract as `EarnWidget` and `SwapWidget`. See
[processBytecode Contract](/widgets/process-bytecode).
