@strkfarm/sdk 1.1.5 → 1.1.7

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.mjs CHANGED
@@ -241,6 +241,7 @@ var defaultTokens = [{
241
241
  address: ContractAddr.from("0x0593e034dda23eea82d2ba9a30960ed42cf4a01502cc2351dc9b9881f9931a68"),
242
242
  decimals: 18,
243
243
  coingeckId: void 0,
244
+ priceProxySymbol: "WBTC",
244
245
  displayDecimals: 6,
245
246
  priceCheckAmount: 1e-4
246
247
  // 112000 * 0.0001 = $11.2
@@ -252,6 +253,40 @@ var defaultTokens = [{
252
253
  decimals: 8,
253
254
  coingeckId: void 0,
254
255
  displayDecimals: 6,
256
+ priceProxySymbol: "WBTC",
257
+ priceCheckAmount: 1e-4
258
+ // 112000 * 0.0001 = $11.2
259
+ }, {
260
+ name: "xWBTC",
261
+ symbol: "xWBTC",
262
+ logo: "https://assets.strkfarm.com/integrations/tokens/xwbtc.svg",
263
+ address: ContractAddr.from("0x6a567e68c805323525fe1649adb80b03cddf92c23d2629a6779f54192dffc13"),
264
+ decimals: 8,
265
+ coingeckId: void 0,
266
+ displayDecimals: 6,
267
+ priceProxySymbol: "WBTC",
268
+ priceCheckAmount: 1e-4
269
+ // 112000 * 0.0001 = $11.2
270
+ }, {
271
+ name: "xsBTC",
272
+ symbol: "xsBTC",
273
+ logo: "https://assets.strkfarm.com/integrations/tokens/xsbtc_solv.svg",
274
+ address: ContractAddr.from("0x580f3dc564a7b82f21d40d404b3842d490ae7205e6ac07b1b7af2b4a5183dc9"),
275
+ decimals: 18,
276
+ coingeckId: void 0,
277
+ displayDecimals: 6,
278
+ priceProxySymbol: "WBTC",
279
+ priceCheckAmount: 1e-4
280
+ // 112000 * 0.0001 = $11.2
281
+ }, {
282
+ name: "xtBTC",
283
+ symbol: "xtBTC",
284
+ logo: "https://assets.strkfarm.com/integrations/tokens/xtbtc.svg",
285
+ address: ContractAddr.from("0x43a35c1425a0125ef8c171f1a75c6f31ef8648edcc8324b55ce1917db3f9b91"),
286
+ decimals: 8,
287
+ coingeckId: void 0,
288
+ displayDecimals: 6,
289
+ priceProxySymbol: "WBTC",
255
290
  priceCheckAmount: 1e-4
256
291
  // 112000 * 0.0001 = $11.2
257
292
  }];
@@ -341,9 +376,11 @@ var PricerBase = class {
341
376
  // src/modules/pricer.ts
342
377
  var Pricer = class extends PricerBase {
343
378
  // e.g. ETH/USDC
344
- constructor(config, tokens2) {
379
+ constructor(config, tokens2, refreshInterval = 3e4, staleTime = 6e4) {
345
380
  super(config, tokens2);
346
381
  this.prices = {};
382
+ this.refreshInterval = 3e4;
383
+ this.staleTime = 6e4;
347
384
  // code populates this map during runtime to determine which method to use for a given token
348
385
  // The method set will be the first one to try after first attempt
349
386
  this.methodToUse = {};
@@ -352,6 +389,8 @@ var Pricer = class extends PricerBase {
352
389
  */
353
390
  this.PRICE_API = `https://api.coinbase.com/v2/prices/{{PRICER_KEY}}/buy`;
354
391
  this.EKUBO_API = "https://quoter-mainnet-api.ekubo.org/{{AMOUNT}}/{{TOKEN_ADDRESS}}/0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8";
392
+ this.refreshInterval = refreshInterval;
393
+ this.staleTime = staleTime;
355
394
  }
356
395
  isReady() {
357
396
  const allPricesExist = Object.keys(this.prices).length === this.tokens.length;
@@ -384,10 +423,10 @@ var Pricer = class extends PricerBase {
384
423
  this._loadPrices();
385
424
  setInterval(() => {
386
425
  this._loadPrices();
387
- }, 3e4);
426
+ }, this.refreshInterval);
388
427
  }
389
428
  isStale(timestamp, tokenName) {
390
- const STALE_TIME = 6e4;
429
+ const STALE_TIME = this.staleTime;
391
430
  return (/* @__PURE__ */ new Date()).getTime() - timestamp.getTime() > STALE_TIME;
392
431
  }
393
432
  assertNotStale(timestamp, tokenName) {
@@ -413,13 +452,25 @@ var Pricer = class extends PricerBase {
413
452
  onUpdate(token.symbol);
414
453
  return;
415
454
  }
416
- const price = await this._getPrice(token);
417
- this.prices[token.symbol] = {
418
- price,
419
- timestamp: /* @__PURE__ */ new Date()
420
- };
455
+ if (token.priceProxySymbol) {
456
+ const proxyToken = this.tokens.find((t) => t.symbol === token.priceProxySymbol);
457
+ if (!proxyToken) {
458
+ throw new FatalError(`Price proxy token ${token.priceProxySymbol} not found`);
459
+ }
460
+ const price = await this._getPrice(proxyToken);
461
+ this.prices[token.symbol] = {
462
+ price,
463
+ timestamp: /* @__PURE__ */ new Date()
464
+ };
465
+ } else {
466
+ const price = await this._getPrice(token);
467
+ this.prices[token.symbol] = {
468
+ price,
469
+ timestamp: /* @__PURE__ */ new Date()
470
+ };
471
+ }
421
472
  onUpdate(token.symbol);
422
- logger.verbose(`Fetched price of ${token.name} as ${price}`);
473
+ logger.verbose(`Fetched price of ${token.name} as ${this.prices[token.symbol].price}`);
423
474
  break;
424
475
  } catch (error) {
425
476
  if (retry < MAX_RETRIES) {
@@ -3859,6 +3910,18 @@ async function getAPIUsingHeadlessBrowser(url) {
3859
3910
 
3860
3911
  // src/modules/harvests.ts
3861
3912
  import { Contract as Contract4, num as num3 } from "starknet";
3913
+
3914
+ // src/strategies/constants.ts
3915
+ var COMMON_CONTRACTS = [{
3916
+ address: ContractAddr.from("0x0636a3f51cc37f5729e4da4b1de6a8549a28f3c0d5bf3b17f150971e451ff9c2"),
3917
+ name: "Access Controller",
3918
+ sourceCodeUrl: "https://github.com/strkfarm/strkfarm-contracts/blob/main/src/components/accessControl.cairo"
3919
+ }];
3920
+ var ENDPOINTS = {
3921
+ VESU_BASE: "https://cache-server-t2me.onrender.com/vesu"
3922
+ };
3923
+
3924
+ // src/modules/harvests.ts
3862
3925
  var Harvests = class _Harvests {
3863
3926
  constructor(config) {
3864
3927
  this.config = config;
@@ -3918,7 +3981,7 @@ var EkuboHarvests = class extends Harvests {
3918
3981
  var VESU_REWARDS_CONTRACT = ContractAddr.from("0x0387f3eb1d98632fbe3440a9f1385Aec9d87b6172491d3Dd81f1c35A7c61048F");
3919
3982
  var VesuHarvests = class _VesuHarvests extends Harvests {
3920
3983
  async getHarvests(addr) {
3921
- const result = await fetch(`https://api.vesu.xyz/users/${addr.address}/strk-rewards/calldata`);
3984
+ const result = await fetch(`${ENDPOINTS.VESU_BASE}/users/${addr.address}/strk-rewards/calldata`);
3922
3985
  const data = await result.json();
3923
3986
  const rewardsContract = VESU_REWARDS_CONTRACT;
3924
3987
  const cls = await this.config.provider.getClassAt(rewardsContract.address);
@@ -9396,13 +9459,6 @@ var vesu_pools_default = {
9396
9459
  ]
9397
9460
  };
9398
9461
 
9399
- // src/strategies/constants.ts
9400
- var COMMON_CONTRACTS = [{
9401
- address: ContractAddr.from("0x0636a3f51cc37f5729e4da4b1de6a8549a28f3c0d5bf3b17f150971e451ff9c2"),
9402
- name: "Access Controller",
9403
- sourceCodeUrl: "https://github.com/strkfarm/strkfarm-contracts/blob/main/src/components/accessControl.cairo"
9404
- }];
9405
-
9406
9462
  // src/strategies/vesu-rebalance.tsx
9407
9463
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
9408
9464
  var VesuRebalance = class _VesuRebalance extends BaseStrategy {
@@ -9531,7 +9587,7 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
9531
9587
  };
9532
9588
  }
9533
9589
  static async getAllPossibleVerifiedPools(asset) {
9534
- const data = await getAPIUsingHeadlessBrowser("https://api.vesu.xyz/pools");
9590
+ const data = await getAPIUsingHeadlessBrowser(`${ENDPOINTS.VESU_BASE}/pools`);
9535
9591
  const verifiedPools = data.data.filter((d) => d.isVerified);
9536
9592
  const pools = verifiedPools.map((p) => {
9537
9593
  const hasMyAsset = p.assets.find((a) => asset.eqString(a.address));
@@ -9708,7 +9764,7 @@ var VesuRebalance = class _VesuRebalance extends BaseStrategy {
9708
9764
  let pools = [];
9709
9765
  try {
9710
9766
  const data = await getAPIUsingHeadlessBrowser(
9711
- "https://api.vesu.xyz/pools"
9767
+ `${ENDPOINTS.VESU_BASE}/pools`
9712
9768
  );
9713
9769
  pools = data.data;
9714
9770
  for (const pool of vesu_pools_default.data) {
@@ -15308,7 +15364,7 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
15308
15364
  * Calculates assets before and now in a given token of TVL per share to observe growth
15309
15365
  * @returns {Promise<number>} The weighted average APY across all pools
15310
15366
  */
15311
- async netAPY(blockIdentifier = "latest", sinceBlocks = 2e4) {
15367
+ async netAPY(blockIdentifier = "latest", sinceBlocks = 6e5) {
15312
15368
  const tvlNow = await this._getTVL(blockIdentifier);
15313
15369
  const supplyNow = await this.totalSupply(blockIdentifier);
15314
15370
  const priceNow = await this.getCurrentPrice(blockIdentifier);
@@ -16345,6 +16401,15 @@ var faqs2 = [
16345
16401
  ] })
16346
16402
  }
16347
16403
  ];
16404
+ function getLSTFAQs(lstSymbol) {
16405
+ return [
16406
+ ...faqs2,
16407
+ {
16408
+ question: "Why might I see a negative APY?",
16409
+ answer: `A negative APY can occur when ${lstSymbol}'s price drops on DEXes. This is usually temporary and tends to recover within a few days or a week.`
16410
+ }
16411
+ ];
16412
+ }
16348
16413
  var xSTRKSTRK = {
16349
16414
  name: "Ekubo xSTRK/STRK",
16350
16415
  description: /* @__PURE__ */ jsx3(Fragment2, {}),
@@ -16366,7 +16431,7 @@ var xSTRKSTRK = {
16366
16431
  netRisk: _corelatedPoolRiskFactors.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _corelatedPoolRiskFactors.reduce((acc, curr) => acc + curr.weight, 0),
16367
16432
  notARisks: getNoRiskTags(_corelatedPoolRiskFactors)
16368
16433
  },
16369
- apyMethodology: "APY based on 7-day historical performance, including fees and rewards.",
16434
+ apyMethodology: "APY based on 30-day historical performance, including fees and rewards.",
16370
16435
  additionalInfo: {
16371
16436
  newBounds: {
16372
16437
  lower: -1,
@@ -16383,13 +16448,7 @@ var xSTRKSTRK = {
16383
16448
  },
16384
16449
  quoteAsset: Global.getDefaultTokens().find((t) => t.symbol === "STRK")
16385
16450
  },
16386
- faqs: [
16387
- ...faqs2,
16388
- {
16389
- question: "Why might I see a negative APY?",
16390
- answer: "A negative APY can occur when xSTRK's price drops on DEXes. This is usually temporary and tends to recover within a few days or a week."
16391
- }
16392
- ],
16451
+ faqs: getLSTFAQs("xSTRK"),
16393
16452
  points: [{
16394
16453
  multiplier: 1,
16395
16454
  logo: "https://endur.fi/favicon.ico",
@@ -16398,6 +16457,78 @@ var xSTRKSTRK = {
16398
16457
  contractDetails: [],
16399
16458
  investmentSteps: []
16400
16459
  };
16460
+ var lstStrategies = [
16461
+ xSTRKSTRK,
16462
+ {
16463
+ ...xSTRKSTRK,
16464
+ name: "Ekubo xWBTC/WBTC",
16465
+ description: /* @__PURE__ */ jsx3(Fragment2, {}),
16466
+ address: ContractAddr.from(
16467
+ "0x2ea99b4971d3c277fa4a9b4beb7d4d7d169e683393a29eef263d5d57b4380a"
16468
+ ),
16469
+ launchBlock: 2338309,
16470
+ // must be same order as poolKey token0 and token1
16471
+ depositTokens: [
16472
+ Global.getDefaultTokens().find((t) => t.symbol === "WBTC"),
16473
+ Global.getDefaultTokens().find((t) => t.symbol === "xWBTC")
16474
+ ],
16475
+ additionalInfo: {
16476
+ ...xSTRKSTRK.additionalInfo,
16477
+ quoteAsset: Global.getDefaultTokens().find((t) => t.symbol === "WBTC"),
16478
+ lstContract: Global.getDefaultTokens().find((t) => t.symbol === "xWBTC").address
16479
+ },
16480
+ faqs: getLSTFAQs("xWBTC"),
16481
+ points: [],
16482
+ contractDetails: [],
16483
+ investmentSteps: []
16484
+ },
16485
+ {
16486
+ ...xSTRKSTRK,
16487
+ name: "Ekubo xtBTC/tBTC",
16488
+ description: /* @__PURE__ */ jsx3(Fragment2, {}),
16489
+ address: ContractAddr.from(
16490
+ "0x785dc3dfc4e80ef2690a99512481e3ed3a5266180adda5a47e856245d68a4af"
16491
+ ),
16492
+ launchBlock: 2344809,
16493
+ // must be same order as poolKey token0 and token1
16494
+ depositTokens: [
16495
+ Global.getDefaultTokens().find((t) => t.symbol === "xtBTC"),
16496
+ Global.getDefaultTokens().find((t) => t.symbol === "tBTC")
16497
+ ],
16498
+ additionalInfo: {
16499
+ ...xSTRKSTRK.additionalInfo,
16500
+ quoteAsset: Global.getDefaultTokens().find((t) => t.symbol === "tBTC"),
16501
+ lstContract: Global.getDefaultTokens().find((t) => t.symbol === "xtBTC").address
16502
+ },
16503
+ faqs: getLSTFAQs("xtBTC"),
16504
+ points: [],
16505
+ contractDetails: [],
16506
+ investmentSteps: []
16507
+ },
16508
+ {
16509
+ ...xSTRKSTRK,
16510
+ name: "Ekubo xsBTC/solvBTC",
16511
+ description: /* @__PURE__ */ jsx3(Fragment2, {}),
16512
+ address: ContractAddr.from(
16513
+ "0x3af1c7faa7c464cf2c494e988972ad1939f1103dbfb6e47e9bf0c47e49b14ef"
16514
+ ),
16515
+ launchBlock: 2344809,
16516
+ // must be same order as poolKey token0 and token1
16517
+ depositTokens: [
16518
+ Global.getDefaultTokens().find((t) => t.symbol === "xsBTC"),
16519
+ Global.getDefaultTokens().find((t) => t.symbol === "solvBTC")
16520
+ ],
16521
+ additionalInfo: {
16522
+ ...xSTRKSTRK.additionalInfo,
16523
+ quoteAsset: Global.getDefaultTokens().find((t) => t.symbol === "solvBTC"),
16524
+ lstContract: Global.getDefaultTokens().find((t) => t.symbol === "xsBTC").address
16525
+ },
16526
+ faqs: getLSTFAQs("xsBTC"),
16527
+ points: [],
16528
+ contractDetails: [],
16529
+ investmentSteps: []
16530
+ }
16531
+ ];
16401
16532
  var ETHUSDCRe7Strategy = {
16402
16533
  ...xSTRKSTRK,
16403
16534
  name: "Ekubo ETH/USDC",
@@ -16405,12 +16536,13 @@ var ETHUSDCRe7Strategy = {
16405
16536
  address: ContractAddr.from(
16406
16537
  "0x160d8fa4569ef6a12e6bf47cb943d7b5ebba8a41a69a14c1d943050ba5ff947"
16407
16538
  ),
16408
- launchBlock: 1501761,
16539
+ launchBlock: 1504232,
16409
16540
  // must be same order as poolKey token0 and token1
16410
16541
  depositTokens: [
16411
16542
  Global.getDefaultTokens().find((t) => t.symbol === "ETH"),
16412
16543
  Global.getDefaultTokens().find((t) => t.symbol === "USDC")
16413
16544
  ],
16545
+ apyMethodology: "APY based on 7-day historical performance, including fees and rewards.",
16414
16546
  additionalInfo: {
16415
16547
  newBounds: "Managed by Re7",
16416
16548
  truePrice: 1,
@@ -16446,7 +16578,7 @@ var RE7Strategies = [
16446
16578
  address: ContractAddr.from(
16447
16579
  "0x3a4f8debaf12af97bb911099bc011d63d6c208d4c5ba8e15d7f437785b0aaa2"
16448
16580
  ),
16449
- launchBlock: 1501761,
16581
+ launchBlock: 1506139,
16450
16582
  // must be same order as poolKey token0 and token1
16451
16583
  depositTokens: [
16452
16584
  Global.getDefaultTokens().find((t) => t.symbol === "USDC"),
@@ -16461,7 +16593,7 @@ var RE7Strategies = [
16461
16593
  address: ContractAddr.from(
16462
16594
  "0x351b36d0d9d8b40010658825adeeddb1397436cd41acd0ff6c6e23aaa8b5b30"
16463
16595
  ),
16464
- launchBlock: 1501762,
16596
+ launchBlock: 1504079,
16465
16597
  // must be same order as poolKey token0 and token1
16466
16598
  depositTokens: [
16467
16599
  Global.getDefaultTokens().find((t) => t.symbol === "STRK"),
@@ -16476,7 +16608,7 @@ var RE7Strategies = [
16476
16608
  address: ContractAddr.from(
16477
16609
  "0x4ce3024b0ee879009112d7b0e073f8a87153dd35b029347d4247ffe48d28f51"
16478
16610
  ),
16479
- launchBlock: 1501763,
16611
+ launchBlock: 1504149,
16480
16612
  // must be same order as poolKey token0 and token1
16481
16613
  depositTokens: [
16482
16614
  Global.getDefaultTokens().find((t) => t.symbol === "STRK"),
@@ -16491,7 +16623,7 @@ var RE7Strategies = [
16491
16623
  address: ContractAddr.from(
16492
16624
  "0x2bcaef2eb7706875a5fdc6853dd961a0590f850bc3a031c59887189b5e84ba1"
16493
16625
  ),
16494
- launchBlock: 1501764,
16626
+ launchBlock: 1506144,
16495
16627
  // must be same order as poolKey token0 and token1
16496
16628
  depositTokens: [
16497
16629
  Global.getDefaultTokens().find((t) => t.symbol === "WBTC"),
@@ -16521,7 +16653,7 @@ var RE7Strategies = [
16521
16653
  address: ContractAddr.from(
16522
16654
  "0x1c9232b8186d9317652f05055615f18a120c2ad9e5ee96c39e031c257fb945b"
16523
16655
  ),
16524
- launchBlock: 1501765,
16656
+ launchBlock: 1506145,
16525
16657
  // must be same order as poolKey token0 and token1
16526
16658
  depositTokens: [
16527
16659
  Global.getDefaultTokens().find((t) => t.symbol === "WBTC"),
@@ -16536,7 +16668,7 @@ var RE7Strategies = [
16536
16668
  address: ContractAddr.from(
16537
16669
  "0x1248e385c23a929a015ec298a26560fa7745bbd6e41a886550e337b02714b1b"
16538
16670
  ),
16539
- launchBlock: 1501766,
16671
+ launchBlock: 1506147,
16540
16672
  // must be same order as poolKey token0 and token1
16541
16673
  depositTokens: [
16542
16674
  Global.getDefaultTokens().find((t) => t.symbol === "WBTC"),
@@ -16546,7 +16678,7 @@ var RE7Strategies = [
16546
16678
  }
16547
16679
  ];
16548
16680
  var EkuboCLVaultStrategies = [
16549
- xSTRKSTRK,
16681
+ ...[lstStrategies[0]],
16550
16682
  ...RE7Strategies
16551
16683
  ];
16552
16684
  EkuboCLVaultStrategies.forEach((s) => {
@@ -16577,7 +16709,11 @@ EkuboCLVaultStrategies.forEach((s) => {
16577
16709
  /* @__PURE__ */ jsx3("h4", { style: { fontWeight: "bold" }, children: "Key points to note:" }),
16578
16710
  /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: "10px", color: "var(--chakra-colors-text_secondary)" }, children: [
16579
16711
  /* @__PURE__ */ jsx3("p", { style: {}, children: "1. During withdrawal, you may receive either or both tokens depending on market conditions and prevailing prices." }),
16580
- s.name.includes("xSTRK/STRK") && /* @__PURE__ */ jsx3("p", { style: {}, children: "2. Sometimes you might see a negative APY \u2014 this is usually not a big deal. It happens when xSTRK's price drops on DEXes, but things typically bounce back within a few days or a week." })
16712
+ s.additionalInfo.lstContract && /* @__PURE__ */ jsxs2("p", { style: {}, children: [
16713
+ "2. Sometimes you might see a negative APY \u2014 this is usually not a big deal. It happens when ",
16714
+ s.name.split(" ")[1].split("/")[0],
16715
+ "'s price drops on DEXes, but things typically bounce back within a few days or a week."
16716
+ ] })
16581
16717
  ] })
16582
16718
  ] })
16583
16719
  ] });
@@ -21359,7 +21495,7 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
21359
21495
  let pools = [];
21360
21496
  try {
21361
21497
  const data = await getAPIUsingHeadlessBrowser(
21362
- "https://api.vesu.xyz/pools"
21498
+ `${ENDPOINTS.VESU_BASE}/pools`
21363
21499
  );
21364
21500
  pools = data.data;
21365
21501
  for (const pool of vesu_pools_default.data) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strkfarm/sdk",
3
- "version": "1.1.5",
3
+ "version": "1.1.7",
4
4
  "description": "STRKFarm TS SDK (Meant for our internal use, but feel free to use it)",
5
5
  "typings": "dist/index.d.ts",
6
6
  "types": "dist/index.d.ts",
@@ -60,6 +60,7 @@
60
60
  "@avnu/avnu-sdk": "3.0.2",
61
61
  "@ericnordelo/strk-merkle-tree": "^1.0.0",
62
62
  "@noble/curves": "^1.9.7",
63
+ "@noble/hashes": "^2.0.0",
63
64
  "@scure/starknet": "^2.0.0",
64
65
  "bignumber.js": "4.0.4",
65
66
  "browser-assert": "^1.2.1",
package/src/global.ts CHANGED
@@ -84,6 +84,7 @@ const defaultTokens: TokenInfo[] = [{
84
84
  address: ContractAddr.from('0x0593e034dda23eea82d2ba9a30960ed42cf4a01502cc2351dc9b9881f9931a68'),
85
85
  decimals: 18,
86
86
  coingeckId: undefined,
87
+ priceProxySymbol: 'WBTC',
87
88
  displayDecimals: 6,
88
89
  priceCheckAmount: 0.0001, // 112000 * 0.0001 = $11.2
89
90
  }, {
@@ -94,6 +95,37 @@ const defaultTokens: TokenInfo[] = [{
94
95
  decimals: 8,
95
96
  coingeckId: undefined,
96
97
  displayDecimals: 6,
98
+ priceProxySymbol: 'WBTC',
99
+ priceCheckAmount: 0.0001, // 112000 * 0.0001 = $11.2
100
+ }, {
101
+ name: 'xWBTC',
102
+ symbol: 'xWBTC',
103
+ logo: 'https://assets.strkfarm.com/integrations/tokens/xwbtc.svg',
104
+ address: ContractAddr.from('0x6a567e68c805323525fe1649adb80b03cddf92c23d2629a6779f54192dffc13'),
105
+ decimals: 8,
106
+ coingeckId: undefined,
107
+ displayDecimals: 6,
108
+ priceProxySymbol: 'WBTC',
109
+ priceCheckAmount: 0.0001, // 112000 * 0.0001 = $11.2
110
+ }, {
111
+ name: 'xsBTC',
112
+ symbol: 'xsBTC',
113
+ logo: 'https://assets.strkfarm.com/integrations/tokens/xsbtc_solv.svg',
114
+ address: ContractAddr.from('0x580f3dc564a7b82f21d40d404b3842d490ae7205e6ac07b1b7af2b4a5183dc9'),
115
+ decimals: 18,
116
+ coingeckId: undefined,
117
+ displayDecimals: 6,
118
+ priceProxySymbol: 'WBTC',
119
+ priceCheckAmount: 0.0001, // 112000 * 0.0001 = $11.2
120
+ }, {
121
+ name: 'xtBTC',
122
+ symbol: 'xtBTC',
123
+ logo: 'https://assets.strkfarm.com/integrations/tokens/xtbtc.svg',
124
+ address: ContractAddr.from('0x43a35c1425a0125ef8c171f1a75c6f31ef8648edcc8324b55ce1917db3f9b91'),
125
+ decimals: 8,
126
+ coingeckId: undefined,
127
+ displayDecimals: 6,
128
+ priceProxySymbol: 'WBTC',
97
129
  priceCheckAmount: 0.0001, // 112000 * 0.0001 = $11.2
98
130
  }]
99
131
  const tokens: TokenInfo[] = defaultTokens;
@@ -33,6 +33,7 @@ export interface TokenInfo {
33
33
  logo: string;
34
34
  coingeckId?: string;
35
35
  displayDecimals: number;
36
+ priceProxySymbol?: string; // for tokens like illiquid tokens, we use a proxy symbol to get the price
36
37
  priceCheckAmount?: number; // for tokens like BTC, doing 1BTC price check may not be ideal, esp on illiquid netwrks like sn
37
38
  }
38
39
 
@@ -4,6 +4,7 @@ import { IConfig } from "@/interfaces";
4
4
  import { assert } from "@/utils";
5
5
  import { Contract, num } from "starknet";
6
6
  import { ERC20 } from "./erc20";
7
+ import { ENDPOINTS } from "@/strategies/constants";
7
8
 
8
9
  export interface HarvestInfo {
9
10
  rewardsContract: ContractAddr,
@@ -87,7 +88,7 @@ export const VESU_REWARDS_CONTRACT = ContractAddr.from('0x0387f3eb1d98632fbe3440
87
88
 
88
89
  export class VesuHarvests extends Harvests {
89
90
  async getHarvests(addr: ContractAddr): Promise<HarvestInfo[]> {
90
- const result = await fetch(`https://api.vesu.xyz/users/${addr.address}/strk-rewards/calldata`);
91
+ const result = await fetch(`${ENDPOINTS.VESU_BASE}/users/${addr.address}/strk-rewards/calldata`);
91
92
  const data = await result.json();
92
93
  const rewardsContract = VESU_REWARDS_CONTRACT;
93
94
 
@@ -16,6 +16,9 @@ export class Pricer extends PricerBase {
16
16
  [key: string]: PriceInfo
17
17
  } = {}
18
18
 
19
+ refreshInterval = 30000;
20
+ staleTime = 60000;
21
+
19
22
  // code populates this map during runtime to determine which method to use for a given token
20
23
  // The method set will be the first one to try after first attempt
21
24
  private methodToUse: {[tokenSymbol: string]: 'Ekubo' | 'Coinbase' | 'Coinmarketcap'} = {};
@@ -26,8 +29,10 @@ export class Pricer extends PricerBase {
26
29
  protected PRICE_API = `https://api.coinbase.com/v2/prices/{{PRICER_KEY}}/buy`;
27
30
  protected EKUBO_API = 'https://quoter-mainnet-api.ekubo.org/{{AMOUNT}}/{{TOKEN_ADDRESS}}/0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8'; // e.g. ETH/USDC
28
31
 
29
- constructor(config: IConfig, tokens: TokenInfo[]) {
32
+ constructor(config: IConfig, tokens: TokenInfo[], refreshInterval = 30000, staleTime = 60000) {
30
33
  super(config, tokens);
34
+ this.refreshInterval = refreshInterval;
35
+ this.staleTime = staleTime;
31
36
  }
32
37
 
33
38
  isReady() {
@@ -64,11 +69,11 @@ export class Pricer extends PricerBase {
64
69
  this._loadPrices();
65
70
  setInterval(() => {
66
71
  this._loadPrices();
67
- }, 30000);
72
+ }, this.refreshInterval);
68
73
  }
69
74
 
70
75
  isStale(timestamp: Date, tokenName: string) {
71
- const STALE_TIME = 60000;
76
+ const STALE_TIME = this.staleTime;
72
77
  return (new Date().getTime() - timestamp.getTime()) > STALE_TIME;
73
78
  }
74
79
 
@@ -97,13 +102,25 @@ export class Pricer extends PricerBase {
97
102
  return;
98
103
  }
99
104
 
100
- const price = await this._getPrice(token);
101
- this.prices[token.symbol] = {
102
- price,
103
- timestamp: new Date()
105
+ if (token.priceProxySymbol) {
106
+ const proxyToken = this.tokens.find(t => t.symbol === token.priceProxySymbol);
107
+ if (!proxyToken) {
108
+ throw new FatalError(`Price proxy token ${token.priceProxySymbol} not found`);
109
+ }
110
+ const price = await this._getPrice(proxyToken);
111
+ this.prices[token.symbol] = {
112
+ price,
113
+ timestamp: new Date()
114
+ }
115
+ } else {
116
+ const price = await this._getPrice(token);
117
+ this.prices[token.symbol] = {
118
+ price,
119
+ timestamp: new Date()
120
+ }
104
121
  }
105
122
  onUpdate(token.symbol);
106
- logger.verbose(`Fetched price of ${token.name} as ${price}`);
123
+ logger.verbose(`Fetched price of ${token.name} as ${this.prices[token.symbol].price}`);
107
124
  break;
108
125
  } catch (error: any) {
109
126
  if (retry < MAX_RETRIES) {
@@ -4,4 +4,8 @@ export const COMMON_CONTRACTS = [{
4
4
  address: ContractAddr.from("0x0636a3f51cc37f5729e4da4b1de6a8549a28f3c0d5bf3b17f150971e451ff9c2"),
5
5
  name: "Access Controller",
6
6
  sourceCodeUrl: "https://github.com/strkfarm/strkfarm-contracts/blob/main/src/components/accessControl.cairo",
7
- }];
7
+ }];
8
+
9
+ export const ENDPOINTS = {
10
+ VESU_BASE: "https://cache-server-t2me.onrender.com/vesu"
11
+ }