Skip to main content

Funding the embedded wallet

Once your user has an embedded wallet, they likely need assets in the wallet to make purchases and pay gas fees.

Privy makes it simple for your user to fund their embedded wallet with a variety of assets, through our default fiat on-ramp integration with MoonPay. Using MoonPay, your users can purchase cryptocurrency via familiar payment methods including bank (ACH) transfer, credit/debit cards, and mobile payment providers like Google or Apple Pay.

To use MoonPay's fiat on-ramp in your app, follow the instructions below!


Fiat on-ramps are not one-size fits all; the best on-ramp provider for your app will vary based on your app experience and user base. Some considerations in choosing the right fiat on-ramp provider include:

  • Token Support: On-ramp providers are required to obtain a license for each token they offer. Not all on-ramp providers will support all tokens. You can find the supported tokens in this integration here.
  • Regional Support: On-ramp providers can only process purchases in select regions, and not all tokens may be supported in all regions. Make sure the on-ramp provider you integrate is appropriate for the geographies of your user base.
  • Payment Methods: Different on-ramp providers support different payment methods, with varying degrees of payment success. MoonPay recommends that users purchase with a debit card, but your users may be more familiar with other methods.
  • Purchase Minimums: MoonPay has strict minimums for cryptocurrency purchases. If your users regularly need to purchase low dollar-value assets (<30 USD), this integration may not be right for you.

If you'd like to use your own fiat on-ramp (e.g. other than MoonPay) that's better suited to your app's needs, you can easily do so! Follow this guide to integrate your own fiat on-ramp alongside Privy.


This feature is also compatible with external wallets!

1. Enable the MoonPay Fiat On-Ramp plugin for your app

In the Privy Console, select your app from the App Dropdown in the left sidebar and navigate to the Plugins page. Find the MoonPay Fiat On-Ramp plugin and click Request Access.

Once you've requested access, the Privy team will review your request and enable this plugin for your account. In order to comply with MoonPay's Know Your Business (KYB) policies, we may request additional information about your product.

After the Privy team has enabled the MoonPay Fiat On-Ramp plugin for your account, go back to the Plugins page; you will find a toggle where you previously saw the Request Access button. You can use this toggle to enable/disable the MoonPay Fiat On-Ramp for your app.

2. Invoking the on-ramp

Once you've enabled the MoonPay Fiat On-Ramp plugin for your app, there are two ways to invoke this flow for a user:


To invoke the on-ramp directly, first, find the embedded wallet's ConnectedWallet object from the useWallets array:

const {wallets} = useWallets();
const embeddedWallet = wallet.find((wallet) => (wallet.walletClientType === 'privy'));

Then, use the object's fund method to use the MoonPay fiat on-ramp to fund that wallet:

await{config: fundWalletConfig});

Once invoked, fund will open a Privy modal that contains some introductory context about MoonPay and the purchase they are about to make.

Intro screen for the MoonPay on-ramp flow.

Introductory screen for the MoonPay on-ramp flow.

Once the user clicks Continue in the screen above, they will be redirected to MoonPay in a new tab to complete their purchase. As part of this purchase:

  • If the user does not already have a MoonPay account, they will need to create one within this tab, and go through identity verification. This is required by law. They may be asked for their SSN/EIN, home address, and/or a government-issued ID. This flow may also require your users to wait on manual approval by MoonPay and follow-up information gathering requests.
  • If the user already has a MoonPay account and has completed their identity verification flow before, they will not need to re-complete this flow, and can immediately continue to their purchase.

While the user is completing their purchase in the MoonPay tab, the Privy modal will show a status indicator within your site indicating if the purchase is in progress, is awaiting authorization, is successful, or has failed.

Please note that purchases are not always instantaneous, and there may be some time before the user completes their purchase and the funds are available in their wallet.

Indirectly, as part of sending a transaction with insufficient funds

When sending a transaction with the embedded wallet, if your app has the config.embeddedWallets.noPromptOnSignature property set to false (which is the default), Privy will show the user a modal asking them to confirm the details of their transaction.

If the user does not have sufficient funds to complete the transaction, they will see an error in this modal indicating that their wallet needs more assets. If your app has the MoonPay Fiat On-Ramp plugin enabled, the user will also see an "Add funds" button within this screen, that invokes the fiat on-ramp flow as described above.

Adding funds from the send transaction screen.

Users can invoke the fiat on-ramp flow directly from the embedded wallet's transaction screen.

3. Customizing the on-ramp flow

To better guide your user, you can provide a FundWalletConfig object to tailor the on-ramp flow for your specific use case.

Within this object, you can provide the following fields to customize them (all optional):

FundWalletConfig Fields
currencyCodeIndicates the cryptocurrency you'd like the user to purchase, and takes the form {TOKEN_SYMBOL}_{NETWORK_NAME_} (e.g. ETH_ETHEREUM for ETH on Ethereum Mainnet).

If a currencyCode is set, the user can only purchase the set cryptocurrency. If no currencyCode is set, the user will see ETH on Ethereum Mainnet as the default currency to purchase, but can select any other cryptocurrency supported in their region.

We recommend setting this parameter to ensure your user purchases the right token for your app.
See the currencyCodes table below.
quoteCurrencyAmountIndicates the amount of the currency specified by currencyCode that you'd like the user to purchase. If set, the user will not be able to edit this amount.number
paymentMethodIndicates the payment method you'd like your user to use when completing their purchase. Supported paymentMethods are listed on the right.'ach_bank_transfer', 'credit_debit_card', 'gbp_bank_transfer', 'gbp_open_banking_payment', 'mobile_wallet', 'sepa_bank_transfer', 'sepa_open_banking_payment', 'pix_instant_payment', 'yellow_card_bank_transfer'
uiConfig.accentColorHex string indicating an accent color for MoonPay's fiat on-ramp UIsstring
uiConfig.themeTheme to use for MoonPay's fiat on-ramp UIs'light', 'dark'
currencyCode Options for the FundWalletConfig

These are the values you may use for the currencyCode field of the FundWalletConfig above. For ERC-20 tokens, the corresponding contract is linked in the token description below.

Please note that not all currencies are supported in all regions. You can find a list of unsupported regions within the US for each token below.

currencyCodeDescriptionUnsupported Regions
'AVAX_CCHAIN'AVAX token on Avalanche's C-Chain network.Hawaii, Louisiana, New York, Texas, US Virgin Islands
'CELO_CELO'CELO token on Celo network.Hawaii, Louisiana, New York, Texas, US Virgin Islands
'CUSD_CELO'cUSD stablecoin on Celo network.New York, Texas, US Virgin Islands
'DAI_ETHEREUM'Dai stablecoin on Ethereum mainnet.Hawaii, New York, US Virgin Islands
'ETH_ETHEREUM'ETH token on Ethereum mainnet.Hawaii, US Virgin Islands
'ETH_ARBITRUM'ETH token on Arbitrum network.Hawaii, New York, US Virgin Islands
'ETH_POLYGON'ETH token on Polygon.Hawaii, Louisiana, New York Texas, US Virgin Islands
'FIL_FVM'FIL token on Filecoin Virtual Machine.None
'MATIC_ETHEREUM'MATIC token on Ethereum mainnet.None
'MATIC_POLYGON'MATIC token on PolygonHawaii, Louisiana, New York, Texas, US Virgin Islands
'USDC_ETHEREUM'USDC stablecoin on Ethereum mainnet.Hawaii, US Virgin Islands
'USDC_ARBITRUM'USDC stablecoin on Arbitrum network.Hawaii, New York, Texas, US Virgin Islands
'USDC_OPTIMISM'USDC stablecoin on OP Mainnet.Hawaii, Louisiana, New York, Texas, US Virgin Islands
'USDC_POLYGON'USDC stablecoin on Polygon network.Hawaii, Louisiana, New York, Texas, US Virgin Islands
'USDT_ETHEREUM'USDT stablecoin on Ethereum mainnet.Hawaii, New York, US Virgin Islands
'USDT_POLYGON'USDT stablecoin on Polygon network.New York

As an example, you might construct a FundWalletConfig like below:

const fundWalletConfig = {
currencyCode: 'ETH_ETHEREUM', // Purchase ETH on Ethereum mainnet
quoteCurrencyAmount: 0.05, // Purchase 0.05 ETH
paymentMethod: 'credit_debit_card', // Purchase with credit or debit card
uiConfig: {accentColor: '#696FFD', theme: 'light'} // Styling preferences for MoonPay's UIs

You can then pass this FundWalletConfig as an optional parameter to (for the direct on-ramp) or sendTransaction (for the indirect on-ramp):

// Passing the fundWalletConfig to
await{config: fundWalletConfig});

// Passing the fundWalletConfig to sendTransaction
const receipt = await sendTransaction(
// UnsignedTransactionRequest
to: 'insert-destination-address',
value: 1,
chainId: 1
// SendTransactionUIConfig
description: 'Sending ETH',
// FundWalletConfig
config: fundWalletConfig

That's it! Your users can now fund their wallets via Privy's fiat on-ramp integration with MoonPay.

Want to test the fiat on-ramp in MoonPay's sandbox environment?

By default, using the MoonPay Fiat On-Ramp plugin as described above will use MoonPay's production environment.

If you'd like to use the sandbox environment for testing, simply update your PrivyProvider's config property as follows:

Configuring the PrivyProvider to use the MoonPay sandbox environment
fiatOnRamp: {
useSandbox: true, // This defaults to false
{/* your app's components/pages*/}

When testing in sandbox, note that:

  • You should purchase an amount of cryptocurrency that corresponds to <200 USD. If the amount exceeds 200 USD, the transaction may fail.
  • Do not input a real payment method. Instead, use one of MoonPay's test credit cards for your payment method
  • Instead of completing an actual identity verification flow, you will be asked to choose between three options to simulate the flow: Approve, Final Rejection, and Request Additional Information.
  • For sandbox, MoonPay will send different cryptocurrencies than they would in production:
    • For ETH on Ethereum, MoonPay will send ETH on the Ethereum Goerli testnet.
    • For ERC-20s on Ethereum, MoonPay will send its sample ERC-20 token on the Ethereum Goerli testnet.
    • For tokens on L2s, MoonPay will send 0.001 ETH on the Ethereum Goerli testnet instead.

Please note that supported tokens and regions may vary between the production and sandbox environments.

Debugging failed transactions

When purchasing cryptocurrency with fiat payments, users may run into issues due to stringent regulations around digital asset purchases. For instance, MoonPay's identity verification provider may deem the user too high-risk to complete this transaction, or the user's bank may reject the transaction.

Please note that Privy is not a payment processor nor identity verification provider and has extremely limited visibility into these issues.

If your users are running into such issues, please have them contact MoonPay support. We are unable to directly assist with a resolution in these cases.