Skip to main content

Overview

When users delegate multiple wallets, priority determines the order in which wallets are evaluated for funding card transactions. When a transaction is initiated, the platform checks wallets sequentially in priority order (1, 2, 3…). The first wallet with sufficient balance and allowance to cover the entire transaction cost is used. Only one wallet funds each transaction - multi-funding is not supported.
Priority is a simple numeric value where lower numbers = higher priority. Priority 1 is checked before Priority 2, which is checked before Priority 3, etc.
Critical: If a wallet has insufficient balance to cover the ENTIRE transaction, it’s skipped entirely. The platform moves to the next priority wallet. Partial funding from multiple wallets is NOT supported.

How Priority Works

Sequential Wallet Evaluation

When a user makes a card purchase, the platform evaluates wallets in priority order to find one that can fund the entire transaction:
1

Check Priority 1 Wallet

Platform checks the highest priority wallet (priority: 1) for sufficient balance and allowance to cover the ENTIRE transaction amount
2

Use or Skip

  • Sufficient Balance: Transaction is funded entirely from Priority 1 wallet. Process complete.
  • Insufficient Balance: Priority 1 wallet is skipped entirely (no partial funding). Platform moves to Priority 2.
3

Check Next Priority

If Priority 1 was insufficient, check Priority 2 for sufficient balance. If sufficient, use Priority 2 for the entire transaction. If insufficient, skip to Priority 3.
4

Success or Failure

Process continues through priority list until a wallet with sufficient balance is found (transaction succeeds) or all wallets exhausted (transaction fails).
Key Point: Only ONE wallet is used per transaction. The platform does not combine funds from multiple wallets. Each wallet must have enough balance to cover the full transaction cost.

Why Wallets Are Skipped

A wallet is skipped and the next priority wallet is evaluated when:
  • Insufficient balance: Wallet doesn’t have enough tokens to cover the ENTIRE purchase amount
  • Insufficient allowance: Remaining delegated amount is less than the full purchase amount
  • Network unavailable: Blockchain network is experiencing issues
  • Transaction timeout: Blockchain confirmation takes too long
If ALL wallets have insufficient balance to cover the full transaction cost, the card transaction will be declined. At least one wallet must have sufficient balance for the entire amount. Partial funding from multiple wallets is not supported.

Get Current Priority

Retrieve the priority order of all delegated wallets for a user.

API Request

interface WalletPriority {
  id: number;
  address: string;
  currency: string;
  network: string;
  priority: number;
}

async function getCurrentPriority(
  userAccessToken: string
): Promise<WalletPriority[]> {
  const response = await fetch(
    'https://api.yourplatform.com/v1/wallet/external/priority',
    {
      method: 'GET',
      headers: {
        'x-client-key': process.env.CLIENT_PUBLIC_KEY!,
        'Authorization': `Bearer ${userAccessToken}`
      }
    }
  );

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

  return await response.json();
}
API Reference: GET /v1/wallet/external/priority

Response

[
  {
    "id": 551,
    "address": "0x3a11a86cf218c448be519728cd3ac5c741fb3424",
    "currency": "usdc",
    "network": "linea",
    "priority": 1
  },
  {
    "id": 552,
    "address": "0x7b22e8a8f132448be519728cd3ac5c741fb9876",
    "currency": "usdt",
    "network": "ethereum",
    "priority": 2
  },
  {
    "id": 553,
    "address": "DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK",
    "currency": "usdc",
    "network": "solana",
    "priority": 3
  }
]

Response Fields

FieldTypeDescription
idnumberUnique wallet identifier (required for updates)
addressstringWallet address
currencystringToken currency (usdc, usdt)
networkstringBlockchain network (linea, ethereum, solana)
prioritynumberCharging priority (lower = higher priority)

Update Priority

Reorder wallet priority to change which wallets are charged first.

API Request

interface PriorityUpdate {
  id: number;
  priority: number;
}

async function updatePriority(
  userAccessToken: string,
  updates: PriorityUpdate[]
): Promise<void> {
  const response = await fetch(
    'https://api.yourplatform.com/v1/wallet/external/priority',
    {
      method: 'PUT',
      headers: {
        'x-client-key': process.env.CLIENT_PUBLIC_KEY!,
        'Authorization': `Bearer ${userAccessToken}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ wallets: updates })
    }
  );

  if (!response.ok) {
    const error = await response.json();
    throw new Error(error.message || 'Failed to update priority');
  }
}
API Reference: PUT /v1/wallet/external/priority

Request Body

{
  "wallets": [
    { "id": 552, "priority": 1 },
    { "id": 551, "priority": 2 },
    { "id": 553, "priority": 3 }
  ]
}
You must include ALL wallets in the update request. Any wallet not included will not have its priority changed.

Validation Rules

  • All priorities must be unique: No two wallets can have the same priority
  • Continuous numbering: Priorities should typically be 1, 2, 3, etc. (gaps are allowed but not recommended)
  • Valid wallet IDs: All IDs must belong to the user’s delegated wallets
  • Complete update: Include all wallets you want to manage

Use Cases

1. Gas Fee Optimization

Route transactions through lower-fee networks first. The platform will check wallets in this order and use the first one with sufficient balance for the entire transaction:
const priorityByGasCost = [
  { id: 553, priority: 1 }, // Solana (lowest fees ~$0.00025) - checked first
  { id: 551, priority: 2 }, // Linea (low fees ~$0.01-$0.10) - used if Solana insufficient
  { id: 552, priority: 3 }  // Ethereum (high fees $5-$50+) - used if both others insufficient
];

await updatePriority(userToken, priorityByGasCost);
When to use: Cost-conscious users making frequent small purchases. Ensures lowest fee network is used when possible, with higher-fee networks as fallback only when necessary.

2. Balance Management

Use wallets with smaller balances first to consolidate funds:
// Get current wallets with balances
const wallets = await getExternalWallets(userToken);

// Sort by balance ascending (spend smaller balances first)
const sortedByBalance = wallets
  .sort((a, b) => parseFloat(a.balance) - parseFloat(b.balance))
  .map((wallet, index) => ({
    id: wallet.id,
    priority: index + 1
  }));

await updatePriority(userToken, sortedByBalance);
When to use: Users want to consolidate funds or empty smaller wallets

3. Network Preference

Prefer specific networks for faster confirmations or better UX:
// Prefer Linea for speed and cost
const networkPreference = wallets.map(wallet => ({
  id: wallet.id,
  priority: wallet.network === 'linea' ? 1 :
            wallet.network === 'solana' ? 2 : 3
}));

await updatePriority(userToken, networkPreference);
When to use: Users want faster transactions or prefer specific ecosystems

4. Backup Wallet Strategy

Keep high-balance wallet as backup, use smaller wallets first. Each wallet must have enough balance to fund full transactions on its own:
const backupStrategy = [
  { id: 551, priority: 1 }, // Daily spending wallet (1,000 USDC) - used first
  { id: 552, priority: 2 }, // Secondary wallet (2,000 USDC) - backup if Priority 1 insufficient
  { id: 553, priority: 3 }  // Backup/savings wallet (10,000 USDC) - last resort
];

await updatePriority(userToken, backupStrategy);
When to use: Users want to protect larger holdings while ensuring transactions succeed. Note that if Priority 1 has insufficient balance for a transaction, it will be skipped entirely and Priority 2 used for the full amount.

5. Currency Routing

Prefer specific stablecoins based on availability or preference:
// Prefer USDC over USDT
const currencyPreference = wallets.map(wallet => ({
  id: wallet.id,
  priority: wallet.currency === 'usdc' ? 1 : 2
})).sort((a, b) => a.priority - b.priority)
  .map((item, index) => ({
    id: item.id,
    priority: index + 1
  }));

await updatePriority(userToken, currencyPreference);
When to use: Users prefer specific stablecoins for accounting or regulatory reasons

UI Implementation Examples

Drag-and-Drop Priority Management

import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
import { useState, useEffect } from 'react';

interface Wallet {
  id: number;
  address: string;
  currency: string;
  network: string;
  balance: string;
  priority: number;
}

function PriorityManager({ userId }: { userId: string }) {
  const [wallets, setWallets] = useState<Wallet[]>([]);
  const [loading, setLoading] = useState(false);

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

  async function loadWallets() {
    const data = await getCurrentPriority(userId);
    setWallets(data.sort((a, b) => a.priority - b.priority));
  }

  function handleDragEnd(result: any) {
    if (!result.destination) return;

    const items = Array.from(wallets);
    const [reorderedItem] = items.splice(result.source.index, 1);
    items.splice(result.destination.index, 0, reorderedItem);

    const updatedWallets = items.map((wallet, index) => ({
      ...wallet,
      priority: index + 1
    }));

    setWallets(updatedWallets);
  }

  async function savePriority() {
    setLoading(true);
    try {
      const updates = wallets.map(w => ({ id: w.id, priority: w.priority }));
      await updatePriority(userId, updates);
      alert('Priority updated successfully!');
    } catch (error) {
      console.error('Failed to update priority:', error);
      alert('Failed to update priority');
    } finally {
      setLoading(false);
    }
  }

  return (
    <div className="priority-manager">
      <h2>Wallet Priority</h2>
      <p>Drag to reorder. Wallets at the top are charged first.</p>

      <DragDropContext onDragEnd={handleDragEnd}>
        <Droppable droppableId="wallets">
          {(provided) => (
            <div {...provided.droppableProps} ref={provided.innerRef}>
              {wallets.map((wallet, index) => (
                <Draggable
                  key={wallet.id}
                  draggableId={wallet.id.toString()}
                  index={index}
                >
                  {(provided) => (
                    <div
                      ref={provided.innerRef}
                      {...provided.draggableProps}
                      {...provided.dragHandleProps}
                      className="wallet-card"
                    >
                      <div className="priority-badge">{wallet.priority}</div>
                      <div className="wallet-info">
                        <div className="network">{wallet.network}</div>
                        <div className="address">
                          {wallet.address.slice(0, 6)}...{wallet.address.slice(-4)}
                        </div>
                        <div className="balance">
                          {wallet.balance} {wallet.currency.toUpperCase()}
                        </div>
                      </div>
                    </div>
                  )}
                </Draggable>
              ))}
              {provided.placeholder}
            </div>
          )}
        </Droppable>
      </DragDropContext>

      <button onClick={savePriority} disabled={loading}>
        {loading ? 'Saving...' : 'Save Priority'}
      </button>
    </div>
  );
}

Quick Actions

function QuickActions({ wallets, onUpdate }: {
  wallets: Wallet[],
  onUpdate: (updates: PriorityUpdate[]) => void
}) {

  function optimizeForGas() {
    const gasCostOrder = ['solana', 'linea', 'ethereum'];
    const sorted = [...wallets].sort((a, b) => {
      return gasCostOrder.indexOf(a.network) - gasCostOrder.indexOf(b.network);
    });
    onUpdate(sorted.map((w, i) => ({ id: w.id, priority: i + 1 })));
  }

  function optimizeForBalance() {
    const sorted = [...wallets].sort((a, b) => {
      return parseFloat(a.balance) - parseFloat(b.balance);
    });
    onUpdate(sorted.map((w, i) => ({ id: w.id, priority: i + 1 })));
  }

  function preferNetwork(network: string) {
    const sorted = [...wallets].sort((a, b) => {
      if (a.network === network && b.network !== network) return -1;
      if (a.network !== network && b.network === network) return 1;
      return 0;
    });
    onUpdate(sorted.map((w, i) => ({ id: w.id, priority: i + 1 })));
  }

  return (
    <div className="quick-actions">
      <button onClick={optimizeForGas}>
        Optimize for Gas Fees
      </button>
      <button onClick={optimizeForBalance}>
        Use Smallest Balances First
      </button>
      <button onClick={() => preferNetwork('linea')}>
        Prefer Linea
      </button>
      <button onClick={() => preferNetwork('solana')}>
        Prefer Solana
      </button>
    </div>
  );
}

Best Practices

Priority Strategy Guidelines

Begin with a straightforward priority order based on your primary use case (e.g., lowest gas fees). You can always adjust later.
Regularly check wallet balances and adjust priority to prevent transaction failures. Set up alerts when balances run low.
For frequent small purchases, prioritizing lower-fee networks can save significant amounts over time.
Always keep at least one wallet with sufficient balance as a lower priority backup to prevent declined transactions.
After updating priority, make a small test purchase to ensure the new order works as expected.
Keep notes on why you’ve set specific priorities, especially for business accounts with multiple administrators.

Automation Opportunities

Consider building automated priority management:
async function autoAdjustPriority(userId: string) {
  const wallets = await getExternalWallets(userId);

  const optimized = wallets
    .filter(w => parseFloat(w.balance) > 100)
    .map(wallet => {
      let score = 0;

      if (wallet.network === 'solana') score += 3;
      else if (wallet.network === 'linea') score += 2;
      else score += 1;

      if (parseFloat(wallet.balance) < 500) score += 2;
      else if (parseFloat(wallet.balance) < 1000) score += 1;

      return { ...wallet, score };
    })
    .sort((a, b) => b.score - a.score)
    .map((w, i) => ({ id: w.id, priority: i + 1 }));

  await updatePriority(userId, optimized);
}

Troubleshooting

Symptoms: Transactions failing across all walletsCommon Causes:
  • All wallets have insufficient balance to cover the ENTIRE transaction amount
  • All allowances exhausted (need redelegation)
  • Network issues on all blockchains (rare)
Key Point: Remember that only ONE wallet funds each transaction. If you have 3 wallets with 30,30, 40, and 50,a50, a 100 transaction will FAIL even though the combined balance is $120. Each wallet is evaluated individually.Solutions:
  • Check balances: GET /v1/wallet/external
  • Ensure at least ONE wallet has sufficient balance for the full transaction
  • Top up wallets or redelegate with higher allowances
  • Verify network status on block explorers
Symptoms: Lower priority wallet charged instead of higher priorityCommon Causes:
  • Higher priority wallet has insufficient balance/allowance to cover the ENTIRE transaction (was skipped)
  • Recent priority update not yet reflected
  • Cached priority data
Expected Behavior: If Priority 1 wallet has insufficient balance for the full transaction amount, it will be skipped and Priority 2 will be used for the entire transaction. This is correct behavior - each wallet must be able to fund the full transaction on its own.Solutions:
  • Verify current priority: GET /v1/wallet/external/priority
  • Check wallet balances and allowances - ensure Priority 1 has enough for typical transaction sizes
  • Make test transaction to verify behavior
Symptoms: Priority update succeeds but charging order unchangedCommon Causes:
  • Update request malformed (missing wallets)
  • Duplicate priorities in request
  • API error not caught
Solutions:
  • Fetch current priority after update to verify
  • Ensure all wallet IDs are included in update
  • Check API response for errors

Next Steps