Get External Wallets
curl --request GET \
--url https://api.example.com/v1/wallet/external \
--header 'Authorization: <authorization>' \
--header 'x-client-key: <x-client-key>'import requests
url = "https://api.example.com/v1/wallet/external"
headers = {
"x-client-key": "<x-client-key>",
"Authorization": "<authorization>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {'x-client-key': '<x-client-key>', Authorization: '<authorization>'}
};
fetch('https://api.example.com/v1/wallet/external', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/v1/wallet/external",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"x-client-key: <x-client-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v1/wallet/external"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-client-key", "<x-client-key>")
req.Header.Add("Authorization", "<authorization>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/v1/wallet/external")
.header("x-client-key", "<x-client-key>")
.header("Authorization", "<authorization>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v1/wallet/external")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-client-key"] = '<x-client-key>'
request["Authorization"] = '<authorization>'
response = http.request(request)
puts response.read_body[
{
"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"
}
]
{
"message": "Not authenticated"
}
{
"message": "Not authorized"
}
{
"message": "Internal server error"
}
Wallet
Get External Wallets
Retrieve non-custodial wallet addresses registered by the user
GET
/
v1
/
wallet
/
external
Get External Wallets
curl --request GET \
--url https://api.example.com/v1/wallet/external \
--header 'Authorization: <authorization>' \
--header 'x-client-key: <x-client-key>'import requests
url = "https://api.example.com/v1/wallet/external"
headers = {
"x-client-key": "<x-client-key>",
"Authorization": "<authorization>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {'x-client-key': '<x-client-key>', Authorization: '<authorization>'}
};
fetch('https://api.example.com/v1/wallet/external', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/v1/wallet/external",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"x-client-key: <x-client-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v1/wallet/external"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-client-key", "<x-client-key>")
req.Header.Add("Authorization", "<authorization>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/v1/wallet/external")
.header("x-client-key", "<x-client-key>")
.header("Authorization", "<authorization>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v1/wallet/external")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-client-key"] = '<x-client-key>'
request["Authorization"] = '<authorization>'
response = http.request(request)
puts response.read_body[
{
"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"
}
]
{
"message": "Not authenticated"
}
{
"message": "Not authorized"
}
{
"message": "Internal server error"
}
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
- View all registered external wallets
- Check current balance and allowance
- Verify wallet registration status
- Display available payment sources
Authentication
string
required
Your public API client key
string
required
Bearer token for authentication
Query Parameters
boolean
default:false
Route to US backend environment
Response
Returns an array of registered external wallets.string
Blockchain address of the external wallet
string
Currency held in the wallet (e.g., “usdc”, “usdt”)
string
Current on-chain balance (decimal string)
string
Maximum amount platform can spend from this wallet (delegation limit)
string
Blockchain network (e.g., “linea”, “ethereum”, “solana”)
[
{
"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"
}
]
{
"message": "Not authenticated"
}
{
"message": "Not authorized"
}
{
"message": "Internal server error"
}
Code Examples
curl -X GET "https://dev.api.baanx.com/v1/wallet/external" \
-H "x-client-key: YOUR_CLIENT_KEY" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
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")
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`);
});
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
);
Understanding Balance vs Allowance
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.
Calculate Available Amount
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
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
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
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
Allowance Limitations: Even if balance is high, transactions cannot exceed the delegated allowance. Users must redelegate to increase allowance.
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).
Network Specificity: Same address on different networks represents different wallets. Always check both address AND network when identifying wallets.
Edge Cases
Empty Wallet List
User has not completed delegation: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: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: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:1
Get Delegation Token
Call
GET /v1/delegation/token to initiate2
Connect Wallet
User connects wallet in your frontend (MetaMask, WalletConnect, etc.)
3
Approve Transaction
User signs blockchain transaction granting spending authority
4
Submit Proof
Call blockchain-specific endpoint:
POST /v1/delegation/evm/post-approvalfor Linea/EthereumPOST /v1/delegation/solana/post-approvalfor Solana
5
Verify Registration
Check this endpoint to confirm wallet appears in list
Related Endpoints
- Get External Wallet Priority - View and update wallet charging order
- Get Delegation Token - Start delegation flow to register new wallet
- Withdraw from Credit Wallet - Withdraw to external wallet
- Withdraw from Reward Wallet - Withdraw to external wallet
Was this page helpful?