E-wallet Top-up
The top-up flow lets your users fund their crypto wallets using local payment methods -- mobile money, bank transfer, local cards, and other region-specific options. The ONE SDK (@one_deploy/sdk v1.1.0) exposes this through the OnePayWidget in fund_wallet mode and through API methods on OneEngineClient.
Top-up Flow
User initiates SDK fetches User selects Payment is
top-up with amount --> local providers --> payment method --> processed
|
v
Tokens delivered
to wallet
- The user specifies how much they want to add to their wallet.
- The SDK queries available local payment providers for the user's country.
- The user picks a payment method and confirms.
- The payment is processed through the local provider.
- The equivalent crypto amount (minus fees) is delivered to the user's wallet.
Widget Usage (Web)
OnePayWidget in fund_wallet Mode
The OnePayWidget component supports multiple modes. When set to fund_wallet, it renders the complete top-up flow.
import { OnePayWidget } from '@one_deploy/sdk';
function TopUpPage() {
return (
<OnePayWidget
mode="fund_wallet"
walletAddress="0xYourUserWalletAddress"
chainId={137}
defaultAmount={50}
defaultFiatCurrency="NGN"
targetToken="USDT"
country="NG"
onSuccess={(result) => {
console.log('Top-up complete:', result.transactionId);
console.log('Delivered:', result.cryptoAmount, result.cryptoCurrency);
}}
onError={(error) => {
console.error('Top-up failed:', error.message);
}}
onClose={() => {
console.log('Widget closed');
}}
theme="light"
/>
);
}
OneFundWalletWidget Preset
A shorthand that sets mode="fund_wallet" automatically:
import { OneFundWalletWidget } from '@one_deploy/sdk';
function FundWalletPage() {
return (
<OneFundWalletWidget
walletAddress="0xAbc..."
chainId={137}
defaultFiatCurrency="KES"
targetToken="USDC"
country="KE"
defaultAmount={1000}
onSuccess={(result) => {
console.log('Wallet funded:', result.cryptoAmount, result.cryptoCurrency);
}}
/>
);
}
OnePayWidget Props (fund_wallet mode)
interface OnePayWidgetProps {
/** Payment mode */
mode: 'fund_wallet' | 'direct_payment' | 'transaction';
/** Destination wallet address */
walletAddress: string;
/** Target chain ID */
chainId?: number;
/** Default fiat amount to top up */
defaultAmount?: number;
/** Default fiat currency (ISO 4217) */
defaultFiatCurrency?: string;
/** Crypto token to receive in the wallet */
targetToken?: string;
/** ISO 3166-1 alpha-2 country code for local providers */
country?: string;
/** Restrict available payment methods */
allowedPaymentMethods?: string[];
/** Called when the top-up completes */
onSuccess?: (result: TopupResult) => void;
/** Called on error */
onError?: (error: { code: string; message: string }) => void;
/** Called when user closes the widget */
onClose?: () => void;
/** Widget color theme */
theme?: 'light' | 'dark' | 'auto';
/** Override CSS class name */
className?: string;
}
API Methods (All Platforms)
getTopupProviders
List available local payment providers for a country.
import { OneEngineClient } from '@one_deploy/sdk';
const engine = new OneEngineClient({
apiKey: 'YOUR_API_KEY',
projectId: 'YOUR_PROJECT_ID',
});
const providers = await engine.getTopupProviders('NG');
console.log(providers);
// [
// {
// providerId: 'prov_ng_bank',
// name: 'Bank Transfer (Nigeria)',
// type: 'bank_transfer',
// currencies: ['NGN'],
// minAmount: 1000,
// maxAmount: 5000000,
// fee: { percentage: 1.5, fixed: 50, currency: 'NGN' },
// },
// {
// providerId: 'prov_ng_momo',
// name: 'Mobile Money',
// type: 'mobile_money',
// currencies: ['NGN'],
// minAmount: 500,
// maxAmount: 1000000,
// fee: { percentage: 2.0, fixed: 0, currency: 'NGN' },
// },
// ]
getTopupQuote
Get a quote for a top-up showing the expected crypto amount.
const quote = await engine.getTopupQuote({
country: 'NG',
providerId: 'prov_ng_bank',
fiatCurrency: 'NGN',
fiatAmount: 50000,
targetToken: 'USDT',
chainId: 137,
});
console.log(quote);
// {
// quoteId: 'tq_abc123',
// fiatAmount: 50000,
// fiatCurrency: 'NGN',
// cryptoAmount: '31.25',
// cryptoCurrency: 'USDT',
// exchangeRate: 1600,
// fee: { fiatAmount: 800, fiatCurrency: 'NGN' },
// providerId: 'prov_ng_bank',
// expiresAt: '2026-02-02T12:10:00Z',
// }
createTopup
Initiate a top-up transaction.
const topup = await engine.createTopup({
quoteId: quote.quoteId,
walletAddress: '0xAbc...',
chainId: 137,
paymentDetails: {
providerId: 'prov_ng_bank',
accountName: 'Alice Adeyemi',
},
metadata: { userId: 'user_42' },
});
console.log(topup);
// {
// transactionId: 'top_xyz789',
// status: 'pending',
// paymentInstructions: {
// type: 'bank_transfer',
// bankName: 'ONE Payments Bank',
// accountNumber: '9876543210',
// accountName: 'One Deploy Ltd',
// reference: 'TOP-xyz789',
// expiresAt: '2026-02-02T13:00:00Z',
// },
// }
getTopupStatus
Check the status of a top-up.
const status = await engine.getTopupStatus('top_xyz789');
console.log(status);
// {
// transactionId: 'top_xyz789',
// status: 'completed',
// fiatAmount: 50000,
// fiatCurrency: 'NGN',
// cryptoAmount: '31.25',
// cryptoCurrency: 'USDT',
// txHash: '0xabc...',
// completedAt: '2026-02-02T12:35:00Z',
// }
Types
interface TopupProvider {
/** Unique provider identifier */
providerId: string;
/** Human-readable provider name */
name: string;
/** Payment type */
type: 'bank_transfer' | 'mobile_money' | 'card' | 'ussd' | 'qr_code';
/** Supported fiat currencies */
currencies: string[];
/** Minimum top-up amount (in fiat) */
minAmount: number;
/** Maximum top-up amount (in fiat) */
maxAmount: number;
/** Fee structure */
fee: {
percentage: number;
fixed: number;
currency: string;
};
}
interface TopupQuoteRequest {
/** Country code (ISO 3166-1 alpha-2) */
country: string;
/** Provider to use */
providerId: string;
/** Fiat currency */
fiatCurrency: string;
/** Fiat amount to pay */
fiatAmount: number;
/** Crypto token to receive */
targetToken: string;
/** Target chain */
chainId: number;
}
interface TopupQuote {
/** Quote identifier */
quoteId: string;
/** Fiat amount */
fiatAmount: number;
/** Fiat currency */
fiatCurrency: string;
/** Estimated crypto to receive */
cryptoAmount: string;
/** Crypto token symbol */
cryptoCurrency: string;
/** Exchange rate (fiat per 1 unit of crypto) */
exchangeRate: number;
/** Fee breakdown */
fee: {
fiatAmount: number;
fiatCurrency: string;
};
/** Provider used */
providerId: string;
/** ISO 8601 expiry */
expiresAt: string;
}
interface TopupRequest {
/** Quote ID */
quoteId: string;
/** Destination wallet */
walletAddress: string;
/** Target chain */
chainId: number;
/** Payment-specific details */
paymentDetails: {
providerId: string;
accountName?: string;
mobileNumber?: string;
[key: string]: unknown;
};
/** Arbitrary metadata */
metadata?: Record<string, string>;
}
interface TopupResult {
/** Unique transaction identifier */
transactionId: string;
/** Current status */
status: PaymentStatus;
/** Fiat amount paid */
fiatAmount?: number;
/** Fiat currency */
fiatCurrency?: string;
/** Crypto amount delivered */
cryptoAmount?: string;
/** Crypto token symbol */
cryptoCurrency?: string;
/** On-chain tx hash (once completed) */
txHash?: string;
/** Instructions for completing payment (bank transfer, USSD, etc.) */
paymentInstructions?: PaymentInstructions;
/** ISO 8601 completion timestamp */
completedAt?: string;
}
interface PaymentInstructions {
/** Instruction type */
type: string;
/** Bank name for transfer */
bankName?: string;
/** Account number to pay into */
accountNumber?: string;
/** Account name */
accountName?: string;
/** Payment reference code */
reference?: string;
/** USSD code to dial */
ussdCode?: string;
/** QR code data URL */
qrCodeUrl?: string;
/** Expiry for these instructions */
expiresAt?: string;
}
type PaymentStatus =
| 'pending'
| 'processing'
| 'completed'
| 'failed'
| 'expired'
| 'refunded';
Full Example: Complete Top-up Flow
import { OneEngineClient } from '@one_deploy/sdk';
const engine = new OneEngineClient({
apiKey: process.env.ONE_API_KEY!,
projectId: process.env.ONE_PROJECT_ID!,
});
async function fundWallet(wallet: string, amountNGN: number) {
// 1. Discover local providers
const providers = await engine.getTopupProviders('NG');
const bankProvider = providers.find((p) => p.type === 'bank_transfer');
if (!bankProvider) throw new Error('No bank transfer provider available');
console.log(`Using provider: ${bankProvider.name}`);
console.log(`Fee: ${bankProvider.fee.percentage}% + ₦${bankProvider.fee.fixed}`);
// 2. Get a quote
const quote = await engine.getTopupQuote({
country: 'NG',
providerId: bankProvider.providerId,
fiatCurrency: 'NGN',
fiatAmount: amountNGN,
targetToken: 'USDT',
chainId: 137,
});
console.log(`Pay ₦${quote.fiatAmount} -> receive ${quote.cryptoAmount} USDT`);
// 3. Initiate the top-up
const topup = await engine.createTopup({
quoteId: quote.quoteId,
walletAddress: wallet,
chainId: 137,
paymentDetails: {
providerId: bankProvider.providerId,
accountName: 'Alice Adeyemi',
},
});
// 4. Display payment instructions to user
if (topup.paymentInstructions) {
const inst = topup.paymentInstructions;
console.log('--- Payment Instructions ---');
console.log(`Bank: ${inst.bankName}`);
console.log(`Account: ${inst.accountNumber}`);
console.log(`Name: ${inst.accountName}`);
console.log(`Reference: ${inst.reference}`);
console.log(`Expires: ${inst.expiresAt}`);
}
// 5. Poll for completion
let status = await engine.getTopupStatus(topup.transactionId);
while (status.status === 'pending' || status.status === 'processing') {
await new Promise((r) => setTimeout(r, 10000));
status = await engine.getTopupStatus(topup.transactionId);
console.log(`Top-up status: ${status.status}`);
}
if (status.status === 'completed') {
console.log(`Wallet funded with ${status.cryptoAmount} USDT`);
console.log(`On-chain tx: ${status.txHash}`);
} else {
console.error(`Top-up failed: ${status.status}`);
}
}
// Fund wallet with 50,000 NGN
await fundWallet('0xAbc...', 50000);