npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@suidex/clmm-sdk

v1.0.0

Published

SuiDex V3 CLMM SDK — quote, swap, and manage concentrated liquidity positions on Sui

Readme

Overview

The SuiDex CLMM SDK provides everything needed to interact with SuiDex V3 concentrated liquidity pools on Sui — swap, provide liquidity, flash loans, multi-pool routing, position management, and CLMM math.

Built on the Sui TypeScript SDK using the official client extension pattern, so it works with any Sui client (SuiGrpcClient, SuiGraphQLClient, or any ClientWithCoreApi).

Features

  • On-chain quotes — Exact swap output via compute_swap_result simulation (multi-tick accurate)
  • Multi-pool routing — Chain quotes across multiple pools via preSwap
  • Transaction builders — Swap, add/remove liquidity, collect fees/rewards, flash loans
  • Position management — Query positions by wallet, fetch position state
  • Pool discovery — List all pools with TVL, volume, and tick liquidity via indexer API
  • Flash loans — Borrow pool reserves for arbitrage with atomic repayment
  • Single-sided LP — Zap with on-chain optimal split calculation
  • APR estimation — Fee APR and reward APR helpers
  • CLMM math — Tick/price conversions, liquidity calculations (Q64 fixed-point)
  • Event types — Typed interfaces for all contract events (for indexers)
  • SIP-58 compatible — Uses coinWithBalance for automatic coin resolution
  • Transport agnostic — Works with gRPC, GraphQL, or any Sui client
  • Minimal dependencies — Only @mysten/sui as a peer dependency

Installation

npm install @suidex/clmm-sdk @mysten/sui

Quick Start

import { SuiGrpcClient } from '@mysten/sui/grpc';
import { suidexCLMM } from '@suidex/clmm-sdk';

const client = new SuiGrpcClient({
  network: 'mainnet',
  baseUrl: 'https://fullnode.mainnet.sui.io:443',
}).$extend(suidexCLMM());

API Reference

Pool & Position Queries

// Fetch pool state
const pool = await client.suidex.getPool('0xPoolId');

// Fetch position state
const position = await client.suidex.getPosition('0xPositionId');

// List all positions owned by a wallet
const positions = await client.suidex.listPositions('0xWalletAddress');

Quoting

// Single-pool quote
const quote = await client.suidex.view.getQuote({
  poolId: '0xPoolId',
  tokenXType: '0x2::sui::SUI',
  tokenYType: '0x...::token::TOKEN',
  isXtoY: true,
  amountIn: 1_000_000_000n,
});
// Returns: { amountOut, feeAmount, priceImpact, sqrtPriceAfter, feeRate }

// Multi-pool route quote (A → B → C)
const output = await client.suidex.view.preSwap({
  route: [
    { poolId: '0xPool1', tokenXType: 'A', tokenYType: 'B', isXtoY: true },
    { poolId: '0xPool2', tokenXType: 'B', tokenYType: 'C', isXtoY: true },
  ],
  amountIn: 1_000_000_000n,
});

Swap

const quote = await client.suidex.view.getQuote({ ... });
const minAmountOut = quote.amountOut - (quote.amountOut * 100n) / 10000n; // 1% slippage

const tx = client.suidex.tx.swap({
  poolId: '0xPoolId',
  tokenXType: '0x2::sui::SUI',
  tokenYType: '0x...::token::TOKEN',
  isXtoY: true,
  amountIn: 1_000_000_000n,
  minAmountOut,
  sender: '0xYourAddress',
});

const result = await wallet.signAndExecuteTransaction({ transaction: tx });

Add Liquidity

// New position
const tx = client.suidex.tx.addLiquidity({
  poolId: '0xPoolId',
  tokenXType: '0x2::sui::SUI',
  tokenYType: '0x...::token::TOKEN',
  tickLower: 4200,
  tickUpper: 5400,
  amountX: 1_000_000_000n,
  amountY: 500_000_000n,
  minAmountX: 990_000_000n,
  minAmountY: 495_000_000n,
  sender: '0xYourAddress',
  tickSpacing: 60, // validates tick alignment before building TX
});

// Add to existing position
const tx2 = client.suidex.tx.addLiquidity({
  ...params,
  existingPositionId: '0xPositionId',
});

Remove Liquidity

// Partial remove (keep position open)
const tx = client.suidex.tx.removeLiquidity({
  poolId, positionId, tokenXType, tokenYType,
  liquidityAmount: position.liquidity / 2n,
  minAmountX: 0n, minAmountY: 0n,
  sender: '0xYourAddress',
  closePosition: false,
});

// Full remove + close (auto-collects fees and rewards)
const tx2 = client.suidex.tx.removeLiquidity({
  poolId, positionId, tokenXType, tokenYType,
  liquidityAmount: position.liquidity,
  minAmountX: 0n, minAmountY: 0n,
  sender: '0xYourAddress',
  closePosition: true,
  rewardCoinTypes: ['0x...::victory_token::VICTORY_TOKEN'],
});

Collect Fees & Rewards

// Collect trading fees
const tx = client.suidex.tx.collectFees({
  poolId, positionId, tokenXType, tokenYType, sender,
});

// Collect single reward type
const tx2 = client.suidex.tx.collectReward({
  poolId, positionId, tokenXType, tokenYType,
  rewardCoinType: '0x...::victory_token::VICTORY_TOKEN',
  sender,
});

// Collect ALL reward types in one TX
const tx3 = client.suidex.tx.collectAllRewards({
  poolId, positionId, tokenXType, tokenYType,
  rewardCoinTypes: ['0x...::reward1::R1', '0x...::reward2::R2'],
  sender,
});

Flash Loans

// Borrow from pool, execute arb logic, repay with fees
const { tx, balanceX, balanceY, receipt } = client.suidex.tx.flashLoan({
  poolId, tokenXType, tokenYType,
  amountX: 1_000_000_000n,
  amountY: 0n,
  sender,
});

// ... add your arbitrage logic here (moveCall, etc.) ...

// Repay (must return borrowed amount + fee)
client.suidex.tx.repayFlashLoan({
  tx, poolId, tokenXType, tokenYType,
  receipt, balanceX, balanceY,
});

await wallet.signAndExecuteTransaction({ transaction: tx });

Single-Sided Liquidity (Zap)

// Add liquidity with only one token — SDK auto-calculates optimal split
const tx = client.suidex.tx.addLiquiditySingleSided({
  poolId, tokenXType, tokenYType,
  positionId: '0xExistingPosition',
  amountIn: 1_000_000_000n,
  isTokenX: true, // depositing token X
  sender,
});

Indexer API (Pool Discovery)

// List all pools with TVL and volume
const pools = await client.suidex.api.getAllPools();
// Returns: [{ poolId, tokenXType, tokenYType, feeRate, tickSpacing, liquidity, tvlUsd, volume24hUsd, ... }]

// Get tick liquidity depth for a pool
const ticks = await client.suidex.api.getPoolTicks('0xPoolId');
// Returns: [{ tickLower, tickUpper, netLiquidity }]

// Protocol stats
const stats = await client.suidex.api.getStats();
// Returns: { totalPools, totalTvlUsd, totalVolume24hUsd, totalSwaps24h, activePositions }

APR Estimation

import { SuiDexCLMMClient } from '@suidex/clmm-sdk';

// Fee APR
const feeAPR = SuiDexCLMMClient.estimateFeeAPR({
  volume24hUsd: 50000,
  feeRate: 3000, // 0.30%
  positionLiquidity: position.liquidity,
  poolLiquidity: pool.liquidity,
  positionValueUsd: 1000,
});

// Reward APR
const rewardAPR = SuiDexCLMMClient.estimateRewardAPR({
  rewardPerSecond: 1_000_000_000n,
  rewardDecimals: 9,
  rewardPriceUsd: 0.50,
  positionLiquidity: position.liquidity,
  poolLiquidity: pool.liquidity,
  positionValueUsd: 1000,
});

Math Utilities

import {
  tickToSqrtPrice, sqrtPriceToTick, sqrtPriceToPrice,
  priceToTick, tickToPrice,
  getAmountsForLiquidity, getLiquidityForAmounts,
} from '@suidex/clmm-sdk';

// Tick ↔ sqrt price (exact, integer)
const sqrtPrice = tickToSqrtPrice(5000);
const tick = sqrtPriceToTick(pool.sqrtPrice);

// Human-readable price
const price = sqrtPriceToPrice(pool.sqrtPrice, 9, 6); // decimalsX, decimalsY
const tick2 = priceToTick(1800, 9, 6, 60); // price, decimalsX, decimalsY, tickSpacing

// Position token amounts
const { amountX, amountY } = getAmountsForLiquidity(
  pool.sqrtPrice, tickToSqrtPrice(tickLower), tickToSqrtPrice(tickUpper), liquidity,
);

// Liquidity from token amounts
const liq = getLiquidityForAmounts(
  pool.sqrtPrice, tickToSqrtPrice(tickLower), tickToSqrtPrice(tickUpper), amountX, amountY,
);

Event Types (for Indexers)

import { EVENT_TYPES } from '@suidex/clmm-sdk';
import type { SwapEvent, AddLiquidityEvent } from '@suidex/clmm-sdk';

// Filter events by type
const swapEvents = txEvents.filter(e => e.type === EVENT_TYPES.Swap);
const parsed = swapEvents[0].parsedJson as SwapEvent;
console.log(parsed.amount_x, parsed.amount_y, parsed.fee_amount);

// Available: EVENT_TYPES.Swap, .AddLiquidity, .RemoveLiquidity,
//   .CollectFee, .CollectReward, .OpenPosition, .ClosePosition,
//   .FlashLoan, .PoolCreated, .RepayFlashSwap, .RepayFlashLoan

Important Notes

Amounts are in raw base units

All amounts use raw on-chain base units. Divide by 10^decimals for human values. Check decimals via suix_getCoinMetadata.

Slippage protection

All transaction builders accept minAmountOut / minAmountX / minAmountY for slippage. Always set these in production. Passing 0n disables slippage checks.

Fee rate encoding

Fee rates are integers where 1_000_000 = 100%: 500 = 0.05%, 3000 = 0.30%, 10000 = 1.00%.

Price representation

SuiDex V3 uses Q64 fixed-point sqrt prices (2^64 scale factor), different from Uniswap V3's Q96.

Tick spacing

Ticks must be aligned to the pool's tickSpacing. Pass tickSpacing to addLiquidity for client-side validation (avoids wasting gas on contract abort code 19).

Closing positions

Positions with unclaimed incentive rewards cannot be closed (contract abort code 30). Pass rewardCoinTypes when closing to auto-collect all rewards first.

Constants

import { MAINNET, MIN_TICK, MAX_TICK, Q64, FEE_DENOMINATOR } from '@suidex/clmm-sdk';

MAINNET.PACKAGE_ID          // V3 contract package
MAINNET.ORIGINAL_PACKAGE_ID // Original package (for struct types)
MAINNET.VERSION_ID          // Version object
MAINNET.CLOCK_ID            // Sui Clock (0x6)

MIN_TICK  // -443636
MAX_TICK  //  443636
Q64       // 2^64 (18446744073709551616n)
FEE_DENOMINATOR // 1_000_000n

Custom Deployments

const client = new SuiGrpcClient({ ... }).$extend(
  suidexCLMM({
    packageId: '0xYourPackage',
    versionId: '0xYourVersion',
    apiUrl: 'https://your-indexer.com',
  })
);

Testing

SUI_PRIVATE_KEY=suiprivkey1... npx tsx --test test/sdk.test.ts

Tests execute real mainnet transactions (swap, LP, fees, rewards, flash loans). Requires a funded wallet with ~0.1 SUI.

Contract

SuiDex V3 CLMM is an audited, MIT-licensed concentrated liquidity protocol on Sui.

  • Audit: SpyWolf Security Audit — 0 critical, 0 high, 1 medium (JIT protection, resolved)
  • Package: 0xb5f529c1dcda6580a61bf7ee9fbd524b50be62f11044d137c8202c8cbace9e56
  • Contract source: suidex-v3-clmm

License

MIT