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

# External Wallet Operations

> View and manage user-controlled external wallets registered via delegation

## Overview

External wallets are user-controlled blockchain wallets registered through the delegation process. Users maintain full custody of their private keys while granting spending authority to the platform for card payments. The platform can view balance and allowance information but never has access to private keys.

## Viewing External Wallets

Retrieve all external wallets registered by the authenticated user:

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

  ```json Response theme={null}
  [
    {
      "address": "0x3a11a86cf218c448be519728cd3ac5c741fb3424",
      "currency": "usdc",
      "balance": "5000.00",
      "allowance": "3500",
      "network": "linea"
    },
    {
      "address": "0x7b22c97de329f3b8dc3b1c472f9af2b2e5c84a91",
      "currency": "usdt",
      "balance": "1250.75",
      "allowance": "1250",
      "network": "ethereum"
    },
    {
      "address": "DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK",
      "currency": "usdc",
      "balance": "800.00",
      "allowance": "500",
      "network": "solana"
    }
  ]
  ```
</CodeGroup>

### Response Fields

| Field       | Type   | Description                                      |
| ----------- | ------ | ------------------------------------------------ |
| `address`   | string | Blockchain wallet address controlled by user     |
| `currency`  | string | Currency delegated from this wallet              |
| `balance`   | string | Current wallet balance (on-chain)                |
| `allowance` | string | Remaining spending authority granted to platform |
| `network`   | string | Blockchain network (linea, ethereum, solana)     |

## Understanding Balance vs Allowance

External wallet data includes two critical values:

<Tabs>
  <Tab title="Balance">
    **Balance** is the total amount of cryptocurrency in the user's wallet on the blockchain.

    * Retrieved directly from blockchain
    * Updated in real-time
    * Includes all funds, not just delegated amount
    * User controls this completely

    **Example:**
    User has 5000 USDC total in their wallet. This is the `balance` value.
  </Tab>

  <Tab title="Allowance">
    **Allowance** is the remaining spending authority the user has granted to the platform.

    * Set during initial delegation
    * Decreases with each card transaction
    * Enforced by blockchain smart contract
    * Cannot exceed original delegated amount

    **Example:**
    User originally delegated 5000 USDC. After spending 1500 USDC on card purchases, `allowance` is 3500 USDC.
  </Tab>
</Tabs>

<Note>
  **Key Relationship:** Allowance can never exceed balance. Even if user delegated 5000 USDC but only has 2000 USDC remaining in wallet, maximum chargeable amount is 2000 USDC.
</Note>

## Interpreting Wallet Status

Different balance/allowance combinations indicate different states:

<AccordionGroup>
  <Accordion title="Healthy Wallet">
    ```json theme={null}
    {
      "balance": "5000.00",
      "allowance": "4800"
    }
    ```

    **Status:** Wallet is funded and has ample allowance.

    **Action:** None needed. User can make card purchases normally.
  </Accordion>

  <Accordion title="Low Allowance">
    ```json theme={null}
    {
      "balance": "5000.00",
      "allowance": "200"
    }
    ```

    **Status:** Wallet is funded but allowance is nearly exhausted.

    **Action:** Prompt user to redelegate with higher allowance to continue card payments.
  </Accordion>

  <Accordion title="Low Balance">
    ```json theme={null}
    {
      "balance": "150.00",
      "allowance": "3500"
    }
    ```

    **Status:** Allowance is high but wallet balance is low.

    **Action:** Platform can only charge up to 150 USDC (balance), not 3500 USDC (allowance). Prompt user to add funds to wallet.
  </Accordion>

  <Accordion title="Exhausted Allowance">
    ```json theme={null}
    {
      "balance": "5000.00",
      "allowance": "0"
    }
    ```

    **Status:** Allowance fully consumed, card payments blocked.

    **Action:** User must redelegate to continue using card. Balance is sufficient once redelegation completes.
  </Accordion>

  <Accordion title="Empty Wallet">
    ```json theme={null}
    {
      "balance": "0.00",
      "allowance": "0"
    }
    ```

    **Status:** Wallet is empty and no spending authority remains.

    **Action:** User must fund wallet and redelegate before card payments can resume.
  </Accordion>
</AccordionGroup>

## Registering External Wallets

External wallets are registered through the delegation process. Users cannot be added directly via the API.

<Steps>
  <Step title="User Initiates Delegation">
    User clicks "Connect Wallet" or "Add External Wallet" in your application.
  </Step>

  <Step title="Request Delegation Token">
    Your backend calls `GET /v1/delegation/token` to obtain a single-use token.
  </Step>

  <Step title="Frontend Wallet Interaction">
    User connects Web3 wallet and approves blockchain transaction granting spending authority.
  </Step>

  <Step title="Submit Delegation Proof">
    Your backend calls blockchain-specific endpoint to finalize registration:

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

  <Step title="Verify Registration">
    Call `GET /v1/wallet/external` to confirm wallet appears in user's registered wallets.
  </Step>
</Steps>

[Complete Delegation Guide →](/guides/delegation)

## Network-Specific Details

### EVM Networks (Linea, Ethereum)

<Tabs>
  <Tab title="Address Format">
    * **Length:** 42 characters
    * **Format:** Hexadecimal starting with "0x"
    * **Example:** `0x3a11a86cf218c448be519728cd3ac5c741fb3424`
    * **Checksum:** Case-sensitive checksummed addresses

    ```json theme={null}
    {
      "address": "0x3a11a86cf218c448be519728cd3ac5c741fb3424",
      "network": "linea"
    }
    ```
  </Tab>

  <Tab title="Delegation Method">
    Uses ERC-20 token `approve()` function:

    ```solidity theme={null}
    function approve(address spender, uint256 amount)
    ```

    * `spender`: Platform smart contract address
    * `amount`: Maximum spending limit (allowance)
  </Tab>

  <Tab title="Gas Considerations">
    * **Linea:** Low gas fees (\~\$0.01-0.05 per transaction)
    * **Ethereum:** Higher gas fees (\$2-10 depending on network congestion)

    Recommend Linea for cost-conscious users.
  </Tab>
</Tabs>

### Solana

<Tabs>
  <Tab title="Address Format">
    * **Length:** 32-44 characters
    * **Format:** Base58-encoded public key
    * **Example:** `DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK`

    ```json theme={null}
    {
      "address": "DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK",
      "network": "solana"
    }
    ```
  </Tab>

  <Tab title="Delegation Method">
    Uses SPL Token delegation:

    ```typescript theme={null}
    Token.createApproveInstruction(
      tokenAccount,
      delegateAddress,
      owner,
      amount
    )
    ```

    Creates delegation on token account, not wallet directly.
  </Tab>

  <Tab title="Transaction Speed">
    * **Confirmation:** 5-30 seconds
    * **Finality:** \~13 seconds
    * **Fees:** ~~0.000005 SOL (~~\$0.0001)

    Fastest and cheapest network for delegation.
  </Tab>
</Tabs>

## Implementation Examples

### Display External Wallets

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function fetchExternalWallets(userToken) {
    const response = await fetch(
      'https://api.example.com/v1/wallet/external',
      {
        headers: {
          'x-client-key': 'YOUR_PUBLIC_KEY',
          'Authorization': `Bearer ${userToken}`
        }
      }
    );

    const wallets = await response.json();

    return wallets.map(wallet => ({
      ...wallet,
      balanceNumber: parseFloat(wallet.balance),
      allowanceNumber: parseFloat(wallet.allowance),
      isLowAllowance: parseFloat(wallet.allowance) < parseFloat(wallet.balance) * 0.2,
      isLowBalance: parseFloat(wallet.balance) < 100,
      effectiveLimit: Math.min(
        parseFloat(wallet.balance),
        parseFloat(wallet.allowance)
      )
    }));
  }

  // Usage
  const wallets = await fetchExternalWallets(userToken);

  wallets.forEach(wallet => {
    console.log(`${wallet.network} ${wallet.currency.toUpperCase()}`);
    console.log(`  Address: ${wallet.address}`);
    console.log(`  Balance: ${wallet.balance}`);
    console.log(`  Allowance: ${wallet.allowance}`);
    console.log(`  Effective Limit: ${wallet.effectiveLimit}`);

    if (wallet.isLowAllowance) {
      console.log('  ⚠️ Low allowance - suggest redelegation');
    }

    if (wallet.isLowBalance) {
      console.log('  ⚠️ Low balance - suggest funding wallet');
    }
  });
  ```

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

  def fetch_external_wallets(user_token: str) -> List[Dict]:
      response = requests.get(
          'https://api.example.com/v1/wallet/external',
          headers={
              'x-client-key': 'YOUR_PUBLIC_KEY',
              'Authorization': f'Bearer {user_token}'
          }
      )

      wallets = response.json()

      for wallet in wallets:
          balance = float(wallet['balance'])
          allowance = float(wallet['allowance'])

          wallet['balance_number'] = balance
          wallet['allowance_number'] = allowance
          wallet['is_low_allowance'] = allowance < balance * 0.2
          wallet['is_low_balance'] = balance < 100
          wallet['effective_limit'] = min(balance, allowance)

      return wallets

  # Usage
  wallets = fetch_external_wallets(user_token)

  for wallet in wallets:
      print(f"{wallet['network']} {wallet['currency'].upper()}")
      print(f"  Address: {wallet['address']}")
      print(f"  Balance: {wallet['balance']}")
      print(f"  Allowance: {wallet['allowance']}")
      print(f"  Effective Limit: {wallet['effective_limit']}")

      if wallet['is_low_allowance']:
          print('  ⚠️ Low allowance - suggest redelegation')

      if wallet['is_low_balance']:
          print('  ⚠️ Low balance - suggest funding wallet')
  ```
</CodeGroup>

### Wallet Status Component

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

  function ExternalWalletList({ userToken }) {
    const [wallets, setWallets] = useState([]);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
      fetchWallets();
    }, []);

    const fetchWallets = async () => {
      setLoading(true);
      const response = await fetch(
        'https://api.example.com/v1/wallet/external',
        {
          headers: {
            'x-client-key': 'YOUR_PUBLIC_KEY',
            'Authorization': `Bearer ${userToken}`
          }
        }
      );

      const data = await response.json();
      setWallets(data);
      setLoading(false);
    };

    const getWalletStatus = (wallet) => {
      const balance = parseFloat(wallet.balance);
      const allowance = parseFloat(wallet.allowance);

      if (allowance === 0) return { status: 'exhausted', color: 'red' };
      if (allowance < balance * 0.2) return { status: 'low-allowance', color: 'orange' };
      if (balance < 100) return { status: 'low-balance', color: 'yellow' };
      return { status: 'healthy', color: 'green' };
    };

    const formatAddress = (address) => {
      return `${address.slice(0, 6)}...${address.slice(-4)}`;
    };

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

    if (wallets.length === 0) {
      return (
        <div className="empty-state">
          <p>No external wallets connected</p>
          <button onClick={() => window.location.href = '/connect-wallet'}>
            Connect Wallet
          </button>
        </div>
      );
    }

    return (
      <div className="wallet-list">
        <h3>External Wallets</h3>

        {wallets.map((wallet, index) => {
          const { status, color } = getWalletStatus(wallet);
          const effectiveLimit = Math.min(
            parseFloat(wallet.balance),
            parseFloat(wallet.allowance)
          );

          return (
            <div key={index} className={`wallet-card status-${color}`}>
              <div className="wallet-header">
                <div>
                  <h4>{wallet.currency.toUpperCase()} on {wallet.network}</h4>
                  <code>{formatAddress(wallet.address)}</code>
                </div>
                <div className={`status-badge ${color}`}>
                  {status.replace('-', ' ')}
                </div>
              </div>

              <div className="wallet-stats">
                <div className="stat">
                  <label>Balance</label>
                  <span>{wallet.balance} {wallet.currency.toUpperCase()}</span>
                </div>

                <div className="stat">
                  <label>Allowance</label>
                  <span>{wallet.allowance} {wallet.currency.toUpperCase()}</span>
                </div>

                <div className="stat">
                  <label>Available for Card</label>
                  <span className="highlight">
                    {effectiveLimit.toFixed(2)} {wallet.currency.toUpperCase()}
                  </span>
                </div>
              </div>

              {status === 'low-allowance' && (
                <div className="warning-banner">
                  Allowance is low. Redelegate to continue card payments.
                  <button onClick={() => handleRedelegate(wallet)}>
                    Redelegate
                  </button>
                </div>
              )}

              {status === 'low-balance' && (
                <div className="warning-banner">
                  Wallet balance is low. Add funds to enable purchases.
                  <button onClick={() => handleFundWallet(wallet)}>
                    Fund Wallet
                  </button>
                </div>
              )}

              {status === 'exhausted' && (
                <div className="error-banner">
                  Allowance exhausted. Redelegate to resume card payments.
                  <button onClick={() => handleRedelegate(wallet)}>
                    Redelegate Now
                  </button>
                </div>
              )}
            </div>
          );
        })}
      </div>
    );
  }
  ```
</CodeGroup>

## Monitoring and Alerts

Implement proactive monitoring to alert users before issues occur:

### Allowance Monitoring

<AccordionGroup>
  <Accordion title="50% Threshold">
    Alert when allowance drops below 50% of original delegation.

    **Message:** "Your allowance is half-used. Consider redelegating soon."
  </Accordion>

  <Accordion title="20% Threshold">
    Stronger alert when allowance drops below 20%.

    **Message:** "Your allowance is running low. Redelegate now to avoid payment issues."
  </Accordion>

  <Accordion title="Exhausted">
    Critical alert when allowance reaches 0.

    **Message:** "Card payments blocked. Redelegate immediately to continue."
  </Accordion>
</AccordionGroup>

### Balance Monitoring

<AccordionGroup>
  <Accordion title="Low Balance">
    Alert when balance drops below minimum threshold (e.g., \$100).

    **Message:** "Your wallet balance is low. Add funds to enable purchases."
  </Accordion>

  <Accordion title="Empty Wallet">
    Alert when balance reaches 0.

    **Message:** "Your wallet is empty. Add funds to resume card payments."
  </Accordion>
</AccordionGroup>

## Use Cases

<AccordionGroup>
  <Accordion title="Multi-Network Spending">
    Register wallets on different networks to optimize for fees or speed:

    * Linea for daily spending (low fees)
    * Ethereum for large purchases (more liquidity)
    * Solana for fast transactions (quick confirmations)

    Use priority management to control which network is charged first.
  </Accordion>

  <Accordion title="Currency Diversification">
    Register wallets with different currencies:

    * USDC wallet for stable value
    * USDT wallet as backup
    * Multiple stablecoins for redundancy

    Platform automatically tries next currency if primary is insufficient.
  </Accordion>

  <Accordion title="DeFi Integration">
    Users can keep majority of funds in DeFi protocols while maintaining delegated wallet for card payments:

    * Delegate small amount for daily spending
    * Keep bulk in yield-earning protocols
    * Transfer and redelegate as needed
  </Accordion>

  <Accordion title="Business Expense Separation">
    Register separate wallets for personal vs. business spending:

    * Personal wallet with priority 1
    * Business wallet with priority 2
    * Clear separation for accounting
  </Accordion>
</AccordionGroup>

## Best Practices

<Card title="Poll for Updates" icon="rotate">
  External wallet data is retrieved from blockchain in real-time. Poll this endpoint periodically (every 30-60 seconds) when user is viewing wallet information to show current status.
</Card>

<Card title="Show Effective Limit" icon="calculator">
  Display `min(balance, allowance)` as the actual spendable amount. This is the real limit for card transactions.
</Card>

<Card title="Proactive Redelegation Prompts" icon="bell">
  Alert users when allowance drops below 20% and provide one-click redelegation flow. Don't wait until allowance is exhausted.
</Card>

<Card title="Network Fee Information" icon="info-circle">
  Display approximate network fees for each blockchain to help users choose cost-effective options when registering multiple wallets.
</Card>

<Card title="Blockchain Explorer Links" icon="external-link">
  Provide links to blockchain explorers (Etherscan, Solscan) so users can verify wallet state independently.
</Card>

<Card title="Security Reminders" icon="shield-halved">
  Remind users that they control their private keys and should secure their wallet software properly. Platform never has access to keys.
</Card>

## Next Steps

<CardGroup cols={2}>
  <Card title="Delegation Guide" icon="link" href="/guides/delegation">
    Learn how to implement wallet delegation flow
  </Card>

  <Card title="Priority Management" icon="list-ol" href="/guides/wallet/non-custodial/priority">
    Control which wallet is charged first
  </Card>

  <Card title="Credit/Reward Withdrawals" icon="money-bill-transfer" href="/guides/wallet/non-custodial#credit-and-reward-wallets">
    Withdraw platform credits to external wallets
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference">
    Complete API documentation
  </Card>
</CardGroup>
