@0xmonaco/core 1.0.83 → 1.0.85
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/auth/api.d.ts +7 -3
- package/dist/api/auth/api.js +17 -3
- package/dist/api/websocket/websocket.js +36 -4
- package/dist/coverage.d.ts +2 -0
- package/dist/coverage.js +2 -0
- package/dist/errors/errors.d.ts +6 -0
- package/dist/errors/errors.js +13 -0
- package/dist/sdk.d.ts +2 -0
- package/dist/sdk.js +2 -1
- package/package.json +3 -3
package/dist/api/auth/api.d.ts
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* );
|
|
26
26
|
* ```
|
|
27
27
|
*/
|
|
28
|
-
import type { AuthAPI, AuthState, ChallengeResponse, SessionCredentials, SessionRefreshResponse } from "@0xmonaco/types";
|
|
28
|
+
import type { AuthAPI, AuthState, ChallengeResponse, InviteCodeList, InviteCodeRequestSummary, SessionCredentials, SessionRefreshResponse } from "@0xmonaco/types";
|
|
29
29
|
import type { Chain, WalletClient } from "viem";
|
|
30
30
|
import { BaseAPI } from "../base";
|
|
31
31
|
export declare class AuthAPIImpl extends BaseAPI implements AuthAPI {
|
|
@@ -69,7 +69,7 @@ export declare class AuthAPIImpl extends BaseAPI implements AuthAPI {
|
|
|
69
69
|
* console.log(`User ID: ${authResult.user.id}`);
|
|
70
70
|
* ```
|
|
71
71
|
*/
|
|
72
|
-
authenticate(clientId: string, referralCode?: string): Promise<AuthState>;
|
|
72
|
+
authenticate(clientId: string, referralCode?: string, inviteCode?: string): Promise<AuthState>;
|
|
73
73
|
/**
|
|
74
74
|
* Signs a challenge message using the wallet client.
|
|
75
75
|
*
|
|
@@ -149,7 +149,11 @@ export declare class AuthAPIImpl extends BaseAPI implements AuthAPI {
|
|
|
149
149
|
* console.log(`Session public key: ${authResult.sessionPublicKey}`);
|
|
150
150
|
* ```
|
|
151
151
|
*/
|
|
152
|
-
verifySignature(address: string, signature: string, nonce: string, clientId: string, session: SessionCredentials, referralCode?: string): Promise<AuthState>;
|
|
152
|
+
verifySignature(address: string, signature: string, nonce: string, clientId: string, session: SessionCredentials, referralCode?: string, inviteCode?: string): Promise<AuthState>;
|
|
153
|
+
/** Mint one code: one initial allowance plus one per 250,000 USDC of Mainnet volume. */
|
|
154
|
+
requestInviteCodes(): Promise<InviteCodeRequestSummary>;
|
|
155
|
+
/** Read the allowance and minted codes. Read-only: never consumes a slot. */
|
|
156
|
+
listInviteCodes(): Promise<InviteCodeList>;
|
|
153
157
|
/**
|
|
154
158
|
* Refreshes the current session's expiry.
|
|
155
159
|
*
|
package/dist/api/auth/api.js
CHANGED
|
@@ -75,7 +75,7 @@ export class AuthAPIImpl extends BaseAPI {
|
|
|
75
75
|
* console.log(`User ID: ${authResult.user.id}`);
|
|
76
76
|
* ```
|
|
77
77
|
*/
|
|
78
|
-
async authenticate(clientId, referralCode) {
|
|
78
|
+
async authenticate(clientId, referralCode, inviteCode) {
|
|
79
79
|
if (!this.walletClient) {
|
|
80
80
|
throw new InvalidConfigError("Wallet client not set. Connect a wallet first.", "walletClient");
|
|
81
81
|
}
|
|
@@ -95,7 +95,7 @@ export class AuthAPIImpl extends BaseAPI {
|
|
|
95
95
|
// 3. Sign the challenge message with the wallet
|
|
96
96
|
const signature = await this.signChallenge(challenge.message);
|
|
97
97
|
// 4. Verify signature, registering the session public key (and optional referral)
|
|
98
|
-
return await this.verifySignature(account.address, signature, challenge.nonce, clientId, session, referralCode);
|
|
98
|
+
return await this.verifySignature(account.address, signature, challenge.nonce, clientId, session, referralCode, inviteCode);
|
|
99
99
|
}
|
|
100
100
|
/**
|
|
101
101
|
* Signs a challenge message using the wallet client.
|
|
@@ -204,7 +204,7 @@ export class AuthAPIImpl extends BaseAPI {
|
|
|
204
204
|
* console.log(`Session public key: ${authResult.sessionPublicKey}`);
|
|
205
205
|
* ```
|
|
206
206
|
*/
|
|
207
|
-
async verifySignature(address, signature, nonce, clientId, session, referralCode) {
|
|
207
|
+
async verifySignature(address, signature, nonce, clientId, session, referralCode, inviteCode) {
|
|
208
208
|
const responseBody = await this.makePublicRequest("/api/v1/auth/verify", {
|
|
209
209
|
method: "POST",
|
|
210
210
|
body: JSON.stringify({
|
|
@@ -215,6 +215,7 @@ export class AuthAPIImpl extends BaseAPI {
|
|
|
215
215
|
chainId: this.chain.id,
|
|
216
216
|
sessionPublicKey: session.publicKey,
|
|
217
217
|
...(referralCode ? { referralCode } : {}),
|
|
218
|
+
...(inviteCode ? { inviteCode } : {}),
|
|
218
219
|
}),
|
|
219
220
|
});
|
|
220
221
|
return {
|
|
@@ -234,6 +235,19 @@ export class AuthAPIImpl extends BaseAPI {
|
|
|
234
235
|
...(responseBody.referralApplied !== undefined ? { referralApplied: responseBody.referralApplied } : {}),
|
|
235
236
|
};
|
|
236
237
|
}
|
|
238
|
+
/** Mint one code: one initial allowance plus one per 250,000 USDC of Mainnet volume. */
|
|
239
|
+
async requestInviteCodes() {
|
|
240
|
+
return await this.makeAuthenticatedRequest("/api/v1/invite-codes/requests", {
|
|
241
|
+
method: "POST",
|
|
242
|
+
body: JSON.stringify({}),
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
/** Read the allowance and minted codes. Read-only: never consumes a slot. */
|
|
246
|
+
async listInviteCodes() {
|
|
247
|
+
return await this.makeAuthenticatedRequest("/api/v1/invite-codes", {
|
|
248
|
+
method: "GET",
|
|
249
|
+
});
|
|
250
|
+
}
|
|
237
251
|
/**
|
|
238
252
|
* Refreshes the current session's expiry.
|
|
239
253
|
*
|
|
@@ -40,6 +40,19 @@ function readOptionalString(source, field) {
|
|
|
40
40
|
}
|
|
41
41
|
return value;
|
|
42
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Read an optional decimal-string field: absent (or `null`) is `undefined`,
|
|
45
|
+
* and a present value must be a non-empty string. An empty string is
|
|
46
|
+
* rejected rather than surfaced, because a client converting it with
|
|
47
|
+
* `Number("")` would read it as zero.
|
|
48
|
+
*/
|
|
49
|
+
function readOptionalDecimalString(source, field) {
|
|
50
|
+
const value = readOptionalString(source, field);
|
|
51
|
+
if (value === "") {
|
|
52
|
+
throw new Error(`Invalid WebSocket event: ${field} must not be empty`);
|
|
53
|
+
}
|
|
54
|
+
return value;
|
|
55
|
+
}
|
|
43
56
|
/**
|
|
44
57
|
* Read a field the server serializes as an explicit `null` when unset.
|
|
45
58
|
*
|
|
@@ -377,6 +390,11 @@ function parseAccountEventData(raw) {
|
|
|
377
390
|
freeCollateral: readString(data, "freeCollateral"),
|
|
378
391
|
marginRatio: readString(data, "marginRatio"),
|
|
379
392
|
maintenanceRequirement: readString(data, "maintenanceRequirement"),
|
|
393
|
+
// Optional so a frame from an older server parses; a present value must
|
|
394
|
+
// still be a non-empty decimal string, or the frame is rejected.
|
|
395
|
+
initialMarginRequired: readOptionalDecimalString(data, "initialMarginRequired"),
|
|
396
|
+
withdrawableCollateral: readOptionalDecimalString(data, "withdrawableCollateral"),
|
|
397
|
+
realizedPnl: readOptionalDecimalString(data, "realizedPnl"),
|
|
380
398
|
updatedAt: readString(data, "updatedAt"),
|
|
381
399
|
};
|
|
382
400
|
}
|
|
@@ -800,8 +818,10 @@ function parseBalanceSnapshotItem(raw) {
|
|
|
800
818
|
*
|
|
801
819
|
* The optional fields are read as nullable, not optional: they are Rust
|
|
802
820
|
* `Option`s serialized without `skip_serializing_if`, so the key is always
|
|
803
|
-
* present carrying `null`.
|
|
804
|
-
*
|
|
821
|
+
* present carrying `null`. The fields the server omits outright
|
|
822
|
+
* (`clientOrderId`, `selfTradePreventionMode`, `parentOrderId`, `postOnly`,
|
|
823
|
+
* `expirationDate`, `triggerPrice`, `positionSide`, `version` and `origin`) are
|
|
824
|
+
* read as optional and spread in only when present.
|
|
805
825
|
*/
|
|
806
826
|
function parseOrderSnapshotItem(raw) {
|
|
807
827
|
if (!isRecord(raw)) {
|
|
@@ -819,6 +839,7 @@ function parseOrderSnapshotItem(raw) {
|
|
|
819
839
|
const triggerPrice = readOptionalString(item, "triggerPrice");
|
|
820
840
|
const positionSide = readOptionalString(item, "positionSide");
|
|
821
841
|
const version = readOptionalNumber(item, "version");
|
|
842
|
+
const origin = readOptionalString(item, "origin");
|
|
822
843
|
return {
|
|
823
844
|
orderId: readString(item, "orderId"),
|
|
824
845
|
userId: readString(item, "userId"),
|
|
@@ -866,6 +887,10 @@ function parseOrderSnapshotItem(raw) {
|
|
|
866
887
|
// than becoming `version: undefined` — a resync compares this value, and
|
|
867
888
|
// absent means unknown, never zero (0XM-2440).
|
|
868
889
|
...(version === undefined ? {} : { version }),
|
|
890
|
+
// Read as a plain string, like the value fields above: an unrecognized
|
|
891
|
+
// origin passes through rather than dropping the row, and absent stays
|
|
892
|
+
// absent.
|
|
893
|
+
...(origin === undefined ? {} : { origin }),
|
|
869
894
|
};
|
|
870
895
|
}
|
|
871
896
|
/**
|
|
@@ -1248,6 +1273,9 @@ export function createMonacoWebSocket(baseUrl, options = {}, serverClock = new S
|
|
|
1248
1273
|
if (msg.code === "AUTH_FAILED") {
|
|
1249
1274
|
lastAuthError = { code: msg.code, message: msg.message, session: pendingAuthSessions.shift() };
|
|
1250
1275
|
}
|
|
1276
|
+
else if (msg.code === "ACCOUNT_DEACTIVATED") {
|
|
1277
|
+
lastAuthError = { code: msg.code, message: msg.message, session: pendingAuthSessions.shift() ?? confirmedSession };
|
|
1278
|
+
}
|
|
1251
1279
|
else if (msg.code === "SESSION_INVALID") {
|
|
1252
1280
|
lastAuthError = { code: msg.code, message: msg.message, session: confirmedSession ?? pendingAuthSessions[0] };
|
|
1253
1281
|
}
|
|
@@ -1430,7 +1458,10 @@ export function createMonacoWebSocket(baseUrl, options = {}, serverClock = new S
|
|
|
1430
1458
|
const skewRetry = autoReconnect && authError?.code === "AUTH_FAILED" && SKEW_REJECTION.test(authError.message) && skewAuthRetries < MAX_SKEW_AUTH_RETRIES;
|
|
1431
1459
|
if (skewRetry)
|
|
1432
1460
|
skewAuthRetries++;
|
|
1433
|
-
const authLoss = !skewRetry &&
|
|
1461
|
+
const authLoss = !skewRetry &&
|
|
1462
|
+
authError !== null &&
|
|
1463
|
+
authError.session !== undefined &&
|
|
1464
|
+
(authError.code === "AUTH_FAILED" || authError.code === "ACCOUNT_DEACTIVATED" || event.code === 1008);
|
|
1434
1465
|
const terminalAuthLoss = authLoss && session === authError.session;
|
|
1435
1466
|
if (terminalAuthLoss) {
|
|
1436
1467
|
session = undefined;
|
|
@@ -1910,7 +1941,8 @@ export function createMonacoWebSocket(baseUrl, options = {}, serverClock = new S
|
|
|
1910
1941
|
/**
|
|
1911
1942
|
* Subscribe to the authenticated user's account-level margin health updates
|
|
1912
1943
|
* (equity, collateral, free collateral, margin ratio, maintenance
|
|
1913
|
-
* requirement
|
|
1944
|
+
* requirement, initial margin required, withdrawable collateral, realized
|
|
1945
|
+
* PnL). Requires authentication - the user is identified from the
|
|
1914
1946
|
* signed session-key handshake. Detected broadcast lag closes the connection
|
|
1915
1947
|
* with 1013; reconnect and reconcile missed state. Each frame is a terminal-state snapshot
|
|
1916
1948
|
* per margin account, not an additive delta.
|
package/dist/coverage.d.ts
CHANGED
|
@@ -34,6 +34,8 @@ export declare const COVERED: {
|
|
|
34
34
|
list_twap_order_slices: string;
|
|
35
35
|
close_position: string;
|
|
36
36
|
create_challenge: string;
|
|
37
|
+
request_invite_codes: string;
|
|
38
|
+
list_invite_codes: string;
|
|
37
39
|
create_delegated_session: string;
|
|
38
40
|
create_order: string;
|
|
39
41
|
create_sub_account_limit: string;
|
package/dist/coverage.js
CHANGED
|
@@ -34,6 +34,8 @@ export const COVERED = {
|
|
|
34
34
|
list_twap_order_slices: "listTwapOrderSlices",
|
|
35
35
|
close_position: "closePosition",
|
|
36
36
|
create_challenge: "createChallenge",
|
|
37
|
+
request_invite_codes: "auth.requestInviteCodes",
|
|
38
|
+
list_invite_codes: "auth.listInviteCodes",
|
|
37
39
|
create_delegated_session: "createDelegatedSession",
|
|
38
40
|
create_order: "placeLimitOrder / placeMarketOrder",
|
|
39
41
|
create_sub_account_limit: "subAccounts.createLimit",
|
package/dist/errors/errors.d.ts
CHANGED
|
@@ -303,6 +303,12 @@ export declare class APIError extends MonacoCoreError {
|
|
|
303
303
|
requestId?: string;
|
|
304
304
|
retryAfter?: number;
|
|
305
305
|
});
|
|
306
|
+
/**
|
|
307
|
+
* The server's stable error code from the response envelope's `code` field
|
|
308
|
+
* (e.g. `INVITE_CODE_REQUIRED`, `POST_ONLY_WOULD_CROSS`), when it sent one.
|
|
309
|
+
* Branch on this rather than on the message text.
|
|
310
|
+
*/
|
|
311
|
+
get serverCode(): string | undefined;
|
|
306
312
|
/**
|
|
307
313
|
* Override toJSON to include API-specific fields with sanitization
|
|
308
314
|
*
|
package/dist/errors/errors.js
CHANGED
|
@@ -563,6 +563,19 @@ export class APIError extends MonacoCoreError {
|
|
|
563
563
|
this.requestId = options?.requestId;
|
|
564
564
|
this.retryAfter = options?.retryAfter;
|
|
565
565
|
}
|
|
566
|
+
/**
|
|
567
|
+
* The server's stable error code from the response envelope's `code` field
|
|
568
|
+
* (e.g. `INVITE_CODE_REQUIRED`, `POST_ONLY_WOULD_CROSS`), when it sent one.
|
|
569
|
+
* Branch on this rather than on the message text.
|
|
570
|
+
*/
|
|
571
|
+
get serverCode() {
|
|
572
|
+
const body = this.responseBody;
|
|
573
|
+
if (body && typeof body === "object" && "code" in body) {
|
|
574
|
+
const code = body.code;
|
|
575
|
+
return typeof code === "string" ? code : undefined;
|
|
576
|
+
}
|
|
577
|
+
return undefined;
|
|
578
|
+
}
|
|
566
579
|
/**
|
|
567
580
|
* Override toJSON to include API-specific fields with sanitization
|
|
568
581
|
*
|
package/dist/sdk.d.ts
CHANGED
|
@@ -62,6 +62,7 @@ export declare class MonacoSDKImpl implements MonacoSDK {
|
|
|
62
62
|
* @param clientId - The client ID for authentication
|
|
63
63
|
* @param options - Optional configuration
|
|
64
64
|
* @param options.connectWebSocket - Auto-connect WebSocket after login (default: false)
|
|
65
|
+
* @param options.inviteCode - Optional case-sensitive Mainnet invite code
|
|
65
66
|
*
|
|
66
67
|
* @example
|
|
67
68
|
* ```typescript
|
|
@@ -79,6 +80,7 @@ export declare class MonacoSDKImpl implements MonacoSDK {
|
|
|
79
80
|
*/
|
|
80
81
|
login(clientId: string, options?: {
|
|
81
82
|
connectWebSocket?: boolean;
|
|
83
|
+
inviteCode?: string;
|
|
82
84
|
}): Promise<AuthState>;
|
|
83
85
|
/**
|
|
84
86
|
* Create and adopt an owner-scoped delegated session.
|
package/dist/sdk.js
CHANGED
|
@@ -213,6 +213,7 @@ export class MonacoSDKImpl {
|
|
|
213
213
|
* @param clientId - The client ID for authentication
|
|
214
214
|
* @param options - Optional configuration
|
|
215
215
|
* @param options.connectWebSocket - Auto-connect WebSocket after login (default: false)
|
|
216
|
+
* @param options.inviteCode - Optional case-sensitive Mainnet invite code
|
|
216
217
|
*
|
|
217
218
|
* @example
|
|
218
219
|
* ```typescript
|
|
@@ -229,7 +230,7 @@ export class MonacoSDKImpl {
|
|
|
229
230
|
* ```
|
|
230
231
|
*/
|
|
231
232
|
async login(clientId, options) {
|
|
232
|
-
this.authState = await this.auth.authenticate(clientId);
|
|
233
|
+
this.authState = await this.auth.authenticate(clientId, undefined, options?.inviteCode);
|
|
233
234
|
this.propagateSession(this.sessionFromAuthState(this.authState));
|
|
234
235
|
// Auto-connect WebSocket if requested
|
|
235
236
|
if (options?.connectWebSocket) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@0xmonaco/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.85",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"homepage": "https://docs.0xmonaco.com/sdk/typescript",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -19,8 +19,8 @@
|
|
|
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.85",
|
|
23
|
+
"@0xmonaco/types": "1.0.85",
|
|
24
24
|
"@noble/curves": "^1.9.1",
|
|
25
25
|
"@noble/hashes": "^2.4.0",
|
|
26
26
|
"http-status-codes": "^2.3.0"
|