@cexyio/cexy 0.1.0-dev.0 → 0.1.0-dev.3
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/README.md +9 -4
- package/dist/index.cjs +23 -5
- package/dist/index.d.cts +10 -4
- package/dist/index.d.ts +10 -4
- package/dist/index.js +23 -6
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -5,16 +5,17 @@ The official TypeScript/JavaScript SDK for the [CEXY.io](https://cexy.io) REST a
|
|
|
5
5
|
- Typed models generated from the public OpenAPI spec ([cexy-api-spec](https://github.com/cexyio/cexy-api-spec)).
|
|
6
6
|
- Safe by default: retries with backoff, order placement that never duplicates (via `client_order_id`), a client-side rate limiter.
|
|
7
7
|
- A WebSocket client with heartbeat, reconnect and a live order book that applies the sync rules for you.
|
|
8
|
-
- ESM and CommonJS, Node
|
|
8
|
+
- ESM and CommonJS, Node 22+, zero runtime dependencies.
|
|
9
9
|
|
|
10
10
|
> **Status: 0.x.** The API is not yet frozen. It stays 0.x until the exchange ships HMAC request signing,
|
|
11
11
|
> which will change how credentials are sent.
|
|
12
|
+
> Pre-release: `npm install @cexyio/cexy@next`; `latest` currently points at a pre-release until 1.0.
|
|
12
13
|
|
|
13
14
|
## Install
|
|
14
15
|
|
|
15
16
|
```bash
|
|
16
|
-
npm install @cexyio/cexy
|
|
17
|
-
# Node only, optional: lets the WebSocket client send a User-Agent
|
|
17
|
+
npm install @cexyio/cexy@next
|
|
18
|
+
# Node only, optional: lets the WebSocket client send a User-Agent
|
|
18
19
|
npm install ws
|
|
19
20
|
```
|
|
20
21
|
|
|
@@ -102,6 +103,7 @@ Every API failure throws a `CexyApiError` (or a subclass) with `status`, `code`,
|
|
|
102
103
|
|---|---|
|
|
103
104
|
| `AuthenticationError` | 401: missing or invalid credentials |
|
|
104
105
|
| `ForbiddenError` | 403: the key lacks a scope (`FORBIDDEN`), or the route is session-only (`API_KEY_NOT_ALLOWED`) |
|
|
106
|
+
| `JurisdictionBlockedError` | 451: `JURISDICTION_BLOCKED` (not available in the caller's jurisdiction); a `ForbiddenError` subclass |
|
|
105
107
|
| `ValidationError` | 400: see `fields` |
|
|
106
108
|
| `NotFoundError` | 404 |
|
|
107
109
|
| `ConflictError` | 409: `ALREADY_EXISTS`, `IDEMPOTENCY_KEY_CONFLICT`, `CONCURRENT_MODIFICATION` |
|
|
@@ -213,7 +215,7 @@ use public channels and poll REST for private state. If the session is revoked,
|
|
|
213
215
|
`authLost`; public channels keep working.
|
|
214
216
|
|
|
215
217
|
In Node the client uses the optional `ws` package when installed (so it can send the SDK User-Agent),
|
|
216
|
-
otherwise the global `WebSocket` (Node
|
|
218
|
+
otherwise the global `WebSocket` (Node, browsers).
|
|
217
219
|
|
|
218
220
|
## Browsers
|
|
219
221
|
|
|
@@ -227,6 +229,9 @@ endpoints from a server. Browsers do not let scripts set `User-Agent`, so the SD
|
|
|
227
229
|
- Credentials go only in the `X-API-Key` / `X-API-Secret` headers and only on private endpoints; never in URLs.
|
|
228
230
|
- Only `https://` base URLs and `wss://` WebSocket URLs are accepted. `allowInsecure: true` permits
|
|
229
231
|
`http://` / `ws://` solely for `localhost`, `127.0.0.1` or `::1` (local test servers).
|
|
232
|
+
- The SDK **never follows HTTP redirects**. A 3xx answer throws a `CexyApiError` with code
|
|
233
|
+
`UNEXPECTED_REDIRECT` (not retried), so credentials are never re-sent to another host and an order
|
|
234
|
+
is never re-posted to a redirect target. If you pass your own `fetch`, it must honour `redirect: "manual"`.
|
|
230
235
|
- The SDK redacts the secret from `toString()`, `util.inspect`, `JSON.stringify` and error messages.
|
|
231
236
|
- Keep keys in environment variables or a secret manager, not in code.
|
|
232
237
|
|
package/dist/index.cjs
CHANGED
|
@@ -56,6 +56,8 @@ var AuthenticationError = class extends CexyApiError {
|
|
|
56
56
|
};
|
|
57
57
|
var ForbiddenError = class extends CexyApiError {
|
|
58
58
|
};
|
|
59
|
+
var JurisdictionBlockedError = class extends ForbiddenError {
|
|
60
|
+
};
|
|
59
61
|
var NotFoundError = class extends CexyApiError {
|
|
60
62
|
};
|
|
61
63
|
var ValidationError = class extends CexyApiError {
|
|
@@ -78,8 +80,8 @@ var STATUS_CLASSES = {
|
|
|
78
80
|
401: AuthenticationError,
|
|
79
81
|
403: ForbiddenError,
|
|
80
82
|
404: NotFoundError,
|
|
81
|
-
451:
|
|
82
|
-
// unavailable for legal reasons
|
|
83
|
+
451: JurisdictionBlockedError,
|
|
84
|
+
// unavailable for legal reasons
|
|
83
85
|
409: ConflictError,
|
|
84
86
|
422: UnprocessableError
|
|
85
87
|
};
|
|
@@ -172,6 +174,7 @@ function errorFromResponse(status, body, headers, redact = (t) => t) {
|
|
|
172
174
|
if (status === 429 || init.code === "RATE_LIMITED") {
|
|
173
175
|
return new RateLimitError(init, retryAfterMs(headers, init.details));
|
|
174
176
|
}
|
|
177
|
+
if (init.code === "JURISDICTION_BLOCKED") return new JurisdictionBlockedError(init);
|
|
175
178
|
if (env && !isKnownErrorCode(env.code)) return new CexyApiError(init);
|
|
176
179
|
if (status >= 500) return new ServerError(init);
|
|
177
180
|
const Cls = STATUS_CLASSES[status] ?? CexyApiError;
|
|
@@ -391,7 +394,13 @@ var Transport = class {
|
|
|
391
394
|
let res;
|
|
392
395
|
let text;
|
|
393
396
|
try {
|
|
394
|
-
res = await this.config.fetch(url.toString(), {
|
|
397
|
+
res = await this.config.fetch(url.toString(), {
|
|
398
|
+
method: info.method,
|
|
399
|
+
headers,
|
|
400
|
+
body,
|
|
401
|
+
signal: ctrl.signal,
|
|
402
|
+
redirect: "manual"
|
|
403
|
+
});
|
|
395
404
|
text = await res.text();
|
|
396
405
|
} catch (err) {
|
|
397
406
|
if (opts.signal?.aborted) throw opts.signal.reason ?? err;
|
|
@@ -403,6 +412,14 @@ var Transport = class {
|
|
|
403
412
|
clearTimeout(timer);
|
|
404
413
|
opts.signal?.removeEventListener("abort", onAbort);
|
|
405
414
|
}
|
|
415
|
+
if (res.type === "opaqueredirect" || res.status >= 300 && res.status < 400 || res.redirected) {
|
|
416
|
+
throw new CexyApiError({
|
|
417
|
+
status: res.status,
|
|
418
|
+
code: "UNEXPECTED_REDIRECT",
|
|
419
|
+
message: `${info.method} ${info.path}: the server answered with a redirect (HTTP ${res.status}); the SDK does not follow redirects. Check baseUrl.`,
|
|
420
|
+
retryable: false
|
|
421
|
+
});
|
|
422
|
+
}
|
|
406
423
|
this.config.limiter?.update(res.headers);
|
|
407
424
|
if (!res.ok) {
|
|
408
425
|
const parsed = safeJson(text);
|
|
@@ -901,7 +918,7 @@ var TradingResource = class extends Resource {
|
|
|
901
918
|
};
|
|
902
919
|
|
|
903
920
|
// src/version.ts
|
|
904
|
-
var VERSION = "0.1.0-dev.
|
|
921
|
+
var VERSION = "0.1.0-dev.3";
|
|
905
922
|
var USER_AGENT = `cexy-typescript/${VERSION}`;
|
|
906
923
|
|
|
907
924
|
// src/ws/emitter.ts
|
|
@@ -1661,7 +1678,7 @@ var CexyClient = class {
|
|
|
1661
1678
|
assertSecureUrl(parsed, "https:", "http:", options.allowInsecure === true, "baseUrl");
|
|
1662
1679
|
this.#allowInsecure = options.allowInsecure === true;
|
|
1663
1680
|
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
1664
|
-
if (!fetchImpl) throw new CexyConfigError("no global fetch found (Node
|
|
1681
|
+
if (!fetchImpl) throw new CexyConfigError("no global fetch found (Node 22+ required); pass options.fetch");
|
|
1665
1682
|
const timeoutMs = options.timeoutMs ?? 1e4;
|
|
1666
1683
|
const maxRetries = options.maxRetries ?? 3;
|
|
1667
1684
|
if (!(timeoutMs > 0)) throw new CexyConfigError("timeoutMs must be > 0");
|
|
@@ -1772,6 +1789,7 @@ exports.ExportsResource = ExportsResource;
|
|
|
1772
1789
|
exports.FeesResource = FeesResource;
|
|
1773
1790
|
exports.ForbiddenError = ForbiddenError;
|
|
1774
1791
|
exports.InvalidAmountError = InvalidAmountError;
|
|
1792
|
+
exports.JurisdictionBlockedError = JurisdictionBlockedError;
|
|
1775
1793
|
exports.KNOWN_EVENT_TYPES = KNOWN_EVENT_TYPES;
|
|
1776
1794
|
exports.LiveOrderBook = LiveOrderBook;
|
|
1777
1795
|
exports.MarketsResource = MarketsResource;
|
package/dist/index.d.cts
CHANGED
|
@@ -3458,6 +3458,12 @@ declare class AuthenticationError extends CexyApiError {
|
|
|
3458
3458
|
/** 403: the key lacks a scope (`FORBIDDEN`), or the route is session-only (`API_KEY_NOT_ALLOWED`). */
|
|
3459
3459
|
declare class ForbiddenError extends CexyApiError {
|
|
3460
3460
|
}
|
|
3461
|
+
/**
|
|
3462
|
+
* 451: not available in the caller's jurisdiction (`JURISDICTION_BLOCKED`). A `ForbiddenError`
|
|
3463
|
+
* subclass, so existing `instanceof ForbiddenError` checks still match. Retrying will not help.
|
|
3464
|
+
*/
|
|
3465
|
+
declare class JurisdictionBlockedError extends ForbiddenError {
|
|
3466
|
+
}
|
|
3461
3467
|
/** 404 */
|
|
3462
3468
|
declare class NotFoundError extends CexyApiError {
|
|
3463
3469
|
}
|
|
@@ -3838,7 +3844,7 @@ interface CexyClientOptions {
|
|
|
3838
3844
|
timeoutMs?: number;
|
|
3839
3845
|
/** Retries after the first attempt for retryable failures. Default 3. */
|
|
3840
3846
|
maxRetries?: number;
|
|
3841
|
-
/** A `fetch` implementation. Default: the global `fetch` (Node
|
|
3847
|
+
/** A `fetch` implementation. Default: the global `fetch` (Node 22+, browsers). */
|
|
3842
3848
|
fetch?: FetchLike;
|
|
3843
3849
|
/**
|
|
3844
3850
|
* Client-side rate limit in requests per minute, or `false` to disable. Default 100/min
|
|
@@ -3919,11 +3925,11 @@ declare function isAmount(value: unknown): value is Amount;
|
|
|
3919
3925
|
declare function assertAmountFields(body: Record<string, unknown>, fields: readonly string[], context: string): void;
|
|
3920
3926
|
|
|
3921
3927
|
/** SDK version, kept in sync with package.json (a test enforces this). */
|
|
3922
|
-
declare const VERSION = "0.1.0-dev.
|
|
3928
|
+
declare const VERSION = "0.1.0-dev.3";
|
|
3923
3929
|
/** Default User-Agent product token. */
|
|
3924
|
-
declare const USER_AGENT = "cexy-typescript/0.1.0-dev.
|
|
3930
|
+
declare const USER_AGENT = "cexy-typescript/0.1.0-dev.3";
|
|
3925
3931
|
|
|
3926
3932
|
/** True for loopback hosts, the only ones where plain-text transport may be allowed. */
|
|
3927
3933
|
declare function isLocalHost(hostname: string): boolean;
|
|
3928
3934
|
|
|
3929
|
-
export { AccountResource, type Amount, type ApiKey, ApiKeyAuthenticator, type ApiScope, type Asset, type AssetNetwork, AssetsResource, type AuthRequest, type AuthResult, type AuthenticatedFrame, AuthenticationError, type Authenticator, type Balance, type BalanceUpdatedEvent, type BookLevel, type CancelAllParams, type CancelAllRequest, type CancelAllResult, type Candle, type CandleInterval, CexyApiError, type CexyApiErrorInit, CexyClient, type CexyClientOptions, CexyConfigError, CexyConnectionError, CexyError, CexyTimeoutError, CexyWebSocket, CexyWebSocketError, type CexyWebSocketEvents, type CexyWebSocketOptions, type CloseInfo, ConflictError, type CursorParams, DEFAULT_BASE_URL, DEFAULT_RPM_ANONYMOUS, DEFAULT_RPM_WITH_KEY, DEFAULT_WS_URL, type Deposit, type DepositAddress, type DepositEvent, type DepositStatus, type ErrorBody, type ErrorCode, type ErrorFrame, type EventMap, type ExchangeConfig, type ExitPoolRequest, type ExitPoolResult, ExportsResource, type FeeSchedule, FeesResource, type FetchLike, type Fill, ForbiddenError, InvalidAmountError, type IterateOptions, type JoinPoolRequest, type JoinPoolResult, KNOWN_EVENT_TYPES, type KnownErrorCode, type LedgerEntry, type LedgerEntryKind, type LiquidityRole, type Listener, LiveOrderBook, type LiveOrderBookEvents, type LiveOrderBookOptions, type MaintenanceState, type Market, type MarketStatus, type MarketStatusEvent, MarketsResource, type Network, NetworksResource, NotFoundError, type Notification, type NotificationKind, OPERATIONS, type OperationAuth, type OperationId, type OperationInfo, type OperationScope, type Order, type OrderBook, type OrderBookUpdateData, type OrderBookUpdateEvent, type OrderEvent, type OrderSide, OrderStateUnknownError, type OrderStatus, type OrderType, PRIVATE_CHANNELS, type Page, type PlaceOrderRequest, type PlaceOrderResponse, type PlaceOrderResult, type PongFrame, type Pool, type PoolStatus, PoolsResource, type PublicTrade, type QueryOf, RateLimitError, RateLimiter, type RateLimiterOptions, type RateLimiterState, type ReconnectOptions, type RequestOptions, type ResyncReason, type RetryInfo, SUPPORTED_PROTOCOL_VERSION, ServerError, type ServerTime, type SessionRevokedData, type SessionRevokedEvent, type SnapshotSource, type SortDirection, type SubAccount, type SubscribeResult, type SubscribedFrame, type TickerUpdateEvent, type TimeInForce, type TradeNewEvent, TradingResource, type TriggerDirection, TypedEmitter, USER_AGENT, UnprocessableError, type UnsubscribedFrame, VERSION, ValidationError, WS_BOOK_DEPTH, WalletResource, type WebSocketConstructor, type WebSocketLike, type WelcomeFrame, type Withdrawal, type WithdrawalAddress, type WithdrawalStatus, type WithdrawalUpdatedEvent, type WsEvent, type WsLogger, assertAmountFields, type components, errorFromResponse, isAmount, isKnownErrorCode, isLocalHost, isRetryable, type operations, paginate, type paths };
|
|
3935
|
+
export { AccountResource, type Amount, type ApiKey, ApiKeyAuthenticator, type ApiScope, type Asset, type AssetNetwork, AssetsResource, type AuthRequest, type AuthResult, type AuthenticatedFrame, AuthenticationError, type Authenticator, type Balance, type BalanceUpdatedEvent, type BookLevel, type CancelAllParams, type CancelAllRequest, type CancelAllResult, type Candle, type CandleInterval, CexyApiError, type CexyApiErrorInit, CexyClient, type CexyClientOptions, CexyConfigError, CexyConnectionError, CexyError, CexyTimeoutError, CexyWebSocket, CexyWebSocketError, type CexyWebSocketEvents, type CexyWebSocketOptions, type CloseInfo, ConflictError, type CursorParams, DEFAULT_BASE_URL, DEFAULT_RPM_ANONYMOUS, DEFAULT_RPM_WITH_KEY, DEFAULT_WS_URL, type Deposit, type DepositAddress, type DepositEvent, type DepositStatus, type ErrorBody, type ErrorCode, type ErrorFrame, type EventMap, type ExchangeConfig, type ExitPoolRequest, type ExitPoolResult, ExportsResource, type FeeSchedule, FeesResource, type FetchLike, type Fill, ForbiddenError, InvalidAmountError, type IterateOptions, type JoinPoolRequest, type JoinPoolResult, JurisdictionBlockedError, KNOWN_EVENT_TYPES, type KnownErrorCode, type LedgerEntry, type LedgerEntryKind, type LiquidityRole, type Listener, LiveOrderBook, type LiveOrderBookEvents, type LiveOrderBookOptions, type MaintenanceState, type Market, type MarketStatus, type MarketStatusEvent, MarketsResource, type Network, NetworksResource, NotFoundError, type Notification, type NotificationKind, OPERATIONS, type OperationAuth, type OperationId, type OperationInfo, type OperationScope, type Order, type OrderBook, type OrderBookUpdateData, type OrderBookUpdateEvent, type OrderEvent, type OrderSide, OrderStateUnknownError, type OrderStatus, type OrderType, PRIVATE_CHANNELS, type Page, type PlaceOrderRequest, type PlaceOrderResponse, type PlaceOrderResult, type PongFrame, type Pool, type PoolStatus, PoolsResource, type PublicTrade, type QueryOf, RateLimitError, RateLimiter, type RateLimiterOptions, type RateLimiterState, type ReconnectOptions, type RequestOptions, type ResyncReason, type RetryInfo, SUPPORTED_PROTOCOL_VERSION, ServerError, type ServerTime, type SessionRevokedData, type SessionRevokedEvent, type SnapshotSource, type SortDirection, type SubAccount, type SubscribeResult, type SubscribedFrame, type TickerUpdateEvent, type TimeInForce, type TradeNewEvent, TradingResource, type TriggerDirection, TypedEmitter, USER_AGENT, UnprocessableError, type UnsubscribedFrame, VERSION, ValidationError, WS_BOOK_DEPTH, WalletResource, type WebSocketConstructor, type WebSocketLike, type WelcomeFrame, type Withdrawal, type WithdrawalAddress, type WithdrawalStatus, type WithdrawalUpdatedEvent, type WsEvent, type WsLogger, assertAmountFields, type components, errorFromResponse, isAmount, isKnownErrorCode, isLocalHost, isRetryable, type operations, paginate, type paths };
|
package/dist/index.d.ts
CHANGED
|
@@ -3458,6 +3458,12 @@ declare class AuthenticationError extends CexyApiError {
|
|
|
3458
3458
|
/** 403: the key lacks a scope (`FORBIDDEN`), or the route is session-only (`API_KEY_NOT_ALLOWED`). */
|
|
3459
3459
|
declare class ForbiddenError extends CexyApiError {
|
|
3460
3460
|
}
|
|
3461
|
+
/**
|
|
3462
|
+
* 451: not available in the caller's jurisdiction (`JURISDICTION_BLOCKED`). A `ForbiddenError`
|
|
3463
|
+
* subclass, so existing `instanceof ForbiddenError` checks still match. Retrying will not help.
|
|
3464
|
+
*/
|
|
3465
|
+
declare class JurisdictionBlockedError extends ForbiddenError {
|
|
3466
|
+
}
|
|
3461
3467
|
/** 404 */
|
|
3462
3468
|
declare class NotFoundError extends CexyApiError {
|
|
3463
3469
|
}
|
|
@@ -3838,7 +3844,7 @@ interface CexyClientOptions {
|
|
|
3838
3844
|
timeoutMs?: number;
|
|
3839
3845
|
/** Retries after the first attempt for retryable failures. Default 3. */
|
|
3840
3846
|
maxRetries?: number;
|
|
3841
|
-
/** A `fetch` implementation. Default: the global `fetch` (Node
|
|
3847
|
+
/** A `fetch` implementation. Default: the global `fetch` (Node 22+, browsers). */
|
|
3842
3848
|
fetch?: FetchLike;
|
|
3843
3849
|
/**
|
|
3844
3850
|
* Client-side rate limit in requests per minute, or `false` to disable. Default 100/min
|
|
@@ -3919,11 +3925,11 @@ declare function isAmount(value: unknown): value is Amount;
|
|
|
3919
3925
|
declare function assertAmountFields(body: Record<string, unknown>, fields: readonly string[], context: string): void;
|
|
3920
3926
|
|
|
3921
3927
|
/** SDK version, kept in sync with package.json (a test enforces this). */
|
|
3922
|
-
declare const VERSION = "0.1.0-dev.
|
|
3928
|
+
declare const VERSION = "0.1.0-dev.3";
|
|
3923
3929
|
/** Default User-Agent product token. */
|
|
3924
|
-
declare const USER_AGENT = "cexy-typescript/0.1.0-dev.
|
|
3930
|
+
declare const USER_AGENT = "cexy-typescript/0.1.0-dev.3";
|
|
3925
3931
|
|
|
3926
3932
|
/** True for loopback hosts, the only ones where plain-text transport may be allowed. */
|
|
3927
3933
|
declare function isLocalHost(hostname: string): boolean;
|
|
3928
3934
|
|
|
3929
|
-
export { AccountResource, type Amount, type ApiKey, ApiKeyAuthenticator, type ApiScope, type Asset, type AssetNetwork, AssetsResource, type AuthRequest, type AuthResult, type AuthenticatedFrame, AuthenticationError, type Authenticator, type Balance, type BalanceUpdatedEvent, type BookLevel, type CancelAllParams, type CancelAllRequest, type CancelAllResult, type Candle, type CandleInterval, CexyApiError, type CexyApiErrorInit, CexyClient, type CexyClientOptions, CexyConfigError, CexyConnectionError, CexyError, CexyTimeoutError, CexyWebSocket, CexyWebSocketError, type CexyWebSocketEvents, type CexyWebSocketOptions, type CloseInfo, ConflictError, type CursorParams, DEFAULT_BASE_URL, DEFAULT_RPM_ANONYMOUS, DEFAULT_RPM_WITH_KEY, DEFAULT_WS_URL, type Deposit, type DepositAddress, type DepositEvent, type DepositStatus, type ErrorBody, type ErrorCode, type ErrorFrame, type EventMap, type ExchangeConfig, type ExitPoolRequest, type ExitPoolResult, ExportsResource, type FeeSchedule, FeesResource, type FetchLike, type Fill, ForbiddenError, InvalidAmountError, type IterateOptions, type JoinPoolRequest, type JoinPoolResult, KNOWN_EVENT_TYPES, type KnownErrorCode, type LedgerEntry, type LedgerEntryKind, type LiquidityRole, type Listener, LiveOrderBook, type LiveOrderBookEvents, type LiveOrderBookOptions, type MaintenanceState, type Market, type MarketStatus, type MarketStatusEvent, MarketsResource, type Network, NetworksResource, NotFoundError, type Notification, type NotificationKind, OPERATIONS, type OperationAuth, type OperationId, type OperationInfo, type OperationScope, type Order, type OrderBook, type OrderBookUpdateData, type OrderBookUpdateEvent, type OrderEvent, type OrderSide, OrderStateUnknownError, type OrderStatus, type OrderType, PRIVATE_CHANNELS, type Page, type PlaceOrderRequest, type PlaceOrderResponse, type PlaceOrderResult, type PongFrame, type Pool, type PoolStatus, PoolsResource, type PublicTrade, type QueryOf, RateLimitError, RateLimiter, type RateLimiterOptions, type RateLimiterState, type ReconnectOptions, type RequestOptions, type ResyncReason, type RetryInfo, SUPPORTED_PROTOCOL_VERSION, ServerError, type ServerTime, type SessionRevokedData, type SessionRevokedEvent, type SnapshotSource, type SortDirection, type SubAccount, type SubscribeResult, type SubscribedFrame, type TickerUpdateEvent, type TimeInForce, type TradeNewEvent, TradingResource, type TriggerDirection, TypedEmitter, USER_AGENT, UnprocessableError, type UnsubscribedFrame, VERSION, ValidationError, WS_BOOK_DEPTH, WalletResource, type WebSocketConstructor, type WebSocketLike, type WelcomeFrame, type Withdrawal, type WithdrawalAddress, type WithdrawalStatus, type WithdrawalUpdatedEvent, type WsEvent, type WsLogger, assertAmountFields, type components, errorFromResponse, isAmount, isKnownErrorCode, isLocalHost, isRetryable, type operations, paginate, type paths };
|
|
3935
|
+
export { AccountResource, type Amount, type ApiKey, ApiKeyAuthenticator, type ApiScope, type Asset, type AssetNetwork, AssetsResource, type AuthRequest, type AuthResult, type AuthenticatedFrame, AuthenticationError, type Authenticator, type Balance, type BalanceUpdatedEvent, type BookLevel, type CancelAllParams, type CancelAllRequest, type CancelAllResult, type Candle, type CandleInterval, CexyApiError, type CexyApiErrorInit, CexyClient, type CexyClientOptions, CexyConfigError, CexyConnectionError, CexyError, CexyTimeoutError, CexyWebSocket, CexyWebSocketError, type CexyWebSocketEvents, type CexyWebSocketOptions, type CloseInfo, ConflictError, type CursorParams, DEFAULT_BASE_URL, DEFAULT_RPM_ANONYMOUS, DEFAULT_RPM_WITH_KEY, DEFAULT_WS_URL, type Deposit, type DepositAddress, type DepositEvent, type DepositStatus, type ErrorBody, type ErrorCode, type ErrorFrame, type EventMap, type ExchangeConfig, type ExitPoolRequest, type ExitPoolResult, ExportsResource, type FeeSchedule, FeesResource, type FetchLike, type Fill, ForbiddenError, InvalidAmountError, type IterateOptions, type JoinPoolRequest, type JoinPoolResult, JurisdictionBlockedError, KNOWN_EVENT_TYPES, type KnownErrorCode, type LedgerEntry, type LedgerEntryKind, type LiquidityRole, type Listener, LiveOrderBook, type LiveOrderBookEvents, type LiveOrderBookOptions, type MaintenanceState, type Market, type MarketStatus, type MarketStatusEvent, MarketsResource, type Network, NetworksResource, NotFoundError, type Notification, type NotificationKind, OPERATIONS, type OperationAuth, type OperationId, type OperationInfo, type OperationScope, type Order, type OrderBook, type OrderBookUpdateData, type OrderBookUpdateEvent, type OrderEvent, type OrderSide, OrderStateUnknownError, type OrderStatus, type OrderType, PRIVATE_CHANNELS, type Page, type PlaceOrderRequest, type PlaceOrderResponse, type PlaceOrderResult, type PongFrame, type Pool, type PoolStatus, PoolsResource, type PublicTrade, type QueryOf, RateLimitError, RateLimiter, type RateLimiterOptions, type RateLimiterState, type ReconnectOptions, type RequestOptions, type ResyncReason, type RetryInfo, SUPPORTED_PROTOCOL_VERSION, ServerError, type ServerTime, type SessionRevokedData, type SessionRevokedEvent, type SnapshotSource, type SortDirection, type SubAccount, type SubscribeResult, type SubscribedFrame, type TickerUpdateEvent, type TimeInForce, type TradeNewEvent, TradingResource, type TriggerDirection, TypedEmitter, USER_AGENT, UnprocessableError, type UnsubscribedFrame, VERSION, ValidationError, WS_BOOK_DEPTH, WalletResource, type WebSocketConstructor, type WebSocketLike, type WelcomeFrame, type Withdrawal, type WithdrawalAddress, type WithdrawalStatus, type WithdrawalUpdatedEvent, type WsEvent, type WsLogger, assertAmountFields, type components, errorFromResponse, isAmount, isKnownErrorCode, isLocalHost, isRetryable, type operations, paginate, type paths };
|
package/dist/index.js
CHANGED
|
@@ -54,6 +54,8 @@ var AuthenticationError = class extends CexyApiError {
|
|
|
54
54
|
};
|
|
55
55
|
var ForbiddenError = class extends CexyApiError {
|
|
56
56
|
};
|
|
57
|
+
var JurisdictionBlockedError = class extends ForbiddenError {
|
|
58
|
+
};
|
|
57
59
|
var NotFoundError = class extends CexyApiError {
|
|
58
60
|
};
|
|
59
61
|
var ValidationError = class extends CexyApiError {
|
|
@@ -76,8 +78,8 @@ var STATUS_CLASSES = {
|
|
|
76
78
|
401: AuthenticationError,
|
|
77
79
|
403: ForbiddenError,
|
|
78
80
|
404: NotFoundError,
|
|
79
|
-
451:
|
|
80
|
-
// unavailable for legal reasons
|
|
81
|
+
451: JurisdictionBlockedError,
|
|
82
|
+
// unavailable for legal reasons
|
|
81
83
|
409: ConflictError,
|
|
82
84
|
422: UnprocessableError
|
|
83
85
|
};
|
|
@@ -170,6 +172,7 @@ function errorFromResponse(status, body, headers, redact = (t) => t) {
|
|
|
170
172
|
if (status === 429 || init.code === "RATE_LIMITED") {
|
|
171
173
|
return new RateLimitError(init, retryAfterMs(headers, init.details));
|
|
172
174
|
}
|
|
175
|
+
if (init.code === "JURISDICTION_BLOCKED") return new JurisdictionBlockedError(init);
|
|
173
176
|
if (env && !isKnownErrorCode(env.code)) return new CexyApiError(init);
|
|
174
177
|
if (status >= 500) return new ServerError(init);
|
|
175
178
|
const Cls = STATUS_CLASSES[status] ?? CexyApiError;
|
|
@@ -389,7 +392,13 @@ var Transport = class {
|
|
|
389
392
|
let res;
|
|
390
393
|
let text;
|
|
391
394
|
try {
|
|
392
|
-
res = await this.config.fetch(url.toString(), {
|
|
395
|
+
res = await this.config.fetch(url.toString(), {
|
|
396
|
+
method: info.method,
|
|
397
|
+
headers,
|
|
398
|
+
body,
|
|
399
|
+
signal: ctrl.signal,
|
|
400
|
+
redirect: "manual"
|
|
401
|
+
});
|
|
393
402
|
text = await res.text();
|
|
394
403
|
} catch (err) {
|
|
395
404
|
if (opts.signal?.aborted) throw opts.signal.reason ?? err;
|
|
@@ -401,6 +410,14 @@ var Transport = class {
|
|
|
401
410
|
clearTimeout(timer);
|
|
402
411
|
opts.signal?.removeEventListener("abort", onAbort);
|
|
403
412
|
}
|
|
413
|
+
if (res.type === "opaqueredirect" || res.status >= 300 && res.status < 400 || res.redirected) {
|
|
414
|
+
throw new CexyApiError({
|
|
415
|
+
status: res.status,
|
|
416
|
+
code: "UNEXPECTED_REDIRECT",
|
|
417
|
+
message: `${info.method} ${info.path}: the server answered with a redirect (HTTP ${res.status}); the SDK does not follow redirects. Check baseUrl.`,
|
|
418
|
+
retryable: false
|
|
419
|
+
});
|
|
420
|
+
}
|
|
404
421
|
this.config.limiter?.update(res.headers);
|
|
405
422
|
if (!res.ok) {
|
|
406
423
|
const parsed = safeJson(text);
|
|
@@ -899,7 +916,7 @@ var TradingResource = class extends Resource {
|
|
|
899
916
|
};
|
|
900
917
|
|
|
901
918
|
// src/version.ts
|
|
902
|
-
var VERSION = "0.1.0-dev.
|
|
919
|
+
var VERSION = "0.1.0-dev.3";
|
|
903
920
|
var USER_AGENT = `cexy-typescript/${VERSION}`;
|
|
904
921
|
|
|
905
922
|
// src/ws/emitter.ts
|
|
@@ -1659,7 +1676,7 @@ var CexyClient = class {
|
|
|
1659
1676
|
assertSecureUrl(parsed, "https:", "http:", options.allowInsecure === true, "baseUrl");
|
|
1660
1677
|
this.#allowInsecure = options.allowInsecure === true;
|
|
1661
1678
|
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
1662
|
-
if (!fetchImpl) throw new CexyConfigError("no global fetch found (Node
|
|
1679
|
+
if (!fetchImpl) throw new CexyConfigError("no global fetch found (Node 22+ required); pass options.fetch");
|
|
1663
1680
|
const timeoutMs = options.timeoutMs ?? 1e4;
|
|
1664
1681
|
const maxRetries = options.maxRetries ?? 3;
|
|
1665
1682
|
if (!(timeoutMs > 0)) throw new CexyConfigError("timeoutMs must be > 0");
|
|
@@ -1749,4 +1766,4 @@ function canSetUserAgent() {
|
|
|
1749
1766
|
return !(typeof g.window !== "undefined" && typeof g.window.document !== "undefined");
|
|
1750
1767
|
}
|
|
1751
1768
|
|
|
1752
|
-
export { AccountResource, ApiKeyAuthenticator, AssetsResource, AuthenticationError, CexyApiError, CexyClient, CexyConfigError, CexyConnectionError, CexyError, CexyTimeoutError, CexyWebSocket, CexyWebSocketError, ConflictError, DEFAULT_BASE_URL, DEFAULT_RPM_ANONYMOUS, DEFAULT_RPM_WITH_KEY, DEFAULT_WS_URL, ExportsResource, FeesResource, ForbiddenError, InvalidAmountError, KNOWN_EVENT_TYPES, LiveOrderBook, MarketsResource, NetworksResource, NotFoundError, OPERATIONS, OrderStateUnknownError, PRIVATE_CHANNELS, PoolsResource, RateLimitError, RateLimiter, SUPPORTED_PROTOCOL_VERSION, ServerError, TradingResource, TypedEmitter, USER_AGENT, UnprocessableError, VERSION, ValidationError, WS_BOOK_DEPTH, WalletResource, assertAmountFields, errorFromResponse, isAmount, isKnownErrorCode, isLocalHost, isRetryable, paginate };
|
|
1769
|
+
export { AccountResource, ApiKeyAuthenticator, AssetsResource, AuthenticationError, CexyApiError, CexyClient, CexyConfigError, CexyConnectionError, CexyError, CexyTimeoutError, CexyWebSocket, CexyWebSocketError, ConflictError, DEFAULT_BASE_URL, DEFAULT_RPM_ANONYMOUS, DEFAULT_RPM_WITH_KEY, DEFAULT_WS_URL, ExportsResource, FeesResource, ForbiddenError, InvalidAmountError, JurisdictionBlockedError, KNOWN_EVENT_TYPES, LiveOrderBook, MarketsResource, NetworksResource, NotFoundError, OPERATIONS, OrderStateUnknownError, PRIVATE_CHANNELS, PoolsResource, RateLimitError, RateLimiter, SUPPORTED_PROTOCOL_VERSION, ServerError, TradingResource, TypedEmitter, USER_AGENT, UnprocessableError, VERSION, ValidationError, WS_BOOK_DEPTH, WalletResource, assertAmountFields, errorFromResponse, isAmount, isKnownErrorCode, isLocalHost, isRetryable, paginate };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cexyio/cexy",
|
|
3
|
-
"version": "0.1.0-dev.
|
|
3
|
+
"version": "0.1.0-dev.3",
|
|
4
4
|
"description": "Official TypeScript/JavaScript SDK for the CEXY.io REST and WebSocket API",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "CEXY.io",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
],
|
|
44
44
|
"sideEffects": false,
|
|
45
45
|
"engines": {
|
|
46
|
-
"node": ">=
|
|
46
|
+
"node": ">=22"
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
49
49
|
"generate": "node scripts/generate.mjs",
|
|
@@ -65,16 +65,16 @@
|
|
|
65
65
|
}
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
|
-
"@eslint/js": "^
|
|
69
|
-
"@types/node": "^20.
|
|
68
|
+
"@eslint/js": "^10.0.1",
|
|
69
|
+
"@types/node": "^22.20.4",
|
|
70
70
|
"@types/ws": "^8.18.0",
|
|
71
|
-
"eslint": "^
|
|
71
|
+
"eslint": "^10.11.0",
|
|
72
72
|
"openapi-typescript": "^7.13.0",
|
|
73
73
|
"tsup": "^8.5.0",
|
|
74
74
|
"typescript": "~5.9.3",
|
|
75
75
|
"typescript-eslint": "^8.70.0",
|
|
76
|
-
"vite": "^
|
|
77
|
-
"vitest": "^
|
|
76
|
+
"vite": "^8.3.0",
|
|
77
|
+
"vitest": "^5.0.2",
|
|
78
78
|
"ws": "^8.18.0"
|
|
79
79
|
},
|
|
80
80
|
"publishConfig": {
|