@0xmonaco/core 1.0.56 → 1.0.58

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/dist/api/base.js CHANGED
@@ -20,7 +20,7 @@
20
20
  * }
21
21
  * ```
22
22
  */
23
- import { bytesToHex, utf8ToBytes } from "@noble/hashes/utils";
23
+ import { bytesToHex, utf8ToBytes } from "@noble/hashes/utils.js";
24
24
  import { StatusCodes } from "http-status-codes";
25
25
  import { buildHttpSignatureHeaders } from "../crypto/http-signatures";
26
26
  import { composeSigningString, keypairFromHex, sha256Hex, signMessage } from "../crypto/session";
@@ -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, ListFundingPaymentsParams, ListFundingPaymentsResponse, 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, SelfTradePreventionDefault, SelfTradePreventionMode, UserProfile } from "@0xmonaco/types";
21
21
  import { BaseAPI } from "../base";
22
22
  export declare class ProfileAPIImpl extends BaseAPI implements ProfileAPI {
23
23
  /**
@@ -245,4 +245,42 @@ export declare class ProfileAPIImpl extends BaseAPI implements ProfileAPI {
245
245
  * ```
246
246
  */
247
247
  listFundingPayments(params?: ListFundingPaymentsParams): Promise<ListFundingPaymentsResponse>;
248
+ /**
249
+ * Get the wallet's self-trade-prevention default.
250
+ *
251
+ * Fetches the setting from the /api/v1/accounts/self-trade-prevention endpoint.
252
+ * Requires a valid access token to be set. The default is wallet-scoped: it
253
+ * covers every application and account sharing the wallet address, and a
254
+ * per-order mode always overrides it.
255
+ *
256
+ * @returns Promise resolving to the effective mode plus whether it was explicitly set
257
+ * @throws {APIError} When the request fails or user is not authenticated
258
+ *
259
+ * @example
260
+ * ```typescript
261
+ * const stp = await profileAPI.getSelfTradePreventionDefault();
262
+ * console.log(`Mode: ${stp.mode} (explicitly set: ${stp.isCustom})`);
263
+ * ```
264
+ */
265
+ getSelfTradePreventionDefault(): Promise<SelfTradePreventionDefault>;
266
+ /**
267
+ * Set the wallet's self-trade-prevention default.
268
+ *
269
+ * Sends a PUT to the /api/v1/accounts/self-trade-prevention endpoint. The
270
+ * write is sequenced through the matching engine; on success the wallet
271
+ * family's next order already resolves the new mode. Delegated-agent
272
+ * sessions cannot change it (403).
273
+ *
274
+ * @param mode - One of "CANCEL_MAKER", "CANCEL_TAKER", "CANCEL_BOTH", "SKIP"
275
+ * @returns Promise resolving to the setting now in force
276
+ * @throws ValidationError If mode is not a known token; this occurs before any network request.
277
+ * @throws {APIError} When the request fails or user is not authenticated
278
+ *
279
+ * @example
280
+ * ```typescript
281
+ * const stp = await profileAPI.setSelfTradePreventionDefault("SKIP");
282
+ * console.log(`Mode is now ${stp.mode}`);
283
+ * ```
284
+ */
285
+ setSelfTradePreventionDefault(mode: SelfTradePreventionMode): Promise<SelfTradePreventionDefault>;
248
286
  }
@@ -17,7 +17,7 @@
17
17
  * console.log(`User: ${profile.username} (${profile.address})`);
18
18
  * ```
19
19
  */
20
- import { GetUserMovementsSchema, GetUserTradesSchema, ListFundingPaymentsSchema, validate } from "@0xmonaco/types";
20
+ import { GetUserMovementsSchema, GetUserTradesSchema, ListFundingPaymentsSchema, SetSelfTradePreventionDefaultSchema, validate } from "@0xmonaco/types";
21
21
  import { APIError } from "../../errors";
22
22
  import { BaseAPI } from "../base";
23
23
  export class ProfileAPIImpl extends BaseAPI {
@@ -360,4 +360,50 @@ export class ProfileAPIImpl extends BaseAPI {
360
360
  const url = queryString ? `/api/v1/accounts/funding-payments?${queryString}` : "/api/v1/accounts/funding-payments";
361
361
  return await this.makeAuthenticatedRequest(url);
362
362
  }
363
+ /**
364
+ * Get the wallet's self-trade-prevention default.
365
+ *
366
+ * Fetches the setting from the /api/v1/accounts/self-trade-prevention endpoint.
367
+ * Requires a valid access token to be set. The default is wallet-scoped: it
368
+ * covers every application and account sharing the wallet address, and a
369
+ * per-order mode always overrides it.
370
+ *
371
+ * @returns Promise resolving to the effective mode plus whether it was explicitly set
372
+ * @throws {APIError} When the request fails or user is not authenticated
373
+ *
374
+ * @example
375
+ * ```typescript
376
+ * const stp = await profileAPI.getSelfTradePreventionDefault();
377
+ * console.log(`Mode: ${stp.mode} (explicitly set: ${stp.isCustom})`);
378
+ * ```
379
+ */
380
+ async getSelfTradePreventionDefault() {
381
+ return await this.makeAuthenticatedRequest("/api/v1/accounts/self-trade-prevention");
382
+ }
383
+ /**
384
+ * Set the wallet's self-trade-prevention default.
385
+ *
386
+ * Sends a PUT to the /api/v1/accounts/self-trade-prevention endpoint. The
387
+ * write is sequenced through the matching engine; on success the wallet
388
+ * family's next order already resolves the new mode. Delegated-agent
389
+ * sessions cannot change it (403).
390
+ *
391
+ * @param mode - One of "CANCEL_MAKER", "CANCEL_TAKER", "CANCEL_BOTH", "SKIP"
392
+ * @returns Promise resolving to the setting now in force
393
+ * @throws ValidationError If mode is not a known token; this occurs before any network request.
394
+ * @throws {APIError} When the request fails or user is not authenticated
395
+ *
396
+ * @example
397
+ * ```typescript
398
+ * const stp = await profileAPI.setSelfTradePreventionDefault("SKIP");
399
+ * console.log(`Mode is now ${stp.mode}`);
400
+ * ```
401
+ */
402
+ async setSelfTradePreventionDefault(mode) {
403
+ const validated = validate(SetSelfTradePreventionDefaultSchema, { mode });
404
+ return await this.makeAuthenticatedRequest("/api/v1/accounts/self-trade-prevention", {
405
+ method: "PUT",
406
+ body: JSON.stringify(validated),
407
+ });
408
+ }
363
409
  }
@@ -21,7 +21,7 @@
21
21
  * );
22
22
  * ```
23
23
  */
24
- import type { BatchCancelOrdersResponse, BatchCreateOrderParams, BatchCreateOrdersResponse, BatchReplaceOrderParams, BatchReplaceOrdersResponse, CancelConditionalOrderResponse, CancelOrderResponse, CancelTwapOrderResponse, ConditionalOrder, CreateOrderResponse, CreateTwapOrderOptions, CreateTwapOrderResponse, GetOrderResponse, GetPaginatedOrdersParams, GetPaginatedOrdersResponse, GetTwapOrderTcaResponse, ListConditionalOrdersParams, ListConditionalOrdersResponse, ListTwapOrdersParams, ListTwapOrdersResponse, MarginMode, OrderSide, ParentTpSlLegParams, PositionSide, ReplaceOrderResponse, TimeInForce, TradingAPI, TradingMode, TwapOrder } from "@0xmonaco/types";
24
+ import type { BatchCancelOrdersResponse, BatchCreateOrderParams, BatchCreateOrdersResponse, BatchReplaceOrderParams, BatchReplaceOrdersResponse, CancelConditionalOrderResponse, CancelOrderResponse, CancelTwapOrderResponse, ConditionalOrder, CreateOrderResponse, CreateTwapOrderOptions, CreateTwapOrderResponse, GetOrderResponse, GetPaginatedOrdersParams, GetPaginatedOrdersResponse, GetTwapOrderTcaResponse, ListConditionalOrdersParams, ListConditionalOrdersResponse, ListTwapOrdersParams, ListTwapOrdersResponse, MarginMode, OrderSide, ParentTpSlLegParams, PositionSide, ReplaceOrderResponse, SelfTradePreventionMode, TimeInForce, TradingAPI, TradingMode, TwapOrder } from "@0xmonaco/types";
25
25
  import { BaseAPI } from "../base";
26
26
  export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
27
27
  /**
@@ -88,6 +88,7 @@ export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
88
88
  leverage?: string;
89
89
  reduceOnly?: boolean;
90
90
  postOnly?: boolean;
91
+ selfTradePreventionMode?: SelfTradePreventionMode;
91
92
  clientOrderId?: string;
92
93
  /** Generated once per call when omitted. Supply the same key to retry a logical order within 24 hours. */
93
94
  idempotencyKey?: string;
@@ -148,6 +149,7 @@ export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
148
149
  positionSide?: PositionSide;
149
150
  leverage?: string;
150
151
  reduceOnly?: boolean;
152
+ selfTradePreventionMode?: SelfTradePreventionMode;
151
153
  takeProfit?: ParentTpSlLegParams;
152
154
  stopLoss?: ParentTpSlLegParams;
153
155
  clientOrderId?: string;
@@ -218,6 +220,7 @@ export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
218
220
  quantity?: string;
219
221
  useMasterBalance?: boolean;
220
222
  postOnly?: boolean;
223
+ selfTradePreventionMode?: SelfTradePreventionMode;
221
224
  clientOrderId?: string;
222
225
  }): Promise<ReplaceOrderResponse>;
223
226
  /**
@@ -257,6 +260,17 @@ export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
257
260
  * Each order is canceled and re-created with new parameters.
258
261
  * Failed replacements do not prevent other orders from being replaced.
259
262
  *
263
+ * Pre-sequencing validation is scoped per item too, matching `batchCreate`:
264
+ * a malformed `orderId`, `price`, `quantity` or `clientOrderId`, or a
265
+ * `postOnly` violation, fails only that item — its result slot carries a
266
+ * structured `error.code` (`INVALID_ORDER_ID`, `INVALID_PRICE`,
267
+ * `INVALID_QUANTITY`, `INVALID_CLIENT_ORDER_ID`, `INVALID_POST_ONLY`) and its
268
+ * original is left untouched — while the valid items proceed. A `2xx`
269
+ * response can therefore mix executed replacements and failed items: read
270
+ * `results[]` per item rather than treating the status code as the verdict.
271
+ * Only an empty or oversize (>100) batch rejects the whole request.
272
+ * `totalRequested === totalSucceeded + totalFailed` always holds.
273
+ *
260
274
  * @param orders - Array of order replacement parameters
261
275
  * @returns Promise resolving to BatchReplaceOrdersResponse with individual results
262
276
  * @throws {APIError} When API communication fails
@@ -281,6 +295,11 @@ export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
281
295
  * Gets orders based on query parameters, cursor-paginated by default.
282
296
  *
283
297
  * Retrieves orders with optional filtering by status, trading pair, and pagination.
298
+ * Every kind of order comes back in ONE stream ordered by timestamp: book orders,
299
+ * TWAP parents (`orderType: "TWAP"`, detail on `twap`) and conditional orders
300
+ * (`orderType: "CONDITIONAL"`, detail on `conditional`). There is no separate
301
+ * open-orders call — filter `status` to `["SUBMITTED", "PARTIALLY_FILLED"]` for the
302
+ * working set.
284
303
  * When neither `page` nor `pageToken` is passed, the SDK drives cursor (pageToken)
285
304
  * pagination: it starts a cursor walk from the newest (or oldest, for
286
305
  * `orderBy: "ASC"`) row and the response's `nextPageToken` resumes it. Cursor
@@ -305,6 +324,17 @@ export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
305
324
  *
306
325
  * @example
307
326
  * ```typescript
327
+ * // Every working order, of every kind, in one page
328
+ * const open = await tradingAPI.getPaginatedOrders({ status: ["SUBMITTED", "PARTIALLY_FILLED"] });
329
+ * for (const order of open.orders) {
330
+ * if (order.orderType === "TWAP") console.log("TWAP parent", order.twap?.slicesPlaced);
331
+ * else if (order.orderType === "CONDITIONAL") console.log("trigger", order.conditional?.triggerPrice);
332
+ * else console.log("resting", order.price);
333
+ * }
334
+ * ```
335
+ *
336
+ * @example
337
+ * ```typescript
308
338
  * // Walk full order history with cursor pagination (the default mode)
309
339
  * let pageToken: string | undefined;
310
340
  * do {
@@ -120,6 +120,7 @@ export class TradingAPIImpl extends BaseAPI {
120
120
  leverage: options?.leverage,
121
121
  reduceOnly: options?.reduceOnly,
122
122
  postOnly: options?.postOnly,
123
+ selfTradePreventionMode: options?.selfTradePreventionMode,
123
124
  clientOrderId: options?.clientOrderId,
124
125
  idempotencyKey: options?.idempotencyKey === undefined ? crypto.randomUUID() : options.idempotencyKey,
125
126
  takeProfit: parentTpSlLegToRequest(options?.takeProfit),
@@ -197,6 +198,7 @@ export class TradingAPIImpl extends BaseAPI {
197
198
  positionSide: options?.positionSide,
198
199
  leverage: options?.leverage,
199
200
  reduceOnly: options?.reduceOnly,
201
+ selfTradePreventionMode: options?.selfTradePreventionMode,
200
202
  takeProfit: parentTpSlLegToRequest(options?.takeProfit),
201
203
  stopLoss: parentTpSlLegToRequest(options?.stopLoss),
202
204
  clientOrderId: options?.clientOrderId,
@@ -327,6 +329,9 @@ export class TradingAPIImpl extends BaseAPI {
327
329
  if (newOrder.postOnly !== undefined) {
328
330
  requestBody.postOnly = newOrder.postOnly;
329
331
  }
332
+ if (newOrder.selfTradePreventionMode !== undefined) {
333
+ requestBody.selfTradePreventionMode = newOrder.selfTradePreventionMode;
334
+ }
330
335
  if (newOrder.clientOrderId !== undefined) {
331
336
  requestBody.clientOrderId = newOrder.clientOrderId;
332
337
  }
@@ -388,6 +393,7 @@ export class TradingAPIImpl extends BaseAPI {
388
393
  leverage: order.leverage,
389
394
  reduceOnly: order.reduceOnly,
390
395
  postOnly: order.postOnly,
396
+ selfTradePreventionMode: order.selfTradePreventionMode,
391
397
  clientOrderId: order.clientOrderId,
392
398
  idempotencyKey: order.idempotencyKey === undefined ? crypto.randomUUID() : order.idempotencyKey,
393
399
  })),
@@ -403,6 +409,17 @@ export class TradingAPIImpl extends BaseAPI {
403
409
  * Each order is canceled and re-created with new parameters.
404
410
  * Failed replacements do not prevent other orders from being replaced.
405
411
  *
412
+ * Pre-sequencing validation is scoped per item too, matching `batchCreate`:
413
+ * a malformed `orderId`, `price`, `quantity` or `clientOrderId`, or a
414
+ * `postOnly` violation, fails only that item — its result slot carries a
415
+ * structured `error.code` (`INVALID_ORDER_ID`, `INVALID_PRICE`,
416
+ * `INVALID_QUANTITY`, `INVALID_CLIENT_ORDER_ID`, `INVALID_POST_ONLY`) and its
417
+ * original is left untouched — while the valid items proceed. A `2xx`
418
+ * response can therefore mix executed replacements and failed items: read
419
+ * `results[]` per item rather than treating the status code as the verdict.
420
+ * Only an empty or oversize (>100) batch rejects the whole request.
421
+ * `totalRequested === totalSucceeded + totalFailed` always holds.
422
+ *
406
423
  * @param orders - Array of order replacement parameters
407
424
  * @returns Promise resolving to BatchReplaceOrdersResponse with individual results
408
425
  * @throws {APIError} When API communication fails
@@ -431,6 +448,7 @@ export class TradingAPIImpl extends BaseAPI {
431
448
  quantity: order.quantity,
432
449
  useMasterBalance: order.useMasterBalance,
433
450
  postOnly: order.postOnly,
451
+ selfTradePreventionMode: order.selfTradePreventionMode,
434
452
  clientOrderId: order.clientOrderId,
435
453
  })),
436
454
  };
@@ -443,6 +461,11 @@ export class TradingAPIImpl extends BaseAPI {
443
461
  * Gets orders based on query parameters, cursor-paginated by default.
444
462
  *
445
463
  * Retrieves orders with optional filtering by status, trading pair, and pagination.
464
+ * Every kind of order comes back in ONE stream ordered by timestamp: book orders,
465
+ * TWAP parents (`orderType: "TWAP"`, detail on `twap`) and conditional orders
466
+ * (`orderType: "CONDITIONAL"`, detail on `conditional`). There is no separate
467
+ * open-orders call — filter `status` to `["SUBMITTED", "PARTIALLY_FILLED"]` for the
468
+ * working set.
446
469
  * When neither `page` nor `pageToken` is passed, the SDK drives cursor (pageToken)
447
470
  * pagination: it starts a cursor walk from the newest (or oldest, for
448
471
  * `orderBy: "ASC"`) row and the response's `nextPageToken` resumes it. Cursor
@@ -467,6 +490,17 @@ export class TradingAPIImpl extends BaseAPI {
467
490
  *
468
491
  * @example
469
492
  * ```typescript
493
+ * // Every working order, of every kind, in one page
494
+ * const open = await tradingAPI.getPaginatedOrders({ status: ["SUBMITTED", "PARTIALLY_FILLED"] });
495
+ * for (const order of open.orders) {
496
+ * if (order.orderType === "TWAP") console.log("TWAP parent", order.twap?.slicesPlaced);
497
+ * else if (order.orderType === "CONDITIONAL") console.log("trigger", order.conditional?.triggerPrice);
498
+ * else console.log("resting", order.price);
499
+ * }
500
+ * ```
501
+ *
502
+ * @example
503
+ * ```typescript
470
504
  * // Walk full order history with cursor pagination (the default mode)
471
505
  * let pageToken: string | undefined;
472
506
  * do {
@@ -1,4 +1,4 @@
1
- import { hexToBytes } from "@noble/hashes/utils";
1
+ import { hexToBytes } from "@noble/hashes/utils.js";
2
2
  import { composeWsSigningString, signMessage } from "../../crypto/session";
3
3
  import { ALL_MAGNITUDES } from "../../utils";
4
4
  import { keysToCamelCase } from "./utils";
@@ -543,6 +543,7 @@ function parseOrderSnapshotItem(raw) {
543
543
  // conditionally so an absent one stays absent rather than becoming
544
544
  // `clientOrderId: undefined`, which a structural comparison would see.
545
545
  const clientOrderId = readOptionalString(item, "clientOrderId");
546
+ const selfTradePreventionMode = readOptionalString(item, "selfTradePreventionMode");
546
547
  const version = readOptionalNumber(item, "version");
547
548
  return {
548
549
  orderId: readString(item, "orderId"),
@@ -574,6 +575,9 @@ function parseOrderSnapshotItem(raw) {
574
575
  leverage: readNullableString(item, "leverage"),
575
576
  reduceOnly: readBoolean(item, "reduceOnly"),
576
577
  ...(clientOrderId === undefined ? {} : { clientOrderId }),
578
+ // Spread in conditionally like `clientOrderId`: absent means the order
579
+ // requested no override, and must stay absent (0XM-2733).
580
+ ...(selfTradePreventionMode === undefined ? {} : { selfTradePreventionMode }),
577
581
  // Spread in conditionally for the same reason as `clientOrderId`: the
578
582
  // server omits the key when unknown, and absent must stay absent rather
579
583
  // than becoming `version: undefined` — a resync compares this value, and
@@ -38,7 +38,9 @@ export declare const COVERED: {
38
38
  get_sweeper_chains: string;
39
39
  get_my_trader_code: string;
40
40
  get_rewards_balance: string;
41
+ get_self_trade_prevention_default: string;
41
42
  get_trader_code_info: string;
43
+ set_self_trade_prevention_default: string;
42
44
  set_trader_code: string;
43
45
  clear_trader_code: string;
44
46
  check_trader_code_availability: string;
package/dist/coverage.js CHANGED
@@ -38,7 +38,9 @@ export const COVERED = {
38
38
  get_sweeper_chains: "sweeper.getChains",
39
39
  get_my_trader_code: "pitpass.getMyTraderCode",
40
40
  get_rewards_balance: "pitpass.getRewardsBalance",
41
+ get_self_trade_prevention_default: "profile.getSelfTradePreventionDefault",
41
42
  get_trader_code_info: "pitpass.getTraderCodeInfo",
43
+ set_self_trade_prevention_default: "profile.setSelfTradePreventionDefault",
42
44
  set_trader_code: "pitpass.setTraderCode",
43
45
  clear_trader_code: "pitpass.clearTraderCode",
44
46
  check_trader_code_availability: "pitpass.checkTraderCodeAvailability",
@@ -1,7 +1,7 @@
1
1
  /** Monaco's RFC 9421 Ed25519 profile; key registration remains wallet-authorized. */
2
2
  import { ed25519 } from "@noble/curves/ed25519";
3
- import { sha256 } from "@noble/hashes/sha2";
4
- import { bytesToHex, utf8ToBytes } from "@noble/hashes/utils";
3
+ import { sha256 } from "@noble/hashes/sha2.js";
4
+ import { bytesToHex, utf8ToBytes } from "@noble/hashes/utils.js";
5
5
  function base64(bytes) {
6
6
  return btoa(String.fromCharCode(...bytes));
7
7
  }
@@ -8,8 +8,8 @@
8
8
  * key — it never sees the private key, so it cannot mint requests as the user.
9
9
  */
10
10
  import { ed25519 } from "@noble/curves/ed25519";
11
- import { sha256 } from "@noble/hashes/sha2";
12
- import { bytesToHex, hexToBytes, utf8ToBytes } from "@noble/hashes/utils";
11
+ import { sha256 } from "@noble/hashes/sha2.js";
12
+ import { bytesToHex, hexToBytes, utf8ToBytes } from "@noble/hashes/utils.js";
13
13
  /**
14
14
  * Generate a fresh ed25519 session keypair.
15
15
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xmonaco/core",
3
- "version": "1.0.56",
3
+ "version": "1.0.58",
4
4
  "type": "module",
5
5
  "homepage": "https://docs.0xmonaco.com/sdk/typescript",
6
6
  "main": "./dist/index.js",
@@ -19,10 +19,10 @@
19
19
  "viem": "^2.45.2"
20
20
  },
21
21
  "dependencies": {
22
- "@0xmonaco/contracts": "1.0.56",
23
- "@0xmonaco/types": "1.0.56",
22
+ "@0xmonaco/contracts": "1.0.58",
23
+ "@0xmonaco/types": "1.0.58",
24
24
  "@noble/curves": "^1.9.1",
25
- "@noble/hashes": "^1.8.0",
25
+ "@noble/hashes": "^2.4.0",
26
26
  "http-status-codes": "^2.3.0"
27
27
  },
28
28
  "devDependencies": {