Skip to main content

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 TypeMethodWhat It DoesWhen To Use
💰 Money InonrampTestnet()Fiat → USDCUser deposits money
💰 Money InconfirmDeposit()USDC → Fiat walletSomeone sent you crypto
🔄 TransferonrampWalletTestnet()Wallet → WalletInternal transfers
🔄 TransfersendUsd()USD → USDC → USDCross-border magic
🔄 TransfersendUsdcDirect()Direct USDC sendPay any blockchain address
📊 HelpergetMyUsdWallet()Get your wallet infoStart any operation
📊 HelpergetUserWalletListUsd()Find test walletsMulti-user testing
📊 HelperlogUserTransfer()Track external txsMonitor MetaMask activity
⚙️ SetupgetAvailableChains()Check networksEnvironment 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 got
  • wallet_address: Where the crypto went
  • exchange_rate: What rate was used
  • transaction_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 got
  • currency: What currency (IDR, USD, etc.)
  • exchange_rate: Conversion rate used
  • deposit_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:

  1. Convert sender's USD to USDC
  2. Send USDC across blockchain
  3. Convert USDC to recipient's USD

What you get back:

  • transaction_id: Unique transfer ID
  • step_log: Each step and its status
  • recipient_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 tracking
  • status: Transfer status
  • timestamp: 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 hash
  • network: 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

Security & Smart Contract Best Practices

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.

Multi-Network Contract Addresses

Each network has different USDC contract addresses. Sepolia uses 0x9BF350fBaaA8c7200990B051809334c90778f435, while Amoy uses 0xC15239B6B9012F3225f9ebC091C7CE85FF31b983. Always verify contract addresses for your target network.

Production Migration Path

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.