Skip to main content

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
  1. The user specifies how much they want to add to their wallet.
  2. The SDK queries available local payment providers for the user's country.
  3. The user picks a payment method and confirms.
  4. The payment is processed through the local provider.
  5. 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);

See Also