Funding wallets
Simplify onnramping funds to your embedded wallet.
Openfort makes it easy for your users to fund their wallets with a variety of assets, including a network's native currency (e.g. ETH), USDC, and other ERC20 tokens. This makes it seamless to take onchain actions within your apps such as purchasing goods, swapping tokens, minting NFTs, and more.
Openfort enables users to fund their wallets by:
- transferring assets from an external wallet (e.g. Rabbit Wallet)
- purchasing assets from MoonPay with fiat currency
- purchasing assets from Coinbase Onramp or transferring from Coinbase accounts
The following are three funding methods suggested from Openfort and you can find implementations of such in our SDK. You're open though to integrate any onramp.
External wallets#
The external wallets funding option enables users to transfer funds from an external wallet (e.g. MetaMask) to their embedded wallet within your app.
With external wallets, users can fund their accounts with a network's native currency (e.g. ETH), USDC, or other ERC20 tokens.
If users don't want to connect an external wallet, Openfort will also give the users to copy their embedded wallet address, and manually transfer funds from their external wallet to their embedded wallet.
Coinbase Onramp#
The Coinbase Onramp funding option enables users to purchase assets from Coinbase or transfer assets from an existing Coinbase account, directly within your app. If users have already completed KYC and identity verification with Coinbase for an existing Coinbase account, they will not need to do so again, streamlining their asset purchase/transfer experience.
Please note that these purchases are not immediate and it may take a few minutes for funds to arrive in your user's wallet.
With Coinbase Onramp, users can fund their accounts with a network's native currency (e.g. ETH) or USDC on Coinbase's supported networks.
Note that not all payment methods are available in all regions due to local regulations. See Coinbase's regional support guide for more information on which payment methods are supported in which regions.
MoonPay#
The MoonPay funding option enables users to purchase assets with fiat payments including bank transfer, credit cards, and debit cards. This is particularly useful for users that may not hold crypto outside of your application and are purchasing crypto for the first time.
Please note that these purchases are not immediate, and depending on the payment method selected by your users, it may take a few days for funds to arrive in your user's wallet. Generally, paying with bank transfer has the highest approval rates for cryptocurrency purchases.
With MoonPay, users can fund their accounts with a network's native currency (e.g. ETH) or USDC on MoonPay's supported networks.
Note that support for assets varies by region due to local regulations. If a user attempts to purchase an asset from an unsupported region, MoonPay will allow the user to purchase any assets that are supported in their region.
Integrating a custom fiat on-ramp#
To start, you'll need to choose a fiat on-ramp provider that meets your app's requirements. Different on-ramp providers vary in their support of:
- different tokens (ETH, USDC, Dai, POL, etc.)
- different networks (Ethereum, Polygon, Optimism, etc.)
- different regions (US, Europe, Brazil, South Korea, India, etc.).
- different payment methods (credit cards, debit cards, ACH, instant ACH, etc. )
Once you have chosen an on-ramp provider for your app, set up an account with that provider and retrieve your sandbox API keys to build an integration. For example, after setting up a Moonpay account, you can retrieve your API keys from their developer dashboard like below:
Most providers will provision you with a public API key that can be exposed to your frontend, and a secret API key that should only exist on your server. Some providers may also offer a webhook API key so you can subscribe to updates on your users' transactions.
Integrating the provider#
For the remainder of this guide, we will focus on integrating Moonpay as your fiat on-ramp provider. The integration follows three main steps:
- Collect user details in your frontend
- Generate the Moonpay URL with proper parameters
- Handle the purchase flow and monitor transactions
1. Collect User Information in Your Frontend#
First, we need to collect information about the user and their desired purchase. With Openfort, we can get the user's wallet address using the useOpenfort
hook:
_15import { useOpenfort } from "@/hooks/useOpenfort";_15import { Address } from "viem";_15import { EmbeddedState } from "@openfort/openfort-js";_15_15const { state, getEOAAddress } = useOpenfort();_15const [accountAddress, setAccountAddress] = useState<Address>();_15_15useEffect(() => {_15 const init = async () => {_15 if (state !== EmbeddedState.READY) return;_15 const accountAddress = await getEOAAddress();_15 setAccountAddress(accountAddress as `0x${string}`);_15 };_15 init();_15}, [state]);
For the funding amount, we can let users input their desired amount:
_10const [fundAmount, setFundAmount] = useState<string>('0.02');
2. Generate the Moonpay URL#
Once we have the user's information, we can generate the Moonpay URL. You'll need your Moonpay API key for this step:
_10// Generate a unique transaction ID for tracking_10const txId = 'openfort-' + window.crypto.randomUUID();_10_10// Construct the Moonpay URL with all necessary parameters_10const moonpayLink = `https://buy-sandbox.moonpay.com/` +_10 `?externalTransactionId=${txId}` +_10 `&apiKey=${process.env.NEXT_PUBLIC_MOONPAY_API_KEY}` +_10 `&walletAddress=${accountAddress}` +_10 `¤cyCode=ETH` +_10 `"eCurrencyAmount=${fundAmount}`;
Important parameters in the URL:
externalTransactionId
: A unique identifier for tracking the transactionapiKey
: Your Moonpay public API keywalletAddress
: The user's wallet addresscurrencyCode
: The cryptocurrency to purchase (e.g., 'ETH')quoteCurrencyAmount
: The amount to purchase
3. Redirect your user to the on-ramp URL#
Once you have generated the Moonpay URL, you can redirect your user to complete their purchase. The following code handles the redirection and monitors the transaction status:
_47const handleFund = async (service: any) => {_47 // Update UI state to show progress_47 setStep(StepEnum.SERVICE_PROGRESS);_47 setService(service);_47 _47 // Open Moonpay in a new window_47 window.open(service.link, '_blank');_47 _47 // Start monitoring the transaction_47 const intervalFund = setInterval(_47 () => checkFunding(() => service.checkTxResult(service.verifyUrl)),_47 2000_47 );_47 intervalFundingId.current = intervalFund;_47};_47_47// Function to check funding status_47const checkFunding = async (txResult: any) => {_47 if (await txResult() === 'completed') {_47 clearInterval(intervalFundingId.current);_47 setStep(StepEnum.COMPLETED);_47 handleSetMessage('Funds added successfully!');_47 }_47};_47_47// Function to check transaction status_47const checkMoonpayTransaction = async (txId: string) => {_47 const verifyUrl = `https://api.moonpay.com/v1/transactions/ext/${txId}?apiKey=${process.env.NEXT_PUBLIC_MOONPAY_API_KEY}`;_47 _47 try {_47 const response = await fetch(verifyUrl);_47 if (!response.ok) return 'pending';_47 _47 const json = await response.json();_47 switch (json[0].status) {_47 case 'completed':_47 return 'completed';_47 case 'failed':_47 return 'failed';_47 default:_47 return 'pending';_47 }_47 } catch (error) {_47 console.error('Error checking transaction status:', error);_47 return 'pending';_47 }_47};
Alternatively, if you do not want to redirect the user to a new tab, you can instead surface the on-ramp URL within an iframe embedded within your site.
That's it! Your users can now fund the wallets they've connected/created through Openfort and take on-chain actions in your app.