AgentSkillsCN

Bridge Wallets

借助Bridge.xyz API管理托管钱包。可在多条区块链网络(Solana、以太坊、Polygon、Base、Arbitrum)上创建并管理钱包,支持钱包间转账、余额查询,以及钱包标签策略的实施。适用场景包括:钱包创建、资金库管理、多链支持,以及资金统筹与调配。

SKILL.md
--- frontmatter
name: Bridge Wallets
description: Custodial wallet management with Bridge.xyz API. Create and manage wallets on multiple blockchain networks (Solana, Ethereum, Polygon, Base, Arbitrum), handle wallet-to-wallet transfers, query balances, and implement wallet tagging policies. Use for: wallet creation, treasury management, multi-chain support, and fund management.

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

  1. Never send tokens directly to wallet address - Use liquidation addresses
  2. Save wallet IDs - Required for all future operations
  3. Idempotency - Always use Idempotency-Key
  4. Error handling - Handle chain-specific errors gracefully
  5. Balance checks - Verify balances before transfers