@0xmonaco/core 1.0.55 → 1.0.57
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 +1 -1
- package/dist/api/perp/routes.d.ts +1 -0
- package/dist/api/perp/routes.js +1 -0
- package/dist/api/sweeper/api.d.ts +16 -1
- package/dist/api/sweeper/api.js +19 -0
- package/dist/api/trading/api.d.ts +27 -0
- package/dist/api/trading/api.js +27 -0
- package/dist/api/websocket/websocket.js +31 -5
- package/dist/coverage.d.ts +1 -0
- package/dist/coverage.js +1 -0
- package/dist/crypto/http-signatures.js +2 -2
- package/dist/crypto/session.js +2 -2
- package/package.json +4 -4
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";
|
package/dist/api/perp/routes.js
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* const margin = await sdk.sweeper.register({ depositTarget: "margin" });
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
|
-
import type { RegisterSweeperRequest, RegisterSweeperResponse, SweeperAPI } from "@0xmonaco/types";
|
|
25
|
+
import type { GetSweeperChainsResponse, RegisterSweeperRequest, RegisterSweeperResponse, SweeperAPI } from "@0xmonaco/types";
|
|
26
26
|
import { BaseAPI } from "../base";
|
|
27
27
|
export declare class SweeperAPIImpl extends BaseAPI implements SweeperAPI {
|
|
28
28
|
/**
|
|
@@ -42,10 +42,25 @@ export declare class SweeperAPIImpl extends BaseAPI implements SweeperAPI {
|
|
|
42
42
|
* rather than a guarantee, since a deposit the backend cannot route to
|
|
43
43
|
* collateral is credited to the spot wallet instead.
|
|
44
44
|
*
|
|
45
|
+
* The deposit address is identical on every supported chain and one
|
|
46
|
+
* registration is watched on all of them (see {@link getChains} for the
|
|
47
|
+
* set), so there is nothing chain-specific to pass.
|
|
48
|
+
*
|
|
45
49
|
* @param body - Optionally the destination ledger; everything else comes
|
|
46
50
|
* from the session
|
|
47
51
|
* @returns Promise resolving to the deposit address and the initial-check
|
|
48
52
|
* state
|
|
49
53
|
*/
|
|
50
54
|
register(body?: RegisterSweeperRequest): Promise<RegisterSweeperResponse>;
|
|
55
|
+
/**
|
|
56
|
+
* The chains and assets the sweeper watches: where a registered deposit
|
|
57
|
+
* address accepts deposits, which tokens are swept on each chain, and each
|
|
58
|
+
* token's minimum sweep amount in raw base units.
|
|
59
|
+
*
|
|
60
|
+
* Public — no session needed. The set changes only with operator
|
|
61
|
+
* configuration, so it is safe to cache briefly.
|
|
62
|
+
*
|
|
63
|
+
* @returns Promise resolving to the supported chain/asset listing
|
|
64
|
+
*/
|
|
65
|
+
getChains(): Promise<GetSweeperChainsResponse>;
|
|
51
66
|
}
|
package/dist/api/sweeper/api.js
CHANGED
|
@@ -69,6 +69,10 @@ export class SweeperAPIImpl extends BaseAPI {
|
|
|
69
69
|
* rather than a guarantee, since a deposit the backend cannot route to
|
|
70
70
|
* collateral is credited to the spot wallet instead.
|
|
71
71
|
*
|
|
72
|
+
* The deposit address is identical on every supported chain and one
|
|
73
|
+
* registration is watched on all of them (see {@link getChains} for the
|
|
74
|
+
* set), so there is nothing chain-specific to pass.
|
|
75
|
+
*
|
|
72
76
|
* @param body - Optionally the destination ledger; everything else comes
|
|
73
77
|
* from the session
|
|
74
78
|
* @returns Promise resolving to the deposit address and the initial-check
|
|
@@ -82,4 +86,19 @@ export class SweeperAPIImpl extends BaseAPI {
|
|
|
82
86
|
body: JSON.stringify(wireBody),
|
|
83
87
|
});
|
|
84
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* The chains and assets the sweeper watches: where a registered deposit
|
|
91
|
+
* address accepts deposits, which tokens are swept on each chain, and each
|
|
92
|
+
* token's minimum sweep amount in raw base units.
|
|
93
|
+
*
|
|
94
|
+
* Public — no session needed. The set changes only with operator
|
|
95
|
+
* configuration, so it is safe to cache briefly.
|
|
96
|
+
*
|
|
97
|
+
* @returns Promise resolving to the supported chain/asset listing
|
|
98
|
+
*/
|
|
99
|
+
async getChains() {
|
|
100
|
+
return await this.makePublicRequest(perpRoutes.sweeper.chains(), {
|
|
101
|
+
method: "GET",
|
|
102
|
+
});
|
|
103
|
+
}
|
|
85
104
|
}
|
|
@@ -257,6 +257,17 @@ export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
|
|
|
257
257
|
* Each order is canceled and re-created with new parameters.
|
|
258
258
|
* Failed replacements do not prevent other orders from being replaced.
|
|
259
259
|
*
|
|
260
|
+
* Pre-sequencing validation is scoped per item too, matching `batchCreate`:
|
|
261
|
+
* a malformed `orderId`, `price`, `quantity` or `clientOrderId`, or a
|
|
262
|
+
* `postOnly` violation, fails only that item — its result slot carries a
|
|
263
|
+
* structured `error.code` (`INVALID_ORDER_ID`, `INVALID_PRICE`,
|
|
264
|
+
* `INVALID_QUANTITY`, `INVALID_CLIENT_ORDER_ID`, `INVALID_POST_ONLY`) and its
|
|
265
|
+
* original is left untouched — while the valid items proceed. A `2xx`
|
|
266
|
+
* response can therefore mix executed replacements and failed items: read
|
|
267
|
+
* `results[]` per item rather than treating the status code as the verdict.
|
|
268
|
+
* Only an empty or oversize (>100) batch rejects the whole request.
|
|
269
|
+
* `totalRequested === totalSucceeded + totalFailed` always holds.
|
|
270
|
+
*
|
|
260
271
|
* @param orders - Array of order replacement parameters
|
|
261
272
|
* @returns Promise resolving to BatchReplaceOrdersResponse with individual results
|
|
262
273
|
* @throws {APIError} When API communication fails
|
|
@@ -281,6 +292,11 @@ export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
|
|
|
281
292
|
* Gets orders based on query parameters, cursor-paginated by default.
|
|
282
293
|
*
|
|
283
294
|
* Retrieves orders with optional filtering by status, trading pair, and pagination.
|
|
295
|
+
* Every kind of order comes back in ONE stream ordered by timestamp: book orders,
|
|
296
|
+
* TWAP parents (`orderType: "TWAP"`, detail on `twap`) and conditional orders
|
|
297
|
+
* (`orderType: "CONDITIONAL"`, detail on `conditional`). There is no separate
|
|
298
|
+
* open-orders call — filter `status` to `["SUBMITTED", "PARTIALLY_FILLED"]` for the
|
|
299
|
+
* working set.
|
|
284
300
|
* When neither `page` nor `pageToken` is passed, the SDK drives cursor (pageToken)
|
|
285
301
|
* pagination: it starts a cursor walk from the newest (or oldest, for
|
|
286
302
|
* `orderBy: "ASC"`) row and the response's `nextPageToken` resumes it. Cursor
|
|
@@ -305,6 +321,17 @@ export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
|
|
|
305
321
|
*
|
|
306
322
|
* @example
|
|
307
323
|
* ```typescript
|
|
324
|
+
* // Every working order, of every kind, in one page
|
|
325
|
+
* const open = await tradingAPI.getPaginatedOrders({ status: ["SUBMITTED", "PARTIALLY_FILLED"] });
|
|
326
|
+
* for (const order of open.orders) {
|
|
327
|
+
* if (order.orderType === "TWAP") console.log("TWAP parent", order.twap?.slicesPlaced);
|
|
328
|
+
* else if (order.orderType === "CONDITIONAL") console.log("trigger", order.conditional?.triggerPrice);
|
|
329
|
+
* else console.log("resting", order.price);
|
|
330
|
+
* }
|
|
331
|
+
* ```
|
|
332
|
+
*
|
|
333
|
+
* @example
|
|
334
|
+
* ```typescript
|
|
308
335
|
* // Walk full order history with cursor pagination (the default mode)
|
|
309
336
|
* let pageToken: string | undefined;
|
|
310
337
|
* do {
|
package/dist/api/trading/api.js
CHANGED
|
@@ -403,6 +403,17 @@ export class TradingAPIImpl extends BaseAPI {
|
|
|
403
403
|
* Each order is canceled and re-created with new parameters.
|
|
404
404
|
* Failed replacements do not prevent other orders from being replaced.
|
|
405
405
|
*
|
|
406
|
+
* Pre-sequencing validation is scoped per item too, matching `batchCreate`:
|
|
407
|
+
* a malformed `orderId`, `price`, `quantity` or `clientOrderId`, or a
|
|
408
|
+
* `postOnly` violation, fails only that item — its result slot carries a
|
|
409
|
+
* structured `error.code` (`INVALID_ORDER_ID`, `INVALID_PRICE`,
|
|
410
|
+
* `INVALID_QUANTITY`, `INVALID_CLIENT_ORDER_ID`, `INVALID_POST_ONLY`) and its
|
|
411
|
+
* original is left untouched — while the valid items proceed. A `2xx`
|
|
412
|
+
* response can therefore mix executed replacements and failed items: read
|
|
413
|
+
* `results[]` per item rather than treating the status code as the verdict.
|
|
414
|
+
* Only an empty or oversize (>100) batch rejects the whole request.
|
|
415
|
+
* `totalRequested === totalSucceeded + totalFailed` always holds.
|
|
416
|
+
*
|
|
406
417
|
* @param orders - Array of order replacement parameters
|
|
407
418
|
* @returns Promise resolving to BatchReplaceOrdersResponse with individual results
|
|
408
419
|
* @throws {APIError} When API communication fails
|
|
@@ -443,6 +454,11 @@ export class TradingAPIImpl extends BaseAPI {
|
|
|
443
454
|
* Gets orders based on query parameters, cursor-paginated by default.
|
|
444
455
|
*
|
|
445
456
|
* Retrieves orders with optional filtering by status, trading pair, and pagination.
|
|
457
|
+
* Every kind of order comes back in ONE stream ordered by timestamp: book orders,
|
|
458
|
+
* TWAP parents (`orderType: "TWAP"`, detail on `twap`) and conditional orders
|
|
459
|
+
* (`orderType: "CONDITIONAL"`, detail on `conditional`). There is no separate
|
|
460
|
+
* open-orders call — filter `status` to `["SUBMITTED", "PARTIALLY_FILLED"]` for the
|
|
461
|
+
* working set.
|
|
446
462
|
* When neither `page` nor `pageToken` is passed, the SDK drives cursor (pageToken)
|
|
447
463
|
* pagination: it starts a cursor walk from the newest (or oldest, for
|
|
448
464
|
* `orderBy: "ASC"`) row and the response's `nextPageToken` resumes it. Cursor
|
|
@@ -467,6 +483,17 @@ export class TradingAPIImpl extends BaseAPI {
|
|
|
467
483
|
*
|
|
468
484
|
* @example
|
|
469
485
|
* ```typescript
|
|
486
|
+
* // Every working order, of every kind, in one page
|
|
487
|
+
* const open = await tradingAPI.getPaginatedOrders({ status: ["SUBMITTED", "PARTIALLY_FILLED"] });
|
|
488
|
+
* for (const order of open.orders) {
|
|
489
|
+
* if (order.orderType === "TWAP") console.log("TWAP parent", order.twap?.slicesPlaced);
|
|
490
|
+
* else if (order.orderType === "CONDITIONAL") console.log("trigger", order.conditional?.triggerPrice);
|
|
491
|
+
* else console.log("resting", order.price);
|
|
492
|
+
* }
|
|
493
|
+
* ```
|
|
494
|
+
*
|
|
495
|
+
* @example
|
|
496
|
+
* ```typescript
|
|
470
497
|
* // Walk full order history with cursor pagination (the default mode)
|
|
471
498
|
* let pageToken: string | undefined;
|
|
472
499
|
* 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";
|
|
@@ -82,6 +82,12 @@ function readOptionalNumber(source, field) {
|
|
|
82
82
|
}
|
|
83
83
|
return value;
|
|
84
84
|
}
|
|
85
|
+
function readOptionalSequence(source, field) {
|
|
86
|
+
const value = source[field];
|
|
87
|
+
if (value === undefined || value === null)
|
|
88
|
+
return undefined;
|
|
89
|
+
return readSequence(source, field);
|
|
90
|
+
}
|
|
85
91
|
function readStringArray(source, field) {
|
|
86
92
|
const value = source[field];
|
|
87
93
|
if (!Array.isArray(value) || value.some((item) => typeof item !== "string")) {
|
|
@@ -492,6 +498,7 @@ function parseUserBalanceEventData(raw) {
|
|
|
492
498
|
lockedRaw: readString(data, "lockedRaw"),
|
|
493
499
|
total: readString(data, "total"),
|
|
494
500
|
totalRaw: readString(data, "totalRaw"),
|
|
501
|
+
version: readOptionalSequence(data, "version"),
|
|
495
502
|
// Free-form on the wire and read leniently: a snapshot row carries the
|
|
496
503
|
// `snapshot` literal, a live frame the mutation cause, and a reason added
|
|
497
504
|
// server-side after this SDK shipped must not drop the row (0XM-2627).
|
|
@@ -500,6 +507,20 @@ function parseUserBalanceEventData(raw) {
|
|
|
500
507
|
updatedAt: readString(data, "updatedAt"),
|
|
501
508
|
};
|
|
502
509
|
}
|
|
510
|
+
/**
|
|
511
|
+
* Parse one row from a `balances` channel snapshot.
|
|
512
|
+
*
|
|
513
|
+
* `version` is read leniently, for the same reason `reason` is: a pre-feature
|
|
514
|
+
* server sends no version at all, and rejecting the row would drop the entire
|
|
515
|
+
* subscribe-time baseline for a client whose SDK is ahead of the server it is
|
|
516
|
+
* talking to. `UserBalanceEventData.version` is optional precisely so an absent
|
|
517
|
+
* value is representable, and consumers already treat it as the unranked
|
|
518
|
+
* sentinel. A version that IS present is still validated — `readSequence`
|
|
519
|
+
* rejects negative and unsafe values.
|
|
520
|
+
*/
|
|
521
|
+
function parseBalanceSnapshotItem(raw) {
|
|
522
|
+
return parseUserBalanceEventData(raw);
|
|
523
|
+
}
|
|
503
524
|
/**
|
|
504
525
|
* Parse one resting order from an `orders` channel snapshot.
|
|
505
526
|
*
|
|
@@ -847,9 +868,14 @@ export function createMonacoWebSocket(baseUrl, options = {}) {
|
|
|
847
868
|
sendAuthenticate();
|
|
848
869
|
resubscribeAll();
|
|
849
870
|
options.onStatusChange?.("connected");
|
|
850
|
-
//
|
|
851
|
-
//
|
|
852
|
-
// snapshots
|
|
871
|
+
// Resync-join order: the live stream resumes first (auth +
|
|
872
|
+
// subscribe above), then the application is asked to refetch
|
|
873
|
+
// snapshots and reconcile against each channel's authoritative
|
|
874
|
+
// identity/version. Balance ordering uses the durable row version,
|
|
875
|
+
// never `updatedAt`, arrival time, or receiver backlog.
|
|
876
|
+
//
|
|
877
|
+
// This callback waits for neither acknowledgements nor snapshots,
|
|
878
|
+
// and the SDK performs no REST recovery itself.
|
|
853
879
|
if (pendingResyncCode !== null) {
|
|
854
880
|
const code = pendingResyncCode;
|
|
855
881
|
pendingResyncCode = null;
|
|
@@ -1201,7 +1227,7 @@ export function createMonacoWebSocket(baseUrl, options = {}) {
|
|
|
1201
1227
|
catch (err) {
|
|
1202
1228
|
console.error("WebSocket: Error processing balance event", err);
|
|
1203
1229
|
}
|
|
1204
|
-
}, onSnapshot && snapshotFrameHandler("balances",
|
|
1230
|
+
}, onSnapshot && snapshotFrameHandler("balances", parseBalanceSnapshotItem, onSnapshot));
|
|
1205
1231
|
};
|
|
1206
1232
|
const subscribeConditionalOrders = (handler, tradingPairId, onSnapshot) => {
|
|
1207
1233
|
if (!handler) {
|
package/dist/coverage.d.ts
CHANGED
package/dist/coverage.js
CHANGED
|
@@ -35,6 +35,7 @@ export const COVERED = {
|
|
|
35
35
|
get_market_stats: "getMarketStats",
|
|
36
36
|
get_my_fee_tier: "getMyFeeTier",
|
|
37
37
|
get_pulse: "pulse.getPulse",
|
|
38
|
+
get_sweeper_chains: "sweeper.getChains",
|
|
38
39
|
get_my_trader_code: "pitpass.getMyTraderCode",
|
|
39
40
|
get_rewards_balance: "pitpass.getRewardsBalance",
|
|
40
41
|
get_trader_code_info: "pitpass.getTraderCodeInfo",
|
|
@@ -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
|
}
|
package/dist/crypto/session.js
CHANGED
|
@@ -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.
|
|
3
|
+
"version": "1.0.57",
|
|
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.
|
|
23
|
-
"@0xmonaco/types": "1.0.
|
|
22
|
+
"@0xmonaco/contracts": "1.0.57",
|
|
23
|
+
"@0xmonaco/types": "1.0.57",
|
|
24
24
|
"@noble/curves": "^1.9.1",
|
|
25
|
-
"@noble/hashes": "^
|
|
25
|
+
"@noble/hashes": "^2.4.0",
|
|
26
26
|
"http-status-codes": "^2.3.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|