Skip to main content

FX Module

The fx module handles foreign exchange and currency conversion operations via USDC bridge.

Import

const fx = await brdzSDK.fx;

Methods Overview (7 methods)

MethodDescriptionAuth RequiredHTTP Endpoint
getFiatRoutesConversionFIAT to FIAT via USDCGET /fx/convert
getUsdcConversionUSDC to FIAT directGET /fx/usdc
getUsdcTickerGet ticker with changesGET /fx/usdc-ticker
updateUsdcTickerManual ticker updatePOST /fx/usdc-ticker/update
convertAllConvert with route detailsGET /fx/convertall
getRateGet exchange rate (deprecated)GET /fx/rate/:from/:to
simulateFxSimulate FX transaction (deprecated)POST /fx/simulate

Configuration

// Configure SDK
const config = await brdzSDK.config;
config.setBaseUrl('https://api.brdz.link/api');
config.setApiKey('your_api_key'); // Only API key required, no JWT token

Methods

getFiatRoutesConversion

Convert between fiat currencies using USDC as bridge.

Syntax:

await fx.getFiatRoutesConversion(from, to, amount)

Parameters:

  • from (string): Source currency code (e.g., "IDR", "USD")
  • to (string): Target currency code (e.g., "USD", "SGD")
  • amount (number): Amount to convert

Returns:

{
route: "IDR → USDC → USD",
result: 67.45,
usdcIntermediate: 0.000064
}

Example:

try {
// Convert 1,000,000 IDR to USD
const conversion = await fx.getFiatRoutesConversion('IDR', 'USD', 1000000);
console.log('Conversion Route:', conversion.route);
console.log('Result:', conversion.result, 'USD');
console.log('USDC Intermediate:', conversion.usdcIntermediate);

// Multiple conversions
const conversions = [
{ from: 'IDR', to: 'USD', amount: 1000000 },
{ from: 'USD', to: 'SGD', amount: 100 },
{ from: 'SGD', to: 'IDR', amount: 50 }
];

for (const conv of conversions) {
const result = await fx.getFiatRoutesConversion(conv.from, conv.to, conv.amount);
console.log(`${conv.from} ${conv.amount} = ${result.result} ${conv.to}`);
}
} catch (error) {
console.error('Conversion failed:', error.message);
}

Use Cases:

  • Currency conversion for international payments
  • Multi-currency portfolio valuation
  • Cross-border remittance calculations

getUsdcConversion

Direct conversion between USDC and fiat currencies.

Syntax:

await fx.getUsdcConversion(fiat, direction, amount)

Parameters:

  • fiat (string): Fiat currency code (e.g., "IDR", "USD")
  • direction (string): "toFiat" (USDC → Fiat) or "fromFiat" (Fiat → USDC)
  • amount (number): Amount to convert

Returns:

{
route: "USDC → IDR",
rate: 15750.50,
result: 157505.00
}

Example:

try {
// Convert 10 USDC to IDR
const usdcToIdr = await fx.getUsdcConversion('IDR', 'toFiat', 10);
console.log('10 USDC =', usdcToIdr.result, 'IDR');
console.log('Rate:', usdcToIdr.rate);

// Convert 157,500 IDR to USDC
const idrToUsdc = await fx.getUsdcConversion('IDR', 'fromFiat', 157500);
console.log('157,500 IDR =', idrToUsdc.result, 'USDC');
console.log('Rate:', idrToUsdc.rate);

// Helper function for USDC conversions
async function convertUsdc(fiat, direction, amount) {
const result = await fx.getUsdcConversion(fiat, direction, amount);
return result;
}

// Batch USDC conversions
const usdcConversions = await Promise.all([
convertUsdc('IDR', 'toFiat', 10), // 10 USDC → IDR
convertUsdc('USD', 'fromFiat', 100), // 100 USD → USDC
convertUsdc('SGD', 'toFiat', 5) // 5 USDC → SGD
]);

usdcConversions.forEach((conv, i) => {
console.log(`Conversion ${i + 1}: ${conv.route} = ${conv.result}`);
});
} catch (error) {
console.error('USDC conversion failed:', error.message);
}

Direction Values:

  • "toFiat": Convert USDC to fiat currency
  • "fromFiat": Convert fiat currency to USDC

getUsdcTicker

Get real-time USDC ticker data with price changes.

Syntax:

await fx.getUsdcTicker()

Parameters: None

Returns:

{
success: true,
data: {
USD: {
rate: 1.0000,
change: 0.0000,
percent: 0.0000,
isUp: true
},
IDR: {
rate: 15750.50,
change: -125.25,
percent: -0.79,
isUp: false
},
SGD: {
rate: 1.3456,
change: 0.0012,
percent: 0.09,
isUp: true
}
}
}

Example:

try {
const tickerData = await fx.getUsdcTicker();

if (tickerData.success) {
console.log('USDC Ticker Data:');

Object.entries(tickerData.data).forEach(([currency, data]) => {
const arrow = data.isUp ? '↗️' : '↘️';
const sign = data.change >= 0 ? '+' : '';

console.log(`${currency}/USDC: ${data.rate}`);
console.log(` Change: ${sign}${data.change} (${sign}${data.percent}%) ${arrow}`);
});
} else {
console.error('Failed to load ticker:', tickerData.error);
}

// Create ticker monitor
class TickerMonitor {
constructor() {
this.previousRates = {};
}

async checkRates() {
const ticker = await fx.getUsdcTicker();

if (ticker.success) {
Object.entries(ticker.data).forEach(([currency, data]) => {
const currentRate = data.rate;

if (this.previousRates[currency]) {
const prevRate = this.previousRates[currency];
const changePercent = ((currentRate - prevRate) / prevRate) * 100;

if (Math.abs(changePercent) > 1) { // 1% change threshold
console.log(`🚨 ${currency} significant change: ${prevRate}${currentRate} (${changePercent.toFixed(2)}%)`);
}
}

this.previousRates[currency] = currentRate;
});
}
}

startMonitoring(intervalSeconds = 30) {
setInterval(() => this.checkRates(), intervalSeconds * 1000);
}
}

// Start monitoring
const monitor = new TickerMonitor();
monitor.startMonitoring(30); // Check every 30 seconds
} catch (error) {
console.error('Ticker fetch failed:', error.message);
}

Ticker Properties:

  • rate: Current exchange rate
  • change: Absolute price change
  • percent: Percentage change
  • isUp: Boolean indicating price direction

updateUsdcTicker

Manually trigger ticker update from Coinbase.

Syntax:

await fx.updateUsdcTicker()

Parameters: None

Returns:

{
success: true,
message: "Rates updated successfully"
}

Example:

try {
const updateResult = await fx.updateUsdcTicker();

if (updateResult.success) {
console.log('✅ Ticker updated:', updateResult.message);

// Get updated ticker data
const tickerData = await fx.getUsdcTicker();
console.log('Updated rates:', tickerData.data);
} else {
console.error('❌ Update failed:', updateResult.error);
}

// Auto-update ticker every hour
setInterval(async () => {
try {
const result = await fx.updateUsdcTicker();
if (result.success) {
console.log('🔄 Hourly ticker update completed');
}
} catch (error) {
console.error('❌ Scheduled update failed:', error);
}
}, 3600000); // 1 hour = 3,600,000 ms
} catch (error) {
console.error('Manual update failed:', error.message);
}

Use Cases:

  • Get latest rates during high volatility
  • Refresh rates before important transactions
  • Scheduled rate updates for applications

convertAll

Convert currencies with detailed route information.

Syntax:

await fx.convertAll(from, to, amount)

Parameters:

  • from (string): Source currency code
  • to (string): Target currency code
  • amount (number): Amount to convert

Returns:

{
from: "IDR",
to: "USD",
original_amount: 1000000,
route: "IDR → USDC → USD",
usdc_intermediate: 63.456,
converted_amount: 63.45,
exchange_rate: 0.00006345
}

Example:

try {
const conversion = await fx.convertAll('IDR', 'USD', 1000000);

console.log('Conversion Details:');
console.log(`From: ${conversion.from} ${conversion.original_amount}`);
console.log(`To: ${conversion.to} ${conversion.converted_amount}`);
console.log(`Route: ${conversion.route}`);
console.log(`Exchange Rate: ${conversion.exchange_rate}`);

if (conversion.usdc_intermediate) {
console.log(`USDC Intermediate: ${conversion.usdc_intermediate}`);
}

// Conversion tracker
class ConversionTracker {
constructor() {
this.conversions = [];
}

async convert(from, to, amount) {
const conversion = await fx.convertAll(from, to, amount);
conversion.timestamp = new Date().toISOString();
this.conversions.push(conversion);
return conversion;
}

getHistory() {
return this.conversions.map(conv => ({
timestamp: conv.timestamp,
conversion: `${conv.from} ${conv.original_amount}${conv.to} ${conv.converted_amount}`,
rate: conv.exchange_rate,
route: conv.route
}));
}

getTotalConverted(currency) {
return this.conversions
.filter(conv => conv.to === currency)
.reduce((total, conv) => total + conv.converted_amount, 0);
}
}

// Usage
const tracker = new ConversionTracker();
await tracker.convert('IDR', 'USD', 1000000);
await tracker.convert('USD', 'SGD', 100);

console.log('Conversion History:', tracker.getHistory());
console.log('Total USD Converted:', tracker.getTotalConverted('USD'));
} catch (error) {
console.error('Detailed conversion failed:', error.message);
}

Detailed Properties:

  • original_amount: Input amount
  • converted_amount: Output amount
  • exchange_rate: Calculated rate
  • route: Conversion path taken
  • usdc_intermediate: USDC amount (if applicable)

getRate (Deprecated)

⚠️ This method is deprecated. Use getFiatRoutesConversion instead.

Syntax:

await fx.getRate(from, to)

Example:

// ❌ Deprecated - will show warning
const rate = await fx.getRate('USD', 'IDR');

// ✅ Use this instead
const conversion = await fx.getFiatRoutesConversion('USD', 'IDR', 1);
console.log('Rate:', conversion.result); // Rate for 1 USD

simulateFx (Deprecated)

⚠️ This method is deprecated. Use convertAll instead.

Syntax:

await fx.simulateFx(data)

Example:

// ❌ Deprecated - will show warning
const simulation = await fx.simulateFx({
from_currency: 'IDR',
to_currency: 'USDC',
amount: 1000000
});

// ✅ Use this instead
const conversion = await fx.convertAll('IDR', 'USDC', 1000000);
console.log('Conversion result:', conversion);

Complete Integration Example

class FXManager {
constructor() {
this.fx = null;
this.init();
}

async init() {
// Initialize SDK
const config = await brdzSDK.config;
config.setBaseUrl('https://api.brdz.link/api');
config.setApiKey('your_api_key');

this.fx = await brdzSDK.fx;
}

async getCurrentRates() {
try {
const ticker = await this.fx.getUsdcTicker();
return ticker.success ? ticker.data : null;
} catch (error) {
console.error('Failed to get rates:', error);
return null;
}
}

async convertCurrency(from, to, amount) {
try {
if (from === 'USDC' || to === 'USDC') {
// Direct USDC conversion
const direction = from === 'USDC' ? 'toFiat' : 'fromFiat';
const fiat = from === 'USDC' ? to : from;
return await this.fx.getUsdcConversion(fiat, direction, amount);
} else {
// FIAT to FIAT conversion
return await this.fx.convertAll(from, to, amount);
}
} catch (error) {
console.error('Conversion failed:', error);
throw error;
}
}

async refreshRates() {
try {
const result = await this.fx.updateUsdcTicker();
return result.success;
} catch (error) {
console.error('Rate refresh failed:', error);
return false;
}
}

async calculatePortfolioValue(holdings, targetCurrency = 'USD') {
let totalValue = 0;
const conversions = [];

for (const holding of holdings) {
if (holding.currency === targetCurrency) {
totalValue += holding.amount;
conversions.push({
...holding,
convertedAmount: holding.amount,
rate: 1
});
} else {
const conversion = await this.convertCurrency(
holding.currency,
targetCurrency,
holding.amount
);

const convertedAmount = conversion.converted_amount || conversion.result;
totalValue += convertedAmount;

conversions.push({
...holding,
convertedAmount,
rate: conversion.exchange_rate || conversion.rate
});
}
}

return {
totalValue,
targetCurrency,
conversions,
timestamp: new Date().toISOString()
};
}
}

// Usage
const fxManager = new FXManager();
await fxManager.init();

// Get current rates
const rates = await fxManager.getCurrentRates();
console.log('Current rates:', rates);

// Convert currency
const conversion = await fxManager.convertCurrency('IDR', 'USD', 1000000);
console.log('Conversion result:', conversion);

// Calculate portfolio value
const portfolio = [
{ currency: 'IDR', amount: 10000000, asset: 'Cash' },
{ currency: 'USD', amount: 500, asset: 'Savings' },
{ currency: 'USDC', amount: 1000, asset: 'Crypto' }
];

const valuation = await fxManager.calculatePortfolioValue(portfolio, 'USD');
console.log(`Total Portfolio Value: $${valuation.totalValue.toFixed(2)} USD`);

Error Handling

Common Error Patterns

try {
const result = await fx.convertAll('IDR', 'USD', 1000000);
} catch (error) {
if (error.message.includes('Missing required parameters')) {
console.error('Invalid parameters provided');
} else if (error.message.includes('Invalid amount')) {
console.error('Amount must be a positive number');
} else if (error.message.includes('Unsupported currency')) {
console.error('Currency not supported');
} else if (error.message.includes('Conversion failed')) {
console.error('Rate source unavailable, try again later');
} else {
console.error('Unexpected error:', error.message);
}
}

Rate Availability Check

async function checkRateAvailability(currencies) {
try {
const ticker = await fx.getUsdcTicker();

if (!ticker.success) {
return { available: false, reason: 'Ticker service unavailable' };
}

const unavailable = currencies.filter(curr =>
curr !== 'USDC' && !ticker.data[curr]
);

if (unavailable.length > 0) {
return {
available: false,
reason: `Unsupported currencies: ${unavailable.join(', ')}`
};
}

return { available: true };
} catch (error) {
return { available: false, reason: error.message };
}
}

// Usage
const availability = await checkRateAvailability(['IDR', 'USD', 'SGD']);
if (availability.available) {
// Proceed with conversion
} else {
console.error('Cannot convert:', availability.reason);
}

USDC Bridge Architecture

All currency conversions use USDC as an intermediate bridge:

Conversion Flow

  1. FIAT → USDC: Convert source fiat to USDC
  2. USDC → FIAT: Convert USDC to target fiat
  3. Rate Calculation: Combine both rates for final conversion

Advantages

  • Consistent Pricing: Single source of truth for rates
  • Reduced Complexity: No need for N×N currency pairs
  • Real-time Updates: Direct connection to Coinbase rates
  • Lower Slippage: Stable intermediate currency

Supported Currencies

Primary Fiat Currencies

  • IDR: Indonesian Rupiah (~15,000-16,000 per USDC)
  • USD: US Dollar (~1.0000 per USDC)
  • SGD: Singapore Dollar (~1.30-1.40 per USDC)

Digital Assets

  • USDC: USD Coin (bridge currency)

Rate Characteristics

  • Update Frequency: Every 15 minutes (automatic)
  • Manual Updates: Available via API
  • Precision: Up to 6 decimal places
  • Source: Coinbase Pro API

Best Practices

1. Rate Monitoring

// Monitor significant rate changes
class RateMonitor {
constructor(threshold = 1) {
this.threshold = threshold; // 1% change threshold
this.previousRates = {};
}

async checkSignificantChanges() {
const ticker = await fx.getUsdcTicker();

if (ticker.success) {
Object.entries(ticker.data).forEach(([currency, data]) => {
if (Math.abs(data.percent) > this.threshold) {
console.log(`🚨 ${currency} changed ${data.percent}% in recent period`);
}
});
}
}
}

2. Conversion Batching

// Batch multiple conversions for efficiency
async function batchConvert(conversions) {
return Promise.all(
conversions.map(conv =>
fx.convertAll(conv.from, conv.to, conv.amount)
)
);
}

3. Rate Caching

// Cache rates to reduce API calls
class RateCache {
constructor(ttl = 300000) { // 5 minutes TTL
this.cache = new Map();
this.ttl = ttl;
}

async getRates() {
const now = Date.now();
const cached = this.cache.get('rates');

if (cached && (now - cached.timestamp) < this.ttl) {
return cached.data;
}

const rates = await fx.getUsdcTicker();
this.cache.set('rates', {
data: rates,
timestamp: now
});

return rates;
}
}