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

@oneswap/sdk

v1.4.0

Published

Official TypeScript SDK for OneSwap on Canton: swaps, quotes, pools, and live market data

Readme

@oneswap/sdk

Official TypeScript SDK for OneSwap on Canton. Execute swaps (create a swap for a user, tell them the party to deposit to, and OneSwap returns the swapped output to the depositing party — no wallet integration required on your side), and read pools, live market data, and swap quotes. Works in Node.js and browsers.

Install

npm install @oneswap/sdk

Maintainers: see PUBLISHING.md for the release workflow.

Quick Start

import { OneSwap } from '@oneswap/sdk'

const client = new OneSwap({ apiKey: 'sk_live_...' })

// 1. Create a swap for one of your users.
const swap = await client.swaps.createSwap({
  userRef: 'user-1234',   // your stable id for this user
  inSymbol: 'CC',
  amountIn: 100,
  outSymbol: 'CBTC',
  poolId: 'rt-private-pool', // optional; pin a visible/private pool
  slippageBps: 50,        // optional; or pass an absolute minOut
})

// 2. Tell the user (or your system) where to deposit the input.
//    The output is returned to whoever makes this deposit (return-to-sender).
console.log(`Send ${swap.amountIn} ${swap.inSymbol} to ${swap.depositParty}`)
console.log(`Deposit before ${swap.deadline}`)

// 3. Wait for the swap to finish (polls until terminal).
const result = await client.swaps.waitForSwap(swap.id)

if (result.status === 'returned') {
  console.log(`Swapped! Received ${result.amountOut} ${result.outSymbol}`)
} else {
  console.log(`Swap did not complete: ${result.status} (${result.error ?? 'no detail'})`)
}

You can also poll manually with client.swaps.getSwap(swap.id).

Market data & quotes

// Which tokens and pools exist?
const tokens = await client.tokens.list()
const pools = await client.pools.list()

// A quote: how much CBTC for 100 CC? The SDK finds the pool that trades the
// pair and derives the direction for you.
const quote = await client.quotes.get({ from: 'CC', to: 'CBTC', amount: 100 })
console.log(`~${quote.amountOut} CBTC (price impact ${quote.priceImpactPct}%)`)
console.log(`via pool ${quote.poolId}`)

// Live market data for a pool: USD price and 24h USD volume.
const ticker = await client.pools.getTicker(quote.poolId)
console.log(`${ticker.pair}: $${ticker.price.usd}, 24h volume $${ticker.volume24h.usd ?? '—'}`)

// TVL comes with the pool list.
for (const p of pools) console.log(`${p.id}: TVL $${p.tvlUsd ?? '—'}`)

// One pool in full, with its settled-swap history.
const { pool, swaps } = await client.pools.get(quote.poolId)

Notes:

  • Every swap settles against exactly one pool. If no pool trades your pair directly, quotes.get throws NoDirectPoolError — there is no multi-hop routing, so run two swaps through an intermediate asset (usually CC) yourself. If several pools trade the pair it throws AmbiguousPoolPairError with the candidates; retry with poolId.
  • ticker.priceChange24h fields are null until the backend's hourly price snapshots are at least 24h old, and price.usd is null for pools that can't be USD-priced yet (e.g. unseeded pools).

Authentication

Every request is authenticated with your integrator API key, sent as the x-sdk-key HTTP header. Live keys look like sk_live_.... Create one from your OneSwap account — swap.oneswap.cc for mainnet, devnet.oneswap.cc for devnet. Never expose a live key in client-side code.

Configuration

new OneSwap({
  apiKey: 'sk_live_...',       // required
  environment: 'mainnet',      // 'mainnet' (default) | 'devnet'
  timeout: 30000,              // optional; per-request timeout in ms (default 30000)
})

The SDK resolves the backend URL itself from environment — mainnet (https://api.oneswap.cc/swapv2, the default) or devnet (https://devnet.api.oneswap.cc/swapv2). You never pass a raw URL. The instance exposes readonly baseUrl (the resolved URL) and environment.

Swap statuses

| Status | Terminal | Meaning | | ------------------ | :------: | ---------------------------------------------------------- | | awaiting_deposit | no | Swap created; send the input to depositParty. | | deposit_detected | no | The deposit landed and is being processed. | | swapping | no | The swap is executing against the pool. | | recovering | no | A step failed with the deposit in hand; it is being retried and the funds returned to the sender. | | needs_review | no | Automatic recovery was exhausted. Funds are safe; a human is resolving it. | | returned | yes | Success — the output was returned to the depositing party. | | refunded | yes | The input was returned to the depositing party. | | expired | yes | The deposit deadline passed before a deposit arrived. | | failed | yes | The swap could not be completed. | | cancelled | yes | Closed via cancel() before any deposit arrived. |

Helpers isTerminal(status) and TERMINAL_STATUSES are exported for convenience. waitForSwap resolves once a terminal status is reached (or its timeout elapses).

API

client.swaps.createSwap(args): Promise<Swap>
client.swaps.getSwap(id): Promise<Swap>
client.swaps.waitForSwap(id, { pollMs?, timeoutMs? }): Promise<Swap>
client.swaps.getOpenSwap(userRef): Promise<Swap | null>
client.swaps.cancel(id): Promise<Swap>

client.quotes.get({ from, to, amount, poolId?, walletId? }): Promise<QuoteResult>

client.pools.list(): Promise<Pool[]>
client.pools.get(poolId): Promise<PoolDetail>          // { pool, swaps }
client.pools.getTicker(poolId): Promise<PoolTicker>

client.tokens.list(): Promise<Token[]>

createSwap args: { userRef, inSymbol, amountIn, outSymbol, poolId?, minOut?, slippageBps? }.

The symbol pair must match a direct pool accessible to your SDK key. Available tokens cannot be combined arbitrarily: CC/HANDL and CC/USDCx pools do not imply a HANDL/USDCx route. An unsupported pair returns HTTP 400 (no pool for HANDL/USDCx, for example) before an intent or deposit wallet is created. A missing or inaccessible explicit poolId returns HTTP 404. Choose a supported pair; retrying the same unsupported request will not make it executable. Use poolId to target a pool returned by pools.list() or quotes.get(), including a private pool allowlisted for your API key.

waitForSwap polls getSwap every pollMs (default 3000) until the status is terminal or timeoutMs (default 900000) elapses, then resolves with the latest Swap — it does not throw on timeout, so always inspect result.status.

Recovering from OpenSwapExistsError

A userRef may hold only one open swap at a time. If you no longer have the id createSwap returned, getOpenSwap finds it — then either wait it out or release it:

try {
  swap = await client.swaps.createSwap({ userRef, inSymbol: 'CC', amountIn: 100, outSymbol: 'CBTC' })
} catch (err) {
  if (!(err instanceof OpenSwapExistsError)) throw err
  const open = await client.swaps.getOpenSwap(userRef)
  if (open?.status === 'awaiting_deposit') {
    await client.swaps.cancel(open.id) // no deposit arrived — release it and retry
  } else if (open) {
    await client.swaps.waitForSwap(open.id) // funds are in flight — let it finish
  }
}

cancel only closes a swap still in awaiting_deposit. Once a deposit has arrived the swap holds funds and must run to completion — cancelling then throws ConflictError (409). Cancelling an already-finished swap returns it unchanged.

client.escrow (the 1.0.0 name for client.swaps) still works as a deprecated alias of the same instance.

quotes.get returns the v2 Quote (amountOut, priceImpactPct, networkFeeIn, effFeeBps, lpFee, platformFee, …) plus the resolved poolId and direction xToY. The pool list backing symbol resolution is cached for 30s per client instance.

Errors

All errors extend OneSwapError, which carries an optional status (HTTP status code) and data (parsed response body):

OneSwapError, AuthError (401), ValidationError (400), NotFoundError (404), RateLimitError (429), ConflictError (409), OpenSwapExistsError (409 — the user already has an open swap), ServerError (5xx), NetworkError, TimeoutError, NoDirectPoolError (no pool trades the requested pair — the multi-hop case), AmbiguousPoolPairError (several pools trade the pair; carries candidates, retry with poolId).

import { OpenSwapExistsError, RateLimitError } from '@oneswap/sdk'

try {
  await client.swaps.createSwap({ userRef, inSymbol: 'CC', amountIn: 100, outSymbol: 'CBTC' })
} catch (err) {
  if (err instanceof OpenSwapExistsError) {
    // this user already has an open swap — resolve it before starting another
  } else if (err instanceof RateLimitError) {
    // back off and retry
  } else {
    throw err
  }
}

Availability

Swaps are live on devnet and mainnet — all you need is an SDK API key (sk_live_...) from your OneSwap account (swap.oneswap.cc for mainnet, devnet.oneswap.cc for devnet). Market data and quotes (pools, quotes, tokens) are read-only and available on both networks.

License

MIT