npm package: @suitracker/aggregator-sdk
Description: Suitracker SDK
Author: Suitracker
Latest version: 1.1.24

# 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`, and `getOneCoinUsedToMerge`.
- Keep configuration reusable with `DEFAULT_CONFIG` that maps routers and DEX packages.

## 📦 Installation

```bash
# 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@3` is bundled for older environments).
- Peer dependency: `@mysten/sui@^1.33.0`.
- Any npm-compatible package manager (`npm`, `yarn`, `pnpm`, `bun`).

## 🚀 Quick Start

```ts
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. Requires `poolData` and `swapTicks` from `fetchPoolData`. 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:

```ts
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:

```ts
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:

```ts
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:

```ts
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:

```ts
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:

```ts
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:

```ts
// 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`:

```ts
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` — remove `dist/`.
- `npm run build` — run `tsup src/index.ts --format esm,cjs --dts`.

Published packages only include `dist/`.

## 📄 License

MIT © Suitracker