@0xmonaco/core 1.0.77 → 1.0.80

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.
@@ -77,10 +77,12 @@ export declare class PitpassAPIImpl extends BaseAPI implements PitpassAPI {
77
77
  */
78
78
  transferRewards(params: TransferRewardsParams): Promise<TransferRewardsResponse>;
79
79
  /**
80
- * Read the caller's own referral position: their upline (L1, L2, ...), their
81
- * L1 referrer, total earned, and recent rewards. Self-scoped — no id is sent,
82
- * so it can only ever return your own chain. `referrer` is "" and `upline` is
83
- * empty when you were not referred.
80
+ * Read the caller's own referral position: their upline (L1, L2, ..., as
81
+ * many levels as their trades on this client application pay), their L1
82
+ * referrer, total earned, and recent rewards. Self-scoped — no id is sent,
83
+ * so it can only ever return your own chain. `referrer` is "" when you were
84
+ * not referred; `upline` is also empty when this client application pays no
85
+ * referral levels.
84
86
  */
85
87
  getMyReferralPosition(): Promise<GetMyReferralPositionResponse>;
86
88
  /**
@@ -96,7 +98,8 @@ export declare class PitpassAPIImpl extends BaseAPI implements PitpassAPI {
96
98
  * Read one level of the caller's own referral tree: the wallets `parent`
97
99
  * directly referred (the caller when omitted), a page at a time, newest
98
100
  * first. `parent` must be the caller or one of their own referees above the
99
- * deepest rewarded level; any other wallet is a 404.
101
+ * deepest level any client application rewards (at most 10); any other
102
+ * wallet is a 404. The caller's direct referees (L1) are always listed.
100
103
  */
101
104
  getMyReferralTree(params?: GetMyReferralTreeParams): Promise<GetMyReferralTreeResponse>;
102
105
  }
@@ -109,10 +109,12 @@ export class PitpassAPIImpl extends BaseAPI {
109
109
  });
110
110
  }
111
111
  /**
112
- * Read the caller's own referral position: their upline (L1, L2, ...), their
113
- * L1 referrer, total earned, and recent rewards. Self-scoped — no id is sent,
114
- * so it can only ever return your own chain. `referrer` is "" and `upline` is
115
- * empty when you were not referred.
112
+ * Read the caller's own referral position: their upline (L1, L2, ..., as
113
+ * many levels as their trades on this client application pay), their L1
114
+ * referrer, total earned, and recent rewards. Self-scoped — no id is sent,
115
+ * so it can only ever return your own chain. `referrer` is "" when you were
116
+ * not referred; `upline` is also empty when this client application pays no
117
+ * referral levels.
116
118
  */
117
119
  async getMyReferralPosition() {
118
120
  return await this.makeAuthenticatedRequest("/api/v1/pitpass/referrals/me", {
@@ -146,7 +148,8 @@ export class PitpassAPIImpl extends BaseAPI {
146
148
  * Read one level of the caller's own referral tree: the wallets `parent`
147
149
  * directly referred (the caller when omitted), a page at a time, newest
148
150
  * first. `parent` must be the caller or one of their own referees above the
149
- * deepest rewarded level; any other wallet is a 404.
151
+ * deepest level any client application rewards (at most 10); any other
152
+ * wallet is a 404. The caller's direct referees (L1) are always listed.
150
153
  */
151
154
  async getMyReferralTree(params) {
152
155
  if (params) {
@@ -11,10 +11,11 @@ export declare class PositionsAPIImpl extends BaseAPI implements PositionsAPI {
11
11
  * paging loop off it — follow `nextPageToken`.
12
12
  *
13
13
  * Order depends on the filter: `status: "OPEN"` is served from the engine's
14
- * live view in `(marginAccountId, tradingPairId, positionId)` order, every
15
- * other filter from persisted rows newest-opened first. The two are
16
- * separate cursor spaces, so a token is only valid in the one that minted
17
- * it.
14
+ * live view in `(marginAccountId, tradingPairId, positionId)` order;
15
+ * `status: "CLOSED"` and `status: "LIQUIDATED"` from persisted rows
16
+ * newest-closed first; every other filter from persisted rows
17
+ * newest-opened first. Each is a separate cursor space, so a token is only
18
+ * valid in the one that minted it.
18
19
  */
19
20
  listPositions(params?: ListPositionsParams): Promise<ListPositionsResponse>;
20
21
  getPosition(positionId: string): Promise<GetPositionResponse>;
@@ -12,10 +12,11 @@ export class PositionsAPIImpl extends BaseAPI {
12
12
  * paging loop off it — follow `nextPageToken`.
13
13
  *
14
14
  * Order depends on the filter: `status: "OPEN"` is served from the engine's
15
- * live view in `(marginAccountId, tradingPairId, positionId)` order, every
16
- * other filter from persisted rows newest-opened first. The two are
17
- * separate cursor spaces, so a token is only valid in the one that minted
18
- * it.
15
+ * live view in `(marginAccountId, tradingPairId, positionId)` order;
16
+ * `status: "CLOSED"` and `status: "LIQUIDATED"` from persisted rows
17
+ * newest-closed first; every other filter from persisted rows
18
+ * newest-opened first. Each is a separate cursor space, so a token is only
19
+ * valid in the one that minted it.
19
20
  */
20
21
  async listPositions(params) {
21
22
  if (params) {
@@ -468,6 +468,60 @@ function parseMarketStatsAllEvent(rawData) {
468
468
  markets: rawData.markets.map(parseMarketStatsSummary),
469
469
  };
470
470
  }
471
+ function parseRiskTier(raw) {
472
+ if (!isRecord(raw)) {
473
+ throw new Error("Invalid instrument event: each riskTiers entry must be an object");
474
+ }
475
+ const tierLevel = raw.tierLevel;
476
+ if (typeof tierLevel !== "number" || !Number.isSafeInteger(tierLevel) || tierLevel < 1) {
477
+ throw new Error("Invalid WebSocket event: tierLevel must be a positive integer");
478
+ }
479
+ return {
480
+ tierLevel,
481
+ lowerBoundNotional: readString(raw, "lowerBoundNotional"),
482
+ maxLeverage: readOptionalString(raw, "maxLeverage"),
483
+ initialMarginRatio: readString(raw, "initialMarginRatio"),
484
+ maintenanceMarginRatio: readString(raw, "maintenanceMarginRatio"),
485
+ initialMarginDeduction: readString(raw, "initialMarginDeduction"),
486
+ maintenanceMarginDeduction: readString(raw, "maintenanceMarginDeduction"),
487
+ maxPositionNotional: readOptionalString(raw, "maxPositionNotional"),
488
+ };
489
+ }
490
+ /**
491
+ * Read the perp-only margin ladder. Absent (a spot market, or a server that
492
+ * predates the key) is `undefined`, never a made-up empty ladder; a present
493
+ * value that is not an array of well-formed tiers throws like any other
494
+ * malformed field.
495
+ */
496
+ function readOptionalRiskTiers(source, field) {
497
+ const value = source[field];
498
+ if (value === undefined || value === null)
499
+ return undefined;
500
+ if (!Array.isArray(value)) {
501
+ throw new Error(`Invalid WebSocket event: ${field} must be an array`);
502
+ }
503
+ return value.map(parseRiskTier);
504
+ }
505
+ /**
506
+ * Parse one `trades` snapshot row: the live trade frame's `data` body.
507
+ *
508
+ * Strict, unlike the live trade handler's casts: a snapshot is delivered
509
+ * all-or-nothing, so a row with a missing or non-string field must throw for
510
+ * {@link snapshotFrameHandler} to withhold the frame. The output is the same
511
+ * `TradeEventData` the live handler builds, `makerSide` uppercased likewise.
512
+ */
513
+ function parseTradeEventData(raw) {
514
+ if (!isRecord(raw)) {
515
+ throw new Error("Invalid trade snapshot row: must be an object");
516
+ }
517
+ return {
518
+ tradeId: readString(raw, "trade_id"),
519
+ price: readString(raw, "price"),
520
+ quantity: readString(raw, "quantity"),
521
+ makerSide: readString(raw, "maker_side").toUpperCase(),
522
+ executedAt: readString(raw, "executed_at"),
523
+ };
524
+ }
471
525
  function parseInstrumentEventData(raw) {
472
526
  if (!isRecord(raw)) {
473
527
  throw new Error("Invalid instrument event: data must be an object");
@@ -514,6 +568,7 @@ function parseInstrumentEventData(raw) {
514
568
  maxLeverage: readOptionalString(data, "maxLeverage"),
515
569
  initialMarginRate: readOptionalString(data, "initialMarginRate"),
516
570
  maintenanceMarginRate: readOptionalString(data, "maintenanceMarginRate"),
571
+ riskTiers: readOptionalRiskTiers(data, "riskTiers"),
517
572
  // Values are snake_case wire field NAMES (e.g. "tick_size"); only object
518
573
  // keys are camelCased, so they pass through untouched.
519
574
  changedFields: readStringArray(data, "changedFields"),
@@ -1461,7 +1516,7 @@ export function createMonacoWebSocket(baseUrl, options = {}, serverClock = new S
1461
1516
  }
1462
1517
  });
1463
1518
  };
1464
- const subscribeTrades = (tradingPairId, handler) => {
1519
+ const subscribeTrades = (tradingPairId, handler, onSnapshot) => {
1465
1520
  const channel = `trades:${tradingPairId}`;
1466
1521
  return subscribe(channel, (rawData) => {
1467
1522
  try {
@@ -1484,7 +1539,7 @@ export function createMonacoWebSocket(baseUrl, options = {}, serverClock = new S
1484
1539
  catch (err) {
1485
1540
  console.error("WebSocket: Error processing trade event", err);
1486
1541
  }
1487
- });
1542
+ }, onSnapshot && snapshotFrameHandler("trades", parseTradeEventData, onSnapshot));
1488
1543
  };
1489
1544
  const subscribeMovements = (handler) => {
1490
1545
  // User is identified from the authenticated session, so channel is just "movements"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xmonaco/core",
3
- "version": "1.0.77",
3
+ "version": "1.0.80",
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.77",
23
- "@0xmonaco/types": "1.0.77",
22
+ "@0xmonaco/contracts": "1.0.80",
23
+ "@0xmonaco/types": "1.0.80",
24
24
  "@noble/curves": "^1.9.1",
25
25
  "@noble/hashes": "^2.4.0",
26
26
  "http-status-codes": "^2.3.0"