Testnet SDK - Your Financial Building Blocks
Think of the Testnet SDK as your digital construction kit for building any kind of financial flow. Instead of rigid, pre-built solutions, you get flexible building blocks that snap together to create exactly what your app needs.
🎯 What's This For?
Building financial apps is like building with Lego - you need the right pieces that work together. The Testnet SDK gives you:
- Money Input Blocks: Convert real money into crypto
- Transfer Blocks: Move money between wallets and across borders
- Money Output Blocks: Convert crypto back to real money
- Helper Blocks: Find wallets, track transactions, manage flows
🚀 Quick Start
// Import your building kit
const testnet = await brdzSDK.testnet;
// Setup your workspace with proper authentication
const config = await brdzSDK.config;
config.setBaseUrl('https://api.brdz.link/api');
config.setApiKey('your-api-key'); // Required for all calls
config.setToken('your-jwt-token'); // Required for authenticated calls
// Validate your setup
const utils = await brdzSDK.utils;
utils.validateSDKSetup(); // Checks configuration
🧩 Your Building Blocks
| Block Type | Method | What It Does | When To Use |
|---|---|---|---|
| 💰 Money In | onrampTestnet() | Fiat → USDC | User deposits money |
| 💰 Money In | confirmDeposit() | USDC → Fiat wallet | Someone sent you crypto |
| 🔄 Transfer | onrampWalletTestnet() | Wallet → Wallet | Internal transfers |
| 🔄 Transfer | sendUsd() | USD → USDC → USD | Cross-border magic |
| 🔄 Transfer | sendUsdcDirect() | Direct USDC send | Pay any blockchain address |
| 📊 Helper | getMyUsdWallet() | Get your wallet info | Start any operation |
| 📊 Helper | getUserWalletListUsd() | Find test wallets | Multi-user testing |
| 📊 Helper | logUserTransfer() | Track external txs | Monitor MetaMask activity |
| ⚙️ Setup | getAvailableChains() | Check networks | Environment validation |
💰 Money Input Blocks
onrampTestnet() - Bring Fiat Money Into Crypto
What it does: Converts your real money (IDR, USD, etc.) into USDC that lives on the blockchain.
When to use: User wants to deposit money into your crypto system.
// Turn Indonesian Rupiah into USDC
const deposit = await testnet.onrampTestnet({
amount_idr: 150000, // 150k IDR
wallet_id: "my_crypto_wallet"
});
console.log(`💰 Converted ${deposit.amount_idr} IDR into ${deposit.amount_usdc} USDC`);
console.log(`📍 USDC is now at: ${deposit.wallet_address}`);
console.log(`💱 Exchange rate: 1 USDC = ${deposit.exchange_rate} IDR`);
What you get back:
amount_usdc: How much crypto they gotwallet_address: Where the crypto wentexchange_rate: What rate was usedtransaction_id: For tracking
Pro tip: Different countries use different currencies. The system auto-detects based on user's country.
confirmDeposit() - Convert Received Crypto to Fiat
What it does: Takes USDC someone sent you and converts it to real money in your fiat wallet.
When to use: Someone sent you crypto and you want it as normal money.
// Convert received USDC to fiat money
const conversion = await testnet.confirmDeposit({
user_id: 123,
wallet_address: "0x153c26a547C35009Ba3fE69a1F9f431B089bB301",
amount: 100.00 // Optional - auto-detects if not provided
});
console.log(`🎯 Converted ${conversion.amount_usdc} USDC`);
console.log(`💵 Into ${conversion.amount_fiat} ${conversion.currency}`);
console.log(`📈 Rate: 1 USDC = ${conversion.exchange_rate} ${conversion.currency}`);
What you get back:
amount_fiat: How much real money they gotcurrency: What currency (IDR, USD, etc.)exchange_rate: Conversion rate useddeposit_id: For tracking
🔄 Transfer Blocks
sendUsd() - Cross-Border Money Transfer Magic
What it does: Takes USD from one wallet, converts to USDC, sends across blockchain, converts back to USD in recipient's wallet.
When to use: International money transfers without traditional banks.
// Send money across borders via blockchain
const transfer = await testnet.sendUsd({
from_wallet_id: "alice_usd_wallet",
to_wallet_id: "bob_usd_wallet_singapore",
amount: 75.00
});
console.log(`🌍 Sent $${transfer.amount_usd} from Alice to Bob`);
console.log(`🔗 Blockchain address used: ${transfer.recipient_address}`);
// Check each step of the magic
console.log(`📋 Transfer steps:`);
Object.entries(transfer.step_log).forEach(([step, status]) => {
console.log(` ${step}: ${status}`);
});
The magic behind the scenes:
- Convert sender's USD to USDC
- Send USDC across blockchain
- Convert USDC to recipient's USD
What you get back:
transaction_id: Unique transfer IDstep_log: Each step and its statusrecipient_address: Blockchain address used
onrampWalletTestnet() - Internal Wallet Transfers
What it does: Moves money between wallets within your system.
When to use: Users transferring money to each other inside your app.
// Transfer between internal wallets
const transfer = await testnet.onrampWalletTestnet({
from_wallet_id: "wallet_alice",
to_wallet_id: "wallet_bob",
amount: 50.00,
chain: "sepolia" // Which blockchain network
});
console.log(`✅ Transfer completed: ${transfer.transaction_id}`);
console.log(`💸 ${transfer.amount} moved from Alice to Bob`);
What you get back:
transaction_id: For trackingstatus: Transfer statustimestamp: When it happened
sendUsdcDirect() - Pay Any Blockchain Address
What it does: Sends USDC directly to any Ethereum-compatible wallet address.
When to use: Direct crypto payments, paying external services, funding other wallets.
// Send USDC to any blockchain address
const payment = await testnet.sendUsdcDirect({
evm_address: "0x987654321098765432109876543210987654321",
amount: 50.00
});
console.log(`🚀 Sent ${payment.amount} USDC to ${payment.evm_address}`);
console.log(`⛓️ Transaction hash: ${payment.tx_hash}`);
console.log(`🌐 Network: ${payment.network}`);
What you get back:
tx_hash: Blockchain transaction hashnetwork: Which network (sepolia)evm_address: Where it went
📊 Helper Blocks
getMyUsdWallet() - Get Your Wallet Info
What it does: Gets information about your USD wallet.
When to use: Start of any operation - you need to know your wallet details first.
// Get your wallet info first
const myWallet = await testnet.getMyUsdWallet();
console.log(`🏦 My wallet ID: ${myWallet.wallet.wallet_id}`);
console.log(`📍 Address: ${myWallet.wallet.address}`);
console.log(`💰 Balance limit: $${myWallet.wallet.balance_limit}`);
console.log(`📊 Status: ${myWallet.wallet.wallet_status}`);
// Now use it for transfers
const transfer = await testnet.sendUsd({
from_wallet_id: myWallet.wallet.wallet_id,
to_wallet_id: "someone_else",
amount: 100.00
});
getUserWalletListUsd() - Find Test Wallets
What it does: Finds other users' USD wallets for testing transfers.
When to use: Multi-user testing, finding recipients for test transfers.
// Find wallets to test with
const wallets = await testnet.getUserWalletListUsd();
console.log(`🔍 Found ${wallets.wallets.length} test wallets:`);
wallets.wallets.forEach(wallet => {
console.log(` 👤 ${wallet.username} (${wallet.country_code})`);
console.log(` 💳 ID: ${wallet.wallet_id}`);
console.log(` 📍 Address: ${wallet.address}`);
});
// Pick one for testing
const testRecipient = wallets.wallets[0];
const transfer = await testnet.sendUsd({
from_wallet_id: "my_wallet",
to_wallet_id: testRecipient.wallet_id,
amount: 25.00
});
logUserTransfer() - Track External Transactions
What it does: Records transactions that users did outside your app (like MetaMask transfers).
When to use: User made a crypto transaction externally and you want to track it.
// User sent USDC via MetaMask - log it
const log = await testnet.logUserTransfer({
user_id: 123,
tx_hash: "0x1234567890abcdef1234567890abcdef12345678",
to: "0x987654321098765432109876543210987654321",
amount: 25.50
});
console.log(`📝 Logged external transfer: ${log.transaction.transaction_id}`);
console.log(`💸 User sent ${log.transaction.amount} USDC`);
console.log(`🔗 Blockchain hash: ${log.transaction.reference_id}`);
⚙️ Setup Block
getAvailableChains() - Check Your Environment
What it does: Shows which blockchain networks are available for testing.
When to use: Start of testing session to validate your environment.
// Check what networks are available
const chains = await testnet.getAvailableChains();
console.log(`🌐 Network type: ${chains.network}`);
console.log(`⛓️ Available chains:`);
chains.chains.forEach(chain => {
const status = chain.active ? '✅ Active' : '❌ Inactive';
console.log(` ${chain.name}: ${status}`);
});
// Only use active chains for testing
const activeChains = chains.chains.filter(c => c.active);
console.log(`🎯 Ready to test with: ${activeChains.map(c => c.name).join(', ')}`);
🏗️ Building Complete Flows
Flow 1: Complete Money Journey (Fiat → Crypto → Fiat)
// Test the full cycle: Real money → Crypto → Real money
async function testCompleteJourney() {
console.log('🚀 Starting complete money journey test...');
// Step 1: Bring fiat money into crypto
const onramp = await testnet.onrampTestnet({
amount_idr: 300000, // 300k Indonesian Rupiah
wallet_id: "my_test_wallet"
});
console.log(`💰 Step 1: ${onramp.amount_idr} IDR → ${onramp.amount_usdc} USDC`);
// Step 2: Convert crypto back to fiat
const offramp = await testnet.confirmDeposit({
user_id: 123,
wallet_address: onramp.wallet_address,
amount: onramp.amount_usdc
});
console.log(`💵 Step 2: ${offramp.amount_usdc} USDC → ${offramp.amount_fiat} ${offramp.currency}`);
console.log(`✅ Journey complete! Money went full circle.`);
return { onramp, offramp };
}
Flow 2: International Money Transfer
// Test sending money across borders
async function testInternationalTransfer() {
console.log('🌍 Testing international money transfer...');
// Step 1: Get your wallet and find recipients
const myWallet = await testnet.getMyUsdWallet();
const otherWallets = await testnet.getUserWalletListUsd();
console.log(`👤 Sender: ${myWallet.wallet.wallet_id}`);
console.log(`🎯 Found ${otherWallets.wallets.length} potential recipients`);
// Step 2: Pick someone from different country
const recipient = otherWallets.wallets.find(w => w.country_code !== 'US');
// Step 3: Send money via blockchain bridge
const transfer = await testnet.sendUsd({
from_wallet_id: myWallet.wallet.wallet_id,
to_wallet_id: recipient.wallet_id,
amount: 100.00
});
console.log(`💸 Sent $${transfer.amount_usd} to ${recipient.username} in ${recipient.country_code}`);
console.log(`🔗 Used blockchain address: ${transfer.recipient_address}`);
// Step 4: Check each step completed
console.log(`📋 Transfer steps:`);
Object.entries(transfer.step_log).forEach(([step, status]) => {
console.log(` ✅ ${step}: ${status}`);
});
return transfer;
}
Flow 3: Multi-Currency Testing
// Test with different currencies and amounts
async function testMultiCurrency() {
console.log('💱 Testing multiple currencies...');
const testCases = [
{ amount_idr: 150000, country: 'Indonesia' },
{ amount_usd: 50, country: 'United States' },
{ amount_sgd: 75, country: 'Singapore' }
];
const results = [];
for (const testCase of testCases) {
console.log(`🧪 Testing ${testCase.country}...`);
const result = await testnet.onrampTestnet({
...testCase,
wallet_id: "multi_currency_test_wallet"
});
const currency = Object.keys(testCase)[0].replace('amount_', '').toUpperCase();
console.log(` 💰 ${testCase[Object.keys(testCase)[0]]} ${currency} → ${result.amount_usdc} USDC`);
results.push(result);
}
console.log(`✅ Tested ${results.length} currencies successfully`);
return results;
}
Flow 4: External Transaction Tracking
// Test tracking external MetaMask transactions
async function testExternalTracking() {
console.log('📝 Testing external transaction tracking...');
// Simulate user doing transaction in MetaMask
const externalTx = {
user_id: 123,
tx_hash: "0x1234567890abcdef1234567890abcdef12345678",
to: "0x987654321098765432109876543210987654321",
amount: 25.50
};
// Log the external transaction
const log = await testnet.logUserTransfer(externalTx);
console.log(`📝 Logged external USDC transfer:`);
console.log(` 💰 Amount: ${log.transaction.amount} USDC`);
console.log(` 🔗 Hash: ${log.transaction.reference_id}`);
console.log(` 📊 Status: ${log.transaction.status}`);
console.log(` 🆔 Transaction ID: ${log.transaction.transaction_id}`);
return log;
}
🎯 When To Use Which Block
Starting Any Test Session
// Always start with these
const chains = await testnet.getAvailableChains(); // Check environment
const myWallet = await testnet.getMyUsdWallet(); // Get your wallet
const testWallets = await testnet.getUserWalletListUsd(); // Find test partners
Testing User Onboarding
// User wants to deposit money
const deposit = await testnet.onrampTestnet({
amount_idr: 200000,
wallet_id: myWallet.wallet.wallet_id
});
Testing Cross-Border Payments
// User wants to send money internationally
const transfer = await testnet.sendUsd({
from_wallet_id: myWallet.wallet.wallet_id,
to_wallet_id: internationalWallet.wallet_id,
amount: 100.00
});
Testing Direct Crypto Payments
// User wants to pay a blockchain address directly
const payment = await testnet.sendUsdcDirect({
evm_address: "0x...",
amount: 50.00
});
Testing External Wallet Integration
// User did something in MetaMask - track it
const log = await testnet.logUserTransfer({
user_id: user.id,
tx_hash: metamaskTxHash,
to: recipientAddress,
amount: amountSent
});
💡 Pro Developer Tips
Error Handling Strategy
// Always wrap in try-catch with specific error handling
async function safeTestnetCall(operation) {
try {
return await operation();
} catch (error) {
if (error.message.includes('Missing required fields')) {
console.error('❌ Check your parameters');
console.error('Required fields:', error.message);
} else if (error.message.includes('wallet not found')) {
console.error('❌ Wallet doesn\'t exist - create one first');
} else if (error.message.includes('insufficient balance')) {
console.error('❌ Not enough money in wallet');
} else {
console.error('❌ Unexpected error:', error.message);
}
throw error;
}
}
// Usage
const result = await safeTestnetCall(() =>
testnet.onrampTestnet({
amount_idr: 150000,
wallet_id: "my_wallet"
})
);
Testing Flow Validation
// Always validate your test environment first
async function validateTestEnvironment() {
console.log('🔍 Validating test environment...');
// Check networks
const chains = await testnet.getAvailableChains();
const activeChains = chains.chains.filter(c => c.active);
if (activeChains.length === 0) {
throw new Error('No active chains available for testing');
}
// Check wallet
const myWallet = await testnet.getMyUsdWallet();
if (!myWallet.wallet) {
throw new Error('No USD wallet found - create one first');
}
// Check test partners
const testWallets = await testnet.getUserWalletListUsd();
if (testWallets.wallets.length === 0) {
console.warn('⚠️ No other test wallets found - limited testing possible');
}
console.log('✅ Test environment validated');
console.log(` 📡 Active networks: ${activeChains.map(c => c.name).join(', ')}`);
console.log(` 💳 My wallet: ${myWallet.wallet.wallet_id}`);
console.log(` 👥 Test partners: ${testWallets.wallets.length}`);
return { chains: activeChains, myWallet, testWallets };
}
Debugging Complex Flows
// Use step logs to debug complex operations
async function debugTransfer(from_wallet, to_wallet, amount) {
console.log(`🔍 Starting transfer debug: ${amount} USD`);
console.log(` 📤 From: ${from_wallet}`);
console.log(` 📥 To: ${to_wallet}`);
const transfer = await testnet.sendUsd({
from_wallet_id: from_wallet,
to_wallet_id: to_wallet,
amount: amount
});
console.log(`📋 Transfer steps breakdown:`);
Object.entries(transfer.step_log).forEach(([step, status]) => {
const emoji = status === 'completed' ? '✅' : '❌';
console.log(` ${emoji} ${step.replace(/_/g, ' ')}: ${status}`);
});
if (transfer.step_log['3_credit_usd_to_recipient'] === 'completed') {
console.log(`🎉 Transfer successful! Transaction ID: ${transfer.transaction_id}`);
} else {
console.log(`💥 Transfer failed at recipient crediting stage`);
}
return transfer;
}
🌍 Supported Currencies & Networks
Fiat Currencies (Auto-detected by User Country)
- IDR (Indonesia) - Primary testing currency, 1 USDC = 15,000 IDR
- USD (United States) - International standard, 1 USDC = 1 USD
- SGD (Singapore) - Regional testing
- AUD (Australia) - Regional testing
- VND (Vietnam) - Regional testing
- INR (India) - Regional testing
Blockchain Networks
- Sepolia Testnet - ✅ Active for all operations
- Other EVM Networks - 📋 Available but currently inactive
Test Configuration
- Test Wallet Address:
0x153c26a547C35009Ba3fE69a1F9f431B089bB301 - Token Standard: ERC-20 USDC (testnet version)
- Primary Network: Sepolia Testnet
🔐 Authentication Setup
// Essential setup for all operations
const config = await brdzSDK.config;
config.setBaseUrl('https://api.brdz.link/api');
config.setApiKey('your-api-key'); // Required for all calls
config.setToken('your-jwt-token'); // Required for authenticated calls
// Test your setup
const utils = await brdzSDK.utils;
utils.validateSDKSetup(); // Checks if everything is configured correctly
Public vs Authenticated Methods
Public (No JWT required):
getAvailableChains()- Check networks
Authenticated (JWT required):
- All other testnet methods need JWT token
Never ask users for private keys in testing or production. Use controlled safe addresses for testing (like 0x153c26a547C35009Ba3fE69a1F9f431B089bB301), and let users specify their own addresses for production. All USDC operations interact with audited ERC-20 contracts.
Each network has different USDC contract addresses. Sepolia uses 0x9BF350fBaaA8c7200990B051809334c90778f435, while Amoy uses 0xC15239B6B9012F3225f9ebC091C7CE85FF31b983. Always verify contract addresses for your target network.
The same SDK methods and security patterns work for mainnet deployment. Only contract addresses, RPC URLs, and chain IDs need updating when moving from testnet to production networks.