@cexyio/cexy 0.1.0-dev.6 → 0.1.0-dev.7
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 +13 -3
- package/dist/index.cjs +42 -10
- package/dist/index.d.cts +105 -6
- package/dist/index.d.ts +105 -6
- package/dist/index.js +42 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -46,6 +46,8 @@ const cexy = new CexyClient({
|
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
const balances = await cexy.account.balances();
|
|
49
|
+
// A sub-account's balances (parent account only; same shape, incl. held_incoming):
|
|
50
|
+
const subBalances = await cexy.account.subAccountBalances("sub-account-id");
|
|
49
51
|
const open = await cexy.trading.openOrders({ symbol: "BTC/USDT" });
|
|
50
52
|
|
|
51
53
|
const placed = await cexy.trading.placeOrder({
|
|
@@ -94,7 +96,7 @@ Give both `apiKey` and `apiSecret`, or neither: passing only one throws at const
|
|
|
94
96
|
| `markets` | `list`, `get`, `orderbook`, `trades`, `iterateTrades`, `candles` | public |
|
|
95
97
|
| `assets`, `networks`, `fees`, `pools` | `list`, `get` / `list` / `get` / `list`, `get` | public |
|
|
96
98
|
| `time()`, `config()` | | public |
|
|
97
|
-
| `account` | `balances`, `balance`, `ledger`, `notifications`, `subAccounts`, `apiKeys` (+ iterators) | read |
|
|
99
|
+
| `account` | `balances`, `balance`, `ledger`, `notifications`, `subAccounts`, `subAccountBalances`, `apiKeys` (+ iterators) | read |
|
|
98
100
|
| `exports` | `deposits`, `ledger`, `orders`, `trades`, `withdrawals` (CSV text) | read |
|
|
99
101
|
| `wallet` | `deposits`, `deposit`, `withdrawals`, `withdrawal`, `withdrawalAddresses`, `depositAddress` (+ iterators) | read |
|
|
100
102
|
| `trading` | `openOrders`, `order`, `orderByClientId`, `orderHistory`, `trades` (+ iterators) | read |
|
|
@@ -106,6 +108,13 @@ asset/network (later calls return the same one). Always use the `memo` too when
|
|
|
106
108
|
|
|
107
109
|
There are no withdrawal or transfer methods: API keys cannot withdraw or transfer funds.
|
|
108
110
|
|
|
111
|
+
**Held incoming transfers.** Each balance has `held_incoming`: incoming internal transfers still
|
|
112
|
+
held, as `{ transfer_id, amount, available_at }`. Their sum is **already included in `locked`**, so
|
|
113
|
+
never add them to `locked` or `total` again. There are at most 100 entries, soonest `available_at`
|
|
114
|
+
first (millisecond precision), with no sender identity. An entry disappears once the transfer is
|
|
115
|
+
released (the amount moves to `available`) or cancelled by the exchange. It is always an array
|
|
116
|
+
(`[]` when none, including from servers that predate the field).
|
|
117
|
+
|
|
109
118
|
## Amounts
|
|
110
119
|
|
|
111
120
|
Every amount is an exact decimal **string** (`"0.00150000"`), in responses and requests. JS numbers are
|
|
@@ -153,7 +162,8 @@ try {
|
|
|
153
162
|
## Retries and idempotency
|
|
154
163
|
|
|
155
164
|
- Timeout per attempt: `timeoutMs` (default 10 s). Retries: `maxRetries` (default 3), exponential backoff with full jitter.
|
|
156
|
-
- Retried: network errors, timeouts and responses with `retryable: true
|
|
165
|
+
- Retried: network errors, timeouts and responses with `retryable: true` (and 409 `CONCURRENT_MODIFICATION`).
|
|
166
|
+
A 4xx is never retried except 429 and 409 `CONCURRENT_MODIFICATION`, whatever its body says.
|
|
157
167
|
- 429 waits at least `Retry-After` / `details.retry_after_seconds`. Server wait hints are untrusted: unusable
|
|
158
168
|
values are ignored, and a hint longer than 120 s (`MAX_SERVER_WAIT_MS`) is never waited: the call fails at
|
|
159
169
|
once with `RateLimitError`, whose `retryAfterMs` still has the server's value. The client-side rate limiter
|
|
@@ -285,7 +295,7 @@ Report vulnerabilities as described in [SECURITY.md](SECURITY.md).
|
|
|
285
295
|
## For tool builders
|
|
286
296
|
|
|
287
297
|
The package exports its building blocks: the `OPERATIONS` table (method, path, auth and scope for each of the
|
|
288
|
-
|
|
298
|
+
41 operations), all model types, the error classes, `paginate()`, `RateLimiter`, the `Authenticator`
|
|
289
299
|
interface (HMAC signing will plug in here) and `userAgentSuffix` to identify your tool.
|
|
290
300
|
|
|
291
301
|
## Development
|
package/dist/index.cjs
CHANGED
|
@@ -146,7 +146,7 @@ var CLIENT_ERROR_CODES = { UNEXPECTED_REDIRECT: "UNEXPECTED_REDIRECT" };
|
|
|
146
146
|
function isKnownErrorCode(code) {
|
|
147
147
|
return KNOWN_CODES.has(code);
|
|
148
148
|
}
|
|
149
|
-
var DEFAULT_RETRYABLE_STATUS = /* @__PURE__ */ new Set([
|
|
149
|
+
var DEFAULT_RETRYABLE_STATUS = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
150
150
|
var MAX_SERVER_WAIT_MS = 12e4;
|
|
151
151
|
function retryAfterMs(headers, details) {
|
|
152
152
|
let best = null;
|
|
@@ -296,6 +296,7 @@ var OPERATIONS = {
|
|
|
296
296
|
get_ledger: op("GET", "/api/v1/account/ledger", "api_key", "read", "account.ledger"),
|
|
297
297
|
list_notifications: op("GET", "/api/v1/account/notifications", "api_key", "read", "account.notifications"),
|
|
298
298
|
list_sub_accounts: op("GET", "/api/v1/account/sub-accounts", "api_key", "read", "account.subAccounts"),
|
|
299
|
+
sub_account_balances: op("GET", "/api/v1/account/sub-accounts/{id}/balances", "api_key", "read", "account.subAccountBalances"),
|
|
299
300
|
list_api_keys: op("GET", "/api/v1/account/api-keys", "api_key", "read", "account.apiKeys"),
|
|
300
301
|
// Exports (read)
|
|
301
302
|
export_deposits: op("GET", "/api/v1/exports/deposits", "api_key", "read", "exports.deposits"),
|
|
@@ -326,6 +327,7 @@ var OPERATIONS = {
|
|
|
326
327
|
|
|
327
328
|
// src/http.ts
|
|
328
329
|
var IDEMPOTENT_OPS = /* @__PURE__ */ new Set(["join_pool", "exit_pool"]);
|
|
330
|
+
var REPEAT_SAFE_MUTATIONS = /* @__PURE__ */ new Set(["join_pool", "exit_pool", "cancel_all"]);
|
|
329
331
|
var BACKOFF_BASE_MS = 500;
|
|
330
332
|
var BACKOFF_MAX_MS = 1e4;
|
|
331
333
|
var Transport = class {
|
|
@@ -337,13 +339,14 @@ var Transport = class {
|
|
|
337
339
|
* Sends a request with the standard retry policy: retryable errors and network failures are
|
|
338
340
|
* retried. Pool join/exit carry an `Idempotency-Key` reused on every attempt (the server
|
|
339
341
|
* honours it there, which makes their retries safe); the other mutations routed here
|
|
340
|
-
* (cancel-all) are naturally repeatable and send no key.
|
|
341
|
-
* `attempt()` with their own policies.
|
|
342
|
+
* (cancel-all) are naturally repeatable and send no key. Any other mutation is sent once.
|
|
343
|
+
* `placeOrder` and `cancelOrder` use `attempt()` with their own policies.
|
|
342
344
|
*/
|
|
343
345
|
async request(spec, opts = {}) {
|
|
344
346
|
const info = OPERATIONS[spec.op];
|
|
345
347
|
const idempotencyKey = IDEMPOTENT_OPS.has(spec.op) ? spec.idempotencyKey ?? opts.idempotencyKey ?? newId() : void 0;
|
|
346
|
-
const
|
|
348
|
+
const repeatSafe = info.method === "GET" || REPEAT_SAFE_MUTATIONS.has(spec.op);
|
|
349
|
+
const maxRetries = repeatSafe ? opts.maxRetries ?? this.config.maxRetries : 0;
|
|
347
350
|
for (let attempt = 0; ; attempt++) {
|
|
348
351
|
try {
|
|
349
352
|
return await this.attempt({ ...spec, idempotencyKey }, opts);
|
|
@@ -458,6 +461,7 @@ var Transport = class {
|
|
|
458
461
|
const path = info.path.replace(/\{(\w+)\}/g, (_m, name) => {
|
|
459
462
|
const v = pathParams[name];
|
|
460
463
|
if (typeof v !== "string" || v === "") throw new CexyConfigError(`${info.sdkMethod}(): ${name} is required`);
|
|
464
|
+
if (v === "." || v === "..") throw new CexyConfigError(`${info.sdkMethod}(): ${name} must not be "." or ".."`);
|
|
461
465
|
return encodeURIComponent(v);
|
|
462
466
|
});
|
|
463
467
|
const url = new URL(this.config.baseUrl.replace(/\/+$/, "") + path);
|
|
@@ -480,7 +484,11 @@ function serverHintMs(err) {
|
|
|
480
484
|
}
|
|
481
485
|
function isRetryable(err) {
|
|
482
486
|
if (err instanceof CexyConnectionError) return true;
|
|
483
|
-
if (err instanceof CexyApiError)
|
|
487
|
+
if (err instanceof CexyApiError) {
|
|
488
|
+
const concurrent = err.code === "CONCURRENT_MODIFICATION";
|
|
489
|
+
if (err.status >= 400 && err.status < 500 && err.status !== 429 && !(err.status === 409 && concurrent)) return false;
|
|
490
|
+
return err.retryable || concurrent;
|
|
491
|
+
}
|
|
484
492
|
return false;
|
|
485
493
|
}
|
|
486
494
|
function isAmbiguous(err) {
|
|
@@ -752,12 +760,22 @@ var PoolsResource = class extends Resource {
|
|
|
752
760
|
return this.data({ op: "exit_pool", pathParams: { symbol }, body }, opts);
|
|
753
761
|
}
|
|
754
762
|
};
|
|
763
|
+
function withHeldIncoming(b) {
|
|
764
|
+
if (!b || typeof b !== "object" || Array.isArray(b.held_incoming)) return b;
|
|
765
|
+
return { ...b, held_incoming: [] };
|
|
766
|
+
}
|
|
755
767
|
var AccountResource = class extends Resource {
|
|
756
|
-
|
|
757
|
-
|
|
768
|
+
/**
|
|
769
|
+
* Balances per asset. `held_incoming` lists incoming internal transfers still held; their sum is
|
|
770
|
+
* already included in `locked` (never add it again). Always an array (`[]` when none).
|
|
771
|
+
*/
|
|
772
|
+
async balances(opts) {
|
|
773
|
+
const rows = await this.data({ op: "list_balances" }, opts);
|
|
774
|
+
return Array.isArray(rows) ? rows.map(withHeldIncoming) : rows;
|
|
758
775
|
}
|
|
759
|
-
balance
|
|
760
|
-
|
|
776
|
+
/** One asset's balance. `held_incoming`: incoming transfers still held, already inside `locked`. */
|
|
777
|
+
async balance(asset, opts) {
|
|
778
|
+
return withHeldIncoming(await this.data({ op: "get_balance", pathParams: { asset } }, opts));
|
|
761
779
|
}
|
|
762
780
|
ledger(params, opts) {
|
|
763
781
|
return this.page({ op: "get_ledger", query: params }, opts);
|
|
@@ -774,6 +792,20 @@ var AccountResource = class extends Resource {
|
|
|
774
792
|
subAccounts(opts) {
|
|
775
793
|
return this.data({ op: "list_sub_accounts" }, opts);
|
|
776
794
|
}
|
|
795
|
+
/**
|
|
796
|
+
* A sub-account's balances, read by its PARENT account: the same shape as `balances()`
|
|
797
|
+
* (zero balances omitted), including `held_incoming`, whose sum is already inside `locked`.
|
|
798
|
+
* The server currently returns them ordered by asset symbol; don't rely on the order.
|
|
799
|
+
* An id that is not one of the caller's sub-accounts (or a call with the sub-account's own
|
|
800
|
+
* key) gets `NotFoundError`; a sub-account's own key reads its balances with `balances()`.
|
|
801
|
+
* A malformed id gets 400 (`ValidationError`); a key without the `read` scope gets 403
|
|
802
|
+
* `FORBIDDEN` (`ForbiddenError`). `id` must be non-empty and not "." or ".."; it is sent as
|
|
803
|
+
* one URL path segment.
|
|
804
|
+
*/
|
|
805
|
+
async subAccountBalances(id, opts) {
|
|
806
|
+
const rows = await this.data({ op: "sub_account_balances", pathParams: { id } }, opts);
|
|
807
|
+
return Array.isArray(rows) ? rows.map(withHeldIncoming) : rows;
|
|
808
|
+
}
|
|
777
809
|
/** Your API keys (metadata only; secrets are never returned). */
|
|
778
810
|
apiKeys(opts) {
|
|
779
811
|
return this.data({ op: "list_api_keys" }, opts);
|
|
@@ -1040,7 +1072,7 @@ var TradingResource = class extends Resource {
|
|
|
1040
1072
|
};
|
|
1041
1073
|
|
|
1042
1074
|
// src/version.ts
|
|
1043
|
-
var VERSION = "0.1.0-dev.
|
|
1075
|
+
var VERSION = "0.1.0-dev.7";
|
|
1044
1076
|
var USER_AGENT = `cexy-typescript/${VERSION}`;
|
|
1045
1077
|
|
|
1046
1078
|
// src/ws/emitter.ts
|
package/dist/index.d.cts
CHANGED
|
@@ -102,6 +102,7 @@ declare const OPERATIONS: {
|
|
|
102
102
|
readonly get_ledger: OperationInfo;
|
|
103
103
|
readonly list_notifications: OperationInfo;
|
|
104
104
|
readonly list_sub_accounts: OperationInfo;
|
|
105
|
+
readonly sub_account_balances: OperationInfo;
|
|
105
106
|
readonly list_api_keys: OperationInfo;
|
|
106
107
|
readonly export_deposits: OperationInfo;
|
|
107
108
|
readonly export_ledger: OperationInfo;
|
|
@@ -189,8 +190,8 @@ declare class Transport {
|
|
|
189
190
|
* Sends a request with the standard retry policy: retryable errors and network failures are
|
|
190
191
|
* retried. Pool join/exit carry an `Idempotency-Key` reused on every attempt (the server
|
|
191
192
|
* honours it there, which makes their retries safe); the other mutations routed here
|
|
192
|
-
* (cancel-all) are naturally repeatable and send no key.
|
|
193
|
-
* `attempt()` with their own policies.
|
|
193
|
+
* (cancel-all) are naturally repeatable and send no key. Any other mutation is sent once.
|
|
194
|
+
* `placeOrder` and `cancelOrder` use `attempt()` with their own policies.
|
|
194
195
|
*/
|
|
195
196
|
request(spec: CallSpec, opts?: RequestOptions): Promise<RawResponse>;
|
|
196
197
|
/**
|
|
@@ -205,7 +206,11 @@ declare class Transport {
|
|
|
205
206
|
buildUrl(info: OperationInfo, pathParams?: Record<string, string>, query?: Record<string, unknown>): URL;
|
|
206
207
|
redact(text: string): string;
|
|
207
208
|
}
|
|
208
|
-
/**
|
|
209
|
+
/**
|
|
210
|
+
* Retryable = a network failure/timeout, or an API error with `retryable: true` (incl. 409
|
|
211
|
+
* CONCURRENT_MODIFICATION). A 4xx is never retryable except 429 and 409 CONCURRENT_MODIFICATION,
|
|
212
|
+
* whatever its body says.
|
|
213
|
+
*/
|
|
209
214
|
declare function isRetryable(err: unknown): boolean;
|
|
210
215
|
|
|
211
216
|
interface paths {
|
|
@@ -314,6 +319,26 @@ interface paths {
|
|
|
314
319
|
patch?: never;
|
|
315
320
|
trace?: never;
|
|
316
321
|
};
|
|
322
|
+
"/api/v1/account/sub-accounts/{id}/balances": {
|
|
323
|
+
parameters: {
|
|
324
|
+
query?: never;
|
|
325
|
+
header?: never;
|
|
326
|
+
path?: never;
|
|
327
|
+
cookie?: never;
|
|
328
|
+
};
|
|
329
|
+
/**
|
|
330
|
+
* A sub-account's balances, for its parent.
|
|
331
|
+
* @description The same shape as `/account/balances`, zero balances omitted: what the sub-account holds, so its funds can be shown and moved back. Only the parent may read it; any id that is not one of the caller's sub-accounts is not found.
|
|
332
|
+
*/
|
|
333
|
+
get: operations["sub_account_balances"];
|
|
334
|
+
put?: never;
|
|
335
|
+
post?: never;
|
|
336
|
+
delete?: never;
|
|
337
|
+
options?: never;
|
|
338
|
+
head?: never;
|
|
339
|
+
patch?: never;
|
|
340
|
+
trace?: never;
|
|
341
|
+
};
|
|
317
342
|
"/api/v1/assets": {
|
|
318
343
|
parameters: {
|
|
319
344
|
query?: never;
|
|
@@ -1041,6 +1066,8 @@ interface components {
|
|
|
1041
1066
|
/** @description Asset symbol. */
|
|
1042
1067
|
asset: string;
|
|
1043
1068
|
available: components["schemas"]["Amount"];
|
|
1069
|
+
/** @description Internal transfers to this account still held, soonest released first; empty when none. Their sum is part of `locked`. Shows at most 100. */
|
|
1070
|
+
held_incoming: components["schemas"]["HeldIncomingResponse"][];
|
|
1044
1071
|
locked: components["schemas"]["Amount"];
|
|
1045
1072
|
pending: components["schemas"]["Amount"];
|
|
1046
1073
|
total: components["schemas"]["Amount"];
|
|
@@ -1326,6 +1353,17 @@ interface components {
|
|
|
1326
1353
|
* @example 507f1f77bcf86cd799439011
|
|
1327
1354
|
*/
|
|
1328
1355
|
FuturesTransferId: string;
|
|
1356
|
+
/** @description An internal transfer credited to `locked` and not yet available. */
|
|
1357
|
+
HeldIncomingResponse: {
|
|
1358
|
+
amount: components["schemas"]["Amount"];
|
|
1359
|
+
/**
|
|
1360
|
+
* Format: date-time
|
|
1361
|
+
* @description When it becomes available, unless an operator cancels it before then.
|
|
1362
|
+
*/
|
|
1363
|
+
available_at: string;
|
|
1364
|
+
/** @description The transfer. */
|
|
1365
|
+
transfer_id: string;
|
|
1366
|
+
};
|
|
1329
1367
|
/** @description Adds liquidity to a pool. */
|
|
1330
1368
|
JoinPoolRequest: {
|
|
1331
1369
|
base_amount: components["schemas"]["Amount"];
|
|
@@ -2081,6 +2119,49 @@ interface operations {
|
|
|
2081
2119
|
};
|
|
2082
2120
|
};
|
|
2083
2121
|
};
|
|
2122
|
+
sub_account_balances: {
|
|
2123
|
+
parameters: {
|
|
2124
|
+
query?: never;
|
|
2125
|
+
header?: never;
|
|
2126
|
+
path: {
|
|
2127
|
+
/** @description Sub-account id */
|
|
2128
|
+
id: string;
|
|
2129
|
+
};
|
|
2130
|
+
cookie?: never;
|
|
2131
|
+
};
|
|
2132
|
+
requestBody?: never;
|
|
2133
|
+
responses: {
|
|
2134
|
+
/** @description The sub-account's balances */
|
|
2135
|
+
200: {
|
|
2136
|
+
headers: {
|
|
2137
|
+
[name: string]: unknown;
|
|
2138
|
+
};
|
|
2139
|
+
content: {
|
|
2140
|
+
"application/json": {
|
|
2141
|
+
data: components["schemas"]["BalanceResponse"][];
|
|
2142
|
+
};
|
|
2143
|
+
};
|
|
2144
|
+
};
|
|
2145
|
+
/** @description Malformed sub-account id */
|
|
2146
|
+
400: {
|
|
2147
|
+
headers: {
|
|
2148
|
+
[name: string]: unknown;
|
|
2149
|
+
};
|
|
2150
|
+
content: {
|
|
2151
|
+
"application/json": components["schemas"]["ErrorResponse"];
|
|
2152
|
+
};
|
|
2153
|
+
};
|
|
2154
|
+
/** @description No such sub-account on this account */
|
|
2155
|
+
404: {
|
|
2156
|
+
headers: {
|
|
2157
|
+
[name: string]: unknown;
|
|
2158
|
+
};
|
|
2159
|
+
content: {
|
|
2160
|
+
"application/json": components["schemas"]["ErrorResponse"];
|
|
2161
|
+
};
|
|
2162
|
+
};
|
|
2163
|
+
};
|
|
2164
|
+
};
|
|
2084
2165
|
list_assets: {
|
|
2085
2166
|
parameters: {
|
|
2086
2167
|
query?: never;
|
|
@@ -3301,6 +3382,8 @@ type ApiScope = S["ApiScope"];
|
|
|
3301
3382
|
type Asset = S["AssetResponse"];
|
|
3302
3383
|
type AssetNetwork = S["AssetNetworkResponse"];
|
|
3303
3384
|
type Balance = S["BalanceResponse"];
|
|
3385
|
+
/** An incoming internal transfer still held (see `Balance.held_incoming`). */
|
|
3386
|
+
type HeldIncoming = S["HeldIncomingResponse"];
|
|
3304
3387
|
type CancelAllRequest = S["CancelAllRequest"];
|
|
3305
3388
|
type CancelAllResult = S["CancelAllResponse"];
|
|
3306
3389
|
/** Why one order could not be cancelled (`CancelAllResult.failures`). */
|
|
@@ -3458,13 +3541,29 @@ declare class PoolsResource extends Resource {
|
|
|
3458
3541
|
exit(symbol: string, body: ExitPoolRequest, opts?: RequestOptions): Promise<ExitPoolResult>;
|
|
3459
3542
|
}
|
|
3460
3543
|
declare class AccountResource extends Resource {
|
|
3544
|
+
/**
|
|
3545
|
+
* Balances per asset. `held_incoming` lists incoming internal transfers still held; their sum is
|
|
3546
|
+
* already included in `locked` (never add it again). Always an array (`[]` when none).
|
|
3547
|
+
*/
|
|
3461
3548
|
balances(opts?: RequestOptions): Promise<Balance[]>;
|
|
3549
|
+
/** One asset's balance. `held_incoming`: incoming transfers still held, already inside `locked`. */
|
|
3462
3550
|
balance(asset: string, opts?: RequestOptions): Promise<Balance>;
|
|
3463
3551
|
ledger(params?: Q<"get_ledger">, opts?: RequestOptions): Promise<Page<LedgerEntry>>;
|
|
3464
3552
|
iterateLedger(params?: Q<"get_ledger">, iter?: IterateOptions & RequestOptions): AsyncGenerator<LedgerEntry, void, undefined>;
|
|
3465
3553
|
notifications(params?: Q<"list_notifications">, opts?: RequestOptions): Promise<Page<Notification>>;
|
|
3466
3554
|
iterateNotifications(params?: Q<"list_notifications">, iter?: IterateOptions & RequestOptions): AsyncGenerator<Notification, void, undefined>;
|
|
3467
3555
|
subAccounts(opts?: RequestOptions): Promise<SubAccount[]>;
|
|
3556
|
+
/**
|
|
3557
|
+
* A sub-account's balances, read by its PARENT account: the same shape as `balances()`
|
|
3558
|
+
* (zero balances omitted), including `held_incoming`, whose sum is already inside `locked`.
|
|
3559
|
+
* The server currently returns them ordered by asset symbol; don't rely on the order.
|
|
3560
|
+
* An id that is not one of the caller's sub-accounts (or a call with the sub-account's own
|
|
3561
|
+
* key) gets `NotFoundError`; a sub-account's own key reads its balances with `balances()`.
|
|
3562
|
+
* A malformed id gets 400 (`ValidationError`); a key without the `read` scope gets 403
|
|
3563
|
+
* `FORBIDDEN` (`ForbiddenError`). `id` must be non-empty and not "." or ".."; it is sent as
|
|
3564
|
+
* one URL path segment.
|
|
3565
|
+
*/
|
|
3566
|
+
subAccountBalances(id: string, opts?: RequestOptions): Promise<Balance[]>;
|
|
3468
3567
|
/** Your API keys (metadata only; secrets are never returned). */
|
|
3469
3568
|
apiKeys(opts?: RequestOptions): Promise<ApiKey[]>;
|
|
3470
3569
|
}
|
|
@@ -4167,11 +4266,11 @@ declare function isLedgerReference<T extends LedgerReferenceType>(ref: LedgerRef
|
|
|
4167
4266
|
}>;
|
|
4168
4267
|
|
|
4169
4268
|
/** SDK version, kept in sync with package.json (a test enforces this). */
|
|
4170
|
-
declare const VERSION = "0.1.0-dev.
|
|
4269
|
+
declare const VERSION = "0.1.0-dev.7";
|
|
4171
4270
|
/** Default User-Agent product token. */
|
|
4172
|
-
declare const USER_AGENT = "cexy-typescript/0.1.0-dev.
|
|
4271
|
+
declare const USER_AGENT = "cexy-typescript/0.1.0-dev.7";
|
|
4173
4272
|
|
|
4174
4273
|
/** True for loopback hosts, the only ones where plain-text transport may be allowed. */
|
|
4175
4274
|
declare function isLocalHost(hostname: string): boolean;
|
|
4176
4275
|
|
|
4177
|
-
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, CLIENT_ERROR_CODES, CancelAllInterruptedError, type CancelAllParams, type CancelAllRequest, type CancelAllResult, type CancelAllStopReason, type CancelAllUntilDoneResult, type CancelFailure, 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 DepositId, 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, type FuturesTransferId, InvalidAmountError, type IterateOptions, type JoinPoolRequest, type JoinPoolResult, JurisdictionBlockedError, KNOWN_EVENT_TYPES, type KnownErrorCode, type KnownLedgerReference, type LedgerEntry, type LedgerEntryKind, type LedgerReference, type LedgerReferenceType, type LiquidityRole, type Listener, LiveOrderBook, type LiveOrderBookEvents, type LiveOrderBookOptions, MAX_SERVER_WAIT_MS, 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 OrderId, type OrderSide, OrderStateUnknownError, type OrderStatus, type OrderType, PRIVATE_CHANNELS, type Page, type PlaceOrderRequest, type PlaceOrderResponse, type PlaceOrderResult, type PongFrame, type Pool, type PoolId, 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 TradeId, type TradeNewEvent, TradingResource, type TriggerDirection, TypedEmitter, USER_AGENT, type UnknownLedgerReference, UnprocessableError, type UnsubscribedFrame, type UserId, VERSION, ValidationError, WS_BOOK_DEPTH, WalletResource, type WebSocketConstructor, type WebSocketLike, type WelcomeFrame, type Withdrawal, type WithdrawalAddress, type WithdrawalId, type WithdrawalStatus, type WithdrawalUpdatedEvent, type WsEvent, type WsLogger, assertAmountFields, type components, errorFromResponse, isAmount, isKnownErrorCode, isLedgerReference, isLocalHost, isRetryable, type operations, paginate, type paths };
|
|
4276
|
+
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, CLIENT_ERROR_CODES, CancelAllInterruptedError, type CancelAllParams, type CancelAllRequest, type CancelAllResult, type CancelAllStopReason, type CancelAllUntilDoneResult, type CancelFailure, 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 DepositId, 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, type FuturesTransferId, type HeldIncoming, InvalidAmountError, type IterateOptions, type JoinPoolRequest, type JoinPoolResult, JurisdictionBlockedError, KNOWN_EVENT_TYPES, type KnownErrorCode, type KnownLedgerReference, type LedgerEntry, type LedgerEntryKind, type LedgerReference, type LedgerReferenceType, type LiquidityRole, type Listener, LiveOrderBook, type LiveOrderBookEvents, type LiveOrderBookOptions, MAX_SERVER_WAIT_MS, 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 OrderId, type OrderSide, OrderStateUnknownError, type OrderStatus, type OrderType, PRIVATE_CHANNELS, type Page, type PlaceOrderRequest, type PlaceOrderResponse, type PlaceOrderResult, type PongFrame, type Pool, type PoolId, 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 TradeId, type TradeNewEvent, TradingResource, type TriggerDirection, TypedEmitter, USER_AGENT, type UnknownLedgerReference, UnprocessableError, type UnsubscribedFrame, type UserId, VERSION, ValidationError, WS_BOOK_DEPTH, WalletResource, type WebSocketConstructor, type WebSocketLike, type WelcomeFrame, type Withdrawal, type WithdrawalAddress, type WithdrawalId, type WithdrawalStatus, type WithdrawalUpdatedEvent, type WsEvent, type WsLogger, assertAmountFields, type components, errorFromResponse, isAmount, isKnownErrorCode, isLedgerReference, isLocalHost, isRetryable, type operations, paginate, type paths };
|
package/dist/index.d.ts
CHANGED
|
@@ -102,6 +102,7 @@ declare const OPERATIONS: {
|
|
|
102
102
|
readonly get_ledger: OperationInfo;
|
|
103
103
|
readonly list_notifications: OperationInfo;
|
|
104
104
|
readonly list_sub_accounts: OperationInfo;
|
|
105
|
+
readonly sub_account_balances: OperationInfo;
|
|
105
106
|
readonly list_api_keys: OperationInfo;
|
|
106
107
|
readonly export_deposits: OperationInfo;
|
|
107
108
|
readonly export_ledger: OperationInfo;
|
|
@@ -189,8 +190,8 @@ declare class Transport {
|
|
|
189
190
|
* Sends a request with the standard retry policy: retryable errors and network failures are
|
|
190
191
|
* retried. Pool join/exit carry an `Idempotency-Key` reused on every attempt (the server
|
|
191
192
|
* honours it there, which makes their retries safe); the other mutations routed here
|
|
192
|
-
* (cancel-all) are naturally repeatable and send no key.
|
|
193
|
-
* `attempt()` with their own policies.
|
|
193
|
+
* (cancel-all) are naturally repeatable and send no key. Any other mutation is sent once.
|
|
194
|
+
* `placeOrder` and `cancelOrder` use `attempt()` with their own policies.
|
|
194
195
|
*/
|
|
195
196
|
request(spec: CallSpec, opts?: RequestOptions): Promise<RawResponse>;
|
|
196
197
|
/**
|
|
@@ -205,7 +206,11 @@ declare class Transport {
|
|
|
205
206
|
buildUrl(info: OperationInfo, pathParams?: Record<string, string>, query?: Record<string, unknown>): URL;
|
|
206
207
|
redact(text: string): string;
|
|
207
208
|
}
|
|
208
|
-
/**
|
|
209
|
+
/**
|
|
210
|
+
* Retryable = a network failure/timeout, or an API error with `retryable: true` (incl. 409
|
|
211
|
+
* CONCURRENT_MODIFICATION). A 4xx is never retryable except 429 and 409 CONCURRENT_MODIFICATION,
|
|
212
|
+
* whatever its body says.
|
|
213
|
+
*/
|
|
209
214
|
declare function isRetryable(err: unknown): boolean;
|
|
210
215
|
|
|
211
216
|
interface paths {
|
|
@@ -314,6 +319,26 @@ interface paths {
|
|
|
314
319
|
patch?: never;
|
|
315
320
|
trace?: never;
|
|
316
321
|
};
|
|
322
|
+
"/api/v1/account/sub-accounts/{id}/balances": {
|
|
323
|
+
parameters: {
|
|
324
|
+
query?: never;
|
|
325
|
+
header?: never;
|
|
326
|
+
path?: never;
|
|
327
|
+
cookie?: never;
|
|
328
|
+
};
|
|
329
|
+
/**
|
|
330
|
+
* A sub-account's balances, for its parent.
|
|
331
|
+
* @description The same shape as `/account/balances`, zero balances omitted: what the sub-account holds, so its funds can be shown and moved back. Only the parent may read it; any id that is not one of the caller's sub-accounts is not found.
|
|
332
|
+
*/
|
|
333
|
+
get: operations["sub_account_balances"];
|
|
334
|
+
put?: never;
|
|
335
|
+
post?: never;
|
|
336
|
+
delete?: never;
|
|
337
|
+
options?: never;
|
|
338
|
+
head?: never;
|
|
339
|
+
patch?: never;
|
|
340
|
+
trace?: never;
|
|
341
|
+
};
|
|
317
342
|
"/api/v1/assets": {
|
|
318
343
|
parameters: {
|
|
319
344
|
query?: never;
|
|
@@ -1041,6 +1066,8 @@ interface components {
|
|
|
1041
1066
|
/** @description Asset symbol. */
|
|
1042
1067
|
asset: string;
|
|
1043
1068
|
available: components["schemas"]["Amount"];
|
|
1069
|
+
/** @description Internal transfers to this account still held, soonest released first; empty when none. Their sum is part of `locked`. Shows at most 100. */
|
|
1070
|
+
held_incoming: components["schemas"]["HeldIncomingResponse"][];
|
|
1044
1071
|
locked: components["schemas"]["Amount"];
|
|
1045
1072
|
pending: components["schemas"]["Amount"];
|
|
1046
1073
|
total: components["schemas"]["Amount"];
|
|
@@ -1326,6 +1353,17 @@ interface components {
|
|
|
1326
1353
|
* @example 507f1f77bcf86cd799439011
|
|
1327
1354
|
*/
|
|
1328
1355
|
FuturesTransferId: string;
|
|
1356
|
+
/** @description An internal transfer credited to `locked` and not yet available. */
|
|
1357
|
+
HeldIncomingResponse: {
|
|
1358
|
+
amount: components["schemas"]["Amount"];
|
|
1359
|
+
/**
|
|
1360
|
+
* Format: date-time
|
|
1361
|
+
* @description When it becomes available, unless an operator cancels it before then.
|
|
1362
|
+
*/
|
|
1363
|
+
available_at: string;
|
|
1364
|
+
/** @description The transfer. */
|
|
1365
|
+
transfer_id: string;
|
|
1366
|
+
};
|
|
1329
1367
|
/** @description Adds liquidity to a pool. */
|
|
1330
1368
|
JoinPoolRequest: {
|
|
1331
1369
|
base_amount: components["schemas"]["Amount"];
|
|
@@ -2081,6 +2119,49 @@ interface operations {
|
|
|
2081
2119
|
};
|
|
2082
2120
|
};
|
|
2083
2121
|
};
|
|
2122
|
+
sub_account_balances: {
|
|
2123
|
+
parameters: {
|
|
2124
|
+
query?: never;
|
|
2125
|
+
header?: never;
|
|
2126
|
+
path: {
|
|
2127
|
+
/** @description Sub-account id */
|
|
2128
|
+
id: string;
|
|
2129
|
+
};
|
|
2130
|
+
cookie?: never;
|
|
2131
|
+
};
|
|
2132
|
+
requestBody?: never;
|
|
2133
|
+
responses: {
|
|
2134
|
+
/** @description The sub-account's balances */
|
|
2135
|
+
200: {
|
|
2136
|
+
headers: {
|
|
2137
|
+
[name: string]: unknown;
|
|
2138
|
+
};
|
|
2139
|
+
content: {
|
|
2140
|
+
"application/json": {
|
|
2141
|
+
data: components["schemas"]["BalanceResponse"][];
|
|
2142
|
+
};
|
|
2143
|
+
};
|
|
2144
|
+
};
|
|
2145
|
+
/** @description Malformed sub-account id */
|
|
2146
|
+
400: {
|
|
2147
|
+
headers: {
|
|
2148
|
+
[name: string]: unknown;
|
|
2149
|
+
};
|
|
2150
|
+
content: {
|
|
2151
|
+
"application/json": components["schemas"]["ErrorResponse"];
|
|
2152
|
+
};
|
|
2153
|
+
};
|
|
2154
|
+
/** @description No such sub-account on this account */
|
|
2155
|
+
404: {
|
|
2156
|
+
headers: {
|
|
2157
|
+
[name: string]: unknown;
|
|
2158
|
+
};
|
|
2159
|
+
content: {
|
|
2160
|
+
"application/json": components["schemas"]["ErrorResponse"];
|
|
2161
|
+
};
|
|
2162
|
+
};
|
|
2163
|
+
};
|
|
2164
|
+
};
|
|
2084
2165
|
list_assets: {
|
|
2085
2166
|
parameters: {
|
|
2086
2167
|
query?: never;
|
|
@@ -3301,6 +3382,8 @@ type ApiScope = S["ApiScope"];
|
|
|
3301
3382
|
type Asset = S["AssetResponse"];
|
|
3302
3383
|
type AssetNetwork = S["AssetNetworkResponse"];
|
|
3303
3384
|
type Balance = S["BalanceResponse"];
|
|
3385
|
+
/** An incoming internal transfer still held (see `Balance.held_incoming`). */
|
|
3386
|
+
type HeldIncoming = S["HeldIncomingResponse"];
|
|
3304
3387
|
type CancelAllRequest = S["CancelAllRequest"];
|
|
3305
3388
|
type CancelAllResult = S["CancelAllResponse"];
|
|
3306
3389
|
/** Why one order could not be cancelled (`CancelAllResult.failures`). */
|
|
@@ -3458,13 +3541,29 @@ declare class PoolsResource extends Resource {
|
|
|
3458
3541
|
exit(symbol: string, body: ExitPoolRequest, opts?: RequestOptions): Promise<ExitPoolResult>;
|
|
3459
3542
|
}
|
|
3460
3543
|
declare class AccountResource extends Resource {
|
|
3544
|
+
/**
|
|
3545
|
+
* Balances per asset. `held_incoming` lists incoming internal transfers still held; their sum is
|
|
3546
|
+
* already included in `locked` (never add it again). Always an array (`[]` when none).
|
|
3547
|
+
*/
|
|
3461
3548
|
balances(opts?: RequestOptions): Promise<Balance[]>;
|
|
3549
|
+
/** One asset's balance. `held_incoming`: incoming transfers still held, already inside `locked`. */
|
|
3462
3550
|
balance(asset: string, opts?: RequestOptions): Promise<Balance>;
|
|
3463
3551
|
ledger(params?: Q<"get_ledger">, opts?: RequestOptions): Promise<Page<LedgerEntry>>;
|
|
3464
3552
|
iterateLedger(params?: Q<"get_ledger">, iter?: IterateOptions & RequestOptions): AsyncGenerator<LedgerEntry, void, undefined>;
|
|
3465
3553
|
notifications(params?: Q<"list_notifications">, opts?: RequestOptions): Promise<Page<Notification>>;
|
|
3466
3554
|
iterateNotifications(params?: Q<"list_notifications">, iter?: IterateOptions & RequestOptions): AsyncGenerator<Notification, void, undefined>;
|
|
3467
3555
|
subAccounts(opts?: RequestOptions): Promise<SubAccount[]>;
|
|
3556
|
+
/**
|
|
3557
|
+
* A sub-account's balances, read by its PARENT account: the same shape as `balances()`
|
|
3558
|
+
* (zero balances omitted), including `held_incoming`, whose sum is already inside `locked`.
|
|
3559
|
+
* The server currently returns them ordered by asset symbol; don't rely on the order.
|
|
3560
|
+
* An id that is not one of the caller's sub-accounts (or a call with the sub-account's own
|
|
3561
|
+
* key) gets `NotFoundError`; a sub-account's own key reads its balances with `balances()`.
|
|
3562
|
+
* A malformed id gets 400 (`ValidationError`); a key without the `read` scope gets 403
|
|
3563
|
+
* `FORBIDDEN` (`ForbiddenError`). `id` must be non-empty and not "." or ".."; it is sent as
|
|
3564
|
+
* one URL path segment.
|
|
3565
|
+
*/
|
|
3566
|
+
subAccountBalances(id: string, opts?: RequestOptions): Promise<Balance[]>;
|
|
3468
3567
|
/** Your API keys (metadata only; secrets are never returned). */
|
|
3469
3568
|
apiKeys(opts?: RequestOptions): Promise<ApiKey[]>;
|
|
3470
3569
|
}
|
|
@@ -4167,11 +4266,11 @@ declare function isLedgerReference<T extends LedgerReferenceType>(ref: LedgerRef
|
|
|
4167
4266
|
}>;
|
|
4168
4267
|
|
|
4169
4268
|
/** SDK version, kept in sync with package.json (a test enforces this). */
|
|
4170
|
-
declare const VERSION = "0.1.0-dev.
|
|
4269
|
+
declare const VERSION = "0.1.0-dev.7";
|
|
4171
4270
|
/** Default User-Agent product token. */
|
|
4172
|
-
declare const USER_AGENT = "cexy-typescript/0.1.0-dev.
|
|
4271
|
+
declare const USER_AGENT = "cexy-typescript/0.1.0-dev.7";
|
|
4173
4272
|
|
|
4174
4273
|
/** True for loopback hosts, the only ones where plain-text transport may be allowed. */
|
|
4175
4274
|
declare function isLocalHost(hostname: string): boolean;
|
|
4176
4275
|
|
|
4177
|
-
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, CLIENT_ERROR_CODES, CancelAllInterruptedError, type CancelAllParams, type CancelAllRequest, type CancelAllResult, type CancelAllStopReason, type CancelAllUntilDoneResult, type CancelFailure, 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 DepositId, 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, type FuturesTransferId, InvalidAmountError, type IterateOptions, type JoinPoolRequest, type JoinPoolResult, JurisdictionBlockedError, KNOWN_EVENT_TYPES, type KnownErrorCode, type KnownLedgerReference, type LedgerEntry, type LedgerEntryKind, type LedgerReference, type LedgerReferenceType, type LiquidityRole, type Listener, LiveOrderBook, type LiveOrderBookEvents, type LiveOrderBookOptions, MAX_SERVER_WAIT_MS, 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 OrderId, type OrderSide, OrderStateUnknownError, type OrderStatus, type OrderType, PRIVATE_CHANNELS, type Page, type PlaceOrderRequest, type PlaceOrderResponse, type PlaceOrderResult, type PongFrame, type Pool, type PoolId, 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 TradeId, type TradeNewEvent, TradingResource, type TriggerDirection, TypedEmitter, USER_AGENT, type UnknownLedgerReference, UnprocessableError, type UnsubscribedFrame, type UserId, VERSION, ValidationError, WS_BOOK_DEPTH, WalletResource, type WebSocketConstructor, type WebSocketLike, type WelcomeFrame, type Withdrawal, type WithdrawalAddress, type WithdrawalId, type WithdrawalStatus, type WithdrawalUpdatedEvent, type WsEvent, type WsLogger, assertAmountFields, type components, errorFromResponse, isAmount, isKnownErrorCode, isLedgerReference, isLocalHost, isRetryable, type operations, paginate, type paths };
|
|
4276
|
+
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, CLIENT_ERROR_CODES, CancelAllInterruptedError, type CancelAllParams, type CancelAllRequest, type CancelAllResult, type CancelAllStopReason, type CancelAllUntilDoneResult, type CancelFailure, 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 DepositId, 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, type FuturesTransferId, type HeldIncoming, InvalidAmountError, type IterateOptions, type JoinPoolRequest, type JoinPoolResult, JurisdictionBlockedError, KNOWN_EVENT_TYPES, type KnownErrorCode, type KnownLedgerReference, type LedgerEntry, type LedgerEntryKind, type LedgerReference, type LedgerReferenceType, type LiquidityRole, type Listener, LiveOrderBook, type LiveOrderBookEvents, type LiveOrderBookOptions, MAX_SERVER_WAIT_MS, 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 OrderId, type OrderSide, OrderStateUnknownError, type OrderStatus, type OrderType, PRIVATE_CHANNELS, type Page, type PlaceOrderRequest, type PlaceOrderResponse, type PlaceOrderResult, type PongFrame, type Pool, type PoolId, 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 TradeId, type TradeNewEvent, TradingResource, type TriggerDirection, TypedEmitter, USER_AGENT, type UnknownLedgerReference, UnprocessableError, type UnsubscribedFrame, type UserId, VERSION, ValidationError, WS_BOOK_DEPTH, WalletResource, type WebSocketConstructor, type WebSocketLike, type WelcomeFrame, type Withdrawal, type WithdrawalAddress, type WithdrawalId, type WithdrawalStatus, type WithdrawalUpdatedEvent, type WsEvent, type WsLogger, assertAmountFields, type components, errorFromResponse, isAmount, isKnownErrorCode, isLedgerReference, isLocalHost, isRetryable, type operations, paginate, type paths };
|
package/dist/index.js
CHANGED
|
@@ -144,7 +144,7 @@ var CLIENT_ERROR_CODES = { UNEXPECTED_REDIRECT: "UNEXPECTED_REDIRECT" };
|
|
|
144
144
|
function isKnownErrorCode(code) {
|
|
145
145
|
return KNOWN_CODES.has(code);
|
|
146
146
|
}
|
|
147
|
-
var DEFAULT_RETRYABLE_STATUS = /* @__PURE__ */ new Set([
|
|
147
|
+
var DEFAULT_RETRYABLE_STATUS = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
148
148
|
var MAX_SERVER_WAIT_MS = 12e4;
|
|
149
149
|
function retryAfterMs(headers, details) {
|
|
150
150
|
let best = null;
|
|
@@ -294,6 +294,7 @@ var OPERATIONS = {
|
|
|
294
294
|
get_ledger: op("GET", "/api/v1/account/ledger", "api_key", "read", "account.ledger"),
|
|
295
295
|
list_notifications: op("GET", "/api/v1/account/notifications", "api_key", "read", "account.notifications"),
|
|
296
296
|
list_sub_accounts: op("GET", "/api/v1/account/sub-accounts", "api_key", "read", "account.subAccounts"),
|
|
297
|
+
sub_account_balances: op("GET", "/api/v1/account/sub-accounts/{id}/balances", "api_key", "read", "account.subAccountBalances"),
|
|
297
298
|
list_api_keys: op("GET", "/api/v1/account/api-keys", "api_key", "read", "account.apiKeys"),
|
|
298
299
|
// Exports (read)
|
|
299
300
|
export_deposits: op("GET", "/api/v1/exports/deposits", "api_key", "read", "exports.deposits"),
|
|
@@ -324,6 +325,7 @@ var OPERATIONS = {
|
|
|
324
325
|
|
|
325
326
|
// src/http.ts
|
|
326
327
|
var IDEMPOTENT_OPS = /* @__PURE__ */ new Set(["join_pool", "exit_pool"]);
|
|
328
|
+
var REPEAT_SAFE_MUTATIONS = /* @__PURE__ */ new Set(["join_pool", "exit_pool", "cancel_all"]);
|
|
327
329
|
var BACKOFF_BASE_MS = 500;
|
|
328
330
|
var BACKOFF_MAX_MS = 1e4;
|
|
329
331
|
var Transport = class {
|
|
@@ -335,13 +337,14 @@ var Transport = class {
|
|
|
335
337
|
* Sends a request with the standard retry policy: retryable errors and network failures are
|
|
336
338
|
* retried. Pool join/exit carry an `Idempotency-Key` reused on every attempt (the server
|
|
337
339
|
* honours it there, which makes their retries safe); the other mutations routed here
|
|
338
|
-
* (cancel-all) are naturally repeatable and send no key.
|
|
339
|
-
* `attempt()` with their own policies.
|
|
340
|
+
* (cancel-all) are naturally repeatable and send no key. Any other mutation is sent once.
|
|
341
|
+
* `placeOrder` and `cancelOrder` use `attempt()` with their own policies.
|
|
340
342
|
*/
|
|
341
343
|
async request(spec, opts = {}) {
|
|
342
344
|
const info = OPERATIONS[spec.op];
|
|
343
345
|
const idempotencyKey = IDEMPOTENT_OPS.has(spec.op) ? spec.idempotencyKey ?? opts.idempotencyKey ?? newId() : void 0;
|
|
344
|
-
const
|
|
346
|
+
const repeatSafe = info.method === "GET" || REPEAT_SAFE_MUTATIONS.has(spec.op);
|
|
347
|
+
const maxRetries = repeatSafe ? opts.maxRetries ?? this.config.maxRetries : 0;
|
|
345
348
|
for (let attempt = 0; ; attempt++) {
|
|
346
349
|
try {
|
|
347
350
|
return await this.attempt({ ...spec, idempotencyKey }, opts);
|
|
@@ -456,6 +459,7 @@ var Transport = class {
|
|
|
456
459
|
const path = info.path.replace(/\{(\w+)\}/g, (_m, name) => {
|
|
457
460
|
const v = pathParams[name];
|
|
458
461
|
if (typeof v !== "string" || v === "") throw new CexyConfigError(`${info.sdkMethod}(): ${name} is required`);
|
|
462
|
+
if (v === "." || v === "..") throw new CexyConfigError(`${info.sdkMethod}(): ${name} must not be "." or ".."`);
|
|
459
463
|
return encodeURIComponent(v);
|
|
460
464
|
});
|
|
461
465
|
const url = new URL(this.config.baseUrl.replace(/\/+$/, "") + path);
|
|
@@ -478,7 +482,11 @@ function serverHintMs(err) {
|
|
|
478
482
|
}
|
|
479
483
|
function isRetryable(err) {
|
|
480
484
|
if (err instanceof CexyConnectionError) return true;
|
|
481
|
-
if (err instanceof CexyApiError)
|
|
485
|
+
if (err instanceof CexyApiError) {
|
|
486
|
+
const concurrent = err.code === "CONCURRENT_MODIFICATION";
|
|
487
|
+
if (err.status >= 400 && err.status < 500 && err.status !== 429 && !(err.status === 409 && concurrent)) return false;
|
|
488
|
+
return err.retryable || concurrent;
|
|
489
|
+
}
|
|
482
490
|
return false;
|
|
483
491
|
}
|
|
484
492
|
function isAmbiguous(err) {
|
|
@@ -750,12 +758,22 @@ var PoolsResource = class extends Resource {
|
|
|
750
758
|
return this.data({ op: "exit_pool", pathParams: { symbol }, body }, opts);
|
|
751
759
|
}
|
|
752
760
|
};
|
|
761
|
+
function withHeldIncoming(b) {
|
|
762
|
+
if (!b || typeof b !== "object" || Array.isArray(b.held_incoming)) return b;
|
|
763
|
+
return { ...b, held_incoming: [] };
|
|
764
|
+
}
|
|
753
765
|
var AccountResource = class extends Resource {
|
|
754
|
-
|
|
755
|
-
|
|
766
|
+
/**
|
|
767
|
+
* Balances per asset. `held_incoming` lists incoming internal transfers still held; their sum is
|
|
768
|
+
* already included in `locked` (never add it again). Always an array (`[]` when none).
|
|
769
|
+
*/
|
|
770
|
+
async balances(opts) {
|
|
771
|
+
const rows = await this.data({ op: "list_balances" }, opts);
|
|
772
|
+
return Array.isArray(rows) ? rows.map(withHeldIncoming) : rows;
|
|
756
773
|
}
|
|
757
|
-
balance
|
|
758
|
-
|
|
774
|
+
/** One asset's balance. `held_incoming`: incoming transfers still held, already inside `locked`. */
|
|
775
|
+
async balance(asset, opts) {
|
|
776
|
+
return withHeldIncoming(await this.data({ op: "get_balance", pathParams: { asset } }, opts));
|
|
759
777
|
}
|
|
760
778
|
ledger(params, opts) {
|
|
761
779
|
return this.page({ op: "get_ledger", query: params }, opts);
|
|
@@ -772,6 +790,20 @@ var AccountResource = class extends Resource {
|
|
|
772
790
|
subAccounts(opts) {
|
|
773
791
|
return this.data({ op: "list_sub_accounts" }, opts);
|
|
774
792
|
}
|
|
793
|
+
/**
|
|
794
|
+
* A sub-account's balances, read by its PARENT account: the same shape as `balances()`
|
|
795
|
+
* (zero balances omitted), including `held_incoming`, whose sum is already inside `locked`.
|
|
796
|
+
* The server currently returns them ordered by asset symbol; don't rely on the order.
|
|
797
|
+
* An id that is not one of the caller's sub-accounts (or a call with the sub-account's own
|
|
798
|
+
* key) gets `NotFoundError`; a sub-account's own key reads its balances with `balances()`.
|
|
799
|
+
* A malformed id gets 400 (`ValidationError`); a key without the `read` scope gets 403
|
|
800
|
+
* `FORBIDDEN` (`ForbiddenError`). `id` must be non-empty and not "." or ".."; it is sent as
|
|
801
|
+
* one URL path segment.
|
|
802
|
+
*/
|
|
803
|
+
async subAccountBalances(id, opts) {
|
|
804
|
+
const rows = await this.data({ op: "sub_account_balances", pathParams: { id } }, opts);
|
|
805
|
+
return Array.isArray(rows) ? rows.map(withHeldIncoming) : rows;
|
|
806
|
+
}
|
|
775
807
|
/** Your API keys (metadata only; secrets are never returned). */
|
|
776
808
|
apiKeys(opts) {
|
|
777
809
|
return this.data({ op: "list_api_keys" }, opts);
|
|
@@ -1038,7 +1070,7 @@ var TradingResource = class extends Resource {
|
|
|
1038
1070
|
};
|
|
1039
1071
|
|
|
1040
1072
|
// src/version.ts
|
|
1041
|
-
var VERSION = "0.1.0-dev.
|
|
1073
|
+
var VERSION = "0.1.0-dev.7";
|
|
1042
1074
|
var USER_AGENT = `cexy-typescript/${VERSION}`;
|
|
1043
1075
|
|
|
1044
1076
|
// src/ws/emitter.ts
|