@strkfarm/sdk 2.0.0-staging.69 → 2.0.0-staging.70
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 +148 -48
- package/dist/index.browser.mjs +164 -63
- package/dist/index.d.ts +29 -3
- package/dist/index.js +166 -63
- package/dist/index.mjs +165 -63
- package/package.json +1 -1
- package/src/global.ts +5 -0
- package/src/interfaces/common.tsx +1 -0
- package/src/modules/index.ts +1 -0
- package/src/modules/pricer-avnu-api.ts +114 -0
- package/src/modules/pricer.ts +63 -45
- package/src/node/pricer-redis.ts +1 -0
- package/src/strategies/ekubo-cl-vault.tsx +4 -1
- package/src/strategies/universal-strategy.tsx +4 -1
- package/src/strategies/yoloVault.ts +4 -1
package/src/modules/pricer.ts
CHANGED
|
@@ -7,12 +7,23 @@ import { PricerBase } from "./pricerBase";
|
|
|
7
7
|
import { logger } from "@/utils/logger";
|
|
8
8
|
import { AvnuWrapper } from "./avnu";
|
|
9
9
|
import { BlockIdentifier } from "starknet";
|
|
10
|
+
import { PricerAvnuApi } from "./pricer-avnu-api";
|
|
10
11
|
|
|
11
12
|
export interface PriceInfo {
|
|
12
13
|
price: number,
|
|
13
14
|
timestamp: Date
|
|
14
15
|
}
|
|
15
16
|
|
|
17
|
+
type PriceMethod = 'AvnuApi' | 'Coinbase' | 'Coinmarketcap' | 'Ekubo' | 'Avnu';
|
|
18
|
+
|
|
19
|
+
const PRICE_METHOD_PRIORITY: PriceMethod[] = [
|
|
20
|
+
'AvnuApi',
|
|
21
|
+
'Coinbase',
|
|
22
|
+
'Coinmarketcap',
|
|
23
|
+
'Ekubo',
|
|
24
|
+
'Avnu',
|
|
25
|
+
];
|
|
26
|
+
|
|
16
27
|
export class Pricer extends PricerBase {
|
|
17
28
|
protected prices: {
|
|
18
29
|
[key: string]: PriceInfo
|
|
@@ -21,9 +32,11 @@ export class Pricer extends PricerBase {
|
|
|
21
32
|
refreshInterval = 30000;
|
|
22
33
|
staleTime = 60000;
|
|
23
34
|
|
|
35
|
+
protected readonly avnuApiPricer: PricerAvnuApi;
|
|
36
|
+
|
|
24
37
|
// code populates this map during runtime to determine which method to use for a given token
|
|
25
38
|
// The method set will be the first one to try after first attempt
|
|
26
|
-
protected methodToUse: {[tokenSymbol: string]:
|
|
39
|
+
protected methodToUse: {[tokenSymbol: string]: PriceMethod} = {};
|
|
27
40
|
|
|
28
41
|
/**
|
|
29
42
|
* TOKENA and TOKENB are the two token names to get price of TokenA in terms of TokenB
|
|
@@ -36,6 +49,7 @@ export class Pricer extends PricerBase {
|
|
|
36
49
|
super(config, tokens);
|
|
37
50
|
this.refreshInterval = refreshInterval;
|
|
38
51
|
this.staleTime = staleTime;
|
|
52
|
+
this.avnuApiPricer = new PricerAvnuApi(config, tokens);
|
|
39
53
|
}
|
|
40
54
|
|
|
41
55
|
isReady() {
|
|
@@ -69,6 +83,7 @@ export class Pricer extends PricerBase {
|
|
|
69
83
|
}
|
|
70
84
|
|
|
71
85
|
start() {
|
|
86
|
+
this.avnuApiPricer.start();
|
|
72
87
|
this._loadPrices();
|
|
73
88
|
setInterval(() => {
|
|
74
89
|
this._loadPrices();
|
|
@@ -96,6 +111,9 @@ export class Pricer extends PricerBase {
|
|
|
96
111
|
let retry = 0;
|
|
97
112
|
while (retry < MAX_RETRIES) {
|
|
98
113
|
try {
|
|
114
|
+
if (token.dontPrice) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
99
117
|
if (token.symbol === 'USDT' || token.symbol === 'USDC') {
|
|
100
118
|
this.prices[token.symbol] = {
|
|
101
119
|
price: 1,
|
|
@@ -145,56 +163,56 @@ export class Pricer extends PricerBase {
|
|
|
145
163
|
}
|
|
146
164
|
}
|
|
147
165
|
|
|
148
|
-
async _getPrice(token: TokenInfo
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
166
|
+
async _getPrice(token: TokenInfo): Promise<number> {
|
|
167
|
+
const pinned = this.methodToUse[token.symbol];
|
|
168
|
+
if (pinned) {
|
|
169
|
+
logger.verbose(`Fetching price of ${token.symbol} using pinned ${pinned}`);
|
|
170
|
+
try {
|
|
171
|
+
return await this._tryPriceMethod(token, pinned);
|
|
172
|
+
} catch (error: any) {
|
|
173
|
+
console.warn(`${pinned}: pinned price failed [${token.symbol}]: `, error.message);
|
|
174
|
+
delete this.methodToUse[token.symbol];
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
for (const method of PRICE_METHOD_PRIORITY) {
|
|
179
|
+
logger.verbose(`Fetching price of ${token.symbol} using ${method}`);
|
|
180
|
+
try {
|
|
181
|
+
const result = await this._tryPriceMethod(token, method);
|
|
182
|
+
this.methodToUse[token.symbol] = method;
|
|
183
|
+
return result;
|
|
184
|
+
} catch (error: any) {
|
|
185
|
+
console.warn(`${method}: price err [${token.symbol}]: `, error.message);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
throw new FatalError(`Price not found for ${token.symbol}`);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
protected async _tryPriceMethod(token: TokenInfo, method: PriceMethod): Promise<number> {
|
|
193
|
+
switch (method) {
|
|
194
|
+
case 'AvnuApi':
|
|
195
|
+
return await this._getPriceAvnuApi(token);
|
|
152
196
|
case 'Coinbase':
|
|
153
|
-
|
|
154
|
-
// const result = await this._getPriceCoinbase(token);
|
|
155
|
-
// this.methodToUse[token.symbol] = 'Coinbase';
|
|
156
|
-
// return result;
|
|
157
|
-
// } catch (error: any) {
|
|
158
|
-
// console.warn(`Coinbase: price err: message [${token.symbol}]: `, error.message);
|
|
159
|
-
// // do nothing, try next
|
|
160
|
-
// }
|
|
197
|
+
return await this._getPriceCoinbase(token);
|
|
161
198
|
case 'Coinmarketcap':
|
|
162
|
-
|
|
163
|
-
const result = await this._getPriceCoinMarketCap(token);
|
|
164
|
-
this.methodToUse[token.symbol] = 'Coinmarketcap';
|
|
165
|
-
return result;
|
|
166
|
-
} catch (error: any) {
|
|
167
|
-
console.warn(`CoinMarketCap: price err [${token.symbol}]: `, Object.keys(error));
|
|
168
|
-
console.warn(`CoinMarketCap: price err [${token.symbol}]: `, error.message);
|
|
169
|
-
}
|
|
199
|
+
return await this._getPriceCoinMarketCap(token);
|
|
170
200
|
case 'Ekubo':
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
} catch (error: any) {
|
|
176
|
-
console.warn(`Ekubo: price err [${token.symbol}]: `, error.message);
|
|
177
|
-
console.warn(`Ekubo: price err [${token.symbol}]: `, Object.keys(error));
|
|
178
|
-
// do nothing, try next
|
|
179
|
-
}
|
|
201
|
+
return await this._getPriceEkubo(
|
|
202
|
+
token,
|
|
203
|
+
new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals),
|
|
204
|
+
);
|
|
180
205
|
case 'Avnu':
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
} catch (error: any) {
|
|
186
|
-
console.warn(`Avnu: price err [${token.symbol}]: `, error.message);
|
|
187
|
-
console.warn(`Avnu: price err [${token.symbol}]: `, Object.keys(error));
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// if methodToUse is the default one, pass Coinbase to try all from start
|
|
192
|
-
if (defaultMethod == 'all') {
|
|
193
|
-
// try again with coinbase
|
|
194
|
-
return await this._getPrice(token, 'Coinbase');
|
|
206
|
+
return await this._getAvnuPrice(
|
|
207
|
+
token,
|
|
208
|
+
new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals),
|
|
209
|
+
);
|
|
195
210
|
}
|
|
211
|
+
}
|
|
196
212
|
|
|
197
|
-
|
|
213
|
+
async _getPriceAvnuApi(token: TokenInfo): Promise<number> {
|
|
214
|
+
const priceInfo = await this.avnuApiPricer.getPrice(token.symbol);
|
|
215
|
+
return priceInfo.price;
|
|
198
216
|
}
|
|
199
217
|
|
|
200
218
|
async _getPriceCoinbase(token: TokenInfo) {
|
package/src/node/pricer-redis.ts
CHANGED
|
@@ -18,6 +18,7 @@ export class PricerRedis extends Pricer {
|
|
|
18
18
|
await this.initRedis(redisUrl);
|
|
19
19
|
|
|
20
20
|
logger.info(`Starting Pricer with Redis`);
|
|
21
|
+
this.avnuApiPricer.start();
|
|
21
22
|
this._loadPrices(this._setRedisPrices.bind(this));
|
|
22
23
|
setInterval(() => {
|
|
23
24
|
this._loadPrices(this._setRedisPrices.bind(this));
|
|
@@ -874,7 +874,10 @@ export class EkuboCLVault extends BaseStrategy<
|
|
|
874
874
|
const token1Usd = Number(amount1.toFixed(13)) * P1.price;
|
|
875
875
|
const totalUsdValue = token0Usd + token1Usd;
|
|
876
876
|
|
|
877
|
-
if (
|
|
877
|
+
if (
|
|
878
|
+
(totalUsdValue === 0 || token0Usd === 0 || token1Usd === 0 || amount0.eq(0) || amount1.eq(0)) &&
|
|
879
|
+
this.metadata.settings?.liveStatus === StrategyLiveStatus.ACTIVE
|
|
880
|
+
) {
|
|
878
881
|
logger.warn(
|
|
879
882
|
`${this.metadata.name}:getTVL - Zero value detected: ` +
|
|
880
883
|
`usdValue=${totalUsdValue}, ` +
|
|
@@ -469,7 +469,10 @@ export class UniversalStrategy<
|
|
|
469
469
|
);
|
|
470
470
|
const usdValue = Number(amount.toFixed(6)) * price.price;
|
|
471
471
|
|
|
472
|
-
if (
|
|
472
|
+
if (
|
|
473
|
+
(usdValue === 0 || amount.eq(0)) &&
|
|
474
|
+
this.metadata.settings?.liveStatus === StrategyLiveStatus.ACTIVE
|
|
475
|
+
) {
|
|
473
476
|
logger.warn(
|
|
474
477
|
`${this.metadata.name}:getTVL - Zero value detected: ` +
|
|
475
478
|
`usdValue=${usdValue}, ` +
|
|
@@ -463,7 +463,10 @@ export class YoLoVault extends BaseStrategy<DualTokenInfo, SingleActionAmount, D
|
|
|
463
463
|
|
|
464
464
|
const totalUsdValue = primaryTokenUsd.plus(secondaryTokenUsd).toNumber();
|
|
465
465
|
|
|
466
|
-
if (
|
|
466
|
+
if (
|
|
467
|
+
(totalUsdValue === 0 || primaryTokenAmount.eq(0) || secondaryTokenAmount.eq(0)) &&
|
|
468
|
+
this.metadata.settings?.liveStatus === StrategyLiveStatus.ACTIVE
|
|
469
|
+
) {
|
|
467
470
|
logger.warn(
|
|
468
471
|
`${this.metadata.name}:getTVL - Zero value detected: ` +
|
|
469
472
|
`usdValue=${totalUsdValue}, ` +
|