@strkfarm/sdk 2.0.0-dev.26 → 2.0.0-dev.28

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 (70) hide show
  1. package/dist/cli.js +190 -36
  2. package/dist/cli.mjs +188 -34
  3. package/dist/index.browser.global.js +79130 -49354
  4. package/dist/index.browser.mjs +18039 -11431
  5. package/dist/index.d.ts +2869 -898
  6. package/dist/index.js +19036 -12207
  7. package/dist/index.mjs +18942 -12158
  8. package/package.json +1 -1
  9. package/src/data/avnu.abi.json +840 -0
  10. package/src/data/ekubo-price-fethcer.abi.json +265 -0
  11. package/src/dataTypes/_bignumber.ts +13 -4
  12. package/src/dataTypes/index.ts +3 -2
  13. package/src/dataTypes/mynumber.ts +141 -0
  14. package/src/global.ts +76 -41
  15. package/src/index.browser.ts +2 -1
  16. package/src/interfaces/common.tsx +167 -2
  17. package/src/modules/ExtendedWrapperSDk/types.ts +26 -4
  18. package/src/modules/ExtendedWrapperSDk/wrapper.ts +110 -67
  19. package/src/modules/apollo-client-config.ts +28 -0
  20. package/src/modules/avnu.ts +4 -4
  21. package/src/modules/ekubo-pricer.ts +79 -0
  22. package/src/modules/ekubo-quoter.ts +46 -30
  23. package/src/modules/erc20.ts +17 -0
  24. package/src/modules/harvests.ts +43 -29
  25. package/src/modules/pragma.ts +23 -8
  26. package/src/modules/pricer-from-api.ts +156 -15
  27. package/src/modules/pricer-lst.ts +1 -1
  28. package/src/modules/pricer.ts +40 -4
  29. package/src/modules/pricerBase.ts +2 -1
  30. package/src/node/deployer.ts +36 -1
  31. package/src/node/pricer-redis.ts +2 -1
  32. package/src/strategies/base-strategy.ts +78 -10
  33. package/src/strategies/ekubo-cl-vault.tsx +906 -347
  34. package/src/strategies/factory.ts +159 -0
  35. package/src/strategies/index.ts +6 -1
  36. package/src/strategies/registry.ts +239 -0
  37. package/src/strategies/sensei.ts +335 -7
  38. package/src/strategies/svk-strategy.ts +97 -27
  39. package/src/strategies/types.ts +4 -0
  40. package/src/strategies/universal-adapters/adapter-utils.ts +2 -1
  41. package/src/strategies/universal-adapters/avnu-adapter.ts +177 -268
  42. package/src/strategies/universal-adapters/baseAdapter.ts +263 -251
  43. package/src/strategies/universal-adapters/common-adapter.ts +206 -203
  44. package/src/strategies/universal-adapters/extended-adapter.ts +155 -336
  45. package/src/strategies/universal-adapters/index.ts +9 -8
  46. package/src/strategies/universal-adapters/token-transfer-adapter.ts +200 -0
  47. package/src/strategies/universal-adapters/usdc<>usdce-adapter.ts +200 -0
  48. package/src/strategies/universal-adapters/vesu-adapter.ts +110 -75
  49. package/src/strategies/universal-adapters/vesu-modify-position-adapter.ts +476 -0
  50. package/src/strategies/universal-adapters/vesu-multiply-adapter.ts +762 -844
  51. package/src/strategies/universal-adapters/vesu-position-common.ts +251 -0
  52. package/src/strategies/universal-adapters/vesu-supply-only-adapter.ts +18 -3
  53. package/src/strategies/universal-lst-muliplier-strategy.tsx +396 -204
  54. package/src/strategies/universal-strategy.tsx +1426 -1178
  55. package/src/strategies/vesu-extended-strategy/services/executionService.ts +2251 -0
  56. package/src/strategies/vesu-extended-strategy/services/extended-vesu-state-manager.ts +2941 -0
  57. package/src/strategies/vesu-extended-strategy/services/operationService.ts +12 -1
  58. package/src/strategies/vesu-extended-strategy/types/transaction-metadata.ts +52 -0
  59. package/src/strategies/vesu-extended-strategy/utils/config.runtime.ts +1 -0
  60. package/src/strategies/vesu-extended-strategy/utils/constants.ts +3 -1
  61. package/src/strategies/vesu-extended-strategy/utils/helper.ts +158 -124
  62. package/src/strategies/vesu-extended-strategy/vesu-extended-strategy.tsx +377 -1781
  63. package/src/strategies/vesu-rebalance.tsx +255 -152
  64. package/src/utils/health-factor-math.ts +4 -1
  65. package/src/utils/index.ts +2 -1
  66. package/src/utils/logger.browser.ts +22 -4
  67. package/src/utils/logger.node.ts +259 -24
  68. package/src/utils/starknet-call-parser.ts +1036 -0
  69. package/src/utils/strategy-utils.ts +61 -0
  70. package/src/strategies/universal-adapters/unused-balance-adapter.ts +0 -109
@@ -3,6 +3,7 @@ import {
3
3
  DepositParams,
4
4
  WithdrawParams,
5
5
  BaseAdapterConfig,
6
+ SwapPriceInfo,
6
7
  } from "./baseAdapter";
7
8
  import { toBigInt } from "./adapter-utils";
8
9
  import { Protocols } from "@/interfaces";
@@ -19,9 +20,12 @@ import { Quote } from "@avnu/avnu-sdk";
19
20
  import { hash, uint256 } from "starknet";
20
21
  import { AvnuWrapper } from "@/modules/avnu";
21
22
  import axios from "axios";
22
- import {SIMPLE_SANITIZER } from "./adapter-utils";
23
+ import { SIMPLE_SANITIZER } from "./adapter-utils";
23
24
  import { returnFormattedAmount } from "../vesu-extended-strategy/utils/helper";
24
- import { logger } from "@/utils";
25
+ import { assert, logger } from "@/utils";
26
+ import { Global } from "@/global";
27
+ import { TokenInfo } from "@/interfaces";
28
+ import { ERC20 } from "@/modules";
25
29
  export interface AvnuAdapterConfig extends BaseAdapterConfig {
26
30
  baseUrl: string;
27
31
  avnuContract: ContractAddr; //0x04270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f
@@ -33,23 +37,163 @@ export interface AvnuAdapterConfig extends BaseAdapterConfig {
33
37
  export class AvnuAdapter extends BaseAdapter<DepositParams, WithdrawParams> {
34
38
  readonly config: AvnuAdapterConfig;
35
39
  protected avnuWrapper: AvnuWrapper;
40
+ lastSwapPriceInfo: SwapPriceInfo | null = null;
41
+
42
+ private _depositApproveProofReadableId(): string {
43
+ return `approve_${this.config.supportedPositions[0].asset.symbol}`;
44
+ }
45
+
46
+ private _depositSwapProofReadableId(): string {
47
+ return `asutb_${this.config.supportedPositions[0].asset.symbol}_${this.config.supportedPositions[1].asset.symbol}`;
48
+ }
49
+
50
+ private _withdrawApproveProofReadableId(): string {
51
+ return `approve_${this.config.supportedPositions[1].asset.symbol}`;
52
+ }
53
+
54
+ private _withdrawSwapProofReadableId(): string {
55
+ const fromToken = this.config.supportedPositions[1].asset;
56
+ return `asbtu_${fromToken.symbol}_${fromToken.symbol}`;
57
+ }
58
+
59
+ private buildSwapLeafConfigs(
60
+ fromToken: TokenInfo,
61
+ toToken: TokenInfo,
62
+ swapId: string,
63
+ ): {
64
+ target: ContractAddr;
65
+ method: string;
66
+ packedArguments: bigint[];
67
+ sanitizer: ContractAddr;
68
+ id: string;
69
+ }[] {
70
+ const vaultAllocator = ContractAddr.from(this.config.vaultAllocator.address);
71
+ return [
72
+ {
73
+ target: fromToken.address,
74
+ method: "approve",
75
+ packedArguments: [AVNU_EXCHANGE.toBigInt()],
76
+ sanitizer: SIMPLE_SANITIZER,
77
+ id: `approve_${fromToken.symbol}`,
78
+ },
79
+ {
80
+ target: AVNU_EXCHANGE,
81
+ method: "multi_route_swap",
82
+ packedArguments: [
83
+ fromToken.address.toBigInt(),
84
+ toToken.address.toBigInt(),
85
+ vaultAllocator.toBigInt(),
86
+ ],
87
+ sanitizer: SIMPLE_SANITIZER,
88
+ id: swapId,
89
+ },
90
+ ];
91
+ }
92
+
93
+ private async buildSwapCalls(
94
+ params: DepositParams | WithdrawParams,
95
+ fromToken: TokenInfo,
96
+ toToken: TokenInfo,
97
+ usdcToBtc: boolean,
98
+ ): Promise<ManageCall[]> {
99
+ const vaultAllocator = ContractAddr.from(this.config.vaultAllocator.address);
100
+ const quote = await this.avnuWrapper.getQuotes(
101
+ fromToken.address.toString(),
102
+ toToken.address.toString(),
103
+ params.amount.toWei(),
104
+ vaultAllocator.address.toString(),
105
+ );
106
+
107
+ if (!quote) {
108
+ logger.error("No quotes available for this swap, error in quotes avnu");
109
+ return [];
110
+ }
111
+
112
+ const fromAmt = Web3Number.fromWei(quote.sellAmount.toString(), fromToken.decimals).toNumber();
113
+ const toAmt = Web3Number.fromWei(quote.buyAmount.toString(), toToken.decimals).toNumber();
114
+ this.lastSwapPriceInfo = {
115
+ source: 'avnu',
116
+ fromTokenSymbol: fromToken.symbol,
117
+ toTokenSymbol: toToken.symbol,
118
+ fromAmount: fromAmt,
119
+ toAmount: toAmt,
120
+ effectivePrice: toAmt !== 0 ? fromAmt / toAmt : 0,
121
+ };
122
+ logger.verbose(
123
+ `${AvnuAdapter.name}::buildSwapCalls stored price info: ` +
124
+ `${fromAmt} ${fromToken.symbol} → ${toAmt} ${toToken.symbol}, ` +
125
+ `effectivePrice=${this.lastSwapPriceInfo.effectivePrice}`,
126
+ );
127
+
128
+ const getCalldata = await this.avnuWrapper.getSwapCallData(
129
+ quote,
130
+ vaultAllocator.address,
131
+ );
132
+ const swapCallData = getCalldata[0];
133
+ const approveAmount = uint256.bnToUint256(params.amount.toWei());
134
+
135
+ return [
136
+ {
137
+ proofReadableId: usdcToBtc
138
+ ? this._depositApproveProofReadableId()
139
+ : this._withdrawApproveProofReadableId(),
140
+ sanitizer: SIMPLE_SANITIZER,
141
+ call: {
142
+ contractAddress: fromToken.address,
143
+ selector: hash.getSelectorFromName("approve"),
144
+ calldata: [
145
+ AVNU_EXCHANGE.toBigInt(),
146
+ toBigInt(approveAmount.low.toString()),
147
+ toBigInt(approveAmount.high.toString()),
148
+ ],
149
+ },
150
+ },
151
+ {
152
+ proofReadableId: usdcToBtc
153
+ ? this._depositSwapProofReadableId()
154
+ : this._withdrawSwapProofReadableId(),
155
+ sanitizer: SIMPLE_SANITIZER,
156
+ call: {
157
+ contractAddress: AVNU_EXCHANGE,
158
+ selector: hash.getSelectorFromName("multi_route_swap"),
159
+ calldata: swapCallData,
160
+ },
161
+ },
162
+ ];
163
+ }
36
164
 
37
165
  constructor(config: AvnuAdapterConfig) {
38
166
  super(config, AvnuAdapter.name, Protocols.AVNU);
39
167
  this.config = config as AvnuAdapterConfig;
40
168
  this.avnuWrapper = new AvnuWrapper();
169
+ assert(this.config.supportedPositions.length === 2, "AvnuAdapter must have 2 supported positions");
41
170
  }
42
171
  //abstract means the method has no implementation in this class; instead, child classes must implement it.
43
172
  protected async getAPY(
44
- supportedPosition: SupportedPosition
173
+ supportedPosition: SupportedPosition,
45
174
  ): Promise<PositionAPY> {
46
175
  return Promise.resolve({ apy: 0, type: APYType.BASE });
47
176
  }
48
177
 
49
178
  protected async getPosition(
50
- supportedPosition: SupportedPosition
51
- ): Promise<PositionAmount> {
52
- return Promise.resolve({ amount: new Web3Number(0, 0), remarks: "Avnu Positions" });
179
+ supportedPosition: SupportedPosition,
180
+ ): Promise<PositionAmount | null> {
181
+ const toToken = this.config.supportedPositions[1].asset;
182
+ if (supportedPosition.asset.symbol != toToken.symbol) {
183
+ return null;
184
+ }
185
+ try {
186
+ // only measure balance of toToken, bcz from token usually gets trakced in unused balance or a previous avnu adapter
187
+ const balance = await new ERC20(this.config.networkConfig).balanceOf(
188
+ supportedPosition.asset.address,
189
+ this.config.vaultAllocator.address,
190
+ supportedPosition.asset.decimals,
191
+ );
192
+ return { amount: balance, remarks: `Swapped Unused balance (VA)` };
193
+ } catch (_e) {
194
+ logger.error(`${AvnuAdapter.name}::getPosition: failed for ${toToken.symbol}`);
195
+ throw new Error(`${AvnuAdapter.name}: failed to get balance for ${toToken.symbol}`);
196
+ }
53
197
  }
54
198
 
55
199
  async maxDeposit(amount?: Web3Number): Promise<PositionInfo> {
@@ -82,31 +226,11 @@ export class AvnuAdapter extends BaseAdapter<DepositParams, WithdrawParams> {
82
226
  sanitizer: ContractAddr;
83
227
  id: string;
84
228
  }[] {
85
- const vaultAllocator = ContractAddr.from(
86
- this.config.vaultAllocator.address
229
+ return this.buildSwapLeafConfigs(
230
+ this.config.supportedPositions[0].asset,
231
+ this.config.supportedPositions[1].asset,
232
+ this._depositSwapProofReadableId(),
87
233
  );
88
- return [
89
- {
90
- target: this.config.supportedPositions[0].asset.address,
91
- method: "approve",
92
- packedArguments: [
93
- AVNU_EXCHANGE.toBigInt(),
94
- ],
95
- sanitizer: SIMPLE_SANITIZER,
96
- id: `approve_${this.config.supportedPositions[0].asset.symbol}`,
97
- },
98
- {
99
- target: AVNU_EXCHANGE,
100
- method: "multi_route_swap",
101
- packedArguments: [
102
- this.config.supportedPositions[0].asset.address.toBigInt(), //usdc
103
- this.config.supportedPositions[1].asset.address.toBigInt(), //wbtc
104
- vaultAllocator.toBigInt(),
105
- ],
106
- sanitizer: SIMPLE_SANITIZER,
107
- id: `asutb_${this.config.supportedPositions[0].asset.symbol}_${this.config.supportedPositions[1].asset.symbol}`,
108
- },
109
- ];
110
234
  }
111
235
 
112
236
  protected _getWithdrawLeaf(): {
@@ -116,33 +240,13 @@ export class AvnuAdapter extends BaseAdapter<DepositParams, WithdrawParams> {
116
240
  sanitizer: ContractAddr;
117
241
  id: string;
118
242
  }[] {
119
- const vaultAllocator = ContractAddr.from(
120
- this.config.vaultAllocator.address
121
- );
122
243
  const toToken = this.config.supportedPositions[0].asset;
123
244
  const fromToken = this.config.supportedPositions[1].asset;
124
- return [
125
- {
126
- target: fromToken.address,
127
- method: "approve",
128
- packedArguments: [
129
- AVNU_EXCHANGE.toBigInt(),
130
- ],
131
- sanitizer: SIMPLE_SANITIZER,
132
- id: `approve_${fromToken.symbol}`,
133
- },
134
- {
135
- target: AVNU_EXCHANGE,
136
- method: "multi_route_swap",
137
- packedArguments: [
138
- fromToken.address.toBigInt(), //wbtc
139
- toToken.address.toBigInt(), //usdc
140
- vaultAllocator.toBigInt(),
141
- ],
142
- sanitizer: SIMPLE_SANITIZER,
143
- id: `asbtu_${fromToken.symbol}_${fromToken.symbol}`,
144
- },
145
- ];
245
+ return this.buildSwapLeafConfigs(
246
+ fromToken,
247
+ toToken,
248
+ this._withdrawSwapProofReadableId(),
249
+ );
146
250
  }
147
251
 
148
252
  protected _getLegacySwapLeaf(): {
@@ -159,54 +263,13 @@ export class AvnuAdapter extends BaseAdapter<DepositParams, WithdrawParams> {
159
263
  try {
160
264
  const fromToken = this.config.supportedPositions[0].asset; //usdc
161
265
  const toToken = this.config.supportedPositions[1].asset; //wbtc
162
- const vaultAllocator = ContractAddr.from(
163
- this.config.vaultAllocator.address
164
- );
165
- const quote = await this.getQuotesAvnu(
166
- fromToken.address.toString(),
167
- toToken.address.toString(),
168
- params.amount.toNumber(),
169
- vaultAllocator.address.toString(),
170
- toToken.decimals,
171
- true
172
- )
173
- //console.log(`${AvnuAdapter.name}::getDepositCall quote: ${JSON.stringify(quote)}`);
174
- if (!quote) {
175
- logger.error("error getting quote from avnu");
176
- return [];
177
- }
178
-
179
- const getCalldata = await this.avnuWrapper.getSwapCallData(
180
- quote,
181
- vaultAllocator.address
266
+ const calls = await this.buildSwapCalls(
267
+ params,
268
+ fromToken,
269
+ toToken,
270
+ true,
182
271
  );
183
- const dataObject = quote;
184
- logger.info(`${AvnuAdapter.name}::getQuotesAvnu finalAmountOfWbtcOut : ${dataObject.avnuFees} ${parseInt(dataObject.buyAmount.toString(), 16)} ${parseInt(dataObject.sellAmount.toString(), 16)} ${parseInt(dataObject.sellAmount.toString(), 16)}`);
185
- const swapCallData = getCalldata[0];
186
- // const approveCallData = getCalldata[0];
187
- const amount = uint256.bnToUint256(quote.sellAmountInUsd*10**7)
188
- return [
189
- {
190
- sanitizer: SIMPLE_SANITIZER,
191
- call: {
192
- contractAddress: fromToken.address,
193
- selector: hash.getSelectorFromName("approve"),
194
- calldata:[
195
- AVNU_EXCHANGE.toBigInt(),
196
- toBigInt(amount.low.toString()), // amount low
197
- toBigInt(amount.high.toString()), // amount high
198
- ] ,
199
- },
200
- },
201
- {
202
- sanitizer: SIMPLE_SANITIZER,
203
- call: {
204
- contractAddress: AVNU_EXCHANGE,
205
- selector: hash.getSelectorFromName("multi_route_swap"),
206
- calldata: swapCallData,
207
- },
208
- },
209
- ];
272
+ return calls;
210
273
  } catch (error) {
211
274
  logger.error(`Error getting Avnu quote: ${error}`);
212
275
  return [];
@@ -218,49 +281,13 @@ export class AvnuAdapter extends BaseAdapter<DepositParams, WithdrawParams> {
218
281
  try {
219
282
  const toToken = this.config.supportedPositions[0].asset;
220
283
  const fromToken = this.config.supportedPositions[1].asset;
221
- const vaultAllocator = ContractAddr.from(
222
- this.config.vaultAllocator.address
223
- );
224
- const quote = await this.getQuotesAvnu(
225
- fromToken.address.toString(),
226
- toToken.address.toString(),
227
- params.amount.toNumber(),
228
- vaultAllocator.address.toString(),
229
- fromToken.decimals,
230
- false
231
- );
232
- if (!quote) {
233
- logger.error("No quotes available for this swap, error in quotes avnu");
234
- return [];
235
- }
236
- const getCalldata = await this.avnuWrapper.getSwapCallData(
237
- quote,
238
- vaultAllocator.address
284
+ const calls = await this.buildSwapCalls(
285
+ params,
286
+ fromToken,
287
+ toToken,
288
+ false,
239
289
  );
240
- const swapCallData = getCalldata[0];
241
- const amount = uint256.bnToUint256(params.amount.toWei())
242
- return [
243
- {
244
- sanitizer: SIMPLE_SANITIZER,
245
- call: {
246
- contractAddress:fromToken.address,
247
- selector: hash.getSelectorFromName("approve"),
248
- calldata: [
249
- AVNU_EXCHANGE.toBigInt(),
250
- toBigInt(amount.low.toString()), // amount low
251
- toBigInt(amount.high.toString()), // amount high
252
- ],
253
- },
254
- },
255
- {
256
- sanitizer: SIMPLE_SANITIZER,
257
- call: {
258
- contractAddress: AVNU_EXCHANGE,
259
- selector: hash.getSelectorFromName("multi_route_swap"),
260
- calldata: swapCallData,
261
- },
262
- },
263
- ];
290
+ return calls;
264
291
  } catch (error) {
265
292
  logger.error(`Error getting Avnu quote: ${error}`);
266
293
  return [];
@@ -268,7 +295,10 @@ export class AvnuAdapter extends BaseAdapter<DepositParams, WithdrawParams> {
268
295
  }
269
296
 
270
297
  async getSwapCallData(quote: Quote): Promise<bigint[][]> {
271
- return await this.avnuWrapper.getSwapCallData(quote, this.config.vaultAllocator.address);
298
+ return await this.avnuWrapper.getSwapCallData(
299
+ quote,
300
+ this.config.vaultAllocator.address,
301
+ );
272
302
  }
273
303
 
274
304
  async getHealthFactor(): Promise<number> {
@@ -277,7 +307,7 @@ export class AvnuAdapter extends BaseAdapter<DepositParams, WithdrawParams> {
277
307
 
278
308
  async fetchQuoteWithRetry(
279
309
  params: Record<string, any>,
280
- retries: number = 5
310
+ retries: number = 5,
281
311
  ): Promise<any> {
282
312
  for (let attempt = 0; attempt < retries; attempt++) {
283
313
  try {
@@ -296,125 +326,4 @@ export class AvnuAdapter extends BaseAdapter<DepositParams, WithdrawParams> {
296
326
  }
297
327
  throw new Error("Failed to fetch quote after retries");
298
328
  }
299
-
300
- async getQuotesAvnu (
301
- from_token_address: string,
302
- to_token_address: string,
303
- amount: number, //amount in btc units
304
- takerAddress: string,
305
- toTokenDecimals: number,
306
- usdcToBtc: boolean,
307
- maxIterations: number = 5,
308
- tolerance: number = 5000
309
- ): Promise<Quote | null>{
310
- try {
311
- const fromToken = this.config.supportedPositions[0].asset; //usdc
312
- const toToken = this.config.supportedPositions[1].asset; //wbtc
313
- if(!usdcToBtc) {
314
- const sellAmount = returnFormattedAmount(amount, toTokenDecimals);
315
- const params: Record<string, any> = {
316
- sellTokenAddress: from_token_address,
317
- buyTokenAddress: to_token_address,
318
- takerAddress,
319
- sellAmount:sellAmount,
320
- };
321
- const finalQuote = await this.fetchQuoteWithRetry(params);
322
- if (!finalQuote.data.length) {
323
- logger.error("No quotes available for this swap, error in quotes avnu");
324
- return null;
325
- }
326
- const dataObject: Quote = finalQuote.data[0];
327
- return dataObject;
328
- }
329
- const btcPrice = await this.getPriceOfToken(toToken.address.toString());
330
- if (!btcPrice) {
331
- logger.error(`error getting btc price: ${btcPrice}`);
332
- return null;
333
- }
334
- const estimatedUsdcAmount = Math.floor(amount * btcPrice);
335
- logger.info(`${AvnuAdapter.name}::getQuotesAvnu estimatedUsdcAmount: ${estimatedUsdcAmount}`);
336
- const targetBtcBig = BigInt(returnFormattedAmount(amount, toTokenDecimals));
337
- logger.info(`${AvnuAdapter.name}::getQuotesAvnu targetBtcBig: ${targetBtcBig}`);
338
- let low = BigInt(
339
- Math.floor(
340
- (estimatedUsdcAmount * 10 ** fromToken.decimals) * 0.9
341
- )
342
- );
343
- let high = BigInt(
344
- Math.floor(
345
- (estimatedUsdcAmount * 10 ** fromToken.decimals) * 1.1
346
- )
347
- );
348
- let mid = 0n;
349
- for (let i = 0; i < maxIterations; i++) {
350
- mid = (low + high) / 2n;
351
- const sellAmount = returnFormattedAmount(Number(mid), 0);
352
- const quote = await this.fetchQuoteWithRetry({
353
- sellTokenAddress: from_token_address,
354
- buyTokenAddress: to_token_address,
355
- takerAddress,
356
- sellAmount,
357
- });
358
-
359
- const gotBtc = BigInt(quote.data[0].buyAmount);
360
- if (gotBtc === targetBtcBig) return quote.data[0];
361
-
362
- if (gotBtc > targetBtcBig) {
363
- high = mid;
364
- } else {
365
- low = mid;
366
- }
367
-
368
- if (
369
- gotBtc >= targetBtcBig &&
370
- gotBtc <= targetBtcBig + BigInt(tolerance)
371
- ) {
372
- return quote.data[0];
373
- }
374
- }
375
- let sellAmount = returnFormattedAmount(
376
- Number(mid),
377
- 0
378
- );
379
- const params: Record<string, any> = {
380
- sellTokenAddress: from_token_address,
381
- buyTokenAddress: to_token_address,
382
- takerAddress,
383
- sellAmount: sellAmount,
384
- };
385
- const finalQuote = await this.fetchQuoteWithRetry(params);
386
- if (!finalQuote.data.length) {
387
- logger.error("No quotes available for this swap, error in quotes avnu");
388
- return null;
389
- }
390
- const dataObject: Quote = finalQuote.data[0];
391
- const wbtcAmountOut = parseInt(dataObject.buyAmount.toString(), 16);
392
- logger.info(`${AvnuAdapter.name}::getQuotesAvnu finalAmountOfWbtcOut : ${wbtcAmountOut} ${dataObject.buyAmount} ${dataObject.sellAmount.toString()} ${dataObject.sellAmount.toString()}`);
393
- return dataObject;
394
- } catch (err) {
395
- logger.error(`No quotes available for this swap: ${err}`);
396
- return null;
397
- }
398
- };
399
-
400
- async getPriceOfToken (
401
- tokenAddress: string,
402
- retries: number = MAX_RETRIES
403
- ): Promise<number | null> {
404
- try {
405
- const url = `https://starknet.impulse.avnu.fi/v1/tokens/${tokenAddress}/prices/line`;
406
- const response = await axios.get(url);
407
- const length = response.data.length;
408
- return response.data[length - 1].value;
409
- } catch (err) {
410
- if (retries > 0) {
411
- await new Promise((resolve) => setTimeout(resolve, MAX_DELAY));
412
- return this.getPriceOfToken(tokenAddress, retries - 1);
413
- } else {
414
- logger.error(`Failed to fetch price for ${tokenAddress} after ${MAX_RETRIES} attempts`);
415
- return null;
416
- }
417
- }
418
- };
419
-
420
- }
329
+ }