BagsLens, token discovery through the factory registry and events, pool ID derivation, and post-migration price reads. All of these are read-only — no wallet or gas required.
Prerequisites
Before starting, make sure you have:- Completed the Environment Setup (
publicClient, addresses, ABIs). - Read the Overview for the token lifecycle.
1. Read a Token’s State with BagsLens
BagsLens.getTokenState returns everything you need about a token in one eth_call. It’s the recommended entry point for any token view.
read-state.ts
TokenState struct:
Batch multiple tokens
For lists, usegetTokenStates to fetch many tokens in one call:
2. Discover Tokens via the Factory Registry
BagsFactory maintains an append-only registry of every launch. Because it’s append-only, the tail of the list is the newest launches.
list-tokens.ts
3. Read Immutable Token Info
Name, symbol, and metadata URI never change, so read them once and cache. Non-Bags ERC-20s revert onmetadataURI, so treat that as absent.
token-info.ts
4. Discover via TokenCreated Events
You can also index launches directly fromTokenCreated logs (useful for backfilling history or building a stream). Start no earlier than the protocol deploy block.
index-launches.ts
Indexer notes
- Trade events are self-contained.
TokensBoughtandTokensSoldembed the post-trade price, virtual reserves, and full fee breakdown (vault / creator / partner), so you can index curve trades without extra state reads per event. - Phase flip.
Migratedon the curve is the switch point: stop consuming curve events and start consumingPoolManagerSwaplogs (filtered by the token’spoolId) and the hook’sHookFeeTaken. - Pool-phase volume. The hook takes 2% of the WETH leg on every pool swap, so gross WETH volume per swap =
HookFeeTaken.amount x 50. - Fee claimers are not in events at launch. Call
feeShare.getClaimers()afterTokenCreated, and watchClaimersUpdated— the list can change. - Upgrade monitoring.
BagsFactoryandBagsVaultare UUPS proxies, and per-token curves/fee-shares point at two shared beacons. WatchUpgradedon the factory/vault proxies and on both beacons (BagsBondingCurveBeacon,BagsFeeShareBeacon— addresses in the Contracts Reference) to detect implementation changes.
5. Post-Migration Price from the Pool
After migration, read the live spot price from the pool’sslot0 via StateView. Never fall back to the frozen lens price for migrated tokens.
Add the StateView fragment to abi/periphery.ts:
slot0 and convert sqrtPriceX96 to ETH per whole token:
pool-price.ts
sqrtPriceX96 is a Q64.96 fixed-point number. The Number()-based conversion above is fine for display; for high-precision accounting, compute the square in BigInt before converting.6. Pool ID Derivation
Prefer thepoolId from getTokenState or the TokenCreated event. When you must derive it yourself, it’s keccak256(abi.encode(poolKey)) over the sorted key:
pool-id.ts
Next steps
- Trade against this state with the Trade Tokens guide.
- Read
claimableOfand the fee-share breakdown in the Claim Creator Fees guide. - See the Contracts Reference for every read function and event.
