Documentation Index
Fetch the complete documentation index at: https://anypay-docs-sdk-0-15-0-updates.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Fund mode implements input-driven deposit flows where users select the amount they want to send. The widget routes funds from any supported chain and token to the destination automatically.
Trade type: EXACT_INPUT — user specifies input amount, variable output after fees.
Quick start
Fund supports four payment methods: connected wallet, crypto transfer (QR/address), fiat on-ramp, and exchange (CEX). Set paymentMethod to open a specific flow, or omit it to let the user choose.
import { Fund } from '0xtrails/widget'
// Fiat on-ramp — user buys crypto with a card
<Fund
apiKey="YOUR_API_KEY"
paymentMethod="CREDIT_DEBIT_CARD"
from={{ currency: "USD", amount: 100 }}
to={{ recipient: "0xYourAddress", currency: "USDC", chain: "base" }}
onFundingSuccess={({ sessionId }) => console.log("funded", sessionId)}
/>
// CEX transfer — user sends from their exchange account
<Fund
apiKey="YOUR_API_KEY"
paymentMethod="EXCHANGE"
from={{ exchange: "coinbase" }}
to={{ recipient: "0xYourAddress", currency: "USDC", chain: "base" }}
/>
The exchange (CEX) flow requires your app to be added to the allowlist. Contact us to get access.
// Connected wallet — user pays from their wallet (default)
<Fund
apiKey="YOUR_API_KEY"
paymentMethod="CONNECTED_WALLET"
to={{ recipient: "0xYourAddress", currency: "USDC", chain: "base" }}
/>
// Fully open — let the user pick their preferred method
<Fund apiKey="YOUR_API_KEY" />
See Source selection for all paymentMethod values and the from options each accepts.
Props
Required
| Prop | Type | Description |
|---|
apiKey | string | Trails API key |
Destination (optional)
| Prop | Type | Description |
|---|
to.recipient | string | Wallet or contract address that receives the funds |
to.currency | string | Token symbol or address |
to.chain | ChainIdentifier | Destination chain — name, ID, or viem Chain |
to.defaultCurrency | string | Default token — user can change |
to.defaultChain | ChainIdentifier | Default chain — user can change |
to.calldata | string | ABI-encoded calldata to execute after funds arrive |
Source selection (optional)
Set paymentMethod to control how the user funds:
| Value | Method |
|---|
"CONNECTED_WALLET" | Connected wallet (default) |
"CRYPTO_TRANSFER" | QR code / address deposit |
"CREDIT_DEBIT_CARD" | Fiat on-ramp |
"EXCHANGE" | CEX transfer (Coinbase, Binance, etc.) |
The from prop is fully typed based on the selected paymentMethod. TypeScript will narrow the allowed fields automatically, so only valid options for that method are accepted.
When paymentMethod is set, the from object applies to that method:
// Fiat on-ramp with pre-selected currency and amount
<Fund
apiKey="YOUR_API_KEY"
paymentMethod="CREDIT_DEBIT_CARD"
from={{ currency: "EUR", amount: 100 }}
to={{ currency: "USDC", chain: "base" }}
/>
// Exchange onramp from Coinbase
<Fund
apiKey="YOUR_API_KEY"
paymentMethod="EXCHANGE"
from={{ exchange: "coinbase" }}
to={{ currency: "USDC", chain: "base" }}
/>
Fund method list (optional)
Control which funding methods are shown to the user:
| Prop | Type | Description |
|---|
fundMethodsList | FundMethodListOption[] | Ordered list: "connected-wallet", "crypto-transfer", "cc-onramp", "exchange" |
hideUnlistedFundMethods | boolean | Hide methods not in fundMethodsList (default: false) |
hideSwap | boolean | Hide the swap tab in the fund UI (default: false) |
hideWallets | string[] | Wallet addresses to exclude from the source wallet list |
defaultInputMode | "fiat" | "token" | Default amount input mode |
Lifecycle callbacks
| Callback | Signature | When it fires |
|---|
onFundingStart | ({ sessionId }) => void | User begins the funding flow |
onFundingSuccess | ({ sessionId }) => void | Funding completes successfully |
onFundingError | ({ sessionId, error }) => void | Funding encounters an error |
Examples
Buy crypto with a credit card
import { Fund } from '0xtrails/widget'
<Fund
apiKey="YOUR_API_KEY"
paymentMethod="CREDIT_DEBIT_CARD"
from={{ currency: "EUR", amount: 100 }}
to={{ currency: "USDC", chain: "base" }}
onFundingSuccess={({ sessionId }) => console.log("funded", sessionId)}
/>
Transfer from a CEX
<Fund
apiKey="YOUR_API_KEY"
paymentMethod="EXCHANGE"
from={{ currency: "USDC", chain: "base", exchange: "coinbase" }}
to={{ currency: "KAT", chain: "katana" }}
/>
QR code / address deposit
<Fund
apiKey="YOUR_API_KEY"
paymentMethod="CRYPTO_TRANSFER"
to={{
recipient: "0x...",
currency: "USDC",
chain: "base",
}}
/>
Restrict to specific funding methods
Show only fiat and exchange onramps, hide the rest:
<Fund
apiKey="YOUR_API_KEY"
to={{ currency: "USDC", chain: "base" }}
fundMethodsList={["cc-onramp", "exchange"]}
hideUnlistedFundMethods={true}
/>
Exchange onramp
Users can transfer directly from a CEX account (Coinbase, Binance, Robinhood, and others) without leaving your app. The OAuth connection and transfer are handled automatically — Trails receives the funds and routes them to the destination. No separate account or additional API keys are required.
Pass the onramp prop to enable the exchange flow. At minimum, set environment:
<Fund
apiKey="YOUR_API_KEY"
onramp={{
mesh: {
environment: 'production',
},
}}
/>
To open the exchange flow directly instead of showing the funding method selector:
<Fund
apiKey="YOUR_API_KEY"
paymentMethod="EXCHANGE"
onramp={{
mesh: {
environment: 'production',
},
}}
to={{ recipient: "0xYourAddress", currency: "USDC", chain: "base" }}
onFundingSuccess={({ sessionId }) => console.log("funded", sessionId)}
/>
To restrict which exchanges appear, pass an exchanges array:
<Fund
apiKey="YOUR_API_KEY"
onramp={{
mesh: {
environment: 'production',
exchanges: ['coinbase', 'robinhoodDirect'],
},
}}
/>
For development and testing, use environment: 'sandbox'. A yellow banner is shown inside the widget when sandbox is active.
How the auth flow works:
- User selects an exchange from the list.
- An OAuth popup opens to the exchange’s login.
- After authentication, a transfer confirmation is shown with the amount, token, and destination.
- User confirms and the withdrawal is initiated from their exchange account.
- Once detected on-chain, Trails routes the funds to the destination.
The widget shows a pending state while the exchange processes the withdrawal. Session tokens are stored locally for 5 minutes so the user does not have to re-authenticate if they retry.
Troubleshooting:
- Exchange list is empty — confirm
apiKey is valid; the exchange list fetch requires a valid API key.
- Popup blocked — trigger the flow from a user gesture (button click) rather than programmatically, and encourage users to allow popups for your domain.
- Session expired — the exchange session is valid for 5 minutes; a “Refresh Session” button appears if it expires.
Protocol deposit with dynamic calldata
For ERC-4626 vaults and staking contracts where the deposit amount is a function parameter, use TRAILS_ROUTER_PLACEHOLDER_AMOUNT. Trails replaces it with the actual bridged/swapped output at execution time.
import { Fund } from '0xtrails/widget'
import { TRAILS_ROUTER_PLACEHOLDER_AMOUNT } from '0xtrails'
import { encodeFunctionData } from 'viem'
const depositCalldata = encodeFunctionData({
abi: [{
name: 'deposit',
type: 'function',
stateMutability: 'nonpayable',
inputs: [
{ name: 'amount', type: 'uint256' },
{ name: 'receiver', type: 'address' },
],
outputs: [{ name: 'shares', type: 'uint256' }],
}],
functionName: 'deposit',
args: [TRAILS_ROUTER_PLACEHOLDER_AMOUNT, '0xReceiverAddress'],
})
<Fund
apiKey="YOUR_API_KEY"
to={{
recipient: "0xYearnVault",
currency: "USDC",
chain: "katana",
calldata: depositCalldata,
}}
onFundingSuccess={({ sessionId }) => console.log("deposited", sessionId)}
/>
Use TRAILS_ROUTER_PLACEHOLDER_AMOUNT when the deposit amount is a function parameter and the user selects the amount. Do not use it for functions that read balance internally (e.g. depositAll()).
See also