@nadohq/client 0.1.0-alpha.1

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.
Files changed (184) hide show
  1. package/README.md +3 -0
  2. package/dist/apis/base.cjs +66 -0
  3. package/dist/apis/base.cjs.map +1 -0
  4. package/dist/apis/base.d.cts +23 -0
  5. package/dist/apis/base.d.ts +23 -0
  6. package/dist/apis/base.js +41 -0
  7. package/dist/apis/base.js.map +1 -0
  8. package/dist/apis/market/MarketExecuteAPI.cjs +169 -0
  9. package/dist/apis/market/MarketExecuteAPI.cjs.map +1 -0
  10. package/dist/apis/market/MarketExecuteAPI.d.cts +57 -0
  11. package/dist/apis/market/MarketExecuteAPI.d.ts +57 -0
  12. package/dist/apis/market/MarketExecuteAPI.js +144 -0
  13. package/dist/apis/market/MarketExecuteAPI.js.map +1 -0
  14. package/dist/apis/market/MarketQueryAPI.cjs +191 -0
  15. package/dist/apis/market/MarketQueryAPI.cjs.map +1 -0
  16. package/dist/apis/market/MarketQueryAPI.d.cts +127 -0
  17. package/dist/apis/market/MarketQueryAPI.d.ts +127 -0
  18. package/dist/apis/market/MarketQueryAPI.js +166 -0
  19. package/dist/apis/market/MarketQueryAPI.js.map +1 -0
  20. package/dist/apis/market/index.cjs +38 -0
  21. package/dist/apis/market/index.cjs.map +1 -0
  22. package/dist/apis/market/index.d.cts +18 -0
  23. package/dist/apis/market/index.d.ts +18 -0
  24. package/dist/apis/market/index.js +11 -0
  25. package/dist/apis/market/index.js.map +1 -0
  26. package/dist/apis/market/types.cjs +19 -0
  27. package/dist/apis/market/types.cjs.map +1 -0
  28. package/dist/apis/market/types.d.cts +26 -0
  29. package/dist/apis/market/types.d.ts +26 -0
  30. package/dist/apis/market/types.js +1 -0
  31. package/dist/apis/market/types.js.map +1 -0
  32. package/dist/apis/perp/PerpExecuteAPI.cjs +36 -0
  33. package/dist/apis/perp/PerpExecuteAPI.cjs.map +1 -0
  34. package/dist/apis/perp/PerpExecuteAPI.d.cts +13 -0
  35. package/dist/apis/perp/PerpExecuteAPI.d.ts +13 -0
  36. package/dist/apis/perp/PerpExecuteAPI.js +11 -0
  37. package/dist/apis/perp/PerpExecuteAPI.js.map +1 -0
  38. package/dist/apis/perp/PerpQueryAPI.cjs +47 -0
  39. package/dist/apis/perp/PerpQueryAPI.cjs.map +1 -0
  40. package/dist/apis/perp/PerpQueryAPI.d.cts +23 -0
  41. package/dist/apis/perp/PerpQueryAPI.d.ts +23 -0
  42. package/dist/apis/perp/PerpQueryAPI.js +22 -0
  43. package/dist/apis/perp/PerpQueryAPI.js.map +1 -0
  44. package/dist/apis/perp/index.cjs +35 -0
  45. package/dist/apis/perp/index.cjs.map +1 -0
  46. package/dist/apis/perp/index.d.cts +16 -0
  47. package/dist/apis/perp/index.d.ts +16 -0
  48. package/dist/apis/perp/index.js +10 -0
  49. package/dist/apis/perp/index.js.map +1 -0
  50. package/dist/apis/spot/BaseSpotAPI.cjs +55 -0
  51. package/dist/apis/spot/BaseSpotAPI.cjs.map +1 -0
  52. package/dist/apis/spot/BaseSpotAPI.d.cts +19 -0
  53. package/dist/apis/spot/BaseSpotAPI.d.ts +19 -0
  54. package/dist/apis/spot/BaseSpotAPI.js +30 -0
  55. package/dist/apis/spot/BaseSpotAPI.js.map +1 -0
  56. package/dist/apis/spot/SpotExecuteAPI.cjs +108 -0
  57. package/dist/apis/spot/SpotExecuteAPI.cjs.map +1 -0
  58. package/dist/apis/spot/SpotExecuteAPI.d.cts +28 -0
  59. package/dist/apis/spot/SpotExecuteAPI.d.ts +28 -0
  60. package/dist/apis/spot/SpotExecuteAPI.js +88 -0
  61. package/dist/apis/spot/SpotExecuteAPI.js.map +1 -0
  62. package/dist/apis/spot/SpotQueryAPI.cjs +74 -0
  63. package/dist/apis/spot/SpotQueryAPI.cjs.map +1 -0
  64. package/dist/apis/spot/SpotQueryAPI.d.cts +35 -0
  65. package/dist/apis/spot/SpotQueryAPI.d.ts +35 -0
  66. package/dist/apis/spot/SpotQueryAPI.js +49 -0
  67. package/dist/apis/spot/SpotQueryAPI.js.map +1 -0
  68. package/dist/apis/spot/index.cjs +38 -0
  69. package/dist/apis/spot/index.cjs.map +1 -0
  70. package/dist/apis/spot/index.d.cts +23 -0
  71. package/dist/apis/spot/index.d.ts +23 -0
  72. package/dist/apis/spot/index.js +11 -0
  73. package/dist/apis/spot/index.js.map +1 -0
  74. package/dist/apis/spot/types.cjs +19 -0
  75. package/dist/apis/spot/types.cjs.map +1 -0
  76. package/dist/apis/spot/types.d.cts +23 -0
  77. package/dist/apis/spot/types.d.ts +23 -0
  78. package/dist/apis/spot/types.js +1 -0
  79. package/dist/apis/spot/types.js.map +1 -0
  80. package/dist/apis/subaccount/SubaccountExecuteAPI.cjs +59 -0
  81. package/dist/apis/subaccount/SubaccountExecuteAPI.cjs.map +1 -0
  82. package/dist/apis/subaccount/SubaccountExecuteAPI.d.cts +26 -0
  83. package/dist/apis/subaccount/SubaccountExecuteAPI.d.ts +26 -0
  84. package/dist/apis/subaccount/SubaccountExecuteAPI.js +34 -0
  85. package/dist/apis/subaccount/SubaccountExecuteAPI.js.map +1 -0
  86. package/dist/apis/subaccount/SubaccountQueryAPI.cjs +84 -0
  87. package/dist/apis/subaccount/SubaccountQueryAPI.cjs.map +1 -0
  88. package/dist/apis/subaccount/SubaccountQueryAPI.d.cts +51 -0
  89. package/dist/apis/subaccount/SubaccountQueryAPI.d.ts +51 -0
  90. package/dist/apis/subaccount/SubaccountQueryAPI.js +61 -0
  91. package/dist/apis/subaccount/SubaccountQueryAPI.js.map +1 -0
  92. package/dist/apis/subaccount/index.cjs +68 -0
  93. package/dist/apis/subaccount/index.cjs.map +1 -0
  94. package/dist/apis/subaccount/index.d.cts +27 -0
  95. package/dist/apis/subaccount/index.d.ts +27 -0
  96. package/dist/apis/subaccount/index.js +41 -0
  97. package/dist/apis/subaccount/index.js.map +1 -0
  98. package/dist/apis/subaccount/types.cjs +19 -0
  99. package/dist/apis/subaccount/types.cjs.map +1 -0
  100. package/dist/apis/subaccount/types.d.cts +9 -0
  101. package/dist/apis/subaccount/types.d.ts +9 -0
  102. package/dist/apis/subaccount/types.js +1 -0
  103. package/dist/apis/subaccount/types.js.map +1 -0
  104. package/dist/apis/types.cjs +19 -0
  105. package/dist/apis/types.cjs.map +1 -0
  106. package/dist/apis/types.d.cts +9 -0
  107. package/dist/apis/types.d.ts +9 -0
  108. package/dist/apis/types.js +1 -0
  109. package/dist/apis/types.js.map +1 -0
  110. package/dist/apis/ws/WebSocketExecuteAPI.cjs +73 -0
  111. package/dist/apis/ws/WebSocketExecuteAPI.cjs.map +1 -0
  112. package/dist/apis/ws/WebSocketExecuteAPI.d.cts +48 -0
  113. package/dist/apis/ws/WebSocketExecuteAPI.d.ts +48 -0
  114. package/dist/apis/ws/WebSocketExecuteAPI.js +48 -0
  115. package/dist/apis/ws/WebSocketExecuteAPI.js.map +1 -0
  116. package/dist/apis/ws/WebSocketQueryAPI.cjs +42 -0
  117. package/dist/apis/ws/WebSocketQueryAPI.cjs.map +1 -0
  118. package/dist/apis/ws/WebSocketQueryAPI.d.cts +23 -0
  119. package/dist/apis/ws/WebSocketQueryAPI.d.ts +23 -0
  120. package/dist/apis/ws/WebSocketQueryAPI.js +17 -0
  121. package/dist/apis/ws/WebSocketQueryAPI.js.map +1 -0
  122. package/dist/apis/ws/WebSocketSubscriptionAPI.cjs +61 -0
  123. package/dist/apis/ws/WebSocketSubscriptionAPI.cjs.map +1 -0
  124. package/dist/apis/ws/WebSocketSubscriptionAPI.d.cts +37 -0
  125. package/dist/apis/ws/WebSocketSubscriptionAPI.d.ts +37 -0
  126. package/dist/apis/ws/WebSocketSubscriptionAPI.js +36 -0
  127. package/dist/apis/ws/WebSocketSubscriptionAPI.js.map +1 -0
  128. package/dist/apis/ws/index.cjs +42 -0
  129. package/dist/apis/ws/index.cjs.map +1 -0
  130. package/dist/apis/ws/index.d.cts +22 -0
  131. package/dist/apis/ws/index.d.ts +22 -0
  132. package/dist/apis/ws/index.js +17 -0
  133. package/dist/apis/ws/index.js.map +1 -0
  134. package/dist/client.cjs +79 -0
  135. package/dist/client.cjs.map +1 -0
  136. package/dist/client.d.cts +57 -0
  137. package/dist/client.d.ts +57 -0
  138. package/dist/client.js +54 -0
  139. package/dist/client.js.map +1 -0
  140. package/dist/context.cjs +125 -0
  141. package/dist/context.cjs.map +1 -0
  142. package/dist/context.d.cts +42 -0
  143. package/dist/context.d.ts +42 -0
  144. package/dist/context.js +109 -0
  145. package/dist/context.js.map +1 -0
  146. package/dist/createNadoClient.cjs +35 -0
  147. package/dist/createNadoClient.cjs.map +1 -0
  148. package/dist/createNadoClient.d.cts +42 -0
  149. package/dist/createNadoClient.d.ts +42 -0
  150. package/dist/createNadoClient.js +12 -0
  151. package/dist/createNadoClient.js.map +1 -0
  152. package/dist/index.cjs +47 -0
  153. package/dist/index.cjs.map +1 -0
  154. package/dist/index.d.cts +32 -0
  155. package/dist/index.d.ts +32 -0
  156. package/dist/index.js +14 -0
  157. package/dist/index.js.map +1 -0
  158. package/package.json +54 -0
  159. package/src/apis/base.ts +52 -0
  160. package/src/apis/market/MarketExecuteAPI.ts +169 -0
  161. package/src/apis/market/MarketQueryAPI.ts +214 -0
  162. package/src/apis/market/index.ts +7 -0
  163. package/src/apis/market/types.ts +58 -0
  164. package/src/apis/perp/PerpExecuteAPI.ts +8 -0
  165. package/src/apis/perp/PerpQueryAPI.ts +25 -0
  166. package/src/apis/perp/index.ts +5 -0
  167. package/src/apis/spot/BaseSpotAPI.ts +30 -0
  168. package/src/apis/spot/SpotExecuteAPI.ts +102 -0
  169. package/src/apis/spot/SpotQueryAPI.ts +53 -0
  170. package/src/apis/spot/index.ts +10 -0
  171. package/src/apis/spot/types.ts +44 -0
  172. package/src/apis/subaccount/SubaccountExecuteAPI.ts +32 -0
  173. package/src/apis/subaccount/SubaccountQueryAPI.ts +78 -0
  174. package/src/apis/subaccount/index.ts +44 -0
  175. package/src/apis/subaccount/types.ts +16 -0
  176. package/src/apis/types.ts +11 -0
  177. package/src/apis/ws/WebSocketExecuteAPI.ts +70 -0
  178. package/src/apis/ws/WebSocketQueryAPI.ts +25 -0
  179. package/src/apis/ws/WebSocketSubscriptionAPI.ts +62 -0
  180. package/src/apis/ws/index.ts +21 -0
  181. package/src/client.ts +67 -0
  182. package/src/context.ts +165 -0
  183. package/src/createNadoClient.ts +20 -0
  184. package/src/index.ts +15 -0
@@ -0,0 +1,169 @@
1
+ import { BaseNadoAPI } from '../base';
2
+ import { OptionalSignatureParams } from '../types';
3
+ import {
4
+ CancelAndPlaceOrderParams,
5
+ CancelOrdersParams,
6
+ CancelProductOrdersParams,
7
+ CancelTriggerOrdersParams,
8
+ CancelTriggerProductOrdersParams,
9
+ PlaceIsolatedOrderParams,
10
+ PlaceOrderParams,
11
+ PlaceTriggerOrderParams,
12
+ } from './types';
13
+
14
+ export class MarketExecuteAPI extends BaseNadoAPI {
15
+ /**
16
+ * Places an order through the engine
17
+ * @param params
18
+ */
19
+ async placeOrder(params: PlaceOrderParams) {
20
+ const { id: orderId, productId, order, nonce } = params;
21
+
22
+ return this.context.engineClient.placeOrder({
23
+ id: orderId,
24
+ order: {
25
+ ...order,
26
+ subaccountOwner: this.getSubaccountOwnerIfNeeded(params.order),
27
+ },
28
+ chainId: this.getWalletClientChainIdIfNeeded(params),
29
+ verifyingAddr: await this.getOrderbookVerifyingAddressIfNeeded(params),
30
+ productId,
31
+ spotLeverage: params.spotLeverage,
32
+ nonce,
33
+ });
34
+ }
35
+
36
+ /**
37
+ * Places an isolated order through the engine
38
+ * @param params
39
+ */
40
+ async placeIsolatedOrder(params: PlaceIsolatedOrderParams) {
41
+ const { id: orderId, productId, order, nonce, borrowMargin } = params;
42
+
43
+ return this.context.engineClient.placeIsolatedOrder({
44
+ id: orderId,
45
+ order: {
46
+ ...order,
47
+ subaccountOwner: this.getSubaccountOwnerIfNeeded(params.order),
48
+ },
49
+ chainId: this.getWalletClientChainIdIfNeeded(params),
50
+ verifyingAddr: await this.getOrderbookVerifyingAddressIfNeeded(params),
51
+ productId,
52
+ borrowMargin,
53
+ nonce,
54
+ });
55
+ }
56
+
57
+ /**
58
+ * Cancels orders through the engine
59
+ * @param params
60
+ */
61
+ async cancelOrders(params: CancelOrdersParams) {
62
+ return this.context.engineClient.cancelOrders({
63
+ ...params,
64
+ chainId: this.getWalletClientChainIdIfNeeded(params),
65
+ subaccountOwner: this.getSubaccountOwnerIfNeeded(params),
66
+ verifyingAddr: this.getEndpointAddress(),
67
+ });
68
+ }
69
+
70
+ /**
71
+ * Cancels orders through the engine and places a new one
72
+ * @param params
73
+ */
74
+ async cancelAndPlace(params: CancelAndPlaceOrderParams) {
75
+ const { productId, order, nonce, spotLeverage } = params.placeOrder;
76
+ const subaccountOwner = this.getSubaccountOwnerIfNeeded(
77
+ params.cancelOrders,
78
+ );
79
+ const chainId = this.getWalletClientChainIdIfNeeded(params.cancelOrders);
80
+
81
+ return this.context.engineClient.cancelAndPlace({
82
+ cancelOrders: {
83
+ ...params.cancelOrders,
84
+ subaccountOwner,
85
+ verifyingAddr:
86
+ params.cancelOrders.verifyingAddr ?? this.getEndpointAddress(),
87
+ chainId,
88
+ },
89
+ placeOrder: {
90
+ order: {
91
+ ...order,
92
+ subaccountOwner,
93
+ },
94
+ verifyingAddr: await this.getOrderbookVerifyingAddressIfNeeded(
95
+ params.placeOrder,
96
+ ),
97
+ chainId,
98
+ productId,
99
+ spotLeverage,
100
+ nonce,
101
+ },
102
+ });
103
+ }
104
+
105
+ /**
106
+ * Cancels all orders for provided products through the engine.
107
+ * @param params
108
+ */
109
+ async cancelProductOrders(params: CancelProductOrdersParams) {
110
+ return this.context.engineClient.cancelProductOrders({
111
+ ...params,
112
+ chainId: this.getWalletClientChainIdIfNeeded(params),
113
+ subaccountOwner: this.getSubaccountOwnerIfNeeded(params),
114
+ verifyingAddr: this.getEndpointAddress(),
115
+ });
116
+ }
117
+
118
+ /**
119
+ * Places a trigger order through the trigger service
120
+ * @param params
121
+ */
122
+ async placeTriggerOrder(params: PlaceTriggerOrderParams) {
123
+ return this.context.triggerClient.placeTriggerOrder({
124
+ ...params,
125
+ chainId: this.getWalletClientChainIdIfNeeded(params),
126
+ verifyingAddr: await this.getOrderbookVerifyingAddressIfNeeded(params),
127
+ order: {
128
+ subaccountOwner: this.getSubaccountOwnerIfNeeded(params.order),
129
+ ...params.order,
130
+ },
131
+ });
132
+ }
133
+
134
+ /**
135
+ * Cancels all trigger orders for provided digests through the trigger service.
136
+ * @param params
137
+ */
138
+ async cancelTriggerOrders(params: CancelTriggerOrdersParams) {
139
+ return this.context.triggerClient.cancelTriggerOrders({
140
+ ...params,
141
+ chainId: this.getWalletClientChainIdIfNeeded(params),
142
+ subaccountOwner: this.getSubaccountOwnerIfNeeded(params),
143
+ verifyingAddr: params.verifyingAddr ?? this.getEndpointAddress(),
144
+ });
145
+ }
146
+
147
+ /**
148
+ * Cancels all trigger orders for provided products through the trigger service.
149
+ * @param params
150
+ */
151
+ async cancelTriggerProductOrders(params: CancelTriggerProductOrdersParams) {
152
+ return this.context.triggerClient.cancelProductOrders({
153
+ ...params,
154
+ chainId: this.getWalletClientChainIdIfNeeded(params),
155
+ subaccountOwner: this.getSubaccountOwnerIfNeeded(params),
156
+ verifyingAddr: params.verifyingAddr ?? this.getEndpointAddress(),
157
+ });
158
+ }
159
+
160
+ protected async getOrderbookVerifyingAddressIfNeeded(
161
+ params: OptionalSignatureParams<{
162
+ productId: number;
163
+ }>,
164
+ ): Promise<string> {
165
+ return (
166
+ params.verifyingAddr ?? (await this.getOrderbookAddress(params.productId))
167
+ );
168
+ }
169
+ }
@@ -0,0 +1,214 @@
1
+ import { getAllMarkets, GetAllMarketsResponse } from '@nadohq/contracts';
2
+ import {
3
+ GetEngineMarketLiquidityParams,
4
+ GetEngineMarketPriceParams,
5
+ GetEngineMarketPricesParams,
6
+ GetEngineMaxOrderSizeParams,
7
+ GetEngineSubaccountOrdersParams,
8
+ GetEngineSubaccountProductOrdersParams,
9
+ ValidateEngineOrderParams,
10
+ } from '@nadohq/engine-client';
11
+ import {
12
+ GetIndexerCandlesticksParams,
13
+ GetIndexerEdgeCandlesticksParams,
14
+ GetIndexerEdgeMarketSnapshotsParams,
15
+ GetIndexerFundingRateParams,
16
+ GetIndexerMarketSnapshotsParams,
17
+ GetIndexerMultiProductFundingRatesParams,
18
+ GetIndexerMultiProductSnapshotsParams,
19
+ GetIndexerOrdersParams,
20
+ GetIndexerOrdersResponse,
21
+ GetIndexerProductSnapshotsParams,
22
+ } from '@nadohq/indexer-client';
23
+ import { BaseNadoAPI } from '../base';
24
+ import { GetTriggerOrdersParams } from './types';
25
+
26
+ export class MarketQueryAPI extends BaseNadoAPI {
27
+ /**
28
+ * Retrieves all market states from the on-chain contracts
29
+ */
30
+ async getAllMarkets(): Promise<GetAllMarketsResponse> {
31
+ return getAllMarkets(this.context.contracts);
32
+ }
33
+
34
+ /**
35
+ * Retrieves all market states from the offchain engine
36
+ */
37
+ async getAllEngineMarkets(): Promise<GetAllMarketsResponse> {
38
+ return this.context.engineClient.getAllMarkets();
39
+ }
40
+
41
+ /**
42
+ * Get all edge engine markets
43
+ */
44
+ async getEdgeAllEngineMarkets(): Promise<
45
+ Record<number, GetAllMarketsResponse>
46
+ > {
47
+ return this.context.engineClient.getEdgeAllMarkets();
48
+ }
49
+
50
+ /**
51
+ * Retrieves all spread health groups
52
+ */
53
+ async getHealthGroups() {
54
+ return this.context.engineClient.getHealthGroups();
55
+ }
56
+
57
+ /**
58
+ * Queries engine to determine if the order can be submitted within health requirements
59
+ */
60
+ async validateOrderParams(params: ValidateEngineOrderParams) {
61
+ return this.context.engineClient.validateOrderParams(params);
62
+ }
63
+
64
+ /**
65
+ * Queries the offchain engine to retrieve status of any open orders for the given subaccount
66
+ * @param params
67
+ */
68
+ async getOpenSubaccountOrders(params: GetEngineSubaccountOrdersParams) {
69
+ return this.context.engineClient.getSubaccountOrders(params);
70
+ }
71
+
72
+ /**
73
+ * Queries the offchain engine to retrieve status of any open orders for the given subaccount for multiple products
74
+ * @param params
75
+ */
76
+ async getOpenSubaccountMultiProductOrders(
77
+ params: GetEngineSubaccountProductOrdersParams,
78
+ ) {
79
+ return this.context.engineClient.getSubaccountMultiProductOrders(params);
80
+ }
81
+
82
+ /**
83
+ * Queries the offchain trigger service to list trigger orders. Requires a signature
84
+ * @param params
85
+ */
86
+ async getTriggerOrders(params: GetTriggerOrdersParams) {
87
+ return this.context.triggerClient.listOrders({
88
+ ...params,
89
+ chainId: this.getWalletClientChainIdIfNeeded(params),
90
+ verifyingAddr: params.verifyingAddr ?? this.getEndpointAddress(),
91
+ });
92
+ }
93
+
94
+ /**
95
+ * Queries indexer to fetch historical orders
96
+ *
97
+ * @param params
98
+ */
99
+ async getHistoricalOrders(
100
+ params: GetIndexerOrdersParams,
101
+ ): Promise<GetIndexerOrdersResponse> {
102
+ return this.context.indexerClient.getOrders(params);
103
+ }
104
+
105
+ /**
106
+ * Queries engine to determine maximum order size
107
+ * @param params
108
+ */
109
+ async getMaxOrderSize(params: GetEngineMaxOrderSizeParams) {
110
+ return this.context.engineClient.getMaxOrderSize(params);
111
+ }
112
+
113
+ /**
114
+ * Retrieves liquidity per price tick from the engine. The engine will skip price levels that have no liquidity,
115
+ * so it is not guaranteed that the bids/asks are evenly spaced
116
+ */
117
+ async getMarketLiquidity(params: GetEngineMarketLiquidityParams) {
118
+ return this.context.engineClient.getMarketLiquidity(params);
119
+ }
120
+
121
+ /**
122
+ * Historical candlesticks from the indexer, use getLatestMarketPrice for the latest orderbook prices
123
+ *
124
+ * @param params
125
+ */
126
+ async getCandlesticks(params: GetIndexerCandlesticksParams) {
127
+ return this.context.indexerClient.getCandlesticks(params);
128
+ }
129
+
130
+ /**
131
+ * Historical candlesticks from Edge, use getLatestMarketPrice for the latest orderbook prices
132
+ *
133
+ * @param params
134
+ */
135
+ async getEdgeCandlesticks(params: GetIndexerEdgeCandlesticksParams) {
136
+ return this.context.indexerClient.getEdgeCandlesticks(params);
137
+ }
138
+
139
+ /**
140
+ * Retrieves the latest off-chain orderbook price from the engine
141
+ *
142
+ * @param params
143
+ */
144
+ async getLatestMarketPrice(params: GetEngineMarketPriceParams) {
145
+ return this.context.engineClient.getMarketPrice(params);
146
+ }
147
+
148
+ /**
149
+ * Retrieves the latest off-chain orderbook price from the engine for multiple markets
150
+ *
151
+ * @param params
152
+ */
153
+ async getLatestMarketPrices(params: GetEngineMarketPricesParams) {
154
+ return this.context.engineClient.getMarketPrices(params);
155
+ }
156
+
157
+ /**
158
+ * Retrieves the latest funding rate for a perp product
159
+ *
160
+ * @param params
161
+ */
162
+ async getFundingRate(params: GetIndexerFundingRateParams) {
163
+ return this.context.indexerClient.getFundingRate(params);
164
+ }
165
+
166
+ /**
167
+ * Retrieves the latest funding rate for multiple perp products
168
+ *
169
+ * @param params
170
+ */
171
+ async getMultiProductFundingRates(
172
+ params: GetIndexerMultiProductFundingRatesParams,
173
+ ) {
174
+ return this.context.indexerClient.getMultiProductFundingRates(params);
175
+ }
176
+
177
+ /**
178
+ * Retrieves the historical snapshots for a product from the indexer
179
+ *
180
+ * @param params
181
+ */
182
+ async getProductSnapshots(params: GetIndexerProductSnapshotsParams) {
183
+ return this.context.indexerClient.getProductSnapshots(params);
184
+ }
185
+
186
+ /**
187
+ * Retrieves the historical snapshots for a market from the indexer
188
+ *
189
+ * @param params
190
+ */
191
+ async getMarketSnapshots(params: GetIndexerMarketSnapshotsParams) {
192
+ return this.context.indexerClient.getMarketSnapshots(params);
193
+ }
194
+
195
+ /**
196
+ * Retrieves the historical snapshots for a market from Edge
197
+ *
198
+ * @param params
199
+ */
200
+ async getEdgeMarketSnapshots(params: GetIndexerEdgeMarketSnapshotsParams) {
201
+ return this.context.indexerClient.getEdgeMarketSnapshots(params);
202
+ }
203
+
204
+ /**
205
+ * Retrieves the historical snapshots for multiple products from the indexer
206
+ *
207
+ * @param params
208
+ */
209
+ async getMultiProductSnapshots(
210
+ params: GetIndexerMultiProductSnapshotsParams,
211
+ ) {
212
+ return this.context.indexerClient.getMultiProductSnapshots(params);
213
+ }
214
+ }
@@ -0,0 +1,7 @@
1
+ import { Mixin } from 'ts-mixer';
2
+ import { MarketExecuteAPI } from './MarketExecuteAPI';
3
+ import { MarketQueryAPI } from './MarketQueryAPI';
4
+
5
+ export * from './types';
6
+
7
+ export class MarketAPI extends Mixin(MarketExecuteAPI, MarketQueryAPI) {}
@@ -0,0 +1,58 @@
1
+ import {
2
+ EngineCancelOrdersParams,
3
+ EngineCancelProductOrdersParams,
4
+ EngineIsolatedOrderParams,
5
+ EngineOrderParams,
6
+ EnginePlaceIsolatedOrderParams,
7
+ EnginePlaceOrderParams,
8
+ } from '@nadohq/engine-client';
9
+ import {
10
+ TriggerCancelOrdersParams,
11
+ TriggerCancelProductOrdersParams,
12
+ TriggerListOrdersParams,
13
+ TriggerPlaceOrderParams,
14
+ } from '@nadohq/trigger-client';
15
+ import { OptionalSignatureParams, OptionalSubaccountOwner } from '../types';
16
+
17
+ type ClientOrderParams<T> = Omit<OptionalSignatureParams<T>, 'order'> & {
18
+ order: OptionalSubaccountOwner<EngineOrderParams>;
19
+ };
20
+
21
+ export type PlaceOrderParams = ClientOrderParams<EnginePlaceOrderParams>;
22
+
23
+ /**
24
+ * Same as PlaceOrderParams but with isolated fields for isolated margin trading
25
+ */
26
+ export type PlaceIsolatedOrderParams = Omit<
27
+ OptionalSignatureParams<EnginePlaceIsolatedOrderParams>,
28
+ 'order'
29
+ > & {
30
+ order: OptionalSubaccountOwner<EngineIsolatedOrderParams>;
31
+ };
32
+
33
+ export type CancelOrdersParams = OptionalSignatureParams<
34
+ OptionalSubaccountOwner<EngineCancelOrdersParams>
35
+ >;
36
+
37
+ export type CancelProductOrdersParams = OptionalSignatureParams<
38
+ OptionalSubaccountOwner<EngineCancelProductOrdersParams>
39
+ >;
40
+
41
+ export interface CancelAndPlaceOrderParams {
42
+ placeOrder: PlaceOrderParams;
43
+ cancelOrders: CancelOrdersParams;
44
+ }
45
+
46
+ export type PlaceTriggerOrderParams =
47
+ ClientOrderParams<TriggerPlaceOrderParams>;
48
+
49
+ export type CancelTriggerOrdersParams = OptionalSignatureParams<
50
+ OptionalSubaccountOwner<TriggerCancelOrdersParams>
51
+ >;
52
+
53
+ export type CancelTriggerProductOrdersParams = OptionalSignatureParams<
54
+ OptionalSubaccountOwner<TriggerCancelProductOrdersParams>
55
+ >;
56
+
57
+ export type GetTriggerOrdersParams =
58
+ OptionalSignatureParams<TriggerListOrdersParams>;
@@ -0,0 +1,8 @@
1
+ import { SettlePnlParams } from '@nadohq/contracts';
2
+ import { BaseNadoAPI } from '../base';
3
+
4
+ export class PerpExecuteAPI extends BaseNadoAPI {
5
+ settlePnl(_params: SettlePnlParams) {
6
+ throw Error('Not implemented');
7
+ }
8
+ }
@@ -0,0 +1,25 @@
1
+ import {
2
+ GetIndexerMultiProductPerpPricesParams,
3
+ GetIndexerPerpPricesParams,
4
+ } from '@nadohq/indexer-client';
5
+ import { BaseNadoAPI } from '../base';
6
+
7
+ export class PerpQueryAPI extends BaseNadoAPI {
8
+ /**
9
+ * Gets the latest index & mark price for a perp product
10
+ * @param params
11
+ */
12
+ async getPerpPrices(params: GetIndexerPerpPricesParams) {
13
+ return this.context.indexerClient.getPerpPrices(params);
14
+ }
15
+
16
+ /**
17
+ * Gets the latest index & mark price for multiple perp products
18
+ * @param params
19
+ */
20
+ async getMultiProductPerpPrices(
21
+ params: GetIndexerMultiProductPerpPricesParams,
22
+ ) {
23
+ return this.context.indexerClient.getMultiProductPerpPrices(params);
24
+ }
25
+ }
@@ -0,0 +1,5 @@
1
+ import { Mixin } from 'ts-mixer';
2
+ import { PerpExecuteAPI } from './PerpExecuteAPI';
3
+ import { PerpQueryAPI } from './PerpQueryAPI';
4
+
5
+ export class PerpAPI extends Mixin(PerpExecuteAPI, PerpQueryAPI) {}
@@ -0,0 +1,30 @@
1
+ import { ContractInstance, ERC20_ABI } from '@nadohq/contracts';
2
+ import { getValidatedAddress } from '@nadohq/utils';
3
+ import { getContract } from 'viem';
4
+ import { BaseNadoAPI } from '../base';
5
+ import { ProductIdOrTokenAddress } from './types';
6
+
7
+ export class BaseSpotAPI extends BaseNadoAPI {
8
+ /**
9
+ * Retrieves the ERC20 token contract for a spot product
10
+ */
11
+ async getTokenContractForProduct(
12
+ params: ProductIdOrTokenAddress,
13
+ ): Promise<ContractInstance<typeof ERC20_ABI>> {
14
+ let tokenAddress: string;
15
+ if ('productId' in params) {
16
+ const config = await this.context.contracts.spotEngine.read.getConfig([
17
+ params.productId,
18
+ ]);
19
+ tokenAddress = config.token;
20
+ } else {
21
+ tokenAddress = params.tokenAddress;
22
+ }
23
+
24
+ return getContract({
25
+ abi: ERC20_ABI,
26
+ address: getValidatedAddress(tokenAddress),
27
+ client: this.context.walletClient ?? this.context.publicClient,
28
+ });
29
+ }
30
+ }
@@ -0,0 +1,102 @@
1
+ import {
2
+ approveDepositAllowance,
3
+ depositCollateral,
4
+ DepositCollateralParams,
5
+ isWriteableContract,
6
+ MintMockERC20Params,
7
+ MOCK_ERC20_ABI,
8
+ } from '@nadohq/contracts';
9
+ import { toBigInt, WalletNotProvidedError } from '@nadohq/utils';
10
+ import { BaseSpotAPI } from './BaseSpotAPI';
11
+ import {
12
+ ApproveAllowanceParams,
13
+ BurnVlpParams,
14
+ MintVlpParams,
15
+ TransferQuoteParams,
16
+ WithdrawCollateralParams,
17
+ } from './types';
18
+
19
+ export class SpotExecuteAPI extends BaseSpotAPI {
20
+ async deposit(params: DepositCollateralParams) {
21
+ return depositCollateral({
22
+ endpoint: this.context.contracts.endpoint,
23
+ subaccountName: params.subaccountName,
24
+ productId: params.productId,
25
+ amount: params.amount,
26
+ referralCode: params.referralCode,
27
+ });
28
+ }
29
+
30
+ async withdraw(params: WithdrawCollateralParams) {
31
+ return this.context.engineClient.withdrawCollateral({
32
+ ...params,
33
+ subaccountOwner: this.getSubaccountOwnerIfNeeded(params),
34
+ chainId: this.getWalletClientChainIdIfNeeded(params),
35
+ verifyingAddr: params.verifyingAddr ?? this.getEndpointAddress(),
36
+ });
37
+ }
38
+
39
+ async approveAllowance(params: ApproveAllowanceParams) {
40
+ const tokenContract = await this.getTokenContractForProduct(params);
41
+ if (!isWriteableContract(tokenContract)) {
42
+ throw new Error(
43
+ 'Token contract does not permit writes. Is a wallet client provided?',
44
+ );
45
+ }
46
+
47
+ return approveDepositAllowance({
48
+ amount: params.amount,
49
+ endpoint: this.context.contracts.endpoint,
50
+ tokenContract,
51
+ });
52
+ }
53
+
54
+ /**
55
+ * Transfers quote between subaccounts under the same wallet.
56
+ *
57
+ * @param params
58
+ */
59
+ async transferQuote(params: TransferQuoteParams) {
60
+ return this.context.engineClient.transferQuote({
61
+ ...params,
62
+ subaccountOwner: this.getSubaccountOwnerIfNeeded(params),
63
+ verifyingAddr: params.verifyingAddr ?? this.getEndpointAddress(),
64
+ chainId: this.getWalletClientChainIdIfNeeded(params),
65
+ });
66
+ }
67
+
68
+ async mintVlp(params: MintVlpParams) {
69
+ return this.context.engineClient.mintVlp({
70
+ ...params,
71
+ subaccountOwner: this.getSubaccountOwnerIfNeeded(params),
72
+ chainId: this.getWalletClientChainIdIfNeeded(params),
73
+ verifyingAddr: params.verifyingAddr ?? this.getEndpointAddress(),
74
+ });
75
+ }
76
+
77
+ async burnVlp(params: BurnVlpParams) {
78
+ return this.context.engineClient.burnVlp({
79
+ ...params,
80
+ subaccountOwner: this.getSubaccountOwnerIfNeeded(params),
81
+ chainId: this.getWalletClientChainIdIfNeeded(params),
82
+ verifyingAddr: params.verifyingAddr ?? this.getEndpointAddress(),
83
+ });
84
+ }
85
+
86
+ async _mintMockERC20(params: MintMockERC20Params) {
87
+ if (!this.context.walletClient) {
88
+ throw new WalletNotProvidedError();
89
+ }
90
+
91
+ const config = await this.context.contracts.spotEngine.read.getConfig([
92
+ params.productId,
93
+ ]);
94
+
95
+ return this.context.walletClient.writeContract({
96
+ abi: MOCK_ERC20_ABI,
97
+ address: config.token,
98
+ functionName: 'mint',
99
+ args: [this.getWalletClientAddress(), toBigInt(params.amount)],
100
+ });
101
+ }
102
+ }
@@ -0,0 +1,53 @@
1
+ import {
2
+ GetEngineMaxMintVlpAmountParams,
3
+ GetEngineMaxWithdrawableParams,
4
+ } from '@nadohq/engine-client';
5
+ import { BigDecimal, getValidatedAddress, toBigDecimal } from '@nadohq/utils';
6
+ import { BaseSpotAPI } from './BaseSpotAPI';
7
+ import { GetTokenAllowanceParams, GetTokenWalletBalanceParams } from './types';
8
+
9
+ export class SpotQueryAPI extends BaseSpotAPI {
10
+ /**
11
+ * Gets the estimated max withdrawable amount for a product
12
+ * @param params
13
+ */
14
+ async getMaxWithdrawable(params: GetEngineMaxWithdrawableParams) {
15
+ return this.context.engineClient.getMaxWithdrawable(params);
16
+ }
17
+
18
+ /**
19
+ * Queries engine to determine maximum quote amount for minting VLP.
20
+ *
21
+ * @param params
22
+ */
23
+ async getMaxMintVlpAmount(params: GetEngineMaxMintVlpAmountParams) {
24
+ return this.context.engineClient.getMaxMintVlpAmount(params);
25
+ }
26
+
27
+ /**
28
+ * Helper to get current token balance in the user's wallet (i.e. not in a Nado subaccount)
29
+ */
30
+ async getTokenWalletBalance({
31
+ address,
32
+ ...rest
33
+ }: GetTokenWalletBalanceParams): Promise<bigint> {
34
+ const token = await this.getTokenContractForProduct(rest);
35
+ return token.read.balanceOf([getValidatedAddress(address)]);
36
+ }
37
+
38
+ /**
39
+ * Helper to get current token allowance
40
+ */
41
+ async getTokenAllowance({
42
+ address,
43
+ ...rest
44
+ }: GetTokenAllowanceParams): Promise<BigDecimal> {
45
+ const token = await this.getTokenContractForProduct(rest);
46
+ return toBigDecimal(
47
+ await token.read.allowance([
48
+ getValidatedAddress(address),
49
+ this.getEndpointAddress(),
50
+ ]),
51
+ );
52
+ }
53
+ }
@@ -0,0 +1,10 @@
1
+ import { Mixin } from 'ts-mixer';
2
+ import { SpotExecuteAPI } from './SpotExecuteAPI';
3
+ import { SpotQueryAPI } from './SpotQueryAPI';
4
+
5
+ /**
6
+ * Combined Spot trading API providing both execution and query functionality
7
+ */
8
+ export class SpotAPI extends Mixin(SpotExecuteAPI, SpotQueryAPI) {}
9
+
10
+ export * from './types';