@0xmonaco/core 0.8.7 → 0.8.10

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.
Files changed (48) hide show
  1. package/dist/api/applications/api.d.ts +61 -8
  2. package/dist/api/applications/api.js +71 -7
  3. package/dist/api/auth/api.d.ts +44 -76
  4. package/dist/api/auth/api.js +61 -104
  5. package/dist/api/base.d.ts +48 -7
  6. package/dist/api/base.js +95 -12
  7. package/dist/api/delegated-agents/api.d.ts +2 -1
  8. package/dist/api/delegated-agents/api.js +4 -0
  9. package/dist/api/faucet/api.d.ts +25 -0
  10. package/dist/api/faucet/api.js +29 -0
  11. package/dist/api/faucet/index.d.ts +1 -0
  12. package/dist/api/faucet/index.js +1 -0
  13. package/dist/api/index.d.ts +4 -0
  14. package/dist/api/index.js +4 -0
  15. package/dist/api/margin-accounts/api.d.ts +3 -4
  16. package/dist/api/margin-accounts/api.js +8 -15
  17. package/dist/api/market/api.d.ts +3 -1
  18. package/dist/api/market/api.js +8 -0
  19. package/dist/api/orderbook/api.js +2 -1
  20. package/dist/api/perp/routes.d.ts +62 -4
  21. package/dist/api/perp/routes.js +27 -4
  22. package/dist/api/profile/api.d.ts +18 -1
  23. package/dist/api/profile/api.js +41 -1
  24. package/dist/api/sub-accounts/api.d.ts +62 -0
  25. package/dist/api/sub-accounts/api.js +80 -0
  26. package/dist/api/sub-accounts/index.d.ts +1 -0
  27. package/dist/api/sub-accounts/index.js +1 -0
  28. package/dist/api/trades/api.d.ts +12 -1
  29. package/dist/api/trades/api.js +13 -1
  30. package/dist/api/trading/api.d.ts +5 -2
  31. package/dist/api/trading/api.js +13 -27
  32. package/dist/api/websocket/types.d.ts +5 -5
  33. package/dist/api/websocket/websocket.js +43 -22
  34. package/dist/api/whitelist/api.d.ts +27 -0
  35. package/dist/api/whitelist/api.js +32 -0
  36. package/dist/api/whitelist/index.d.ts +1 -0
  37. package/dist/api/whitelist/index.js +1 -0
  38. package/dist/api/withdrawals/api.d.ts +15 -0
  39. package/dist/api/withdrawals/api.js +27 -0
  40. package/dist/api/withdrawals/index.d.ts +1 -0
  41. package/dist/api/withdrawals/index.js +1 -0
  42. package/dist/coverage.d.ts +85 -0
  43. package/dist/coverage.js +85 -0
  44. package/dist/crypto/session.d.ts +40 -0
  45. package/dist/crypto/session.js +60 -0
  46. package/dist/sdk.d.ts +56 -18
  47. package/dist/sdk.js +156 -53
  48. package/package.json +5 -3
@@ -26,15 +26,19 @@ export const perpRoutes = {
26
26
  batchCancelAllByPair: (tradingPairId) => `${API_V1}/orders/batch-cancel-all/${encodeSegment(tradingPairId)}`,
27
27
  batchCreate: () => `${API_V1}/orders/batch-create`,
28
28
  batchReplace: () => `${API_V1}/orders/batch-replace`,
29
- createConditional: () => `${API_V1}/orders/conditional`,
30
29
  listConditional: (params) => withQuery(`${API_V1}/orders/conditional`, params),
31
30
  cancelConditional: (conditionalOrderId) => `${API_V1}/orders/conditional/${encodeSegment(conditionalOrderId)}`,
32
31
  },
33
32
  delegatedAgents: {
34
33
  list: () => `${API_V1}/delegated-agents`,
34
+ owners: () => `${API_V1}/delegated-agents/owners`,
35
35
  byId: (delegatedAgentId) => `${API_V1}/delegated-agents/${encodeSegment(delegatedAgentId)}`,
36
36
  sessions: () => `${API_V1}/delegated-agents/sessions`,
37
37
  },
38
+ withdrawals: {
39
+ initiate: () => `${API_V1}/withdrawals`,
40
+ byIndex: (withdrawalIndex) => `${API_V1}/withdrawals/${encodeSegment(String(withdrawalIndex))}`,
41
+ },
38
42
  market: {
39
43
  listTradingPairs: (params) => withQuery(`${API_V1}/market/pairs`, params),
40
44
  getTradingPair: (tradingPairId) => `${API_V1}/market/pairs/${encodeSegment(tradingPairId)}`,
@@ -47,14 +51,35 @@ export const perpRoutes = {
47
51
  getFundingState: (tradingPairId) => `${API_V1}/market/pairs/${encodeSegment(tradingPairId)}/funding`,
48
52
  listFundingHistory: (tradingPairId, params) => withQuery(`${API_V1}/market/pairs/${encodeSegment(tradingPairId)}/funding/history`, params),
49
53
  getOpenInterest: (tradingPairId) => `${API_V1}/market/pairs/${encodeSegment(tradingPairId)}/open-interest`,
54
+ getScreener: (params) => withQuery(`${API_V1}/market/screener`, params),
50
55
  },
51
56
  orderbook: {
52
57
  get: (tradingPairId, params) => withQuery(`${API_V1}/orderbook/${encodeSegment(tradingPairId)}`, params),
53
58
  },
54
59
  trades: {
55
60
  publicByPair: (tradingPairId, params) => withQuery(`${API_V1}/trades/${encodeSegment(tradingPairId)}`, params),
61
+ byId: (tradeId) => `${API_V1}/trades/by-id/${encodeSegment(tradeId)}`,
56
62
  user: (params) => withQuery(`${API_V1}/accounts/trades`, params),
57
63
  },
64
+ applications: {
65
+ orders: (params) => withQuery(`${API_V1}/applications/orders`, params),
66
+ users: (params) => withQuery(`${API_V1}/applications/users`, params),
67
+ movements: (params) => withQuery(`${API_V1}/applications/movements`, params),
68
+ balances: (params) => withQuery(`${API_V1}/applications/balances`, params),
69
+ stats: (params) => withQuery(`${API_V1}/applications/stats`, params),
70
+ },
71
+ subAccounts: {
72
+ list: () => `${API_V1}/accounts/sub-accounts`,
73
+ createLimit: () => `${API_V1}/accounts/sub-accounts/limits`,
74
+ getLimits: (subAccountId) => `${API_V1}/accounts/sub-accounts/${encodeSegment(subAccountId)}/limits`,
75
+ limit: (subAccountId, assetId) => `${API_V1}/accounts/sub-accounts/${encodeSegment(subAccountId)}/limits/${encodeSegment(assetId)}`,
76
+ },
77
+ faucet: {
78
+ mint: () => `${API_V1}/faucet/mint`,
79
+ },
80
+ whitelist: {
81
+ submit: () => `${API_V1}/whitelist`,
82
+ },
58
83
  positions: {
59
84
  list: (params) => withQuery(`${API_V1}/positions`, params),
60
85
  get: (positionId) => `${API_V1}/positions/${encodeSegment(positionId)}`,
@@ -67,8 +92,7 @@ export const perpRoutes = {
67
92
  },
68
93
  marginAccounts: {
69
94
  list: (params) => withQuery(`${API_V1}/margin/accounts`, params),
70
- create: () => `${API_V1}/margin/accounts`,
71
- summary: (marginAccountId) => `${API_V1}/margin/accounts/${encodeSegment(marginAccountId)}`,
95
+ summary: (marginAccountId, params) => withQuery(`${API_V1}/margin/accounts/${encodeSegment(marginAccountId)}`, params),
72
96
  availableCollateral: (params) => withQuery(`${API_V1}/margin/collateral/available`, params),
73
97
  transferIn: (marginAccountId) => `${API_V1}/margin/accounts/${encodeSegment(marginAccountId)}/collateral/transfer-in`,
74
98
  transferInAuto: () => `${API_V1}/margin/collateral/transfer-in`,
@@ -85,7 +109,6 @@ export const perpRoutes = {
85
109
  privateTrades: () => `${API_V1}/streaming/private-trades`,
86
110
  orders: () => `${API_V1}/streaming/orders`,
87
111
  positions: () => `${API_V1}/streaming/positions`,
88
- marginAccount: () => `${API_V1}/streaming/margin-account`,
89
112
  funding: () => `${API_V1}/streaming/funding`,
90
113
  liquidationAlerts: () => `${API_V1}/streaming/liquidation-alerts`,
91
114
  },
@@ -17,7 +17,7 @@
17
17
  * console.log(`User: ${profile.username} (${profile.address})`);
18
18
  * ```
19
19
  */
20
- import type { AccountBalance, GetPaginatedUserMovementsResponse, GetUserBalancesParams, GetUserBalancesResponse, GetUserMovementsParams, GetUserTradesParams, GetUserTradesResponse, PortfolioChartResponse, PortfolioMetric, PortfolioPeriod, PortfolioStats, ProfileAPI, UserProfile } from "@0xmonaco/types";
20
+ import type { AccountBalance, GetPaginatedUserMovementsResponse, GetUserBalancesParams, GetUserBalancesResponse, GetUserMovementsParams, GetUserTradesParams, GetUserTradesResponse, ListFundingPaymentsParams, ListFundingPaymentsResponse, PortfolioChartResponse, PortfolioMetric, PortfolioPeriod, PortfolioStats, ProfileAPI, UserProfile } from "@0xmonaco/types";
21
21
  import { BaseAPI } from "../base";
22
22
  export declare class ProfileAPIImpl extends BaseAPI implements ProfileAPI {
23
23
  /**
@@ -188,4 +188,21 @@ export declare class ProfileAPIImpl extends BaseAPI implements ProfileAPI {
188
188
  * ```
189
189
  */
190
190
  getUserTrades(params?: GetUserTradesParams): Promise<GetUserTradesResponse>;
191
+ /**
192
+ * List the current user's funding payment history with pagination and filters.
193
+ *
194
+ * Fetches funding payments from the /api/v1/accounts/funding-payments endpoint.
195
+ * Requires a valid access token to be set.
196
+ *
197
+ * @param params - Optional query parameters for pagination and filtering
198
+ * @returns Promise resolving to paginated funding payments response
199
+ * @throws {APIError} When the request fails or user is not authenticated
200
+ *
201
+ * @example
202
+ * ```typescript
203
+ * const funding = await profileAPI.listFundingPayments({ trading_pair_id: "550e8400-e29b-41d4-a716-446655440000" });
204
+ * console.log(`Total funding payments: ${funding.total}`);
205
+ * ```
206
+ */
207
+ listFundingPayments(params?: ListFundingPaymentsParams): Promise<ListFundingPaymentsResponse>;
191
208
  }
@@ -17,7 +17,7 @@
17
17
  * console.log(`User: ${profile.username} (${profile.address})`);
18
18
  * ```
19
19
  */
20
- import { GetUserMovementsSchema, GetUserTradesSchema, validate } from "@0xmonaco/types";
20
+ import { GetUserMovementsSchema, GetUserTradesSchema, ListFundingPaymentsSchema, validate } from "@0xmonaco/types";
21
21
  import { APIError } from "../../errors";
22
22
  import { BaseAPI } from "../base";
23
23
  export class ProfileAPIImpl extends BaseAPI {
@@ -256,4 +256,44 @@ export class ProfileAPIImpl extends BaseAPI {
256
256
  const url = queryString ? `/api/v1/accounts/trades?${queryString}` : "/api/v1/accounts/trades";
257
257
  return await this.makeAuthenticatedRequest(url);
258
258
  }
259
+ /**
260
+ * List the current user's funding payment history with pagination and filters.
261
+ *
262
+ * Fetches funding payments from the /api/v1/accounts/funding-payments endpoint.
263
+ * Requires a valid access token to be set.
264
+ *
265
+ * @param params - Optional query parameters for pagination and filtering
266
+ * @returns Promise resolving to paginated funding payments response
267
+ * @throws {APIError} When the request fails or user is not authenticated
268
+ *
269
+ * @example
270
+ * ```typescript
271
+ * const funding = await profileAPI.listFundingPayments({ trading_pair_id: "550e8400-e29b-41d4-a716-446655440000" });
272
+ * console.log(`Total funding payments: ${funding.total}`);
273
+ * ```
274
+ */
275
+ async listFundingPayments(params) {
276
+ if (params) {
277
+ validate(ListFundingPaymentsSchema, params);
278
+ }
279
+ const searchParams = new URLSearchParams();
280
+ if (params?.page !== undefined) {
281
+ searchParams.append("page", params.page.toString());
282
+ }
283
+ if (params?.page_size !== undefined) {
284
+ searchParams.append("page_size", params.page_size.toString());
285
+ }
286
+ if (params?.trading_pair_id !== undefined) {
287
+ searchParams.append("trading_pair_id", params.trading_pair_id);
288
+ }
289
+ if (params?.position_id !== undefined) {
290
+ searchParams.append("position_id", params.position_id);
291
+ }
292
+ if (params?.margin_account_id !== undefined) {
293
+ searchParams.append("margin_account_id", params.margin_account_id);
294
+ }
295
+ const queryString = searchParams.toString();
296
+ const url = queryString ? `/api/v1/accounts/funding-payments?${queryString}` : "/api/v1/accounts/funding-payments";
297
+ return await this.makeAuthenticatedRequest(url);
298
+ }
259
299
  }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Sub-Accounts API Implementation
3
+ *
4
+ * Manage a master account's sub-accounts and their per-asset spending limits.
5
+ * All methods are session-authenticated. The limit mutations (`createLimit`,
6
+ * `updateLimit`, `deleteLimit`) additionally require the master account to hold
7
+ * the `ManageSubAccounts` permission — enforced server-side, so a non-master or
8
+ * unpermissioned caller receives a 403.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const { sub_accounts } = await sdk.subAccounts.list();
13
+ * await sdk.subAccounts.createLimit({ sub_account_id, asset_id, max_amount: "1000.00" });
14
+ * ```
15
+ */
16
+ import type { CreateSubAccountLimitRequest, CreateSubAccountLimitResponse, GetSubAccountLimitsResponse, ListSubAccountsResponse, SubAccountsAPI, UpdateSubAccountLimitBody, UpdateSubAccountLimitResponse } from "@0xmonaco/types";
17
+ import { BaseAPI } from "../base";
18
+ export declare class SubAccountsAPIImpl extends BaseAPI implements SubAccountsAPI {
19
+ /**
20
+ * Lists the authenticated master account's sub-accounts with balances.
21
+ *
22
+ * @returns Promise resolving to the sub-accounts and total count
23
+ */
24
+ list(): Promise<ListSubAccountsResponse>;
25
+ /**
26
+ * Creates a per-asset spending limit on a sub-account.
27
+ *
28
+ * Requires the `ManageSubAccounts` permission (enforced server-side).
29
+ *
30
+ * @param body - Sub-account, asset, max amount, and optional daily limit
31
+ * @returns Promise resolving to the created limit
32
+ */
33
+ createLimit(body: CreateSubAccountLimitRequest): Promise<CreateSubAccountLimitResponse>;
34
+ /**
35
+ * Gets the limits configured for a sub-account.
36
+ *
37
+ * @param subAccountId - Sub-account UUID
38
+ * @returns Promise resolving to the sub-account's limits
39
+ */
40
+ getLimits(subAccountId: string): Promise<GetSubAccountLimitsResponse>;
41
+ /**
42
+ * Updates a sub-account's per-asset limit (partial update).
43
+ *
44
+ * Requires the `ManageSubAccounts` permission (enforced server-side).
45
+ *
46
+ * @param subAccountId - Sub-account UUID
47
+ * @param assetId - Asset UUID
48
+ * @param body - Fields to update
49
+ * @returns Promise resolving to the updated limit
50
+ */
51
+ updateLimit(subAccountId: string, assetId: string, body: UpdateSubAccountLimitBody): Promise<UpdateSubAccountLimitResponse>;
52
+ /**
53
+ * Deletes a sub-account's per-asset limit.
54
+ *
55
+ * Requires the `ManageSubAccounts` permission (enforced server-side).
56
+ *
57
+ * @param subAccountId - Sub-account UUID
58
+ * @param assetId - Asset UUID
59
+ * @returns Promise resolving when the limit is deleted
60
+ */
61
+ deleteLimit(subAccountId: string, assetId: string): Promise<void>;
62
+ }
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Sub-Accounts API Implementation
3
+ *
4
+ * Manage a master account's sub-accounts and their per-asset spending limits.
5
+ * All methods are session-authenticated. The limit mutations (`createLimit`,
6
+ * `updateLimit`, `deleteLimit`) additionally require the master account to hold
7
+ * the `ManageSubAccounts` permission — enforced server-side, so a non-master or
8
+ * unpermissioned caller receives a 403.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const { sub_accounts } = await sdk.subAccounts.list();
13
+ * await sdk.subAccounts.createLimit({ sub_account_id, asset_id, max_amount: "1000.00" });
14
+ * ```
15
+ */
16
+ import { BaseAPI } from "../base";
17
+ import { perpRoutes } from "../perp/routes";
18
+ export class SubAccountsAPIImpl extends BaseAPI {
19
+ /**
20
+ * Lists the authenticated master account's sub-accounts with balances.
21
+ *
22
+ * @returns Promise resolving to the sub-accounts and total count
23
+ */
24
+ async list() {
25
+ return await this.makeAuthenticatedRequest(perpRoutes.subAccounts.list());
26
+ }
27
+ /**
28
+ * Creates a per-asset spending limit on a sub-account.
29
+ *
30
+ * Requires the `ManageSubAccounts` permission (enforced server-side).
31
+ *
32
+ * @param body - Sub-account, asset, max amount, and optional daily limit
33
+ * @returns Promise resolving to the created limit
34
+ */
35
+ async createLimit(body) {
36
+ return await this.makeAuthenticatedRequest(perpRoutes.subAccounts.createLimit(), {
37
+ method: "POST",
38
+ body: JSON.stringify(body),
39
+ });
40
+ }
41
+ /**
42
+ * Gets the limits configured for a sub-account.
43
+ *
44
+ * @param subAccountId - Sub-account UUID
45
+ * @returns Promise resolving to the sub-account's limits
46
+ */
47
+ async getLimits(subAccountId) {
48
+ return await this.makeAuthenticatedRequest(perpRoutes.subAccounts.getLimits(subAccountId));
49
+ }
50
+ /**
51
+ * Updates a sub-account's per-asset limit (partial update).
52
+ *
53
+ * Requires the `ManageSubAccounts` permission (enforced server-side).
54
+ *
55
+ * @param subAccountId - Sub-account UUID
56
+ * @param assetId - Asset UUID
57
+ * @param body - Fields to update
58
+ * @returns Promise resolving to the updated limit
59
+ */
60
+ async updateLimit(subAccountId, assetId, body) {
61
+ return await this.makeAuthenticatedRequest(perpRoutes.subAccounts.limit(subAccountId, assetId), {
62
+ method: "PUT",
63
+ body: JSON.stringify(body),
64
+ });
65
+ }
66
+ /**
67
+ * Deletes a sub-account's per-asset limit.
68
+ *
69
+ * Requires the `ManageSubAccounts` permission (enforced server-side).
70
+ *
71
+ * @param subAccountId - Sub-account UUID
72
+ * @param assetId - Asset UUID
73
+ * @returns Promise resolving when the limit is deleted
74
+ */
75
+ async deleteLimit(subAccountId, assetId) {
76
+ await this.makeAuthenticatedRequest(perpRoutes.subAccounts.limit(subAccountId, assetId), {
77
+ method: "DELETE",
78
+ });
79
+ }
80
+ }
@@ -0,0 +1 @@
1
+ export { SubAccountsAPIImpl } from "./api";
@@ -0,0 +1 @@
1
+ export { SubAccountsAPIImpl } from "./api";
@@ -11,8 +11,11 @@ interface RawTradeEvent {
11
11
  trade_id: string;
12
12
  price: string;
13
13
  quantity: string;
14
+ /** Raw (integer) quantity; present on single-trade lookups, ignored when mapping */
15
+ quantity_raw?: string;
14
16
  maker_side: string;
15
- executed_at: string;
17
+ /** Absent when the trade has no recorded execution time */
18
+ executed_at?: string;
16
19
  };
17
20
  }
18
21
  /**
@@ -40,5 +43,13 @@ export declare class TradesAPIImpl extends BaseAPI {
40
43
  * @returns Array of TradeEvent records sorted by executed_at descending (newest first)
41
44
  */
42
45
  getTrades(tradingPairId: string, options?: GetTradesOptions): Promise<TradeEvent[]>;
46
+ /**
47
+ * Get a single trade by its UUID.
48
+ *
49
+ * @param tradeId - The trade UUID
50
+ * @returns The matching TradeEvent
51
+ * @throws {APIError} If the trade is not found
52
+ */
53
+ getTradeById(tradeId: string): Promise<TradeEvent>;
43
54
  }
44
55
  export {};
@@ -1,4 +1,5 @@
1
1
  import { BaseAPI } from "../base";
2
+ import { perpRoutes } from "../perp";
2
3
  /**
3
4
  * Convert a raw trade event (snake_case) to a TradeEvent (camelCase)
4
5
  */
@@ -12,7 +13,7 @@ export function parseRawTradeEvent(raw) {
12
13
  price: raw.data.price,
13
14
  quantity: raw.data.quantity,
14
15
  makerSide: raw.data.maker_side.toUpperCase(),
15
- executedAt: raw.data.executed_at,
16
+ executedAt: raw.data.executed_at ?? "",
16
17
  },
17
18
  };
18
19
  }
@@ -39,4 +40,15 @@ export class TradesAPIImpl extends BaseAPI {
39
40
  const response = await this.makePublicRequest(`/api/v1/trades/${encodeURIComponent(tradingPairId)}?${params.toString()}`);
40
41
  return response.trades.map(parseRawTradeEvent);
41
42
  }
43
+ /**
44
+ * Get a single trade by its UUID.
45
+ *
46
+ * @param tradeId - The trade UUID
47
+ * @returns The matching TradeEvent
48
+ * @throws {APIError} If the trade is not found
49
+ */
50
+ async getTradeById(tradeId) {
51
+ const response = await this.makePublicRequest(perpRoutes.trades.byId(tradeId));
52
+ return parseRawTradeEvent(response);
53
+ }
42
54
  }
@@ -21,7 +21,7 @@
21
21
  * );
22
22
  * ```
23
23
  */
24
- import type { BatchCancelOrdersResponse, BatchCreateOrderParams, BatchCreateOrdersResponse, BatchReplaceOrderParams, BatchReplaceOrdersResponse, CancelConditionalOrderResponse, CancelOrderResponse, CreateConditionalOrderParams, CreateConditionalOrderResponse, CreateOrderResponse, GetOrderResponse, GetPaginatedOrdersParams, GetPaginatedOrdersResponse, ListConditionalOrdersParams, ListConditionalOrdersResponse, OrderSide, ParentTpSlLegParams, PositionSide, ReplaceOrderResponse, TimeInForce, TradingAPI, TradingMode } from "@0xmonaco/types";
24
+ import type { BatchCancelOrdersResponse, BatchCreateOrderParams, BatchCreateOrdersResponse, BatchReplaceOrderParams, BatchReplaceOrdersResponse, CancelConditionalOrderResponse, CancelOrderResponse, CreateOrderResponse, GetOrderResponse, GetPaginatedOrdersParams, GetPaginatedOrdersResponse, ListConditionalOrdersParams, ListConditionalOrdersResponse, OrderSide, ParentTpSlLegParams, PositionSide, ReplaceOrderResponse, TimeInForce, TradingAPI, TradingMode } from "@0xmonaco/types";
25
25
  import { BaseAPI } from "../base";
26
26
  export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
27
27
  /**
@@ -80,6 +80,8 @@ export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
80
80
  expirationDate?: string;
81
81
  timeInForce?: TimeInForce;
82
82
  marginAccountId?: string;
83
+ marginBucketId?: string;
84
+ marginBucketCollateral?: string;
83
85
  strategyKey?: string;
84
86
  positionSide?: PositionSide;
85
87
  leverage?: string;
@@ -132,6 +134,8 @@ export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
132
134
  tradingMode?: TradingMode;
133
135
  slippageTolerance?: number;
134
136
  marginAccountId?: string;
137
+ marginBucketId?: string;
138
+ marginBucketCollateral?: string;
135
139
  strategyKey?: string;
136
140
  positionSide?: PositionSide;
137
141
  leverage?: string;
@@ -156,7 +160,6 @@ export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
156
160
  * ```
157
161
  */
158
162
  cancelOrder(orderId: string): Promise<CancelOrderResponse>;
159
- createConditionalOrder(params: CreateConditionalOrderParams): Promise<CreateConditionalOrderResponse>;
160
163
  cancelConditionalOrder(conditionalOrderId: string): Promise<CancelConditionalOrderResponse>;
161
164
  listConditionalOrders(params?: ListConditionalOrdersParams): Promise<ListConditionalOrdersResponse>;
162
165
  /**
@@ -21,7 +21,7 @@
21
21
  * );
22
22
  * ```
23
23
  */
24
- import { BatchCreateOrdersSchema, BatchReplaceOrdersSchema, CancelConditionalOrderSchema, CancelOrderSchema, CreateConditionalOrderSchema, GetPaginatedOrdersSchema, ListConditionalOrdersSchema, PlaceLimitOrderSchema, PlaceMarketOrderSchema, ReplaceOrderSchema, validate, } from "@0xmonaco/types";
24
+ import { BatchCreateOrdersSchema, BatchReplaceOrdersSchema, CancelConditionalOrderSchema, CancelOrderSchema, GetPaginatedOrdersSchema, ListConditionalOrdersSchema, PlaceLimitOrderSchema, PlaceMarketOrderSchema, ReplaceOrderSchema, validate, } from "@0xmonaco/types";
25
25
  import { BaseAPI } from "../base";
26
26
  import { perpRoutes } from "../perp";
27
27
  function parentTpSlLegToRequest(leg) {
@@ -107,6 +107,8 @@ export class TradingAPIImpl extends BaseAPI {
107
107
  expiration_date: options?.expirationDate,
108
108
  time_in_force: options?.timeInForce,
109
109
  margin_account_id: options?.marginAccountId,
110
+ margin_bucket_id: options?.marginBucketId,
111
+ margin_bucket_collateral: options?.marginBucketCollateral,
110
112
  strategy_key: options?.strategyKey,
111
113
  position_side: options?.positionSide,
112
114
  leverage: options?.leverage,
@@ -177,6 +179,8 @@ export class TradingAPIImpl extends BaseAPI {
177
179
  quantity,
178
180
  trading_mode: options?.tradingMode || "SPOT",
179
181
  margin_account_id: options?.marginAccountId,
182
+ margin_bucket_id: options?.marginBucketId,
183
+ margin_bucket_collateral: options?.marginBucketCollateral,
180
184
  strategy_key: options?.strategyKey,
181
185
  position_side: options?.positionSide,
182
186
  leverage: options?.leverage,
@@ -216,29 +220,6 @@ export class TradingAPIImpl extends BaseAPI {
216
220
  body: JSON.stringify(requestBody),
217
221
  });
218
222
  }
219
- async createConditionalOrder(params) {
220
- validate(CreateConditionalOrderSchema, params);
221
- const requestBody = {
222
- trading_pair_id: params.tradingPairId,
223
- margin_account_id: params.marginAccountId,
224
- condition_type: params.conditionType,
225
- trigger_price: params.triggerPrice,
226
- trigger_source: params.triggerSource ?? "MARK_PRICE",
227
- side: params.side,
228
- position_side: params.positionSide,
229
- order_type: params.orderType,
230
- limit_price: params.limitPrice,
231
- quantity: params.quantity,
232
- reduce_only: params.reduceOnly ?? true,
233
- time_in_force: params.timeInForce,
234
- slippage_tolerance_bps: params.slippageToleranceBps,
235
- expires_at: params.expiresAt,
236
- };
237
- return await this.makeAuthenticatedRequest(perpRoutes.orders.createConditional(), {
238
- method: "POST",
239
- body: JSON.stringify(requestBody),
240
- });
241
- }
242
223
  async cancelConditionalOrder(conditionalOrderId) {
243
224
  validate(CancelConditionalOrderSchema, { conditionalOrderId });
244
225
  return await this.makeAuthenticatedRequest(perpRoutes.orders.cancelConditional(conditionalOrderId), {
@@ -363,6 +344,8 @@ export class TradingAPIImpl extends BaseAPI {
363
344
  expiration_date: order.expirationDate,
364
345
  time_in_force: order.timeInForce,
365
346
  margin_account_id: order.marginAccountId,
347
+ margin_bucket_id: order.marginBucketId,
348
+ margin_bucket_collateral: order.marginBucketCollateral,
366
349
  strategy_key: order.strategyKey,
367
350
  position_side: order.positionSide,
368
351
  leverage: order.leverage,
@@ -493,8 +476,11 @@ export class TradingAPIImpl extends BaseAPI {
493
476
  * ```
494
477
  */
495
478
  async getOrder(orderId) {
496
- return await this.makeAuthenticatedRequest(perpRoutes.orders.get(orderId), {
497
- method: "GET",
498
- });
479
+ // The REST endpoint returns the order fields at the top level (a flat
480
+ // `Order`), not wrapped in `{ order, status }`. Wrap it here so the SDK
481
+ // honors its declared `GetOrderResponse` contract. A non-2xx response
482
+ // throws in `makeAuthenticatedRequest`, so reaching here means success.
483
+ const order = await this.makeAuthenticatedRequest(perpRoutes.orders.get(orderId), { method: "GET" });
484
+ return { order, status: "SUCCESS" };
499
485
  }
500
486
  }
@@ -1,9 +1,9 @@
1
- import type { ConditionalOrderEvent, Interval, OHLCVEvent, OrderbookEvent, OrderbookQuotationMode, OrderEvent, TradeEvent, TradingMode, UserBalanceEvent, UserMovementEvent, WebSocketStatus } from "@0xmonaco/types";
1
+ import type { ConditionalOrderEvent, Interval, OHLCVEvent, OrderbookEvent, OrderbookQuotationMode, OrderEvent, SessionCredentials, TradeEvent, TradingMode, UserBalanceEvent, UserMovementEvent, WebSocketStatus } from "@0xmonaco/types";
2
2
  export type StatusHandler = (status: WebSocketStatus) => void;
3
3
  export type MessageHandler<T> = (data: T) => void;
4
4
  export interface MonacoWebSocketOptions {
5
- /** JWT access token for authenticated channels (orders) */
6
- token?: string;
5
+ /** Session keypair for authenticated channels (orders, balances, etc.) */
6
+ session?: SessionCredentials;
7
7
  /** Enable auto-reconnect on disconnect (default: true) */
8
8
  autoReconnect?: boolean;
9
9
  /** Maximum reconnection attempts (default: 5) */
@@ -20,8 +20,8 @@ export interface MonacoWebSocket {
20
20
  isConnected: () => boolean;
21
21
  /** Get current websocket connection status */
22
22
  getStatus: () => WebSocketStatus;
23
- /** Update the access token (for re-auth) */
24
- setToken: (token: string) => void;
23
+ /** Set (or clear) the session keypair used to authenticate the connection */
24
+ setSessionKeypair: (credentials: SessionCredentials | undefined) => void;
25
25
  /** Subscribe to order events (requires authentication) */
26
26
  orders: (tradingPairId: string, tradingMode: TradingMode, handler: MessageHandler<OrderEvent>) => () => void;
27
27
  /** Subscribe to orderbook events (public) */
@@ -1,3 +1,5 @@
1
+ import { hexToBytes } from "@noble/hashes/utils";
2
+ import { composeWsSigningString, signMessage } from "../../crypto/session";
1
3
  import { ALL_MAGNITUDES } from "../../utils";
2
4
  import { keysToCamelCase } from "./utils";
3
5
  // Connection constants
@@ -107,7 +109,7 @@ function parseConditionalOrderEvent(rawData) {
107
109
  */
108
110
  export function createMonacoWebSocket(baseUrl, options = {}) {
109
111
  let ws = null;
110
- let token = options.token;
112
+ let session = options.session;
111
113
  let reconnectAttempts = 0;
112
114
  let reconnectTimer = null;
113
115
  let heartbeatTimer = null;
@@ -127,11 +129,24 @@ export function createMonacoWebSocket(baseUrl, options = {}) {
127
129
  return "disconnected";
128
130
  }
129
131
  };
130
- const getUrl = () => {
131
- const url = new URL(baseUrl);
132
- if (token)
133
- url.searchParams.set("token", token);
134
- return url.toString();
132
+ const getUrl = () => baseUrl;
133
+ /**
134
+ * Send the signed auth handshake as the first message after the socket
135
+ * opens. The client signs `WS-AUTH\n<pubkey>\n<ts>` with the session private
136
+ * key; the server binds the connection to the session. No-op if no session
137
+ * is set (public channels work unauthenticated).
138
+ */
139
+ const sendAuthenticate = () => {
140
+ if (!session || ws?.readyState !== WebSocket.OPEN)
141
+ return;
142
+ const timestamp = Date.now();
143
+ const signature = signMessage(hexToBytes(session.privateKey), composeWsSigningString(session.publicKey, timestamp));
144
+ ws.send(JSON.stringify({
145
+ type: "Authenticate",
146
+ public_key: session.publicKey,
147
+ timestamp,
148
+ signature,
149
+ }));
135
150
  };
136
151
  const stopHeartbeat = () => {
137
152
  if (heartbeatTimer) {
@@ -217,6 +232,9 @@ export function createMonacoWebSocket(baseUrl, options = {}) {
217
232
  }
218
233
  reconnectAttempts = 0;
219
234
  startHeartbeat();
235
+ // Authenticate before resubscribing so user-specific channels
236
+ // (orders, balances, …) are authorized when the Subscribe arrives.
237
+ sendAuthenticate();
220
238
  resubscribeAll();
221
239
  options.onStatusChange?.("connected");
222
240
  resolve();
@@ -324,7 +342,9 @@ export function createMonacoWebSocket(baseUrl, options = {}) {
324
342
  const data = rawData;
325
343
  const orderbookData = data.data;
326
344
  const event = {
327
- tradingPairId: data.symbol,
345
+ // `trading_pair_id` is the pair UUID; `symbol` is the display string
346
+ // (e.g. "AMZN/USDC"). `tradingPairId` must carry the UUID.
347
+ tradingPairId: data.trading_pair_id,
328
348
  tradingMode: data.trading_mode,
329
349
  bids: (orderbookData?.bids || []).map((level) => ({
330
350
  price: level.price,
@@ -368,7 +388,9 @@ export function createMonacoWebSocket(baseUrl, options = {}) {
368
388
  const data = rawData;
369
389
  const ohlcvData = data.data;
370
390
  const event = {
371
- tradingPairId: data.symbol,
391
+ // `trading_pair_id` is the pair UUID; `symbol` is the display string.
392
+ // `tradingPairId` must carry the UUID (the symbol lives in `candlestick.s`).
393
+ tradingPairId: data.trading_pair_id,
372
394
  tradingMode: data.trading_mode,
373
395
  interval: data.interval,
374
396
  candlestick: {
@@ -532,21 +554,20 @@ export function createMonacoWebSocket(baseUrl, options = {}) {
532
554
  disconnect,
533
555
  isConnected: () => ws?.readyState === WebSocket.OPEN,
534
556
  getStatus,
535
- setToken: (newToken) => {
536
- token = newToken || undefined;
537
- stopReconnect();
538
- const currentSocket = ws;
539
- if (currentSocket?.readyState === WebSocket.OPEN ||
540
- currentSocket?.readyState === WebSocket.CONNECTING ||
541
- currentSocket?.readyState === WebSocket.CLOSING) {
542
- currentSocket.close(1000, newToken ? "Token updated, reconnecting." : "Token cleared.");
543
- ws = null;
557
+ setSessionKeypair: (credentials) => {
558
+ session = credentials ?? undefined;
559
+ // If already connected, (re)send the signed handshake so the connection
560
+ // picks up the new session without tearing down. If not yet connected,
561
+ // onopen will send it. Clearing the session leaves the connection up for
562
+ // public channels; logout calls disconnect() to fully tear down.
563
+ if (session && ws?.readyState === WebSocket.OPEN) {
564
+ sendAuthenticate();
565
+ }
566
+ else if (session && (!ws || ws.readyState === WebSocket.CLOSED)) {
567
+ connect().catch((err) => {
568
+ console.warn("WebSocket: Failed to connect after session update:", err);
569
+ });
544
570
  }
545
- if (!newToken)
546
- return;
547
- connect().catch((err) => {
548
- console.warn("WebSocket: Failed to reconnect after token update:", err);
549
- });
550
571
  },
551
572
  orders: subscribeOrders,
552
573
  orderbook: subscribeOrderbook,
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Whitelist API Implementation
3
+ *
4
+ * Public (unauthenticated) whitelist/waitlist application submission. The
5
+ * server validates and de-duplicates by wallet address and email, creating an
6
+ * inactive user pending manual approval. This is an onboarding endpoint, not a
7
+ * trading operation.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const { message, user_id } = await sdk.whitelist.submit({
12
+ * wallet_address: "0x...",
13
+ * email: "user@example.com",
14
+ * });
15
+ * ```
16
+ */
17
+ import type { SubmitWhitelistRequest, SubmitWhitelistResponse, WhitelistAPI } from "@0xmonaco/types";
18
+ import { BaseAPI } from "../base";
19
+ export declare class WhitelistAPIImpl extends BaseAPI implements WhitelistAPI {
20
+ /**
21
+ * Submits a whitelist (waitlist) application. Public — no auth required.
22
+ *
23
+ * @param body - Applicant details
24
+ * @returns Promise resolving to the status message and created user id
25
+ */
26
+ submit(body: SubmitWhitelistRequest): Promise<SubmitWhitelistResponse>;
27
+ }