> ## Documentation Index
> Fetch the complete documentation index at: https://docs.baanx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get External Wallets

> Retrieve non-custodial wallet addresses registered by the user

## Overview

External wallets are non-custodial wallet addresses where users maintain full control of their private keys. These wallets are registered through the delegation flow and can be used for card payments and withdrawal destinations.

**Key Differences from Internal Wallets:**

* **User controls private keys** (non-custodial)
* **Requires delegation** to grant spending authority to platform
* **Real-time balance checking** from blockchain
* **Allowance limits** control maximum spendable amount

**Use Cases:**

* View all registered external wallets
* Check current balance and allowance
* Verify wallet registration status
* Display available payment sources

## Authentication

<ParamField header="x-client-key" type="string" required>
  Your public API client key
</ParamField>

<ParamField header="Authorization" type="string" required>
  Bearer token for authentication
</ParamField>

## Query Parameters

<ParamField query="x-us-env" type="boolean" default={false}>
  Route to US backend environment
</ParamField>

## Response

Returns an array of registered external wallets.

<ResponseField name="address" type="string">
  Blockchain address of the external wallet
</ResponseField>

<ResponseField name="currency" type="string">
  Currency held in the wallet (e.g., "usdc", "usdt")
</ResponseField>

<ResponseField name="balance" type="string">
  Current on-chain balance (decimal string)
</ResponseField>

<ResponseField name="allowance" type="string">
  Maximum amount platform can spend from this wallet (delegation limit)
</ResponseField>

<ResponseField name="network" type="string">
  Blockchain network (e.g., "linea", "ethereum", "solana")
</ResponseField>

<ResponseExample>
  ```json 200 - Success theme={null}
  [
    {
      "address": "0x3a11a86cf218c448be519728cd3ac5c741fb3424",
      "currency": "usdc",
      "balance": "1250.50",
      "allowance": "5000",
      "network": "linea"
    },
    {
      "address": "0x7b22c1e6f8a4d92b5c3d8e9f1a2b3c4d5e6f7890",
      "currency": "usdt",
      "balance": "500.00",
      "allowance": "1000",
      "network": "ethereum"
    },
    {
      "address": "DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK",
      "currency": "usdc",
      "balance": "2000.00",
      "allowance": "3000",
      "network": "solana"
    }
  ]
  ```

  ```json 401 - Authentication Error theme={null}
  {
    "message": "Not authenticated"
  }
  ```

  ```json 403 - Authorization Error theme={null}
  {
    "message": "Not authorized"
  }
  ```

  ```json 500 - Internal Server Error theme={null}
  {
    "message": "Internal server error"
  }
  ```
</ResponseExample>

## Code Examples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://dev.api.baanx.com/v1/wallet/external" \
    -H "x-client-key: YOUR_CLIENT_KEY" \
    -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
  ```

  ```python Python theme={null}
  import requests

  url = "https://dev.api.baanx.com/v1/wallet/external"
  headers = {
      "x-client-key": "YOUR_CLIENT_KEY",
      "Authorization": "Bearer YOUR_ACCESS_TOKEN"
  }

  response = requests.get(url, headers=headers)
  external_wallets = response.json()

  print(f"Registered External Wallets: {len(external_wallets)}")

  for wallet in external_wallets:
      print(f"\n{wallet['currency'].upper()} on {wallet['network']}")
      print(f"  Address: {wallet['address']}")
      print(f"  Balance: {wallet['balance']}")
      print(f"  Allowance: {wallet['allowance']}")

      balance = float(wallet['balance'])
      allowance = float(wallet['allowance'])

      if balance < allowance * 0.2:
          print(f"  ⚠️  Low balance warning")
      if allowance < balance * 0.5:
          print(f"  ⚠️  Consider increasing allowance")
  ```

  ```javascript JavaScript theme={null}
  async function getExternalWallets() {
    const response = await fetch(
      'https://dev.api.baanx.com/v1/wallet/external',
      {
        headers: {
          'x-client-key': 'YOUR_CLIENT_KEY',
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
        }
      }
    );

    return await response.json();
  }

  const wallets = await getExternalWallets();

  console.log(`Found ${wallets.length} external wallets`);

  wallets.forEach(wallet => {
    const balance = parseFloat(wallet.balance);
    const allowance = parseFloat(wallet.allowance);
    const available = Math.min(balance, allowance);

    console.log(`${wallet.currency.toUpperCase()}: $${available} available`);
  });
  ```

  ```typescript TypeScript theme={null}
  interface ExternalWallet {
    address: string;
    currency: string;
    balance: string;
    allowance: string;
    network: string;
  }

  async function getExternalWallets(): Promise<ExternalWallet[]> {
    const response = await fetch(
      'https://dev.api.baanx.com/v1/wallet/external',
      {
        headers: {
          'x-client-key': 'YOUR_CLIENT_KEY',
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
        }
      }
    );

    if (!response.ok) {
      throw new Error('Failed to fetch external wallets');
    }

    return await response.json();
  }

  const wallets = await getExternalWallets();

  const lineaWallets = wallets.filter(w => w.network === 'linea');
  const totalLineaBalance = lineaWallets.reduce(
    (sum, w) => sum + parseFloat(w.balance),
    0
  );
  ```
</CodeGroup>

## Understanding Balance vs Allowance

<Note>
  **Available Amount**: The actual spendable amount is the MINIMUM of balance and allowance. If balance is 1000 but allowance is 500, only 500 can be spent.
</Note>

```javascript Calculate Available Amount theme={null}
function calculateAvailableAmount(wallet) {
  const balance = parseFloat(wallet.balance);
  const allowance = parseFloat(wallet.allowance);

  return {
    balance,
    allowance,
    available: Math.min(balance, allowance),
    needsTopUp: balance < allowance * 0.2,
    needsRedelegate: allowance < balance * 0.5
  };
}

const wallet = wallets[0];
const status = calculateAvailableAmount(wallet);

console.log(`Available: $${status.available}`);
if (status.needsTopUp) {
  console.log('⚠️ Wallet balance low - consider depositing more');
}
if (status.needsRedelegate) {
  console.log('⚠️ Allowance low - consider redelegating with higher limit');
}
```

## Integration Patterns

### Display Wallet Summary

```javascript theme={null}
async function getWalletsSummary() {
  const wallets = await getExternalWallets();

  const summary = {
    total: wallets.length,
    byNetwork: {},
    totalAvailable: 0
  };

  wallets.forEach(wallet => {
    const available = Math.min(
      parseFloat(wallet.balance),
      parseFloat(wallet.allowance)
    );

    if (!summary.byNetwork[wallet.network]) {
      summary.byNetwork[wallet.network] = 0;
    }
    summary.byNetwork[wallet.network] += available;
    summary.totalAvailable += available;
  });

  return summary;
}

const summary = await getWalletsSummary();
console.log(`Total available across all wallets: $${summary.totalAvailable.toFixed(2)}`);
```

### Check if User Has External Wallet

```javascript theme={null}
async function hasExternalWallet(currency, network) {
  const wallets = await getExternalWallets();

  return wallets.some(
    w => w.currency === currency && w.network === network
  );
}

const hasLineaUSDC = await hasExternalWallet('usdc', 'linea');
if (!hasLineaUSDC) {
  console.log('User needs to complete delegation for USDC on Linea');
}
```

### Find Wallet with Best Balance

```javascript theme={null}
function findBestWallet(wallets, currency) {
  const currencyWallets = wallets.filter(w => w.currency === currency);

  if (currencyWallets.length === 0) {
    return null;
  }

  return currencyWallets.reduce((best, current) => {
    const bestAvailable = Math.min(
      parseFloat(best.balance),
      parseFloat(best.allowance)
    );
    const currentAvailable = Math.min(
      parseFloat(current.balance),
      parseFloat(current.allowance)
    );

    return currentAvailable > bestAvailable ? current : best;
  });
}

const bestUSDC = findBestWallet(wallets, 'usdc');
console.log(`Best USDC wallet: ${bestUSDC.address} with $${bestUSDC.balance}`);
```

## Important Notes

<Warning>
  **Allowance Limitations**: Even if balance is high, transactions cannot exceed the delegated allowance. Users must redelegate to increase allowance.
</Warning>

<Tip>
  **Real-Time Balance**: Balances are fetched from the blockchain in real-time. For frequently updated UI, consider caching with appropriate TTL (e.g., 30 seconds).
</Tip>

<Note>
  **Network Specificity**: Same address on different networks represents different wallets. Always check both address AND network when identifying wallets.
</Note>

## Edge Cases

### Empty Wallet List

User has not completed delegation:

```javascript theme={null}
const wallets = await getExternalWallets();

if (wallets.length === 0) {
  // Redirect to delegation flow
  console.log('No external wallets registered');
  console.log('Please complete delegation to add a wallet');
}
```

### Zero Balance

Wallet is registered but empty:

```javascript theme={null}
const emptyWallets = wallets.filter(w => parseFloat(w.balance) === 0);

if (emptyWallets.length > 0) {
  console.log('⚠️ Some wallets have zero balance:');
  emptyWallets.forEach(w => {
    console.log(`  ${w.address} (${w.network})`);
  });
}
```

### Exceeded Allowance

Balance exceeds allowance:

```javascript theme={null}
const needsRedelegation = wallets.filter(w =>
  parseFloat(w.balance) > parseFloat(w.allowance)
);

if (needsRedelegation.length > 0) {
  console.log('💡 Consider increasing allowance for these wallets:');
  needsRedelegation.forEach(w => {
    const excess = parseFloat(w.balance) - parseFloat(w.allowance);
    console.log(`  ${w.address}: $${excess.toFixed(2)} unusable`);
  });
}
```

## Delegation Flow

To register a new external wallet, users must complete the delegation flow:

<Steps>
  <Step title="Get Delegation Token">
    Call `GET /v1/delegation/token` to initiate
  </Step>

  <Step title="Connect Wallet">
    User connects wallet in your frontend (MetaMask, WalletConnect, etc.)
  </Step>

  <Step title="Approve Transaction">
    User signs blockchain transaction granting spending authority
  </Step>

  <Step title="Submit Proof">
    Call blockchain-specific endpoint:

    * `POST /v1/delegation/evm/post-approval` for Linea/Ethereum
    * `POST /v1/delegation/solana/post-approval` for Solana
  </Step>

  <Step title="Verify Registration">
    Check this endpoint to confirm wallet appears in list
  </Step>
</Steps>

See the [Delegation Guide](/guides/delegation/overview) for complete implementation details.

## Related Endpoints

* [Get External Wallet Priority](/api-reference/wallet/external-priority) - View and update wallet charging order
* [Get Delegation Token](/api-reference/delegation/token) - Start delegation flow to register new wallet
* [Withdraw from Credit Wallet](/api-reference/wallet/credit-withdraw) - Withdraw to external wallet
* [Withdraw from Reward Wallet](/api-reference/wallet/reward-withdraw) - Withdraw to external wallet
