Documentation Index
Fetch the complete documentation index at: https://docs.moralis.com/llms.txt
Use this file to discover all available pages before exploring further.
Question it answers
“What is wallet 0x…‘s current native-asset (ETH / MATIC / …) balance?”Mirrors Moralis
GET /{address}/balance and GET /wallets/balances. It is the native-asset analog of Token Balances by Wallet: each nativeTransfers event carries the absolute post-transfer native balance for both legs, so the latest observation per (chain_id, wallet_address) is the current balance — no replaying of deltas.
What you get
The recipe lands one row per balance observation — each native transfer is unpivoted into two observations (thefrom leg and the to leg), each carrying that wallet’s absolute native balance immediately after the transfer. There is no token_address and no token_id — the native asset is implied by the chain.
| Column | Description |
|---|---|
wallet_address | The wallet whose post-transfer balance this row records |
balance | Absolute native balance after the transfer (raw uint256, in wei) |
leg | from or to — which side of the transfer produced this observation |
block_number | Block the transfer landed in |
native_seq | 1-based position of the transfer within the block’s nativeTransfers array — the recency tiebreaker |
transaction_index | Informational only (not unique per native transfer) |
block_hash, event_ts | Block hash and block time |
vendor_event_id | Stable per-observation identity |
(block_number, native_seq) per wallet is the live balance.
Source
The transform reads one per-block array and unpivots it:nativeTransfers
Each transfer becomes two observations — (fromAddress, fromPostBalance) and (toAddress, toPostBalance). The zero address and empty post-balances are dropped, and toAddress (nullable on block-reward / fee-burn legs) is coalesced before those filters apply.
Destination
| Destination | Table | Read pattern |
|---|---|---|
| ClickHouse (first-class) | fact_native_balances | Prefix scan on (chain_id, wallet_address, block_number, native_seq); current balance via argMax over FINAL |
| Postgres | native_balances (materialized view over native_balance_observations) | Partial index (wallet_address) WHERE balance > 0 |
| MySQL | native_balances (trigger-maintained from native_balance_observations) | PK (wallet_address) |
argMax picks the live balance. Postgres collapses observations into a current-balance materialized view; MySQL keeps a trigger-maintained state table.
Full schema
Below is the complete read table this recipe produces — observations keyed by wallet. Keep the columns you need and drop the rest (see Schema & flexibility). The rawbalance is a uint256 in wei and is stored as text (it exceeds numeric precision); divide by 10^18 (the native decimals) in your app to read whole units.
ClickHouse — fact_native_balances
ClickHouse — fact_native_balances
sign column drives reorg collapsing — read with FINAL + argMax, never a bare WHERE sign = 1. A single-node setup can use CollapsingMergeTree(sign) without the replication path.Postgres — native_balances
Postgres — native_balances
DECIMAL(65,0) for balance and a trigger-maintained native_balances state table (PK wallet_address, plus a DELETE … WHERE balance = 0 cleanup). position is the block-level cursor used during backfill. Refresh the Postgres view on a schedule: REFRESH MATERIALIZED VIEW CONCURRENTLY native_balances;.Example reads
Current native balance for a wallet (ClickHouse —argMax picks the latest observation):
GET /wallets/balances):
Modes
Shipped defaults: ClickHousehybrid (backfill → realtime), Postgres / MySQL historical (one-shot backfill). For live/reorg-safe ingestion, use ClickHouse — see the overview.
The backfill cursor (
position) is block-level, so realtime/hybrid on Postgres / MySQL is constrained by their single-column UNIQUE requirement. Run realtime/hybrid on ClickHouse; the Postgres / MySQL configs target historical backfill.Multichain
The recipe is chain-parametrized via thechain setting — point it at any supported EVM chain or Solana. On Solana, the vendor_event_id already folds in (transactionIndex, fromAddress, toAddress, amount, 'native'), so observations stay row-unique even where Solana repeats indices within a transaction. The balance surface it produces is identical in shape.
Recency: why native_seq, not log_index
nativeTransfers carry no logIndex, and transactionIndex is not unique per transfer (a single transaction with several internal native movements reuses it). “Which post-balance is current” is therefore tiebroken by native_seq — the 1-based position of each transfer within the block’s nativeTransfers array. It is a stable block-global ordinal emitted in canonical order and computed once in the shared transform, so ClickHouse argMax, Postgres DISTINCT ON, and the MySQL trigger all converge on the same current balance per wallet.
Fidelity gaps
- No USD value. Moralis
GET /{address}/balancecan return a USD-valued balance; that needs the native-asset/USD price at the block, which is not carried onnativeTransfers. Join against a native-price source (e.g. the wrapped-native pair from a Token Prices sync) to add it. - Raw wei, no decimals scaling.
balanceis the rawuint256in wei; divide by10^18in your app to read whole native units.
Related
Token Balances by Wallet
The ERC-20 sibling — every token a wallet holds, with balance.
Portfolio Tracking
Native balances are the base-asset leg of a wallet’s portfolio.

