@strkfarm/sdk 2.0.0-dev.9 → 2.0.0-staging.2
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/index.browser.global.js +111371 -93151
- package/dist/index.browser.mjs +27815 -32690
- package/dist/index.d.ts +1095 -2011
- package/dist/index.js +27425 -32309
- package/dist/index.mjs +27590 -32452
- package/package.json +6 -5
- package/src/data/ekubo-price-fethcer.abi.json +265 -0
- package/src/data/universal-vault.abi.json +20 -135
- package/src/dataTypes/address.ts +0 -7
- package/src/dataTypes/index.ts +3 -2
- package/src/dataTypes/mynumber.ts +141 -0
- package/src/global.ts +296 -288
- package/src/index.browser.ts +6 -5
- package/src/interfaces/common.tsx +324 -184
- package/src/modules/apollo-client-config.ts +28 -0
- package/src/modules/avnu.ts +4 -17
- package/src/modules/ekubo-pricer.ts +79 -0
- package/src/modules/ekubo-quoter.ts +11 -88
- package/src/modules/erc20.ts +21 -67
- package/src/modules/harvests.ts +26 -15
- package/src/modules/index.ts +11 -13
- package/src/modules/lst-apr.ts +0 -36
- package/src/modules/pragma.ts +23 -8
- package/src/modules/pricer-from-api.ts +150 -14
- package/src/modules/pricer.ts +2 -1
- package/src/modules/pricerBase.ts +2 -1
- package/src/node/deployer.ts +36 -1
- package/src/node/pricer-redis.ts +2 -1
- package/src/strategies/autoCompounderStrk.ts +1 -1
- package/src/strategies/base-strategy.ts +5 -22
- package/src/strategies/ekubo-cl-vault.tsx +2904 -2175
- package/src/strategies/factory.ts +165 -0
- package/src/strategies/index.ts +10 -11
- package/src/strategies/registry.ts +268 -0
- package/src/strategies/sensei.ts +416 -292
- package/src/strategies/universal-adapters/adapter-utils.ts +1 -5
- package/src/strategies/universal-adapters/baseAdapter.ts +153 -181
- package/src/strategies/universal-adapters/common-adapter.ts +77 -98
- package/src/strategies/universal-adapters/index.ts +1 -5
- package/src/strategies/universal-adapters/vesu-adapter.ts +218 -220
- package/src/strategies/universal-adapters/vesu-supply-only-adapter.ts +51 -58
- package/src/strategies/universal-lst-muliplier-strategy.tsx +1952 -992
- package/src/strategies/universal-strategy.tsx +1713 -1150
- package/src/strategies/vesu-rebalance.tsx +1189 -986
- package/src/utils/health-factor-math.ts +5 -11
- package/src/utils/index.ts +8 -9
- package/src/utils/strategy-utils.ts +57 -0
- package/src/data/extended-deposit.abi.json +0 -3613
- package/src/modules/ExtendedWrapperSDk/index.ts +0 -62
- package/src/modules/ExtendedWrapperSDk/types.ts +0 -311
- package/src/modules/ExtendedWrapperSDk/wrapper.ts +0 -395
- package/src/modules/midas.ts +0 -159
- package/src/modules/token-market-data.ts +0 -202
- package/src/strategies/svk-strategy.ts +0 -247
- package/src/strategies/universal-adapters/adapter-optimizer.ts +0 -65
- package/src/strategies/universal-adapters/avnu-adapter.ts +0 -413
- package/src/strategies/universal-adapters/extended-adapter.ts +0 -972
- package/src/strategies/universal-adapters/unused-balance-adapter.ts +0 -109
- package/src/strategies/universal-adapters/vesu-multiply-adapter.ts +0 -1306
- package/src/strategies/vesu-extended-strategy/services/operationService.ts +0 -34
- package/src/strategies/vesu-extended-strategy/utils/config.runtime.ts +0 -77
- package/src/strategies/vesu-extended-strategy/utils/constants.ts +0 -49
- package/src/strategies/vesu-extended-strategy/utils/helper.ts +0 -370
- package/src/strategies/vesu-extended-strategy/vesu-extended-strategy.tsx +0 -1379
|
@@ -1,395 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ExtendedWrapper - TypeScript wrapper for Extended Exchange API
|
|
3
|
-
* Provides a clean interface to interact with the Extended Exchange trading API
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
CreateOrderRequest,
|
|
8
|
-
WithdrawRequest,
|
|
9
|
-
SignedWithdrawRequest,
|
|
10
|
-
CancelOrderRequest,
|
|
11
|
-
PlacedOrder,
|
|
12
|
-
OpenOrder,
|
|
13
|
-
Position,
|
|
14
|
-
Balance,
|
|
15
|
-
Market,
|
|
16
|
-
MarketStats,
|
|
17
|
-
AssetOperation,
|
|
18
|
-
ExtendedApiResponse,
|
|
19
|
-
ExtendedWrapperConfig,
|
|
20
|
-
OrderSide,
|
|
21
|
-
TimeInForce,
|
|
22
|
-
AssetOperationType,
|
|
23
|
-
AssetOperationStatus,
|
|
24
|
-
FundingRate,
|
|
25
|
-
UpdateLeverageRequest,
|
|
26
|
-
} from "./types";
|
|
27
|
-
|
|
28
|
-
export class ExtendedWrapper {
|
|
29
|
-
private baseUrl: string;
|
|
30
|
-
private apiKey?: string;
|
|
31
|
-
private timeout: number;
|
|
32
|
-
private retries: number;
|
|
33
|
-
|
|
34
|
-
constructor(config: ExtendedWrapperConfig) {
|
|
35
|
-
this.baseUrl = config.baseUrl.replace(/\/$/, ""); // Remove trailing slash
|
|
36
|
-
this.apiKey = config.apiKey;
|
|
37
|
-
this.timeout = config.timeout || 30000; // 30 seconds default
|
|
38
|
-
this.retries = config.retries || 3;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Make HTTP request with retry logic and error handling
|
|
43
|
-
*/
|
|
44
|
-
private async makeRequest<T>(
|
|
45
|
-
endpoint: string,
|
|
46
|
-
options: RequestInit = {}
|
|
47
|
-
): Promise<ExtendedApiResponse<T>> {
|
|
48
|
-
const url = `${this.baseUrl}${endpoint}`;
|
|
49
|
-
|
|
50
|
-
const headers: Record<string, any> = {
|
|
51
|
-
"Content-Type": "application/json",
|
|
52
|
-
...options.headers,
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
if (this.apiKey) {
|
|
56
|
-
headers["X-API-Key"] = this.apiKey;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const requestOptions: RequestInit = {
|
|
60
|
-
...options,
|
|
61
|
-
headers,
|
|
62
|
-
signal: AbortSignal.timeout(this.timeout),
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
let lastError: Error | null = null;
|
|
66
|
-
|
|
67
|
-
for (let attempt = 1; attempt <= this.retries; attempt++) {
|
|
68
|
-
try {
|
|
69
|
-
const response = await fetch(url, requestOptions);
|
|
70
|
-
|
|
71
|
-
if (!response.ok) {
|
|
72
|
-
const errorData = await response.json().catch(() => ({}));
|
|
73
|
-
throw new Error(
|
|
74
|
-
`HTTP ${response.status}: ${
|
|
75
|
-
errorData.detail || response.statusText
|
|
76
|
-
}`
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const data = await response.json();
|
|
81
|
-
return data;
|
|
82
|
-
} catch (error) {
|
|
83
|
-
lastError = error as Error;
|
|
84
|
-
|
|
85
|
-
if (attempt < this.retries) {
|
|
86
|
-
// Exponential backoff
|
|
87
|
-
const delay = Math.pow(2, attempt) * 1000;
|
|
88
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
throw lastError || new Error("Request failed after all retries");
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Create a new order on Extended Exchange
|
|
98
|
-
*/
|
|
99
|
-
async createOrder(
|
|
100
|
-
request: CreateOrderRequest
|
|
101
|
-
): Promise<ExtendedApiResponse<PlacedOrder>> {
|
|
102
|
-
return this.makeRequest<PlacedOrder>("/api/v1/orders", {
|
|
103
|
-
method: "POST",
|
|
104
|
-
body: JSON.stringify(request),
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Get all markets
|
|
110
|
-
*/
|
|
111
|
-
async getMarkets(
|
|
112
|
-
marketNames?: string
|
|
113
|
-
): Promise<ExtendedApiResponse<Market[]>> {
|
|
114
|
-
const params = marketNames
|
|
115
|
-
? `?market_names=${encodeURIComponent(marketNames)}`
|
|
116
|
-
: "";
|
|
117
|
-
return this.makeRequest<Market[]>(`/api/v1/markets${params}`);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
*
|
|
122
|
-
* @param orderId - The ID of the order to get
|
|
123
|
-
* @returns The order
|
|
124
|
-
*/
|
|
125
|
-
async getOrderByOrderId(orderId: string): Promise<ExtendedApiResponse<OpenOrder>> {
|
|
126
|
-
const orderIdInt = parseInt(orderId);
|
|
127
|
-
return this.makeRequest<OpenOrder>(`/api/v1/orderId/${orderIdInt}`);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Get market statistics for a specific market
|
|
132
|
-
*/
|
|
133
|
-
async getMarketStatistics(
|
|
134
|
-
marketName: string
|
|
135
|
-
): Promise<ExtendedApiResponse<MarketStats>> {
|
|
136
|
-
return this.makeRequest<MarketStats>(
|
|
137
|
-
`/api/v1/markets/statistics?market_name=${encodeURIComponent(marketName)}`
|
|
138
|
-
);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Get current trading positions
|
|
143
|
-
*/
|
|
144
|
-
async getPositions(
|
|
145
|
-
marketNames?: string
|
|
146
|
-
): Promise<ExtendedApiResponse<Position[]>> {
|
|
147
|
-
const params = marketNames
|
|
148
|
-
? `?market_names=${encodeURIComponent(marketNames)}`
|
|
149
|
-
: "";
|
|
150
|
-
return this.makeRequest<Position[]>(`/api/v1/positions${params}`);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Get account balance and holdings
|
|
155
|
-
*/
|
|
156
|
-
async getHoldings(): Promise<ExtendedApiResponse<Balance>> {
|
|
157
|
-
return this.makeRequest<Balance>("/api/v1/holdings");
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Initiate a withdrawal from Extended Exchange
|
|
162
|
-
*/
|
|
163
|
-
async withdraw(
|
|
164
|
-
request: WithdrawRequest
|
|
165
|
-
): Promise<ExtendedApiResponse<number>> {
|
|
166
|
-
return this.makeRequest<number>("/api/v1/withdraw", {
|
|
167
|
-
method: "POST",
|
|
168
|
-
body: JSON.stringify(request),
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Create and sign a withdrawal request hash
|
|
174
|
-
*/
|
|
175
|
-
async signWithdrawalRequest(request: SignedWithdrawRequest): Promise<
|
|
176
|
-
ExtendedApiResponse<{
|
|
177
|
-
withdraw_request_hash: string;
|
|
178
|
-
signature: {
|
|
179
|
-
r: string;
|
|
180
|
-
s: string;
|
|
181
|
-
};
|
|
182
|
-
}>
|
|
183
|
-
> {
|
|
184
|
-
return this.makeRequest("/api/v1/withdraw/sign", {
|
|
185
|
-
method: "POST",
|
|
186
|
-
body: JSON.stringify(request),
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Cancel an existing order
|
|
192
|
-
*/
|
|
193
|
-
async cancelOrder(
|
|
194
|
-
request: CancelOrderRequest
|
|
195
|
-
): Promise<ExtendedApiResponse<{}>> {
|
|
196
|
-
return this.makeRequest<{}>("/api/v1/orders/cancel", {
|
|
197
|
-
method: "POST",
|
|
198
|
-
body: JSON.stringify(request),
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* Get all open orders
|
|
205
|
-
*/
|
|
206
|
-
async getOpenOrders(
|
|
207
|
-
marketName?: string
|
|
208
|
-
): Promise<ExtendedApiResponse<OpenOrder[]>> {
|
|
209
|
-
const endpoint = marketName
|
|
210
|
-
? `/api/v1/marketOrders/${marketName}`
|
|
211
|
-
: "/api/v1/marketOrders";
|
|
212
|
-
return this.makeRequest<OpenOrder[]>(endpoint,{
|
|
213
|
-
method: "GET",
|
|
214
|
-
headers: {
|
|
215
|
-
"Content-Type": "application/json",
|
|
216
|
-
},
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Update leverage on the market
|
|
222
|
-
* @param request
|
|
223
|
-
* @returns
|
|
224
|
-
*/
|
|
225
|
-
async updateLeverage(
|
|
226
|
-
request: UpdateLeverageRequest
|
|
227
|
-
): Promise<ExtendedApiResponse<{}>> {
|
|
228
|
-
return this.makeRequest<{}>("/api/v1/leverage", {
|
|
229
|
-
method: "POST",
|
|
230
|
-
body: JSON.stringify(request),
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Get asset operations with optional filtering
|
|
236
|
-
*/
|
|
237
|
-
async getAssetOperations(
|
|
238
|
-
options: {
|
|
239
|
-
id?: number;
|
|
240
|
-
operationsType?: AssetOperationType[];
|
|
241
|
-
operationsStatus?: AssetOperationStatus[];
|
|
242
|
-
startTime?: number;
|
|
243
|
-
endTime?: number;
|
|
244
|
-
cursor?: number;
|
|
245
|
-
limit?: number;
|
|
246
|
-
} = {}
|
|
247
|
-
): Promise<ExtendedApiResponse<AssetOperation[]>> {
|
|
248
|
-
const params = new URLSearchParams();
|
|
249
|
-
|
|
250
|
-
if (options.id !== undefined) params.append("id", options.id.toString());
|
|
251
|
-
if (options.operationsType) {
|
|
252
|
-
params.append("operations_type", options.operationsType.join(","));
|
|
253
|
-
}
|
|
254
|
-
if (options.operationsStatus) {
|
|
255
|
-
params.append("operations_status", options.operationsStatus.join(","));
|
|
256
|
-
}
|
|
257
|
-
if (options.startTime !== undefined)
|
|
258
|
-
params.append("start_time", options.startTime.toString());
|
|
259
|
-
if (options.endTime !== undefined)
|
|
260
|
-
params.append("end_time", options.endTime.toString());
|
|
261
|
-
if (options.cursor !== undefined)
|
|
262
|
-
params.append("cursor", options.cursor.toString());
|
|
263
|
-
if (options.limit !== undefined)
|
|
264
|
-
params.append("limit", options.limit.toString());
|
|
265
|
-
|
|
266
|
-
const queryString = params.toString();
|
|
267
|
-
const endpoint = `/api/v1/asset-operations${
|
|
268
|
-
queryString ? `?${queryString}` : ""
|
|
269
|
-
}`;
|
|
270
|
-
|
|
271
|
-
return this.makeRequest<AssetOperation[]>(endpoint);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Health check endpoint
|
|
276
|
-
*/
|
|
277
|
-
async healthCheck(): Promise<ExtendedApiResponse<MarketStats>> {
|
|
278
|
-
return this.makeRequest<MarketStats>("/api/v1/health");
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* Convenience method to create a buy order
|
|
283
|
-
*/
|
|
284
|
-
async createBuyOrder(
|
|
285
|
-
marketName: string,
|
|
286
|
-
amount: string,
|
|
287
|
-
price: string,
|
|
288
|
-
options: {
|
|
289
|
-
postOnly?: boolean;
|
|
290
|
-
previousOrderId?: number;
|
|
291
|
-
externalId?: string;
|
|
292
|
-
timeInForce?: TimeInForce;
|
|
293
|
-
} = {}
|
|
294
|
-
): Promise<ExtendedApiResponse<PlacedOrder>> {
|
|
295
|
-
return this.createOrder({
|
|
296
|
-
market_name: marketName,
|
|
297
|
-
amount,
|
|
298
|
-
price,
|
|
299
|
-
side: OrderSide.BUY,
|
|
300
|
-
...options,
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/**
|
|
305
|
-
* Get order by ID
|
|
306
|
-
* @param orderId - The ID of the order to get
|
|
307
|
-
* @returns The order
|
|
308
|
-
*/
|
|
309
|
-
async getOrderById(orderId: number): Promise<ExtendedApiResponse<OpenOrder>> {
|
|
310
|
-
return this.makeRequest<OpenOrder>(`/api/v1/orderId/${orderId}`);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* Convenience method to create a sell order
|
|
315
|
-
*/
|
|
316
|
-
async createSellOrder(
|
|
317
|
-
marketName: string,
|
|
318
|
-
amount: string,
|
|
319
|
-
price: string,
|
|
320
|
-
options: {
|
|
321
|
-
postOnly?: boolean;
|
|
322
|
-
previousOrderId?: number;
|
|
323
|
-
externalId?: string;
|
|
324
|
-
timeInForce?: TimeInForce;
|
|
325
|
-
} = {}
|
|
326
|
-
): Promise<ExtendedApiResponse<PlacedOrder>> {
|
|
327
|
-
return this.createOrder({
|
|
328
|
-
market_name: marketName,
|
|
329
|
-
amount,
|
|
330
|
-
price,
|
|
331
|
-
side: OrderSide.SELL,
|
|
332
|
-
...options,
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
* Get positions for a specific market
|
|
338
|
-
*/
|
|
339
|
-
async getPositionsForMarket(
|
|
340
|
-
marketName: string
|
|
341
|
-
): Promise<ExtendedApiResponse<Position[]>> {
|
|
342
|
-
return this.getPositions(marketName);
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
/**
|
|
346
|
-
* Get open orders for a specific market
|
|
347
|
-
*/
|
|
348
|
-
async getOpenOrdersForMarket(
|
|
349
|
-
marketName: string
|
|
350
|
-
): Promise<ExtendedApiResponse<OpenOrder[]>> {
|
|
351
|
-
return this.getOpenOrders(marketName);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
/**
|
|
355
|
-
* Cancel order by ID (convenience method)
|
|
356
|
-
*/
|
|
357
|
-
async cancelOrderById(orderId: number): Promise<ExtendedApiResponse<{}>> {
|
|
358
|
-
return this.cancelOrder({ order_id: orderId });
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
* Get order history for a specific market
|
|
363
|
-
* @param marketName - The name of the market to get order history for
|
|
364
|
-
* @returns The order history for the specified market
|
|
365
|
-
*/
|
|
366
|
-
async getOrderHistory(marketName: string): Promise<ExtendedApiResponse<OpenOrder[]>> {
|
|
367
|
-
return this.makeRequest<OpenOrder[]>(`/api/v1/marketOrders/${marketName}`);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
/**
|
|
371
|
-
* Withdraw USDC (convenience method)
|
|
372
|
-
*/
|
|
373
|
-
async withdrawUSDC(amount: string): Promise<ExtendedApiResponse<number>> {
|
|
374
|
-
return this.withdraw({ amount, asset: "USDC" });
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
/**
|
|
378
|
-
* Get funding rates for a specific market
|
|
379
|
-
* @param marketName - The name of the market to get funding rates for
|
|
380
|
-
* @returns The funding rates for the specified market
|
|
381
|
-
*/
|
|
382
|
-
async getFundingRates(
|
|
383
|
-
marketName: string,
|
|
384
|
-
side: string
|
|
385
|
-
): Promise<ExtendedApiResponse<FundingRate[]>> {
|
|
386
|
-
return this.makeRequest<FundingRate[]>(
|
|
387
|
-
`/api/v1/markets/funding-rates?market_name=${encodeURIComponent(
|
|
388
|
-
marketName
|
|
389
|
-
)}&side=${encodeURIComponent(side)}`
|
|
390
|
-
);
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
export default ExtendedWrapper;
|
package/src/modules/midas.ts
DELETED
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
|
-
import { ContractAddr } from '../dataTypes';
|
|
3
|
-
import { logger } from '../utils/logger';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Midas module for interacting with Midas API
|
|
7
|
-
* Provides functions to get APY, price, and TVL data for Midas tokens
|
|
8
|
-
*/
|
|
9
|
-
export class Midas {
|
|
10
|
-
// Static mapping of contract addresses to Midas API symbols
|
|
11
|
-
private static readonly CONTRACT_TO_SYMBOL: Record<string, string> = {
|
|
12
|
-
'0x4e4fb1a9ca7e84bae609b9dc0078ad7719e49187ae7e425bb47d131710eddac': 'mre7btc', // mRe7BTC
|
|
13
|
-
'0x4be8945e61dc3e19ebadd1579a6bd53b262f51ba89e6f8b0c4bc9a7e3c633fc': 'mre7', // mRe7YIELD
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
private static readonly BASE_URL = 'https://api-prod.midas.app/api/data';
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Check if a contract address is supported by Midas
|
|
20
|
-
* @param contractAddr The contract address to check
|
|
21
|
-
* @returns True if the contract address is supported
|
|
22
|
-
*/
|
|
23
|
-
static isSupported(contractAddr: ContractAddr): boolean {
|
|
24
|
-
return contractAddr.address in Midas.CONTRACT_TO_SYMBOL;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Get the Midas symbol for a given contract address
|
|
29
|
-
* @param contractAddr The contract address to look up
|
|
30
|
-
* @returns The Midas symbol for the contract
|
|
31
|
-
* @throws Error if contract address is not found
|
|
32
|
-
*/
|
|
33
|
-
static getSymbolFromContract(contractAddr: ContractAddr): string {
|
|
34
|
-
const symbol = Midas.CONTRACT_TO_SYMBOL[contractAddr.address];
|
|
35
|
-
if (!symbol) {
|
|
36
|
-
throw new Error(`Contract address ${contractAddr.address} not found in Midas mapping`);
|
|
37
|
-
}
|
|
38
|
-
return symbol;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Get APY data for all Midas tokens
|
|
43
|
-
* @returns Object with token symbols as keys and APY values as numbers
|
|
44
|
-
* @throws Error if API request fails
|
|
45
|
-
*/
|
|
46
|
-
static async getAPYs(): Promise<Record<string, number>> {
|
|
47
|
-
try {
|
|
48
|
-
const response = await axios.get(`${Midas.BASE_URL}/apys`);
|
|
49
|
-
return response.data;
|
|
50
|
-
} catch (error) {
|
|
51
|
-
logger.error('Failed to fetch APYs from Midas API:', error);
|
|
52
|
-
throw new Error(`Failed to fetch APYs: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Get APY for a specific token by contract address
|
|
58
|
-
* @param contractAddr The contract address of the token
|
|
59
|
-
* @returns The APY value for the token
|
|
60
|
-
* @throws Error if contract address not found or API request fails
|
|
61
|
-
*/
|
|
62
|
-
static async getAPY(contractAddr: ContractAddr): Promise<number> {
|
|
63
|
-
const symbol = Midas.getSymbolFromContract(contractAddr);
|
|
64
|
-
const apys = await Midas.getAPYs();
|
|
65
|
-
|
|
66
|
-
if (!(symbol in apys)) {
|
|
67
|
-
throw new Error(`Symbol ${symbol} not found in APY data`);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return apys[symbol];
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Get price data for a specific token
|
|
75
|
-
* @param contractAddr The contract address of the token
|
|
76
|
-
* @param timestampFrom Optional start timestamp (defaults to 30 days ago)
|
|
77
|
-
* @param timestampTo Optional end timestamp (defaults to now)
|
|
78
|
-
* @param environment Environment (defaults to 'mainnet')
|
|
79
|
-
* @returns The latest price for the token
|
|
80
|
-
* @throws Error if contract address not found or API request fails
|
|
81
|
-
*/
|
|
82
|
-
static async getPrice(
|
|
83
|
-
contractAddr: ContractAddr,
|
|
84
|
-
timestampFrom?: number,
|
|
85
|
-
timestampTo?: number,
|
|
86
|
-
environment: string = 'mainnet'
|
|
87
|
-
): Promise<number> {
|
|
88
|
-
const symbol = Midas.getSymbolFromContract(contractAddr);
|
|
89
|
-
|
|
90
|
-
// Default to 30 days ago if not provided
|
|
91
|
-
const from = timestampFrom ?? Math.floor(Date.now() / 1000) - (30 * 24 * 60 * 60);
|
|
92
|
-
// Default to now if not provided
|
|
93
|
-
const to = timestampTo ?? Math.floor(Date.now() / 1000);
|
|
94
|
-
|
|
95
|
-
try {
|
|
96
|
-
const response = await axios.get(`${Midas.BASE_URL}/${symbol}/price`, {
|
|
97
|
-
params: {
|
|
98
|
-
timestampFrom: from,
|
|
99
|
-
timestampTo: to,
|
|
100
|
-
environment
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
const priceData = response.data;
|
|
105
|
-
if (!Array.isArray(priceData) || priceData.length === 0) {
|
|
106
|
-
throw new Error(`No price data found for ${symbol}`);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Return the latest price (first item in the array)
|
|
110
|
-
return priceData[0].price;
|
|
111
|
-
} catch (error) {
|
|
112
|
-
logger.error(`Failed to fetch price for ${symbol}:`, error);
|
|
113
|
-
throw new Error(`Failed to fetch price for ${symbol}: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Get TVL data for all tokens
|
|
119
|
-
* @param environment Environment (defaults to 'mainnet')
|
|
120
|
-
* @returns Object with TVL data including totalTvl and tokenTvl
|
|
121
|
-
* @throws Error if API request fails
|
|
122
|
-
*/
|
|
123
|
-
static async getTVLData(environment: string = 'mainnet'): Promise<{
|
|
124
|
-
lastUpdatedAt: string;
|
|
125
|
-
totalTvl: number;
|
|
126
|
-
tokenTvl: Record<string, any>;
|
|
127
|
-
}> {
|
|
128
|
-
try {
|
|
129
|
-
const response = await axios.get(`${Midas.BASE_URL}/tvl`, {
|
|
130
|
-
params: { environment }
|
|
131
|
-
});
|
|
132
|
-
return response.data;
|
|
133
|
-
} catch (error) {
|
|
134
|
-
logger.error('Failed to fetch TVL data from Midas API:', error);
|
|
135
|
-
throw new Error(`Failed to fetch TVL data: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Get TVL for a specific token by contract address
|
|
141
|
-
* @param contractAddr The contract address of the token
|
|
142
|
-
* @param environment Environment (defaults to 'mainnet')
|
|
143
|
-
* @returns The TVL data for the token (USD and native amounts)
|
|
144
|
-
* @throws Error if contract address not found or API request fails
|
|
145
|
-
*/
|
|
146
|
-
static async getTVL(
|
|
147
|
-
contractAddr: ContractAddr,
|
|
148
|
-
environment: string = 'mainnet'
|
|
149
|
-
): Promise<{ usd: number; native: number } | number> {
|
|
150
|
-
const symbol = Midas.getSymbolFromContract(contractAddr);
|
|
151
|
-
const tvlData = await Midas.getTVLData(environment);
|
|
152
|
-
|
|
153
|
-
if (!(symbol in tvlData.tokenTvl)) {
|
|
154
|
-
throw new Error(`Symbol ${symbol} not found in TVL data`);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return tvlData.tokenTvl[symbol];
|
|
158
|
-
}
|
|
159
|
-
}
|