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

@sugar-rush/sdk

v0.1.0

Published

TypeScript SDK for the Sugar Rush exchange: streaming market data and order submission over one WebSocket, with a CCXT-familiar surface.

Readme

@sugar-rush/sdk

TypeScript client for the Sugar Rush exchange.

One WebSocket carries everything: streaming market data and your account (materialized locally so you can read current state synchronously) and order submission. The primary surface is events + state + a batch subscribe; a CCXT-familiar watch* layer sits on top so existing bots port with little change.

npm i @sugar-rush/sdk

Quickstart

import { createClient, loadIdentity } from "@sugar-rush/sdk";

const client = createClient({
  wsUrl: "wss://api.sugar.rush.preview.sundae.fi/ws",
  identity: await loadIdentity("bot.skey"), // omit for public/read-only
});
await client.connect();

// Subscribe to many streams in one call.
await client.subscribe({
  orderbook: ["DARK-VAN", "UBE-VAN"],
  orders: true,
  balance: true,
});

// React with typed events…
client.on("orderbook", ({ symbol, book }) => {
  console.log(symbol, "best bid", book.bids[0]?.price, "best ask", book.asks[0]?.price);
});
client.on("order", (order) => console.log("order update", order.id, order.status.tag));

// …or read the current materialized state synchronously, any time.
const book = client.orderBook("DARK-VAN");
const van = client.balanceOf("VAN");
const mine = client.openOrders("DARK-VAN");

// Place an order (built → signed → encrypted → submitted over the socket).
await client.createOrder({
  symbol: "DARK-VAN",
  side: "buy",
  type: "limit",
  price: "2.15",   // human decimal (quote per base)
  size: "1000",    // 1000 whole DARK
  timeInForce: "GTC",
});

await client.cancelOrder(orderId);
await client.cancelAllOrders();

Human units vs. exact wire values

price and size accept human decimals ("2.15", "1000") by default; the SDK converts them with BigInt math (no floating-point loss) using each asset's decimals. When you want to hand the wire an exact value, wrap it with exact(...):

import { exact } from "@sugar-rush/sdk";

await client.createOrder({
  symbol: "DARK-VAN", side: "buy", type: "limit",
  price: exact("2.150000"),      // verbatim wire price
  size: exact(1_000_000_000n),   // 1e9 raw base units, verbatim
});

Deposits & withdrawals

// Watch deposit status live (pending → absorbed → rejected)
client.on("deposit", (d) => console.log(d.requestId, d.status));
const mine = client.deposits();

// Withdraw back to L1 (settles to your account's registered destination)
await client.withdraw({ asset: "VAN", amount: "500" });   // human, or exact(...)

Depositing is an L1 Cardano transaction (provider-injected). It can also establish a session delegate in the same flow — the account key signs once, then a browser session key trades with no further prompts:

await client.deposit({
  amountAda: 10,
  blockfrostProjectId: "preview…",   // Node: signs with your identity key
  // wallet: <blaze CIP-30 wallet>,  // browser: the user's wallet is the depositor
  delegateTo: sessionKeyHash,        // pre-signed now, auto-submitted once the deposit absorbs
});

Candles & ticker

await client.subscribe({
  candles: [{ symbol: "DARK-VAN", interval: "1m" }],
  ticker: ["DARK-VAN"],
});

client.on("candle", ({ symbol, interval, candle }) => {
  console.log(symbol, interval, "close", priceToNumber(candle.close));
});
client.on("ticker", ({ symbol, ticker }) => {
  console.log(symbol, "last", ticker.lastPrice, "bid/ask", ticker.bestBid, ticker.bestAsk);
});

const series = client.candles("DARK-VAN", "1m"); // materialized, ascending
const t = client.ticker("DARK-VAN");

Candle intervals are 1s / 1m / 1h / 1d. Price fields on candles and tickers are u128 fixed-point — render them with the exported priceToNumber.

CCXT-familiar layer

while (running) {
  const book = await client.watchOrderBook("DARK-VAN"); // resolves on the next update
  render(book);
}

watchOrders(symbol?), watchBalance(), watchTicker(symbol), and watchOHLCV(symbol, interval) work the same way — thin wrappers over the same subscription + materialized state.

Time in force

GTC (default) rests until cancelled · IOC fills what crosses now and cancels the rest · FOK fills fully or rejects · PostOnly rejects if it would cross. type: "market" orders are always IOC and sweep the top of book within marketSlippage (default 5%).

Under the hood

Writes go over the streaming API's submit op, which forwards the same COSE-signed, encrypted payload that POST /head/requests accepts — the exchange never sees your order before it matches. The low-level pieces (ViewsClient, buildEncryptedTransactionPayload, createRequestEncryptor, wire types) are exported too, if you need them.