@0xmonaco/core 1.1.5 → 1.1.7

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.
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Analytics API Implementation
3
+ *
4
+ * The public explorer analytics: protocol totals and series over a window,
5
+ * per-market volume, the treasury's all-time net fees, and the builder
6
+ * directory, figures and leaderboard; wallets, token custody and the vault
7
+ * deposit and withdrawal feeds. Volume, trade
8
+ * counts and the spot/perp split count the builders the explorer displays;
9
+ * fees, active takers, new traders and market volume count every trade.
10
+ * Public — no authentication required; each client IP has a read budget.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const week = await sdk.analytics.getProtocolTotals({ window: "7d" });
15
+ * // Both window ends are inclusive, so the previous window ends 1 ms before
16
+ * // this one starts; ending at `startTime` itself would count a bucket twice
17
+ * // whenever the start falls on a bucket boundary.
18
+ * const previous = await sdk.analytics.getProtocolTotals({ window: "7d", endTime: week.window.startTime - 1 });
19
+ * ```
20
+ */
21
+ import type { AnalyticsAPI, AnalyticsWindowParams, GetBuilderResponse, GetBuilderSeriesResponse, GetBuilderTotalsResponse, GetProtocolSeriesResponse, GetProtocolTotalsResponse, GetTokenCustodyResponse, GetTreasuryNetFeesResponse, GetWalletSummaryResponse, ListBuilderLeaderboardParams, ListBuilderLeaderboardResponse, ListBuildersResponse, ListMarketVolumesParams, ListMarketVolumesResponse, ListTokenCustodyResponse, ListVaultDepositsResponse, ListVaultWithdrawalsResponse, ListWalletLeaderboardParams, ListWalletLeaderboardResponse, ListWalletLiquidationsParams, ListWalletLiquidationsResponse, VaultFeedParams } from "@0xmonaco/types";
22
+ import { BaseAPI } from "../base";
23
+ export declare class AnalyticsAPIImpl extends BaseAPI implements AnalyticsAPI {
24
+ getProtocolTotals(params?: AnalyticsWindowParams): Promise<GetProtocolTotalsResponse>;
25
+ getProtocolSeries(params?: AnalyticsWindowParams): Promise<GetProtocolSeriesResponse>;
26
+ listMarketVolumes(params?: ListMarketVolumesParams): Promise<ListMarketVolumesResponse>;
27
+ getTreasuryNetFees(): Promise<GetTreasuryNetFeesResponse>;
28
+ listBuilders(): Promise<ListBuildersResponse>;
29
+ getBuilder(builder: string): Promise<GetBuilderResponse>;
30
+ getBuilderTotals(builder: string, params?: AnalyticsWindowParams): Promise<GetBuilderTotalsResponse>;
31
+ getBuilderSeries(builder: string, params?: AnalyticsWindowParams): Promise<GetBuilderSeriesResponse>;
32
+ listBuilderLeaderboard(params?: ListBuilderLeaderboardParams): Promise<ListBuilderLeaderboardResponse>;
33
+ listWalletLeaderboard(params?: ListWalletLeaderboardParams): Promise<ListWalletLeaderboardResponse>;
34
+ getWalletSummary(wallet: string): Promise<GetWalletSummaryResponse>;
35
+ listWalletLiquidations(wallet: string, params?: ListWalletLiquidationsParams): Promise<ListWalletLiquidationsResponse>;
36
+ listTokenCustody(): Promise<ListTokenCustodyResponse>;
37
+ getTokenCustody(token: string): Promise<GetTokenCustodyResponse>;
38
+ listVaultDeposits(params?: VaultFeedParams): Promise<ListVaultDepositsResponse>;
39
+ listVaultWithdrawals(params?: VaultFeedParams): Promise<ListVaultWithdrawalsResponse>;
40
+ }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Analytics API Implementation
3
+ *
4
+ * The public explorer analytics: protocol totals and series over a window,
5
+ * per-market volume, the treasury's all-time net fees, and the builder
6
+ * directory, figures and leaderboard; wallets, token custody and the vault
7
+ * deposit and withdrawal feeds. Volume, trade
8
+ * counts and the spot/perp split count the builders the explorer displays;
9
+ * fees, active takers, new traders and market volume count every trade.
10
+ * Public — no authentication required; each client IP has a read budget.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const week = await sdk.analytics.getProtocolTotals({ window: "7d" });
15
+ * // Both window ends are inclusive, so the previous window ends 1 ms before
16
+ * // this one starts; ending at `startTime` itself would count a bucket twice
17
+ * // whenever the start falls on a bucket boundary.
18
+ * const previous = await sdk.analytics.getProtocolTotals({ window: "7d", endTime: week.window.startTime - 1 });
19
+ * ```
20
+ */
21
+ import { BaseAPI } from "../base";
22
+ import { perpRoutes } from "../perp/routes";
23
+ export class AnalyticsAPIImpl extends BaseAPI {
24
+ async getProtocolTotals(params) {
25
+ return await this.makePublicRequest(perpRoutes.analytics.protocolTotals(params), { method: "GET" });
26
+ }
27
+ async getProtocolSeries(params) {
28
+ const response = await this.makePublicRequest(perpRoutes.analytics.protocolSeries(params), { method: "GET" });
29
+ return { ...response, points: response.points ?? [] };
30
+ }
31
+ async listMarketVolumes(params) {
32
+ const response = await this.makePublicRequest(perpRoutes.analytics.marketVolumes(params), { method: "GET" });
33
+ return { ...response, markets: response.markets ?? [] };
34
+ }
35
+ async getTreasuryNetFees() {
36
+ return await this.makePublicRequest(perpRoutes.analytics.treasuryNetFees(), { method: "GET" });
37
+ }
38
+ async listBuilders() {
39
+ const response = await this.makePublicRequest(perpRoutes.analytics.builders(), { method: "GET" });
40
+ return { builders: (response.builders ?? []).map(withApplications) };
41
+ }
42
+ async getBuilder(builder) {
43
+ const response = await this.makePublicRequest(perpRoutes.analytics.builder(builder), { method: "GET" });
44
+ return { builder: withApplications(response.builder) };
45
+ }
46
+ async getBuilderTotals(builder, params) {
47
+ const response = await this.makePublicRequest(perpRoutes.analytics.builderTotals(builder, params), {
48
+ method: "GET",
49
+ });
50
+ return { ...response, builder: withApplications(response.builder) };
51
+ }
52
+ async getBuilderSeries(builder, params) {
53
+ const response = await this.makePublicRequest(perpRoutes.analytics.builderSeries(builder, params), { method: "GET" });
54
+ return { ...response, builder: withApplications(response.builder), points: response.points ?? [] };
55
+ }
56
+ async listBuilderLeaderboard(params) {
57
+ const response = await this.makePublicRequest(perpRoutes.analytics.builderLeaderboard(params), { method: "GET" });
58
+ return { ...response, rows: (response.rows ?? []).map((row) => ({ ...row, builder: withApplications(row.builder) })) };
59
+ }
60
+ async listWalletLeaderboard(params) {
61
+ const response = await this.makePublicRequest(perpRoutes.analytics.walletLeaderboard(params), {
62
+ method: "GET",
63
+ });
64
+ return { wallets: response.wallets ?? [] };
65
+ }
66
+ async getWalletSummary(wallet) {
67
+ const response = await this.makePublicRequest(perpRoutes.analytics.walletSummary(wallet), { method: "GET" });
68
+ // Absent optionals and an empty repeated field are omitted on the wire.
69
+ return {
70
+ ...response,
71
+ totals: response.totals ?? null,
72
+ builders: (response.builders ?? []).map((row) => ({ ...row, builder: withApplications(row.builder) })),
73
+ unattributed: response.unattributed ?? null,
74
+ };
75
+ }
76
+ async listWalletLiquidations(wallet, params) {
77
+ const response = await this.makePublicRequest(perpRoutes.analytics.walletLiquidations(wallet, params), { method: "GET" });
78
+ return { ...response, events: response.events ?? [], nextPageToken: response.nextPageToken ?? "" };
79
+ }
80
+ async listTokenCustody() {
81
+ const response = await this.makePublicRequest(perpRoutes.analytics.tokenCustody(), { method: "GET" });
82
+ return { ...response, tokens: response.tokens ?? [] };
83
+ }
84
+ async getTokenCustody(token) {
85
+ return await this.makePublicRequest(perpRoutes.analytics.tokenCustodyDetail(token), { method: "GET" });
86
+ }
87
+ async listVaultDeposits(params) {
88
+ const response = await this.makePublicRequest(perpRoutes.analytics.vaultDeposits(params), { method: "GET" });
89
+ return {
90
+ ...response,
91
+ deposits: (response.deposits ?? []).map((row) => ({ ...row, builder: row.builder ? withApplications(row.builder) : null })),
92
+ nextPageToken: response.nextPageToken ?? "",
93
+ };
94
+ }
95
+ async listVaultWithdrawals(params) {
96
+ const response = await this.makePublicRequest(perpRoutes.analytics.vaultWithdrawals(params), { method: "GET" });
97
+ return {
98
+ ...response,
99
+ withdrawals: (response.withdrawals ?? []).map((row) => ({ ...row, builder: row.builder ? withApplications(row.builder) : null })),
100
+ nextPageToken: response.nextPageToken ?? "",
101
+ };
102
+ }
103
+ }
104
+ /** A builder with its application list present, empty when the wire omitted it. */
105
+ function withApplications(builder) {
106
+ return { ...builder, applications: builder.applications ?? [] };
107
+ }
@@ -0,0 +1 @@
1
+ export { AnalyticsAPIImpl } from "./api";
@@ -0,0 +1 @@
1
+ export { AnalyticsAPIImpl } from "./api";
@@ -56,7 +56,7 @@ export declare class ApplicationsAPIImpl extends BaseAPI implements Applications
56
56
  *
57
57
  * @param params - Pagination and filter options
58
58
  * @returns Promise resolving to a paginated list of orders
59
- * @throws {APIError} When the request fails (404 for an unknown client ID, 429 when rate limited)
59
+ * @throws {APIError} When the request fails (404 for an unknown, inactive or hidden client ID, 429 when rate limited)
60
60
  */
61
61
  listApplicationOrders(params: ListAppOrdersParams): Promise<ListAppOrdersResponse>;
62
62
  /**
@@ -74,7 +74,7 @@ export declare class ApplicationsAPIImpl extends BaseAPI implements Applications
74
74
  *
75
75
  * @param params - Pagination and filter options
76
76
  * @returns Promise resolving to a paginated list of users
77
- * @throws {APIError} When the request fails (404 for an unknown client ID, 429 when rate limited)
77
+ * @throws {APIError} When the request fails (404 for an unknown, inactive or hidden client ID, 429 when rate limited)
78
78
  */
79
79
  listApplicationUsers(params: ListAppUsersParams): Promise<ListAppUsersResponse>;
80
80
  /**
@@ -92,7 +92,7 @@ export declare class ApplicationsAPIImpl extends BaseAPI implements Applications
92
92
  *
93
93
  * @param params - Pagination and filter options
94
94
  * @returns Promise resolving to a paginated list of movements
95
- * @throws {APIError} When the request fails (404 for an unknown client ID, 429 when rate limited)
95
+ * @throws {APIError} When the request fails (404 for an unknown, inactive or hidden client ID, 429 when rate limited)
96
96
  */
97
97
  listApplicationMovements(params: ListAppMovementsParams): Promise<ListAppMovementsResponse>;
98
98
  /**
@@ -110,7 +110,7 @@ export declare class ApplicationsAPIImpl extends BaseAPI implements Applications
110
110
  *
111
111
  * @param params - Pagination and filter options
112
112
  * @returns Promise resolving to a paginated list of balances
113
- * @throws {APIError} When the request fails (404 for an unknown client ID, 429 when rate limited)
113
+ * @throws {APIError} When the request fails (404 for an unknown, inactive or hidden client ID, 429 when rate limited)
114
114
  */
115
115
  listApplicationBalances(params: ListAppBalancesParams): Promise<ListAppBalancesResponse>;
116
116
  /**
@@ -121,7 +121,7 @@ export declare class ApplicationsAPIImpl extends BaseAPI implements Applications
121
121
  *
122
122
  * @param params - Optional `since` filter
123
123
  * @returns Promise resolving to the application stats
124
- * @throws {APIError} When the request fails (404 for an unknown client ID, 429 when rate limited)
124
+ * @throws {APIError} When the request fails (404 for an unknown, inactive or hidden client ID, 429 when rate limited)
125
125
  */
126
126
  getApplicationStats(params: GetAppStatsParams): Promise<GetAppStatsResponse>;
127
127
  }
@@ -69,7 +69,7 @@ export class ApplicationsAPIImpl extends BaseAPI {
69
69
  *
70
70
  * @param params - Pagination and filter options
71
71
  * @returns Promise resolving to a paginated list of orders
72
- * @throws {APIError} When the request fails (404 for an unknown client ID, 429 when rate limited)
72
+ * @throws {APIError} When the request fails (404 for an unknown, inactive or hidden client ID, 429 when rate limited)
73
73
  */
74
74
  async listApplicationOrders(params) {
75
75
  validate(ListAppOrdersSchema, params);
@@ -99,7 +99,7 @@ export class ApplicationsAPIImpl extends BaseAPI {
99
99
  *
100
100
  * @param params - Pagination and filter options
101
101
  * @returns Promise resolving to a paginated list of users
102
- * @throws {APIError} When the request fails (404 for an unknown client ID, 429 when rate limited)
102
+ * @throws {APIError} When the request fails (404 for an unknown, inactive or hidden client ID, 429 when rate limited)
103
103
  */
104
104
  async listApplicationUsers(params) {
105
105
  validate(ListAppUsersSchema, params);
@@ -127,7 +127,7 @@ export class ApplicationsAPIImpl extends BaseAPI {
127
127
  *
128
128
  * @param params - Pagination and filter options
129
129
  * @returns Promise resolving to a paginated list of movements
130
- * @throws {APIError} When the request fails (404 for an unknown client ID, 429 when rate limited)
130
+ * @throws {APIError} When the request fails (404 for an unknown, inactive or hidden client ID, 429 when rate limited)
131
131
  */
132
132
  async listApplicationMovements(params) {
133
133
  validate(ListAppMovementsSchema, params);
@@ -156,7 +156,7 @@ export class ApplicationsAPIImpl extends BaseAPI {
156
156
  *
157
157
  * @param params - Pagination and filter options
158
158
  * @returns Promise resolving to a paginated list of balances
159
- * @throws {APIError} When the request fails (404 for an unknown client ID, 429 when rate limited)
159
+ * @throws {APIError} When the request fails (404 for an unknown, inactive or hidden client ID, 429 when rate limited)
160
160
  */
161
161
  async listApplicationBalances(params) {
162
162
  validate(ListAppBalancesSchema, params);
@@ -176,7 +176,7 @@ export class ApplicationsAPIImpl extends BaseAPI {
176
176
  *
177
177
  * @param params - Optional `since` filter
178
178
  * @returns Promise resolving to the application stats
179
- * @throws {APIError} When the request fails (404 for an unknown client ID, 429 when rate limited)
179
+ * @throws {APIError} When the request fails (404 for an unknown, inactive or hidden client ID, 429 when rate limited)
180
180
  */
181
181
  async getApplicationStats(params) {
182
182
  return await this.makePublicRequest(perpRoutes.applications.stats({ clientId: params.clientId, since: params.since }));
@@ -14,6 +14,7 @@
14
14
  * const result = await sdk.buildercodes.claimBuildercodeRewards({
15
15
  * token: "0x0000000000000000000000000000000000000002",
16
16
  * amount: "1000000",
17
+ * idempotencyKey: crypto.randomUUID(), // keep it across retries of this claim
17
18
  * });
18
19
  * console.log(`Payout remaining: ${result.payoutBalance}`);
19
20
  * console.log(`Now tradeable: ${result.tradingBalance}`);
@@ -78,18 +79,24 @@ export declare class BuildercodesAPIImpl extends BaseAPI implements Buildercodes
78
79
  * Throws 503 when the matching engine is unreachable, restarting, or slow to
79
80
  * answer. Treat that as an UNKNOWN outcome rather than a rejection: the claim
80
81
  * is admitted to the sequencer before its reply is sent, so it may still
81
- * commit, and there is no idempotency key — a blind retry can claim twice.
82
- * Do not retry automatically, and do not settle it with a balance read: an
83
- * admitted claim can still be queued, so an unchanged balance does not prove
84
- * it will not commit. Treat the claim as pending and reconcile first.
82
+ * commit.
85
83
  *
86
- * Because that warning has to hold for code as well as readers, an ambiguous
87
- * failure (any 5xx, or a network error with no response at all) is thrown
88
- * with `retryable: false`, against the SDK's usual "every 5xx is retryable"
89
- * rule, so a caller driving retries off that flag cannot claim twice. A
90
- * pre-admission rejection is exempt and stays retryable: a maintenance block,
91
- * and a sequencer overload (`code: "OVERLOADED"`), both of which are refused
92
- * before the claim is queued and so committed nothing.
84
+ * Pass `idempotencyKey` to make that retry safe: the same key and claim
85
+ * retried within 15 minutes returns the first claim's result without moving
86
+ * money again, so a keyed claim's 5xx keeps the SDK's usual `retryable`
87
+ * flag. The same key with a different claim throws 409
88
+ * `IDEMPOTENCY_KEY_CONFLICT`.
89
+ *
90
+ * Without a key a blind retry can claim twice. Do not retry automatically,
91
+ * and do not settle it with a balance read: an admitted claim can still be
92
+ * queued, so an unchanged balance does not prove it will not commit. Treat
93
+ * the claim as pending and reconcile first. Because that warning has to hold
94
+ * for code as well as readers, an unkeyed claim's ambiguous failure (any 5xx,
95
+ * or a network error with no response at all) is thrown with
96
+ * `retryable: false`, against the SDK's usual "every 5xx is retryable" rule.
97
+ * A pre-admission rejection is exempt and stays retryable: a maintenance
98
+ * block, and a sequencer overload (`code: "OVERLOADED"`), both of which are
99
+ * refused before the claim is queued and so committed nothing.
93
100
  */
94
101
  claimBuildercodeRewards(params: ClaimBuildercodeRewardsParams): Promise<ClaimBuildercodeRewardsResponse>;
95
102
  }
@@ -14,6 +14,7 @@
14
14
  * const result = await sdk.buildercodes.claimBuildercodeRewards({
15
15
  * token: "0x0000000000000000000000000000000000000002",
16
16
  * amount: "1000000",
17
+ * idempotencyKey: crypto.randomUUID(), // keep it across retries of this claim
17
18
  * });
18
19
  * console.log(`Payout remaining: ${result.payoutBalance}`);
19
20
  * console.log(`Now tradeable: ${result.tradingBalance}`);
@@ -36,9 +37,9 @@ const MAINTENANCE_BLOCK_ERROR = "OPERATIONS_BLOCKED";
36
37
  */
37
38
  const OVERLOADED_ENGINE_CODE = "OVERLOADED";
38
39
  /**
39
- * Clear `retryable` on a claim failure whose outcome is UNKNOWN.
40
+ * Clear `retryable` on an unkeyed claim failure whose outcome is UNKNOWN.
40
41
  *
41
- * A claim is not idempotent and is admitted to the sequencer before its reply
42
+ * An unkeyed claim is not idempotent and is admitted to the sequencer before its reply
42
43
  * is sent, so a 5xx or a dropped connection can arrive after the claim already
43
44
  * committed. `APIError` classifies every 5xx and every network failure as
44
45
  * `retryable: true`, and the documented consumer pattern retries whenever that
@@ -71,7 +72,7 @@ function markAmbiguousOutcomeNonRetryable(error) {
71
72
  }
72
73
  error.retryable = false;
73
74
  error.suggestion =
74
- "The claim's outcome is unknown: it may have committed after this failure. Do not retry automatically, and do not rely on a balance read to decide — an admitted claim can still be queued, so an unchanged balance does not prove it will not commit. Treat the claim as pending and reconcile before issuing another; this endpoint has no idempotency key, so a retry can claim a second time.";
75
+ "The claim's outcome is unknown: it may have committed after this failure. Do not retry automatically, and do not rely on a balance read to decide — an admitted claim can still be queued, so an unchanged balance does not prove it will not commit. Treat the claim as pending and reconcile before issuing another; this claim carried no idempotencyKey, so a retry can claim a second time. Send one to make retries safe.";
75
76
  return error;
76
77
  }
77
78
  /**
@@ -192,28 +193,43 @@ export class BuildercodesAPIImpl extends BaseAPI {
192
193
  * Throws 503 when the matching engine is unreachable, restarting, or slow to
193
194
  * answer. Treat that as an UNKNOWN outcome rather than a rejection: the claim
194
195
  * is admitted to the sequencer before its reply is sent, so it may still
195
- * commit, and there is no idempotency key — a blind retry can claim twice.
196
- * Do not retry automatically, and do not settle it with a balance read: an
197
- * admitted claim can still be queued, so an unchanged balance does not prove
198
- * it will not commit. Treat the claim as pending and reconcile first.
196
+ * commit.
199
197
  *
200
- * Because that warning has to hold for code as well as readers, an ambiguous
201
- * failure (any 5xx, or a network error with no response at all) is thrown
202
- * with `retryable: false`, against the SDK's usual "every 5xx is retryable"
203
- * rule, so a caller driving retries off that flag cannot claim twice. A
204
- * pre-admission rejection is exempt and stays retryable: a maintenance block,
205
- * and a sequencer overload (`code: "OVERLOADED"`), both of which are refused
206
- * before the claim is queued and so committed nothing.
198
+ * Pass `idempotencyKey` to make that retry safe: the same key and claim
199
+ * retried within 15 minutes returns the first claim's result without moving
200
+ * money again, so a keyed claim's 5xx keeps the SDK's usual `retryable`
201
+ * flag. The same key with a different claim throws 409
202
+ * `IDEMPOTENCY_KEY_CONFLICT`.
203
+ *
204
+ * Without a key a blind retry can claim twice. Do not retry automatically,
205
+ * and do not settle it with a balance read: an admitted claim can still be
206
+ * queued, so an unchanged balance does not prove it will not commit. Treat
207
+ * the claim as pending and reconcile first. Because that warning has to hold
208
+ * for code as well as readers, an unkeyed claim's ambiguous failure (any 5xx,
209
+ * or a network error with no response at all) is thrown with
210
+ * `retryable: false`, against the SDK's usual "every 5xx is retryable" rule.
211
+ * A pre-admission rejection is exempt and stays retryable: a maintenance
212
+ * block, and a sequencer overload (`code: "OVERLOADED"`), both of which are
213
+ * refused before the claim is queued and so committed nothing.
207
214
  */
208
215
  async claimBuildercodeRewards(params) {
209
216
  const validated = validate(ClaimBuildercodeRewardsParamsSchema, params);
217
+ const body = validated.idempotencyKey === undefined
218
+ ? { token: validated.token, amount: validated.amount }
219
+ : { token: validated.token, amount: validated.amount, idempotencyKey: validated.idempotencyKey };
210
220
  try {
211
221
  return await this.makeAuthenticatedRequest("/api/v1/buildercodes/rewards/claim", {
212
222
  method: "POST",
213
- body: JSON.stringify({ token: validated.token, amount: validated.amount }),
223
+ body: JSON.stringify(body),
214
224
  });
215
225
  }
216
226
  catch (error) {
227
+ // A keyed claim retried under the same key returns the first claim's
228
+ // result instead of claiming again, so its 5xx keeps the flag `APIError`
229
+ // gave it.
230
+ if (validated.idempotencyKey !== undefined) {
231
+ throw error;
232
+ }
217
233
  throw markAmbiguousOutcomeNonRetryable(error);
218
234
  }
219
235
  }
@@ -3,6 +3,7 @@
3
3
  *
4
4
  * This module exports the new simplified APIs for the Monaco SDK.
5
5
  */
6
+ export * from "./analytics";
6
7
  export * from "./applications/index";
7
8
  export * from "./base";
8
9
  export * from "./buildercodes";
package/dist/api/index.js CHANGED
@@ -3,6 +3,7 @@
3
3
  *
4
4
  * This module exports the new simplified APIs for the Monaco SDK.
5
5
  */
6
+ export * from "./analytics";
6
7
  export * from "./applications/index";
7
8
  export * from "./base";
8
9
  export * from "./buildercodes";
@@ -1,7 +1,10 @@
1
1
  import type { OrderbookEvent, OrderbookQuotationMode, TradingMode } from "@0xmonaco/types";
2
2
  import { BaseAPI } from "../base";
3
3
  export interface GetOrderbookOptions {
4
- /** Number of price levels to return (max 100). Defaults to 10. */
4
+ /**
5
+ * Number of price levels per side (max 1000). Defaults to 10. Above 100 the
6
+ * snapshot comes from the market-data book and carries `bookSeq`.
7
+ */
5
8
  depth?: number;
6
9
  /** Trading mode: 'Spot' or 'Margin'. Defaults to 'Spot'. */
7
10
  tradingMode?: TradingMode;
@@ -33,6 +33,8 @@ export class OrderbookAPIImpl extends BaseAPI {
33
33
  quoteDecimals: response.quoteDecimals,
34
34
  timestamp: response.timestamp,
35
35
  sequence: response.sequenceNumber,
36
+ // Kept as the wire's decimal string: a u64 can exceed Number.MAX_SAFE_INTEGER.
37
+ ...(response.bookSeq != null ? { bookSeq: response.bookSeq } : {}),
36
38
  };
37
39
  }
38
40
  }
@@ -1,4 +1,63 @@
1
1
  export declare const perpRoutes: {
2
+ readonly analytics: {
3
+ readonly protocolTotals: (params?: {
4
+ window?: string;
5
+ startTime?: number;
6
+ endTime?: number;
7
+ }) => string;
8
+ readonly protocolSeries: (params?: {
9
+ window?: string;
10
+ startTime?: number;
11
+ endTime?: number;
12
+ }) => string;
13
+ readonly marketVolumes: (params?: {
14
+ window?: string;
15
+ startTime?: number;
16
+ endTime?: number;
17
+ limit?: number;
18
+ }) => string;
19
+ readonly treasuryNetFees: () => string;
20
+ readonly builders: () => string;
21
+ readonly builder: (builder: string) => string;
22
+ readonly builderTotals: (builder: string, params?: {
23
+ window?: string;
24
+ startTime?: number;
25
+ endTime?: number;
26
+ }) => string;
27
+ readonly builderSeries: (builder: string, params?: {
28
+ window?: string;
29
+ startTime?: number;
30
+ endTime?: number;
31
+ }) => string;
32
+ readonly builderLeaderboard: (params?: {
33
+ window?: string;
34
+ startTime?: number;
35
+ endTime?: number;
36
+ limit?: number;
37
+ }) => string;
38
+ readonly walletLeaderboard: (params?: {
39
+ limit?: number;
40
+ }) => string;
41
+ readonly walletSummary: (wallet: string) => string;
42
+ readonly walletLiquidations: (wallet: string, params?: {
43
+ pageSize?: number;
44
+ pageToken?: string;
45
+ }) => string;
46
+ readonly tokenCustody: () => string;
47
+ readonly tokenCustodyDetail: (token: string) => string;
48
+ readonly vaultDeposits: (params?: {
49
+ pageSize?: number;
50
+ pageToken?: string;
51
+ token?: string;
52
+ wallet?: string;
53
+ }) => string;
54
+ readonly vaultWithdrawals: (params?: {
55
+ pageSize?: number;
56
+ pageToken?: string;
57
+ token?: string;
58
+ wallet?: string;
59
+ }) => string;
60
+ };
2
61
  readonly orders: {
3
62
  readonly create: () => string;
4
63
  readonly list: (params?: {
@@ -15,6 +15,24 @@ function withQuery(path, params) {
15
15
  return query ? `${path}?${query}` : path;
16
16
  }
17
17
  export const perpRoutes = {
18
+ analytics: {
19
+ protocolTotals: (params) => withQuery(`${API_V1}/analytics/protocol/totals`, params),
20
+ protocolSeries: (params) => withQuery(`${API_V1}/analytics/protocol/series`, params),
21
+ marketVolumes: (params) => withQuery(`${API_V1}/analytics/markets/volume`, params),
22
+ treasuryNetFees: () => `${API_V1}/analytics/treasury/net-fees`,
23
+ builders: () => `${API_V1}/analytics/builders`,
24
+ builder: (builder) => `${API_V1}/analytics/builders/${encodeURIComponent(builder)}`,
25
+ builderTotals: (builder, params) => withQuery(`${API_V1}/analytics/builders/${encodeURIComponent(builder)}/totals`, params),
26
+ builderSeries: (builder, params) => withQuery(`${API_V1}/analytics/builders/${encodeURIComponent(builder)}/series`, params),
27
+ builderLeaderboard: (params) => withQuery(`${API_V1}/analytics/builder-leaderboard`, params),
28
+ walletLeaderboard: (params) => withQuery(`${API_V1}/analytics/wallet-leaderboard`, params),
29
+ walletSummary: (wallet) => `${API_V1}/analytics/wallets/${encodeSegment(wallet)}`,
30
+ walletLiquidations: (wallet, params) => withQuery(`${API_V1}/analytics/wallets/${encodeSegment(wallet)}/liquidations`, params),
31
+ tokenCustody: () => `${API_V1}/analytics/tokens`,
32
+ tokenCustodyDetail: (token) => `${API_V1}/analytics/tokens/${encodeSegment(token)}`,
33
+ vaultDeposits: (params) => withQuery(`${API_V1}/analytics/deposits`, params),
34
+ vaultWithdrawals: (params) => withQuery(`${API_V1}/analytics/withdrawals`, params),
35
+ },
18
36
  orders: {
19
37
  create: () => `${API_V1}/orders`,
20
38
  list: (params) => withQuery(`${API_V1}/orders`, params),
@@ -23,6 +23,8 @@ interface RawTradeEvent {
23
23
  takerFeeRaw?: string;
24
24
  quoteVolumeRaw?: string;
25
25
  takerApplicationId?: string;
26
+ /** The taker's builder fee in raw quote units; "0" when none. */
27
+ builderFeeRaw?: string;
26
28
  };
27
29
  }
28
30
  /**
@@ -21,6 +21,8 @@ export function parseRawTradeEvent(raw) {
21
21
  ...(raw.data.takerFeeRaw ? { takerFeeRaw: raw.data.takerFeeRaw } : {}),
22
22
  ...(raw.data.quoteVolumeRaw ? { quoteVolumeRaw: raw.data.quoteVolumeRaw } : {}),
23
23
  ...(raw.data.takerApplicationId ? { takerApplicationId: raw.data.takerApplicationId } : {}),
24
+ // Kept when "0": that is a value (no builder fee), not an absence.
25
+ ...(raw.data.builderFeeRaw !== undefined ? { builderFeeRaw: raw.data.builderFeeRaw } : {}),
24
26
  },
25
27
  };
26
28
  }
@@ -41,7 +41,7 @@ export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
41
41
  * @param quantity - The order quantity as string
42
42
  * @param price - The limit price as string
43
43
  * @param options - Optional parameters for the limit order
44
- * @param options.tradingMode - Trading mode (e.g., "SPOT")
44
+ * @param options.tradingMode - Trading mode ("SPOT" or "MARGIN"). Omit it to use the trading pair market type.
45
45
  * @param options.useMasterBalance - Whether to use master balance for sub-accounts
46
46
  * @param options.expirationDate - Optional expiration date for GTC orders (ISO 8601 format)
47
47
  * @param options.timeInForce - Time in force ("GTC", "IOC", or "FOK")
@@ -115,7 +115,7 @@ export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
115
115
  * @param side - The order side ("BUY" or "SELL")
116
116
  * @param quantity - The order quantity as string
117
117
  * @param options - Optional parameters for the market order
118
- * @param options.tradingMode - Trading mode (e.g., "SPOT")
118
+ * @param options.tradingMode - Trading mode ("SPOT" or "MARGIN"). Omit it to use the trading pair market type.
119
119
  * @param options.slippageTolerance - Tightens the mandatory 1,000 bps price band, as a decimal (e.g., 0.01 for 1%; 0 for best price only). It can only tighten the band, never widen it; omitting it applies the full 1,000 bps band.
120
120
  * @returns Promise resolving to CreateOrderResponse with order details
121
121
  *
@@ -214,6 +214,10 @@ export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
214
214
  /**
215
215
  * Batch cancels specific orders by their IDs.
216
216
  *
217
+ * Every ID gets one entry in `results`, in request order, and the totals
218
+ * count every ID. An ID that is not one of your live orders comes back as a
219
+ * failed entry with code `ORDER_NOT_FOUND`.
220
+ *
217
221
  * @param orderIds - Array of order IDs to cancel
218
222
  * @returns Promise resolving to BatchCancelOrdersResponse with cancellation details
219
223
  * @throws {APIError} When API communication fails
@@ -77,7 +77,7 @@ export class TradingAPIImpl extends BaseAPI {
77
77
  * @param quantity - The order quantity as string
78
78
  * @param price - The limit price as string
79
79
  * @param options - Optional parameters for the limit order
80
- * @param options.tradingMode - Trading mode (e.g., "SPOT")
80
+ * @param options.tradingMode - Trading mode ("SPOT" or "MARGIN"). Omit it to use the trading pair market type.
81
81
  * @param options.useMasterBalance - Whether to use master balance for sub-accounts
82
82
  * @param options.expirationDate - Optional expiration date for GTC orders (ISO 8601 format)
83
83
  * @param options.timeInForce - Time in force ("GTC", "IOC", or "FOK")
@@ -131,7 +131,7 @@ export class TradingAPIImpl extends BaseAPI {
131
131
  side,
132
132
  price,
133
133
  quantity,
134
- tradingMode: options?.tradingMode || "SPOT",
134
+ tradingMode: options?.tradingMode,
135
135
  useMasterBalance: options?.useMasterBalance,
136
136
  expirationDate: options?.expirationDate,
137
137
  timeInForce: options?.timeInForce,
@@ -165,7 +165,7 @@ export class TradingAPIImpl extends BaseAPI {
165
165
  * @param side - The order side ("BUY" or "SELL")
166
166
  * @param quantity - The order quantity as string
167
167
  * @param options - Optional parameters for the market order
168
- * @param options.tradingMode - Trading mode (e.g., "SPOT")
168
+ * @param options.tradingMode - Trading mode ("SPOT" or "MARGIN"). Omit it to use the trading pair market type.
169
169
  * @param options.slippageTolerance - Tightens the mandatory 1,000 bps price band, as a decimal (e.g., 0.01 for 1%; 0 for best price only). It can only tighten the band, never widen it; omitting it applies the full 1,000 bps band.
170
170
  * @returns Promise resolving to CreateOrderResponse with order details
171
171
  *
@@ -211,7 +211,7 @@ export class TradingAPIImpl extends BaseAPI {
211
211
  slippageToleranceBps: options?.slippageTolerance !== undefined ? Math.round(options.slippageTolerance * 10000) : undefined,
212
212
  price: null, // Market orders don't need price
213
213
  quantity,
214
- tradingMode: options?.tradingMode || "SPOT",
214
+ tradingMode: options?.tradingMode,
215
215
  marginAccountId: options?.marginAccountId,
216
216
  marginMode: options?.marginMode,
217
217
  riskBucketId: options?.riskBucketId,
@@ -313,6 +313,10 @@ export class TradingAPIImpl extends BaseAPI {
313
313
  /**
314
314
  * Batch cancels specific orders by their IDs.
315
315
  *
316
+ * Every ID gets one entry in `results`, in request order, and the totals
317
+ * count every ID. An ID that is not one of your live orders comes back as a
318
+ * failed entry with code `ORDER_NOT_FOUND`.
319
+ *
316
320
  * @param orderIds - Array of order IDs to cancel
317
321
  * @returns Promise resolving to BatchCancelOrdersResponse with cancellation details
318
322
  * @throws {APIError} When API communication fails
@@ -460,7 +464,7 @@ export class TradingAPIImpl extends BaseAPI {
460
464
  side: order.side,
461
465
  price: order.price,
462
466
  quantity: order.quantity,
463
- tradingMode: order.tradingMode || "SPOT",
467
+ tradingMode: order.tradingMode,
464
468
  slippageToleranceBps: order.slippageTolerance !== undefined ? Math.round(order.slippageTolerance * 10000) : undefined,
465
469
  useMasterBalance: order.useMasterBalance,
466
470
  expirationDate: order.expirationDate,
@@ -761,7 +765,7 @@ export class TradingAPIImpl extends BaseAPI {
761
765
  slippageToleranceBps: options.slippageToleranceBps,
762
766
  randomize: options.randomize,
763
767
  reduceOnly: options.reduceOnly,
764
- tradingMode: options.tradingMode || "SPOT",
768
+ tradingMode: options.tradingMode,
765
769
  marginAccountId: options.marginAccountId,
766
770
  riskBucketId: options.riskBucketId,
767
771
  marginMode: options.marginMode,