@suitracker/aggregator-sdk
v1.1.24
Published
Suitracker SDK
Maintainers
Readme
Suitracker Aggregator SDK
Suitracker Aggregator SDK lets you request quotes across Sui DEXs and build ready-to-submit swap transactions with the Suitracker router.
✨ Features
- Fetch pool state from CLMM, CPMM DEXs (cetus, turbos, bluefin, momentum, flowx_v3, flowx_v2, bluemove, ferra, kriya, magma) using efficient batch fetching.
- Simulate swaps offline to calculate expected output amounts, fees, and price changes without on-chain calls.
- Place and cancel on-chain limit orders through a simple helper API.
- Create token locks and vesting streams (linear, tranched, dynamic) with claim and cancel capabilities.
- Handle coin creation, merges, and cleanup with helpers such as
coinWithBalance,transferOrDestroyCoin, andgetOneCoinUsedToMerge. - Keep configuration reusable with
DEFAULT_CONFIGthat maps routers and DEX packages.
📦 Installation
# npm
npm install @suitracker/aggregator-sdk
# yarn
yarn add @suitracker/aggregator-sdk
# pnpm
pnpm add @suitracker/aggregator-sdk
# bun
bun add @suitracker/aggregator-sdk⚙️ Requirements
- Node.js 18+ (ESM-ready runtime;
node-fetch@3is bundled for older environments). - Peer dependency:
@mysten/sui@^1.33.0. - Any npm-compatible package manager (
npm,yarn,pnpm,bun).
🚀 Quick Start
import { AggregatorClient } from "@suitracker/aggregator-sdk"
import { Transaction } from "@mysten/sui/transactions"
import { SuiClient, getFullnodeUrl } from "@mysten/sui/client"
import BN from "bn.js"
const client = new AggregatorClient({
apiKey: process.env.SUITRACKER_API_KEY, // optional API key for higher rate limits
client: new SuiClient({ url: getFullnodeUrl("mainnet") }), // injected Sui client (defaults to mainnet)
})
const {formattedRoutersData: router, baseRoutersData} = await client.computeRouters({
from: "0x2::sui::SUI", // swap input coin type
target: "0x...::ika::IKA", // swap output coin type
amount: new BN("100000000000"), // amount to swap (BN)
})
const txb = new Transaction()
await client.buildTransaction({
router, // router response from computeRouters
slippage: 0.49, // acceptable slippage (e.g., 49%)
txb, // Transaction block being built
currentAccount: "0xYourAddress", // sender account for move calls
})
await suiClient.devInspectTransactionBlock({
transactionBlock: txb,
sender: '0xYourAddress'
})🧩 Core API
computeRouters(params: FindRouterParams)— fetches routes with BN amounts, depth, slippage, and provider options.buildTransaction(params: BuildTxSwapParams)— buys the input coin, routes through each DEX adapter, and merges the output coin.placeLimitOrder(txb: Transaction, params: IPlaceOrder)— helper to call the on-chain limit order book and place a limit order.cancelOrder(txb: Transaction, params: ICancelOrder)— helper to cancel an existing limit order by owner.fetchPoolData(pools: PoolInfo[], sender?: string)— fetches pool state and tick data from multiple CLMM pools using batch fetching. Groups pools by DEX type (cetus, turbos, bluefin, momentum, flowx_v3) and fetches efficiently in parallel. Returns array of{ poolInfo, poolData, ticks }.simulateSwap(params: SimulateSwapParams)— simulates a CLMM swap offline to calculate swap results (amountOut, fees, price changes) without on-chain calls. RequirespoolDataandswapTicksfromfetchPoolData. Supports cetus, turbos, bluefin, momentum.lock.createLinearLock(txb, params)— creates a linear vesting stream with optional cliff period.lock.createTrunchedLock(txb, params)— creates a tranched lock with multiple unlock timestamps.lock.createDynamicLock(txb, params)— creates a dynamic lock with exponential release segments.lock.createObjectLock(txb, params)— creates a lock for arbitrary Sui objects (NFTs, etc.).lock.claim(txb, params)— claims available tokens from a lock stream.lock.cancel(txb, params)— cancels a lock stream (requires cancel capability).
📊 Pool Data & Swap Simulation
Fetch Pool Data
Fetch pool state and tick data for CLMM pools:
const pools = [
{
poolAddress: "0x...", // pool object ID
dex: "cetus", // DEX type: cetus, turbos, bluefin, momentum, flowx_v3
fee: 3000, // fee rate in ppm (e.g., 3000 = 0.3%)
coinA: "0x2::sui::SUI", // coin type A
coinB: "0x...::usdc::USDC", // coin type B
poolType
},
]
const results = await client.fetchPoolData(pools, "0xYourAddress")
// Returns: Array<{ poolInfo, poolData, ticks }>
// poolData: { currentSqrtPrice, currentTickIndex, feeRate, liquidity, ... }
// ticks: Array<{ index, sqrtPrice, liquidityNet }>Simulate Swap
Simulate a CLMM swap offline to calculate expected output:
const swapResult = await client.simulateSwap({
amountIn: 1000000000n, // input amount (bigint)
a2b: true, // direction: true for A->B, false for B->A
dexType: "cetus", // DEX type: cetus, turbos, bluefin, momentum
poolData: results[0].poolData, // pool data from fetchPoolData
swapTicks: results[0].ticks, // tick data from fetchPoolData
byAmountIn: true, // optional: true for input amount (default), false for output
})
// Returns: { amountIn, amountOut, feeAmount, nextSqrtPrice, nextLiquidity, crossTickNum, protocolFee? }🔒 Token Locks & Streams
Create vesting streams and token locks with different unlock schedules:
Linear Lock
Create a linear vesting stream with optional cliff period:
const txb = new Transaction()
const coinInput = coinWithBalance({
type: "0x...::token::TOKEN",
balance: 1e9,
})(txb)
const startTime = Date.now() + 30 * 60 * 1000 // 30 minutes from now
const endTime = Date.now() + 90 * 60 * 1000 // 90 minutes from now
const cliffTime = startTime + 15 * 60 * 1000 // optional: 15 min cliff
client.lock.createLinearLock(txb, {
coinType: "0x...::token::TOKEN", // coin type to lock
coin: coinInput, // coin object to lock
recipient: "0xRecipientAddress", // recipient address
startTime, // unlock start timestamp (ms)
endTime, // unlock end timestamp (ms)
cliffTime, // optional: cliff timestamp (ms)
cancelable: true, // whether lock can be cancelled
})Tranched Lock
Create a lock with multiple discrete unlock amounts at different timestamps:
const trunches = [
{ timestamp: Date.now() + 30 * 60 * 1000, amount: "200000000" }, // 200M at T+30min
{ timestamp: Date.now() + 60 * 60 * 1000, amount: "200000000" }, // 200M at T+60min
{ timestamp: Date.now() + 90 * 60 * 1000, amount: "200000000" }, // 200M at T+90min
]
client.lock.createTrunchedLock(txb, {
coinType: "0x...::token::TOKEN",
coin: coinInput,
recipient: "0xRecipientAddress",
trunches, // array of { timestamp, amount }
cancelable: true,
})Dynamic Lock
Create a dynamic lock with exponential release segments:
const WAD = BigInt(10 ** 18)
const segments = [
{
timestamp: Date.now() + 30 * 60 * 1000,
amount: "200000000", // amount to unlock
exponent: WAD.toString(), // exponent for release curve
},
{
timestamp: Date.now() + 60 * 60 * 1000,
amount: "200000000",
exponent: (2n * WAD).toString(), // higher exponent = faster release
},
]
client.lock.createDynamicLock(txb, {
coinType: "0x...::token::TOKEN",
coin: coinInput,
recipient: "0xRecipientAddress",
startTime: Date.now(), // stream start time
segments, // array of { timestamp, amount, exponent }
cancelable: true,
})Object Lock
Lock arbitrary Sui objects (NFTs, etc.) until a specific unlock time:
client.lock.createObjectLock(txb, {
objectType: "0x...::nft::NFT", // object type to lock
feeCoin: feeCoinInput, // fee payment coin
objectId: "0xObjectId", // object ID to lock
recipient: "0xRecipientAddress", // recipient address
unlockTime: Date.now() + 7 * 24 * 60 * 60 * 1000, // unlock timestamp (ms)
})Claim & Cancel
Claim available tokens or cancel a lock stream:
// Claim available tokens from a lock
client.lock.claim(txb, {
type: "dynamic", // lock type: 'linear' | 'tranched' | 'dynamic' | 'lock_object'
coinType: "0x...::token::TOKEN", // coin/object type
lock: txb.object("0xLockObjectId"), // lock object ID
})
// Cancel a lock (requires cancel capability)
client.lock.cancel(txb, {
type: "linear", // lock type: 'linear' | 'tranched' | 'dynamic'
coinType: "0x...::token::TOKEN",
lock: txb.object("0xLockObjectId"),
cap: txb.object("0xCancelCapId"), // cancellation capability object
})🧾 Limit Orders
Place and cancel on-chain limit orders via AggregatorClient:
import { AggregatorClient } from "@suitracker/aggregator-sdk"
import { Transaction } from "@mysten/sui/transactions"
import { coinWithBalance } from "@mysten/sui/transactions"
const client = new AggregatorClient({ /* config with trade.package/globalConfig if you want to override defaults */ })
const txb = new Transaction()
// 1. Build pay coin
const payAmount = BigInt(1e8) // 1e8 units (e.g. 0.1 SUI if 9 decimals)
const payCoinType = "0x2::sui::SUI"
const targetCoinType = "0x...::usdc::USDC"
const payCoin = coinWithBalance({
balance: payAmount,
useGasCoin: true,
type: payCoinType,
})(txb)
// 2. Calculate rate off-chain (price = payAmount / targetAmount, scaled by 1e18)
const targetAmount = BigInt(148n * 10n ** 4n)
const rate = (payAmount * 10n ** 18n) / targetAmount
// 3. Place limit order
client.orderBook.placeLimitOrder(txb, {
payCoin,
payCoinType,
targetCoinType,
rate: rate.toString(), // price in 1e18 precision
expAt: Date.now() + 24 * 60 * 60 * 1000, // expiration timestamp (ms)
})
// 4. Cancel limit order later
client.orderBook.cancelOrder(txb, {
payCoinType,
targetCoinType,
orderId: "0xLimitOrderObjectId",
})🧭 Supported Liquidity Sources
Adapters under src/libs/dexs/ cover a growing list: aftermath, bluefin, bluemove, cetus, flowx_v2, flowx_v3, fullsail, magma, momentum, steamm_cpmm, turbos, and more. newDexRouter picks the correct adapter per provider name.
🧪 Examples & Testing
🏗️ Build & Publish
npm run clean— removedist/.npm run build— runtsup src/index.ts --format esm,cjs --dts.
Published packages only include dist/.
📄 License
MIT © Suitracker
