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
Install
npm install @superis/sweetspot-client
# peer deps:
npm install @connectrpc/connect @connectrpc/connect-web @bufbuild/protobufQuickstart
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 want | Page |
|---|---|
| Stream books and fills | Market data |
| Sign-in flow detail | Auth flow |
| Survive transient disconnects | Resilience |
| Pull historical trades / candles | Historical queries |
Authenticated transport
For services other than MarketDataService, layer the AuthFlow interceptor on a fresh transport — every call gets a bearer token attached automatically:
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:
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
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.
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
- Package:
typescript-web/ - Examples:
examples/typescript-web/