Build an authenticated account monitor that keeps exact funding and trading balances separate, tracks reservations and open orders, and uses revisions to reject stale balance updates.
Read and format the balance snapshot
balances, err := client.Balances.List(ctx, nil, nil)
if err != nil { log.Fatal(err) }
for _, balance := range balances.Balances {
available, err := codecs.FormatLedgerU128(balance.Available, codecs.LedgerScale)
if err != nil { log.Fatal(err) }
reserved, err := codecs.FormatLedgerU128(balance.Reserved, codecs.LedgerScale)
if err != nil { log.Fatal(err) }
fmt.Println(
balance.AssetID,
"available", available,
"reserved", reserved,
"trading_revision", balance.TradingRevision,
"funding_revision", balance.FundingRevision,
)
}funding is deposit/withdraw custody state. trading, reserved, and available are execution
state. Their revisions are independent; compare TradingRevision only with trading-state updates
and FundingRevision only with funding-state updates.
Reconcile open orders
open, err := client.Orders.ListOpen(ctx, nil, nil, nil, nil, true, true)
if err != nil { log.Fatal(err) }
for _, order := range open.Orders {
fmt.Println(
order.OrderID,
order.ClientOrderID,
order.SymbolID,
order.Status,
order.OrigQty,
order.CumQty,
order.LeavesQty,
)
}Reserved balance and open-order leaves should move together eventually, but they are served by different read models and can lag briefly. Do not flag a mismatch until a bounded reconciliation window and a fresh read have both completed.
Subscribe for low-latency order changes
sub, err := client.Orders.Subscribe(ctx, accountID)
if err != nil { log.Fatal(err) }
defer sub.Close()
if order, ok := <-sub.Messages(); ok {
scale, found := client.Catalogs.BaseQuantityScaleForSymbolID(order.SymbolID)
if !found {
return fmt.Errorf("stream symbol %d quantity scale is unavailable", order.SymbolID)
}
cum, err := order.CumQty.WithScale(scale).Format()
if err != nil { return err }
leaves, err := order.LeavesQty.WithScale(scale).Format()
if err != nil { return err }
fmt.Println(order.OrderID, order.Status, cum, leaves)
}
if err := sub.Err(); err != nil { log.Print(err) }The private stream accelerates the UI; it does not replace snapshots. On reconnect or queue
overflow, discard local assumptions and reconcile balances plus open orders again. Stream
quantities can omit scale, so resolve it from the hydrated catalog by SymbolID and fail closed
if unavailable; never invent a stream scale.
Resolve fills before computing inventory
orderID := "order-id-from-create"
details, err := client.Orders.WaitForOrderTradesComplete(
ctx, nil, &orderID, nil, nil, 15*time.Second,
)
if err != nil { log.Fatal(err) }
if details.Order != nil {
fmt.Println(details.Order.CumQty, len(details.Trades))
}The order projection can show cumulative quantity before every related trade row is queryable. Use the completed trade projection for fee-source-aware received inventory and realized execution reporting.
Poll as a safety net
Poll slowly enough to respect rate limits, add jitter across replicas, and set one overall context deadline per cycle. A useful cycle is balances โ open orders โ recent history. Publish the new dashboard state atomically only after all required reads succeed; otherwise retain the previous state and mark it stale.
Account-state API map
| Method | Important inputs | Use |
|---|---|---|
Balances.List | account scope, subaccount | Funding/trading snapshot and revisions |
Balances.GetBalanceHistory | range, ledger, account codes | Auditable balance movement |
Orders.ListOpen | scope, pagination, attached-risk flags | Current reservation intent |
Orders.ListHistory | symbol/ID, pagination | Terminal and recent order states |
Orders.Get | order ID or client order ID | One order plus related fills |
Orders.Subscribe | account ID | Low-latency private lifecycle updates |
Orders.WaitForOrderTradesComplete | order identity, timeout | Complete fill projection |
Trades.List | account filters, pagination | User execution ledger |
Tested source
Example 02 in polyester-examples-go performs authenticated
balance and order reads. It compiles and passes tests against the exact v0.1.0a25 SDK commit.