Skip to main content
A fill measures how a swap changes the token0 and token1 backing your position. A positive change means you acquired that token; a negative change means you released it. Fees, deposits, and withdrawals are separate from fills.

Track live fills

Use the authenticated clients from Setup with the latest SDKs. Set POSITION_TOKEN_ID to your position’s NFT token ID. The examples read pool swaps and print how much token0 and token1 your position gained or released. They do not submit transactions.
Add these blocks to the same script, in order, using client and publicClient from Setup.Read the positionThe tracker uses the position’s range and liquidity to calculate fills. checkPosition stops it if those values change, so a deposit or withdrawal is not counted as a swap.
Calculate the tokens backing the positioninventoryAt returns the position’s token0 and token1 amounts at a given square-root price. We will call it before and after each swap to find the difference.
Fetch trades not yet seenThe API returns newest trades first. readNewTrades fetches pages until it reaches a known trade, then finishes reading every trade with that timestamp so none are skipped across pages. On startup, it reads the latest swap’s full timestamp group to find which swap actually came last.
Put swaps in execution orderTimestamps can tie. swapOrder checks that the transaction was accepted and locates the swap by block, transaction, program call, and hop. orderedSwaps drops non-swap activity and sorts the remaining trades oldest first; it stops if a price or an unambiguous program call is missing.
Compute what each swap changedThe previous swap’s ending price is the next swap’s starting price. printFills compares inventory at those two prices and prints signed changes in token base units: positive means acquired, negative means released. The first read only establishes the starting price; if the pool has no history, its first swap establishes it instead.
Run the trackerwatchPositionFills connects the functions and checks for new trades every five seconds. It remembers processed IDs to avoid printing a fill twice. Stop it before changing liquidity or rebalancing, then restart afterward with the current position ID.
For historical replay and WebSocket updates, see the complete runnable tracker.

Calculate a fill

Compare the position’s inventory immediately before and after a swap, using the range and liquidity active during that swap. The examples below use liquidity 1,000,000, range ticks [-100, 100), and a price move from tick 0 to tick 10. They run locally without a key. Prices use Q128.128 integers; amounts use token base units. Install the latest Typescript SDK or Python SDK using Setup.
Each example reports −500 token0 and +500 token1, in base units: the position released token0 and acquired token1. These are rounded inventory changes, not separate wallet payments or profit. For live data:
  • Use accepted pool swaps in chain order, with each swap’s actual before/after square-root prices. Rounded ticks or snapshots spanning several swaps cannot recover individual fills.
  • Use the position state effective for each swap. Start after mint, update liquidity after increases or decreases, and track a rebalance’s replacement under its new position ID.
  • Keep values as integers or decimal strings. Track fee income separately.
See Rebalancing positions for changing the range.