Bridge Wallets Management
Quick Reference
typescript
const SUPPORTED_CHAINS = ['solana', 'ethereum', 'polygon', 'base', 'arbitrum', 'tron'] as const; type Chain = typeof SUPPORTED_CHAINS[number];
Create Wallet
typescript
interface CreateWalletRequest {
chain: Chain;
}
interface Wallet {
id: string;
chain: Chain;
address: string;
tags: string[];
created_at: string;
updated_at: string;
}
async function createWallet(customerId: string, chain: Chain): Promise<Wallet> {
const response = await fetch(`${BRIDGE_API_URL}/customers/${customerId}/wallets`, {
method: 'POST',
headers: {
'Api-Key': API_KEY,
'Idempotency-Key': crypto.randomUUID(),
'Content-Type': 'application/json',
},
body: JSON.stringify({ chain }),
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Wallet creation failed: ${error.message}`);
}
return response.json();
}
// Usage examples
const wallet1 = await createWallet('cust_alice', 'solana');
// { id: "wallet_123", chain: "solana", address: "4oG1sWkP8vcrnhbkzZc1m9RTT2VUjZHKx92qiVFK7FuZ", ... }
const wallet2 = await createWallet('cust_alice', 'ethereum');
// { id: "wallet_456", chain: "ethereum", address: "0x...", ... }
Multi-Chain Wallet Setup
typescript
class MultiChainWalletManager {
private customerId: string;
constructor(customerId: string) {
this.customerId = customerId;
}
async createAllChains(): Promise<Map<Chain, Wallet>> {
const wallets = new Map<Chain, Wallet>();
await Promise.all(
SUPPORTED_CHAINS.map(async (chain) => {
const wallet = await createWallet(this.customerId, chain);
wallets.set(chain, wallet);
})
);
return wallets;
}
async getWalletByChain(chain: Chain): Promise<Wallet> {
const wallets = await listWallets(this.customerId);
return wallets.find(w => w.chain === chain);
}
}
// Usage
const manager = new MultiChainWalletManager('cust_treasury');
await manager.createAllChains();
List Wallets
typescript
async function listWallets(customerId: string): Promise<Wallet[]> {
const response = await fetch(`${BRIDGE_API_URL}/customers/${customerId}/wallets`, {
headers: {
'Api-Key': API_KEY,
},
});
if (!response.ok) {
throw new Error('Failed to list wallets');
}
return response.json();
}
// Usage with filtering
async function getActiveWallets(customerId: string): Promise<Wallet[]> {
const wallets = await listWallets(customerId);
return wallets.filter(w => w.status === 'active');
}
Wallet-to-Wallet Transfer
typescript
interface TransferRequest {
amount: string;
on_behalf_of: string;
developer_fee?: string;
developer_fee_percent?: string;
source: {
payment_rail: 'bridge_wallet';
currency: string;
bridge_wallet_id: string;
};
destination: {
payment_rail: Chain;
currency: string;
bridge_wallet_id: string;
};
features?: {
flexible_amount?: boolean;
};
}
interface Transfer {
id: string;
state: 'awaiting_funds' | 'completed' | 'failed';
amount: string;
developer_fee: string;
source: {
payment_rail: string;
currency: string;
from_address?: string;
bridge_wallet_id?: string;
};
destination: {
payment_rail: string;
currency: string;
to_address?: string;
bridge_wallet_id?: string;
};
receipt?: {
initial_amount: string;
developer_fee: string;
exchange_fee: string;
final_amount: string;
destination_tx_hash?: string;
url?: string;
};
created_at: string;
updated_at: string;
}
async function transferBetweenWallets(
request: Omit<TransferRequest, 'on_behalf_of'>
): Promise<Transfer> {
const response = await fetch(`${BRIDGE_API_URL}/transfers`, {
method: 'POST',
headers: {
'Api-Key': API_KEY,
'Idempotency-Key': crypto.randomUUID(),
'Content-Type': 'application/json',
},
body: JSON.stringify(request),
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Transfer failed: ${error.message}`);
}
return response.json();
}
// Payroll example: Employer to Employee
async function processPayroll(
employerCustomerId: string,
employeeWalletId: string,
amount: string,
employeeChain: Chain
): Promise<Transfer> {
const employerWallets = await listWallets(employerCustomerId);
const employerWallet = employerWallets[0]; // Using first wallet
return transferBetweenWallets({
amount,
source: {
payment_rail: 'bridge_wallet',
currency: 'usdc',
bridge_wallet_id: employerWallet.id,
},
destination: {
payment_rail: employeeChain,
currency: 'usdc',
bridge_wallet_id: employeeWalletId,
},
});
}
// Usage
const payroll = await processPayroll(
'cust_employer',
'wallet_employee_123',
'1000.0',
'solana'
);
Wallet Tagging & Policies
typescript
interface WalletTag {
key: string;
value: string;
}
async function tagWallet(walletId: string, tags: WalletTag[]): Promise<Wallet> {
const response = await fetch(`${BRIDGE_API_URL}/wallets/${walletId}/tags`, {
method: 'PUT',
headers: {
'Api-Key': API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({ tags }),
});
if (!response.ok) {
throw new Error('Failed to tag wallet');
}
return response.json();
}
// Treasury management tagging
async function setupTreasuryWallets(customerId: string) {
const wallets = await Promise.all([
createWallet(customerId, 'solana'),
createWallet(customerId, 'ethereum'),
createWallet(customerId, 'polygon'),
]);
await Promise.all([
tagWallet(wallets[0].id, [
{ key: 'purpose', value: 'payroll' },
{ key: 'department', value: 'engineering' },
]),
tagWallet(wallets[1].id, [
{ key: 'purpose', value: 'reserves' },
{ key: 'policy', value: 'hold_until_emergency' },
]),
tagWallet(wallets[2].id, [
{ key: 'purpose', value: 'operations' },
{ key: 'budget', value: 'monthly' },
]),
]);
}
Balance Query
typescript
interface WalletBalance {
wallet_id: string;
available: {
amount: string;
currency: string;
};
pending: {
amount: string;
currency: string;
};
}
async function getWalletBalance(walletId: string): Promise<WalletBalance> {
const response = await fetch(`${BRIDGE_API_URL}/wallets/${walletId}/balance`, {
headers: {
'Api-Key': API_KEY,
},
});
if (!response.ok) {
throw new Error('Failed to get balance');
}
return response.json();
}
async function getAllWalletBalances(customerId: string): Promise<WalletBalance[]> {
const wallets = await listWallets(customerId);
return Promise.all(
wallets.map(async (wallet) => {
try {
return await getWalletBalance(wallet.id);
} catch {
return {
wallet_id: wallet.id,
available: { amount: '0', currency: 'usdc' },
pending: { amount: '0', currency: 'usdc' },
};
}
})
);
}
// Dashboard summary
async function getTreasurySummary(customerId: string) {
const balances = await getAllWalletBalances(customerId);
const wallets = await listWallets(customerId);
return {
totalWallets: wallets.length,
totalValueUSD: balances.reduce(
(sum, b) => sum + parseFloat(b.available.amount),
0
),
byChain: wallets.map((w, i) => ({
chain: w.chain,
address: w.address,
balance: balances[i].available,
})),
};
}
Fund Wallet (Onramp)
typescript
interface FundWalletRequest {
on_behalf_of: string;
source: {
payment_rail: 'ach_push' | 'wire' | 'sepa';
currency: 'usd' | 'eur';
};
destination: {
payment_rail: Chain;
currency: string; // 'usdc', 'usdb'
bridge_wallet_id: string;
};
features?: {
flexible_amount?: boolean;
};
}
async function fundWallet(request: FundWalletRequest): Promise<Transfer> {
const response = await fetch(`${BRIDGE_API_URL}/transfers`, {
method: 'POST',
headers: {
'Api-Key': API_KEY,
'Idempotency-Key': crypto.randomUUID(),
'Content-Type': 'application/json',
},
body: JSON.stringify(request),
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Funding failed: ${error.message}`);
}
return response.json();
}
// Usage: Fund from USD bank account to Solana wallet
const transfer = await fundWallet({
on_behalf_of: 'cust_alice',
source: {
payment_rail: 'ach_push',
currency: 'usd',
},
destination: {
payment_rail: 'solana',
currency: 'usdc',
bridge_wallet_id: 'wallet_sol_123',
},
});
console.log('Transfer ID:', transfer.id);
console.log('Status:', transfer.state);
console.log('Deposit Instructions:', transfer.source_deposit_instructions);
Complete Treasury Management Example
typescript
class TreasuryManager {
private customerId: string;
constructor(customerId: string) {
this.customerId = customerId;
}
async initializeTreasury(): Promise<void> {
await this.createAllChainWallets();
console.log('Treasury wallets initialized');
}
private async createAllChainWallets(): Promise<void> {
await createWallet(this.customerId, 'solana');
await createWallet(this.customerId, 'ethereum');
await createWallet(this.customerId, 'polygon');
}
async distributeFunds(
amounts: Partial<Record<Chain, string>>
): Promise<Transfer[]> {
const wallets = await listWallets(this.customerId);
const mainWallet = wallets[0]; // Using first wallet as source
const transfers: Transfer[] = [];
for (const [chain, amount] of Object.entries(amounts)) {
const targetWallet = wallets.find(w => w.chain === chain);
if (targetWallet && amount) {
const transfer = await transferBetweenWallets({
amount,
source: {
payment_rail: 'bridge_wallet',
currency: 'usdc',
bridge_wallet_id: mainWallet.id,
},
destination: {
payment_rail: chain as Chain,
currency: 'usdc',
bridge_wallet_id: targetWallet.id,
},
});
transfers.push(transfer);
}
}
return transfers;
}
async getDashboard(): Promise<{
summary: Awaited<ReturnType<typeof getTreasurySummary>>;
recentTransfers: Transfer[];
}> {
const [summary, transfers] = await Promise.all([
getTreasurySummary(this.customerId),
listTransfers({ on_behalf_of: this.customerId, limit: 5 }),
]);
return { summary, recentTransfers: transfers.data };
}
}
// Usage
const treasury = new TreasuryManager('cust_company');
await treasury.initializeTreasury();
await treasury.distributeFunds({
solana: '5000',
ethereum: '3000',
polygon: '2000',
});
const dashboard = await treasury.getDashboard();
console.log('Treasury Dashboard:', dashboard);
Webhook Events
- •
wallet.created- New wallet created - •
wallet.tagged- Wallet tags updated - •
transfer.completed- Transfer finished successfully
Best Practices
- •Never send tokens directly to wallet address - Use liquidation addresses
- •Save wallet IDs - Required for all future operations
- •Idempotency - Always use
Idempotency-Key - •Error handling - Handle chain-specific errors gracefully
- •Balance checks - Verify balances before transfers