> ## 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.

# Whitelist Management

> Manage approved withdrawal addresses for secure custodial wallet operations

## Overview

The whitelist is a security feature that restricts custodial wallet withdrawals to pre-approved external addresses. Before funds can be withdrawn from an internal wallet, the destination address must be added to the user's whitelist with verified beneficiary information.

## Why Whitelisting?

<CardGroup cols={2}>
  <Card title="Security Layer" icon="shield-check">
    Prevents unauthorized withdrawals to unknown addresses by requiring pre-approval.
  </Card>

  <Card title="Fraud Prevention" icon="ban">
    Adds friction to withdrawal attacks, giving users time to detect unauthorized activity.
  </Card>

  <Card title="Compliance Tracking" icon="clipboard-check">
    Maintains beneficiary records for all withdrawal destinations, supporting regulatory requirements.
  </Card>

  <Card title="User Protection" icon="user-shield">
    Reduces risk of user error by validating addresses before enabling withdrawals.
  </Card>
</CardGroup>

## How Whitelisting Works

```mermaid theme={null}
graph TB
    A[User Requests Withdrawal] --> B{Address Whitelisted?}
    B -->|No| C[User Adds Address to Whitelist]
    C --> D[Platform Validates Address]
    D --> E[Address Approved]
    E --> F[User Can Withdraw]
    B -->|Yes| F
    F --> G[Platform Executes Withdrawal]
    G --> H[Funds Sent On-Chain]
```

## Adding Addresses to Whitelist

Add one or more external wallet addresses to the user's whitelist:

<CodeGroup>
  ```bash Single Address theme={null}
  curl -X POST "https://api.example.com/v1/wallet/whitelist" \
    -H "x-client-key: YOUR_PUBLIC_KEY" \
    -H "Authorization: Bearer USER_ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "wallets": [
        {
          "currency": "usdc",
          "name": "Coinbase Main Account",
          "beneficiaryFirstName": "John",
          "beneficiaryLastName": "Doe",
          "walletAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
          "walletMemo": null
        }
      ]
    }'
  ```

  ```bash Multiple Addresses theme={null}
  curl -X POST "https://api.example.com/v1/wallet/whitelist" \
    -H "x-client-key: YOUR_PUBLIC_KEY" \
    -H "Authorization: Bearer USER_ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "wallets": [
        {
          "currency": "usdc",
          "name": "Coinbase USDC Account",
          "beneficiaryFirstName": "John",
          "beneficiaryLastName": "Doe",
          "walletAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
          "walletMemo": null
        },
        {
          "currency": "xrp",
          "name": "Binance XRP Wallet",
          "beneficiaryFirstName": "John",
          "beneficiaryLastName": "Doe",
          "walletAddress": "rNxp4h8apvRis6mJf9Sh8C6iRxfrDWN7AA",
          "walletMemo": "66"
        }
      ]
    }'
  ```

  ```json Response theme={null}
  {
    "success": true
  }
  ```
</CodeGroup>

### Request Parameters

| Field                  | Required | Description                                            |
| ---------------------- | -------- | ------------------------------------------------------ |
| `currency`             | Yes      | Currency for this address (e.g., "usdc", "xrp", "btc") |
| `name`                 | Yes      | Descriptive name to identify this address              |
| `beneficiaryFirstName` | Yes      | First name of the address owner                        |
| `beneficiaryLastName`  | Yes      | Last name of the address owner                         |
| `walletAddress`        | Yes      | Blockchain address for withdrawals                     |
| `walletMemo`           | No       | Memo/destination tag (required for XRP, Stellar, etc.) |

<Note>
  Whitelist entries are currency-specific. The same address can be whitelisted for multiple currencies if the blockchain supports multiple assets.
</Note>

## Viewing Whitelisted Addresses

Retrieve all whitelisted addresses for a specific currency:

<CodeGroup>
  ```bash Request theme={null}
  curl -X GET "https://api.example.com/v1/wallet/whitelist?currency=usdc" \
    -H "x-client-key: YOUR_PUBLIC_KEY" \
    -H "Authorization: Bearer USER_ACCESS_TOKEN"
  ```

  ```json Response theme={null}
  [
    {
      "id": "d7ed0d12-270c-4491-b1a4-bebf2cc42b5c",
      "name": "Coinbase Main Account",
      "beneficiaryFirstName": "John",
      "beneficiaryLastName": "Doe",
      "walletAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
      "walletMemo": null,
      "currency": "usdc",
      "lastUsedAt": "2025-08-12T13:44:47.287Z",
      "createdAt": "2025-08-11T13:44:47.287Z"
    },
    {
      "id": "e8fe1e23-381d-5502-c2b5-5feg3dd53c6d",
      "name": "Hardware Wallet",
      "beneficiaryFirstName": "John",
      "beneficiaryLastName": "Doe",
      "walletAddress": "0x1b5c32gb844f9fbefcef181303b96c670ef24d5e",
      "walletMemo": null,
      "currency": "usdc",
      "lastUsedAt": null,
      "createdAt": "2025-08-10T10:22:33.000Z"
    }
  ]
  ```
</CodeGroup>

### Response Fields

| Field                  | Description                                              |
| ---------------------- | -------------------------------------------------------- |
| `id`                   | Whitelist entry identifier (used for deletion)           |
| `name`                 | User-provided name for this address                      |
| `beneficiaryFirstName` | Beneficiary first name                                   |
| `beneficiaryLastName`  | Beneficiary last name                                    |
| `walletAddress`        | Blockchain address                                       |
| `walletMemo`           | Memo/destination tag if applicable                       |
| `currency`             | Currency for this address                                |
| `lastUsedAt`           | Timestamp of most recent withdrawal (null if never used) |
| `createdAt`            | Timestamp when address was whitelisted                   |

<Note>
  The `lastUsedAt` field helps users identify their frequently-used withdrawal addresses. This can be useful for displaying "favorites" or "recent" addresses in your UI.
</Note>

## Removing Addresses from Whitelist

Delete one or more whitelisted addresses:

<CodeGroup>
  ```bash Single Address theme={null}
  curl -X DELETE "https://api.example.com/v1/wallet/whitelist" \
    -H "x-client-key: YOUR_PUBLIC_KEY" \
    -H "Authorization: Bearer USER_ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "walletIds": ["d7ed0d12-270c-4491-b1a4-bebf2cc42b5c"]
    }'
  ```

  ```bash Multiple Addresses theme={null}
  curl -X DELETE "https://api.example.com/v1/wallet/whitelist" \
    -H "x-client-key: YOUR_PUBLIC_KEY" \
    -H "Authorization: Bearer USER_ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "walletIds": [
        "d7ed0d12-270c-4491-b1a4-bebf2cc42b5c",
        "e8fe1e23-381d-5502-c2b5-5feg3dd53c6d"
      ]
    }'
  ```

  ```json Response theme={null}
  {
    "success": true
  }
  ```
</CodeGroup>

<Warning>
  Removing an address from the whitelist immediately prevents withdrawals to that address. Any pending withdrawals to the removed address may fail.
</Warning>

## Network-Specific Requirements

Different blockchain networks have different address formats and requirements:

### EVM Networks (Ethereum, Linea)

<Tabs>
  <Tab title="Standard Address">
    ```json theme={null}
    {
      "currency": "usdc",
      "walletAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
      "walletMemo": null
    }
    ```

    Ethereum addresses are 42 characters starting with "0x". No memo required.
  </Tab>
</Tabs>

### Solana

<Tabs>
  <Tab title="Standard Address">
    ```json theme={null}
    {
      "currency": "usdc",
      "walletAddress": "DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK",
      "walletMemo": null
    }
    ```

    Solana addresses are base58-encoded, 32-44 characters. No memo required.
  </Tab>
</Tabs>

### XRP Ledger

<Tabs>
  <Tab title="Address with Destination Tag">
    ```json theme={null}
    {
      "currency": "xrp",
      "walletAddress": "rNxp4h8apvRis6mJf9Sh8C6iRxfrDWN7AA",
      "walletMemo": "66"
    }
    ```

    XRP addresses start with "r" and are 25-35 characters. **Destination tag (memo) is required** for exchange addresses.
  </Tab>
</Tabs>

<Warning>
  For XRP and similar networks, always include the destination tag (memo) if provided by the recipient. Missing destination tags can result in lost funds or delayed processing.
</Warning>

## Address Validation

The platform performs basic validation when addresses are added:

<AccordionGroup>
  <Accordion title="Format Validation">
    Ensures address matches expected format for the currency:

    * Ethereum/Linea: 42-character hex string starting with "0x"
    * Solana: 32-44 character base58 string
    * XRP: 25-35 characters starting with "r"
    * Bitcoin: 26-35 characters starting with "1", "3", or "bc1"
  </Accordion>

  <Accordion title="Checksum Verification">
    For currencies with checksum validation (Ethereum, Bitcoin), verifies address checksum to prevent typos.
  </Accordion>

  <Accordion title="Network Compatibility">
    Ensures the address format matches the currency's blockchain network. For example, prevents adding an Ethereum address for Bitcoin.
  </Accordion>

  <Accordion title="Duplicate Prevention">
    Checks if the exact address (including memo) is already whitelisted for the same currency.
  </Accordion>
</AccordionGroup>

<Note>
  While the platform validates address format, it cannot verify that you control the address or that it's the correct destination. Always double-check addresses before whitelisting.
</Note>

## Implementation Examples

### Complete Whitelist Flow

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function addToWhitelist(userToken, addressData) {
    const response = await fetch(
      'https://api.example.com/v1/wallet/whitelist',
      {
        method: 'POST',
        headers: {
          'x-client-key': 'YOUR_PUBLIC_KEY',
          'Authorization': `Bearer ${userToken}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          wallets: [addressData]
        })
      }
    );

    if (!response.ok) {
      const error = await response.json();
      throw new Error(error.message);
    }

    return await response.json();
  }

  // Usage
  const addressData = {
    currency: 'usdc',
    name: 'My Coinbase Account',
    beneficiaryFirstName: 'John',
    beneficiaryLastName: 'Doe',
    walletAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
    walletMemo: null
  };

  try {
    await addToWhitelist(userToken, addressData);
    console.log('Address whitelisted successfully');
  } catch (error) {
    console.error('Failed to whitelist address:', error.message);
  }
  ```

  ```python Python theme={null}
  import requests
  from typing import Dict, Optional

  def add_to_whitelist(
      user_token: str,
      currency: str,
      name: str,
      beneficiary_first_name: str,
      beneficiary_last_name: str,
      wallet_address: str,
      wallet_memo: Optional[str] = None
  ) -> Dict:
      url = 'https://api.example.com/v1/wallet/whitelist'
      headers = {
          'x-client-key': 'YOUR_PUBLIC_KEY',
          'Authorization': f'Bearer {user_token}',
          'Content-Type': 'application/json'
      }

      payload = {
          'wallets': [{
              'currency': currency,
              'name': name,
              'beneficiaryFirstName': beneficiary_first_name,
              'beneficiaryLastName': beneficiary_last_name,
              'walletAddress': wallet_address,
              'walletMemo': wallet_memo
          }]
      }

      response = requests.post(url, headers=headers, json=payload)
      response.raise_for_status()

      return response.json()

  # Usage
  result = add_to_whitelist(
      user_token=user_token,
      currency='usdc',
      name='My Coinbase Account',
      beneficiary_first_name='John',
      beneficiary_last_name='Doe',
      wallet_address='0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb'
  )
  print('Address whitelisted successfully')
  ```
</CodeGroup>

### Whitelist Management UI

<CodeGroup>
  ```jsx React Component theme={null}
  import { useState, useEffect } from 'react';

  function WhitelistManager({ userToken, currency }) {
    const [addresses, setAddresses] = useState([]);
    const [loading, setLoading] = useState(false);

    useEffect(() => {
      fetchWhitelist();
    }, [currency]);

    const fetchWhitelist = async () => {
      setLoading(true);
      const response = await fetch(
        `https://api.example.com/v1/wallet/whitelist?currency=${currency}`,
        {
          headers: {
            'x-client-key': 'YOUR_PUBLIC_KEY',
            'Authorization': `Bearer ${userToken}`
          }
        }
      );
      const data = await response.json();
      setAddresses(data);
      setLoading(false);
    };

    const removeAddress = async (id) => {
      if (!confirm('Remove this address from whitelist?')) return;

      await fetch('https://api.example.com/v1/wallet/whitelist', {
        method: 'DELETE',
        headers: {
          'x-client-key': 'YOUR_PUBLIC_KEY',
          'Authorization': `Bearer ${userToken}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ walletIds: [id] })
      });

      await fetchWhitelist();
    };

    if (loading) return <div>Loading...</div>;

    return (
      <div className="whitelist-manager">
        <h3>Whitelisted {currency.toUpperCase()} Addresses</h3>

        {addresses.length === 0 ? (
          <p>No whitelisted addresses yet. Add one to enable withdrawals.</p>
        ) : (
          <div className="address-list">
            {addresses.map(addr => (
              <div key={addr.id} className="address-card">
                <div className="address-header">
                  <h4>{addr.name}</h4>
                  <button onClick={() => removeAddress(addr.id)}>
                    Remove
                  </button>
                </div>

                <div className="address-details">
                  <div>
                    <label>Beneficiary</label>
                    <span>
                      {addr.beneficiaryFirstName} {addr.beneficiaryLastName}
                    </span>
                  </div>

                  <div>
                    <label>Address</label>
                    <code>{addr.walletAddress}</code>
                  </div>

                  {addr.walletMemo && (
                    <div>
                      <label>Memo</label>
                      <code>{addr.walletMemo}</code>
                    </div>
                  )}

                  <div className="metadata">
                    <span>Added: {new Date(addr.createdAt).toLocaleDateString()}</span>
                    {addr.lastUsedAt && (
                      <span>Last used: {new Date(addr.lastUsedAt).toLocaleDateString()}</span>
                    )}
                  </div>
                </div>
              </div>
            ))}
          </div>
        )}
      </div>
    );
  }
  ```
</CodeGroup>

## Use Cases

<AccordionGroup>
  <Accordion title="Exchange Withdrawals">
    Whitelist your exchange deposit addresses (Coinbase, Binance, Kraken) to quickly move funds from your custodial wallet to exchange accounts.

    **Example:**

    * Name: "Coinbase USDC Account"
    * Address: Your Coinbase USDC deposit address
    * Beneficiary: Your name (as registered with Coinbase)
  </Accordion>

  <Accordion title="Personal Cold Storage">
    Whitelist your hardware wallet or cold storage addresses for secure long-term holdings.

    **Example:**

    * Name: "Ledger Nano X - Primary"
    * Address: Your Ledger device address
    * Beneficiary: Your name
  </Accordion>

  <Accordion title="Third-Party Services">
    Whitelist addresses for DeFi protocols, staking services, or other blockchain applications.

    **Example:**

    * Name: "Aave Lending Pool"
    * Address: Your Aave deposit address
    * Beneficiary: Your name
  </Accordion>

  <Accordion title="Family Member Transfers">
    Whitelist addresses of family members for easy recurring transfers.

    **Example:**

    * Name: "Spouse - Emergency Fund"
    * Address: Spouse's wallet address
    * Beneficiary: Spouse's name
  </Accordion>
</AccordionGroup>

## Error Handling

### Invalid Address Format

```json theme={null}
{
  "error": "Invalid address format",
  "code": "WALLET_INVALID_ADDRESS",
  "message": "The provided wallet address is not a valid Ethereum address"
}
```

**Solution:** Verify the address format matches the currency's blockchain. Use address validation libraries before submitting.

### Duplicate Address

```json theme={null}
{
  "error": "Address already whitelisted",
  "code": "WALLET_DUPLICATE_WHITELIST",
  "message": "This address is already whitelisted for this currency"
}
```

**Solution:** The address is already whitelisted. No action needed. Fetch the whitelist to confirm.

### Missing Memo

```json theme={null}
{
  "error": "Memo required",
  "code": "WALLET_MEMO_REQUIRED",
  "message": "This network requires a memo/destination tag"
}
```

**Solution:** Provide the `walletMemo` field for networks like XRP that require destination tags.

### Invalid Currency

```json theme={null}
{
  "error": "Unsupported currency",
  "code": "WALLET_UNSUPPORTED_CURRENCY",
  "message": "The specified currency is not supported"
}
```

**Solution:** Verify the currency is supported in your environment. Check API documentation for available currencies.

## Best Practices

<Card title="Verify Before Adding" icon="magnifying-glass-check">
  Always double-check addresses before whitelisting. Blockchain transactions are irreversible, and incorrect addresses can result in permanent loss of funds.
</Card>

<Card title="Use Descriptive Names" icon="tag">
  Give each address a clear, memorable name that helps identify its purpose (e.g., "Coinbase Main" not "Address 1").
</Card>

<Card title="Store Beneficiary Info Accurately" icon="user-check">
  Use the actual name of the address owner for compliance tracking and dispute resolution.
</Card>

<Card title="Include Memos When Required" icon="memo">
  For XRP and similar networks, always include the destination tag/memo if provided by the recipient. Missing memos can cause lost funds.
</Card>

<Card title="Test with Small Amounts" icon="flask">
  Before large withdrawals, test new addresses with small amounts to verify the address is correct and accessible.
</Card>

<Card title="Regular Audits" icon="clipboard-list">
  Periodically review whitelisted addresses and remove any that are no longer needed or controlled.
</Card>

<Card title="Display Last Used Date" icon="clock">
  Show `lastUsedAt` in your UI to help users identify their active vs. unused addresses.
</Card>

## Security Considerations

<Warning>
  **Irreversible Transactions**: Blockchain transactions cannot be reversed. If you whitelist an incorrect address and withdraw funds, they cannot be recovered.
</Warning>

<Warning>
  **Address Verification**: The platform validates address format but cannot verify ownership. Ensure you control the address before whitelisting.
</Warning>

<Warning>
  **Phishing Prevention**: Verify you're adding addresses from trusted sources. Attackers may provide fake addresses that look similar to legitimate ones.
</Warning>

<Note>
  **Two-Factor Authentication**: Consider implementing additional verification (2FA, email confirmation) before allowing users to add or modify whitelist addresses.
</Note>

## Next Steps

<CardGroup cols={2}>
  <Card title="Withdrawals" icon="arrow-right-from-bracket" href="/guides/wallet/custodial/withdrawals">
    Learn how to withdraw funds to whitelisted addresses
  </Card>

  <Card title="Internal Wallets" icon="wallet" href="/guides/wallet/custodial/internal-wallets">
    Manage internal wallets for deposits and storage
  </Card>

  <Card title="Security Best Practices" icon="shield-halved" href="/guides/oauth/security">
    Implement security measures for your integration
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/wallet/whitelist">
    View complete API documentation
  </Card>
</CardGroup>
