Skip to main content

Overview

Ready-to-run example: All code snippets in this guide are available as runnable scripts in the wallet-balance-tracker repo.
This guide covers how to track wallet balances (native SOL + SPL tokens) across thousands of wallets — typical for market-making operations where you have many wallets trading different tokens on Solana. There are 3 approaches, each suited to different use cases: Recommendation for MM wallets: Use webhooks to get notified of every transfer in/out of your wallets, then call the portfolio API to refresh the full balance when needed.
Webhooks let you receive push notifications every time tokens move in or out of your wallets. You track transfer events filtered to your wallet addresses.
Full runnable script: src/create-webhooks.ts

Step 1: Create a Transfer Webhook

Filter limit: Max 1,000 leaf operations per webhook. With the or filter above, each wallet uses 2 operations (from + to), so you can track up to 500 wallets per webhook. For more wallets, create multiple webhooks — see Scaling to Thousands of Wallets.

Step 2: Receive Transfer Events on Your Server

Every time a transfer happens involving your wallets, Mobula POSTs a payload like this:
Key transfer fields:

Step 3: Build Your Webhook Server

Full runnable server with health check & balance query endpoints: src/server.ts

Step 4: Also Track Swap Events (Optional)

If your MM wallets are actively trading, you can also track swap events to see trades:
Swap payload fields:
Pro tip: The rawPostBalance0 and rawPostBalance1 fields in swap events give you the wallet’s balance of both tokens after the swap — no extra API call needed!

Approach 2: Portfolio API (Polling)

For on-demand balance checks or to initialize/reconcile your balance tracking, use the Portfolio API.
Full runnable script with batch polling & rate limiting: src/poll-balances.ts

Single Wallet Balance

Full Portfolio with USD Values

Batch Polling for Thousands of Wallets


Approach 3: WebSocket Balance Stream

For persistent, real-time balance feeds with the lowest latency.
Full runnable script with auto-reconnect: src/ws-stream.ts

Subscribe to Balance Updates

WebSocket subscriptions require specifying each wallet + token + blockchain triple individually. For thousands of wallets each holding many tokens, the webhook approach is more practical.

Scaling to Thousands of Wallets

All scaling scripts are in the wallet-balance-tracker repo:

Architecture

1. Partition Wallets Across Multiple Webhooks

Each webhook supports ~450 wallets (1,000 filter ops limit, 2 per wallet). The create-webhooks.ts script handles this automatically:

2. Add/Remove Wallets Dynamically

When you spin up new MM wallets or retire old ones, update the webhook filter with update-webhooks.ts:
Under the hood, this calls PATCH /api/1/webhook:

3. Initialize Balances on Startup

Before relying on webhooks for deltas, fetch current balances for all wallets using the batch poller:

4. Periodic Reconciliation

Webhooks can occasionally miss events (network issues, dead webhook recovery). Run periodic reconciliation by re-polling a random subset:

  1. Initialize: Poll all wallets on startup (bun run poll-balances)
  2. Track: Webhooks push transfer events in real-time (bun run server)
  3. Reconcile: Every 5 min, re-poll a random subset of wallets
  4. Store: Use Redis or a database instead of in-memory maps
  5. Monitor: Track webhook delivery failures via the list webhooks endpoint
See the complete working setup in the wallet-balance-tracker repo — clone it, set your env vars, and run.

Quick Reference

API Endpoints

Transfer Event Fields for Filtering

Filter Operators

Solana-Specific Notes

  • Native SOL address: So11111111111111111111111111111111111111112 (Wrapped SOL mint)
  • Chain ID: solana:solana
  • SOL decimals: 9 (1 SOL = 1,000,000,000 lamports)
  • USDC decimals: 6
  • Webhook event delivery is batched (up to 10 events per POST, 2-second debounce)
  • Failed deliveries are retried every 10 minutes for up to 7 days

Repo Scripts


GitHub Repo

Ready-to-run code example

Webhook Getting Started

Webhook basics

Filter Reference

Full filter documentation

Transfer Data Model

Transfer event fields

Mobula SDK

TypeScript SDK

Support

Telegram support