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

@cetusprotocol/dca-sdk

v1.2.5

Published

SDK for cetus dca

Readme

@cetusprotocol/dca-sdk

DCA (Dollar-Cost Averaging) is a low-risk investment strategy that spreads purchases over time. The Cetus DCA SDK helps developers integrate DCA order creation, withdrawal, cancellation, and on-chain queries into Sui applications.

Table of Contents

Installation

npm: https://www.npmjs.com/package/@cetusprotocol/dca-sdk

npm install @cetusprotocol/dca-sdk

Initialization

import { CetusDcaSDK } from '@cetusprotocol/dca-sdk'

// Mainnet with default RPC
const sdk = CetusDcaSDK.createSDK({ env: 'mainnet' })

// Testnet
const sdkTestnet = CetusDcaSDK.createSDK({ env: 'testnet' })

// Custom RPC or Sui client
const sdkCustom = CetusDcaSDK.createSDK({ env: 'mainnet', full_rpc_url: 'YOUR_FULL_NODE_URL' })
// or
const sdkGrpc = CetusDcaSDK.createSDK({ env: 'mainnet', sui_client })

Set the transaction sender before building payloads that transfer coins to the user:

const wallet = 'YOUR_WALLET_ADDRESS'
sdk.setSenderAddress(wallet)

Core Workflow

Opening a DCA order requires two steps:

  1. Fetch a signed quote from the Cetus DCA Quote API. The response provides fee_rate, per_cycle_in_amount_limit, timestamp, and signature, which the on-chain contract validates before accepting the order.
  2. Build and submit the open-order transaction via sdk.Dca.dcaOpenOrderPayload().
User wallet ──► Quote API ──► signed quote ──► dcaOpenOrderPayload ──► Sui transaction

Quote API (Signature)

Before calling dcaOpenOrderPayload, request a quote from the Cetus backend. The server signs order constraints (input coin, cycle frequency, cycle count, and per-cycle input cap). The contract rejects orders with invalid or expired signatures.

Endpoint

GET https://api-sui.cetus.zone/dca/quote

Query parameters

| Parameter | Type | Required | Description | | --- | --- | --- | --- | | in_coin | string | Yes | Full Move type of the input (pay) coin, e.g. 0x2::sui::SUI or normalized long-form address | | freq | number | Yes | Cycle interval in seconds (must meet on-chain min_cycle_frequency; see Global Config) | | count | number | Yes | Total number of execution cycles (must meet on-chain min_cycle_count) | | sender | string | Yes | Sui address of the order creator (same as sdk.setSenderAddress) |

Example request

https://api-sui.cetus.zone/dca/quote?in_coin=0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC&freq=3600&count=2&sender=0xc5cea39da987d8fe16bf0c6db51bfbf4897aef0edf9588e035ae175ac416fdd1

Example response

{
  "code": 200,
  "msg": "Success",
  "data": {
    "signer": "0x3124f1006b3a48b41648d6dd2beddc26d96beef0d5aa198c2589e3f44e2bcea4",
    "coin_type": "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC",
    "fee_rate": 0,
    "amount_in_limit_per_cycle": 3000689,
    "timestamp": 1780399709,
    "signature": "008385eba204435555c4d730bd1723e8ee9d25e8ea9d3dc3727c24263bd2814b544a25ac9193d63991aa0244e89f685e43577787f682cd3beb493e48eaf7ec570997b4eb4448da38141944bd7c2c42cdf63e94b65fac24da132cb732c9bf6d4f30"
  }
}

Response field mapping

| Quote API field (data) | dcaOpenOrderPayload param | Description | | --- | --- | --- | | fee_rate | fee_rate | Protocol fee rate for the order | | amount_in_limit_per_cycle | per_cycle_in_amount_limit | Maximum input amount allowed per cycle (base units) | | timestamp | timestamp | Quote expiry timestamp (Unix seconds); must be used before it expires | | signature | signature | Backend signature authorizing the quote parameters |

Fetch quote in TypeScript

async function fetchDcaQuote(params: {
  in_coin_type: string
  cycle_frequency: number
  cycle_count: number
  sender: string
}) {
  const url = new URL('https://api-sui.cetus.zone/dca/quote')
  url.searchParams.set('in_coin', params.in_coin_type)
  url.searchParams.set('freq', String(params.cycle_frequency))
  url.searchParams.set('count', String(params.cycle_count))
  url.searchParams.set('sender', params.sender)

  const res = await fetch(url.toString())
  const body = await res.json()
  if (body.code !== 200) {
    throw new Error(body.msg ?? 'Failed to fetch DCA quote')
  }
  return body.data
}

Note: Quotes are time-bound. Fetch a fresh quote immediately before building the transaction. Reusing an expired timestamp or signature will cause the on-chain call to fail.

Open DCA Order

Parameter overview

| Parameter | Type | Description | | --- | --- | --- | | in_coin_type | string | Input coin Move type (coin deposited into the DCA order) | | out_coin_type | string | Output coin Move type (coin received each cycle via swap) | | in_coin_amount | string | Total input amount to deposit, in base units (integer string) | | cycle_frequency | number | Seconds between each swap execution | | cycle_count | number | Number of cycles; in_coin_amount is split evenly across cycles | | per_cycle_min_out_amount | string | Minimum acceptable output per cycle (base units); swap reverts if output is below this | | per_cycle_max_out_amount | string | Maximum acceptable output per cycle (base units); used as slippage upper bound | | per_cycle_in_amount_limit | string | From quote API amount_in_limit_per_cycle; caps input spent per cycle | | fee_rate | number | From quote API | | timestamp | number | From quote API | | signature | string | From quote API |

Slippage bounds (per_cycle_min/max_out_amount)

These define the acceptable swap output range per cycle. A common approach:

  1. Compute human-readable input per cycle: in_coin_amount / 10^inDecimals / cycle_count
  2. Derive expected output using price bounds:
    • per_cycle_max_out_amount ≈ cycleInput / minPrice × 10^outDecimals (best case)
    • per_cycle_min_out_amount ≈ cycleInput / maxPrice × 10^outDecimals (worst case)

Full example

import { d } from '@cetusprotocol/common-sdk'
import Decimal from 'decimal.js'

const wallet = 'YOUR_WALLET_ADDRESS'
sdk.setSenderAddress(wallet)

const in_coin_type = '0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI'
const out_coin_type = '0x26b3bc67befc214058ca78ea9a2690298d731a2d4309485ec3d40198063c4abc::usdc::USDC'
const cycle_count = 4
const cycle_frequency = 3600 // 1 hour
const in_coin_amount = '40000000000' // 40 SUI (9 decimals)

// Step 1: fetch signed quote
const quote = await fetchDcaQuote({
  in_coin_type,
  cycle_frequency,
  cycle_count,
  sender: wallet,
})

// Step 2: compute slippage bounds (example: SUI → USDC)
const inDecimals = 9
const outDecimals = 6
const cycleInputHuman = new Decimal(in_coin_amount).div(10 ** inDecimals).div(cycle_count)
const minPrice = 0.83854  // conservative min output price
const maxPrice = 2.172898 // conservative max input price
const per_cycle_max_out_amount = d(cycleInputHuman).div(d(minPrice)).mul(10 ** outDecimals).toFixed(0)
const per_cycle_min_out_amount = d(cycleInputHuman).div(d(maxPrice)).mul(10 ** outDecimals).toFixed(0)

// Step 3: build and submit transaction
const payload = sdk.Dca.dcaOpenOrderPayload({
  in_coin_type,
  out_coin_type,
  in_coin_amount,
  cycle_frequency,
  cycle_count,
  per_cycle_min_out_amount,
  per_cycle_max_out_amount,
  per_cycle_in_amount_limit: String(quote.amount_in_limit_per_cycle),
  fee_rate: quote.fee_rate,
  timestamp: quote.timestamp,
  signature: quote.signature,
})

const send_key_pair = 'THE_KEY_PAIR_GENERATED_BY_YOUR_PRIVATE_KEY'
const result = await sdk.FullClient.sendTransaction(send_key_pair, payload)

Query Orders

List all DCA orders owned by a wallet address:

const wallet = 'YOUR_WALLET_ADDRESS'
const { data: orders, has_next_page } = await sdk.Dca.getDcaOrders(wallet)

| Parameter | Type | Description | | --- | --- | --- | | wallet_address | string | Sui address of the order owner |

Returns a paginated DataPage<DcaOrder> with fields such as id, in_coin_type, out_coin_type, in_balance, out_balance, cycle_frequency, next_cycle_at, and status.

Withdraw Output

Withdraw accumulated output coin from an active order without closing it:

const payload = await sdk.Dca.withdrawPayload({
  order_id: '0xa60c763185a84b87380a0a1e7e677...',
  in_coin_type: '0x2::sui::SUI',
  out_coin_type: '0x26b3bc67...::usdc::USDC',
})

const result = await sdk.FullClient.sendTransaction(send_key_pair, payload)

| Parameter | Type | Description | | --- | --- | --- | | order_id | string | On-chain DCA order object ID | | in_coin_type | string | Input coin type of the order | | out_coin_type | string | Output coin type of the order |

Batch withdraw:

const payload = await sdk.Dca.withdrawAll([
  { order_id, in_coin_type, out_coin_type },
  // ...
])

Close Order

Cancel one or more DCA orders and return remaining input/output balances:

const payload = sdk.Dca.dcaCloseOrderPayload([
  {
    order_id: '0xfc519e9cccf90f4dfdf3008e529...',
    in_coin_type: '0x2::sui::SUI',
    out_coin_type: '0x26b3bc67...::usdc::USDC',
  },
])

const result = await sdk.FullClient.sendTransaction(send_key_pair, payload)

| Parameter | Type | Description | | --- | --- | --- | | order_id | string | Order object ID to cancel | | in_coin_type | string | Input coin type | | out_coin_type | string | Output coin type |

Order Transaction History

Query MakeDealEvent history (per-cycle swap executions) for a given order:

const history = await sdk.Dca.getDcaOrdersMakeDeal('0x45b567654b09d291f3c99566922b7...')

| Parameter | Type | Description | | --- | --- | --- | | order_id | string | DCA order object ID |

Token Whitelist

When whitelist mode is enabled on-chain, only listed coin types can be used as input and/or output. Query allowed coins with getDcaCoinWhiteList(whitelist_mode):

| whitelist_mode | Behavior | | --- | --- | | 0 | Whitelist disabled; returns empty lists | | 1 | Return input-coin whitelist only | | 2 | Return output-coin whitelist only | | 3 | Return both input and output whitelists |

const { in_coin_list, out_coin_list } = await sdk.Dca.getDcaCoinWhiteList(3)

Global Config

Read on-chain limits before creating an order:

const config = await sdk.Dca.getDcaGlobalConfig()
// { min_cycle_count, min_cycle_frequency, whitelist_mode }

Ensure cycle_count >= min_cycle_count and cycle_frequency >= min_cycle_frequency.

API Reference

| Method | Description | | --- | --- | | dcaOpenOrderPayload(params) | Build transaction to open a DCA order | | dcaCloseOrderPayload(params[]) | Build transaction to cancel one or more orders | | withdrawPayload(params) | Build transaction to withdraw output coin | | withdrawAll(params[]) | Build batch withdraw transaction | | getDcaOrders(wallet_address) | List orders for a wallet | | getDcaOrdersMakeDeal(order_id) | Query per-cycle execution events | | getDcaCoinWhiteList(whitelist_mode) | Query token whitelist | | getDcaGlobalConfig() | Read global DCA configuration | | getDcaConfigs() | Read deployed package config object IDs |

More About Cetus

License

MIT