tickLower–tickUpper) and earn fees only while the price is inside it. Each pool is identified by a token pair plus a fee tier (configIndex). Prices are stored as sqrtPriceX96 = sqrt(token1/token0) × 2^96.
Guide: swap on CLMM
Guide: open & manage a position
Fee tiers (pool configs)
A fee tier is aPoolConfig contract registered in the factory, indexed from 0n. Every pool references exactly one.
Pool lookups
getPoolState(poolId)
object
PoolNotFoundError if the pool doesn’t exist.
Other pool reads
Swaps
simulateSwap(params)
simulateSwap view method on the node (no transaction) and returns the liquidity curve the swap walks through. Feed the result to PoolUtils.offlineSwap to compute the output amount locally.
bigint
required
string
required
The pool’s tokens (any order, used to locate the pool).
boolean
required
true sells sorted token0 for token1 (price goes down).bigint
required
Positive = exact-in, negative = exact-out.
string
Multi-hop path from
buildSwapPath (optional).string[]
Addresses of extra pools touched by a multi-hop path.
object
swap(params)
SwapWithoutAccount script (or SwapWithoutAccountWithFee when an integrator fee is set). The signer is both payer and recipient.
string
required
The input token (not necessarily the pool’s sorted token0).
string
required
The output token.
bigint
required
Amount specified: positive = exact-in, negative = exact-out (the negated desired output).
bigint
required
How much input token to attach. Exact-in: same as
amount. Exact-out: your maximum input (simulate, then add slippage).bigint
required
Basis points, converted to a
sqrtPriceLimitX96.bigint[]
required
Fee tiers to route through. Only
routePlan[0] is used today.bigint / string
Optional integrator fee, in the input token.
swapTo(params)
targetSqrtPriceX96, spending at most amountInMax of tokenIn. Fails on-chain (error code 106, InvalidSqrtPriceLimit) if the target is on the wrong side of the current price.
buildSwapPath(tokenId, configIndex)
Encodes one extra hop for simulateSwap({ data }): tokenId + configIndex as 4 hex characters.
Liquidity positions
A position is identified by pool + owner + tickLower + tickUpper. The position contract ID doubles as a position token ID. The owner holds one unit of it, and it is attached when modifying the position.getPositionId(poolId, owner, tickLower, tickUpper)
Derives the position ID offline. Pass owner in normalized form for groupless addresses (see Groups and addresses). PoolUtils.getPositionId(poolAddress, owner, ...) normalizes for you.
createPool(...)
tick and mints the first position in [tickLower, tickUpper]. Tokens, their amounts, and the ticks are sorted internally. Attaches 6 × MINIMAL_CONTRACT_DEPOSIT ALPH for the new contracts.
addLiquidity(params)
string
required
Pool tokens. Pass them sorted (
sortTokens) and match amount0 / amount1 to that order.bigint
required
bigint
required
Multiples of the tier’s
tickSpacing. Use TickUtils.getAlignedTick.bigint
required
Desired amounts. The contract deposits the maximal balanced amounts up to these.
bigint
required
Basis points on price. Minimum amounts are derived from the price bounds.
string
Position owner. Defaults to the signer.
boolean
Set
true when adding to a position you already own (attaches the position token). The signer must hold its position NFT, which the SDK attaches automatically.dustAmount) is read on-chain via PositionManager.getSqrtPricesX96.
Two-step variant: getAddLiquidityParams(p) returns [positionId, positionManager, params] without sending, and addLiquidityFromParams(positionId, positionManager, params) executes them. Use this to show a confirmation screen with the exact minimum amounts.
removeLiquidity(params)
required
Identify the pool.
required
Identify the position.
bigint
required
Liquidity units to remove (read the position’s current
liquidity, then take a fraction).'token0' | 'token1'
required
Which side
baseAmount refers to.bigint
required
Minimum amount of the
base token to receive.bigint
required
Minimum amount of the other token to receive. Despite the name, it’s passed on-chain as a minimum.
0n for both minimums to disable the check.
collectTokens(params)
recipient. It does not remove liquidity; use removeLiquidity for that.
required
Identify the position.
string
required
bigint
required
Caps on what to collect. Use
U128_MAX-sized values (for example UNLIMITED_AMOUNT) to collect everything.positionInfo(params)
positionInfo view and returns its result unchanged. fees holds three entries: token0, token1, and the pool’s reward token. The SDK passes the accumulator arguments (acc, iacc0, iacc1, t0, acct0) straight to the contract. See the Pool contract source for what they mean.
To read a position’s raw liquidity, fetch the position contract:
Farming rewards
A pool can run up to three reward programs (MAX_REWARDS = 3), paying in token0, token1, or the pool’s extra reward token (token2). Programs are set up and funded by the Powfi team.
getPoolRewardState(poolId)returns the reward token and each program’samount,openTime, andendTime(millisecond timestamps).- Rewards accrued by a position appear in
positionInfo(...).fees: token0 rewards infees[0], token1 rewards infees[1], and rewards in any other token infees[2]. They are paid out throughcollectTokens.
Referral (DEX) accounts
Powfi tracks referrals through per-userDexAccount contracts under a DexAccountRoot.
Configuration
getClmmConfig() and override it with setConfig(). getConfig() re-reads the bundled deployment.