@strkfarm/sdk 1.2.0 → 2.0.0-dev-strategy2.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 (60) hide show
  1. package/dist/index.browser.global.js +76556 -66640
  2. package/dist/index.browser.mjs +34235 -24392
  3. package/dist/index.d.ts +2372 -793
  4. package/dist/index.js +31967 -22084
  5. package/dist/index.mjs +25545 -15719
  6. package/package.json +86 -76
  7. package/readme.md +56 -1
  8. package/src/data/extended-deposit.abi.json +3613 -0
  9. package/src/data/universal-vault.abi.json +135 -20
  10. package/src/dataTypes/_bignumber.ts +11 -0
  11. package/src/dataTypes/address.ts +7 -0
  12. package/src/global.ts +240 -193
  13. package/src/interfaces/common.tsx +26 -2
  14. package/src/modules/ExtendedWrapperSDk/index.ts +62 -0
  15. package/src/modules/ExtendedWrapperSDk/types.ts +311 -0
  16. package/src/modules/ExtendedWrapperSDk/wrapper.ts +448 -0
  17. package/src/modules/avnu.ts +17 -4
  18. package/src/modules/ekubo-quoter.ts +89 -10
  19. package/src/modules/erc20.ts +67 -21
  20. package/src/modules/harvests.ts +29 -43
  21. package/src/modules/index.ts +5 -1
  22. package/src/modules/lst-apr.ts +36 -0
  23. package/src/modules/midas.ts +159 -0
  24. package/src/modules/pricer-from-api.ts +2 -2
  25. package/src/modules/pricer-lst.ts +1 -1
  26. package/src/modules/pricer.ts +3 -38
  27. package/src/modules/token-market-data.ts +202 -0
  28. package/src/node/deployer.ts +1 -36
  29. package/src/strategies/autoCompounderStrk.ts +1 -1
  30. package/src/strategies/base-strategy.ts +20 -3
  31. package/src/strategies/btc-vesu-extended-strategy/core-strategy.tsx +1486 -0
  32. package/src/strategies/btc-vesu-extended-strategy/services/operationService.ts +32 -0
  33. package/src/strategies/btc-vesu-extended-strategy/utils/constants.ts +3 -0
  34. package/src/strategies/btc-vesu-extended-strategy/utils/helper.ts +396 -0
  35. package/src/strategies/btc-vesu-extended-strategy/utils/types.ts +5 -0
  36. package/src/strategies/ekubo-cl-vault.tsx +123 -306
  37. package/src/strategies/index.ts +7 -1
  38. package/src/strategies/svk-strategy.ts +247 -0
  39. package/src/strategies/universal-adapters/adapter-optimizer.ts +65 -0
  40. package/src/strategies/universal-adapters/adapter-utils.ts +5 -1
  41. package/src/strategies/universal-adapters/avnu-adapter.ts +432 -0
  42. package/src/strategies/universal-adapters/baseAdapter.ts +181 -153
  43. package/src/strategies/universal-adapters/common-adapter.ts +98 -77
  44. package/src/strategies/universal-adapters/extended-adapter.ts +976 -0
  45. package/src/strategies/universal-adapters/index.ts +7 -1
  46. package/src/strategies/universal-adapters/unused-balance-adapter.ts +109 -0
  47. package/src/strategies/universal-adapters/vesu-adapter.ts +230 -230
  48. package/src/strategies/universal-adapters/vesu-borrow-adapter.ts +1247 -0
  49. package/src/strategies/universal-adapters/vesu-multiply-adapter.ts +1306 -0
  50. package/src/strategies/universal-adapters/vesu-supply-only-adapter.ts +58 -51
  51. package/src/strategies/universal-lst-muliplier-strategy.tsx +716 -844
  52. package/src/strategies/universal-strategy.tsx +1103 -1181
  53. package/src/strategies/vesu-extended-strategy/services/operationService.ts +34 -0
  54. package/src/strategies/vesu-extended-strategy/types/transaction-metadata.ts +25 -0
  55. package/src/strategies/vesu-extended-strategy/utils/config.runtime.ts +77 -0
  56. package/src/strategies/vesu-extended-strategy/utils/constants.ts +50 -0
  57. package/src/strategies/vesu-extended-strategy/utils/helper.ts +367 -0
  58. package/src/strategies/vesu-extended-strategy/vesu-extended-strategy.tsx +1420 -0
  59. package/src/strategies/vesu-rebalance.tsx +16 -20
  60. package/src/utils/health-factor-math.ts +11 -5
@@ -1,29 +1,75 @@
1
1
  import { ContractAddr, Web3Number } from "@/dataTypes";
2
2
  import { IConfig } from "@/interfaces";
3
- import { Contract } from "starknet";
4
- import ERC20Abi from '@/data/erc20.abi.json';
3
+ import { Contract, uint256 } from "starknet";
4
+ import ERC20Abi from "@/data/erc20.abi.json";
5
5
 
6
6
  export class ERC20 {
7
- readonly config: IConfig;
7
+ readonly config: IConfig;
8
8
 
9
- constructor(config: IConfig) {
10
- this.config = config;
11
- }
9
+ constructor(config: IConfig) {
10
+ this.config = config;
11
+ }
12
12
 
13
- contract(addr: string | ContractAddr) {
14
- const _addr = typeof addr === 'string' ? addr : addr.address;
15
- return new Contract({abi: ERC20Abi, address: _addr, providerOrAccount: this.config.provider});
16
- }
13
+ contract(addr: string | ContractAddr) {
14
+ const _addr = typeof addr === "string" ? addr : addr.address;
15
+ return new Contract({
16
+ abi: ERC20Abi,
17
+ address: _addr,
18
+ providerOrAccount: this.config.provider,
19
+ });
20
+ }
17
21
 
18
- async balanceOf(token: string | ContractAddr, address: string | ContractAddr, tokenDecimals: number) {
19
- const contract = this.contract(token);
20
- const balance = await contract.call('balanceOf', [address.toString()]);
21
- return Web3Number.fromWei(balance.toString(), tokenDecimals);
22
- }
22
+ async balanceOf(
23
+ token: string | ContractAddr,
24
+ address: string | ContractAddr,
25
+ tokenDecimals: number
26
+ ) {
27
+ const contract = this.contract(token);
28
+ const balance = await contract.call("balance_of", [address.toString()]);
29
+ return Web3Number.fromWei(balance.toString(), tokenDecimals);
30
+ }
23
31
 
24
- async allowance(token: string | ContractAddr, owner: string | ContractAddr, spender: string | ContractAddr, tokenDecimals: number) {
25
- const contract = this.contract(token);
26
- const allowance = await contract.call('allowance', [owner.toString(), spender.toString()]);
27
- return Web3Number.fromWei(allowance.toString(), tokenDecimals);
28
- }
29
- }
32
+ async allowance(
33
+ token: string | ContractAddr,
34
+ owner: string | ContractAddr,
35
+ spender: string | ContractAddr,
36
+ tokenDecimals: number
37
+ ) {
38
+ const contract = this.contract(token);
39
+ const allowance = await contract.call("allowance", [
40
+ owner.toString(),
41
+ spender.toString(),
42
+ ]);
43
+ return Web3Number.fromWei(allowance.toString(), tokenDecimals);
44
+ }
45
+
46
+ transfer(
47
+ token: string | ContractAddr,
48
+ to: string | ContractAddr,
49
+ amount: Web3Number
50
+ ) {
51
+ const contract = this.contract(token);
52
+ const amountUint256 = uint256.bnToUint256(amount.toWei());
53
+ const transferCall = contract.populate("transfer", [
54
+ to.toString(),
55
+ amountUint256.low.toString(),
56
+ amountUint256.high.toString(),
57
+ ]);
58
+ return transferCall;
59
+ }
60
+
61
+ approve(
62
+ token: string | ContractAddr,
63
+ spender: string | ContractAddr,
64
+ amount: Web3Number
65
+ ) {
66
+ const contract = this.contract(token);
67
+ const amountUint256 = uint256.bnToUint256(amount.toWei());
68
+ const approveCall = contract.populate("approve", [
69
+ spender.toString(),
70
+ amountUint256.low.toString(),
71
+ amountUint256.high.toString(),
72
+ ]);
73
+ return approveCall;
74
+ }
75
+ }
@@ -29,36 +29,28 @@ export class Harvests {
29
29
 
30
30
  async getUnHarvestedRewards(addr: ContractAddr) {
31
31
  const rewards = await this.getHarvests(addr);
32
- logger.verbose(`${Harvests.name}: getUnHarvestedRewards => rewards length: ${rewards.length}`);
33
32
  if (rewards.length == 0) return [];
34
33
 
35
34
  const unClaimed: HarvestInfo[] = [];
36
35
 
37
36
  // use the latest one
38
- const sortedRewards = rewards.sort((a, b) => b.endDate.getTime() - a.endDate.getTime());
39
- if (sortedRewards.length == 0) {
40
- logger.verbose(`${Harvests.name}: no rewards found`);
41
- return [];
42
- }
43
-
44
- const cls = await this.config.provider.getClassAt(sortedRewards[0].rewardsContract.address);
37
+ const reward = rewards.sort((a, b) => b.endDate.getTime() - a.endDate.getTime())[0];
45
38
 
46
- for (const reward of sortedRewards) {
47
- const contract = new Contract({abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider});
48
- const isClaimed = await contract.call('is_claimed', [reward.claim.id]);
49
- logger.verbose(`${Harvests.name}: isClaimed: ${isClaimed}, claim id: ${reward.claim.id}, address: ${reward.rewardsContract.address}`);
50
- if (isClaimed) {
51
- continue;
52
- }
53
- // rewards contract must have enough balance to claim
54
- const bal = await (new ERC20(this.config)).balanceOf(reward.token, reward.rewardsContract.address, 18);
55
- if (bal.lessThan(reward.claim.amount)) {
56
- logger.verbose(`${Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
57
- continue;
58
- }
59
-
60
- unClaimed.push(reward); // to ensure older harvest is first
39
+ const cls = await this.config.provider.getClassAt(reward.rewardsContract.address);
40
+ const contract = new Contract({abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider});
41
+ const isClaimed = await contract.call('is_claimed', [reward.claim.id]);
42
+ logger.verbose(`${Harvests.name}: isClaimed: ${isClaimed}`);
43
+ if (isClaimed) {
44
+ return unClaimed;
45
+ }
46
+ // rewards contract must have enough balance to claim
47
+ const bal = await (new ERC20(this.config)).balanceOf(reward.token, reward.rewardsContract.address, 18);
48
+ if (bal.lessThan(reward.claim.amount)) {
49
+ logger.verbose(`${Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
50
+ return unClaimed;
61
51
  }
52
+
53
+ unClaimed.unshift(reward); // to ensure older harvest is first
62
54
  return unClaimed;
63
55
  }
64
56
  }
@@ -67,28 +59,26 @@ const STRK = '0x4718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d'
67
59
 
68
60
  export class EkuboHarvests extends Harvests {
69
61
  async getHarvests(addr: ContractAddr) {
70
- logger.verbose(`${EkuboHarvests.name}: getHarvests => addr: ${addr.address}`);
71
- const EKUBO_API = `https://prod-api.ekubo.org/claims/${addr.address}`
62
+ const EKUBO_API = `https://starknet-mainnet-api.ekubo.org/airdrops/${addr.address}?token=${STRK}`
72
63
  const resultEkubo = await fetch(EKUBO_API);
73
- const data = (await resultEkubo.json());
74
- const claims = data.claims || [];
75
- logger.verbose(`${EkuboHarvests.name}: getHarvests => claims length: ${claims.length}`);
64
+ const items = (await resultEkubo.json());
65
+
76
66
  const rewards: HarvestInfo[] = [];
77
- for (let i=0; i<claims.length; ++i) {
78
- const claimData = claims[i];
79
- assert(claimData.key.token == STRK, 'expected strk token only')
67
+ for (let i=0; i<items.length; ++i) {
68
+ const info = items[i];
69
+ assert(info.token == STRK, 'expected strk token only')
80
70
  rewards.push({
81
- rewardsContract: ContractAddr.from(claimData.dropAddress),
71
+ rewardsContract: ContractAddr.from(info.contract_address),
82
72
  token: ContractAddr.from(STRK),
83
- startDate: new Date(0),
84
- endDate: new Date(0),
73
+ startDate: new Date(info.start_date),
74
+ endDate: new Date(info.end_date),
85
75
  claim: {
86
- id: claimData.claim.index,
87
- amount: Web3Number.fromWei(claimData.claim.amount, 18),
88
- claimee: ContractAddr.from(claimData.claim.account)
76
+ id: info.claim.id,
77
+ amount: Web3Number.fromWei(info.claim.amount, 18),
78
+ claimee: ContractAddr.from(info.claim.claimee)
89
79
  },
90
- actualReward: Web3Number.fromWei(claimData.claim.amount, 18),
91
- proof: claimData.proof
80
+ actualReward: Web3Number.fromWei(info.claim.amount, 18),
81
+ proof: info.proof
92
82
  });
93
83
  }
94
84
  return rewards.sort((a, b) => b.endDate.getTime() - a.endDate.getTime());
@@ -111,10 +101,6 @@ export class VesuHarvests extends Harvests {
111
101
  logger.verbose(`${VesuHarvests.name}: claimed_amount: ${claimed_amount.toString()}`);
112
102
 
113
103
  const data = _data.data['defiSpring'];
114
- if (!data) {
115
- logger.verbose(`${VesuHarvests.name}: no defiSpring data found`);
116
- return [];
117
- }
118
104
 
119
105
  // get the actual reward
120
106
  const actualReward = Web3Number.fromWei(data.amount, 18).minus(claimed_amount);
@@ -1,3 +1,4 @@
1
+ export * from './token-market-data';
1
2
  export * from './pricer';
2
3
  export * from './pragma';
3
4
  export * from './zkLend';
@@ -6,4 +7,7 @@ export * from './erc20';
6
7
  export * from './avnu';
7
8
  export * from './ekubo-quoter';
8
9
  export * from './pricer-lst';
9
- export * from './lst-apr';
10
+ export * from './lst-apr';
11
+ export * from './pricerBase';
12
+ export * from './midas';
13
+ export * from './ExtendedWrapperSDk';
@@ -1,4 +1,6 @@
1
1
  import { ContractAddr } from "@/dataTypes";
2
+ import { Global } from "@/global";
3
+ import { TokenInfo } from "@/interfaces";
2
4
  import { logger } from "@/utils";
3
5
 
4
6
  export interface LSTStats {
@@ -19,6 +21,19 @@ export class LSTAPRService {
19
21
  private static cacheTimestamp: number = 0;
20
22
  private static readonly CACHE_DURATION = 5 * 60 * 1000; // 5 minutes
21
23
 
24
+ static lstMapping: Record<string, TokenInfo> = {};
25
+
26
+ static isLST(address: ContractAddr): boolean {
27
+ return this.lstMapping[address.address] !== undefined;
28
+ }
29
+
30
+ static getUnderlyingFromLST(lstAddress: ContractAddr): TokenInfo {
31
+ const underlying = this.lstMapping[lstAddress.address];
32
+ if (!underlying) {
33
+ throw new Error(`Underlying token not found for ${lstAddress.address}`);
34
+ }
35
+ return underlying;
36
+ }
22
37
  /**
23
38
  * Fetches LST stats from Endur API with caching
24
39
  * @returns Promise<LSTStats[]> Array of LST statistics
@@ -138,3 +153,24 @@ export class LSTAPRService {
138
153
  logger.verbose(`LSTAPRService: Cache cleared`);
139
154
  }
140
155
  }
156
+
157
+
158
+ // populate lstMapping
159
+ const lstSymbolMapping: any = {
160
+ xSTRK: "STRK",
161
+ xWBTC: "WBTC",
162
+ xtBTC: "tBTC",
163
+ xsBTC: "solvBTC",
164
+ xLBTC: "LBTC",
165
+ }
166
+ Object.keys(lstSymbolMapping).forEach(key => {
167
+ const lst = Global.getDefaultTokens().find(t => t.symbol === key);
168
+ if (!lst) {
169
+ throw new Error(`LST token not found for ${key}`);
170
+ }
171
+ const underlying = Global.getDefaultTokens().find(t => t.symbol === lstSymbolMapping[key]);
172
+ if (!underlying) {
173
+ throw new Error(`Underlying token not found for ${key}`);
174
+ }
175
+ LSTAPRService.lstMapping[lst.address.address] = underlying;
176
+ });
@@ -0,0 +1,159 @@
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
+ }
@@ -13,7 +13,7 @@ export class PricerFromApi extends PricerBase {
13
13
  try {
14
14
  return await this.getPriceFromMyAPI(tokenSymbol);
15
15
  } catch (e: any) {
16
- logger.warn('getPriceFromMyAPI error', JSON.stringify(e.message || e));
16
+ logger.warn('getPriceFromMyAPI error', e);
17
17
  }
18
18
  logger.info('getPrice coinbase', tokenSymbol);
19
19
  let retry = 0;
@@ -41,7 +41,7 @@ export class PricerFromApi extends PricerBase {
41
41
  }
42
42
 
43
43
  async getPriceFromMyAPI(tokenSymbol: string) {
44
- logger.verbose(`getPrice from redis: ${tokenSymbol}`);
44
+ // logger.verbose(`getPrice from api: ${tokenSymbol}`);
45
45
  const endpoint = 'https://proxy.api.troves.fi'
46
46
  const url = `${endpoint}/api/price/${tokenSymbol}`;
47
47
  const priceInfoRes = await fetch(url);
@@ -6,7 +6,7 @@ import axios from "axios";
6
6
 
7
7
  export class PricerLST extends Pricer {
8
8
  private tokenMaps: {lst: TokenInfo, underlying: TokenInfo}[];
9
- protected EKUBO_API = 'https://prod-api-quoter.ekubo.org/23448594291968334/{{AMOUNT}}/{{TOKEN_ADDRESS}}/{{UNDERLYING_ADDRESS}}'; // e.g. xSTRK/STRK
9
+ protected EKUBO_API = 'https://quoter-mainnet-api.ekubo.org/{{AMOUNT}}/{{TOKEN_ADDRESS}}/{{UNDERLYING_ADDRESS}}'; // e.g. xSTRK/STRK
10
10
 
11
11
  constructor(config: IConfig, tokenMaps: {lst: TokenInfo, underlying: TokenInfo}[]) {
12
12
  const refreshInterval = 5000;
@@ -5,7 +5,6 @@ import { IConfig } from "@/interfaces/common";
5
5
  import { Web3Number } from "@/dataTypes";
6
6
  import { PricerBase } from "./pricerBase";
7
7
  import { logger } from "@/utils/logger";
8
- import { AvnuWrapper } from "./avnu";
9
8
 
10
9
  export interface PriceInfo {
11
10
  price: number,
@@ -22,14 +21,13 @@ export class Pricer extends PricerBase {
22
21
 
23
22
  // code populates this map during runtime to determine which method to use for a given token
24
23
  // The method set will be the first one to try after first attempt
25
- protected methodToUse: {[tokenSymbol: string]: 'Ekubo' | 'Coinbase' | 'Coinmarketcap' | 'Avnu'} = {};
24
+ protected methodToUse: {[tokenSymbol: string]: 'Ekubo' | 'Coinbase' | 'Coinmarketcap'} = {};
26
25
 
27
26
  /**
28
27
  * TOKENA and TOKENB are the two token names to get price of TokenA in terms of TokenB
29
28
  */
30
- // ! switch to USDC (new) later
31
29
  protected PRICE_API = `https://api.coinbase.com/v2/prices/{{PRICER_KEY}}/buy`;
32
- protected EKUBO_API = 'https://prod-api-quoter.ekubo.org/23448594291968334/{{AMOUNT}}/{{TOKEN_ADDRESS}}/0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb'; // e.g. ETH/USDC
30
+ protected EKUBO_API = 'https://quoter-mainnet-api.ekubo.org/{{AMOUNT}}/{{TOKEN_ADDRESS}}/0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8'; // e.g. ETH/USDC
33
31
 
34
32
  constructor(config: IConfig, tokens: TokenInfo[], refreshInterval = 30000, staleTime = 60000) {
35
33
  super(config, tokens);
@@ -95,7 +93,7 @@ export class Pricer extends PricerBase {
95
93
  let retry = 0;
96
94
  while (retry < MAX_RETRIES) {
97
95
  try {
98
- if (token.symbol === 'USDT' || token.symbol === 'USDC') {
96
+ if (token.symbol === 'USDT') {
99
97
  this.prices[token.symbol] = {
100
98
  price: 1,
101
99
  timestamp: new Date()
@@ -176,15 +174,6 @@ export class Pricer extends PricerBase {
176
174
  console.warn(`Ekubo: price err [${token.symbol}]: `, Object.keys(error));
177
175
  // do nothing, try next
178
176
  }
179
- case 'Avnu':
180
- try {
181
- const result = await this._getAvnuPrice(token, new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals));
182
- this.methodToUse[token.symbol] = 'Avnu';
183
- return result;
184
- } catch (error: any) {
185
- console.warn(`Avnu: price err [${token.symbol}]: `, error.message);
186
- console.warn(`Avnu: price err [${token.symbol}]: `, Object.keys(error));
187
- }
188
177
  }
189
178
 
190
179
  // if methodToUse is the default one, pass Coinbase to try all from start
@@ -211,31 +200,7 @@ export class Pricer extends PricerBase {
211
200
  throw new Error("Not implemented");
212
201
  }
213
202
 
214
- async _getAvnuPrice(token: TokenInfo, amountIn = new Web3Number(1, token.decimals), retry = 0): Promise<number> {
215
- logger.verbose(`Getting price of ${token.symbol} using Ekubo, amountIn: ${amountIn.toWei()}`);
216
-
217
- const avnuWrapper = new AvnuWrapper();
218
- const usdcAddress = '0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb';
219
- const quote = await avnuWrapper.getQuotes(token.address.toString(), usdcAddress, amountIn.toWei(), '0x1');
220
- const multiplier = 1 / amountIn.toNumber();
221
- const outputUSDC = Number(Web3Number.fromWei(quote.buyAmount.toString(), 6).toFixed(6)) * multiplier;
222
- logger.verbose(`Avnu: ${token.symbol} -> USDC: ${outputUSDC}, retry: ${retry}`);
223
- if (outputUSDC === 0 && retry < 3) {
224
- // try again with a higher amount
225
- const amountIn = new Web3Number(100, token.decimals); // 100 unit of token
226
- return await this._getAvnuPrice(token, amountIn, retry + 1);
227
- }
228
-
229
- // if usdc depegs, it will not longer be 1 USD
230
- // so we need to get the price of USDC in USD
231
- // and then convert the outputUSDC to USD
232
- const usdcPrice = 1; // (await this.getPrice('USDC')).price;
233
- logger.verbose(`USDC Price: ${usdcPrice}`);
234
- return outputUSDC * usdcPrice;
235
- }
236
-
237
203
  async _getPriceEkubo(token: TokenInfo, amountIn = new Web3Number(1, token.decimals), retry = 0): Promise<number> {
238
- logger.verbose(`Getting price of ${token.symbol} using Ekubo, amountIn: ${amountIn.toWei()}`);
239
204
  const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address.toString()).replace("{{AMOUNT}}", amountIn.toWei());
240
205
  const result = await axios.get(url);
241
206
  const data: any = result.data;