> ## Documentation Index
> Fetch the complete documentation index at: https://turnkey-0e7c1f5b-ethan-captcha-protection.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Fiat Onramp

> This is a guide to implementing Fiat Onramps within a Turnkey-powered application.

## Using @turnkey/react-wallet-kit

Setting up Fiat Onramp with [@turnkey/react-wallet-kit](https://www.npmjs.com/package/@turnkey/react-wallet-kit) is straightforward.

### handleOnRamp

The `handleOnRamp()` helper abstracts the process of initializing and launching a fiat on-ramp flow as well as polling transaction status.

```ts theme={null}
import { handleOnRamp } from "@turnkey/react-wallet-kit";

  const handleAddFunds = async () => {
    try {
      await handleOnRamp({
        onrampProvider: "FIAT_ON_RAMP_PROVIDER_MOONPAY",
        walletAccount: selectedWalletAccount!,
        sandboxMode: true,
      });
    } catch (error) {
      handleError(error);
    }
  };

```

## White Label Implementation

If you prefer a more **white label** approach, you can replicate the behavior of `handleOnRamp()` directly in your own app.\
This allows full control over how you open the provider's UI, manage state, and poll transaction status.

The general flow is:

1. Call `initFiatOnRamp()` with your desired parameters to receive the `onRampUrl` and `onRampTransactionId`.
2. Open the `onRampUrl` in a popup or new tab for the user to complete their purchase.
3. Poll `getOnRampTransactionStatus()` periodically until the transaction is `COMPLETED`, `FAILED`, or `CANCELLED`.
4. Handle cleanup and UI updates accordingly.

Below is a simplified example inspired by the internal `handleOnRamp()` implementation:

```ts theme={null}
import { useState, useRef, useEffect } from "react";
import {
  FiatOnRampCryptoCurrency,
  FiatOnRampBlockchainNetwork,
} from "@turnkey/sdk-types";
import { useTurnkey } from "@turnkey/react-wallet-kit";

async function whiteLabelOnRamp(walletAccount, organizationId) {
  const { client } = useTurnkey();
  let cryptoCurrencyCode;
  let network;

  switch (true) {
    case walletAccount.addressFormat === "ADDRESS_FORMAT_ETHEREUM":
      cryptoCurrencyCode = FiatOnRampCryptoCurrency.ETHEREUM;
      network = FiatOnRampBlockchainNetwork.ETHEREUM;
      break;
    case walletAccount.addressFormat?.includes("ADDRESS_FORMAT_BITCOIN"):
      cryptoCurrencyCode = FiatOnRampCryptoCurrency.BITCOIN;
      network = FiatOnRampBlockchainNetwork.BITCOIN;
      break;
    case walletAccount.addressFormat === "ADDRESS_FORMAT_SOLANA":
      cryptoCurrencyCode = FiatOnRampCryptoCurrency.SOLANA;
      network = FiatOnRampBlockchainNetwork.SOLANA;
      break;
    default:
      cryptoCurrencyCode = FiatOnRampCryptoCurrency.ETHEREUM;
      network = FiatOnRampBlockchainNetwork.ETHEREUM;
      break;
  }

  // Step 1: Initialize the on-ramp
  const result = await client.httpClient.initFiatOnRamp({
    onrampProvider: "FIAT_ON_RAMP_PROVIDER_MOONPAY",
    organizationId,
    walletAddress: walletAccount.address,
    network,
    cryptoCurrencyCode,
    sandboxMode: true,
  });

  if (!result?.onRampUrl || !result?.onRampTransactionId) {
    throw new Error("Invalid onramp initialization response");
  }

  // Step 2: Open the on-ramp URL
  const popup = window.open(result.onRampUrl, "_blank", "width=500,height=600");
  if (!popup) throw new Error("Failed to open on-ramp window");

  // Step 3: Poll the transaction status
  const pollInterval = setInterval(async () => {
    try {
      const statusResp = await client.httpClient.getOnRampTransactionStatus({
        transactionId: result.onRampTransactionId,
        refresh: true,
      });
      const status = statusResp?.transactionStatus;

      if (["COMPLETED", "FAILED", "CANCELLED"].includes(status ?? "")) {
        clearInterval(pollInterval);
        popup.close();
        console.log("On-ramp status:", status);
      }
    } catch (err) {
      console.warn("Polling error:", err);
    }
  }, 3000);
}
```

This approach gives you:

* Full control over the UI and provider window handling.
* The ability to customize polling intervals, completion logic, and error handling.
* A foundation for integrating custom analytics, logging, or notifications.

## Example

See our example app leveraging `handleOnRamp` [here](https://wallets.turnkey.com/) and the code [here](https://github.com/tkhq/sdk/blob/81884b2ae57f6054d45eb8009f191793c3c46aa8/examples/react-wallet-kit/src/components/demo/DemoPanel.tsx#L116)
