Skip to main content

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?

Security Layer

Prevents unauthorized withdrawals to unknown addresses by requiring pre-approval.

Fraud Prevention

Adds friction to withdrawal attacks, giving users time to detect unauthorized activity.

Compliance Tracking

Maintains beneficiary records for all withdrawal destinations, supporting regulatory requirements.

User Protection

Reduces risk of user error by validating addresses before enabling withdrawals.

How Whitelisting Works

Adding Addresses to Whitelist

Add one or more external wallet addresses to the user’s whitelist:
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
      }
    ]
  }'

Request Parameters

FieldRequiredDescription
currencyYesCurrency for this address (e.g., “usdc”, “xrp”, “btc”)
nameYesDescriptive name to identify this address
beneficiaryFirstNameYesFirst name of the address owner
beneficiaryLastNameYesLast name of the address owner
walletAddressYesBlockchain address for withdrawals
walletMemoNoMemo/destination tag (required for XRP, Stellar, etc.)
Whitelist entries are currency-specific. The same address can be whitelisted for multiple currencies if the blockchain supports multiple assets.

Viewing Whitelisted Addresses

Retrieve all whitelisted addresses for a specific currency:
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"

Response Fields

FieldDescription
idWhitelist entry identifier (used for deletion)
nameUser-provided name for this address
beneficiaryFirstNameBeneficiary first name
beneficiaryLastNameBeneficiary last name
walletAddressBlockchain address
walletMemoMemo/destination tag if applicable
currencyCurrency for this address
lastUsedAtTimestamp of most recent withdrawal (null if never used)
createdAtTimestamp when address was whitelisted
The lastUsedAt field helps users identify their frequently-used withdrawal addresses. This can be useful for displaying “favorites” or “recent” addresses in your UI.

Removing Addresses from Whitelist

Delete one or more whitelisted addresses:
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"]
  }'
Removing an address from the whitelist immediately prevents withdrawals to that address. Any pending withdrawals to the removed address may fail.

Network-Specific Requirements

Different blockchain networks have different address formats and requirements:

EVM Networks (Ethereum, Linea)

{
  "currency": "usdc",
  "walletAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
  "walletMemo": null
}
Ethereum addresses are 42 characters starting with “0x”. No memo required.

Solana

{
  "currency": "usdc",
  "walletAddress": "DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK",
  "walletMemo": null
}
Solana addresses are base58-encoded, 32-44 characters. No memo required.

XRP Ledger

{
  "currency": "xrp",
  "walletAddress": "rNxp4h8apvRis6mJf9Sh8C6iRxfrDWN7AA",
  "walletMemo": "66"
}
XRP addresses start with “r” and are 25-35 characters. Destination tag (memo) is required for exchange addresses.
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.

Address Validation

The platform performs basic validation when addresses are added:
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”
For currencies with checksum validation (Ethereum, Bitcoin), verifies address checksum to prevent typos.
Ensures the address format matches the currency’s blockchain network. For example, prevents adding an Ethereum address for Bitcoin.
Checks if the exact address (including memo) is already whitelisted for the same currency.
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.

Implementation Examples

Complete Whitelist Flow

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);
}

Whitelist Management UI

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>
  );
}

Use Cases

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)
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
Whitelist addresses for DeFi protocols, staking services, or other blockchain applications.Example:
  • Name: “Aave Lending Pool”
  • Address: Your Aave deposit address
  • Beneficiary: Your name
Whitelist addresses of family members for easy recurring transfers.Example:
  • Name: “Spouse - Emergency Fund”
  • Address: Spouse’s wallet address
  • Beneficiary: Spouse’s name

Error Handling

Invalid Address Format

{
  "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

{
  "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

{
  "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

{
  "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

Verify Before Adding

Always double-check addresses before whitelisting. Blockchain transactions are irreversible, and incorrect addresses can result in permanent loss of funds.

Use Descriptive Names

Give each address a clear, memorable name that helps identify its purpose (e.g., “Coinbase Main” not “Address 1”).

Store Beneficiary Info Accurately

Use the actual name of the address owner for compliance tracking and dispute resolution.

Include Memos When Required

For XRP and similar networks, always include the destination tag/memo if provided by the recipient. Missing memos can cause lost funds.

Test with Small Amounts

Before large withdrawals, test new addresses with small amounts to verify the address is correct and accessible.

Regular Audits

Periodically review whitelisted addresses and remove any that are no longer needed or controlled.

Display Last Used Date

Show lastUsedAt in your UI to help users identify their active vs. unused addresses.

Security Considerations

Irreversible Transactions: Blockchain transactions cannot be reversed. If you whitelist an incorrect address and withdraw funds, they cannot be recovered.
Address Verification: The platform validates address format but cannot verify ownership. Ensure you control the address before whitelisting.
Phishing Prevention: Verify you’re adding addresses from trusted sources. Attackers may provide fake addresses that look similar to legitimate ones.
Two-Factor Authentication: Consider implementing additional verification (2FA, email confirmation) before allowing users to add or modify whitelist addresses.

Next Steps