Skip to content

TypeScript (web) SDK

ESM-only TypeScript SDK built on @connectrpc/connect-web. Works in any modern browser and in Node 18.14+. No build-time codegen required by consumers — the package ships pre-generated TypeScript.

No quoting layer

The TS SDK intentionally stops at AuthFlow + read-only client wrappers

  • ResilientStream. Browser trading clients should sign and submit transactions through a wallet adapter (Phantom, Solflare, @solana/wallet-adapter-base), not the SDK. For server-side quoting, use the Rust or Go SDK.

Install

sh
npm install @superis/sweetspot-client
# peer deps:
npm install @connectrpc/connect @connectrpc/connect-web @bufbuild/protobuf

Quickstart

ts
import { createClient } from "@connectrpc/connect";
import { createConnectTransport } from "@connectrpc/connect-web";
import {
  AuthFlow,
  MarketDataService,
  type WalletSigner,
} from "@superis/sweetspot-client";

const transport = createConnectTransport({
  baseUrl: "https://api.superis.exchange",
  useBinaryFormat: true,
});

// Public RPC — no auth needed.
const market = createClient(MarketDataService, transport);
const pairs = await market.listPairs({});
console.log(pairs.pairs);

// Authenticated path: AuthService.Challenge → sign → Authenticate.
const auth = new AuthFlow({ transport, signer });
const session = await auth.token();
console.log("authenticated as maker_id=", session.makerId.toString());

The signer is your WalletSigner — typically a thin adapter over @solana/wallet-adapter-base or @noble/ed25519. See Auth flow for the full contract.

Where to go from here

You wantPage
Stream books and fillsMarket data
Sign-in flow detailAuth flow
Survive transient disconnectsResilience
Pull historical trades / candlesHistorical queries

Authenticated transport

For services other than MarketDataService, layer the AuthFlow interceptor on a fresh transport — every call gets a bearer token attached automatically:

ts
const authedTransport = createConnectTransport({
  baseUrl: "https://api.superis.exchange",
  useBinaryFormat: true,
  interceptors: [auth.interceptor()],
});

import { BalanceService } from "@superis/sweetspot-client";
const balances = createClient(BalanceService, authedTransport);
const snapshot = await balances.get({ spotIds: [] });

Decimal handling

price, size, and OHLCV fields come back as Decimal { value: string }. Parse with bignumber.js or decimal.js:

ts
import BigNumber from "bignumber.js";

const price = new BigNumber(trade.price.value);
const size = new BigNumber(trade.size.value);
const notional = price.multipliedBy(size);

Errors

ts
import { ConnectError, Code } from "@connectrpc/connect";

try {
  await balances.get({ spotIds: [] });
} catch (err) {
  if (err instanceof ConnectError) {
    switch (err.code) {
      case Code.Unauthenticated: await auth.refresh(); break;
      case Code.ResourceExhausted: await sleep(backoff); break;
    }
  }
}

See Errors for the full code map.

gRPC-Web

The default transport is Connect-binary. For environments that need gRPC-Web specifically, swap createConnectTransport for createGrpcWebTransport — the rest of the SDK is unchanged.

ts
import { createGrpcWebTransport } from "@connectrpc/connect-web";

const transport = createGrpcWebTransport({
  baseUrl: "https://api.superis.exchange",
  useBinaryFormat: true,
});

Browser compatibility

Modern browsers (Chrome 90+, Firefox 90+, Safari 14+). Requires fetch and ReadableStream — both baseline in every release-channel browser since 2022.

Source

Apache 2.0