cabalspy-id 0.5.1 → 0.5.2
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/CHANGELOG.md +146 -112
- package/LICENSE +21 -21
- package/README.md +505 -475
- package/dist/api.cjs +5 -3
- package/dist/api.cjs.map +1 -1
- package/dist/api.d.cts +1 -1
- package/dist/api.d.ts +1 -1
- package/dist/api.js +16 -14
- package/dist/chunk-A2ZAFAWC.cjs.map +1 -1
- package/dist/chunk-ABFIPCBY.cjs +109 -0
- package/dist/chunk-ABFIPCBY.cjs.map +1 -0
- package/dist/{chunk-Z3UPDOBY.js → chunk-DBYCRBVS.js} +9 -7
- package/dist/chunk-DBYCRBVS.js.map +1 -0
- package/dist/{chunk-P3MDLWLN.cjs → chunk-PKFIMBPW.cjs} +113 -54
- package/dist/chunk-PKFIMBPW.cjs.map +1 -0
- package/dist/{chunk-L4RHSWOA.cjs → chunk-ULEBNY2A.cjs} +121 -212
- package/dist/chunk-ULEBNY2A.cjs.map +1 -0
- package/dist/{chunk-X3OFGGSE.cjs → chunk-VDFCMYLR.cjs} +50 -48
- package/dist/chunk-VDFCMYLR.cjs.map +1 -0
- package/dist/chunk-VOTYIQAY.js +109 -0
- package/dist/chunk-VOTYIQAY.js.map +1 -0
- package/dist/{chunk-3LKLY5WQ.js → chunk-XLBO2RSL.js} +15 -106
- package/dist/chunk-XLBO2RSL.js.map +1 -0
- package/dist/{chunk-3P7QK2PG.js → chunk-Z23B5TY6.js} +89 -30
- package/dist/chunk-Z23B5TY6.js.map +1 -0
- package/dist/index.cjs +13 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +25 -17
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +55 -2
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +28 -5
- package/dist/react.d.ts +28 -5
- package/dist/react.js +55 -2
- package/dist/react.js.map +1 -1
- package/dist/thesis.cjs +11 -3
- package/dist/thesis.cjs.map +1 -1
- package/dist/thesis.d.cts +42 -11
- package/dist/thesis.d.ts +42 -11
- package/dist/thesis.js +24 -16
- package/dist/{users-BDLkwW1p.d.cts → users-3DAw88_U.d.cts} +4 -4
- package/dist/{users-CDlDRuyv.d.ts → users-B4r33i4O.d.ts} +4 -4
- package/dist/widget.cjs +28 -12
- package/dist/widget.cjs.map +1 -1
- package/dist/widget.d.cts +37 -6
- package/dist/widget.d.ts +37 -6
- package/dist/widget.js +17 -1
- package/dist/widget.js.map +1 -1
- package/package.json +147 -147
- package/dist/chunk-3LKLY5WQ.js.map +0 -1
- package/dist/chunk-3P7QK2PG.js.map +0 -1
- package/dist/chunk-L4RHSWOA.cjs.map +0 -1
- package/dist/chunk-P3MDLWLN.cjs.map +0 -1
- package/dist/chunk-X3OFGGSE.cjs.map +0 -1
- package/dist/chunk-Z3UPDOBY.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/types.ts","../src/stream.ts","../src/thesesStream.ts","../src/util.ts","../src/client.ts","../src/webhooks.ts","../src/users.ts"],"sourcesContent":["// ═══════════════════════════════════════════════════════════════════════════\n// ERRORS\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface RateLimitInfo {\n /** Requests per second allowed by the plan. `null` when the header is absent. */\n limit: number | null;\n remaining: number | null;\n /** Seconds until the current one-second window resets. */\n reset: number | null;\n}\n\nexport const EMPTY_RATE_LIMIT: RateLimitInfo = Object.freeze({ limit: null, remaining: null, reset: null });\n\n/** Error body of the Data API: `{\"success\": false, \"error\": {...}}`. */\nexport interface ApiErrorBody {\n code: string;\n message: string;\n request_id: string;\n /** Link to the error's documentation, e.g. https://docs.cabalspy.xyz/cabalspy-id/errors#wallet_not_found */\n docs: string;\n parameter?: string;\n allowed?: unknown[];\n /** Set on `plan_user_limit`. */\n limited?: boolean;\n [key: string]: unknown;\n}\n\nexport interface CabalSpyIDErrorOptions {\n status?: number;\n code?: string;\n requestId?: string;\n docs?: string;\n parameter?: string;\n allowed?: unknown[];\n rateLimit?: RateLimitInfo;\n body?: unknown;\n}\n\n/** Base class for every error thrown by this SDK. */\nexport class CabalSpyIDError extends Error {\n readonly status: number;\n readonly code: string;\n readonly requestId?: string;\n readonly docs?: string;\n readonly parameter?: string;\n readonly allowed?: unknown[];\n readonly rateLimit: RateLimitInfo;\n /** The parsed response body, when there was one. */\n readonly body?: unknown;\n\n constructor(message: string, opts: CabalSpyIDErrorOptions = {}) {\n super(message);\n this.name = new.target.name;\n this.status = opts.status ?? 0;\n this.code = opts.code ?? 'unknown_error';\n this.requestId = opts.requestId;\n this.docs = opts.docs;\n this.parameter = opts.parameter;\n this.allowed = opts.allowed;\n this.rateLimit = opts.rateLimit ?? { ...EMPTY_RATE_LIMIT };\n this.body = opts.body;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** 400 — missing_parameter, invalid_parameter, instance_required */\nexport class BadRequestError extends CabalSpyIDError {}\n/** 401 — missing_api_key */\nexport class AuthenticationError extends CabalSpyIDError {}\n/** 403 — invalid_api_key, product_not_enabled, no_instance, scope_not_allowed */\nexport class PermissionError extends CabalSpyIDError {}\n/**\n * 403 — plan_user_limit. The person signed in beyond the plan's user limit:\n * the platform receives no data for them until it upgrades.\n */\nexport class PlanUserLimitError extends PermissionError {\n readonly limited = true as const;\n}\n/** 404 — profile_not_found, wallet_not_found, instance_not_found */\nexport class NotFoundError extends CabalSpyIDError {}\n/** 429 — rate_limit_exceeded */\nexport class RateLimitError extends CabalSpyIDError {\n /** Seconds until the next request is allowed, taken from Retry-After. */\n readonly retryAfter: number | null;\n constructor(message: string, opts: CabalSpyIDErrorOptions & { retryAfter?: number | null } = {}) {\n super(message, opts);\n this.retryAfter = opts.retryAfter ?? null;\n }\n}\n/** 5xx — internal_error, service_unavailable */\nexport class ServerError extends CabalSpyIDError {}\n/** Network failure, timeout or aborted connection. */\nexport class ConnectionError extends CabalSpyIDError {}\n/** Response was not valid JSON, or did not have the expected envelope. */\nexport class InvalidResponseError extends CabalSpyIDError {}\n\n/**\n * An error from the OpenID Connect endpoints (`/oauth/token`, `/oauth/userinfo`,\n * `/oauth/revoke`) or from the authorization redirect, in OAuth's own format:\n * `code` is the OAuth `error` (invalid_grant, invalid_client, access_denied …).\n */\nexport class OAuthError extends CabalSpyIDError {\n readonly error: string;\n readonly errorDescription?: string;\n constructor(error: string, description?: string, opts: CabalSpyIDErrorOptions = {}) {\n super(description ? `${error}: ${description}` : error, { ...opts, code: error });\n this.error = error;\n this.errorDescription = description;\n }\n}\n\n/** An ID or access token failed verification (signature, iss, aud, exp, nonce …). */\nexport class TokenVerificationError extends CabalSpyIDError {}\n\n/** A webhook failed signature or timestamp verification. */\nexport class WebhookVerificationError extends CabalSpyIDError {}\n\n/** Maps an HTTP status and Data API error body onto the right error class. */\nexport function errorFromStatus(\n status: number,\n body: ApiErrorBody | null,\n rateLimit: RateLimitInfo,\n retryAfter: number | null,\n fallbackMessage: string,\n): CabalSpyIDError {\n const opts: CabalSpyIDErrorOptions = {\n status,\n code: body?.code ?? `http_${status}`,\n requestId: body?.request_id,\n docs: body?.docs,\n parameter: body?.parameter,\n allowed: body?.allowed,\n rateLimit,\n body: body ?? undefined,\n };\n const msg = body?.message ?? fallbackMessage;\n\n if (status === 400) return new BadRequestError(msg, opts);\n if (status === 401) return new AuthenticationError(msg, opts);\n if (status === 403) {\n return body?.code === 'plan_user_limit' ? new PlanUserLimitError(msg, opts) : new PermissionError(msg, opts);\n }\n if (status === 404) return new NotFoundError(msg, opts);\n if (status === 429) return new RateLimitError(msg, { ...opts, retryAfter });\n if (status >= 500) return new ServerError(msg, opts);\n return new CabalSpyIDError(msg, opts);\n}\n\nexport function isRetryable(err: unknown): boolean {\n return err instanceof RateLimitError || err instanceof ServerError || err instanceof ConnectionError;\n}\n","/**\r\n * Response shapes of the CabalSpy ID Data API, derived from the server source.\r\n *\r\n * Every object type keeps an index signature-free shape for editor help, but\r\n * the server may add fields later; nothing is stripped at runtime.\r\n *\r\n * Timestamps are ISO 8601 UTC strings (\"2026-10-12T08:00:00Z\"), except\r\n * `PnlCalendarDay.date`, which is \"DD-MM-YY\" like the CabalSpy API.\r\n */\r\n\r\nexport const CHAINS = ['solana', 'bnb', 'base', 'eth', 'rh'] as const;\r\n/** solana, bnb (BNB Chain), base, eth (Ethereum), rh (Robinhood Chain). */\r\nexport type Chain = (typeof CHAINS)[number];\r\n\r\nexport const PERIODS = ['6h', '1d', '7d', '30d'] as const;\r\nexport type Period = (typeof PERIODS)[number];\r\n\r\nexport const LEADERBOARD_SORTS = ['volume', 'pnl', 'pnl_usd', 'win_rate', 'trades'] as const;\r\nexport type LeaderboardSort = (typeof LEADERBOARD_SORTS)[number];\r\n\r\nexport type Currency = 'SOL' | 'BNB' | 'ETH';\r\nexport type Scope = 'instance' | 'global';\r\n\r\nexport const CURRENCY_BY_CHAIN: Record<Chain, Currency> = {\r\n solana: 'SOL',\r\n bnb: 'BNB',\r\n base: 'ETH',\r\n eth: 'ETH',\r\n rh: 'ETH',\r\n};\r\n\r\n// ── envelope ────────────────────────────────────────────────────────────────\r\n\r\nexport interface ResponseMeta {\r\n request_id: string;\r\n cached: boolean;\r\n cache_age_seconds: number;\r\n version: string;\r\n timestamp: string;\r\n}\r\n\r\nexport interface Pagination {\r\n limit: number;\r\n /** Absent on /wallets/history, `null` on /transactions/latest. */\r\n total?: number | null;\r\n has_more: boolean;\r\n next_cursor: string | null;\r\n}\r\n\r\n/** Shape of every successful Data API response. */\r\nexport interface ApiResponse<T> {\r\n success: true;\r\n data: T;\r\n pagination?: Pagination;\r\n meta: ResponseMeta;\r\n}\r\n\r\n// ── account ─────────────────────────────────────────────────────────────────\r\n\r\nexport interface HealthResponse {\r\n status: 'ok' | 'degraded';\r\n /** Seconds since the last trade sync; `null` when unknown. */\r\n trade_sync_age_seconds: number | null;\r\n}\r\n\r\nexport interface MeResponse {\r\n /** The registrable domain of a live instance, else the client_id. */\r\n instance: string;\r\n client_id: string;\r\n mode: 'sandbox' | 'development' | 'live';\r\n /** free | starter | pro | business | enterprise, or \"development\" for non-live apps. */\r\n plan: string;\r\n /** Requests per second; `null` = unlimited. */\r\n rate_limit_rps: number | null;\r\n /** Whether the key may open the live stream (Pro plan and up). */\r\n websockets: boolean;\r\n /** Whether `scope=global` is available (Enterprise). */\r\n global_scope: boolean;\r\n users_with_data: number;\r\n}\r\n\r\n// ── users ───────────────────────────────────────────────────────────────────\r\n\r\nexport interface VerifiedWallet {\r\n address: string;\r\n /** \"solana\" or \"evm\". */\r\n family: string;\r\n chains: Chain[];\r\n verified_at: string | null;\r\n}\r\n\r\nexport interface Profile {\r\n /** The user's id: the `sub` of their ID token. */\r\n csid_id: string;\r\n /** X handle; for people without X `tg.<telegram name>` (signed in with Telegram) or `id.<hex>` (signed in with Google). X handles never contain a dot. */\r\n username: string;\r\n name: string | null;\r\n image_url: string | null;\r\n bio: string | null;\r\n /** https://x.com/<handle>; `null` for people without X. */\r\n twitter: string | null;\r\n /** https://t.me/<name> when Telegram is connected, else an empty string. */\r\n telegram: string;\r\n /** X stats; `null` for people who signed in with Telegram or Google and have not connected X. */\r\n x: {\r\n id: string;\r\n followers: number | null;\r\n following: number | null;\r\n verified: boolean | null;\r\n verified_type: string | null;\r\n } | null;\r\n kol: { badge: boolean; since: string | null };\r\n profile_url: string;\r\n wallets: VerifiedWallet[];\r\n joined_at: string | null;\r\n}\r\n\r\nexport interface WalletLookupResponse {\r\n address: string;\r\n verified: true;\r\n wallet: VerifiedWallet | null;\r\n owner: Omit<Profile, 'wallets'>;\r\n}\r\n\r\n// ── trading ─────────────────────────────────────────────────────────────────\r\n\r\n/** Trader block on trading responses. */\r\nexport interface TraderProfile {\r\n csid_id: string;\r\n /** X handle; for people without X `tg.<telegram name>` (signed in with Telegram) or `id.<hex>` (signed in with Google). X handles never contain a dot. */\r\n username: string;\r\n name: string | null;\r\n image_url: string | null;\r\n /** https://x.com/<handle>; `null` for people without X. */\r\n twitter: string | null;\r\n /** https://t.me/<name> when Telegram is connected, else an empty string. */\r\n telegram: string;\r\n blockchain: Chain;\r\n currency: Currency;\r\n type: 'csid';\r\n kol: boolean;\r\n /** e.g. \"13:00-22:00 UTC\"; empty when there were no trades in 30 days. */\r\n active_hours: string;\r\n profile_url: string;\r\n wallet_address?: string;\r\n}\r\n\r\nexport interface PeriodStats {\r\n period: Period;\r\n total_buy: number;\r\n total_buy_usd: number;\r\n total_sell: number;\r\n total_sell_usd: number;\r\n volume: number;\r\n volume_usd: number;\r\n /** Cash flow inside the window: sells minus buys. */\r\n realized_pnl: number;\r\n realized_pnl_usd: number;\r\n realized_pnl_percentage: number;\r\n buy_txn: number;\r\n sell_txn: number;\r\n largest_buy: number;\r\n best_trade_pnl: number;\r\n worst_trade_pnl: number;\r\n win_count: number;\r\n loss_count: number;\r\n avg_hold_time_minutes: number;\r\n}\r\n\r\nexport interface WinRateBuckets {\r\n above_500: number;\r\n above_100_to_500: number;\r\n above_zero_to_100: number;\r\n below_zero: number;\r\n}\r\n\r\nexport interface WinRateDistribution extends WinRateBuckets {\r\n win_count: number;\r\n closed_count: number;\r\n win_rate_percentage: number;\r\n}\r\n\r\nexport interface ActiveTokens {\r\n active_tokens_count: number;\r\n avg_position_size: number;\r\n still_holding_count: number;\r\n}\r\n\r\nexport interface HistoryToken {\r\n mint: string;\r\n token_name: string | null;\r\n token_symbol: string | null;\r\n token_logo: string | null;\r\n buy_value: number;\r\n buy_value_usd: number;\r\n sell_value: number;\r\n sell_value_usd: number;\r\n buy_tokens: number;\r\n sell_tokens: number;\r\n realized_pnl: number;\r\n realized_pnl_usd: number;\r\n realized_pnl_percentage: number;\r\n currency: Currency;\r\n remaining_tokens: number;\r\n}\r\n\r\nexport interface PnlChartPoint {\r\n timestamp: string;\r\n realized_pnl: number;\r\n realized_pnl_usd: number;\r\n}\r\n\r\nexport interface TrackerTrade {\r\n mint: string;\r\n token_name: string | null;\r\n token_logo: string | null;\r\n transaction_type: 'buy' | 'sell';\r\n buy_token: null;\r\n sell_token: null;\r\n buy_value?: number;\r\n buy_value_usd?: number;\r\n sell_value?: number;\r\n sell_value_usd?: number;\r\n token_amount: number | null;\r\n created_at: string;\r\n tx_signature: string;\r\n}\r\n\r\nexport interface TrackerResponse {\r\n wallet: string;\r\n profile: TraderProfile;\r\n period_stats: PeriodStats;\r\n period_win_rate_distribution: WinRateDistribution;\r\n period_active_tokens: ActiveTokens;\r\n period_history_tokens: HistoryToken[];\r\n /** Cumulative realized PnL, starts at 0, one point every 15 minutes. */\r\n period_realized_pnl_chart: PnlChartPoint[];\r\n period_trades: TrackerTrade[];\r\n}\r\n\r\nexport interface LifetimeStats {\r\n buy: number;\r\n sell: number;\r\n realized_pnl: number;\r\n realized_pnl_percentage: number;\r\n buy_txn: number;\r\n sell_txn: number;\r\n total_tx_count: number;\r\n win_count: number;\r\n total_sold: number;\r\n win_rate: number;\r\n active_tokens_count: number;\r\n largest_buy: number;\r\n best_trade_pnl: number;\r\n worst_trade_pnl: number;\r\n still_holding_count: number;\r\n}\r\n\r\nexport interface TokenOverview {\r\n mint: string;\r\n token_name: string | null;\r\n token_logo: string | null;\r\n invested: number;\r\n sold: number;\r\n realized_pnl: number;\r\n realized_pnl_percentage: number;\r\n currency: Currency;\r\n buy_txn: number;\r\n sell_txn: number;\r\n first_seen: string;\r\n last_seen: string;\r\n still_holding: boolean;\r\n}\r\n\r\nexport interface HistoryTrade {\r\n tx_signature: string;\r\n mint: string;\r\n token_name: string | null;\r\n token_logo: string | null;\r\n transaction_type: 'buy' | 'sell';\r\n value: number;\r\n value_usd: number;\r\n currency: Currency;\r\n created_at: string;\r\n}\r\n\r\nexport interface HistoryResponse {\r\n lifetime_stats: LifetimeStats;\r\n win_rate_distribution: WinRateBuckets;\r\n token_overview: TokenOverview[];\r\n /** One page of trades, newest first. */\r\n trades: HistoryTrade[];\r\n profile: TraderProfile;\r\n}\r\n\r\nexport interface HoldingToken {\r\n token_address: string | null;\r\n token_name: string | null;\r\n symbol: string | null;\r\n logo: string | null;\r\n amount: string;\r\n amount_formatted: string;\r\n decimals: number | null;\r\n price_usd: number;\r\n value_usd: number;\r\n verified_contract: boolean | null;\r\n avg_buy_price_usd?: number | null;\r\n unrealized_pnl_usd?: number | null;\r\n}\r\n\r\nexport interface HoldingsResponse {\r\n wallet: string;\r\n blockchain: Chain;\r\n profile: TraderProfile;\r\n active_holdings: {\r\n tokens: HoldingToken[];\r\n count: number;\r\n total_value_usd: number;\r\n last_updated: string;\r\n stale: boolean;\r\n loading: boolean;\r\n };\r\n}\r\n\r\nexport interface PnlCalendarDay {\r\n /** \"DD-MM-YY\" */\r\n date: string;\r\n realized_pnl: number;\r\n realized_pnl_usd: number;\r\n buy_txn: number;\r\n sell_txn: number;\r\n txn_total: number;\r\n tokens_traded: number;\r\n volume: number;\r\n total_buy: number;\r\n total_sell: number;\r\n total_buy_usd: number;\r\n total_sell_usd: number;\r\n}\r\n\r\nexport interface PnlCalendarMonth {\r\n month: number;\r\n year: number;\r\n dates: PnlCalendarDay[];\r\n realized_pnl: number;\r\n realized_pnl_usd: number;\r\n volume: number;\r\n total_buy: number;\r\n total_buy_usd: number;\r\n total_sell: number;\r\n total_sell_usd: number;\r\n buy_txn: number;\r\n sell_txn: number;\r\n txn_total: number;\r\n tokens_traded: number;\r\n positive_streak: number;\r\n negative_streak: number;\r\n /** Only on the current month. */\r\n current_positive_streak?: number;\r\n current_negative_streak?: number;\r\n}\r\n\r\nexport interface PnlCalendarResponse {\r\n wallet: string;\r\n profile: TraderProfile;\r\n /** Oldest first. */\r\n months: PnlCalendarMonth[];\r\n /** Days of the current month. */\r\n dates: PnlCalendarDay[];\r\n month: PnlCalendarMonth | null;\r\n}\r\n\r\nexport interface LeaderboardEntry {\r\n rank: number;\r\n wallet: string;\r\n profile: {\r\n csid_id: string;\r\n username: string;\r\n name: string | null;\r\n image_url: string | null;\r\n /** https://x.com/<handle>; `null` for people without X. */\r\n twitter: string | null;\r\n /** https://t.me/<name> when Telegram is connected, else an empty string. */\r\n telegram: string;\r\n blockchain: Chain;\r\n currency: Currency;\r\n wallet_type: 'csid';\r\n kol: boolean;\r\n public_trading: boolean;\r\n };\r\n period_stats: {\r\n period: Period;\r\n total_buy: number;\r\n total_buy_usd: number;\r\n total_sell: number;\r\n total_sell_usd: number;\r\n total_volume: number;\r\n total_volume_usd: number;\r\n realized_pnl: number;\r\n realized_pnl_usd: number;\r\n realized_pnl_percentage: number;\r\n avg_hold_time_minutes: number;\r\n total_txn: number;\r\n buy_txn: number;\r\n sell_txn: number;\r\n };\r\n period_win_rate_distribution: { win_count: number; closed_count: number; win_rate_percentage: number };\r\n period_history_tokens: { total_tokens: number };\r\n}\r\n\r\nexport interface LeaderboardResponse {\r\n blockchain: Chain;\r\n type: 'csid';\r\n scope: Scope;\r\n period: Period;\r\n sort: LeaderboardSort;\r\n currency: Currency;\r\n /** The leaderboard paginates inside `data`. */\r\n pagination: Pagination;\r\n leaderboard: LeaderboardEntry[];\r\n}\r\n\r\n/** Trader summary attached to trades. */\r\nexport interface TradeOwner {\r\n csid_id: string;\r\n username: string;\r\n name: string | null;\r\n image_url: string | null;\r\n kol: boolean;\r\n}\r\n\r\n/** One trade, from /transactions/latest and the live stream. */\r\nexport interface Trade {\r\n signature: string;\r\n blockchain: Chain;\r\n wallet: string;\r\n mint: string;\r\n transaction_type: 'buy' | 'sell';\r\n token_symbol: string | null;\r\n token_name: string | null;\r\n token_logo: string | null;\r\n token_amount: number | null;\r\n value: number;\r\n value_usd: number;\r\n currency: Currency;\r\n timestamp: string;\r\n trader: TradeOwner | null;\r\n}\r\n\r\n// ── OpenID Connect ──────────────────────────────────────────────────────────\r\n\r\n/**\r\n * `thesis` lets your app post theses and replies, react and report in the\r\n * user's name (Data API writes with `csid_id`, or the public thesis API and\r\n * the thesis widget with the user's access token).\r\n */\r\nexport type OidcScope = 'openid' | 'profile' | 'wallets' | 'onchain' | 'thesis' | 'offline_access';\r\n\r\nexport interface XProfileClaim {\r\n id: string;\r\n username: string;\r\n followers: number | null;\r\n following: number | null;\r\n posts: number | null;\r\n listed: number | null;\r\n verified: boolean | null;\r\n verified_type: string | null;\r\n created_at: string | null;\r\n fetched_at: string;\r\n}\r\n\r\nexport interface WalletClaim {\r\n address: string;\r\n family: string;\r\n chains: Chain[];\r\n verified_at: string | null;\r\n}\r\n\r\n/**\r\n * Claims of an ID token or a userinfo response.\r\n *\r\n * When the platform is over its plan's user limit, `sub` is an anonymous\r\n * `anon_…` id, `limited` is true and no profile or wallet data is included.\r\n */\r\nexport interface CabalSpyIDClaims {\r\n sub: string;\r\n iss?: string;\r\n aud?: string;\r\n azp?: string;\r\n exp?: number;\r\n iat?: number;\r\n auth_time?: number;\r\n nonce?: string;\r\n name?: string | null;\r\n /** X handle; for people without X `tg.<telegram name>` (signed in with Telegram) or `id.<hex>` (signed in with Google). X handles never contain a dot. */\r\n preferred_username?: string;\r\n picture?: string | null;\r\n /** https://id.cabalspy.xyz/u/<username> */\r\n profile?: string;\r\n kol_badge?: boolean;\r\n /**\r\n * Full X profile, userinfo only (scope `profile`). `null` for people who signed\r\n * in with Telegram or Google and have not connected X. See hasX().\r\n */\r\n x?: XProfileClaim | null;\r\n /** Verified wallets, userinfo only (scope `wallets`). */\r\n wallets?: WalletClaim[];\r\n /** Latest 7-day on-chain volume, userinfo only (scope `onchain`). */\r\n onchain?: { volume_7d_usd: number; checked_at: string } | null;\r\n /** A made-up sandbox identity; never trust it in production. */\r\n sandbox?: boolean;\r\n /** True when the platform is over its plan's user limit. */\r\n limited?: boolean;\r\n reason?: 'plan_user_limit' | string;\r\n message?: string;\r\n [claim: string]: unknown;\r\n}\r\n\r\nexport interface TokenResponse {\r\n access_token: string;\r\n token_type: 'Bearer';\r\n /** Seconds. Access and ID tokens live 15 minutes. */\r\n expires_in: number;\r\n id_token: string;\r\n scope: string;\r\n /** Only with the `offline_access` scope. Rotates on every refresh. */\r\n refresh_token?: string;\r\n}\r\n\r\nexport interface DiscoveryDocument {\r\n issuer: string;\r\n authorization_endpoint: string;\r\n token_endpoint: string;\r\n userinfo_endpoint: string;\r\n jwks_uri: string;\r\n revocation_endpoint: string;\r\n scopes_supported: string[];\r\n response_types_supported: string[];\r\n grant_types_supported: string[];\r\n id_token_signing_alg_values_supported: string[];\r\n token_endpoint_auth_methods_supported: string[];\r\n code_challenge_methods_supported: string[];\r\n claims_supported: string[];\r\n [key: string]: unknown;\r\n}\r\n\r\n// ── webhooks ────────────────────────────────────────────────────────────────\r\n\r\nexport type WebhookEventType =\r\n | 'wallet.verified'\r\n | 'wallet.removed'\r\n | 'profile.updated'\r\n | 'kol.granted'\r\n | 'consent.revoked'\r\n | 'thesis.created'\r\n | 'thesis.reply'\r\n | 'thesis.reaction'\r\n | 'webhook.test';\r\n\r\nexport interface WebhookEvent<D = Record<string, unknown>> {\r\n /** Event id; the same on every retry. Dedupe on it. */\r\n id: string;\r\n type: WebhookEventType | string;\r\n created_at: string;\r\n sandbox: boolean;\r\n /** Always carries `sub` (the user's CabalSpy ID), except for webhook.test. */\r\n data: D & { sub?: string };\r\n}\r\n\r\n/** `data` of a `thesis.created` webhook: one of your users posted a thesis. */\r\nexport interface ThesisCreatedData {\r\n sub: string;\r\n thesis: Thesis;\r\n}\r\n\r\n/** `data` of a `thesis.reply` webhook: one of your users replied to a thesis. */\r\nexport interface ThesisReplyData {\r\n sub: string;\r\n reply: Thesis;\r\n}\r\n\r\n/** `data` of a `thesis.reaction` webhook: one of your users added or removed a reaction. */\r\nexport interface ThesisReactionData {\r\n sub: string;\r\n thesis_id: string;\r\n chain: Chain;\r\n mint: string;\r\n emoji: ThesisEmoji | string;\r\n /** true: added, false: removed. */\r\n on: boolean;\r\n /** The new counts. */\r\n reactions: Partial<Record<ThesisEmoji | string, number>>;\r\n}\r\n\r\n// ── token theses ────────────────────────────────────────────────────────────\r\n\r\nexport type ThesisStance = 'bull' | 'bear';\r\nexport type ThesisSort = 'new' | 'top';\r\n\r\n/** Reactions: `like` plus a fixed emoji set. */\r\nexport const THESIS_EMOJIS = ['like', '🔥', '🚀', '💎', '👀', '😂', '🤝', '💀', '🐂', '🐻'] as const;\r\nexport type ThesisEmoji = (typeof THESIS_EMOJIS)[number];\r\n\r\nexport const THESIS_REPORT_REASONS = ['spam', 'scam', 'abuse', 'impersonation', 'other'] as const;\r\nexport type ThesisReportReason = (typeof THESIS_REPORT_REASONS)[number];\r\n\r\n/** Maximum thesis / reply length in characters. */\r\nexport const THESIS_MAX_BODY = 1000;\r\n\r\nexport interface ThesisAuthor {\r\n csid_id: string;\r\n /** X handle; for people without X `tg.<telegram name>` (signed in with Telegram) or `id.<hex>` (signed in with Google). X handles never contain a dot. */\r\n username: string | null;\r\n name: string | null;\r\n image_url: string | null;\r\n kol_badge: boolean;\r\n profile_url: string | null;\r\n}\r\n\r\nexport interface ThesisPnl {\r\n invested_usd: number;\r\n realized_usd: number;\r\n holding_value_usd: number | null;\r\n pnl_usd: number | null;\r\n pnl_percent: number | null;\r\n}\r\n\r\n/** The author's real position in the token, when they show their trading publicly. */\r\nexport interface ThesisPositionPublic {\r\n /** What was bought and sold when the thesis was posted. */\r\n at_post: ThesisPnl & { tokens_held: number | null; first_buy: string | null };\r\n /** Live: PnL now, and whether the author still holds or sold. */\r\n now: (ThesisPnl & { tokens_held: number; status: 'holding' | 'sold' }) | null;\r\n}\r\n\r\n/** The author keeps their trading private: only that they hold the token. */\r\nexport interface ThesisPositionPrivate {\r\n private: true;\r\n}\r\n\r\nexport type ThesisPosition = ThesisPositionPublic | ThesisPositionPrivate;\r\n\r\n/** Who reacted recently (newest first). */\r\nexport interface ThesisReactor {\r\n emoji: ThesisEmoji | string;\r\n csid_id: string;\r\n username: string | null;\r\n at: string;\r\n}\r\n\r\n/** A thesis (`kind: 'thesis'`) or a reply to one (`kind: 'reply'`). */\r\nexport interface Thesis {\r\n id: string;\r\n chain: Chain;\r\n mint: string;\r\n kind: 'thesis' | 'reply';\r\n /** The thesis a reply belongs to. */\r\n parent_id: string | null;\r\n body: string;\r\n stance: ThesisStance | null;\r\n author: ThesisAuthor;\r\n likes: number;\r\n replies: number;\r\n /** Count per reaction, e.g. { like: 3, '🚀': 1 }. */\r\n reactions: Partial<Record<ThesisEmoji | string, number>>;\r\n /** The latest reactions with who reacted, newest first. */\r\n reacted_by: ThesisReactor[];\r\n /** The viewer's own reactions (pass `csid_id` / an access token to get them). */\r\n my_reactions: string[];\r\n /** Name of the app it was posted through. */\r\n via: string | null;\r\n created_at: string;\r\n is_mine: boolean;\r\n /** Theses only (not replies). */\r\n position?: ThesisPosition;\r\n /** Theses only: a preview of the newest replies, oldest first. */\r\n latest_replies?: Thesis[];\r\n}\r\n\r\nexport interface ThesisToken {\r\n chain: Chain;\r\n mint: string;\r\n name: string | null;\r\n symbol: string | null;\r\n logo: string | null;\r\n price_usd: number | null;\r\n}\r\n\r\nexport interface ThesisCounts {\r\n theses: number;\r\n bull: number;\r\n bear: number;\r\n authors: number;\r\n}\r\n\r\nexport interface ThesisSummary extends ThesisCounts {\r\n token: ThesisToken;\r\n}\r\n\r\nexport interface ThesisEligibility {\r\n /** Holders only: one of the user's verified wallets bought and still holds the token. */\r\n can_post: boolean;\r\n can_reply: boolean;\r\n holder: boolean | null;\r\n /** Posting paused after several hidden posts. */\r\n paused: boolean;\r\n /** Data API: why the user can't write for your app (consent_required, plan_user_limit, sandbox_user). */\r\n reason?: string;\r\n}\r\n\r\n/** Moderation notification kinds. */\r\nexport type ThesisNotificationKind =\r\n | 'post_hidden'\r\n | 'paused'\r\n | 'banned'\r\n | 'post_removed'\r\n | 'post_restored'\r\n | 'appeal_accepted'\r\n | 'appeal_rejected'\r\n | 'reporting_paused';\r\n\r\n/** A moderation notification (warning, hidden post, pause, appeal result …). */\r\nexport interface ThesisNotification {\r\n id: number;\r\n kind: ThesisNotificationKind | string;\r\n /** Ready-to-show English text. */\r\n text: string;\r\n /** Details, e.g. thesis_id, until, note. */\r\n data: Record<string, unknown>;\r\n created_at: string;\r\n read: boolean;\r\n /** Can be appealed (within 30 days). */\r\n appealable: boolean;\r\n /** Appeal status when appealed: pending | accepted | rejected; null otherwise. */\r\n appeal: 'pending' | 'accepted' | 'rejected' | string | null;\r\n}\r\n\r\nexport interface ThesisNotifications {\r\n unread: number;\r\n items: ThesisNotification[];\r\n}\r\n\r\n/** Unread moderation notices of the signed-in user (public API `me()`). */\r\nexport interface ThesisNotices {\r\n unread: number;\r\n /** Text of the newest notice when there are unread ones. */\r\n latest: string | null;\r\n /** Where the user reads all notices on id.cabalspy.xyz. */\r\n url: string;\r\n}\r\n\r\nexport interface ThesisReactions {\r\n id: string;\r\n reactions: Partial<Record<ThesisEmoji | string, number>>;\r\n}\r\n\r\n/** Stream / live payload of a new thesis or reply. */\r\nexport type ThesisLiveItem = Thesis & { blockchain?: Chain };\r\n/** Stream / live payload of a removed (deleted or hidden) post. */\r\nexport interface ThesisRemoved {\r\n id: string;\r\n blockchain?: Chain;\r\n mint?: string;\r\n}\r\n/** Stream / live payload of changed reaction counts. */\r\nexport type ThesisReactionUpdate = ThesisReactions & { blockchain?: Chain; mint?: string };\r\n","// ═══════════════════════════════════════════════════════════════════════════\n// LIVE STREAM — wss://api-id.cabalspy.xyz/v1/stream (Pro plan and up)\n// ═══════════════════════════════════════════════════════════════════════════\n\nimport {\n BadRequestError,\n CabalSpyIDError,\n ConnectionError,\n PermissionError,\n RateLimitError,\n} from './errors';\nimport {\n CHAINS,\n type Chain,\n type Scope,\n type ThesisLiveItem,\n type ThesisReactionUpdate,\n type ThesisRemoved,\n type Trade,\n} from './types';\n\n/** `trades`: your users' trades. `theses`: new theses, replies, reactions and removals (public, all users). */\nexport type StreamTopic = 'trades' | 'theses';\n\nexport interface StreamOptions {\n /** What to receive. Default: ['trades'] */\n events?: StreamTopic[];\n /** Only this chain. Default: every chain. */\n blockchain?: Chain;\n /** Theses of one token only (needs `blockchain`). */\n mint?: string;\n /** `global` (every CabalSpy ID user) is Enterprise only. Default: instance */\n scope?: Scope;\n /** Instance client_id, when your account has several. */\n instance?: string;\n /** Reconnect automatically after a dropped connection. Default: true */\n reconnect?: boolean;\n /** Initial reconnect delay in ms, doubling up to maxReconnectDelay. Default: 1000 */\n reconnectDelay?: number;\n /** Default: 30_000 */\n maxReconnectDelay?: number;\n /**\n * The server sends a heartbeat every 30 s. When nothing at all arrives for\n * this many ms, the connection is treated as dead and reopened.\n * 0 disables the check. Default: 75_000\n */\n heartbeatTimeout?: number;\n /**\n * WebSocket implementation. Browsers, Deno, Bun and Node 22+ have a global\n * WebSocket. On Node 18-21, `npm i ws` and pass `{ WebSocketImpl: WebSocket }`.\n */\n WebSocketImpl?: unknown;\n}\n\nexport interface SubscribedEvent {\n blockchain: Chain | 'all';\n scope: Scope;\n events?: StreamTopic[];\n mint?: string | null;\n}\n\nexport interface HeartbeatEvent {\n ts: number;\n}\n\nexport interface CloseEvent {\n code?: number;\n reason?: string;\n}\n\nexport interface ReconnectEvent {\n attempt: number;\n delay: number;\n}\n\nexport interface StreamEventMap {\n trade: Trade;\n /** A new thesis (events: theses). */\n thesis: ThesisLiveItem;\n /** A new reply to a thesis. */\n 'thesis.reply': ThesisLiveItem;\n /** Reaction counts of a thesis or reply changed. */\n 'thesis.reaction': ThesisReactionUpdate;\n /** A thesis or reply was deleted or hidden. */\n 'thesis.removed': ThesisRemoved;\n subscribed: SubscribedEvent;\n heartbeat: HeartbeatEvent;\n pong: Record<string, never>;\n open: undefined;\n close: CloseEvent;\n reconnecting: ReconnectEvent;\n error: CabalSpyIDError;\n /** Every parsed message, before dispatch. */\n message: Record<string, unknown>;\n}\n\nexport type StreamEvent = keyof StreamEventMap;\ntype Handler<T> = (payload: T) => void;\n\ninterface MinimalWebSocket {\n send(data: string): void;\n close(code?: number, reason?: string): void;\n readyState: number;\n onopen: ((ev: unknown) => void) | null;\n onclose: ((ev: unknown) => void) | null;\n onerror: ((ev: unknown) => void) | null;\n onmessage: ((ev: { data: unknown }) => void) | null;\n}\n\n/** Server error codes that will not go away by reconnecting. */\nconst FATAL_CODES = new Set([\n 'invalid_api_key',\n 'plan_required',\n 'invalid_parameter',\n 'missing_parameter',\n 'scope_not_allowed',\n 'product_not_enabled',\n]);\n\nfunction streamError(code: string, message: string): CabalSpyIDError {\n const opts = { code };\n if (code === 'invalid_parameter' || code === 'missing_parameter') return new BadRequestError(message, { ...opts, status: 400 });\n if (code === 'too_many_connections') return new RateLimitError(message, { ...opts, status: 429 });\n if (FATAL_CODES.has(code)) return new PermissionError(message, { ...opts, status: 403 });\n return new CabalSpyIDError(message, opts);\n}\n\n/**\n * WebSocket client for the live trade stream.\n *\n * const stream = csid.stream({ blockchain: 'solana' });\n * stream.on('trade', (t) => console.log(t.trader?.username, t.transaction_type, t.value_usd));\n * await stream.connect(); // resolves once the server confirmed the subscription\n *\n * or as an async iterator:\n *\n * for await (const trade of csid.stream()) { … }\n *\n * Reconnects with exponential backoff after a dropped connection or a missed\n * heartbeat. Configuration errors from the server (invalid key, plan without\n * the stream, …) are fatal: they are emitted as 'error' and stop reconnecting.\n */\nexport class CabalSpyIDStream {\n private ws: MinimalWebSocket | null = null;\n private readonly opts: Required<Omit<StreamOptions, 'WebSocketImpl' | 'blockchain' | 'scope' | 'instance' | 'events' | 'mint'>>;\n private readonly handlers = new Map<string, Set<Handler<never>>>();\n private reconnectAttempt = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private watchdog: ReturnType<typeof setTimeout> | null = null;\n private closedByUser = false;\n private fatal: CabalSpyIDError | null = null;\n\n constructor(\n private readonly url: string,\n private readonly apiKey: string,\n private readonly options: StreamOptions = {},\n ) {\n const events = options.events ?? ['trades'];\n if (!events.length || events.some((e) => e !== 'trades' && e !== 'theses')) {\n throw new BadRequestError(\"events must contain 'trades' and/or 'theses'\", {\n code: 'invalid_parameter',\n parameter: 'events',\n allowed: ['trades', 'theses'],\n });\n }\n if (options.mint && !options.blockchain) {\n throw new BadRequestError('mint needs blockchain', { code: 'missing_parameter', parameter: 'blockchain' });\n }\n if (options.blockchain && !(CHAINS as readonly string[]).includes(options.blockchain)) {\n throw new BadRequestError(`Unknown blockchain '${options.blockchain}'`, {\n code: 'invalid_parameter',\n parameter: 'blockchain',\n allowed: [...CHAINS],\n });\n }\n this.opts = {\n reconnect: options.reconnect ?? true,\n reconnectDelay: options.reconnectDelay ?? 1_000,\n maxReconnectDelay: options.maxReconnectDelay ?? 30_000,\n heartbeatTimeout: options.heartbeatTimeout ?? 75_000,\n };\n }\n\n /** True while the socket is open. */\n get connected(): boolean {\n return this.ws?.readyState === 1;\n }\n\n /** The stream URL including query parameters, with the key masked. */\n get safeUrl(): string {\n return this.buildUrl('***');\n }\n\n private buildUrl(key: string): string {\n const sp = new URLSearchParams({ api_key: key });\n if (this.options.events) sp.set('events', [...new Set(this.options.events)].join(','));\n if (this.options.blockchain) sp.set('blockchain', this.options.blockchain);\n if (this.options.mint) sp.set('mint', this.options.mint);\n if (this.options.scope) sp.set('scope', this.options.scope);\n if (this.options.instance) sp.set('instance', this.options.instance);\n return `${this.url}?${sp.toString()}`;\n }\n\n on<E extends StreamEvent>(event: E, handler: Handler<StreamEventMap[E]>): this {\n let set = this.handlers.get(event);\n if (!set) {\n set = new Set();\n this.handlers.set(event, set);\n }\n set.add(handler as Handler<never>);\n return this;\n }\n\n off<E extends StreamEvent>(event: E, handler: Handler<StreamEventMap[E]>): this {\n this.handlers.get(event)?.delete(handler as Handler<never>);\n return this;\n }\n\n private emit<E extends StreamEvent>(event: E, payload: StreamEventMap[E]): void {\n const set = this.handlers.get(event);\n if (!set) return;\n for (const h of [...set]) {\n try {\n (h as Handler<StreamEventMap[E]>)(payload);\n } catch (err) {\n // A throwing handler must not take down the connection.\n if (event !== 'error') {\n this.emit('error', err instanceof CabalSpyIDError ? err : new CabalSpyIDError(String((err as Error)?.message ?? err), { code: 'handler_error' }));\n }\n }\n }\n }\n\n /** Opens the socket. Resolves once the server sent `subscribed`. */\n connect(): Promise<SubscribedEvent> {\n this.closedByUser = false;\n this.fatal = null;\n const WS = (this.options.WebSocketImpl ?? (globalThis as { WebSocket?: unknown }).WebSocket) as\n | (new (url: string) => MinimalWebSocket)\n | undefined;\n if (!WS) {\n return Promise.reject(\n new ConnectionError('No WebSocket implementation found. On Node < 22, run `npm i ws` and pass { WebSocketImpl: WebSocket }.', {\n code: 'no_websocket',\n }),\n );\n }\n\n return new Promise<SubscribedEvent>((resolve, reject) => {\n let settled = false;\n const settle = (err: CabalSpyIDError | null, value?: SubscribedEvent) => {\n if (settled) return;\n settled = true;\n if (err) reject(err);\n else resolve(value!);\n };\n\n let ws: MinimalWebSocket;\n try {\n ws = new WS(this.buildUrl(this.apiKey));\n } catch (err) {\n settle(new ConnectionError(`Could not open ${this.safeUrl}: ${(err as Error)?.message ?? err}`, { code: 'ws_error' }));\n return;\n }\n this.ws = ws;\n\n ws.onopen = () => {\n this.armWatchdog();\n this.emit('open', undefined);\n };\n\n ws.onmessage = (ev) => {\n if (this.ws !== ws) return;\n this.armWatchdog();\n let msg: Record<string, unknown>;\n try {\n msg = JSON.parse(typeof ev.data === 'string' ? ev.data : String(ev.data)) as Record<string, unknown>;\n } catch {\n return;\n }\n this.emit('message', msg);\n switch (msg.event) {\n case 'trade':\n this.emit('trade', msg.data as Trade);\n break;\n case 'subscribed': {\n this.reconnectAttempt = 0;\n const data = (msg.data ?? {}) as SubscribedEvent;\n this.emit('subscribed', data);\n settle(null, data);\n break;\n }\n case 'thesis':\n case 'thesis.reply':\n case 'thesis.reaction':\n case 'thesis.removed':\n this.emit(msg.event, msg.data as never);\n break;\n case 'heartbeat':\n this.emit('heartbeat', { ts: Number(msg.ts) });\n break;\n case 'pong':\n this.emit('pong', {});\n break;\n case 'error': {\n const e = (msg.error ?? {}) as { code?: string; message?: string };\n const err = streamError(e.code ?? 'stream_error', e.message ?? 'Stream error');\n if (FATAL_CODES.has(err.code)) this.fatal = err;\n this.emit('error', err);\n settle(err);\n break;\n }\n default:\n break;\n }\n };\n\n ws.onerror = (ev) => {\n if (this.ws !== ws) return;\n const err = new ConnectionError(`WebSocket error on ${this.safeUrl}: ${describeWsEvent(ev)}`, { code: 'ws_error' });\n this.emit('error', err);\n settle(err);\n };\n\n ws.onclose = (ev) => {\n if (this.ws !== ws) return;\n this.clearWatchdog();\n this.ws = null;\n const e = (ev ?? {}) as { code?: number; reason?: string };\n this.emit('close', { code: e.code, reason: e.reason });\n settle(\n new ConnectionError(`Stream closed before it was ready (code ${e.code ?? 'unknown'}${e.reason ? `, ${e.reason}` : ''})`, {\n code: 'ws_closed_early',\n }),\n );\n if (!this.closedByUser && !this.fatal && this.opts.reconnect) this.scheduleReconnect();\n };\n });\n }\n\n private scheduleReconnect(): void {\n const delay = Math.min(this.opts.reconnectDelay * 2 ** this.reconnectAttempt, this.opts.maxReconnectDelay) + Math.random() * 250;\n this.reconnectAttempt++;\n this.emit('reconnecting', { attempt: this.reconnectAttempt, delay });\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n if (this.closedByUser) return;\n this.connect().catch(() => {\n /* reported through 'error'; onclose schedules the next attempt */\n });\n }, delay);\n }\n\n private armWatchdog(): void {\n if (!this.opts.heartbeatTimeout) return;\n this.clearWatchdog();\n this.watchdog = setTimeout(() => {\n // Nothing heard, not even a heartbeat: the connection is dead.\n this.emit('error', new ConnectionError('No heartbeat from the stream; reconnecting', { code: 'heartbeat_timeout' }));\n this.ws?.close(4000, 'heartbeat timeout');\n }, this.opts.heartbeatTimeout);\n }\n\n private clearWatchdog(): void {\n if (this.watchdog) clearTimeout(this.watchdog);\n this.watchdog = null;\n }\n\n /**\n * Sends a ping; the server answers with 'pong'. Not needed to keep the\n * connection alive (the server sends heartbeats), and pinging more often\n * than every 30 s suppresses those heartbeats.\n */\n ping(): void {\n if (this.ws?.readyState === 1) this.ws.send('ping');\n }\n\n /** Closes the connection and stops reconnecting. */\n close(): void {\n this.closedByUser = true;\n this.clearWatchdog();\n if (this.reconnectTimer) clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n const ws = this.ws;\n this.ws = null;\n ws?.close(1000, 'client closed');\n this.emit('close', { code: 1000, reason: 'client closed' });\n }\n\n /**\n * Iterates over trades. Connects if needed; ends when close() is called or\n * a fatal error occurs (which is thrown). Breaking out of the loop closes a\n * connection the iterator opened.\n */\n [Symbol.asyncIterator](): AsyncGenerator<Trade, void, void> {\n return this.iterate<Trade>(['trade'], (_e, d) => d as Trade);\n }\n\n /**\n * Iterates over thesis events (`thesis`, `thesis.reply`, `thesis.reaction`,\n * `thesis.removed`). Open the stream with `events: ['theses']`.\n *\n * for await (const { event, data } of csid.stream({ events: ['theses'] }).theses()) { … }\n */\n theses(): AsyncGenerator<ThesisStreamEvent, void, void> {\n return this.iterate<ThesisStreamEvent>(\n ['thesis', 'thesis.reply', 'thesis.reaction', 'thesis.removed'],\n (event, data) => ({ event, data }) as ThesisStreamEvent,\n );\n }\n\n private async *iterate<T>(\n names: StreamEvent[],\n wrap: (event: StreamEvent, data: unknown) => T,\n ): AsyncGenerator<T, void, void> {\n const queue: T[] = [];\n let wake: (() => void) | null = null;\n let failure: CabalSpyIDError | null = null;\n let done = false;\n const listeners = names.map((name) => {\n const fn = (data: unknown) => {\n queue.push(wrap(name, data));\n wake?.();\n };\n return [name, fn] as const;\n });\n const onError = () => {\n if (this.fatal) {\n failure = this.fatal;\n wake?.();\n }\n };\n const onClose = () => {\n if (this.closedByUser || !this.opts.reconnect) {\n done = true;\n wake?.();\n }\n };\n for (const [name, fn] of listeners) this.on(name, fn as never);\n this.on('error', onError).on('close', onClose);\n const ownsConnection = !this.ws;\n try {\n if (ownsConnection) await this.connect();\n while (true) {\n while (queue.length) yield queue.shift()!;\n if (failure) throw failure;\n if (done) return;\n await new Promise<void>((r) => (wake = r));\n wake = null;\n }\n } finally {\n for (const [name, fn] of listeners) this.off(name, fn as never);\n this.off('error', onError).off('close', onClose);\n // Breaking out of `for await` closes a connection the iterator opened.\n if (ownsConnection && !this.closedByUser) this.close();\n }\n }\n}\n\n/** One thesis event from `stream.theses()`. */\nexport type ThesisStreamEvent =\n | { event: 'thesis'; data: ThesisLiveItem }\n | { event: 'thesis.reply'; data: ThesisLiveItem }\n | { event: 'thesis.reaction'; data: ThesisReactionUpdate }\n | { event: 'thesis.removed'; data: ThesisRemoved };\n\n/** Pulls whatever detail the runtime attached to a websocket error event. */\nfunction describeWsEvent(ev: unknown): string {\n if (!ev || typeof ev !== 'object') return 'no detail available';\n const e = ev as { message?: string; error?: { message?: string; code?: string }; type?: string };\n return e.error?.message ?? e.message ?? (e.error?.code ? `errno ${e.error.code}` : undefined) ?? e.type ?? 'no detail available';\n}\n","// ═══════════════════════════════════════════════════════════════════════════\r\n// THESES STREAM — wss://api-id.cabalspy.xyz/v1/theses/stream (every plan)\r\n// ═══════════════════════════════════════════════════════════════════════════\r\n//\r\n// → {\"op\": \"subscribe\", \"tokens\": [{\"blockchain\": \"solana\", \"mint\": \"…\"}, …]} (up to 200)\r\n// → {\"op\": \"unsubscribe\", \"tokens\": [...]} → {\"op\": \"subscribe\", \"all\": true}\r\n// ← ready, subscribed, thesis, thesis.reply, thesis.reaction, thesis.removed, heartbeat (30 s), error\r\n\r\nimport { BadRequestError, CabalSpyIDError, ConnectionError, PermissionError, RateLimitError } from './errors';\r\nimport type { ThesisStreamEvent } from './stream';\r\nimport {\r\n CHAINS,\r\n type Chain,\r\n type ThesisLiveItem,\r\n type ThesisReactionUpdate,\r\n type ThesisRemoved,\r\n} from './types';\r\n\r\n/** Tokens per connection. */\r\nexport const MAX_THESES_STREAM_TOKENS = 200;\r\n\r\nexport interface ThesisTokenRef {\r\n blockchain: Chain;\r\n mint: string;\r\n}\r\n\r\nexport interface ThesesStreamOptions {\r\n /** `global` (default): theses from every platform. `instance`: only the ones written on your instance. */\r\n scope?: 'global' | 'instance';\r\n /** Instance client_id, when your account has several. */\r\n instance?: string;\r\n /** Default: true */\r\n reconnect?: boolean;\r\n /** Default: 1000 */\r\n reconnectDelay?: number;\r\n /** Default: 30_000 */\r\n maxReconnectDelay?: number;\r\n /** The server sends a heartbeat every 30 s; silence this long reopens the socket. 0 disables. Default: 75_000 */\r\n heartbeatTimeout?: number;\r\n /** WebSocket implementation for Node < 22 (the `ws` package). */\r\n WebSocketImpl?: unknown;\r\n}\r\n\r\nexport interface ThesesReadyEvent {\r\n scope: 'global' | 'instance';\r\n max_tokens: number;\r\n}\r\n\r\nexport interface ThesesSubscribedEvent {\r\n all: boolean;\r\n tokens: ThesisTokenRef[];\r\n}\r\n\r\nexport interface ThesesStreamEventMap {\r\n ready: ThesesReadyEvent;\r\n subscribed: ThesesSubscribedEvent;\r\n thesis: ThesisLiveItem;\r\n 'thesis.reply': ThesisLiveItem;\r\n 'thesis.reaction': ThesisReactionUpdate;\r\n 'thesis.removed': ThesisRemoved;\r\n heartbeat: { ts: number };\r\n pong: Record<string, never>;\r\n open: undefined;\r\n close: { code?: number; reason?: string };\r\n reconnecting: { attempt: number; delay: number };\r\n error: CabalSpyIDError;\r\n}\r\n\r\ntype Handler<T> = (payload: T) => void;\r\n\r\ninterface MinimalWebSocket {\r\n send(data: string): void;\r\n close(code?: number, reason?: string): void;\r\n readyState: number;\r\n onopen: ((ev: unknown) => void) | null;\r\n onclose: ((ev: unknown) => void) | null;\r\n onerror: ((ev: unknown) => void) | null;\r\n onmessage: ((ev: { data: unknown }) => void) | null;\r\n}\r\n\r\nconst THESIS_EVENT_NAMES = ['thesis', 'thesis.reply', 'thesis.reaction', 'thesis.removed'] as const;\r\n\r\nfunction keyOf(t: ThesisTokenRef): string {\r\n const mint = t.blockchain === 'solana' ? t.mint.trim() : t.mint.trim().toLowerCase();\r\n return `${t.blockchain}:${mint}`;\r\n}\r\n\r\nfunction connectionError(code: string, message: string): CabalSpyIDError {\r\n if (code === 'invalid_parameter') return new BadRequestError(message, { code, status: 400 });\r\n if (code === 'too_many_connections') return new RateLimitError(message, { code, status: 429 });\r\n return new PermissionError(message, { code, status: 403 });\r\n}\r\n\r\n/**\r\n * Live theses for the tokens you choose. Subscriptions are remembered and sent\r\n * again after every reconnect.\r\n *\r\n * const ts = csid.thesesStream();\r\n * ts.on('thesis', (t) => addMarker(t.blockchain, t.mint, t));\r\n * await ts.connect();\r\n * ts.subscribe([{ blockchain: 'solana', mint: MINT_A }, { blockchain: 'base', mint: TOKEN_B }]);\r\n *\r\n * for await (const { event, data } of ts) { … }\r\n */\r\nexport class ThesesStream {\r\n private ws: MinimalWebSocket | null = null;\r\n private readonly handlers = new Map<string, Set<Handler<never>>>();\r\n private readonly tokens = new Map<string, ThesisTokenRef>();\r\n private all = false;\r\n private attempt = 0;\r\n private closedByUser = false;\r\n private fatal: CabalSpyIDError | null = null;\r\n private ready = false;\r\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\r\n private watchdog: ReturnType<typeof setTimeout> | null = null;\r\n private readonly opts: Required<Pick<ThesesStreamOptions, 'reconnect' | 'reconnectDelay' | 'maxReconnectDelay' | 'heartbeatTimeout'>>;\r\n\r\n constructor(\r\n private readonly url: string,\r\n private readonly apiKey: string,\r\n private readonly options: ThesesStreamOptions = {},\r\n ) {\r\n if (options.scope && options.scope !== 'global' && options.scope !== 'instance') {\r\n throw new BadRequestError(`Invalid value for 'scope': ${options.scope}`, {\r\n code: 'invalid_parameter',\r\n parameter: 'scope',\r\n allowed: ['global', 'instance'],\r\n });\r\n }\r\n this.opts = {\r\n reconnect: options.reconnect ?? true,\r\n reconnectDelay: options.reconnectDelay ?? 1_000,\r\n maxReconnectDelay: options.maxReconnectDelay ?? 30_000,\r\n heartbeatTimeout: options.heartbeatTimeout ?? 75_000,\r\n };\r\n }\r\n\r\n private buildUrl(key: string): string {\r\n const sp = new URLSearchParams({ api_key: key });\r\n if (this.options.scope) sp.set('scope', this.options.scope);\r\n if (this.options.instance) sp.set('instance', this.options.instance);\r\n return `${this.url}?${sp.toString()}`;\r\n }\r\n\r\n /** The URL with the key masked, safe to log. */\r\n get safeUrl(): string {\r\n return this.buildUrl('***');\r\n }\r\n\r\n get connected(): boolean {\r\n return this.ws?.readyState === 1 && this.ready;\r\n }\r\n\r\n /** The tokens currently subscribed (kept across reconnects). */\r\n get subscriptions(): { all: boolean; tokens: ThesisTokenRef[] } {\r\n return { all: this.all, tokens: [...this.tokens.values()] };\r\n }\r\n\r\n on<E extends keyof ThesesStreamEventMap>(event: E, handler: Handler<ThesesStreamEventMap[E]>): this {\r\n let set = this.handlers.get(event);\r\n if (!set) this.handlers.set(event, (set = new Set()));\r\n set.add(handler as Handler<never>);\r\n return this;\r\n }\r\n\r\n off<E extends keyof ThesesStreamEventMap>(event: E, handler: Handler<ThesesStreamEventMap[E]>): this {\r\n this.handlers.get(event)?.delete(handler as Handler<never>);\r\n return this;\r\n }\r\n\r\n private emit<E extends keyof ThesesStreamEventMap>(event: E, payload: ThesesStreamEventMap[E]): void {\r\n for (const h of [...(this.handlers.get(event) ?? [])]) {\r\n try {\r\n (h as Handler<ThesesStreamEventMap[E]>)(payload);\r\n } catch (err) {\r\n if (event !== 'error') this.emit('error', new CabalSpyIDError(String((err as Error)?.message ?? err), { code: 'handler_error' }));\r\n }\r\n }\r\n }\r\n\r\n private send(frame: unknown): void {\r\n if (this.ws?.readyState === 1 && this.ready) this.ws.send(JSON.stringify(frame));\r\n }\r\n\r\n // ── subscriptions ─────────────────────────────────────────────────────────\r\n\r\n /** Adds tokens (at most 200 per connection). Sent now if connected, and after every reconnect. */\r\n subscribe(tokens: ThesisTokenRef[]): this {\r\n const fresh: ThesisTokenRef[] = [];\r\n for (const t of tokens) {\r\n if (!t || !(CHAINS as readonly string[]).includes(t.blockchain)) {\r\n throw new BadRequestError(`Unknown blockchain '${t?.blockchain}'`, {\r\n code: 'invalid_parameter',\r\n parameter: 'blockchain',\r\n allowed: [...CHAINS],\r\n });\r\n }\r\n if (!t.mint) throw new BadRequestError(\"Parameter 'mint' is required\", { code: 'missing_parameter', parameter: 'mint' });\r\n const k = keyOf(t);\r\n if (!this.tokens.has(k)) fresh.push({ blockchain: t.blockchain, mint: t.mint.trim() });\r\n }\r\n if (this.tokens.size + fresh.length > MAX_THESES_STREAM_TOKENS) {\r\n throw new BadRequestError(`At most ${MAX_THESES_STREAM_TOKENS} tokens per connection`, {\r\n code: 'too_many_tokens',\r\n parameter: 'tokens',\r\n });\r\n }\r\n for (const t of fresh) this.tokens.set(keyOf(t), t);\r\n if (fresh.length) this.send({ op: 'subscribe', tokens: fresh });\r\n return this;\r\n }\r\n\r\n /** Removes tokens. */\r\n unsubscribe(tokens: ThesisTokenRef[]): this {\r\n const gone = tokens.filter((t) => this.tokens.delete(keyOf(t)));\r\n if (gone.length) this.send({ op: 'unsubscribe', tokens: gone });\r\n return this;\r\n }\r\n\r\n /** Every token (all theses). */\r\n subscribeAll(): this {\r\n this.all = true;\r\n this.send({ op: 'subscribe', all: true });\r\n return this;\r\n }\r\n\r\n /** Drops every subscription, including subscribeAll(). */\r\n unsubscribeAll(): this {\r\n this.all = false;\r\n this.tokens.clear();\r\n this.send({ op: 'unsubscribe', all: true });\r\n return this;\r\n }\r\n\r\n private resubscribe(): void {\r\n if (this.all) this.send({ op: 'subscribe', all: true });\r\n const list = [...this.tokens.values()];\r\n if (list.length) this.send({ op: 'subscribe', tokens: list });\r\n }\r\n\r\n // ── connection ────────────────────────────────────────────────────────────\r\n\r\n /** Opens the socket; resolves on `ready` (after sending the remembered subscriptions). */\r\n connect(): Promise<ThesesReadyEvent> {\r\n this.closedByUser = false;\r\n this.fatal = null;\r\n const WS = (this.options.WebSocketImpl ?? (globalThis as { WebSocket?: unknown }).WebSocket) as\r\n | (new (url: string) => MinimalWebSocket)\r\n | undefined;\r\n if (!WS) {\r\n return Promise.reject(\r\n new ConnectionError('No WebSocket implementation found. On Node < 22, run `npm i ws` and pass { WebSocketImpl: WebSocket }.', {\r\n code: 'no_websocket',\r\n }),\r\n );\r\n }\r\n return new Promise<ThesesReadyEvent>((resolve, reject) => {\r\n let settled = false;\r\n const settle = (err: CabalSpyIDError | null, value?: ThesesReadyEvent) => {\r\n if (settled) return;\r\n settled = true;\r\n if (err) reject(err);\r\n else resolve(value!);\r\n };\r\n this.ready = false;\r\n const ws = new WS(this.buildUrl(this.apiKey));\r\n this.ws = ws;\r\n ws.onopen = () => {\r\n this.arm();\r\n this.emit('open', undefined);\r\n };\r\n ws.onmessage = (ev) => {\r\n if (this.ws !== ws) return;\r\n this.arm();\r\n let msg: { event?: string; data?: unknown; ts?: number; error?: { code?: string; message?: string } };\r\n try {\r\n msg = JSON.parse(typeof ev.data === 'string' ? ev.data : String(ev.data));\r\n } catch {\r\n return;\r\n }\r\n const event = msg.event;\r\n if (event === 'ready') {\r\n this.ready = true;\r\n this.attempt = 0;\r\n this.resubscribe();\r\n const data = msg.data as ThesesReadyEvent;\r\n this.emit('ready', data);\r\n settle(null, data);\r\n } else if (event === 'subscribed') {\r\n this.emit('subscribed', msg.data as ThesesSubscribedEvent);\r\n } else if (event && (THESIS_EVENT_NAMES as readonly string[]).includes(event)) {\r\n this.emit(event as (typeof THESIS_EVENT_NAMES)[number], msg.data as never);\r\n } else if (event === 'heartbeat') {\r\n this.emit('heartbeat', { ts: Number(msg.ts) });\r\n } else if (event === 'pong') {\r\n this.emit('pong', {});\r\n } else if (event === 'error') {\r\n const code = msg.error?.code ?? 'stream_error';\r\n const message = msg.error?.message ?? 'Stream error';\r\n if (!this.ready) {\r\n // Refused before ready: the server closes the socket.\r\n const err = connectionError(code, message);\r\n if (code !== 'too_many_connections') this.fatal = err;\r\n this.emit('error', err);\r\n settle(err);\r\n } else {\r\n // A bad frame (too many tokens, unknown token …): the connection stays.\r\n this.emit('error', new BadRequestError(message, { code, status: 400 }));\r\n }\r\n }\r\n };\r\n ws.onerror = () => {\r\n if (this.ws !== ws) return;\r\n const err = new ConnectionError(`WebSocket error on ${this.safeUrl}`, { code: 'ws_error' });\r\n this.emit('error', err);\r\n settle(err);\r\n };\r\n ws.onclose = (ev) => {\r\n if (this.ws !== ws) return;\r\n this.ws = null;\r\n this.ready = false;\r\n this.disarm();\r\n const e = (ev ?? {}) as { code?: number; reason?: string };\r\n this.emit('close', { code: e.code, reason: e.reason });\r\n settle(new ConnectionError(`Theses stream closed before it was ready (code ${e.code ?? 'unknown'})`, { code: 'ws_closed_early' }));\r\n if (!this.closedByUser && !this.fatal && this.opts.reconnect) this.scheduleReconnect();\r\n };\r\n });\r\n }\r\n\r\n private scheduleReconnect(): void {\r\n const delay = Math.min(this.opts.reconnectDelay * 2 ** this.attempt, this.opts.maxReconnectDelay) + Math.random() * 250;\r\n this.attempt++;\r\n this.emit('reconnecting', { attempt: this.attempt, delay });\r\n this.reconnectTimer = setTimeout(() => {\r\n this.reconnectTimer = null;\r\n if (!this.closedByUser) this.connect().catch(() => undefined);\r\n }, delay);\r\n }\r\n\r\n private arm(): void {\r\n if (!this.opts.heartbeatTimeout) return;\r\n this.disarm();\r\n this.watchdog = setTimeout(() => {\r\n this.emit('error', new ConnectionError('No heartbeat from the theses stream; reconnecting', { code: 'heartbeat_timeout' }));\r\n this.ws?.close(4000, 'heartbeat timeout');\r\n }, this.opts.heartbeatTimeout);\r\n }\r\n\r\n private disarm(): void {\r\n if (this.watchdog) clearTimeout(this.watchdog);\r\n this.watchdog = null;\r\n }\r\n\r\n /** Sends a ping (answered with `pong`). Pinging more often than every 30 s suppresses heartbeats. */\r\n ping(): void {\r\n if (this.ws?.readyState === 1) this.ws.send(JSON.stringify({ op: 'ping' }));\r\n }\r\n\r\n /** Closes the socket and stops reconnecting. Subscriptions are kept for a later connect(). */\r\n close(): void {\r\n this.closedByUser = true;\r\n this.disarm();\r\n if (this.reconnectTimer) clearTimeout(this.reconnectTimer);\r\n this.reconnectTimer = null;\r\n const ws = this.ws;\r\n this.ws = null;\r\n this.ready = false;\r\n ws?.close(1000, 'client closed');\r\n this.emit('close', { code: 1000, reason: 'client closed' });\r\n }\r\n\r\n /**\r\n * Iterates over thesis events as `{ event, data }`. Connects if needed;\r\n * breaking out closes a connection the iterator opened.\r\n */\r\n async *[Symbol.asyncIterator](): AsyncGenerator<ThesisStreamEvent, void, void> {\r\n const queue: ThesisStreamEvent[] = [];\r\n let wake: (() => void) | null = null;\r\n let failure: CabalSpyIDError | null = null;\r\n let done = false;\r\n const listeners = THESIS_EVENT_NAMES.map((name) => {\r\n const fn = (data: unknown) => {\r\n queue.push({ event: name, data } as ThesisStreamEvent);\r\n wake?.();\r\n };\r\n return [name, fn] as const;\r\n });\r\n const onError = () => {\r\n if (this.fatal) {\r\n failure = this.fatal;\r\n wake?.();\r\n }\r\n };\r\n const onClose = () => {\r\n if (this.closedByUser || !this.opts.reconnect) {\r\n done = true;\r\n wake?.();\r\n }\r\n };\r\n for (const [name, fn] of listeners) this.on(name, fn as never);\r\n this.on('error', onError).on('close', onClose);\r\n const owns = !this.ws;\r\n try {\r\n if (owns) await this.connect();\r\n while (true) {\r\n while (queue.length) yield queue.shift()!;\r\n if (failure) throw failure;\r\n if (done) return;\r\n await new Promise<void>((r) => (wake = r));\r\n wake = null;\r\n }\r\n } finally {\r\n for (const [name, fn] of listeners) this.off(name, fn as never);\r\n this.off('error', onError).off('close', onClose);\r\n if (owns && !this.closedByUser) this.close();\r\n }\r\n }\r\n}\r\n","/** Internal helpers: encoding, WebCrypto access, environment. */\r\n\r\nexport const SDK_VERSION = '0.5.1';\r\nexport const USER_AGENT = `cabalspy-id-sdk/${SDK_VERSION}`;\r\n\r\nconst enc = new TextEncoder();\r\nconst dec = new TextDecoder();\r\n\r\n/** Bytes backed by a plain ArrayBuffer, as WebCrypto expects. */\r\nexport type Bytes = Uint8Array<ArrayBuffer>;\r\n\r\nexport function utf8(text: string): Bytes {\r\n return enc.encode(text);\r\n}\r\n\r\nexport function fromUtf8(bytes: Uint8Array): string {\r\n return dec.decode(bytes);\r\n}\r\n\r\nexport function bytesToBase64(bytes: Uint8Array): string {\r\n let s = '';\r\n for (let i = 0; i < bytes.length; i++) s += String.fromCharCode(bytes[i]!);\r\n return btoa(s);\r\n}\r\n\r\nexport function base64ToBytes(b64: string): Bytes {\r\n const bin = atob(b64);\r\n const out = new Uint8Array(bin.length);\r\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\r\n return out;\r\n}\r\n\r\nexport function base64UrlEncode(bytes: Uint8Array): string {\r\n return bytesToBase64(bytes).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\r\n}\r\n\r\nexport function base64UrlDecode(text: string): Bytes {\r\n const b64 = text.replace(/-/g, '+').replace(/_/g, '/');\r\n return base64ToBytes(b64 + '='.repeat((4 - (b64.length % 4)) % 4));\r\n}\r\n\r\n/**\r\n * WebCrypto. Global in browsers, Deno, Bun and Node 19+; Node 18 exposes it as\r\n * `require('node:crypto').webcrypto`.\r\n */\r\nlet cryptoPromise: Promise<Crypto> | null = null;\r\nexport function getCrypto(): Promise<Crypto> {\r\n const g = (globalThis as { crypto?: Crypto }).crypto;\r\n if (g?.subtle) return Promise.resolve(g);\r\n if (!cryptoPromise) {\r\n const mod = 'node:crypto';\r\n cryptoPromise = (import(/* webpackIgnore: true */ /* @vite-ignore */ mod) as Promise<{ webcrypto: Crypto }>).then(\r\n (m) => m.webcrypto,\r\n );\r\n }\r\n return cryptoPromise;\r\n}\r\n\r\nexport async function randomToken(bytes = 32): Promise<string> {\r\n const c = await getCrypto();\r\n const a = new Uint8Array(bytes);\r\n c.getRandomValues(a);\r\n return base64UrlEncode(a);\r\n}\r\n\r\nexport async function sha256Base64Url(text: string): Promise<string> {\r\n const c = await getCrypto();\r\n return base64UrlEncode(new Uint8Array(await c.subtle.digest('SHA-256', utf8(text))));\r\n}\r\n\r\n/** Constant-time comparison of two strings. */\r\nexport function timingSafeEqual(a: string, b: string): boolean {\r\n if (a.length !== b.length) return false;\r\n let diff = 0;\r\n for (let i = 0; i < a.length; i++) diff |= a.charCodeAt(i) ^ b.charCodeAt(i);\r\n return diff === 0;\r\n}\r\n\r\nexport function env(name: string): string | undefined {\r\n return (globalThis as { process?: { env?: Record<string, string | undefined> } }).process?.env?.[name];\r\n}\r\n\r\nexport const sleep = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));\r\n","/**\r\n * CabalSpy ID Data API client — https://api-id.cabalspy.xyz/v1\r\n *\r\n * Auth: Authorization: Bearer <API_KEY>. The same key as the CabalSpy API, with\r\n * the \"CabalSpy ID\" toggle enabled on the API keys page of\r\n * https://apidashboard.cabalspy.xyz.\r\n */\r\n\r\nimport {\r\n type ApiErrorBody,\r\n AuthenticationError,\r\n BadRequestError,\r\n CabalSpyIDError,\r\n ConnectionError,\r\n EMPTY_RATE_LIMIT,\r\n InvalidResponseError,\r\n type RateLimitInfo,\r\n RateLimitError,\r\n errorFromStatus,\r\n isRetryable,\r\n} from './errors';\r\nimport { CabalSpyIDStream, type StreamOptions } from './stream';\r\nimport { ThesesStream, type ThesesStreamOptions } from './thesesStream';\r\nimport {\r\n type ApiResponse,\r\n CHAINS,\r\n type Chain,\r\n type HealthResponse,\r\n type HistoryResponse,\r\n type HistoryTrade,\r\n type HoldingsResponse,\r\n LEADERBOARD_SORTS,\r\n type LeaderboardEntry,\r\n type LeaderboardResponse,\r\n type LeaderboardSort,\r\n type MeResponse,\r\n type Pagination,\r\n PERIODS,\r\n type Period,\r\n type PnlCalendarResponse,\r\n type Profile,\r\n type Scope,\r\n THESIS_EMOJIS,\r\n THESIS_REPORT_REASONS,\r\n type Thesis,\r\n type ThesisEligibility,\r\n type ThesisEmoji,\r\n type ThesisNotifications,\r\n type ThesisReactions,\r\n type ThesisReportReason,\r\n type ThesisSort,\r\n type ThesisStance,\r\n type ThesisSummary,\r\n type Trade,\r\n type TrackerResponse,\r\n type WalletLookupResponse,\r\n} from './types';\r\nimport { USER_AGENT, env, sleep } from './util';\r\n\r\nexport const DEFAULT_BASE_URL = 'https://api-id.cabalspy.xyz/v1';\r\nexport const DEFAULT_STREAM_URL = 'wss://api-id.cabalspy.xyz/v1/stream';\r\nexport const DEFAULT_THESES_STREAM_URL = 'wss://api-id.cabalspy.xyz/v1/theses/stream';\r\n\r\nexport interface CabalSpyIDOptions {\r\n /**\r\n * API key. Falls back to CABALSPY_ID_API_KEY, then CABALSPY_API_KEY.\r\n * Only `health()` works without one.\r\n */\r\n apiKey?: string;\r\n /**\r\n * Your instance's client_id (`csid_…`). Only needed when your account has\r\n * several CabalSpy ID instances. Falls back to CABALSPY_ID_INSTANCE.\r\n */\r\n instance?: string;\r\n /** REST base URL including /v1. Falls back to CABALSPY_ID_BASE_URL, then the default. */\r\n baseUrl?: string;\r\n /** Stream URL. Falls back to CABALSPY_ID_STREAM_URL, then the default. */\r\n streamUrl?: string;\r\n /** Theses stream URL. Default: wss://api-id.cabalspy.xyz/v1/theses/stream */\r\n thesesStreamUrl?: string;\r\n /** Per-request timeout in milliseconds. Default: 30_000 */\r\n timeout?: number;\r\n /** Retries on 429, 5xx and network errors. Default: 2 */\r\n maxRetries?: number;\r\n /** Extra headers added to every request. */\r\n headers?: Record<string, string>;\r\n /** Custom fetch implementation, for tests or proxies. */\r\n fetch?: typeof globalThis.fetch;\r\n}\r\n\r\n/** Response body plus the metadata carried in HTTP headers. */\r\nexport interface Envelope<T> extends ApiResponse<T> {\r\n rateLimit: RateLimitInfo;\r\n status: number;\r\n}\r\n\r\ntype QueryValue = string | number | boolean | undefined | null;\r\nexport type Query = Record<string, QueryValue>;\r\n\r\n// ── parameters ──────────────────────────────────────────────────────────────\r\n\r\nexport interface ScopedParams {\r\n /** `global` (every CabalSpy ID user) is Enterprise only. Default: instance */\r\n scope?: Scope;\r\n}\r\n\r\nexport interface UsersParams extends ScopedParams {\r\n /** 1-100. Default: 50 */\r\n limit?: number;\r\n /** Only users with the KOL badge. */\r\n kol?: boolean;\r\n cursor?: string;\r\n}\r\n\r\n/** Exactly one of username, csid_id or address. */\r\nexport type ProfileParams = ScopedParams &\r\n (\r\n | { username: string; csid_id?: never; address?: never }\r\n | { csid_id: string; username?: never; address?: never }\r\n | { address: string; username?: never; csid_id?: never }\r\n );\r\n\r\nexport interface WalletParams extends ScopedParams {\r\n blockchain: Chain;\r\n address: string;\r\n}\r\n\r\nexport interface TrackerParams extends WalletParams {\r\n /** Default: 1d */\r\n period?: Period;\r\n}\r\n\r\nexport interface HistoryParams extends WalletParams {\r\n /** 1-1000. Default: 500 */\r\n limit?: number;\r\n cursor?: string;\r\n}\r\n\r\nexport interface LeaderboardParams extends ScopedParams {\r\n blockchain: Chain;\r\n /** Default: 1d */\r\n period?: Period;\r\n /** Default: volume */\r\n sort?: LeaderboardSort;\r\n /** 1-500. Default: 100 */\r\n limit?: number;\r\n /** The `next_cursor` of the previous page (a wallet address). */\r\n cursor?: string;\r\n}\r\n\r\nexport interface LatestTransactionsParams extends ScopedParams {\r\n /** Omit for every chain. */\r\n blockchain?: Chain;\r\n /** 1-100. Default: 50 */\r\n limit?: number;\r\n}\r\n\r\n// -- theses ------------------------------------------------------------------\r\n\r\nexport interface ThesisTokenParams {\r\n blockchain: Chain;\r\n /** Token mint / contract address. */\r\n mint: string;\r\n}\r\n\r\n/**\r\n * `global` (default): theses written on every platform. `instance`: only the\r\n * ones written on your instance (your apps). Same for every plan.\r\n */\r\nexport interface ThesisScopeParam {\r\n scope?: Scope;\r\n}\r\n\r\nexport interface ListThesesParams extends ThesisTokenParams, ThesisScopeParam {\r\n /** Default: new */\r\n sort?: ThesisSort;\r\n stance?: ThesisStance;\r\n /** 1-50. Default: 20 */\r\n limit?: number;\r\n cursor?: string;\r\n /** Viewer: fills `my_reactions` and `is_mine` for this user. */\r\n csid_id?: string;\r\n}\r\n\r\nexport interface ThesisRepliesParams {\r\n /** The thesis id. */\r\n id: string;\r\n /** 1-100. Default: 50 */\r\n limit?: number;\r\n cursor?: string;\r\n csid_id?: string;\r\n}\r\n\r\nexport interface LatestThesesParams extends ThesisScopeParam {\r\n /** Omit for every chain. */\r\n blockchain?: Chain;\r\n /** `instance`: only theses of your instance's users. Default: all */\r\n users?: 'all' | 'instance';\r\n /** 1-50. Default: 20 */\r\n limit?: number;\r\n cursor?: string;\r\n csid_id?: string;\r\n}\r\n\r\n/** Exactly one of csid_id or username. */\r\nexport type UserThesesParams = { limit?: number; cursor?: string } & (\r\n | { csid_id: string; username?: never }\r\n | { username: string; csid_id?: never }\r\n);\r\n\r\n/**\r\n * Writes happen in the name of one of your users: `csid_id` is the `sub` of\r\n * their ID token. They must have signed in to your app with the scope\r\n * `thesis` and be within your plan's user limit.\r\n */\r\nexport interface ThesisWriter {\r\n csid_id: string;\r\n}\r\n\r\nexport interface PostThesisParams extends ThesisTokenParams, ThesisWriter {\r\n /** Up to 1000 characters. Only holders of the token can post. */\r\n body: string;\r\n stance?: ThesisStance;\r\n}\r\n\r\nexport interface ReplyToThesisParams extends ThesisWriter {\r\n thesis_id: string;\r\n body: string;\r\n}\r\n\r\nexport interface ReactToThesisParams extends ThesisWriter {\r\n thesis_id: string;\r\n emoji: ThesisEmoji;\r\n /** false removes the reaction. Default: true */\r\n on?: boolean;\r\n}\r\n\r\nexport interface ReportThesisParams extends ThesisWriter {\r\n thesis_id: string;\r\n reason: ThesisReportReason;\r\n note?: string;\r\n}\r\n\r\nexport interface DeleteThesisParams extends ThesisWriter {\r\n thesis_id: string;\r\n}\r\n\r\nfunction buildQuery(params: Query): string {\r\n const sp = new URLSearchParams();\r\n for (const [k, v] of Object.entries(params)) {\r\n if (v === undefined || v === null || v === '') continue;\r\n sp.append(k, typeof v === 'boolean' ? (v ? 'true' : 'false') : String(v));\r\n }\r\n const s = sp.toString();\r\n return s ? `?${s}` : '';\r\n}\r\n\r\nfunction parseNumHeader(h: Headers, name: string): number | null {\r\n const raw = h.get(name);\r\n if (raw == null) return null;\r\n const n = Number.parseInt(raw, 10);\r\n return Number.isFinite(n) ? n : null;\r\n}\r\n\r\nfunction backoffDelay(attempt: number, lastError?: unknown): number {\r\n // The server's Retry-After takes precedence over our own backoff.\r\n if (lastError instanceof RateLimitError && lastError.retryAfter != null) {\r\n return Math.min(lastError.retryAfter * 1000, 60_000);\r\n }\r\n const base = 500 * 2 ** (attempt - 1); // 500, 1000, 2000 …\r\n return Math.min(base, 8_000) + Math.random() * 250;\r\n}\r\n\r\nfunction assertOneOf(value: string | undefined, allowed: readonly string[], parameter: string): void {\r\n if (value === undefined) return;\r\n if (!allowed.includes(value)) {\r\n throw new BadRequestError(`Invalid value for '${parameter}': ${value}`, {\r\n code: 'invalid_parameter',\r\n parameter,\r\n allowed: [...allowed],\r\n });\r\n }\r\n}\r\n\r\nfunction assertRequired(value: unknown, parameter: string): void {\r\n if (value === undefined || value === null || value === '') {\r\n throw new BadRequestError(`Parameter '${parameter}' is required`, { code: 'missing_parameter', parameter });\r\n }\r\n}\r\n\r\nfunction assertToken(p: { blockchain?: string; mint?: string }): void {\r\n assertRequired(p.blockchain, 'blockchain');\r\n assertOneOf(p.blockchain, CHAINS, 'blockchain');\r\n assertRequired(p.mint, 'mint');\r\n}\r\n\r\nfunction assertWallet(p: { blockchain?: string; address?: string }): void {\r\n assertRequired(p.blockchain, 'blockchain');\r\n assertOneOf(p.blockchain, CHAINS, 'blockchain');\r\n assertRequired(p.address, 'address');\r\n}\r\n\r\n// ═══════════════════════════════════════════════════════════════════════════\r\n// CLIENT\r\n// ═══════════════════════════════════════════════════════════════════════════\r\n\r\n/**\r\n * Data API client.\r\n *\r\n * const csid = new CabalSpyID({ apiKey: process.env.CABALSPY_API_KEY });\r\n * const me = await csid.me();\r\n * const user = await csid.profile({ csid_id: idToken.sub });\r\n */\r\nexport class CabalSpyID {\r\n readonly baseUrl: string;\r\n readonly streamUrl: string;\r\n readonly thesesStreamUrl: string;\r\n readonly timeout: number;\r\n readonly maxRetries: number;\r\n readonly instance?: string;\r\n\r\n private readonly apiKey: string;\r\n private readonly extraHeaders: Record<string, string>;\r\n private readonly fetchImpl: typeof globalThis.fetch;\r\n\r\n /** Rate limit state from the most recent request. */\r\n lastRateLimit: RateLimitInfo = { ...EMPTY_RATE_LIMIT };\r\n\r\n constructor(options: CabalSpyIDOptions = {}) {\r\n this.apiKey = options.apiKey ?? (env('CABALSPY_ID_API_KEY') || env('CABALSPY_API_KEY') || '');\r\n this.instance = options.instance ?? (env('CABALSPY_ID_INSTANCE') || undefined);\r\n this.baseUrl = (options.baseUrl ?? (env('CABALSPY_ID_BASE_URL') || DEFAULT_BASE_URL)).replace(/\\/+$/, '');\r\n this.streamUrl = (options.streamUrl ?? (env('CABALSPY_ID_STREAM_URL') || DEFAULT_STREAM_URL)).replace(/\\/+$/, '');\r\n this.thesesStreamUrl = (options.thesesStreamUrl ?? DEFAULT_THESES_STREAM_URL).replace(/\\/+$/, '');\r\n this.timeout = options.timeout ?? 30_000;\r\n this.maxRetries = options.maxRetries ?? 2;\r\n this.extraHeaders = options.headers ?? {};\r\n const f = options.fetch ?? globalThis.fetch;\r\n if (typeof f !== 'function') {\r\n throw new CabalSpyIDError('No fetch implementation available. Use Node 18+ or pass { fetch }.', {\r\n code: 'no_fetch',\r\n });\r\n }\r\n this.fetchImpl = options.fetch ?? f.bind(globalThis);\r\n }\r\n\r\n // ── HTTP core ─────────────────────────────────────────────────────────────\r\n\r\n private authedQuery(query: Query, auth: boolean): Query {\r\n if (auth && !this.apiKey) {\r\n throw new AuthenticationError(\r\n 'Missing API key. Pass { apiKey } or set CABALSPY_ID_API_KEY (the CabalSpy API key with CabalSpy ID enabled).',\r\n { status: 401, code: 'missing_api_key' },\r\n );\r\n }\r\n return auth && this.instance && query.instance === undefined ? { ...query, instance: this.instance } : query;\r\n }\r\n\r\n /** GET returning the full envelope: data, pagination, meta and rate limit. */\r\n async getRaw<T>(path: string, query: Query = {}, opts: { auth?: boolean } = {}): Promise<Envelope<T>> {\r\n const auth = opts.auth ?? true;\r\n return this.request<T>('GET', path + buildQuery(this.authedQuery(query, auth)), auth);\r\n }\r\n\r\n /** GET returning only the data payload. */\r\n async get<T>(path: string, query: Query = {}): Promise<T> {\r\n return (await this.getRaw<T>(path, query)).data;\r\n }\r\n\r\n /**\r\n * POST with a JSON body, returning the full envelope. POSTs are not retried\r\n * after a server or network error (the write may have happened); only the\r\n * API's own rate limit (429 rate_limit_exceeded) is retried.\r\n */\r\n async postRaw<T>(path: string, body: Record<string, unknown>): Promise<Envelope<T>> {\r\n return this.request<T>('POST', path + buildQuery(this.authedQuery({}, true)), true, body);\r\n }\r\n\r\n /** POST returning only the data payload. */\r\n async post<T>(path: string, body: Record<string, unknown>): Promise<T> {\r\n return (await this.postRaw<T>(path, body)).data;\r\n }\r\n\r\n private async request<T>(method: 'GET' | 'POST', path: string, auth: boolean, body?: unknown): Promise<Envelope<T>> {\r\n const url = `${this.baseUrl}${path.startsWith('/') ? path : `/${path}`}`;\r\n const label = `${method} ${stripQuery(path)}`;\r\n let lastError: CabalSpyIDError | undefined;\r\n\r\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\r\n if (attempt > 0) await sleep(backoffDelay(attempt, lastError));\r\n\r\n const controller = new AbortController();\r\n const timer = setTimeout(() => controller.abort(), this.timeout);\r\n let res: Response;\r\n let text: string;\r\n try {\r\n res = await this.fetchImpl(url, {\r\n method,\r\n signal: controller.signal,\r\n headers: {\r\n ...(auth ? { Authorization: `Bearer ${this.apiKey}` } : {}),\r\n Accept: 'application/json',\r\n 'User-Agent': USER_AGENT,\r\n ...(body !== undefined ? { 'Content-Type': 'application/json' } : {}),\r\n ...this.extraHeaders,\r\n },\r\n body: body !== undefined ? JSON.stringify(body) : undefined,\r\n });\r\n text = await res.text();\r\n } catch (err) {\r\n const aborted = (err as Error)?.name === 'AbortError';\r\n lastError = new ConnectionError(\r\n aborted ? `Request timed out after ${this.timeout} ms: ${label}` : `Network error: ${(err as Error)?.message ?? String(err)}`,\r\n { code: aborted ? 'timeout' : 'connection_error' },\r\n );\r\n if (method !== 'GET') throw lastError; // the write may have happened\r\n continue; // network errors are retryable\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n\r\n const rateLimit: RateLimitInfo = {\r\n limit: parseNumHeader(res.headers, 'X-RateLimit-Limit'),\r\n remaining: parseNumHeader(res.headers, 'X-RateLimit-Remaining'),\r\n reset: parseNumHeader(res.headers, 'X-RateLimit-Reset'),\r\n };\r\n this.lastRateLimit = rateLimit;\r\n\r\n let parsed: unknown = null;\r\n if (text) {\r\n try {\r\n parsed = JSON.parse(text);\r\n } catch {\r\n parsed = null;\r\n }\r\n }\r\n\r\n if (!res.ok) {\r\n const errBody = (parsed as { error?: ApiErrorBody } | null)?.error ?? null;\r\n const retryAfter = parseNumHeader(res.headers, 'Retry-After');\r\n const error = errorFromStatus(res.status, errBody, rateLimit, retryAfter, `HTTP ${res.status} on ${label}`);\r\n const retryable =\r\n method === 'GET' ? isRetryable(error) : error instanceof RateLimitError && error.code === 'rate_limit_exceeded';\r\n if (retryable && attempt < this.maxRetries) {\r\n lastError = error;\r\n continue;\r\n }\r\n throw error;\r\n }\r\n\r\n if (parsed == null || typeof parsed !== 'object' || !('data' in parsed)) {\r\n throw new InvalidResponseError(`Unexpected response shape on ${label}: no data field`, {\r\n status: res.status,\r\n code: 'invalid_response',\r\n rateLimit,\r\n });\r\n }\r\n return { ...(parsed as ApiResponse<T>), rateLimit, status: res.status };\r\n }\r\n throw lastError ?? new ConnectionError(`Request failed: ${label}`);\r\n }\r\n\r\n /**\r\n * Walks a cursor-paginated route and yields whole pages.\r\n *\r\n * for await (const page of csid.pages((cursor) => csid.usersRaw({ cursor }))) …\r\n *\r\n * Reads `pagination` from the envelope or, for the leaderboard, from `data`.\r\n */\r\n async *pages<T>(\r\n fetchPage: (cursor: string | undefined) => Promise<Envelope<T>>,\r\n opts: { cursor?: string; maxPages?: number } = {},\r\n ): AsyncGenerator<Envelope<T>, void, void> {\r\n let cursor = opts.cursor;\r\n const maxPages = opts.maxPages ?? Infinity;\r\n for (let i = 0; i < maxPages; i++) {\r\n const page = await fetchPage(cursor);\r\n const inner = (page.data as { pagination?: Pagination } | null)?.pagination;\r\n const pagination = page.pagination ?? inner;\r\n yield { ...page, pagination };\r\n const next = pagination?.next_cursor;\r\n if (!pagination?.has_more || !next) return;\r\n cursor = next;\r\n }\r\n }\r\n\r\n // ── account ───────────────────────────────────────────────────────────────\r\n\r\n /** GET /v1/health — service health and trade sync freshness. No API key required. */\r\n async health(): Promise<HealthResponse> {\r\n return (await this.getRaw<HealthResponse>('/health', {}, { auth: false })).data;\r\n }\r\n\r\n /** GET /v1/me — the key's instance, plan, request rate and number of users with data. */\r\n async me(): Promise<MeResponse> {\r\n return this.get<MeResponse>('/me');\r\n }\r\n\r\n // ── users ─────────────────────────────────────────────────────────────────\r\n\r\n /** GET /v1/users — users of your instance (within the plan's user limit), newest first. */\r\n async users(params: UsersParams = {}): Promise<Profile[]> {\r\n return (await this.usersRaw(params)).data;\r\n }\r\n\r\n async usersRaw(params: UsersParams = {}): Promise<Envelope<Profile[]>> {\r\n return this.getRaw<Profile[]>('/users', {\r\n limit: params.limit,\r\n kol: params.kol ? 'true' : undefined,\r\n cursor: params.cursor,\r\n scope: params.scope,\r\n });\r\n }\r\n\r\n /** Iterates over every user, following `next_cursor`. */\r\n async *iterUsers(params: Omit<UsersParams, 'cursor'> & { cursor?: string } = {}): AsyncGenerator<Profile, void, void> {\r\n for await (const page of this.pages((cursor) => this.usersRaw({ ...params, cursor }), { cursor: params.cursor })) {\r\n yield* page.data;\r\n }\r\n }\r\n\r\n /**\r\n * GET /v1/profile — one user by X username, by `csid_id` (the `sub` of their\r\n * ID token) or by a verified wallet address. Pass exactly one.\r\n *\r\n * An anonymous `anon_…` sub throws PlanUserLimitError.\r\n */\r\n async profile(params: ProfileParams): Promise<Profile> {\r\n const p = params as { username?: string; csid_id?: string; address?: string; scope?: Scope };\r\n const given = [p.username, p.csid_id, p.address].filter((v) => v !== undefined && v !== '').length;\r\n if (given !== 1) {\r\n throw new BadRequestError('Pass exactly one of: username, csid_id, address.', {\r\n code: 'missing_parameter',\r\n parameter: 'username|csid_id|address',\r\n });\r\n }\r\n return this.get<Profile>('/profile', {\r\n username: p.username?.replace(/^@/, ''),\r\n csid_id: p.csid_id,\r\n address: p.address,\r\n scope: p.scope,\r\n });\r\n }\r\n\r\n /** GET /v1/wallets/lookup — which of your users verified this wallet (by an on-chain payment). */\r\n async walletLookup(address: string, params: ScopedParams = {}): Promise<WalletLookupResponse> {\r\n assertRequired(address, 'address');\r\n return this.get<WalletLookupResponse>('/wallets/lookup', { address, scope: params.scope });\r\n }\r\n\r\n // ── trading ───────────────────────────────────────────────────────────────\r\n\r\n /**\r\n * GET /v1/wallets/tracker — stats, realized PnL, win-rate distribution,\r\n * tokens, PnL chart (cumulative from 0) and trades of a verified wallet for a\r\n * period. Same numbers as the CabalSpy API.\r\n */\r\n async tracker(params: TrackerParams): Promise<TrackerResponse> {\r\n assertWallet(params);\r\n assertOneOf(params.period, PERIODS, 'period');\r\n return this.get<TrackerResponse>('/wallets/tracker', { ...params });\r\n }\r\n\r\n /** GET /v1/wallets/history — lifetime stats, token overview and one page of trades. */\r\n async history(params: HistoryParams): Promise<HistoryResponse> {\r\n return (await this.historyRaw(params)).data;\r\n }\r\n\r\n async historyRaw(params: HistoryParams): Promise<Envelope<HistoryResponse>> {\r\n assertWallet(params);\r\n return this.getRaw<HistoryResponse>('/wallets/history', { ...params });\r\n }\r\n\r\n /** Iterates over every trade of a wallet, newest first, following `next_cursor`. */\r\n async *iterHistory(params: HistoryParams): AsyncGenerator<HistoryTrade, void, void> {\r\n for await (const page of this.pages((cursor) => this.historyRaw({ ...params, cursor }), { cursor: params.cursor })) {\r\n yield* page.data.trades;\r\n }\r\n }\r\n\r\n /** GET /v1/wallets/holdings — current token balances with USD value (dust under $0.01 hidden). */\r\n async holdings(params: WalletParams): Promise<HoldingsResponse> {\r\n assertWallet(params);\r\n return this.get<HoldingsResponse>('/wallets/holdings', { ...params });\r\n }\r\n\r\n /** GET /v1/wallets/pnl_calendar — realized PnL per UTC day, grouped by month. */\r\n async pnlCalendar(params: WalletParams): Promise<PnlCalendarResponse> {\r\n assertWallet(params);\r\n return this.get<PnlCalendarResponse>('/wallets/pnl_calendar', { ...params });\r\n }\r\n\r\n /** GET /v1/wallets/leaderboard — your users ranked by volume, PnL, win rate or trades. */\r\n async leaderboard(params: LeaderboardParams): Promise<LeaderboardResponse> {\r\n return (await this.leaderboardRaw(params)).data;\r\n }\r\n\r\n async leaderboardRaw(params: LeaderboardParams): Promise<Envelope<LeaderboardResponse>> {\r\n assertRequired(params.blockchain, 'blockchain');\r\n assertOneOf(params.blockchain, CHAINS, 'blockchain');\r\n assertOneOf(params.period, PERIODS, 'period');\r\n assertOneOf(params.sort, LEADERBOARD_SORTS, 'sort');\r\n return this.getRaw<LeaderboardResponse>('/wallets/leaderboard', { ...params });\r\n }\r\n\r\n /** Iterates over every leaderboard entry, following `next_cursor`. */\r\n async *iterLeaderboard(params: LeaderboardParams): AsyncGenerator<LeaderboardEntry, void, void> {\r\n for await (const page of this.pages((cursor) => this.leaderboardRaw({ ...params, cursor }), { cursor: params.cursor })) {\r\n yield* page.data.leaderboard;\r\n }\r\n }\r\n\r\n /** GET /v1/transactions/latest — the newest trades of your users, each with the trader. */\r\n async latestTransactions(params: LatestTransactionsParams = {}): Promise<Trade[]> {\r\n assertOneOf(params.blockchain, CHAINS, 'blockchain');\r\n return this.get<Trade[]>('/transactions/latest', { ...params });\r\n }\r\n\r\n // -- theses ----------------------------------------------------------------\r\n // Reading: theses are public; any key reads them, also outside its instance.\r\n\r\n /** GET /v1/theses — theses on a token, newest or top first. */\r\n async listTheses(params: ListThesesParams): Promise<Thesis[]> {\r\n return (await this.listThesesRaw(params)).data;\r\n }\r\n\r\n async listThesesRaw(params: ListThesesParams): Promise<Envelope<Thesis[]>> {\r\n assertToken(params);\r\n assertOneOf(params.sort, ['new', 'top'], 'sort');\r\n assertOneOf(params.stance, ['bull', 'bear'], 'stance');\r\n assertOneOf(params.scope, ['global', 'instance'], 'scope');\r\n return this.getRaw<Thesis[]>('/theses', { ...params });\r\n }\r\n\r\n /** Iterates over every thesis on a token, following `next_cursor`. */\r\n async *iterTheses(params: ListThesesParams): AsyncGenerator<Thesis, void, void> {\r\n for await (const page of this.pages((cursor) => this.listThesesRaw({ ...params, cursor }), { cursor: params.cursor })) {\r\n yield* page.data;\r\n }\r\n }\r\n\r\n /** GET /v1/theses/summary — counts (theses, bull, bear, authors) and token info. */\r\n async thesisSummary(params: ThesisTokenParams & ThesisScopeParam): Promise<ThesisSummary> {\r\n assertToken(params);\r\n assertOneOf(params.scope, ['global', 'instance'], 'scope');\r\n return this.get<ThesisSummary>('/theses/summary', { blockchain: params.blockchain, mint: params.mint, scope: params.scope });\r\n }\r\n\r\n /** GET /v1/theses/item — one thesis or reply. */\r\n async thesis(id: string, params: { csid_id?: string } = {}): Promise<Thesis> {\r\n assertRequired(id, 'id');\r\n return this.get<Thesis>('/theses/item', { id, csid_id: params.csid_id });\r\n }\r\n\r\n /** GET /v1/theses/replies — replies to a thesis. */\r\n async thesisReplies(params: ThesisRepliesParams): Promise<Thesis[]> {\r\n return (await this.thesisRepliesRaw(params)).data;\r\n }\r\n\r\n async thesisRepliesRaw(params: ThesisRepliesParams): Promise<Envelope<Thesis[]>> {\r\n assertRequired(params.id, 'id');\r\n return this.getRaw<Thesis[]>('/theses/replies', { ...params });\r\n }\r\n\r\n /** Iterates over every reply of a thesis. */\r\n async *iterThesisReplies(params: ThesisRepliesParams): AsyncGenerator<Thesis, void, void> {\r\n for await (const page of this.pages((cursor) => this.thesisRepliesRaw({ ...params, cursor }), { cursor: params.cursor })) {\r\n yield* page.data;\r\n }\r\n }\r\n\r\n /** GET /v1/theses/latest — newest theses on every token (or only your users'). */\r\n async latestTheses(params: LatestThesesParams = {}): Promise<Thesis[]> {\r\n return (await this.latestThesesRaw(params)).data;\r\n }\r\n\r\n async latestThesesRaw(params: LatestThesesParams = {}): Promise<Envelope<Thesis[]>> {\r\n assertOneOf(params.blockchain, CHAINS, 'blockchain');\r\n assertOneOf(params.users, ['all', 'instance'], 'users');\r\n assertOneOf(params.scope, ['global', 'instance'], 'scope');\r\n return this.getRaw<Thesis[]>('/theses/latest', { ...params });\r\n }\r\n\r\n /** GET /v1/theses/user — theses of one user, by csid_id or X username. */\r\n async userTheses(params: UserThesesParams): Promise<Thesis[]> {\r\n return (await this.userThesesRaw(params)).data;\r\n }\r\n\r\n async userThesesRaw(params: UserThesesParams): Promise<Envelope<Thesis[]>> {\r\n const p = params as { csid_id?: string; username?: string; limit?: number; cursor?: string };\r\n if (!!p.csid_id === !!p.username) {\r\n throw new BadRequestError('Pass exactly one of: csid_id, username.', {\r\n code: 'missing_parameter',\r\n parameter: 'csid_id|username',\r\n });\r\n }\r\n return this.getRaw<Thesis[]>('/theses/user', { ...p, username: p.username?.replace(/^@/, '') });\r\n }\r\n\r\n /**\r\n * GET /v1/theses/eligibility — may this user post (holder, not paused) and\r\n * reply on this token through your app? `reason` says why not\r\n * (consent_required, plan_user_limit, sandbox_user).\r\n */\r\n async thesisEligibility(params: ThesisTokenParams & ThesisWriter): Promise<ThesisEligibility> {\r\n assertToken(params);\r\n assertRequired(params.csid_id, 'csid_id');\r\n return this.get<ThesisEligibility>('/theses/eligibility', { ...params });\r\n }\r\n\r\n // Writing, in the name of one of your users (scope `thesis`).\r\n\r\n /** POST /v1/theses — posts a thesis. Holders only (`not_a_holder` otherwise). */\r\n async postThesis(params: PostThesisParams): Promise<Thesis> {\r\n assertToken(params);\r\n assertRequired(params.body, 'body');\r\n assertRequired(params.csid_id, 'csid_id');\r\n assertOneOf(params.stance, ['bull', 'bear'], 'stance');\r\n return this.post<Thesis>('/theses', { ...params });\r\n }\r\n\r\n /** POST /v1/theses/replies — replies to a thesis. */\r\n async replyToThesis(params: ReplyToThesisParams): Promise<Thesis> {\r\n assertRequired(params.thesis_id, 'thesis_id');\r\n assertRequired(params.body, 'body');\r\n assertRequired(params.csid_id, 'csid_id');\r\n return this.post<Thesis>('/theses/replies', { ...params });\r\n }\r\n\r\n /** POST /v1/theses/reactions — adds (or with `on: false` removes) a reaction. */\r\n async reactToThesis(params: ReactToThesisParams): Promise<ThesisReactions> {\r\n assertRequired(params.thesis_id, 'thesis_id');\r\n assertOneOf(params.emoji, THESIS_EMOJIS, 'emoji');\r\n assertRequired(params.csid_id, 'csid_id');\r\n return this.post<ThesisReactions>('/theses/reactions', { ...params, on: params.on ?? true });\r\n }\r\n\r\n /** POST /v1/theses/report — reports a post (hidden for review after 3 reports). */\r\n async reportThesis(params: ReportThesisParams): Promise<{ reported: true }> {\r\n assertRequired(params.thesis_id, 'thesis_id');\r\n assertOneOf(params.reason, THESIS_REPORT_REASONS, 'reason');\r\n assertRequired(params.csid_id, 'csid_id');\r\n return this.post<{ reported: true }>('/theses/report', { ...params });\r\n }\r\n\r\n /**\r\n * GET /v1/theses/notifications — moderation notifications of one of your users\r\n * (warnings, hidden posts, pauses, appeal results), with the unread count.\r\n */\r\n async thesisNotifications(csidId: string): Promise<ThesisNotifications> {\r\n assertRequired(csidId, 'csid_id');\r\n return this.get<ThesisNotifications>('/theses/notifications', { csid_id: csidId });\r\n }\r\n\r\n /**\r\n * POST /v1/theses/appeal — appeals a moderation decision in the user's name\r\n * (an `appealable` notification, within 30 days; message 10-1000 characters).\r\n */\r\n async appealThesisDecision(csidId: string, notificationId: number, message: string): Promise<{ appealed: true }> {\r\n assertRequired(csidId, 'csid_id');\r\n assertRequired(notificationId, 'notification_id');\r\n assertRequired(message, 'message');\r\n return this.post<{ appealed: true }>('/theses/appeal', { csid_id: csidId, notification_id: notificationId, message });\r\n }\r\n\r\n /** POST /v1/theses/delete — deletes the user's own thesis or reply. */\r\n async deleteThesis(params: DeleteThesisParams): Promise<{ deleted: true }> {\r\n assertRequired(params.thesis_id, 'thesis_id');\r\n assertRequired(params.csid_id, 'csid_id');\r\n return this.post<{ deleted: true }>('/theses/delete', { ...params });\r\n }\r\n\r\n // ── stream ────────────────────────────────────────────────────────────────\r\n\r\n /**\r\n * Live trades of your users over WebSocket (Pro plan and up).\r\n *\r\n * const stream = csid.stream({ blockchain: 'solana' });\r\n * stream.on('trade', (trade) => console.log(trade));\r\n * await stream.connect();\r\n */\r\n stream(options: StreamOptions = {}): CabalSpyIDStream {\r\n if (!this.apiKey) {\r\n throw new AuthenticationError('The stream needs an API key.', { status: 401, code: 'missing_api_key' });\r\n }\r\n return new CabalSpyIDStream(this.streamUrl, this.apiKey, { instance: this.instance, ...options });\r\n }\r\n\r\n /**\r\n * Live theses for the tokens you subscribe to (every plan), e.g. for a chart.\r\n *\r\n * const ts = csid.thesesStream();\r\n * ts.on('thesis', (t) => addMarker(t));\r\n * await ts.connect();\r\n * ts.subscribe([{ blockchain: 'solana', mint }]);\r\n */\r\n thesesStream(options: ThesesStreamOptions = {}): ThesesStream {\r\n if (!this.apiKey) {\r\n throw new AuthenticationError('The theses stream needs an API key.', { status: 401, code: 'missing_api_key' });\r\n }\r\n return new ThesesStream(this.thesesStreamUrl, this.apiKey, { instance: this.instance, ...options });\r\n }\r\n}\r\n\r\nfunction stripQuery(path: string): string {\r\n const i = path.indexOf('?');\r\n return i === -1 ? path : path.slice(0, i);\r\n}\r\n","// ═══════════════════════════════════════════════════════════════════════════\r\n// WEBHOOKS — Standard Webhooks signatures (standardwebhooks.com)\r\n// ═══════════════════════════════════════════════════════════════════════════\r\n//\r\n// webhook-id event id, the same on every retry (dedupe on it)\r\n// webhook-timestamp unix seconds\r\n// webhook-signature \"v1,<base64 HMAC-SHA256>\" over \"<id>.<timestamp>.<body>\",\r\n// keyed with the base64-decoded part of the whsec_ secret.\r\n// During a secret roll: several, separated by spaces.\r\n\r\nimport { WebhookVerificationError } from './errors';\r\nimport type { WebhookEvent } from './types';\r\nimport { type Bytes, base64ToBytes, bytesToBase64, fromUtf8, getCrypto, timingSafeEqual, utf8 } from './util';\r\n\r\nexport type HeaderSource =\r\n | Headers\r\n | Record<string, string | string[] | undefined>\r\n | { get(name: string): string | null | undefined };\r\n\r\nexport interface VerifyWebhookOptions {\r\n /** The raw request body, exactly as received (do not re-serialize parsed JSON). */\r\n payload: string | Uint8Array | ArrayBuffer;\r\n /** Request headers (Fetch Headers, Node's IncomingHttpHeaders or a plain object). */\r\n headers: HeaderSource;\r\n /** Signing secret from the dashboard, `whsec_…`. */\r\n secret: string;\r\n /** Maximum age (and future skew) of webhook-timestamp in seconds. Default: 300 */\r\n toleranceSeconds?: number;\r\n /** Current time in seconds; for tests. */\r\n now?: number;\r\n}\r\n\r\nfunction header(headers: HeaderSource, name: string): string | undefined {\r\n if (typeof (headers as { get?: unknown }).get === 'function') {\r\n return (headers as { get(n: string): string | null | undefined }).get(name) ?? undefined;\r\n }\r\n const rec = headers as Record<string, string | string[] | undefined>;\r\n const key = Object.keys(rec).find((k) => k.toLowerCase() === name);\r\n const v = key === undefined ? undefined : rec[key];\r\n return Array.isArray(v) ? v[0] : v;\r\n}\r\n\r\nfunction toBytes(payload: string | Uint8Array | ArrayBuffer): Bytes {\r\n if (typeof payload === 'string') return utf8(payload);\r\n return new Uint8Array(payload instanceof Uint8Array ? payload : new Uint8Array(payload));\r\n}\r\n\r\nfunction secretKey(secret: string): Bytes {\r\n try {\r\n return base64ToBytes(secret.startsWith('whsec_') ? secret.slice(6) : secret);\r\n } catch {\r\n throw new WebhookVerificationError('The webhook secret is not valid base64 (expected whsec_…)', { code: 'invalid_secret' });\r\n }\r\n}\r\n\r\nasync function hmac(secret: string, content: Bytes): Promise<string> {\r\n const c = await getCrypto();\r\n const key = await c.subtle.importKey('raw', secretKey(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);\r\n return bytesToBase64(new Uint8Array(await c.subtle.sign('HMAC', key, content)));\r\n}\r\n\r\nfunction signedContent(id: string, timestamp: number | string, body: Uint8Array): Bytes {\r\n const prefix = utf8(`${id}.${timestamp}.`);\r\n const out = new Uint8Array(prefix.length + body.length);\r\n out.set(prefix, 0);\r\n out.set(body, prefix.length);\r\n return out;\r\n}\r\n\r\n/**\r\n * Computes the `webhook-signature` header value for a payload. Useful to\r\n * build test requests for your receiver.\r\n */\r\nexport async function signWebhook(\r\n secret: string,\r\n id: string,\r\n timestamp: number,\r\n payload: string | Uint8Array,\r\n): Promise<string> {\r\n return `v1,${await hmac(secret, signedContent(id, timestamp, toBytes(payload)))}`;\r\n}\r\n\r\n/**\r\n * Verifies a webhook and returns the parsed event. Throws\r\n * WebhookVerificationError when a header is missing, the timestamp is outside\r\n * the tolerance or no signature matches.\r\n *\r\n * const event = await verifyWebhook({ payload: rawBody, headers: req.headers, secret: process.env.CSID_WEBHOOK_SECRET });\r\n */\r\nexport async function verifyWebhook<D = Record<string, unknown>>(options: VerifyWebhookOptions): Promise<WebhookEvent<D>> {\r\n const { headers, secret } = options;\r\n if (!secret) throw new WebhookVerificationError('Missing webhook secret', { code: 'invalid_secret' });\r\n const id = header(headers, 'webhook-id');\r\n const ts = header(headers, 'webhook-timestamp');\r\n const sigs = header(headers, 'webhook-signature');\r\n if (!id || !ts || !sigs) {\r\n throw new WebhookVerificationError('Missing webhook-id, webhook-timestamp or webhook-signature header', {\r\n code: 'missing_headers',\r\n });\r\n }\r\n const timestamp = Number(ts);\r\n if (!/^\\d+$/.test(ts) || !Number.isSafeInteger(timestamp)) {\r\n throw new WebhookVerificationError('Invalid webhook-timestamp', { code: 'invalid_timestamp' });\r\n }\r\n const now = options.now ?? Math.floor(Date.now() / 1000);\r\n const tolerance = options.toleranceSeconds ?? 300;\r\n if (now - timestamp > tolerance) throw new WebhookVerificationError('Webhook timestamp is too old', { code: 'timestamp_too_old' });\r\n if (timestamp - now > tolerance) throw new WebhookVerificationError('Webhook timestamp is in the future', { code: 'timestamp_too_new' });\r\n\r\n const body = toBytes(options.payload);\r\n const expected = await hmac(secret, signedContent(id, ts, body));\r\n const match = sigs\r\n .split(' ')\r\n .map((s) => s.trim())\r\n .filter(Boolean)\r\n .some((s) => {\r\n const [version, sig] = s.split(',', 2);\r\n return version === 'v1' && sig !== undefined && timingSafeEqual(sig, expected);\r\n });\r\n if (!match) throw new WebhookVerificationError('No matching webhook signature', { code: 'invalid_signature' });\r\n\r\n try {\r\n return JSON.parse(fromUtf8(body)) as WebhookEvent<D>;\r\n } catch {\r\n throw new WebhookVerificationError('Webhook body is not valid JSON', { code: 'invalid_payload' });\r\n }\r\n}\r\n","/**\n * People can sign in with X, Telegram or Google. Accounts without X have no\n * X profile: `x` is null, `twitter` is null and the handle is `tg.<name>`\n * (Telegram) or `id.<hex>` (Google). X handles never contain a dot.\n */\n\n/** Anything that describes a CabalSpy ID user: claims, a Data API profile, a trader or thesis author. */\nexport interface UserLike {\n x?: unknown;\n twitter?: string | null;\n preferred_username?: string | null;\n username?: string | null;\n}\n\n/** The sign-in identity a handle belongs to. */\nexport type HandleKind = 'x' | 'telegram' | 'google';\n\n/** Which identity a CabalSpy ID handle comes from: `tg.` = Telegram, `id.` = Google, else X. */\nexport function handleKind(handle: string): HandleKind {\n if (handle.startsWith('tg.')) return 'telegram';\n if (handle.startsWith('id.')) return 'google';\n return 'x';\n}\n\n/**\n * True when the user has an X account connected.\n *\n * Uses the most reliable field available: `x` (userinfo claims, Data API\n * profiles), then `twitter` (trading profiles, leaderboards), then the handle\n * (ID token claims, thesis authors). Returns false for null/undefined. The ID\n * token carries no `x` claim, so there the handle decides.\n */\nexport function hasX(user: UserLike | null | undefined): boolean {\n if (!user) return false;\n if (user.x !== undefined) return user.x !== null;\n if (user.twitter !== undefined) return Boolean(user.twitter);\n const handle = user.preferred_username ?? user.username;\n return typeof handle === 'string' && handle.length > 0 && handleKind(handle) === 'x';\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/thesis.ts"],"sourcesContent":["// ═══════════════════════════════════════════════════════════════════════════\r\n// PUBLIC THESIS API — https://id.cabalspy.xyz/thesis/v1 (browser friendly)\r\n// ═══════════════════════════════════════════════════════════════════════════\r\n//\r\n// Reading needs nothing. Writing needs the signed-in user's CabalSpy ID access\r\n// token with the scope \"thesis\" (e.g. from the login widget's csid:login event).\r\n// CORS is open and no cookies are used, so this runs in the browser as is.\r\n// Your API key is never needed here (and must never reach a browser).\r\n\r\nimport {\r\n type ApiErrorBody,\r\n AuthenticationError,\r\n BadRequestError,\r\n CabalSpyIDError,\r\n ConnectionError,\r\n EMPTY_RATE_LIMIT,\r\n InvalidResponseError,\r\n PermissionError,\r\n errorFromStatus,\r\n} from './errors';\r\nimport {\r\n CHAINS,\r\n type Chain,\r\n type Pagination,\r\n THESIS_EMOJIS,\r\n THESIS_REPORT_REASONS,\r\n type Thesis,\r\n type ThesisCounts,\r\n type ThesisEligibility,\r\n type ThesisEmoji,\r\n type ThesisNotices,\r\n type ThesisNotifications,\r\n type ThesisReactions,\r\n type ThesisReportReason,\r\n type ThesisSort,\r\n type ThesisStance,\r\n type ThesisSummary,\r\n type ThesisToken,\r\n} from './types';\r\nimport { USER_AGENT } from './util';\r\n\r\nexport const DEFAULT_THESIS_URL = 'https://id.cabalspy.xyz/thesis/v1';\r\nexport const DEFAULT_THESIS_WS_URL = 'wss://id.cabalspy.xyz/thesis/v1/ws';\r\n\r\nexport interface ThesisScopeOptions {\r\n /**\r\n * `global` (default): theses written on every platform. `instance`: only the\r\n * ones written on the instance named by `clientId`.\r\n */\r\n scope?: 'global' | 'instance';\r\n /** Your instance's client_id. Needed for `scope: 'instance'`; also credits posts to your app. */\r\n clientId?: string;\r\n}\r\n\r\nexport interface ThesisClientOptions extends ThesisScopeOptions {\r\n /** The signed-in user's access token (scope `thesis`). Needed only for writing. */\r\n accessToken?: string | null;\r\n /** Default: https://id.cabalspy.xyz/thesis/v1 */\r\n baseUrl?: string;\r\n /** Default: wss://id.cabalspy.xyz/thesis/v1/ws */\r\n wsUrl?: string;\r\n /** Per-request timeout in ms. Default: 15_000 */\r\n timeout?: number;\r\n fetch?: typeof globalThis.fetch;\r\n}\r\n\r\nexport interface TokenThesesPage {\r\n items: Thesis[];\r\n pagination: Pagination;\r\n token: ThesisToken;\r\n summary: ThesisCounts;\r\n}\r\n\r\nexport interface ThesisPage {\r\n items: Thesis[];\r\n pagination: Pagination;\r\n}\r\n\r\nexport interface TokenThesesOptions extends ThesisScopeOptions {\r\n sort?: ThesisSort;\r\n stance?: ThesisStance;\r\n /** 1-50. Default: 20 */\r\n limit?: number;\r\n cursor?: string;\r\n}\r\n\r\nexport interface ThesisViewer {\r\n csid_id: string;\r\n username: string | null;\r\n name: string | null;\r\n image_url: string | null;\r\n}\r\n\r\n/** Eligibility of the signed-in user, who that is, and their unread moderation notices. */\r\nexport type ThesisMe = ThesisEligibility & { user: ThesisViewer; notices: ThesisNotices };\r\n\r\nfunction assertChain(chain: string): void {\r\n if (!(CHAINS as readonly string[]).includes(chain)) {\r\n throw new BadRequestError(`Unknown blockchain '${chain}'`, { code: 'invalid_parameter', parameter: 'chain', allowed: [...CHAINS] });\r\n }\r\n}\r\n\r\nconst enc = encodeURIComponent;\r\n\r\n/** Query parameters for a scope; instance scope needs the client_id. */\r\nfunction scopeQuery(scope: string | undefined, clientId: string | undefined): Record<string, string | undefined> {\r\n if (scope === undefined || scope === 'global') return scope ? { scope } : {};\r\n if (scope !== 'instance') {\r\n throw new BadRequestError(`Invalid value for 'scope': ${scope}`, {\r\n code: 'invalid_parameter',\r\n parameter: 'scope',\r\n allowed: ['global', 'instance'],\r\n });\r\n }\r\n if (!clientId) {\r\n throw new BadRequestError('scope=instance needs clientId', { code: 'missing_parameter', parameter: 'clientId' });\r\n }\r\n return { scope, client_id: clientId };\r\n}\r\n\r\n/**\r\n * Client for the public thesis API, e.g. in a browser app that builds its own\r\n * thesis UI.\r\n *\r\n * const theses = new ThesisClient({ accessToken }); // from csid:login\r\n * const page = await theses.list('solana', mint, { sort: 'top' });\r\n * await theses.post('solana', mint, { body: 'Strong community, early.', stance: 'bull' });\r\n * const live = theses.live('solana', mint);\r\n * live.on('thesis', (t) => render(t));\r\n * await live.connect();\r\n */\r\nexport class ThesisClient {\r\n readonly baseUrl: string;\r\n readonly wsUrl: string;\r\n readonly timeout: number;\r\n readonly scope?: 'global' | 'instance';\r\n readonly clientId?: string;\r\n private accessToken: string | null;\r\n private readonly fetchImpl: typeof globalThis.fetch;\r\n\r\n constructor(options: ThesisClientOptions = {}) {\r\n this.accessToken = options.accessToken ?? null;\r\n this.baseUrl = (options.baseUrl ?? DEFAULT_THESIS_URL).replace(/\\/+$/, '');\r\n this.wsUrl = (options.wsUrl ?? DEFAULT_THESIS_WS_URL).replace(/\\/+$/, '');\r\n this.timeout = options.timeout ?? 15_000;\r\n this.scope = options.scope;\r\n this.clientId = options.clientId;\r\n scopeQuery(this.scope, this.clientId);\r\n this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);\r\n }\r\n\r\n /** Sets (or with null clears) the user's access token, e.g. after sign-in or sign-out. */\r\n setAccessToken(token: string | null | undefined): void {\r\n this.accessToken = token ?? null;\r\n }\r\n\r\n private async call<T>(\r\n method: 'GET' | 'POST' | 'DELETE',\r\n path: string,\r\n opts: { auth?: 'required' | 'optional'; body?: unknown; query?: Record<string, string | number | undefined> } = {},\r\n ): Promise<{ data: T; extra: Record<string, unknown> }> {\r\n if (opts.auth === 'required' && !this.accessToken) {\r\n throw new AuthenticationError('Sign in with CabalSpy ID to write (an access token with the scope \"thesis\").', {\r\n status: 401,\r\n code: 'sign_in_required',\r\n });\r\n }\r\n const sp = new URLSearchParams();\r\n for (const [k, v] of Object.entries(opts.query ?? {})) if (v !== undefined && v !== '') sp.set(k, String(v));\r\n const qs = sp.toString();\r\n const url = `${this.baseUrl}${path}${qs ? `?${qs}` : ''}`;\r\n const controller = new AbortController();\r\n const timer = setTimeout(() => controller.abort(), this.timeout);\r\n let res: Response;\r\n let text: string;\r\n try {\r\n res = await this.fetchImpl(url, {\r\n method,\r\n signal: controller.signal,\r\n credentials: 'omit',\r\n headers: {\r\n Accept: 'application/json',\r\n ...(typeof window === 'undefined' ? { 'User-Agent': USER_AGENT } : {}),\r\n ...(this.accessToken && opts.auth ? { Authorization: `Bearer ${this.accessToken}` } : {}),\r\n ...(opts.body !== undefined ? { 'Content-Type': 'application/json' } : {}),\r\n },\r\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,\r\n });\r\n text = await res.text();\r\n } catch (err) {\r\n const aborted = (err as Error)?.name === 'AbortError';\r\n throw new ConnectionError(aborted ? `Request timed out after ${this.timeout} ms: ${method} ${path}` : `Network error: ${(err as Error)?.message}`, {\r\n code: aborted ? 'timeout' : 'connection_error',\r\n });\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n let parsed: Record<string, unknown> | null = null;\r\n try {\r\n parsed = text ? (JSON.parse(text) as Record<string, unknown>) : null;\r\n } catch {\r\n parsed = null;\r\n }\r\n if (!res.ok || parsed?.success === false) {\r\n const err = (parsed?.error ?? null) as ApiErrorBody | null;\r\n throw errorFromStatus(res.status, err, { ...EMPTY_RATE_LIMIT }, null, `HTTP ${res.status} on ${method} ${path}`);\r\n }\r\n if (!parsed || !('data' in parsed)) {\r\n throw new InvalidResponseError(`Unexpected response shape on ${method} ${path}`, { status: res.status, code: 'invalid_response' });\r\n }\r\n const { data, success: _s, ...extra } = parsed;\r\n return { data: data as T, extra };\r\n }\r\n\r\n private tokenPath(chain: Chain, mint: string): string {\r\n assertChain(chain);\r\n if (!mint) throw new BadRequestError(\"Parameter 'mint' is required\", { code: 'missing_parameter', parameter: 'mint' });\r\n return `/tokens/${enc(chain)}/${enc(mint)}`;\r\n }\r\n\r\n // ── reading ───────────────────────────────────────────────────────────────\r\n\r\n /** Theses on a token, with the token's info and counts. */\r\n async list(chain: Chain, mint: string, opts: TokenThesesOptions = {}): Promise<TokenThesesPage> {\r\n const { data, extra } = await this.call<Thesis[]>('GET', this.tokenPath(chain, mint), {\r\n auth: 'optional',\r\n query: {\r\n sort: opts.sort,\r\n stance: opts.stance,\r\n limit: opts.limit,\r\n cursor: opts.cursor,\r\n ...scopeQuery(opts.scope ?? this.scope, opts.clientId ?? this.clientId),\r\n },\r\n });\r\n return {\r\n items: data,\r\n pagination: extra.pagination as Pagination,\r\n token: extra.token as ThesisToken,\r\n summary: extra.summary as ThesisCounts,\r\n };\r\n }\r\n\r\n /** Every thesis on a token, following `next_cursor`. */\r\n async *iterate(chain: Chain, mint: string, opts: TokenThesesOptions = {}): AsyncGenerator<Thesis, void, void> {\r\n let cursor = opts.cursor;\r\n while (true) {\r\n const page = await this.list(chain, mint, { ...opts, cursor });\r\n yield* page.items;\r\n if (!page.pagination?.has_more || !page.pagination.next_cursor) return;\r\n cursor = page.pagination.next_cursor;\r\n }\r\n }\r\n\r\n /** Counts (theses, bull, bear, authors) and token info. */\r\n async summary(chain: Chain, mint: string, opts: ThesisScopeOptions = {}): Promise<ThesisSummary> {\r\n const query = scopeQuery(opts.scope ?? this.scope, opts.clientId ?? this.clientId);\r\n return (await this.call<ThesisSummary>('GET', `${this.tokenPath(chain, mint)}/summary`, { query })).data;\r\n }\r\n\r\n /** One thesis or reply. */\r\n async get(id: string): Promise<Thesis> {\r\n return (await this.call<Thesis>('GET', `/items/${enc(id)}`, { auth: 'optional' })).data;\r\n }\r\n\r\n /** Replies to a thesis. */\r\n async replies(id: string, opts: { limit?: number; cursor?: string } = {}): Promise<ThesisPage> {\r\n const { data, extra } = await this.call<Thesis[]>('GET', `/items/${enc(id)}/replies`, { auth: 'optional', query: opts });\r\n return { items: data, pagination: extra.pagination as Pagination };\r\n }\r\n\r\n /** Theses of one user (their csid_id). */\r\n async byUser(csidId: string, opts: { limit?: number; cursor?: string } = {}): Promise<ThesisPage> {\r\n const { data, extra } = await this.call<Thesis[]>('GET', `/users/${enc(csidId)}`, { auth: 'optional', query: opts });\r\n return { items: data, pagination: extra.pagination as Pagination };\r\n }\r\n\r\n // ── the signed-in user ────────────────────────────────────────────────────\r\n\r\n /** May the signed-in user post (holder) or reply on this token, and who are they. */\r\n async me(chain: Chain, mint: string): Promise<ThesisMe> {\r\n return (await this.call<ThesisMe>('GET', `${this.tokenPath(chain, mint)}/me`, { auth: 'required' })).data;\r\n }\r\n\r\n /** Posts a thesis. Holders only (`not_a_holder` otherwise). Up to 1000 characters. */\r\n async post(chain: Chain, mint: string, params: { body: string; stance?: ThesisStance }): Promise<Thesis> {\r\n if (params.stance && params.stance !== 'bull' && params.stance !== 'bear') {\r\n throw new BadRequestError('stance must be bull or bear', { code: 'invalid_parameter', parameter: 'stance', allowed: ['bull', 'bear'] });\r\n }\r\n const body = { ...params, ...(this.clientId ? { client_id: this.clientId } : {}) };\r\n return (await this.call<Thesis>('POST', this.tokenPath(chain, mint), { auth: 'required', body })).data;\r\n }\r\n\r\n /** Replies to a thesis. Any signed-in user may reply. */\r\n async reply(id: string, body: string): Promise<Thesis> {\r\n const payload = { body, ...(this.clientId ? { client_id: this.clientId } : {}) };\r\n return (await this.call<Thesis>('POST', `/items/${enc(id)}/replies`, { auth: 'required', body: payload })).data;\r\n }\r\n\r\n /** Adds (or with on=false removes) a reaction. */\r\n async react(id: string, emoji: ThesisEmoji, on = true): Promise<ThesisReactions> {\r\n if (!(THESIS_EMOJIS as readonly string[]).includes(emoji)) {\r\n throw new BadRequestError('Unknown reaction', { code: 'invalid_parameter', parameter: 'emoji', allowed: [...THESIS_EMOJIS] });\r\n }\r\n return (await this.call<ThesisReactions>('POST', `/items/${enc(id)}/reactions`, { auth: 'required', body: { emoji, on } })).data;\r\n }\r\n\r\n /** Reports a post (hidden for review after 3 reports). */\r\n async report(id: string, reason: ThesisReportReason, note?: string): Promise<{ reported: true }> {\r\n if (!(THESIS_REPORT_REASONS as readonly string[]).includes(reason)) {\r\n throw new BadRequestError('Choose a reason', { code: 'invalid_parameter', parameter: 'reason', allowed: [...THESIS_REPORT_REASONS] });\r\n }\r\n return (await this.call<{ reported: true }>('POST', `/items/${enc(id)}/report`, { auth: 'required', body: { reason, note } })).data;\r\n }\r\n\r\n /** Deletes the signed-in user's own thesis or reply. */\r\n async delete(id: string): Promise<{ deleted: true }> {\r\n return (await this.call<{ deleted: true }>('DELETE', `/items/${enc(id)}`, { auth: 'required' })).data;\r\n }\r\n\r\n /** The signed-in user's moderation notifications, with the unread count. */\r\n async notifications(): Promise<ThesisNotifications> {\r\n return (await this.call<ThesisNotifications>('GET', '/me/notifications', { auth: 'required' })).data;\r\n }\r\n\r\n /** Marks all of the signed-in user's notifications as read. */\r\n async markNotificationsRead(): Promise<{ read: true }> {\r\n return (await this.call<{ read: true }>('POST', '/me/notifications/read', { auth: 'required' })).data;\r\n }\r\n\r\n /** Appeals a moderation decision (an `appealable` notification; 10-1000 characters, within 30 days). */\r\n async appeal(notificationId: number, message: string): Promise<{ appealed: true }> {\r\n if (!message) throw new BadRequestError(\"Parameter 'message' is required\", { code: 'missing_parameter', parameter: 'message' });\r\n return (\r\n await this.call<{ appealed: true }>('POST', `/me/notifications/${enc(String(notificationId))}/appeal`, {\r\n auth: 'required',\r\n body: { message },\r\n })\r\n ).data;\r\n }\r\n\r\n // ── live ──────────────────────────────────────────────────────────────────\r\n\r\n /**\r\n * Live updates for one token: thesis, reply, reaction, removed. With\r\n * `scope: 'instance'` (and `clientId`) only theses written on that instance.\r\n */\r\n live(chain: Chain, mint: string, options: ThesisLiveOptions & ThesisScopeOptions = {}): ThesisLive {\r\n this.tokenPath(chain, mint);\r\n const sp = new URLSearchParams(scopeQuery(options.scope ?? this.scope, options.clientId ?? this.clientId) as Record<string, string>);\r\n const qs = sp.toString();\r\n return new ThesisLive(`${this.wsUrl}/${enc(chain)}/${enc(mint)}${qs ? `?${qs}` : ''}`, options);\r\n }\r\n}\r\n\r\n// ── live websocket ─────────────────────────────────────────────────────────\r\n\r\nexport interface ThesisLiveOptions {\r\n /** Default: true */\r\n reconnect?: boolean;\r\n /** Default: 1000 */\r\n reconnectDelay?: number;\r\n /** Default: 30_000 */\r\n maxReconnectDelay?: number;\r\n /** The server sends a heartbeat every 30 s; silence this long reopens the socket. 0 disables. Default: 75_000 */\r\n heartbeatTimeout?: number;\r\n /** WebSocket implementation for Node < 22 (the `ws` package). */\r\n WebSocketImpl?: unknown;\r\n}\r\n\r\nexport interface ThesisLiveEventMap {\r\n thesis: Thesis;\r\n reply: Thesis;\r\n reaction: ThesisReactions;\r\n removed: { id: string };\r\n heartbeat: Record<string, never>;\r\n open: undefined;\r\n close: { code?: number; reason?: string };\r\n error: CabalSpyIDError;\r\n}\r\n\r\ntype LiveHandler<T> = (payload: T) => void;\r\n\r\ninterface MinimalWebSocket {\r\n close(code?: number, reason?: string): void;\r\n readyState: number;\r\n onopen: ((ev: unknown) => void) | null;\r\n onclose: ((ev: unknown) => void) | null;\r\n onerror: ((ev: unknown) => void) | null;\r\n onmessage: ((ev: { data: unknown }) => void) | null;\r\n}\r\n\r\n/**\r\n * Public live socket for one token. Messages arrive as `thesis`, `reply`,\r\n * `reaction` and `removed`; it reconnects after drops or missed heartbeats.\r\n * Code 1008 (invalid token address, too many sockets) is final.\r\n */\r\nexport class ThesisLive {\r\n private ws: MinimalWebSocket | null = null;\r\n private readonly handlers = new Map<string, Set<LiveHandler<never>>>();\r\n private attempt = 0;\r\n private closedByUser = false;\r\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\r\n private watchdog: ReturnType<typeof setTimeout> | null = null;\r\n private readonly opts: Required<Omit<ThesisLiveOptions, 'WebSocketImpl'>>;\r\n\r\n constructor(\r\n readonly url: string,\r\n private readonly options: ThesisLiveOptions = {},\r\n ) {\r\n this.opts = {\r\n reconnect: options.reconnect ?? true,\r\n reconnectDelay: options.reconnectDelay ?? 1_000,\r\n maxReconnectDelay: options.maxReconnectDelay ?? 30_000,\r\n heartbeatTimeout: options.heartbeatTimeout ?? 75_000,\r\n };\r\n }\r\n\r\n get connected(): boolean {\r\n return this.ws?.readyState === 1;\r\n }\r\n\r\n on<E extends keyof ThesisLiveEventMap>(event: E, handler: LiveHandler<ThesisLiveEventMap[E]>): this {\r\n let set = this.handlers.get(event);\r\n if (!set) this.handlers.set(event, (set = new Set()));\r\n set.add(handler as LiveHandler<never>);\r\n return this;\r\n }\r\n\r\n off<E extends keyof ThesisLiveEventMap>(event: E, handler: LiveHandler<ThesisLiveEventMap[E]>): this {\r\n this.handlers.get(event)?.delete(handler as LiveHandler<never>);\r\n return this;\r\n }\r\n\r\n private emit<E extends keyof ThesisLiveEventMap>(event: E, payload: ThesisLiveEventMap[E]): void {\r\n for (const h of [...(this.handlers.get(event) ?? [])]) {\r\n try {\r\n (h as LiveHandler<ThesisLiveEventMap[E]>)(payload);\r\n } catch (err) {\r\n if (event !== 'error') this.emit('error', new CabalSpyIDError(String((err as Error)?.message ?? err), { code: 'handler_error' }));\r\n }\r\n }\r\n }\r\n\r\n /** Opens the socket; resolves once it is open. */\r\n connect(): Promise<void> {\r\n this.closedByUser = false;\r\n const WS = (this.options.WebSocketImpl ?? (globalThis as { WebSocket?: unknown }).WebSocket) as\r\n | (new (url: string) => MinimalWebSocket)\r\n | undefined;\r\n if (!WS) {\r\n return Promise.reject(\r\n new ConnectionError('No WebSocket implementation found. On Node < 22, run `npm i ws` and pass { WebSocketImpl: WebSocket }.', {\r\n code: 'no_websocket',\r\n }),\r\n );\r\n }\r\n return new Promise<void>((resolve, reject) => {\r\n let settled = false;\r\n const ws = new WS(this.url);\r\n this.ws = ws;\r\n ws.onopen = () => {\r\n this.attempt = 0;\r\n this.arm();\r\n this.emit('open', undefined);\r\n if (!settled) {\r\n settled = true;\r\n resolve();\r\n }\r\n };\r\n ws.onmessage = (ev) => {\r\n if (this.ws !== ws) return;\r\n this.arm();\r\n let msg: { type?: string; data?: unknown };\r\n try {\r\n msg = JSON.parse(typeof ev.data === 'string' ? ev.data : String(ev.data));\r\n } catch {\r\n return;\r\n }\r\n if (msg.type === 'thesis' || msg.type === 'reply' || msg.type === 'reaction' || msg.type === 'removed') {\r\n this.emit(msg.type, msg.data as never);\r\n } else if (msg.type === 'heartbeat') {\r\n this.emit('heartbeat', {});\r\n }\r\n };\r\n ws.onerror = () => {\r\n if (this.ws !== ws) return;\r\n const err = new ConnectionError(`WebSocket error on ${this.url}`, { code: 'ws_error' });\r\n this.emit('error', err);\r\n if (!settled) {\r\n settled = true;\r\n reject(err);\r\n }\r\n };\r\n ws.onclose = (ev) => {\r\n if (this.ws !== ws) return;\r\n this.ws = null;\r\n this.disarm();\r\n const e = (ev ?? {}) as { code?: number; reason?: string };\r\n this.emit('close', { code: e.code, reason: e.reason });\r\n const final = e.code === 1008;\r\n if (final) {\r\n this.emit(\r\n 'error',\r\n new PermissionError('The live socket was refused (1008): invalid token address or too many sockets from this IP', {\r\n code: 'ws_refused',\r\n status: 403,\r\n }),\r\n );\r\n }\r\n if (!settled) {\r\n settled = true;\r\n reject(new ConnectionError(`Live socket closed before it opened (code ${e.code ?? 'unknown'})`, { code: 'ws_closed_early' }));\r\n }\r\n if (!this.closedByUser && !final && this.opts.reconnect) this.scheduleReconnect();\r\n };\r\n });\r\n }\r\n\r\n private scheduleReconnect(): void {\r\n const delay = Math.min(this.opts.reconnectDelay * 2 ** this.attempt, this.opts.maxReconnectDelay) + Math.random() * 250;\r\n this.attempt++;\r\n this.reconnectTimer = setTimeout(() => {\r\n this.reconnectTimer = null;\r\n if (!this.closedByUser) this.connect().catch(() => undefined);\r\n }, delay);\r\n }\r\n\r\n private arm(): void {\r\n if (!this.opts.heartbeatTimeout) return;\r\n this.disarm();\r\n this.watchdog = setTimeout(() => {\r\n this.emit('error', new ConnectionError('No heartbeat from the live socket; reconnecting', { code: 'heartbeat_timeout' }));\r\n this.ws?.close(4000, 'heartbeat timeout');\r\n }, this.opts.heartbeatTimeout);\r\n }\r\n\r\n private disarm(): void {\r\n if (this.watchdog) clearTimeout(this.watchdog);\r\n this.watchdog = null;\r\n }\r\n\r\n /** Closes the socket and stops reconnecting. */\r\n close(): void {\r\n this.closedByUser = true;\r\n this.disarm();\r\n if (this.reconnectTimer) clearTimeout(this.reconnectTimer);\r\n this.reconnectTimer = null;\r\n const ws = this.ws;\r\n this.ws = null;\r\n ws?.close(1000, 'client closed');\r\n this.emit('close', { code: 1000, reason: 'client closed' });\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["c:\\Users\\davis\\Desktop\\cabalspy-web\\github\\cabalspy-id-js\\dist\\chunk-L4RHSWOA.cjs"],"names":[],"mappings":"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CA,MAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,kBAAA;AACA,EAAA;AACA,kBAAA;AACA,kBAAA;AACA,kBAAA;AACA,kBAAA;AACA,kBAAA;AACA,kBAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,oBAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,MAAA;AACA,QAAA;AACA,UAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,UAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,UAAA;AACA,QAAA;AACA,UAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,UAAA;AACA,YAAA;AACA,YAAA;AACA,UAAA;AACA,YAAA;AACA,YAAA;AACA,YAAA;AACA,YAAA;AACA,YAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AACA,YAAA;AACA,YAAA;AACA,UAAA;AACA,YAAA;AACA,YAAA;AACA,UAAA;AACA,YAAA;AACA,YAAA;AACA,UAAA;AACA,YAAA;AACA,YAAA;AACA,YAAA;AACA,YAAA;AACA,YAAA;AACA,YAAA;AACA,UAAA;AACA,UAAA;AACA,YAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,UAAA;AACA,YAAA;AACA,UAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,sBAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,oBAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,wBAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,wBAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,wBAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,kBAAA;AACA,mBAAA;AACA,mBAAA;AACA,mBAAA;AACA,mBAAA;AACA,mBAAA;AACA,mBAAA;AACA,mBAAA;AACA,mBAAA;AACA,mBAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,oBAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,MAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,UAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,UAAA;AACA,QAAA;AACA,UAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AACA,QAAA;AACA,UAAA;AACA,QAAA;AACA,UAAA;AACA,QAAA;AACA,UAAA;AACA,QAAA;AACA,UAAA;AACA,QAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AACA,YAAA;AACA,YAAA;AACA,YAAA;AACA,YAAA;AACA,UAAA;AACA,YAAA;AACA,UAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,sBAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,oBAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,wBAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,wBAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,wBAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA;AACA;AACA,MAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA;AACA,mBAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AACA,YAAA;AACA,YAAA;AACA,YAAA;AACA,YAAA;AACA,YAAA;AACA,UAAA;AACA,UAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,UAAA;AACA,UAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,UAAA;AACA,QAAA;AACA,UAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,UAAA;AACA,UAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"C:\\Users\\davis\\Desktop\\cabalspy-web\\github\\cabalspy-id-js\\dist\\chunk-L4RHSWOA.cjs","sourcesContent":[null]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["c:\\Users\\davis\\Desktop\\cabalspy-web\\github\\cabalspy-id-js\\dist\\chunk-P3MDLWLN.cjs"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACA;AACA,IAAI,mBAAmB,EAAE,mCAAmC;AAC5D,IAAI,sBAAsB,EAAE,oCAAoC;AAChE,SAAS,WAAW,CAAC,KAAK,EAAE;AAC5B,EAAE,GAAG,CAAC,CAAC,wBAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;AAC/B,IAAI,MAAM,IAAI,sCAAe,CAAC,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,wBAAM,EAAE,CAAC,CAAC;AACvI,EAAE;AACF;AACA,IAAI,IAAI,EAAE,kBAAkB;AAC5B,SAAS,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE;AACrC,EAAE,GAAG,CAAC,MAAM,IAAI,KAAK,EAAE,GAAG,MAAM,IAAI,QAAQ,EAAE,OAAO,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;AAC3E,EAAE,GAAG,CAAC,MAAM,IAAI,UAAU,EAAE;AAC5B,IAAI,MAAM,IAAI,sCAAe,CAAC,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,iBAAA;AACA,kBAAA;AACA,kBAAA;AACA,kBAAA;AACA,kBAAA;AACA,kBAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,oBAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,MAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,UAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,UAAA;AACA,UAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,UAAA;AACA,QAAA;AACA,UAAA;AACA,QAAA;AACA,QAAA;AACA,UAAA;AACA,QAAA;AACA,UAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,UAAA;AACA,UAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACA,UAAA;AACA,YAAA;AACA,YAAA;AACA,cAAA;AACA,cAAA;AACA,YAAA;AACA,UAAA;AACA,QAAA;AACA,QAAA;AACA,UAAA;AACA,UAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,sBAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,oBAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"C:\\Users\\davis\\Desktop\\cabalspy-web\\github\\cabalspy-id-js\\dist\\chunk-P3MDLWLN.cjs","sourcesContent":[null]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["c:\\Users\\davis\\Desktop\\cabalspy-web\\github\\cabalspy-id-js\\dist\\chunk-X3OFGGSE.cjs"],"names":[],"mappings":"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AACA,UAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,QAAA;AACA,MAAA;AACA,QAAA;AACA,UAAA;AACA,YAAA;AACA,UAAA;AACA,QAAA;AACA,QAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,QAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"C:\\Users\\davis\\Desktop\\cabalspy-web\\github\\cabalspy-id-js\\dist\\chunk-X3OFGGSE.cjs","sourcesContent":[null]}
|