Ledger
Immutable transaction record using double-entry accounting
The ledger is the immutable record of all financial transactions in Phoenix Wallet. Built on double-entry accounting principles, it provides a complete audit trail and ensures that every operation is traceable and balanced.
Double-Entry Accounting
Every transaction in Phoenix Wallet creates balanced ledger entries. For every debit, there's a corresponding credit, ensuring the books always balance:
Transaction: User deposits $100
┌─────────────────────────────────────────────────────────────┐
│ Ledger Entries │
├─────────────────────────────────────────────────────────────┤
│ Entry #1: DEBIT System Liability Account $100.00 │
│ Entry #2: CREDIT User Wallet (lot_abc) $100.00 │
├─────────────────────────────────────────────────────────────┤
│ Balance: $0.00 (debits = credits) ✓ │
└─────────────────────────────────────────────────────────────┘This ensures:
- Accuracy - Mathematical verification that all transactions balance
- Auditability - Complete trail of every fund movement
- Integrity - No funds can be created or destroyed accidentally
Entry Structure
| Field | Type | Description |
|---|---|---|
id | string | Unique entry identifier |
transaction_id | string | Parent transaction grouping |
wallet_id | string | Affected wallet |
lot_id | string | Affected lot (if applicable) |
asset_code | string | Asset type |
amount | string | Entry amount (always positive) |
direction | enum | CREDIT or DEBIT |
entry_type | enum | Type of entry (see below) |
balance_after | string | Lot balance after this entry |
metadata | object | Custom key-value pairs |
created_at | timestamp | Entry timestamp |
Entry Types
| Type | Description | Effect on Wallet |
|---|---|---|
CREDIT | Funds added to lot | Increases available balance |
DEBIT | Funds removed from lot | Decreases available balance |
RESERVE | Funds moved to reserved | Decreases available, increases reserved |
RELEASE | Reserved funds returned | Increases available, decreases reserved |
COMMIT | Reserved funds finalized | Decreases reserved, removes from wallet |
EXPIRE | Lot expiration | Decreases available (funds forfeited) |
Transaction Examples
Simple Credit (Deposit)
{
"transaction_id": "txn_01HV8X9Y2KPQRS3T4UV5WX6YZ7",
"entries": [
{
"id": "ent_01HV8X9Y2KPQRS3T4UV5WX6YZ7",
"wallet_id": "wal_01HV8X9Y2KPQRS3T4UV5WX6YZ7",
"lot_id": "lot_01HV8X9Y2KPQRS3T4UV5WX6YZ7",
"asset_code": "USD",
"amount": "10000",
"direction": "CREDIT",
"entry_type": "CREDIT",
"balance_after": "10000",
"metadata": {
"source": "bank_transfer",
"reference": "dep_12345"
},
"created_at": "2024-01-15T10:30:00Z"
}
]
}Reservation Flow
Creating a reservation generates a RESERVE entry:
{
"transaction_id": "txn_02HV8X9Y2KPQRS3T4UV5WX6YZ8",
"entries": [
{
"id": "ent_02HV8X9Y2KPQRS3T4UV5WX6YZ8",
"wallet_id": "wal_01HV8X9Y2KPQRS3T4UV5WX6YZ7",
"lot_id": "lot_01HV8X9Y2KPQRS3T4UV5WX6YZ7",
"asset_code": "USD",
"amount": "2500",
"direction": "DEBIT",
"entry_type": "RESERVE",
"balance_after": "7500",
"metadata": {
"reservation_id": "rsv_01HV8X9Y2KPQRS3T4UV5WX6YZ7",
"intent": "purchase"
},
"created_at": "2024-01-15T11:00:00Z"
}
]
}Committing the reservation generates a COMMIT entry:
{
"transaction_id": "txn_03HV8X9Y2KPQRS3T4UV5WX6YZ9",
"entries": [
{
"id": "ent_03HV8X9Y2KPQRS3T4UV5WX6YZ9",
"wallet_id": "wal_01HV8X9Y2KPQRS3T4UV5WX6YZ7",
"lot_id": "lot_01HV8X9Y2KPQRS3T4UV5WX6YZ7",
"asset_code": "USD",
"amount": "2500",
"direction": "DEBIT",
"entry_type": "COMMIT",
"balance_after": "7500",
"metadata": {
"reservation_id": "rsv_01HV8X9Y2KPQRS3T4UV5WX6YZ7",
"order_id": "ord_12345"
},
"created_at": "2024-01-15T12:00:00Z"
}
]
}Wallet-to-Wallet Transfer
Transfers create paired entries across two wallets:
{
"transaction_id": "txn_04HV8X9Y2KPQRS3T4UV5WX6YZA",
"entries": [
{
"id": "ent_04HV8X9Y2KPQRS3T4UV5WX6YZA",
"wallet_id": "wal_sender",
"lot_id": "lot_sender_01",
"asset_code": "USD",
"amount": "5000",
"direction": "DEBIT",
"entry_type": "DEBIT",
"balance_after": "2500",
"metadata": {
"transfer_to": "wal_recipient",
"reason": "P2P transfer"
}
},
{
"id": "ent_05HV8X9Y2KPQRS3T4UV5WX6YZB",
"wallet_id": "wal_recipient",
"lot_id": "lot_recipient_01",
"asset_code": "USD",
"amount": "5000",
"direction": "CREDIT",
"entry_type": "CREDIT",
"balance_after": "5000",
"metadata": {
"transfer_from": "wal_sender",
"reason": "P2P transfer"
}
}
]
}Immutability
Ledger entries are immutable. Once created, they cannot be modified or deleted. This is fundamental to maintaining audit integrity.
To correct errors, you must create new compensating entries:
Original (incorrect): CREDIT $100 to user
Correction: DEBIT $100 from user (reversal)
CREDIT $75 to user (correct amount)This approach ensures:
- Complete audit trail of all changes
- Regulatory compliance
- Forensic analysis capability
Querying the Ledger
Get Transaction History for a Wallet
curl "https://api.phoenixwallet.io/v1/wallets/wal_01HV8X.../ledger" \
-H "Authorization: Bearer $API_KEY"Filter by Date Range
curl "https://api.phoenixwallet.io/v1/wallets/wal_01HV8X.../ledger?from=2024-01-01&to=2024-01-31" \
-H "Authorization: Bearer $API_KEY"Filter by Entry Type
curl "https://api.phoenixwallet.io/v1/wallets/wal_01HV8X.../ledger?entry_type=CREDIT" \
-H "Authorization: Bearer $API_KEY"Get Specific Transaction
curl "https://api.phoenixwallet.io/v1/transactions/txn_01HV8X..." \
-H "Authorization: Bearer $API_KEY"Ledger Response Example
{
"data": [
{
"id": "ent_01HV8X9Y2KPQRS3T4UV5WX6YZ7",
"transaction_id": "txn_01HV8X9Y2KPQRS3T4UV5WX6YZ7",
"wallet_id": "wal_01HV8X9Y2KPQRS3T4UV5WX6YZ7",
"lot_id": "lot_01HV8X9Y2KPQRS3T4UV5WX6YZ7",
"asset_code": "USD",
"amount": "10000",
"direction": "CREDIT",
"entry_type": "CREDIT",
"balance_after": "10000",
"metadata": {
"source": "deposit"
},
"created_at": "2024-01-15T10:30:00Z"
}
],
"pagination": {
"has_more": true,
"next_cursor": "cur_abc123"
}
}Balance Reconciliation
You can verify wallet balances by summing ledger entries:
Wallet Balance = SUM(CREDIT entries) - SUM(DEBIT entries)This provides an independent verification mechanism for balance accuracy.
Related Concepts
- Wallets - Balances derived from ledger entries
- Lots - Individual lot balances tracked in ledger
- Reservations - Reserve/release/commit entries
- Multi-Tenancy - Ledger isolation per tenant