@kupogg/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kupo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,137 @@
1
+ # @kupogg/sdk
2
+
3
+ Official TypeScript SDK for the Kupo trading API. Type-safe wrappers around every `/v1/*` endpoint with built-in retries, rate-limit handling and idiomatic async patterns.
4
+
5
+ Zero runtime dependencies. Works in Node 18+, Bun, Deno, the browser, and edge runtimes.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pnpm add @kupogg/sdk
11
+ # or: npm install @kupogg/sdk
12
+ # or: bun add @kupogg/sdk
13
+ ```
14
+
15
+ ## Quickstart
16
+
17
+ ```ts
18
+ import { Kupo } from "@kupogg/sdk";
19
+
20
+ const kupo = new Kupo({ apiKey: process.env.KUPO_API_KEY! });
21
+
22
+ // 1) sanity check — verify the key + load your account
23
+ const me = await kupo.me();
24
+ console.log("Cashback tier:", me.cashback?.tierName);
25
+ console.log("Total staked:", me.staking.totalStaked);
26
+
27
+ // 2) get a route preview before trading
28
+ const quote = await kupo.quote({
29
+ tokenAddress: "0xb2ece11a988a54a79675d4b827fc9ac419fb4ba3",
30
+ amountEth: "0.01",
31
+ });
32
+ console.log("Spot price:", quote.priceUsd);
33
+ console.log("Safety gates pass:", quote.gates.minTvl.passes);
34
+
35
+ // 3) execute a trade
36
+ const swap = await kupo.swap({
37
+ tokenAddress: "0xb2ece11a988a54a79675d4b827fc9ac419fb4ba3",
38
+ fromAddress: me.wallets[0].address,
39
+ amountEth: "0.01",
40
+ slippageBps: 100, // 1%
41
+ });
42
+ console.log("Tx hash:", swap.hash);
43
+ ```
44
+
45
+ ## Authentication
46
+
47
+ API keys ship in the `Authorization: Bearer kupo_live_…` header. Get a key at [kupo.gg/developer](https://kupo.gg/developer) or via the `/api` command in [@kupo_ggbot](https://t.me/kupo_ggbot).
48
+
49
+ The SDK enforces the format at construction:
50
+
51
+ ```ts
52
+ new Kupo({ apiKey: "invalid" }); // throws
53
+ ```
54
+
55
+ ## Error handling
56
+
57
+ Every method throws `KupoApiError` on non-2xx. The error carries the HTTP status, the structured `{ error, code }` body Kupo returns, and the original `Response`.
58
+
59
+ ```ts
60
+ import { Kupo, KupoApiError } from "@kupogg/sdk";
61
+
62
+ try {
63
+ await kupo.swap({ ... });
64
+ } catch (err) {
65
+ if (err instanceof KupoApiError) {
66
+ if (err.code === "buys-paused") {
67
+ console.log("Trading is paused for maintenance.");
68
+ } else if (err.code === "pool-tvl-too-low") {
69
+ console.log("Liquidity is too low — refusing the trade.");
70
+ } else if (err.status === 429) {
71
+ console.log("Rate limited. Retry-After:", err.response.headers.get("Retry-After"));
72
+ } else {
73
+ throw err;
74
+ }
75
+ }
76
+ }
77
+ ```
78
+
79
+ The SDK already retries on `429` (honouring `Retry-After`) and transient `5xx` with exponential backoff. Set `maxRetries: 0` to disable.
80
+
81
+ ## Endpoints
82
+
83
+ | SDK method | HTTP route |
84
+ |---|---|
85
+ | `kupo.me()` | `GET /v1/me` |
86
+ | `kupo.staking()` | `GET /v1/staking` |
87
+ | `kupo.token(addr, opts)` | `GET /v1/tokens/:address` |
88
+ | `kupo.balances(wallet)` | `GET /v1/balances/:wallet` |
89
+ | `kupo.ethPrice()` | `GET /v1/eth-price` |
90
+ | `kupo.quote(opts)` | `GET /v1/quote` |
91
+ | `kupo.swap(opts)` | `POST /v1/swap` |
92
+ | `kupo.sell(opts)` | `POST /v1/sell` |
93
+ | `kupo.launches(opts)` | `GET /v1/launches` |
94
+ | `kupo.trending(chain, period)` | `GET /v1/trending/:chain/:period` |
95
+ | `kupo.listOrders(opts)` | `GET /v1/orders` |
96
+ | `kupo.placeOrder(body)` | `POST /v1/orders` |
97
+ | `kupo.cancelOrder(id)` | `DELETE /v1/orders/:id` |
98
+
99
+ ## Why route through Kupo
100
+
101
+ - **Same fee router** as the web + bot. Routes via the deepest pool across Uniswap V4 / V3 / V2 + Aerodrome.
102
+ - **Cashback + staking discount stack.** Volume through your API key counts toward your cashback tier. Stake $KUPO for up to 40% off the platform fee — both apply on every trade.
103
+ - **Built-in safety gates.** Min-TVL ($500), max-trade-fraction (30%), mcap-vs-TVL ratio (200×), and an approval-propagation guard all run server-side. A bad pool can't fill your trade.
104
+ - **No wallet infra.** Uses your existing Kupo custodial wallets — same identity as the bot.
105
+
106
+ ## Rate limits
107
+
108
+ Per-key token bucket. Defaults:
109
+
110
+ | Tier | req/min | Unlock |
111
+ |---|---|---|
112
+ | Free | 60 | Default |
113
+ | Pro | 180 | Gold staking (10M $KUPO) |
114
+ | Platinum | 300 | Platinum staking (100M $KUPO) |
115
+ | Diamond | 600 | Diamond staking (500M $KUPO) |
116
+
117
+ Every response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`. 429 includes `Retry-After`.
118
+
119
+ ## Custom fetch / runtime
120
+
121
+ The SDK uses `globalThis.fetch` by default. To inject a polyfill or wrap with telemetry:
122
+
123
+ ```ts
124
+ import { Kupo } from "@kupogg/sdk";
125
+ import fetch from "node-fetch";
126
+
127
+ const kupo = new Kupo({
128
+ apiKey: process.env.KUPO_API_KEY!,
129
+ fetch: fetch as unknown as typeof globalThis.fetch,
130
+ timeoutMs: 60_000,
131
+ userAgent: "my-sniper-bot/1.2.0",
132
+ });
133
+ ```
134
+
135
+ ## License
136
+
137
+ MIT
@@ -0,0 +1,311 @@
1
+ /**
2
+ * Kupo SDK — official TypeScript client for the Kupo /v1 trading API.
3
+ *
4
+ * Goals:
5
+ * 1. Type-safe wrapper around every /v1/* endpoint
6
+ * 2. Built-in retry on transient errors + Retry-After-aware backoff on 429
7
+ * 3. Zero runtime deps — works in Node, Bun, Deno, the browser, edge runtimes
8
+ * 4. Tiny — < 5 KB minified, no bundler tax for users
9
+ *
10
+ * Quickstart:
11
+ *
12
+ * import { Kupo } from "@kupogg/sdk";
13
+ *
14
+ * const kupo = new Kupo({ apiKey: process.env.KUPO_API_KEY! });
15
+ *
16
+ * // identity
17
+ * const me = await kupo.me();
18
+ *
19
+ * // price preview
20
+ * const quote = await kupo.quote({
21
+ * tokenAddress: "0xb2ece11a988a54a79675d4b827fc9ac419fb4ba3",
22
+ * amountEth: "0.01",
23
+ * });
24
+ *
25
+ * // execute a trade
26
+ * const swap = await kupo.swap({
27
+ * tokenAddress: "0xb2ece11a988a54a79675d4b827fc9ac419fb4ba3",
28
+ * fromAddress: me.wallets[0].address,
29
+ * amountEth: "0.01",
30
+ * slippageBps: 100,
31
+ * });
32
+ *
33
+ * Errors:
34
+ * Every method throws `KupoApiError` on non-2xx. The error carries
35
+ * the HTTP status, the structured `{ error, code }` body Kupo returns,
36
+ * and the original Response for advanced cases.
37
+ */
38
+ export declare const KUPO_API_BASE = "https://api.kupo.gg";
39
+ export declare const KUPO_API_VERSION = "v1";
40
+ export interface KupoClientOptions {
41
+ /** API key — get one at kupo.gg/developer or via the /api Telegram command. */
42
+ apiKey: string;
43
+ /** Override the API base URL (default https://api.kupo.gg). Useful for
44
+ * staging or self-hosted setups. */
45
+ baseUrl?: string;
46
+ /** Custom fetch implementation. Defaults to globalThis.fetch (Node 18+,
47
+ * Bun, Deno, browsers, edge). Pass node-fetch / undici for legacy envs. */
48
+ fetch?: typeof fetch;
49
+ /** Max retries on transient 5xx + 429. Default 3. Set 0 to disable. */
50
+ maxRetries?: number;
51
+ /** Per-request timeout in ms. Default 30s (trades can take ~3-5s
52
+ * including approve + broadcast, so anything longer is suspect). */
53
+ timeoutMs?: number;
54
+ /** Optional User-Agent tag so the operator can identify your client
55
+ * in api.kupo.gg logs. Convention: "your-app-name/1.0.0". */
56
+ userAgent?: string;
57
+ }
58
+ export declare class KupoApiError extends Error {
59
+ readonly status: number;
60
+ readonly code?: string;
61
+ readonly body: unknown;
62
+ readonly response: Response;
63
+ constructor(opts: {
64
+ status: number;
65
+ message: string;
66
+ code?: string;
67
+ body: unknown;
68
+ response: Response;
69
+ });
70
+ }
71
+ export interface MeResponse {
72
+ subOrgId: string;
73
+ activeKey: {
74
+ id: string;
75
+ prefix: string;
76
+ tier: string;
77
+ };
78
+ wallets: Array<{
79
+ address: string;
80
+ label: string;
81
+ walletId: string;
82
+ }>;
83
+ cashback: {
84
+ tierId: string;
85
+ tierName: string;
86
+ cashbackPct: number;
87
+ volumeUsd: number;
88
+ unclaimedEth: number;
89
+ claimedEth: number;
90
+ } | null;
91
+ staking: {
92
+ totalStaked: string;
93
+ walletCount: number;
94
+ };
95
+ keys: Array<{
96
+ id: string;
97
+ prefix: string;
98
+ label: string | null;
99
+ tier: string;
100
+ createdAt: string;
101
+ lastUsedAt: string | null;
102
+ revoked: boolean;
103
+ }>;
104
+ }
105
+ export interface StakingResponse {
106
+ wallets: Array<{
107
+ address: string;
108
+ walletId: string;
109
+ label: string;
110
+ kupoBalance: string;
111
+ stakingAllowance: string;
112
+ stakedBalance: string;
113
+ totalPending: string;
114
+ nextReadyAtUnixSec: string;
115
+ readyCount: number;
116
+ readyTotal: string;
117
+ batches: Array<{
118
+ batchIndex: number;
119
+ amount: string;
120
+ readyAtUnixSec: string;
121
+ }>;
122
+ }>;
123
+ }
124
+ export interface QuoteResponse {
125
+ chain: string;
126
+ tokenAddress: string;
127
+ pool: {
128
+ address: string;
129
+ dex: string;
130
+ fee: number;
131
+ tvlUsd: number;
132
+ quoteIsNative: boolean;
133
+ };
134
+ priceUsd: number;
135
+ ethUsd: number;
136
+ tradeUsd: number | null;
137
+ gates: {
138
+ minTvl: {
139
+ passes: boolean;
140
+ poolTvlUsd: number;
141
+ minRequired: number;
142
+ };
143
+ maxTradeFraction: {
144
+ passes: boolean;
145
+ fractionPct: number;
146
+ maxPct: number;
147
+ } | null;
148
+ };
149
+ poolsConsidered: number;
150
+ }
151
+ export interface SwapResponse {
152
+ hash: string;
153
+ poolId: string;
154
+ chain: string;
155
+ version: string;
156
+ latencyMs?: {
157
+ sign?: number;
158
+ broadcast?: number;
159
+ };
160
+ }
161
+ export interface SwapRequest {
162
+ tokenAddress: string;
163
+ fromAddress: string;
164
+ amountEth: string;
165
+ slippageBps: number;
166
+ chain?: "base" | "ethereum" | "bsc";
167
+ /** Optional MEV protection toggle (default Kupo's MEV-protected route). */
168
+ mev?: boolean;
169
+ /** Optional priority gas in gwei (overrides per-account default). */
170
+ priorityGasGwei?: string;
171
+ /** Default true (let the router pick a sane priority); set false to
172
+ * honour `priorityGasGwei`. */
173
+ gasAuto?: boolean;
174
+ }
175
+ export interface SellRequest {
176
+ tokenAddress: string;
177
+ fromAddress: string;
178
+ /** Either provide a raw token amount or a percentage of the wallet's
179
+ * current balance. */
180
+ amountTokenRaw?: string;
181
+ percentOfBalance?: number;
182
+ slippageBps: number;
183
+ chain?: "base" | "ethereum" | "bsc";
184
+ }
185
+ export interface OrderListItem {
186
+ id: string;
187
+ kind: "limit" | "tp" | "sl" | "tsl" | "dca";
188
+ side: "buy" | "sell";
189
+ tokenAddress: string;
190
+ status: "pending" | "filled" | "cancelled" | "failed" | "expired";
191
+ createdAt: string;
192
+ [k: string]: unknown;
193
+ }
194
+ export declare class Kupo {
195
+ private readonly apiKey;
196
+ private readonly baseUrl;
197
+ private readonly fetchImpl;
198
+ private readonly maxRetries;
199
+ private readonly timeoutMs;
200
+ private readonly userAgent?;
201
+ constructor(opts: KupoClientOptions);
202
+ private request;
203
+ /** Verify the key + load the bound account's identity, wallets,
204
+ * cashback tier and active keys. Call this first to sanity-check. */
205
+ me(): Promise<MeResponse>;
206
+ /** Full token snapshot (mcap, liq, pools, holders, volumes). */
207
+ token(address: string, opts?: {
208
+ chain?: "base" | "ethereum" | "bsc";
209
+ }): Promise<unknown>;
210
+ /** ETH/USD oracle the rest of the API uses internally. */
211
+ ethPrice(): Promise<{
212
+ priceUsd: number;
213
+ t: number;
214
+ }>;
215
+ /** Wallet balances (native + tracked ERC-20s). Cached 10s server-side. */
216
+ balances(walletAddress: string): Promise<unknown>;
217
+ /** Recent token launches. */
218
+ launches(opts?: {
219
+ limit?: number;
220
+ }): Promise<unknown>;
221
+ /** Trending tokens on a chain over a window. */
222
+ trending(chain: "base" | "ethereum" | "bsc", period: "5m" | "1h" | "6h" | "24h"): Promise<unknown>;
223
+ /** Route preview WITHOUT broadcasting. Returns the pool Kupo would
224
+ * pick + the price + the pre-flight safety gates. */
225
+ quote(opts: {
226
+ tokenAddress: string;
227
+ amountEth?: string;
228
+ chain?: "base" | "ethereum" | "bsc";
229
+ }): Promise<QuoteResponse>;
230
+ /** Execute a buy. Goes through every safety gate Kupo enforces on
231
+ * every trade (min-TVL, max-fraction, mcap-vs-TVL ratio, approval
232
+ * propagation guard, buys-paused flag). */
233
+ swap(opts: SwapRequest): Promise<SwapResponse>;
234
+ /** Execute a sell. */
235
+ sell(opts: SellRequest): Promise<SwapResponse>;
236
+ /** Per-wallet staking state — staked amount, pending batches with
237
+ * their cooldown timers, KUPO balance. */
238
+ staking(): Promise<StakingResponse>;
239
+ /** List orders on the account. */
240
+ listOrders(opts?: {
241
+ status?: string;
242
+ kind?: string;
243
+ }): Promise<{
244
+ orders: OrderListItem[];
245
+ }>;
246
+ /** Place an order — see https://kupo.gg/developer for the body shape
247
+ * per `kind` (limit / tp / sl / tsl / dca). */
248
+ placeOrder(body: Record<string, unknown>): Promise<OrderListItem>;
249
+ /** Cancel a pending order. */
250
+ cancelOrder(orderId: string): Promise<{
251
+ ok: true;
252
+ }>;
253
+ /** Push feed of every new token launch (Bankr / Clanker / Flaunch /
254
+ * Doppler / Virtuals). The callback fires the instant the
255
+ * underlying watcher ingests the Initialize event — same latency
256
+ * as the bot's live feed.
257
+ *
258
+ * Returns a `KupoStream` handle with a `.close()` method. The
259
+ * stream auto-reconnects on transient errors. Pass `onError` to
260
+ * handle terminal failures.
261
+ *
262
+ * Snipers wire this directly: filter the launch, decide, then
263
+ * call `kupo.swap()` from inside `onLaunch`.
264
+ */
265
+ streamLaunches(opts: {
266
+ onLaunch: (launch: KupoLaunchEvent) => void;
267
+ onOpen?: () => void;
268
+ onError?: (err: Error) => void;
269
+ }): KupoStream;
270
+ /** Push feed of every swap on a token. Same in-memory subscriber
271
+ * the bot + web rely on; latency = the watcher's WS push latency.
272
+ *
273
+ * Use case: live dashboards, copy-trade triggers, position alerts. */
274
+ streamSwaps(tokenAddress: string, opts: {
275
+ onSwap: (swap: KupoSwapEvent) => void;
276
+ onOpen?: () => void;
277
+ onError?: (err: Error) => void;
278
+ }): KupoStream;
279
+ }
280
+ export interface KupoLaunchEvent {
281
+ token: string;
282
+ chain: string;
283
+ launchpad?: string;
284
+ deployer?: string;
285
+ createdAt?: number;
286
+ name?: string;
287
+ symbol?: string;
288
+ /** Pass-through fields — the upstream emits the full TokenLaunch
289
+ * shape so we surface everything the indexer captured at launch
290
+ * time without filtering. */
291
+ [k: string]: unknown;
292
+ }
293
+ export interface KupoSwapEvent {
294
+ txHash: string;
295
+ logIndex: number;
296
+ blockNumber: number;
297
+ blockTime: number;
298
+ tokenAddress: string;
299
+ side: "buy" | "sell";
300
+ taker: string;
301
+ amount0: string;
302
+ amount1: string;
303
+ priceUsd: number;
304
+ }
305
+ export interface KupoStream {
306
+ /** Close the stream + cancel auto-reconnect. */
307
+ close(): void;
308
+ /** True once we've received the initial `open` event from the server. */
309
+ readonly opened: boolean;
310
+ }
311
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,410 @@
1
+ /**
2
+ * Kupo SDK — official TypeScript client for the Kupo /v1 trading API.
3
+ *
4
+ * Goals:
5
+ * 1. Type-safe wrapper around every /v1/* endpoint
6
+ * 2. Built-in retry on transient errors + Retry-After-aware backoff on 429
7
+ * 3. Zero runtime deps — works in Node, Bun, Deno, the browser, edge runtimes
8
+ * 4. Tiny — < 5 KB minified, no bundler tax for users
9
+ *
10
+ * Quickstart:
11
+ *
12
+ * import { Kupo } from "@kupogg/sdk";
13
+ *
14
+ * const kupo = new Kupo({ apiKey: process.env.KUPO_API_KEY! });
15
+ *
16
+ * // identity
17
+ * const me = await kupo.me();
18
+ *
19
+ * // price preview
20
+ * const quote = await kupo.quote({
21
+ * tokenAddress: "0xb2ece11a988a54a79675d4b827fc9ac419fb4ba3",
22
+ * amountEth: "0.01",
23
+ * });
24
+ *
25
+ * // execute a trade
26
+ * const swap = await kupo.swap({
27
+ * tokenAddress: "0xb2ece11a988a54a79675d4b827fc9ac419fb4ba3",
28
+ * fromAddress: me.wallets[0].address,
29
+ * amountEth: "0.01",
30
+ * slippageBps: 100,
31
+ * });
32
+ *
33
+ * Errors:
34
+ * Every method throws `KupoApiError` on non-2xx. The error carries
35
+ * the HTTP status, the structured `{ error, code }` body Kupo returns,
36
+ * and the original Response for advanced cases.
37
+ */
38
+ export const KUPO_API_BASE = "https://api.kupo.gg";
39
+ export const KUPO_API_VERSION = "v1";
40
+ // ── Error type ──────────────────────────────────────────────────────
41
+ export class KupoApiError extends Error {
42
+ status;
43
+ code;
44
+ body;
45
+ response;
46
+ constructor(opts) {
47
+ super(opts.message);
48
+ this.name = "KupoApiError";
49
+ this.status = opts.status;
50
+ this.code = opts.code;
51
+ this.body = opts.body;
52
+ this.response = opts.response;
53
+ }
54
+ }
55
+ // ── The client ─────────────────────────────────────────────────────
56
+ export class Kupo {
57
+ apiKey;
58
+ baseUrl;
59
+ fetchImpl;
60
+ maxRetries;
61
+ timeoutMs;
62
+ userAgent;
63
+ constructor(opts) {
64
+ if (!opts.apiKey || !opts.apiKey.startsWith("kupo_live_")) {
65
+ throw new Error("[Kupo SDK] apiKey is required and must start with 'kupo_live_'.");
66
+ }
67
+ this.apiKey = opts.apiKey;
68
+ this.baseUrl = (opts.baseUrl ?? KUPO_API_BASE).replace(/\/$/, "");
69
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
70
+ this.fetchImpl = opts.fetch ?? globalThis.fetch?.bind(globalThis);
71
+ if (!this.fetchImpl) {
72
+ throw new Error("[Kupo SDK] No `fetch` available in this runtime. Pass one via `options.fetch`.");
73
+ }
74
+ this.maxRetries = opts.maxRetries ?? 3;
75
+ this.timeoutMs = opts.timeoutMs ?? 30_000;
76
+ this.userAgent = opts.userAgent;
77
+ }
78
+ // ── Core request — handles auth, retries, 429 backoff, errors ──
79
+ async request(path, init = {}) {
80
+ const url = `${this.baseUrl}/${KUPO_API_VERSION}${path}`;
81
+ const headers = new Headers(init.headers);
82
+ headers.set("Authorization", `Bearer ${this.apiKey}`);
83
+ if (init.body && !headers.has("Content-Type")) {
84
+ headers.set("Content-Type", "application/json");
85
+ }
86
+ if (this.userAgent && !headers.has("User-Agent")) {
87
+ headers.set("User-Agent", this.userAgent);
88
+ }
89
+ let attempt = 0;
90
+ let lastError = null;
91
+ while (attempt <= this.maxRetries) {
92
+ const controller = new AbortController();
93
+ const timer = setTimeout(() => controller.abort(), this.timeoutMs);
94
+ try {
95
+ const res = await this.fetchImpl(url, {
96
+ ...init,
97
+ headers,
98
+ signal: controller.signal,
99
+ });
100
+ clearTimeout(timer);
101
+ // Honour 429 Retry-After before deciding to retry.
102
+ if (res.status === 429 && attempt < this.maxRetries) {
103
+ const retryAfter = Number(res.headers.get("Retry-After")) || 1;
104
+ await sleep(retryAfter * 1000);
105
+ attempt++;
106
+ continue;
107
+ }
108
+ // Retry transient 5xx.
109
+ if (res.status >= 500 && res.status < 600 && attempt < this.maxRetries) {
110
+ await sleep(backoffMs(attempt));
111
+ attempt++;
112
+ continue;
113
+ }
114
+ if (!res.ok) {
115
+ const body = await safeJson(res);
116
+ throw new KupoApiError({
117
+ status: res.status,
118
+ message: body?.error ??
119
+ `Kupo API error: HTTP ${res.status}`,
120
+ code: body?.code,
121
+ body,
122
+ response: res,
123
+ });
124
+ }
125
+ return (await res.json());
126
+ }
127
+ catch (err) {
128
+ clearTimeout(timer);
129
+ if (err instanceof KupoApiError)
130
+ throw err;
131
+ if (err instanceof Error &&
132
+ err.name === "AbortError" &&
133
+ attempt < this.maxRetries) {
134
+ // Timeout — retry with backoff
135
+ lastError = err;
136
+ await sleep(backoffMs(attempt));
137
+ attempt++;
138
+ continue;
139
+ }
140
+ if (err instanceof TypeError &&
141
+ /fetch failed|network/i.test(err.message) &&
142
+ attempt < this.maxRetries) {
143
+ lastError = err;
144
+ await sleep(backoffMs(attempt));
145
+ attempt++;
146
+ continue;
147
+ }
148
+ throw err;
149
+ }
150
+ }
151
+ throw lastError ?? new Error("[Kupo SDK] request retry budget exhausted");
152
+ }
153
+ // ── Identity ──────────────────────────────────────────────────
154
+ /** Verify the key + load the bound account's identity, wallets,
155
+ * cashback tier and active keys. Call this first to sanity-check. */
156
+ me() {
157
+ return this.request("/me");
158
+ }
159
+ // ── Read-only data ────────────────────────────────────────────
160
+ /** Full token snapshot (mcap, liq, pools, holders, volumes). */
161
+ token(address, opts = {}) {
162
+ const q = opts.chain ? `?chain=${opts.chain}` : "";
163
+ return this.request(`/tokens/${address}${q}`);
164
+ }
165
+ /** ETH/USD oracle the rest of the API uses internally. */
166
+ ethPrice() {
167
+ return this.request("/eth-price");
168
+ }
169
+ /** Wallet balances (native + tracked ERC-20s). Cached 10s server-side. */
170
+ balances(walletAddress) {
171
+ return this.request(`/balances/${walletAddress}`);
172
+ }
173
+ /** Recent token launches. */
174
+ launches(opts = {}) {
175
+ const q = opts.limit ? `?limit=${opts.limit}` : "";
176
+ return this.request(`/launches${q}`);
177
+ }
178
+ /** Trending tokens on a chain over a window. */
179
+ trending(chain, period) {
180
+ return this.request(`/trending/${chain}/${period}`);
181
+ }
182
+ // ── Trading ───────────────────────────────────────────────────
183
+ /** Route preview WITHOUT broadcasting. Returns the pool Kupo would
184
+ * pick + the price + the pre-flight safety gates. */
185
+ quote(opts) {
186
+ const params = new URLSearchParams();
187
+ params.set("tokenAddress", opts.tokenAddress);
188
+ if (opts.amountEth)
189
+ params.set("amountEth", opts.amountEth);
190
+ if (opts.chain)
191
+ params.set("chain", opts.chain);
192
+ return this.request(`/quote?${params.toString()}`);
193
+ }
194
+ /** Execute a buy. Goes through every safety gate Kupo enforces on
195
+ * every trade (min-TVL, max-fraction, mcap-vs-TVL ratio, approval
196
+ * propagation guard, buys-paused flag). */
197
+ swap(opts) {
198
+ return this.request("/swap", {
199
+ method: "POST",
200
+ body: JSON.stringify(opts),
201
+ });
202
+ }
203
+ /** Execute a sell. */
204
+ sell(opts) {
205
+ return this.request("/sell", {
206
+ method: "POST",
207
+ body: JSON.stringify(opts),
208
+ });
209
+ }
210
+ // ── Staking ───────────────────────────────────────────────────
211
+ /** Per-wallet staking state — staked amount, pending batches with
212
+ * their cooldown timers, KUPO balance. */
213
+ staking() {
214
+ return this.request("/staking");
215
+ }
216
+ // ── Orders ────────────────────────────────────────────────────
217
+ /** List orders on the account. */
218
+ listOrders(opts = {}) {
219
+ const params = new URLSearchParams();
220
+ if (opts.status)
221
+ params.set("status", opts.status);
222
+ if (opts.kind)
223
+ params.set("kind", opts.kind);
224
+ const qs = params.toString();
225
+ return this.request(qs ? `/orders?${qs}` : "/orders");
226
+ }
227
+ /** Place an order — see https://kupo.gg/developer for the body shape
228
+ * per `kind` (limit / tp / sl / tsl / dca). */
229
+ placeOrder(body) {
230
+ return this.request("/orders", {
231
+ method: "POST",
232
+ body: JSON.stringify(body),
233
+ });
234
+ }
235
+ /** Cancel a pending order. */
236
+ cancelOrder(orderId) {
237
+ return this.request(`/orders/${encodeURIComponent(orderId)}`, {
238
+ method: "DELETE",
239
+ });
240
+ }
241
+ // ── Streams (Server-Sent Events) ──────────────────────────────
242
+ /** Push feed of every new token launch (Bankr / Clanker / Flaunch /
243
+ * Doppler / Virtuals). The callback fires the instant the
244
+ * underlying watcher ingests the Initialize event — same latency
245
+ * as the bot's live feed.
246
+ *
247
+ * Returns a `KupoStream` handle with a `.close()` method. The
248
+ * stream auto-reconnects on transient errors. Pass `onError` to
249
+ * handle terminal failures.
250
+ *
251
+ * Snipers wire this directly: filter the launch, decide, then
252
+ * call `kupo.swap()` from inside `onLaunch`.
253
+ */
254
+ streamLaunches(opts) {
255
+ return openStream({
256
+ url: `${this.baseUrl}/${KUPO_API_VERSION}/stream/launches`,
257
+ apiKey: this.apiKey,
258
+ fetchImpl: this.fetchImpl,
259
+ onEvent: (eventName, data) => {
260
+ if (eventName === "launch")
261
+ opts.onLaunch(data);
262
+ },
263
+ onOpen: opts.onOpen,
264
+ onError: opts.onError,
265
+ });
266
+ }
267
+ /** Push feed of every swap on a token. Same in-memory subscriber
268
+ * the bot + web rely on; latency = the watcher's WS push latency.
269
+ *
270
+ * Use case: live dashboards, copy-trade triggers, position alerts. */
271
+ streamSwaps(tokenAddress, opts) {
272
+ return openStream({
273
+ url: `${this.baseUrl}/${KUPO_API_VERSION}/stream/swaps/${encodeURIComponent(tokenAddress)}`,
274
+ apiKey: this.apiKey,
275
+ fetchImpl: this.fetchImpl,
276
+ onEvent: (eventName, data) => {
277
+ if (eventName === "swap")
278
+ opts.onSwap(data);
279
+ },
280
+ onOpen: opts.onOpen,
281
+ onError: opts.onError,
282
+ });
283
+ }
284
+ }
285
+ /** SSE client implementation that works in Node 18+ and browsers via
286
+ * `fetch` streaming response bodies. Custom-parsed (vs using the
287
+ * browser EventSource API) so we can ship the Bearer header on the
288
+ * request — EventSource doesn't support custom headers in the
289
+ * browser, and there's no native EventSource in Node anyway. */
290
+ function openStream(opts) {
291
+ let cancelled = false;
292
+ let opened = false;
293
+ let abortCtrl = null;
294
+ const connect = async () => {
295
+ while (!cancelled) {
296
+ abortCtrl = new AbortController();
297
+ try {
298
+ const res = await opts.fetchImpl(opts.url, {
299
+ headers: {
300
+ Authorization: `Bearer ${opts.apiKey}`,
301
+ Accept: "text/event-stream",
302
+ },
303
+ signal: abortCtrl.signal,
304
+ });
305
+ if (!res.ok || !res.body) {
306
+ const body = await safeJson(res).catch(() => null);
307
+ const err = new KupoApiError({
308
+ status: res.status,
309
+ message: body?.error ?? `Stream auth failed (HTTP ${res.status})`,
310
+ code: body?.code,
311
+ body,
312
+ response: res,
313
+ });
314
+ // 401/403/404 are terminal — never retry on these.
315
+ if ([400, 401, 403, 404].includes(res.status)) {
316
+ opts.onError?.(err);
317
+ return;
318
+ }
319
+ throw err;
320
+ }
321
+ const reader = res.body.getReader();
322
+ const decoder = new TextDecoder();
323
+ let buf = "";
324
+ let currentEvent = "message";
325
+ // eslint-disable-next-line no-constant-condition
326
+ while (true) {
327
+ const { value, done } = await reader.read();
328
+ if (done)
329
+ break;
330
+ if (cancelled)
331
+ break;
332
+ buf += decoder.decode(value, { stream: true });
333
+ let nl;
334
+ // SSE frames are separated by \n\n. Process whatever full
335
+ // frames we have, leave the trailing partial in `buf`.
336
+ while ((nl = buf.indexOf("\n\n")) >= 0) {
337
+ const frame = buf.slice(0, nl);
338
+ buf = buf.slice(nl + 2);
339
+ const lines = frame.split("\n");
340
+ let dataLines = [];
341
+ currentEvent = "message";
342
+ for (const line of lines) {
343
+ if (line.startsWith(":"))
344
+ continue; // comment / heartbeat
345
+ if (line.startsWith("event:")) {
346
+ currentEvent = line.slice(6).trim();
347
+ }
348
+ else if (line.startsWith("data:")) {
349
+ dataLines.push(line.slice(5).trim());
350
+ }
351
+ }
352
+ if (dataLines.length === 0)
353
+ continue;
354
+ const dataStr = dataLines.join("\n");
355
+ try {
356
+ const parsed = dataStr.length > 0 ? JSON.parse(dataStr) : null;
357
+ if (currentEvent === "open") {
358
+ opened = true;
359
+ opts.onOpen?.();
360
+ }
361
+ opts.onEvent(currentEvent, parsed);
362
+ }
363
+ catch {
364
+ // malformed event, skip
365
+ }
366
+ }
367
+ }
368
+ }
369
+ catch (err) {
370
+ if (cancelled)
371
+ return;
372
+ if (err instanceof Error && err.name === "AbortError")
373
+ return;
374
+ // Network drop / transient — reconnect with backoff.
375
+ opts.onError?.(err instanceof Error ? err : new Error(String(err)));
376
+ }
377
+ if (!cancelled) {
378
+ // Backoff before reconnect: 1s, then 2s, 4s, 8s capped.
379
+ await sleep(1000);
380
+ }
381
+ }
382
+ };
383
+ void connect();
384
+ return {
385
+ close() {
386
+ cancelled = true;
387
+ abortCtrl?.abort();
388
+ },
389
+ get opened() {
390
+ return opened;
391
+ },
392
+ };
393
+ }
394
+ // ── Helpers ────────────────────────────────────────────────────────
395
+ async function safeJson(res) {
396
+ try {
397
+ return await res.json();
398
+ }
399
+ catch {
400
+ return null;
401
+ }
402
+ }
403
+ function sleep(ms) {
404
+ return new Promise((resolve) => setTimeout(resolve, ms));
405
+ }
406
+ function backoffMs(attempt) {
407
+ // 250ms, 500ms, 1s, 2s, 4s — capped at 8s.
408
+ return Math.min(250 * Math.pow(2, attempt), 8000);
409
+ }
410
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@kupogg/sdk",
3
+ "version": "0.1.0",
4
+ "description": "Official TypeScript SDK for the Kupo trading API — typed wrappers around every /v1 endpoint with built-in retries, rate-limit handling, SSE streams and idiomatic async patterns.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js",
14
+ "default": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "README.md",
20
+ "LICENSE"
21
+ ],
22
+ "scripts": {
23
+ "build": "tsc -p tsconfig.build.json",
24
+ "prepublishOnly": "rm -rf dist && pnpm build",
25
+ "typecheck": "tsc --noEmit"
26
+ },
27
+ "keywords": [
28
+ "kupo",
29
+ "base",
30
+ "trading",
31
+ "evm",
32
+ "swap",
33
+ "api",
34
+ "sdk",
35
+ "telegram",
36
+ "discord",
37
+ "sniper",
38
+ "dca"
39
+ ],
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "https://github.com/xiliaf09/kupo.git",
43
+ "directory": "packages/sdk"
44
+ },
45
+ "homepage": "https://kupo.gg/developer",
46
+ "bugs": {
47
+ "url": "https://github.com/xiliaf09/kupo/issues"
48
+ },
49
+ "engines": {
50
+ "node": ">=18"
51
+ },
52
+ "sideEffects": false,
53
+ "devDependencies": {
54
+ "typescript": "^5"
55
+ },
56
+ "publishConfig": {
57
+ "access": "public"
58
+ }
59
+ }