Wallets
Understanding wallet structure, states, and balance management
A wallet is the primary container for a user's balances in Phoenix Wallet. Each wallet can hold multiple assets and is uniquely identified within a tenant.
Wallet Structure
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier (UUID) |
tenant_id | string | Parent tenant identifier |
external_id | string | Your application's user ID |
status | enum | Current state: ACTIVE, FROZEN, CLOSED |
metadata | object | Custom key-value pairs |
created_at | timestamp | Creation timestamp |
updated_at | timestamp | Last modification timestamp |
Wallet States
Wallets follow a defined state machine that controls what operations are permitted:
┌──────────────┐
│ ACTIVE │
│ │
┌───────────────│ All ops │───────────────┐
│ │ permitted │ │
│ └──────────────┘ │
│ │ │
│ unfreeze() │ freeze() │ close()
│ ▼ │
│ ┌──────────────┐ │
└───────────────│ FROZEN │ │
│ │ │
│ Read-only │───────────────┤
│ No debits │ close() │
└──────────────┘ │
│
▼
┌──────────────┐
│ CLOSED │
│ │
│ Terminal │
│ state │
└──────────────┘State Descriptions
| State | Description | Allowed Operations |
|---|---|---|
ACTIVE | Normal operating state | All operations (credit, debit, reserve, transfer) |
FROZEN | Temporarily suspended | Read-only, credits only (no debits or reservations) |
CLOSED | Permanently closed | Read-only (balance must be zero) |
A wallet can only be closed when all balances are zero and there are no pending reservations. Attempting to close a wallet with remaining funds will result in an error.
Balances
Each wallet maintains balances per asset. The balance object provides a complete view of funds:
{
"wallet_id": "wal_01HV8X9Y2KPQRS3T4UV5WX6YZ7",
"balances": [
{
"asset_code": "USD",
"available": "15000",
"reserved": "2500",
"total": "17500",
"scale": 2
},
{
"asset_code": "POINTS",
"available": "50000",
"reserved": "0",
"total": "50000",
"scale": 0
}
]
}Understanding Balance Fields:
available- Funds that can be spent immediatelyreserved- Funds held by active reservations (authorization holds)total- The sum of available + reserved
The scale indicates decimal places. A USD balance of 15000 with scale 2 represents $150.00.
Balance Calculation
Balances are calculated from the underlying lots:
available = SUM(lot.available) for all non-expired lots
reserved = SUM(lot.reserved) for all active reservations
total = available + reservedThis means balances are always consistent with the ledger and lot state.
Creating a Wallet
curl -X POST https://api.phoenixwallet.io/v1/wallets \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"external_id": "user_123",
"metadata": {
"name": "John Doe",
"tier": "premium"
}
}'Response:
{
"id": "wal_01HV8X9Y2KPQRS3T4UV5WX6YZ7",
"tenant_id": "ten_01HV8X9Y2KPQRS3T4UV5WX6YZ7",
"external_id": "user_123",
"status": "ACTIVE",
"metadata": {
"name": "John Doe",
"tier": "premium"
},
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}Wallet Operations
Freeze a Wallet
curl -X POST https://api.phoenixwallet.io/v1/wallets/wal_01HV8X.../freeze \
-H "Authorization: Bearer $API_KEY"Unfreeze a Wallet
curl -X POST https://api.phoenixwallet.io/v1/wallets/wal_01HV8X.../unfreeze \
-H "Authorization: Bearer $API_KEY"Close a Wallet
curl -X POST https://api.phoenixwallet.io/v1/wallets/wal_01HV8X.../close \
-H "Authorization: Bearer $API_KEY"Related Concepts
- Assets - Types of value a wallet can hold
- Lots - How balances are organized within a wallet
- Reservations - How funds are held temporarily
- Ledger - Transaction history for the wallet