@scallop-io/sui-scallop-sdk 1.3.2-alpha.3 → 1.3.3-alpha.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.
package/dist/index.mjs CHANGED
@@ -254,11 +254,18 @@ var voloCoinIds = {
254
254
  var sCoinIds = {
255
255
  susdc: "0x854950aa624b1df59fe64e630b2ba7c550642e9342267a33061d59fb31582da5::scallop_usdc::SCALLOP_USDC",
256
256
  ssbeth: "0xb14f82d8506d139eacef109688d1b71e7236bcce9b2c0ad526abcd6aa5be7de0::scallop_sb_eth::SCALLOP_SB_ETH",
257
- ssui: "0xaafc4f740de0dd0dde642a31148fb94517087052f19afb0f7bed1dc41a50c77b::scallop_sui::SCALLOP_SUI",
257
+ // TODO: Change this to the correct value on production release
258
+ ssui: "0xf569919046f19a0c40b519ecfbb6ca0319698cd5908716c29b62ef56541f298b::scallop_sui::SCALLOP_SUI",
259
+ // ssui: '0xaafc4f740de0dd0dde642a31148fb94517087052f19afb0f7bed1dc41a50c77b::scallop_sui::SCALLOP_SUI',
258
260
  scetus: "0xea346ce428f91ab007210443efcea5f5cdbbb3aae7e9affc0ca93f9203c31f0c::scallop_cetus::SCALLOP_CETUS",
259
261
  ssca: "0x5ca17430c1d046fae9edeaa8fd76c7b4193a00d764a0ecfa9418d733ad27bc1e::scallop_sca::SCALLOP_SCA",
260
- swusdc: "0xad4d71551d31092230db1fd482008ea42867dbf27b286e9c70a79d2a6191d58d::scallop_wormhole_usdc::SCALLOP_WORMHOLE_USDC",
261
- swusdt: "0xe6e5a012ec20a49a3d1d57bd2b67140b96cd4d3400b9d79e541f7bdbab661f95::scallop_wormhole_usdt::SCALLOP_WORMHOLE_USDT",
262
+ // TODO: Change this to the correct value on production release
263
+ swusdc: "0xf5447c4305a486d8c8557559887c2c39449ddb5e748f15d33946d02a1663c158::scallop_wormhole_usdc::SCALLOP_WORMHOLE_USDC",
264
+ // '0xad4d71551d31092230db1fd482008ea42867dbf27b286e9c70a79d2a6191d58d::scallop_wormhole_usdc::SCALLOP_WORMHOLE_USDC',
265
+ swusdt: (
266
+ // '0xe6e5a012ec20a49a3d1d57bd2b67140b96cd4d3400b9d79e541f7bdbab661f95::scallop_wormhole_usdt::SCALLOP_WORMHOLE_USDT',
267
+ "0xac781d9f73058ff5e69f9bf8dde32f2e8c71c66d7fe8497fc83b2d9182254b22::scallop_wormhole_usdt::SCALLOP_WORMHOLE_USDT"
268
+ ),
262
269
  sweth: "0x67540ceb850d418679e69f1fb6b2093d6df78a2a699ffc733f7646096d552e9b::scallop_wormhole_eth::SCALLOP_WORMHOLE_ETH",
263
270
  safsui: "0x00671b1fa2a124f5be8bdae8b91ee711462c5d9e31bda232e70fd9607b523c88::scallop_af_sui::SCALLOP_AF_SUI",
264
271
  shasui: "0x9a2376943f7d22f88087c259c5889925f332ca4347e669dc37d54c2bf651af3c::scallop_ha_sui::SCALLOP_HA_SUI",
@@ -341,10 +348,7 @@ var queryKeys = {
341
348
  "getDynamicFieldObject",
342
349
  {
343
350
  parentId: input?.parentId,
344
- name: {
345
- type: input?.name?.type,
346
- value: input?.name?.value
347
- }
351
+ name: JSON.stringify(input?.name ?? void 0)
348
352
  }
349
353
  ],
350
354
  getTotalVeScaTreasuryAmount: (refreshArgs, vescaAmountArgs) => [
@@ -362,10 +366,10 @@ var queryKeys = {
362
366
  ]
363
367
  },
364
368
  oracle: {
365
- getPythLatestPriceFeed: (pythPriceId) => [
369
+ getPythLatestPriceFeed: (pythPriceId, endpoint) => [
366
370
  "oracle",
367
371
  "getPythPriceId",
368
- { pythPriceId }
372
+ { pythPriceId, endpoint }
369
373
  ]
370
374
  }
371
375
  };
@@ -377,260 +381,684 @@ var MAX_LOCK_DURATION = MAX_LOCK_ROUNDS * UNLOCK_ROUND_DURATION;
377
381
  var MIN_INITIAL_LOCK_AMOUNT = 1e10;
378
382
  var MIN_TOP_UP_AMOUNT = 1e9;
379
383
 
380
- // src/models/scallop.ts
381
- import { SuiKit as SuiKit7 } from "@scallop-io/sui-kit";
382
-
383
- // src/models/scallopAddress.ts
384
- import { SuiKit } from "@scallop-io/sui-kit";
385
-
386
- // src/models/scallopCache.ts
387
- import { QueryClient } from "@tanstack/query-core";
388
- import {
389
- SuiTxBlock,
390
- normalizeStructTag as normalizeStructTag2
391
- } from "@scallop-io/sui-kit";
392
-
393
- // src/constants/cache.ts
394
- var DEFAULT_CACHE_OPTIONS = {
395
- defaultOptions: {
396
- queries: {
397
- staleTime: 5e3,
398
- gcTime: 5e3
399
- }
400
- }
401
- };
402
-
403
- // src/utils/builder.ts
404
- var requireSender = (txBlock) => {
405
- const sender = txBlock.blockData.sender;
406
- if (!sender) {
407
- throw new Error("Sender is required");
408
- }
409
- return sender;
410
- };
411
- var checkVesca = (prevUnlockAtInMillisTimestamp) => {
412
- if (prevUnlockAtInMillisTimestamp === void 0) {
413
- throw new Error("veSca not found");
414
- }
415
- };
416
- var checkVescaExpired = (prevUnlockAtInMillisTimestamp) => {
417
- if (prevUnlockAtInMillisTimestamp <= (/* @__PURE__ */ new Date()).getTime()) {
418
- throw new Error("veSca is expired, use renewExpiredVeScaQuick instead");
419
- }
420
- };
421
- var checkExtendLockPeriod = (lockPeriodInDays, newUnlockAtInSecondTimestamp, prevUnlockAtInMillisTimestamp) => {
422
- checkVesca(prevUnlockAtInMillisTimestamp);
423
- checkVescaExpired(prevUnlockAtInMillisTimestamp);
424
- const prevUnlockAtInSecondTimestamp = Math.floor(
425
- prevUnlockAtInMillisTimestamp / 1e3
426
- );
427
- if (lockPeriodInDays < 1) {
428
- throw new Error("Minimum lock period is 1 day");
429
- }
430
- const availableLockPeriodInDays = Math.floor(
431
- (newUnlockAtInSecondTimestamp - prevUnlockAtInSecondTimestamp) / UNLOCK_ROUND_DURATION
432
- );
433
- if (lockPeriodInDays > availableLockPeriodInDays) {
434
- throw new Error(
435
- `Cannot extend lock period by ${lockPeriodInDays} days, maximum lock period is ~4 years (${MAX_LOCK_ROUNDS} days), remaining lock period is ${MAX_LOCK_ROUNDS - availableLockPeriodInDays}`
436
- );
437
- }
438
- };
439
- var checkLockSca = (scaAmountOrCoin, lockPeriodInDays, newUnlockAtInSecondTimestamp, prevUnlockAtInMillisTimestamp) => {
440
- const prevUnlockAtInSecondTimestamp = prevUnlockAtInMillisTimestamp ? Math.floor(prevUnlockAtInMillisTimestamp / 1e3) : void 0;
441
- const isInitialLock = !prevUnlockAtInSecondTimestamp;
442
- const isLockExpired = !isInitialLock && prevUnlockAtInSecondTimestamp * 1e3 <= (/* @__PURE__ */ new Date()).getTime();
443
- if (isInitialLock || isLockExpired) {
444
- if (scaAmountOrCoin !== void 0 && lockPeriodInDays !== void 0) {
445
- if (lockPeriodInDays <= 0) {
446
- throw new Error("Lock period must be greater than 0");
447
- }
448
- if (typeof scaAmountOrCoin === "number" && scaAmountOrCoin < MIN_INITIAL_LOCK_AMOUNT) {
449
- throw new Error(
450
- `Minimum lock amount for ${isLockExpired ? "renewing expired veSca" : "initial lock"} is 10 SCA`
451
- );
452
- }
453
- const extendLockPeriodInSecond = lockPeriodInDays * UNLOCK_ROUND_DURATION;
454
- if (extendLockPeriodInSecond > MAX_LOCK_DURATION) {
455
- throw new Error(
456
- `Maximum lock period is ~4 years (${MAX_LOCK_ROUNDS} days)`
457
- );
458
- }
459
- } else {
460
- throw new Error(
461
- `SCA amount and lock period is required for ${isLockExpired ? "renewing expired veSca" : "initial lock"}`
462
- );
463
- }
464
- } else {
465
- checkVesca(prevUnlockAtInMillisTimestamp);
466
- checkVescaExpired(prevUnlockAtInMillisTimestamp);
467
- if (typeof scaAmountOrCoin === "number" && scaAmountOrCoin < MIN_TOP_UP_AMOUNT) {
468
- throw new Error("Minimum top up amount is 1 SCA");
469
- }
470
- if (newUnlockAtInSecondTimestamp && lockPeriodInDays) {
471
- checkExtendLockPeriod(
472
- lockPeriodInDays,
473
- newUnlockAtInSecondTimestamp,
474
- prevUnlockAtInMillisTimestamp
475
- );
476
- }
477
- }
478
- };
479
- var checkExtendLockAmount = (scaAmount, prevUnlockAtInMillisTimestamp) => {
480
- checkVesca(prevUnlockAtInMillisTimestamp);
481
- checkVescaExpired(prevUnlockAtInMillisTimestamp);
482
- if (scaAmount < MIN_TOP_UP_AMOUNT) {
483
- throw new Error("Minimum top up amount is 1 SCA");
484
- }
485
- const isInitialLock = !prevUnlockAtInMillisTimestamp;
486
- const isLockExpired = !isInitialLock && prevUnlockAtInMillisTimestamp <= (/* @__PURE__ */ new Date()).getTime();
487
- if (isLockExpired) {
488
- throw new Error("veSca is expired, use renewExpiredVeScaQuick instead");
489
- }
490
- };
491
- var checkRenewExpiredVeSca = (scaAmount, lockPeriodInDays, prevUnlockAtInMillisTimestamp) => {
492
- if (!prevUnlockAtInMillisTimestamp || prevUnlockAtInMillisTimestamp > (/* @__PURE__ */ new Date()).getTime()) {
493
- throw new Error("Renew method can only be used for expired veSca");
494
- }
495
- if (scaAmount < MIN_INITIAL_LOCK_AMOUNT) {
496
- throw new Error("Minimum lock amount for renewing expired vesca 10 SCA");
497
- }
498
- const extendLockPeriodInSecond = lockPeriodInDays * UNLOCK_ROUND_DURATION;
499
- if (extendLockPeriodInSecond >= MAX_LOCK_DURATION - UNLOCK_ROUND_DURATION) {
500
- throw new Error(
501
- `Maximum lock period is ~4 years (${MAX_LOCK_ROUNDS - 1} days)`
502
- );
503
- }
504
- };
505
-
506
- // src/utils/query.ts
507
- import BigNumber from "bignumber.js";
508
- import { normalizeStructTag, parseStructTag } from "@mysten/sui/utils";
509
- var parseOriginMarketPoolData = (originMarketPoolData) => {
510
- return {
511
- coinType: normalizeStructTag(originMarketPoolData.type.name),
512
- // Parse origin data required for basic calculations.
513
- maxBorrowRate: Number(originMarketPoolData.maxBorrowRate.value) / 2 ** 32,
514
- borrowRate: Number(originMarketPoolData.interestRate.value) / 2 ** 32,
515
- borrowRateScale: Number(originMarketPoolData.interestRateScale),
516
- borrowIndex: Number(originMarketPoolData.borrowIndex),
517
- lastUpdated: Number(originMarketPoolData.lastUpdated),
518
- cashAmount: Number(originMarketPoolData.cash),
519
- debtAmount: Number(originMarketPoolData.debt),
520
- marketCoinSupplyAmount: Number(originMarketPoolData.marketCoinSupply),
521
- reserveAmount: Number(originMarketPoolData.reserve),
522
- reserveFactor: Number(originMarketPoolData.reserveFactor.value) / 2 ** 32,
523
- borrowWeight: Number(originMarketPoolData.borrowWeight.value) / 2 ** 32,
524
- borrowFee: Number(originMarketPoolData.borrowFeeRate.value) / 2 ** 32,
525
- // Parse origin data required for additional display.
526
- baseBorrowRate: Number(originMarketPoolData.baseBorrowRatePerSec.value) / 2 ** 32,
527
- borrowRateOnHighKink: Number(originMarketPoolData.borrowRateOnHighKink.value) / 2 ** 32,
528
- borrowRateOnMidKink: Number(originMarketPoolData.borrowRateOnMidKink.value) / 2 ** 32,
529
- highKink: Number(originMarketPoolData.highKink.value) / 2 ** 32,
530
- midKink: Number(originMarketPoolData.midKink.value) / 2 ** 32,
531
- minBorrowAmount: Number(originMarketPoolData.minBorrowAmount)
532
- };
533
- };
534
- var calculateMarketPoolData = (utils, parsedMarketPoolData) => {
535
- const poolCoinName = utils.parseCoinNameFromType(
536
- parsedMarketPoolData.coinType
537
- );
538
- const coinDecimal = utils.getCoinDecimal(poolCoinName);
539
- const borrowYearFactor = 24 * 365 * 3600;
540
- const baseBorrowApr = parsedMarketPoolData.baseBorrowRate * borrowYearFactor / parsedMarketPoolData.borrowRateScale;
541
- const borrowAprOnHighKink = parsedMarketPoolData.borrowRateOnHighKink * borrowYearFactor / parsedMarketPoolData.borrowRateScale;
542
- const borrowAprOnMidKink = parsedMarketPoolData.borrowRateOnMidKink * borrowYearFactor / parsedMarketPoolData.borrowRateScale;
543
- const maxBorrowApr = parsedMarketPoolData.maxBorrowRate * borrowYearFactor / parsedMarketPoolData.borrowRateScale;
544
- const borrowApr = parsedMarketPoolData.borrowRate * borrowYearFactor / parsedMarketPoolData.borrowRateScale;
545
- const timeDelta = Math.floor((/* @__PURE__ */ new Date()).getTime() / 1e3) - parsedMarketPoolData.lastUpdated;
546
- const borrowIndexDelta = BigNumber(parsedMarketPoolData.borrowIndex).multipliedBy(
547
- BigNumber(timeDelta).multipliedBy(parsedMarketPoolData.borrowRate)
548
- ).dividedBy(parsedMarketPoolData.borrowRateScale);
549
- const currentBorrowIndex = BigNumber(parsedMarketPoolData.borrowIndex).plus(
550
- borrowIndexDelta
551
- );
552
- const growthInterest = BigNumber(currentBorrowIndex).dividedBy(parsedMarketPoolData.borrowIndex).minus(1);
553
- const increasedDebtAmount = BigNumber(
554
- parsedMarketPoolData.debtAmount
555
- ).multipliedBy(growthInterest);
556
- const borrowAmount = increasedDebtAmount.plus(
557
- parsedMarketPoolData.debtAmount
558
- );
559
- const borrowCoin = borrowAmount.shiftedBy(-1 * coinDecimal);
560
- const reserveAmount = BigNumber(parsedMarketPoolData.reserveAmount).plus(
561
- increasedDebtAmount.multipliedBy(parsedMarketPoolData.reserveFactor)
562
- );
563
- const reserveCoin = reserveAmount.shiftedBy(-1 * coinDecimal);
564
- const supplyAmount = BigNumber(borrowAmount).plus(
565
- Math.max(parsedMarketPoolData.cashAmount - reserveAmount.toNumber(), 0)
566
- );
567
- const supplyCoin = supplyAmount.shiftedBy(-1 * coinDecimal);
568
- let utilizationRate = BigNumber(borrowAmount).dividedBy(supplyAmount);
569
- utilizationRate = utilizationRate.isFinite() ? utilizationRate : BigNumber(0);
570
- let supplyApr = BigNumber(borrowApr).multipliedBy(utilizationRate).multipliedBy(1 - parsedMarketPoolData.reserveFactor);
571
- supplyApr = supplyApr.isFinite() ? supplyApr : BigNumber(0);
572
- let conversionRate = supplyAmount.dividedBy(
573
- parsedMarketPoolData.marketCoinSupplyAmount
574
- );
575
- conversionRate = conversionRate.isFinite() && !conversionRate.isNaN() ? conversionRate : BigNumber(1);
576
- return {
577
- baseBorrowApr,
578
- baseBorrowApy: utils.parseAprToApy(baseBorrowApr),
579
- borrowAprOnHighKink,
580
- borrowApyOnHighKink: utils.parseAprToApy(borrowAprOnHighKink),
581
- borrowAprOnMidKink,
582
- borrowApyOnMidKink: utils.parseAprToApy(borrowAprOnMidKink),
583
- maxBorrowApr,
584
- maxBorrowApy: utils.parseAprToApy(maxBorrowApr),
585
- borrowApr: Math.min(borrowApr, maxBorrowApr),
586
- borrowApy: Math.min(
587
- utils.parseAprToApy(borrowApr),
588
- utils.parseAprToApy(maxBorrowApr)
589
- ),
590
- borrowIndex: currentBorrowIndex.toNumber(),
591
- growthInterest: growthInterest.toNumber(),
592
- supplyAmount: supplyAmount.toNumber(),
593
- supplyCoin: supplyCoin.toNumber(),
594
- borrowAmount: borrowAmount.toNumber(),
595
- borrowCoin: borrowCoin.toNumber(),
596
- reserveAmount: reserveAmount.toNumber(),
597
- reserveCoin: reserveCoin.toNumber(),
598
- utilizationRate: utilizationRate.toNumber(),
599
- supplyApr: supplyApr.toNumber(),
600
- supplyApy: utils.parseAprToApy(supplyApr.toNumber()),
601
- conversionRate: conversionRate.toNumber()
602
- };
603
- };
604
- var parseOriginMarketCollateralData = (originMarketCollateralData) => {
605
- const divisor = 2 ** 32;
606
- return {
607
- coinType: normalizeStructTag(originMarketCollateralData.type.name),
608
- collateralFactor: Number(originMarketCollateralData.collateralFactor.value) / divisor,
609
- liquidationFactor: Number(originMarketCollateralData.liquidationFactor.value) / divisor,
610
- liquidationDiscount: Number(originMarketCollateralData.liquidationDiscount.value) / divisor,
611
- liquidationPanelty: Number(originMarketCollateralData.liquidationPanelty.value) / divisor,
612
- liquidationReserveFactor: Number(originMarketCollateralData.liquidationReserveFactor.value) / divisor,
613
- maxCollateralAmount: Number(originMarketCollateralData.maxCollateralAmount),
614
- totalCollateralAmount: Number(
615
- originMarketCollateralData.totalCollateralAmount
616
- )
617
- };
618
- };
619
- var calculateMarketCollateralData = (utils, parsedMarketCollateralData) => {
620
- const collateralCoinName = utils.parseCoinNameFromType(
621
- parsedMarketCollateralData.coinType
622
- );
623
- const coinDecimal = utils.getCoinDecimal(collateralCoinName);
624
- const maxCollateralCoin = BigNumber(
625
- parsedMarketCollateralData.maxCollateralAmount
626
- ).shiftedBy(-1 * coinDecimal);
627
- const depositCoin = BigNumber(
628
- parsedMarketCollateralData.totalCollateralAmount
629
- ).shiftedBy(-1 * coinDecimal);
630
- return {
631
- maxDepositAmount: parsedMarketCollateralData.maxCollateralAmount,
632
- maxDepositCoin: maxCollateralCoin.toNumber(),
633
- depositAmount: parsedMarketCollateralData.totalCollateralAmount,
384
+ // src/constants/testAddress.ts
385
+ var TEST_ADDRESSES = {
386
+ core: {
387
+ // version:
388
+ // '0x07871c4b3c847a0f674510d4978d5cf6f960452795e8ff6f189fd2088a3f6ac7',
389
+ version: "0xd318de9b0f6873879a82cbfcc2daa1d1591a8b54e7cea9f4b567da63c692a52b",
390
+ versionCap: "0x590a4011cb649b3878f3ea14b3a78674642a9548d79b7e091ef679574b158a07",
391
+ // object:
392
+ // '0xefe8b36d5b2e43728cc323298626b83177803521d195cfb11e15b910e892fddf',
393
+ object: "0x6c23585e940a989588432509107e98bae06dbca4e333f26d0635d401b3c7c76d",
394
+ // market:
395
+ // '0xa757975255146dc9686aa823b7838b507f315d704f428cbadad2f4ea061939d9',
396
+ market: "0x9d6434e97f3f98fd9b0c0e1dca22632073985abcd22541feae7ee1e34cbe3af2",
397
+ adminCap: "0x09689d018e71c337d9db6d67cbca06b74ed92196103624028ccc3ecea411777c",
398
+ coinDecimalsRegistry: "0x200abe9bf19751cc566ae35aa58e2b7e4ff688fc1130f8d8909ea09bc137d668",
399
+ // obligationAccessStore:
400
+ // '0x733e30b7c94d619d78cb8f5bc4bfbb759ced9a531239028caabb2474e5be59c9',
401
+ obligationAccessStore: "0x46e9b44a77ee9c9d33cc2689ecdfbb8f681935cbc6bdf6ac3df048e396c36c82",
402
+ coins: {
403
+ usdc: {
404
+ id: "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7",
405
+ metaData: "0x69b7a7c3c200439c1b5f3b19d7d495d5966d5f08de66c69276152f8db3992ec6",
406
+ treasury: "",
407
+ oracle: {
408
+ supra: "",
409
+ switchboard: "",
410
+ pyth: {
411
+ feed: "eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a",
412
+ feedObject: "0x5dec622733a204ca27f5a90d8c2fad453cc6665186fd5dff13a83d0b6c9027ab"
413
+ }
414
+ }
415
+ },
416
+ cetus: {
417
+ id: "0x06864a6f921804860930db6ddbe2e16acdf8504495ea7481637a1c8b9a8fe54b",
418
+ metaData: "0x4c0dce55eff2db5419bbd2d239d1aa22b4a400c01bbb648b058a9883989025da",
419
+ treasury: "",
420
+ oracle: {
421
+ supra: "",
422
+ switchboard: "",
423
+ pyth: {
424
+ feed: "e5b274b2611143df055d6e7cd8d93fe1961716bcd4dca1cad87a83bc1e78c1ef",
425
+ feedObject: "0x24c0247fb22457a719efac7f670cdc79be321b521460bd6bd2ccfa9f80713b14"
426
+ }
427
+ }
428
+ },
429
+ wapt: {
430
+ id: "0x3a5143bb1196e3bcdfab6203d1683ae29edd26294fc8bfeafe4aaa9d2704df37",
431
+ metaData: "0xc969c5251f372c0f34c32759f1d315cf1ea0ee5e4454b52aea08778eacfdd0a8",
432
+ treasury: "",
433
+ oracle: {
434
+ supra: "",
435
+ switchboard: "",
436
+ pyth: {
437
+ feed: "03ae4db29ed4ae33d323568895aa00337e658e348b37509f5372ae51f0af00d5",
438
+ feedObject: "0x7c5b7837c44a69b469325463ac0673ac1aa8435ff44ddb4191c9ae380463647f"
439
+ }
440
+ }
441
+ },
442
+ wsol: {
443
+ id: "0xb7844e289a8410e50fb3ca48d69eb9cf29e27d223ef90353fe1bd8e27ff8f3f8",
444
+ metaData: "0x4d2c39082b4477e3e79dc4562d939147ab90c42fc5f3e4acf03b94383cd69b6e",
445
+ treasury: "",
446
+ oracle: {
447
+ supra: "",
448
+ switchboard: "",
449
+ pyth: {
450
+ feed: "ef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d",
451
+ feedObject: "0x9d0d275efbd37d8a8855f6f2c761fa5983293dd8ce202ee5196626de8fcd4469"
452
+ }
453
+ }
454
+ },
455
+ wbtc: {
456
+ id: "0x027792d9fed7f9844eb4839566001bb6f6cb4804f66aa2da6fe1ee242d896881",
457
+ metaData: "0x5d3c6e60eeff8a05b693b481539e7847dfe33013e7070cdcb387f5c0cac05dfd",
458
+ treasury: "",
459
+ oracle: {
460
+ supra: "",
461
+ switchboard: "",
462
+ pyth: {
463
+ feed: "e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43",
464
+ feedObject: "0x9a62b4863bdeaabdc9500fce769cf7e72d5585eeb28a6d26e4cafadc13f76ab2"
465
+ }
466
+ }
467
+ },
468
+ weth: {
469
+ id: "0xaf8cd5edc19c4512f4259f0bee101a40d41ebed738ade5874359610ef8eeced5",
470
+ metaData: "0x8900e4ceede3363bef086d6b50ca89d816d0e90bf6bc46efefe1f8455e08f50f",
471
+ treasury: "",
472
+ oracle: {
473
+ supra: "",
474
+ switchboard: "",
475
+ pyth: {
476
+ feed: "ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace",
477
+ feedObject: "0x9193fd47f9a0ab99b6e365a464c8a9ae30e6150fc37ed2a89c1586631f6fc4ab"
478
+ }
479
+ }
480
+ },
481
+ wusdc: {
482
+ id: "0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf",
483
+ metaData: "0x4fbf84f3029bd0c0b77164b587963be957f853eccf834a67bb9ecba6ec80f189",
484
+ treasury: "",
485
+ oracle: {
486
+ supra: "",
487
+ switchboard: "",
488
+ pyth: {
489
+ feed: "eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a",
490
+ feedObject: "0x5dec622733a204ca27f5a90d8c2fad453cc6665186fd5dff13a83d0b6c9027ab"
491
+ }
492
+ }
493
+ },
494
+ wusdt: {
495
+ id: "0xc060006111016b8a020ad5b33834984a437aaa7d3c74c18e09a95d48aceab08c",
496
+ metaData: "0xfb0e3eb97dd158a5ae979dddfa24348063843c5b20eb8381dd5fa7c93699e45c",
497
+ treasury: "",
498
+ oracle: {
499
+ supra: "",
500
+ switchboard: "",
501
+ pyth: {
502
+ feed: "2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b",
503
+ feedObject: "0x985e3db9f93f76ee8bace7c3dd5cc676a096accd5d9e09e9ae0fb6e492b14572"
504
+ }
505
+ }
506
+ },
507
+ sui: {
508
+ id: "0x0000000000000000000000000000000000000000000000000000000000000002",
509
+ metaData: "0x9258181f5ceac8dbffb7030890243caed69a9599d2886d957a9cb7656af3bdb3",
510
+ treasury: "",
511
+ oracle: {
512
+ supra: "",
513
+ switchboard: "0xbca474133638352ba83ccf7b5c931d50f764b09550e16612c9f70f1e21f3f594",
514
+ pyth: {
515
+ feed: "23d7315113f5b1d3ba7a83604c44b94d79f4fd69af77f804fc7f920a6dc65744",
516
+ feedObject: "0x801dbc2f0053d34734814b2d6df491ce7807a725fe9a01ad74a07e9c51396c37"
517
+ }
518
+ }
519
+ },
520
+ afsui: {
521
+ id: "0xf325ce1300e8dac124071d3152c5c5ee6174914f8bc2161e88329cf579246efc",
522
+ metaData: "0x2f9217f533e51334873a39b8026a4aa6919497b47f49d0986a4f1aec66f8a34d",
523
+ treasury: "",
524
+ oracle: {
525
+ supra: "",
526
+ switchboard: "",
527
+ pyth: {
528
+ feed: "23d7315113f5b1d3ba7a83604c44b94d79f4fd69af77f804fc7f920a6dc65744",
529
+ feedObject: "0x801dbc2f0053d34734814b2d6df491ce7807a725fe9a01ad74a07e9c51396c37"
530
+ }
531
+ }
532
+ },
533
+ hasui: {
534
+ id: "0xbde4ba4c2e274a60ce15c1cfff9e5c42e41654ac8b6d906a57efa4bd3c29f47d",
535
+ metaData: "0x2c5f33af93f6511df699aaaa5822d823aac6ed99d4a0de2a4a50b3afa0172e24",
536
+ treasury: "",
537
+ oracle: {
538
+ supra: "",
539
+ switchboard: "",
540
+ pyth: {
541
+ feed: "23d7315113f5b1d3ba7a83604c44b94d79f4fd69af77f804fc7f920a6dc65744",
542
+ feedObject: "0x801dbc2f0053d34734814b2d6df491ce7807a725fe9a01ad74a07e9c51396c37"
543
+ }
544
+ }
545
+ },
546
+ vsui: {
547
+ id: "0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55",
548
+ metaData: "0xabd84a23467b33854ab25cf862006fd97479f8f6f53e50fe732c43a274d939bd",
549
+ treasury: "",
550
+ oracle: {
551
+ supra: "",
552
+ switchboard: "",
553
+ pyth: {
554
+ feed: "23d7315113f5b1d3ba7a83604c44b94d79f4fd69af77f804fc7f920a6dc65744",
555
+ feedObject: "0x801dbc2f0053d34734814b2d6df491ce7807a725fe9a01ad74a07e9c51396c37"
556
+ }
557
+ }
558
+ },
559
+ sca: {
560
+ id: "0x7016aae72cfc67f2fadf55769c0a7dd54291a583b63051a5ed71081cce836ac6",
561
+ metaData: "0x5d26a1e9a55c88147ac870bfa31b729d7f49f8804b8b3adfdf3582d301cca844",
562
+ treasury: "",
563
+ oracle: {
564
+ supra: "",
565
+ switchboard: "",
566
+ pyth: {
567
+ feed: "7e17f0ac105abe9214deb9944c30264f5986bf292869c6bd8e8da3ccd92d79bc",
568
+ feedObject: "0xf6de1d3279a269a597d813cbaca59aa906543ab9a8c64e84a4722f1a20863985"
569
+ }
570
+ }
571
+ },
572
+ sbeth: {
573
+ id: "0xd0e89b2af5e4910726fbcd8b8dd37bb79b29e5f83f7491bca830e94f7f226d29",
574
+ metaData: "0x89b04ba87f8832d4d76e17a1c9dce72eb3e64d372cf02012b8d2de5384faeef0",
575
+ treasury: "",
576
+ oracle: {
577
+ supra: "",
578
+ switchboard: "",
579
+ pyth: {
580
+ feed: "ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace",
581
+ feedObject: "0x9193fd47f9a0ab99b6e365a464c8a9ae30e6150fc37ed2a89c1586631f6fc4ab"
582
+ }
583
+ }
584
+ }
585
+ },
586
+ oracles: {
587
+ xOracle: "0x93d5bf0936b71eb27255941e532fac33b5a5c7759e377b4923af0a1359ad494f",
588
+ xOracleCap: "0x1edeae568fde99e090dbdec4bcdbd33a15f53a1ce1f87aeef1a560dedf4b4a90",
589
+ supra: { registry: "", registryCap: "", holder: "" },
590
+ switchboard: { registry: "", registryCap: "" },
591
+ pyth: {
592
+ registry: "0xedc293f9413a5a7a5d53bdba1fd889d0a4030894469228f0acdae4aa3c55a213",
593
+ registryCap: "0xbcb07141eb1f7e01fbda4130ecf5f5adaeabb77f5d9c32158b7532bcd2197acd",
594
+ state: "0x1f9310238ee9298fb703c3419030b35b22bb1cc37113e3bb5007c99aec79e5b8",
595
+ wormhole: "0x5306f64e312b581766351c07af79c72fcb1cd25147157fdc2f8ad76de9a3fb6a",
596
+ wormholeState: "0xaeab97f96cf9877fee2883315d459552b2b921edc16d7ceac6eab944dd88919c"
597
+ }
598
+ },
599
+ packages: {
600
+ coinDecimalsRegistry: {
601
+ id: "0xca5a5a62f01c79a104bf4d31669e29daa387f325c241de4edbe30986a9bc8b0d",
602
+ upgradeCap: "0x34e76a945d29f195bc53ca704fa70877d1cf3a5d7bbfdda1b13e633fff13c0f6"
603
+ },
604
+ math: {
605
+ id: "0xad013d5fde39e15eabda32b3dbdafd67dac32b798ce63237c27a8f73339b9b6f",
606
+ upgradeCap: "0x3a329598231de02e6135c62284b66005b41cad1d9ab7ca2dc79c08293aba2ec6"
607
+ },
608
+ whitelist: {
609
+ id: "0x1318fdc90319ec9c24df1456d960a447521b0a658316155895014a6e39b5482f",
610
+ upgradeCap: "0xf5a22aea23db664f7b69855b6a546747f17c1ec4230319cfc17225e462b05761"
611
+ },
612
+ x: {
613
+ id: "0x779b5c547976899f5474f3a5bc0db36ddf4697ad7e5a901db0415c2281d28162",
614
+ upgradeCap: "0x3f203f6fff6a69d151e4f1cd931f22b68c489ef2759765662fc7baf673943c9e"
615
+ },
616
+ protocol: {
617
+ id: "0x6c23585e940a989588432509107e98bae06dbca4e333f26d0635d401b3c7c76d",
618
+ upgradeCap: "0x38527d154618d1fd5a644b90717fe07cf0e9f26b46b63e9568e611a3f86d5c1a"
619
+ },
620
+ // protocol: {
621
+ // id: '0x6e641f0dca8aedab3101d047e96439178f16301bf0b57fe8745086ff1195eb3e',
622
+ // upgradeCap:
623
+ // '0x38527d154618d1fd5a644b90717fe07cf0e9f26b46b63e9568e611a3f86d5c1a',
624
+ // },
625
+ protocolWhitelist: {
626
+ id: "0x4c262d9343dac53ecb28f482a2a3f62c73d0ebac5b5f03d57383d56ff219acdf",
627
+ upgradeCap: "0x4a5e88a75039b00988f633f811f58117f31b8627a46bf822aa114d9010049449"
628
+ },
629
+ // query: {
630
+ // id: '0xb8d603a39114a5efef3dd0bf84df0bed1be1fbd39b78b7dd6e8a61ccc5e6006f',
631
+ // upgradeCap:
632
+ // '0x0d535c35f608b9b01b7ccce11acf43b1dd80c1b72bf8b541744a6e28e8d2745f',
633
+ // },
634
+ query: {
635
+ id: "0x89706958f43fb170de134579e3fbc53972b946ee78bd2442d8e1adc36074fbdc",
636
+ upgradeCap: "0x0d535c35f608b9b01b7ccce11acf43b1dd80c1b72bf8b541744a6e28e8d2745f"
637
+ },
638
+ supra: { id: "", upgradeCap: "" },
639
+ pyth: {
640
+ id: "0x910f30cbc7f601f75a5141a01265cd47c62d468707c5e1aecb32a18f448cb25a",
641
+ upgradeCap: "0xdf0ffbae1ea5bb25fbca5efba433dcf00c7cced65679af2f04728901275c6157"
642
+ },
643
+ switchboard: { id: "", upgradeCap: "" },
644
+ xOracle: {
645
+ id: "0x1478a432123e4b3d61878b629f2c692969fdb375644f1251cd278a4b1e7d7cd6",
646
+ upgradeCap: "0x0f928a6b2e26b73330fecaf9b44acfc9800a4a9794d6415c2a3153bc70e3c1f0"
647
+ },
648
+ testCoin: { id: "", upgradeCap: "" }
649
+ }
650
+ },
651
+ spool: {
652
+ // id: '0x7c4fdabe81c31b19a45d1e572a52a539997a90903fbb5bfab71480abe0fa62c3',
653
+ id: "0x1742655fe5872dfa6456673f9e38612a4965e6979e6cd7696a7f1225f28bae21",
654
+ adminCap: "0xdd8a047cbbf802bfcde5288b8ef1910965d789cc614da11d39af05fca0bd020a",
655
+ // object:
656
+ // '0xe87f1b2d498106a2c61421cec75b7b5c5e348512b0dc263949a0e7a3c256571a',
657
+ object: "0x1742655fe5872dfa6456673f9e38612a4965e6979e6cd7696a7f1225f28bae21",
658
+ pools: {
659
+ sweth: {
660
+ id: "0xeec40beccb07c575bebd842eeaabb835f77cd3dab73add433477e57f583a6787",
661
+ rewardPoolId: "0x957de68a18d87817de8309b30c1ec269a4d87ae513abbeed86b5619cb9ce1077"
662
+ },
663
+ ssui: {
664
+ // id: '0x4f0ba970d3c11db05c8f40c64a15b6a33322db3702d634ced6536960ab6f3ee4',
665
+ id: "0xb9617f83c06ebdeac0a8834782b1015e1cc7ea23739e30c132c4bfb95c37a579",
666
+ rewardPoolId: (
667
+ // '0x162250ef72393a4ad3d46294c4e1bdfcb03f04c869d390e7efbfc995353a7ee9',
668
+ "0xc3206071a8d43212efb6e3b5504f2321f8df97ab122b466c0bc7cfdf398dc13a"
669
+ )
670
+ },
671
+ susdc: {
672
+ id: "0x0b5f5f413bd3799e4052c37311966c77f3a4545eb125d2e93e67a68478021918",
673
+ rewardPoolId: "0x85ed6ed72ea97c35dbf0cdc7ed6fbc48d8ec15de9b17c74bf4512df8a6d7f166"
674
+ },
675
+ swusdc: {
676
+ // id: '0x4ace6648ddc64e646ba47a957c562c32c9599b3bba8f5ac1aadb2ae23a2f8ca0',
677
+ id: "0xf1b383b9cf2e9f515fc69567df1053098f273849d09cd84b0278a773429bd2b2",
678
+ rewardPoolId: (
679
+ // '0xf4268cc9b9413b9bfe09e8966b8de650494c9e5784bf0930759cfef4904daff8',
680
+ "0xc71c53ee6505d928ba15bea4fe4f45d98c9c31eced94b72d00a7827d4b7ba3ff"
681
+ )
682
+ },
683
+ swusdt: {
684
+ // id: '0xcb328f7ffa7f9342ed85af3fdb2f22919e1a06dfb2f713c04c73543870d7548f',
685
+ id: "0xb5567dfa5c7fc17a249e959732664c50713dd8c23db1a11376b27df800c17418",
686
+ rewardPoolId: (
687
+ // '0x2c9f934d67a5baa586ceec2cc24163a2f049a6af3d5ba36b84d8ac40f25c4080',
688
+ "0x60768b0687ff0235e376a039709a683e4c436098785e473b67b32dbab47b69ab"
689
+ )
690
+ },
691
+ scetus: {
692
+ id: "0xac1bb13bf4472a637c18c2415fb0e3c1227ea2bcf35242e50563c98215bd298e",
693
+ rewardPoolId: "0x6835c1224126a45086fc6406adc249e3f30df18d779ca4f4e570e38716a17f3f"
694
+ },
695
+ safsui: {
696
+ // id: '0xeedf438abcaa6ce4d9625ffca110920592d5867e4c5637d84ad9f466c4feb800',
697
+ id: "0xc568bb4c991258e839aa54802ecda04fcd9838c826bc3b42b40af81b23c458c8",
698
+ rewardPoolId: (
699
+ // '0x89255a2f86ed7fbfef35ab8b7be48cc7667015975be2685dd9a55a9a64baf76e',
700
+ "0x389a3cbeda742b918941bb24fd00e077bad3367484394d6234f8209b9a6aa03d"
701
+ )
702
+ },
703
+ shasui: {
704
+ // id: '0xa6148bc1b623e936d39a952ceb5bea79e8b37228a8f595067bf1852efd3c34aa',
705
+ id: "0x93f3f4499bf89f2d05ddc1f8b15f51701a7c6c4d0ac0b9c3bc99462cbbd8e321",
706
+ rewardPoolId: (
707
+ // '0x6f3563644d3e2ef13176dbf9d865bd93479df60ccbe07b7e66db57f6309f5a66',
708
+ "0x94cee1be7f5ff34193f3aabef0b14142cb28af4d905fe487a9a7d85a15edb6aa"
709
+ )
710
+ },
711
+ svsui: {
712
+ // id: '0x69ce8e537e750a95381e6040794afa5ab1758353a1a2e1de7760391b01f91670',
713
+ id: "0xa970e9087f80cb59e9299b8e7af7175d977ad6c9af0322aa4440e138fbd7ae00",
714
+ rewardPoolId: (
715
+ // '0xbca914adce058ad0902c7f3cfcd698392a475f00dcfdc3f76001d0370b98777a',
716
+ "0x38eee9699c4fc132a6623e54b865f047df4fc6eb83af807300f44e8f4b235ff0"
717
+ )
718
+ }
719
+ },
720
+ config: ""
721
+ },
722
+ borrowIncentive: {
723
+ id: "0x85769d63565ce99c7622f8e336ca1460926ddf29738ad2a39407b5cac29f61fe",
724
+ adminCap: "0x56ac8e6f2b360b2b35c0168d72cc6cd17d9592afb83709865cb87af24bb2025b",
725
+ object: "0x85769d63565ce99c7622f8e336ca1460926ddf29738ad2a39407b5cac29f61fe",
726
+ query: "0x8e0d00f8ff1199d7c5fe56cea0e901a525daeefff0445a1635ace8282ae3302c",
727
+ incentivePools: "0x9d564c93128c6ab0c0d3e050a47f11df0b91494f3bb779bdc1301c1c637f15eb",
728
+ incentiveAccounts: "0x09e6040e798246de04941bc79a3ba62d3eca6d7a218cc30f21fb07f478fa2926",
729
+ config: "0x43d4ca1dfc90b161c4240facd119e74e4b850cca2957f88c2ec289c9380da064"
730
+ },
731
+ referral: {
732
+ id: "0x1bf5a8ce77050d8052549d743e16b469f15aa6b81b752b78b6ebb65179665f5a",
733
+ object: "0x5658d4bf5ddcba27e4337b4262108b3ad1716643cac8c2054ac341538adc72ec",
734
+ adminCap: "0xc5dc06b9074291259f2cac460c940012c781c4430e42125c541cc43101c3bcbd",
735
+ referralBindings: "0xcf184487782bed962bf678001efe775d31fb94b9992333a57594cf15d79d5ced",
736
+ bindingTableId: "0x41a50e258c0a266ce84e0e1a618dbf70b878cc943909e613089a50afcceb2bc0",
737
+ referralRevenuePool: "0xc24e3e5e37032f29a3dd91a9a1f057af8821b7e6c148e9683900ac8b6d30f0c6",
738
+ revenueTableId: "0x595baa3654c297bff84ab7786a2d250f019cefc66e8df8e89fd9d41e02bd30dd",
739
+ referralTiers: "0x144350f3db9b46d11b140084cd54e6de0b9c3b8d265ce8059b51d0ef58ea464b",
740
+ tiersTableId: "0xeac755a7a8b7798530905ac79e8c114f19d0f130f6eab012954f08faac29c75d",
741
+ // authorizedWitnessList:
742
+ // '0xf21b0ed043c9bb70842c0129159f4943dbcc3c9ef2f2f808af65f8be25cfd20e',
743
+ authorizedWitnessList: "0x9d6223dc52015b8a3986a573590ef2af8f1b8f3e4685513888c052f001b87e7f",
744
+ version: "0x3545849eb97723e676a476ec9d4fe5f2eb0eb2c6b78972851114fd4c7ed4639f"
745
+ },
746
+ vesca: {
747
+ id: "0x1158813b32962c2d22888fae257d5f2365b03631f0cd5d5b912ccdf51ff4e2f2",
748
+ object: "0x1158813b32962c2d22888fae257d5f2365b03631f0cd5d5b912ccdf51ff4e2f2",
749
+ adminCap: "0x8ffa76135c5b85c5fbd73a6448a4a733d826cb63a267ab817656acb77c72d4a5",
750
+ tableId: "0x0a0b7f749baeb61e3dfee2b42245e32d0e6b484063f0a536b33e771d573d7246",
751
+ table: "0xd3a4632b1080f7d96e1c2487d4dabf2c1196916937c505a69954ac9f393be8d0",
752
+ treasury: "0xafa4b6231e49c15a22d641ce33fda761baaf650fa21899dfa2eb1716146e7306",
753
+ config: "0x7cbcb0a342179577a117dfdff974cf1ab765d3b571067bf22ddf5f9e3a667922"
754
+ },
755
+ loyaltyProgram: {
756
+ id: "0xd17bcf8b5a59652c36225d478564a8593ae0ed7d650bcacdda1d6fe179127907",
757
+ object: "0xd17bcf8b5a59652c36225d478564a8593ae0ed7d650bcacdda1d6fe179127907",
758
+ rewardPool: "0xf9c090492ef476bd542109d0913ffe871cbfa28578b7114eca2a8c0e5671786f",
759
+ userRewardTableId: "0x748a80395849ed37db1b0e14f2ab5d1d96458d2359ab3a84eb079d0f4ac7cf2e"
760
+ },
761
+ scoin: {
762
+ id: "0x773dab39c90fe05439b06a2d061795e52a974ff92c2aef90b2ee467acf7f33c8",
763
+ coins: {
764
+ ssui: {
765
+ coinType: "0xf569919046f19a0c40b519ecfbb6ca0319698cd5908716c29b62ef56541f298b::scallop_sui::SCALLOP_SUI",
766
+ treasury: "0x0e499640a12c38dd9cc44532f5bc5fd1b6da86d2f9a8810357250f4b26e9e5c7"
767
+ },
768
+ scetus: {
769
+ coinType: "0x8b71e6d323ed78515af2bead13bf3d0da1562ba4a99234eb7c4f14fd39ef0427::scallop_cetus::SCALLOP_CETUS",
770
+ treasury: "0xd786f4b2d26278cc7911a3445b1b085eab60f269ef9dbb6b87e803d52f155003"
771
+ },
772
+ ssca: {
773
+ coinType: "0x0a9d3c6c9af9f6e8def82921541bcbd17f73ed31bed3adcb684f2a4c267e42f0::scallop_sca::SCALLOP_SCA",
774
+ treasury: "0xe818636d1d6c46d6ea1a2dce9d94696d7cbc18ce27451b603eeaa47aba8d75e0"
775
+ },
776
+ swusdc: {
777
+ coinType: "0xf5447c4305a486d8c8557559887c2c39449ddb5e748f15d33946d02a1663c158::scallop_wormhole_usdc::SCALLOP_WORMHOLE_USDC",
778
+ treasury: "0x471fbab72578bab577263006fe32543b6e76153fffa2bef69affe4bc4934258f"
779
+ },
780
+ swusdt: {
781
+ coinType: "0xac781d9f73058ff5e69f9bf8dde32f2e8c71c66d7fe8497fc83b2d9182254b22::scallop_wormhole_usdt::SCALLOP_WORMHOLE_USDT",
782
+ treasury: "0x921a4ed4bb4b4f11f51a462c83f4c0f6b60a90e441d1bc0d26d6fd893146bf4d"
783
+ },
784
+ sweth: {
785
+ coinType: "0x27d54f43e3eda701be56b82e5756e41c84467cd202f5cf713d5f9e45a9f1b6bc::scallop_wormhole_eth::SCALLOP_WORMHOLE_ETH",
786
+ treasury: "0x032b4c8fac94c038dbe986f7587e9b1e4ef580b5ee06d2ef249d85459b7ef05d"
787
+ },
788
+ safsui: {
789
+ coinType: "0xb75b46d975d8d80670b53a6bee90baaa8ce2e0b7d397f079447d641eef6b44ad::scallop_af_sui::SCALLOP_AF_SUI",
790
+ treasury: "0x21450ef0570ef3d224ffa3b873ab802e439ece7b93cc7efad10ae0c1e3b3fcfe"
791
+ },
792
+ shasui: {
793
+ coinType: "0xd973a723874e2c7cde196602a79155a1343a933f8cf87d9b1bb7408bc1acbc58::scallop_ha_sui::SCALLOP_HA_SUI",
794
+ treasury: "0xf822fc1402207e47d2e3ba8ff6e1e594bf1de777dc5ebd2744619cd2726e3b0d"
795
+ },
796
+ svsui: {
797
+ coinType: "0x97023a317320c4498cc4cd239dd02fd30c28246e5e8f81325d63f2bd8d70f6b3::scallop_v_sui::SCALLOP_V_SUI",
798
+ treasury: "0x327114f0bf3559d7e2de10282147ed76a236c7c6775029165c4db09a6062ead6"
799
+ },
800
+ ssbeth: {
801
+ coinType: "0xb14f82d8506d139eacef109688d1b71e7236bcce9b2c0ad526abcd6aa5be7de0::scallop_sb_eth::SCALLOP_SB_ETH",
802
+ treasury: "0xfd0f02def6358a1f266acfa1493d4707ee8387460d434fb667d63d755ff907ed"
803
+ }
804
+ }
805
+ }
806
+ };
807
+
808
+ // src/models/scallop.ts
809
+ import { SuiKit as SuiKit7 } from "@scallop-io/sui-kit";
810
+
811
+ // src/models/scallopAddress.ts
812
+ import { SuiKit } from "@scallop-io/sui-kit";
813
+
814
+ // src/models/scallopCache.ts
815
+ import { QueryClient } from "@tanstack/query-core";
816
+ import {
817
+ SuiTxBlock,
818
+ normalizeStructTag as normalizeStructTag2
819
+ } from "@scallop-io/sui-kit";
820
+
821
+ // src/constants/cache.ts
822
+ var DEFAULT_CACHE_OPTIONS = {
823
+ defaultOptions: {
824
+ queries: {
825
+ staleTime: 5e3,
826
+ gcTime: 5e3
827
+ }
828
+ }
829
+ };
830
+
831
+ // src/utils/builder.ts
832
+ var requireSender = (txBlock) => {
833
+ const sender = txBlock.blockData.sender;
834
+ if (!sender) {
835
+ throw new Error("Sender is required");
836
+ }
837
+ return sender;
838
+ };
839
+ var checkVesca = (prevUnlockAtInMillisTimestamp) => {
840
+ if (prevUnlockAtInMillisTimestamp === void 0) {
841
+ throw new Error("veSca not found");
842
+ }
843
+ };
844
+ var checkVescaExpired = (prevUnlockAtInMillisTimestamp) => {
845
+ if (prevUnlockAtInMillisTimestamp <= (/* @__PURE__ */ new Date()).getTime()) {
846
+ throw new Error("veSca is expired, use renewExpiredVeScaQuick instead");
847
+ }
848
+ };
849
+ var checkExtendLockPeriod = (lockPeriodInDays, newUnlockAtInSecondTimestamp, prevUnlockAtInMillisTimestamp) => {
850
+ checkVesca(prevUnlockAtInMillisTimestamp);
851
+ checkVescaExpired(prevUnlockAtInMillisTimestamp);
852
+ const prevUnlockAtInSecondTimestamp = Math.floor(
853
+ prevUnlockAtInMillisTimestamp / 1e3
854
+ );
855
+ if (lockPeriodInDays < 1) {
856
+ throw new Error("Minimum lock period is 1 day");
857
+ }
858
+ const availableLockPeriodInDays = Math.floor(
859
+ (newUnlockAtInSecondTimestamp - prevUnlockAtInSecondTimestamp) / UNLOCK_ROUND_DURATION
860
+ );
861
+ if (lockPeriodInDays > availableLockPeriodInDays) {
862
+ throw new Error(
863
+ `Cannot extend lock period by ${lockPeriodInDays} days, maximum lock period is ~4 years (${MAX_LOCK_ROUNDS} days), remaining lock period is ${MAX_LOCK_ROUNDS - availableLockPeriodInDays}`
864
+ );
865
+ }
866
+ };
867
+ var checkLockSca = (scaAmountOrCoin, lockPeriodInDays, newUnlockAtInSecondTimestamp, prevUnlockAtInMillisTimestamp) => {
868
+ const prevUnlockAtInSecondTimestamp = prevUnlockAtInMillisTimestamp ? Math.floor(prevUnlockAtInMillisTimestamp / 1e3) : void 0;
869
+ const isInitialLock = !prevUnlockAtInSecondTimestamp;
870
+ const isLockExpired = !isInitialLock && prevUnlockAtInSecondTimestamp * 1e3 <= (/* @__PURE__ */ new Date()).getTime();
871
+ if (isInitialLock || isLockExpired) {
872
+ if (scaAmountOrCoin !== void 0 && lockPeriodInDays !== void 0) {
873
+ if (lockPeriodInDays <= 0) {
874
+ throw new Error("Lock period must be greater than 0");
875
+ }
876
+ if (typeof scaAmountOrCoin === "number" && scaAmountOrCoin < MIN_INITIAL_LOCK_AMOUNT) {
877
+ throw new Error(
878
+ `Minimum lock amount for ${isLockExpired ? "renewing expired veSca" : "initial lock"} is 10 SCA`
879
+ );
880
+ }
881
+ const extendLockPeriodInSecond = lockPeriodInDays * UNLOCK_ROUND_DURATION;
882
+ if (extendLockPeriodInSecond > MAX_LOCK_DURATION) {
883
+ throw new Error(
884
+ `Maximum lock period is ~4 years (${MAX_LOCK_ROUNDS} days)`
885
+ );
886
+ }
887
+ } else {
888
+ throw new Error(
889
+ `SCA amount and lock period is required for ${isLockExpired ? "renewing expired veSca" : "initial lock"}`
890
+ );
891
+ }
892
+ } else {
893
+ checkVesca(prevUnlockAtInMillisTimestamp);
894
+ checkVescaExpired(prevUnlockAtInMillisTimestamp);
895
+ if (typeof scaAmountOrCoin === "number" && scaAmountOrCoin < MIN_TOP_UP_AMOUNT) {
896
+ throw new Error("Minimum top up amount is 1 SCA");
897
+ }
898
+ if (newUnlockAtInSecondTimestamp && lockPeriodInDays) {
899
+ checkExtendLockPeriod(
900
+ lockPeriodInDays,
901
+ newUnlockAtInSecondTimestamp,
902
+ prevUnlockAtInMillisTimestamp
903
+ );
904
+ }
905
+ }
906
+ };
907
+ var checkExtendLockAmount = (scaAmount, prevUnlockAtInMillisTimestamp) => {
908
+ checkVesca(prevUnlockAtInMillisTimestamp);
909
+ checkVescaExpired(prevUnlockAtInMillisTimestamp);
910
+ if (scaAmount < MIN_TOP_UP_AMOUNT) {
911
+ throw new Error("Minimum top up amount is 1 SCA");
912
+ }
913
+ const isInitialLock = !prevUnlockAtInMillisTimestamp;
914
+ const isLockExpired = !isInitialLock && prevUnlockAtInMillisTimestamp <= (/* @__PURE__ */ new Date()).getTime();
915
+ if (isLockExpired) {
916
+ throw new Error("veSca is expired, use renewExpiredVeScaQuick instead");
917
+ }
918
+ };
919
+ var checkRenewExpiredVeSca = (scaAmount, lockPeriodInDays, prevUnlockAtInMillisTimestamp) => {
920
+ if (!prevUnlockAtInMillisTimestamp || prevUnlockAtInMillisTimestamp > (/* @__PURE__ */ new Date()).getTime()) {
921
+ throw new Error("Renew method can only be used for expired veSca");
922
+ }
923
+ if (scaAmount < MIN_INITIAL_LOCK_AMOUNT) {
924
+ throw new Error("Minimum lock amount for renewing expired vesca 10 SCA");
925
+ }
926
+ const extendLockPeriodInSecond = lockPeriodInDays * UNLOCK_ROUND_DURATION;
927
+ if (extendLockPeriodInSecond >= MAX_LOCK_DURATION - UNLOCK_ROUND_DURATION) {
928
+ throw new Error(
929
+ `Maximum lock period is ~4 years (${MAX_LOCK_ROUNDS - 1} days)`
930
+ );
931
+ }
932
+ };
933
+
934
+ // src/utils/query.ts
935
+ import BigNumber from "bignumber.js";
936
+ import { normalizeStructTag, parseStructTag } from "@mysten/sui/utils";
937
+ var parseOriginMarketPoolData = (originMarketPoolData) => {
938
+ return {
939
+ coinType: normalizeStructTag(originMarketPoolData.type.name),
940
+ // Parse origin data required for basic calculations.
941
+ maxBorrowRate: Number(originMarketPoolData.maxBorrowRate.value) / 2 ** 32,
942
+ borrowRate: Number(originMarketPoolData.interestRate.value) / 2 ** 32,
943
+ borrowRateScale: Number(originMarketPoolData.interestRateScale),
944
+ borrowIndex: Number(originMarketPoolData.borrowIndex),
945
+ lastUpdated: Number(originMarketPoolData.lastUpdated),
946
+ cashAmount: Number(originMarketPoolData.cash),
947
+ debtAmount: Number(originMarketPoolData.debt),
948
+ marketCoinSupplyAmount: Number(originMarketPoolData.marketCoinSupply),
949
+ reserveAmount: Number(originMarketPoolData.reserve),
950
+ reserveFactor: Number(originMarketPoolData.reserveFactor.value) / 2 ** 32,
951
+ borrowWeight: Number(originMarketPoolData.borrowWeight.value) / 2 ** 32,
952
+ borrowFee: Number(originMarketPoolData.borrowFeeRate.value) / 2 ** 32,
953
+ // Parse origin data required for additional display.
954
+ baseBorrowRate: Number(originMarketPoolData.baseBorrowRatePerSec.value) / 2 ** 32,
955
+ borrowRateOnHighKink: Number(originMarketPoolData.borrowRateOnHighKink.value) / 2 ** 32,
956
+ borrowRateOnMidKink: Number(originMarketPoolData.borrowRateOnMidKink.value) / 2 ** 32,
957
+ highKink: Number(originMarketPoolData.highKink.value) / 2 ** 32,
958
+ midKink: Number(originMarketPoolData.midKink.value) / 2 ** 32,
959
+ minBorrowAmount: Number(originMarketPoolData.minBorrowAmount)
960
+ };
961
+ };
962
+ var calculateMarketPoolData = (utils, parsedMarketPoolData) => {
963
+ const poolCoinName = utils.parseCoinNameFromType(
964
+ parsedMarketPoolData.coinType
965
+ );
966
+ const coinDecimal = utils.getCoinDecimal(poolCoinName);
967
+ const borrowYearFactor = 24 * 365 * 3600;
968
+ const baseBorrowApr = parsedMarketPoolData.baseBorrowRate * borrowYearFactor / parsedMarketPoolData.borrowRateScale;
969
+ const borrowAprOnHighKink = parsedMarketPoolData.borrowRateOnHighKink * borrowYearFactor / parsedMarketPoolData.borrowRateScale;
970
+ const borrowAprOnMidKink = parsedMarketPoolData.borrowRateOnMidKink * borrowYearFactor / parsedMarketPoolData.borrowRateScale;
971
+ const maxBorrowApr = parsedMarketPoolData.maxBorrowRate * borrowYearFactor / parsedMarketPoolData.borrowRateScale;
972
+ const borrowApr = parsedMarketPoolData.borrowRate * borrowYearFactor / parsedMarketPoolData.borrowRateScale;
973
+ const timeDelta = Math.floor((/* @__PURE__ */ new Date()).getTime() / 1e3) - parsedMarketPoolData.lastUpdated;
974
+ const borrowIndexDelta = BigNumber(parsedMarketPoolData.borrowIndex).multipliedBy(
975
+ BigNumber(timeDelta).multipliedBy(parsedMarketPoolData.borrowRate)
976
+ ).dividedBy(parsedMarketPoolData.borrowRateScale);
977
+ const currentBorrowIndex = BigNumber(parsedMarketPoolData.borrowIndex).plus(
978
+ borrowIndexDelta
979
+ );
980
+ const growthInterest = BigNumber(currentBorrowIndex).dividedBy(parsedMarketPoolData.borrowIndex).minus(1);
981
+ const increasedDebtAmount = BigNumber(
982
+ parsedMarketPoolData.debtAmount
983
+ ).multipliedBy(growthInterest);
984
+ const borrowAmount = increasedDebtAmount.plus(
985
+ parsedMarketPoolData.debtAmount
986
+ );
987
+ const borrowCoin = borrowAmount.shiftedBy(-1 * coinDecimal);
988
+ const reserveAmount = BigNumber(parsedMarketPoolData.reserveAmount).plus(
989
+ increasedDebtAmount.multipliedBy(parsedMarketPoolData.reserveFactor)
990
+ );
991
+ const reserveCoin = reserveAmount.shiftedBy(-1 * coinDecimal);
992
+ const supplyAmount = BigNumber(borrowAmount).plus(
993
+ Math.max(parsedMarketPoolData.cashAmount - reserveAmount.toNumber(), 0)
994
+ );
995
+ const supplyCoin = supplyAmount.shiftedBy(-1 * coinDecimal);
996
+ let utilizationRate = BigNumber(borrowAmount).dividedBy(supplyAmount);
997
+ utilizationRate = utilizationRate.isFinite() ? utilizationRate : BigNumber(0);
998
+ let supplyApr = BigNumber(borrowApr).multipliedBy(utilizationRate).multipliedBy(1 - parsedMarketPoolData.reserveFactor);
999
+ supplyApr = supplyApr.isFinite() ? supplyApr : BigNumber(0);
1000
+ let conversionRate = supplyAmount.dividedBy(
1001
+ parsedMarketPoolData.marketCoinSupplyAmount
1002
+ );
1003
+ conversionRate = conversionRate.isFinite() && !conversionRate.isNaN() ? conversionRate : BigNumber(1);
1004
+ return {
1005
+ baseBorrowApr,
1006
+ baseBorrowApy: utils.parseAprToApy(baseBorrowApr),
1007
+ borrowAprOnHighKink,
1008
+ borrowApyOnHighKink: utils.parseAprToApy(borrowAprOnHighKink),
1009
+ borrowAprOnMidKink,
1010
+ borrowApyOnMidKink: utils.parseAprToApy(borrowAprOnMidKink),
1011
+ maxBorrowApr,
1012
+ maxBorrowApy: utils.parseAprToApy(maxBorrowApr),
1013
+ borrowApr: Math.min(borrowApr, maxBorrowApr),
1014
+ borrowApy: Math.min(
1015
+ utils.parseAprToApy(borrowApr),
1016
+ utils.parseAprToApy(maxBorrowApr)
1017
+ ),
1018
+ borrowIndex: currentBorrowIndex.toNumber(),
1019
+ growthInterest: growthInterest.toNumber(),
1020
+ supplyAmount: supplyAmount.toNumber(),
1021
+ supplyCoin: supplyCoin.toNumber(),
1022
+ borrowAmount: borrowAmount.toNumber(),
1023
+ borrowCoin: borrowCoin.toNumber(),
1024
+ reserveAmount: reserveAmount.toNumber(),
1025
+ reserveCoin: reserveCoin.toNumber(),
1026
+ utilizationRate: utilizationRate.toNumber(),
1027
+ supplyApr: supplyApr.toNumber(),
1028
+ supplyApy: utils.parseAprToApy(supplyApr.toNumber()),
1029
+ conversionRate: conversionRate.toNumber()
1030
+ };
1031
+ };
1032
+ var parseOriginMarketCollateralData = (originMarketCollateralData) => {
1033
+ const divisor = 2 ** 32;
1034
+ return {
1035
+ coinType: normalizeStructTag(originMarketCollateralData.type.name),
1036
+ collateralFactor: Number(originMarketCollateralData.collateralFactor.value) / divisor,
1037
+ liquidationFactor: Number(originMarketCollateralData.liquidationFactor.value) / divisor,
1038
+ liquidationDiscount: Number(originMarketCollateralData.liquidationDiscount.value) / divisor,
1039
+ liquidationPanelty: Number(originMarketCollateralData.liquidationPanelty.value) / divisor,
1040
+ liquidationReserveFactor: Number(originMarketCollateralData.liquidationReserveFactor.value) / divisor,
1041
+ maxCollateralAmount: Number(originMarketCollateralData.maxCollateralAmount),
1042
+ totalCollateralAmount: Number(
1043
+ originMarketCollateralData.totalCollateralAmount
1044
+ )
1045
+ };
1046
+ };
1047
+ var calculateMarketCollateralData = (utils, parsedMarketCollateralData) => {
1048
+ const collateralCoinName = utils.parseCoinNameFromType(
1049
+ parsedMarketCollateralData.coinType
1050
+ );
1051
+ const coinDecimal = utils.getCoinDecimal(collateralCoinName);
1052
+ const maxCollateralCoin = BigNumber(
1053
+ parsedMarketCollateralData.maxCollateralAmount
1054
+ ).shiftedBy(-1 * coinDecimal);
1055
+ const depositCoin = BigNumber(
1056
+ parsedMarketCollateralData.totalCollateralAmount
1057
+ ).shiftedBy(-1 * coinDecimal);
1058
+ return {
1059
+ maxDepositAmount: parsedMarketCollateralData.maxCollateralAmount,
1060
+ maxDepositCoin: maxCollateralCoin.toNumber(),
1061
+ depositAmount: parsedMarketCollateralData.totalCollateralAmount,
634
1062
  depositCoin: depositCoin.toNumber()
635
1063
  };
636
1064
  };
@@ -815,797 +1243,405 @@ var calculateBorrowIncentivePoolPointData = (parsedBorrowIncentivePoolPointData,
815
1243
  );
816
1244
  const rewardValueForYear = BigNumber(rewardPerSec).multipliedBy(rateYearFactor).multipliedBy(rewardCoinPrice);
817
1245
  const weightScale = BigNumber(1e12);
818
- const rewardRate = rewardValueForYear.multipliedBy(
819
- BigNumber(parsedBorrowIncentivePoolPointData.baseWeight).dividedBy(
820
- weightScale
821
- )
822
- ).dividedBy(weightedStakedValue).isFinite() && parsedBorrowIncentivePoolPointData.points > 0 ? rewardValueForYear.multipliedBy(
823
- BigNumber(parsedBorrowIncentivePoolPointData.baseWeight).dividedBy(
824
- weightScale
825
- )
826
- ).dividedBy(weightedStakedValue).toNumber() : Infinity;
827
- return {
828
- distributedPointPerSec: distributedPointPerSec.toNumber(),
829
- accumulatedPoints: accumulatedPoints.toNumber(),
830
- currentPointIndex: currentPointIndex.toNumber(),
831
- currentTotalDistributedPoint: currentTotalDistributedPoint.toNumber(),
832
- baseWeight: baseWeight.toNumber(),
833
- weightedStakedAmount: weightedStakedAmount.toNumber(),
834
- weightedStakedCoin: weightedStakedCoin.toNumber(),
835
- weightedStakedValue: weightedStakedValue.toNumber(),
836
- rewardApr: rewardRate,
837
- rewardPerSec: rewardPerSec.toNumber()
838
- };
839
- };
840
- var parseOriginBorrowIncentiveAccountPoolPointData = (originBorrowIncentiveAccountPoolPointData) => {
841
- return {
842
- pointType: normalizeStructTag(
843
- originBorrowIncentiveAccountPoolPointData.point_type.name
844
- ),
845
- weightedAmount: Number(
846
- originBorrowIncentiveAccountPoolPointData.weighted_amount
847
- ),
848
- points: Number(originBorrowIncentiveAccountPoolPointData.points),
849
- totalPoints: Number(originBorrowIncentiveAccountPoolPointData.total_points),
850
- index: Number(originBorrowIncentiveAccountPoolPointData.index)
851
- };
852
- };
853
- var parseOriginBorrowIncentiveAccountData = (originBorrowIncentiveAccountData) => {
854
- return {
855
- poolType: normalizeStructTag(
856
- originBorrowIncentiveAccountData.pool_type.name
857
- ),
858
- debtAmount: Number(originBorrowIncentiveAccountData.debt_amount),
859
- pointList: originBorrowIncentiveAccountData.points_list.reduce(
860
- (acc, point) => {
861
- const parsed = parseOriginBorrowIncentiveAccountPoolPointData(point);
862
- const name = parseStructTag(
863
- parsed.pointType
864
- ).name.toLowerCase();
865
- acc[name] = parsed;
866
- return acc;
867
- },
868
- {}
869
- )
870
- };
871
- };
872
- var minBigNumber = (...args) => {
873
- return BigNumber(
874
- args.reduce(
875
- (min, current) => new BigNumber(current).lt(min) ? current : min
876
- )
877
- );
878
- };
879
- var estimatedFactor = (amount, scaleStep, type) => {
880
- const amountOfDigits = Math.max(
881
- 1,
882
- Math.floor(Math.log10(Math.abs(amount)) + 1)
883
- );
884
- const adjustScale = Math.max(Math.floor((amountOfDigits - 1) / scaleStep), 1) + 1;
885
- let adjustFactor = Math.pow(10, -adjustScale);
886
- adjustFactor = type === "increase" ? 1 - adjustFactor : 1 + adjustFactor;
887
- return adjustFactor;
888
- };
889
-
890
- // src/utils/util.ts
891
- var COIN_SET = Array.from(
892
- /* @__PURE__ */ new Set([
893
- ...SUPPORT_POOLS,
894
- ...SUPPORT_COLLATERALS,
895
- ...SUPPORT_SPOOLS_REWARDS,
896
- ...SUPPORT_BORROW_INCENTIVE_REWARDS,
897
- ...SUPPORT_SCOIN
898
- ])
899
- );
900
- var isMarketCoin = (coinName) => {
901
- const assetCoinName = coinName.slice(1).toLowerCase();
902
- return coinName.charAt(0).toLowerCase() === "s" && COIN_SET.includes(assetCoinName);
903
- };
904
- var isSuiBridgeAsset = (coinName) => {
905
- return SUPPORT_SUI_BRIDGE.includes(coinName);
906
- };
907
- var isWormholeAsset = (coinName) => {
908
- return SUPPORT_WORMHOLE.includes(coinName);
909
- };
910
- var parseAssetSymbol = (coinName) => {
911
- if (isWormholeAsset(coinName)) {
912
- return `w${coinName.slice(1).toUpperCase()}`;
913
- }
914
- if (isSuiBridgeAsset(coinName)) {
915
- return `sb${coinName.slice(2).toUpperCase()}`;
916
- }
917
- if (isMarketCoin(coinName)) {
918
- const assetCoinName = coinName.slice(1).toLowerCase();
919
- return coinName.slice(0, 1).toLowerCase() + parseAssetSymbol(assetCoinName);
920
- }
921
- switch (coinName) {
922
- case "afsui":
923
- return "afSUI";
924
- case "hasui":
925
- return "haSUI";
926
- case "vsui":
927
- return "vSUI";
928
- default:
929
- return coinName.toUpperCase();
930
- }
931
- };
932
- var parseDataFromPythPriceFeed = (feed, address) => {
933
- const assetCoinNames = COIN_SET;
934
- const assetCoinName = assetCoinNames.find((assetCoinName2) => {
935
- return address.get(`core.coins.${assetCoinName2}.oracle.pyth.feed`) === feed.id;
936
- });
937
- if (assetCoinName) {
938
- const price = feed.price.price * 10 ** feed.price.expo;
939
- return {
940
- coinName: assetCoinName,
941
- price,
942
- publishTime: Number(feed.price.publishTime) * 10 ** 3
943
- };
944
- } else {
945
- throw new Error("Invalid feed id");
946
- }
947
- };
948
- var findClosestUnlockRound = (unlockAtInSecondTimestamp) => {
949
- const unlockDate = new Date(unlockAtInSecondTimestamp * 1e3);
950
- const closestTwelveAM = new Date(unlockAtInSecondTimestamp * 1e3);
951
- closestTwelveAM.setUTCHours(0, 0, 0, 0);
952
- if (unlockDate.getUTCHours() >= 0) {
953
- closestTwelveAM.setUTCDate(closestTwelveAM.getUTCDate() + 1);
954
- }
955
- const now = (/* @__PURE__ */ new Date()).getTime();
956
- if (closestTwelveAM.getTime() - now > MAX_LOCK_DURATION * 1e3) {
957
- closestTwelveAM.setUTCDate(closestTwelveAM.getUTCDate() - 1);
958
- }
959
- return Math.floor(closestTwelveAM.getTime() / 1e3);
960
- };
961
-
962
- // src/constants/tokenBucket.ts
963
- var DEFAULT_TOKENS_PER_INTERVAL = 50;
964
- var DEFAULT_INTERVAL_IN_MS = 300;
965
-
966
- // src/utils/tokenBucket.ts
967
- var TokenBucket = class {
968
- constructor(tokensPerInterval, intervalInMs) {
969
- this.tokensPerInterval = tokensPerInterval;
970
- this.interval = intervalInMs;
971
- this.tokens = tokensPerInterval;
972
- this.lastRefill = Date.now();
973
- }
974
- refill() {
975
- const now = Date.now();
976
- const elapsed = now - this.lastRefill;
977
- if (elapsed > this.interval) {
978
- const tokensToAdd = Math.floor(elapsed / this.interval) * this.tokensPerInterval;
979
- this.tokens = Math.min(this.tokens + tokensToAdd, this.tokensPerInterval);
980
- this.lastRefill = now;
981
- }
982
- }
983
- removeTokens(count) {
984
- this.refill();
985
- if (this.tokens >= count) {
986
- this.tokens -= count;
987
- return true;
988
- }
989
- return false;
990
- }
991
- };
992
- var callWithRateLimit = async (tokenBucket, fn, retryDelayInMs = DEFAULT_INTERVAL_IN_MS, maxRetries = 15, backoffFactor = 1.25) => {
993
- let retries = 0;
994
- const tryRequest = async () => {
995
- if (tokenBucket.removeTokens(1)) {
996
- try {
997
- const result = await fn();
998
- if (result && result.status === 429) {
999
- throw new Error("Unexpected status code: 429");
1000
- }
1001
- return result;
1002
- } catch (error) {
1003
- if (error.message === "Unexpected status code: 429" && retries < maxRetries) {
1004
- retries++;
1005
- const delay = retryDelayInMs * Math.pow(backoffFactor, retries);
1006
- await new Promise((resolve) => setTimeout(resolve, delay));
1007
- return tryRequest();
1008
- } else {
1009
- console.error("An error occurred:", error.message);
1010
- return null;
1011
- }
1012
- }
1013
- } else if (retries < maxRetries) {
1014
- retries++;
1015
- const delay = retryDelayInMs * Math.pow(backoffFactor, retries);
1016
- await new Promise((resolve) => setTimeout(resolve, delay));
1017
- return tryRequest();
1018
- } else {
1019
- console.error("Maximum retries reached");
1020
- return null;
1021
- }
1246
+ const rewardRate = rewardValueForYear.multipliedBy(
1247
+ BigNumber(parsedBorrowIncentivePoolPointData.baseWeight).dividedBy(
1248
+ weightScale
1249
+ )
1250
+ ).dividedBy(weightedStakedValue).isFinite() && parsedBorrowIncentivePoolPointData.points > 0 ? rewardValueForYear.multipliedBy(
1251
+ BigNumber(parsedBorrowIncentivePoolPointData.baseWeight).dividedBy(
1252
+ weightScale
1253
+ )
1254
+ ).dividedBy(weightedStakedValue).toNumber() : Infinity;
1255
+ return {
1256
+ distributedPointPerSec: distributedPointPerSec.toNumber(),
1257
+ accumulatedPoints: accumulatedPoints.toNumber(),
1258
+ currentPointIndex: currentPointIndex.toNumber(),
1259
+ currentTotalDistributedPoint: currentTotalDistributedPoint.toNumber(),
1260
+ baseWeight: baseWeight.toNumber(),
1261
+ weightedStakedAmount: weightedStakedAmount.toNumber(),
1262
+ weightedStakedCoin: weightedStakedCoin.toNumber(),
1263
+ weightedStakedValue: weightedStakedValue.toNumber(),
1264
+ rewardApr: rewardRate,
1265
+ rewardPerSec: rewardPerSec.toNumber()
1022
1266
  };
1023
- return tryRequest();
1024
1267
  };
1025
-
1026
- // src/utils/indexer.ts
1027
- async function callMethodWithIndexerFallback(method, context, ...args) {
1028
- const indexer = args[args.length - 1];
1029
- if (indexer) {
1030
- try {
1031
- return await method.apply(context, args);
1032
- } catch (e) {
1033
- console.warn(`Indexer requests failed: ${e}. Retrying without indexer..`);
1034
- return await method.apply(context, [...args.slice(0, -1), false]);
1035
- }
1036
- }
1037
- return await method.apply(context, args);
1038
- }
1039
- function withIndexerFallback(method) {
1040
- return (...args) => {
1041
- return callMethodWithIndexerFallback(method, this, ...args);
1268
+ var parseOriginBorrowIncentiveAccountPoolPointData = (originBorrowIncentiveAccountPoolPointData) => {
1269
+ return {
1270
+ pointType: normalizeStructTag(
1271
+ originBorrowIncentiveAccountPoolPointData.point_type.name
1272
+ ),
1273
+ weightedAmount: Number(
1274
+ originBorrowIncentiveAccountPoolPointData.weighted_amount
1275
+ ),
1276
+ points: Number(originBorrowIncentiveAccountPoolPointData.points),
1277
+ totalPoints: Number(originBorrowIncentiveAccountPoolPointData.total_points),
1278
+ index: Number(originBorrowIncentiveAccountPoolPointData.index)
1042
1279
  };
1043
- }
1280
+ };
1281
+ var parseOriginBorrowIncentiveAccountData = (originBorrowIncentiveAccountData) => {
1282
+ return {
1283
+ poolType: normalizeStructTag(
1284
+ originBorrowIncentiveAccountData.pool_type.name
1285
+ ),
1286
+ debtAmount: Number(originBorrowIncentiveAccountData.debt_amount),
1287
+ pointList: originBorrowIncentiveAccountData.points_list.reduce(
1288
+ (acc, point) => {
1289
+ const parsed = parseOriginBorrowIncentiveAccountPoolPointData(point);
1290
+ const name = parseStructTag(
1291
+ parsed.pointType
1292
+ ).name.toLowerCase();
1293
+ acc[name] = parsed;
1294
+ return acc;
1295
+ },
1296
+ {}
1297
+ )
1298
+ };
1299
+ };
1300
+ var minBigNumber = (...args) => {
1301
+ return BigNumber(
1302
+ args.reduce(
1303
+ (min, current) => new BigNumber(current).lt(min) ? current : min
1304
+ )
1305
+ );
1306
+ };
1307
+ var estimatedFactor = (amount, scaleStep, type) => {
1308
+ const amountOfDigits = Math.max(
1309
+ 1,
1310
+ Math.floor(Math.log10(Math.abs(amount)) + 1)
1311
+ );
1312
+ const adjustScale = Math.max(Math.floor((amountOfDigits - 1) / scaleStep), 1) + 1;
1313
+ let adjustFactor = Math.pow(10, -adjustScale);
1314
+ adjustFactor = type === "increase" ? 1 - adjustFactor : 1 + adjustFactor;
1315
+ return adjustFactor;
1316
+ };
1044
1317
 
1045
- // src/models/scallopCache.ts
1046
- var ScallopCache = class {
1047
- constructor(suiKit, walletAddress, cacheOptions, tokenBucket, queryClient) {
1048
- this.queryClient = queryClient ?? new QueryClient(cacheOptions ?? DEFAULT_CACHE_OPTIONS);
1049
- this._suiKit = suiKit;
1050
- this.tokenBucket = tokenBucket ?? new TokenBucket(DEFAULT_TOKENS_PER_INTERVAL, DEFAULT_INTERVAL_IN_MS);
1051
- this.walletAddress = walletAddress ?? suiKit.currentAddress();
1052
- }
1053
- get suiKit() {
1054
- if (!this._suiKit) {
1055
- throw new Error("SuiKit instance is not initialized");
1056
- }
1057
- return this._suiKit;
1058
- }
1059
- get client() {
1060
- return this.suiKit.client();
1061
- }
1062
- /**
1063
- * @description Invalidate cache based on the refetchType parameter
1064
- * @param refetchType Determines the type of queries to be refetched. Defaults to `active`.
1065
- *
1066
- * - `active`: Only queries that match the refetch predicate and are actively being rendered via useQuery and related functions will be refetched in the background.
1067
- * - `inactive`: Only queries that match the refetch predicate and are NOT actively being rendered via useQuery and related functions will be refetched in the background.
1068
- * - `all`: All queries that match the refetch predicate will be refetched in the background.
1069
- * - `none`: No queries will be refetched. Queries that match the refetch predicate will only be marked as invalid.
1070
- */
1071
- async invalidateAllCache() {
1072
- return Object.values(queryKeys.rpc).map(
1073
- (t) => this.queryClient.invalidateQueries({
1074
- queryKey: t(),
1075
- type: "all"
1076
- })
1077
- );
1078
- }
1079
- /**
1080
- * @description Provides cache for inspectTxn of the SuiKit.
1081
- * @param QueryInspectTxnParams
1082
- * @param txBlock
1083
- * @returns Promise<DevInspectResults>
1084
- */
1085
- async queryInspectTxn({
1086
- queryTarget,
1087
- args,
1088
- typeArgs
1089
- }) {
1090
- const txBlock = new SuiTxBlock();
1091
- txBlock.moveCall(queryTarget, args, typeArgs);
1092
- const query = await this.queryClient.fetchQuery({
1093
- queryKey: queryKeys.rpc.getInspectTxn(queryTarget, args, typeArgs),
1094
- queryFn: async () => {
1095
- return await callWithRateLimit(
1096
- this.tokenBucket,
1097
- () => this.suiKit.inspectTxn(txBlock)
1098
- );
1099
- }
1100
- });
1101
- return query;
1102
- }
1103
- /**
1104
- * @description Provides cache for getObject of the SuiKit.
1105
- * @param objectId
1106
- * @param QueryObjectParams
1107
- * @returns Promise<SuiObjectResponse>
1108
- */
1109
- async queryGetObject(objectId, options) {
1110
- return this.queryClient.fetchQuery({
1111
- queryKey: queryKeys.rpc.getObject(objectId, this.walletAddress, options),
1112
- queryFn: async () => {
1113
- return await callWithRateLimit(
1114
- this.tokenBucket,
1115
- () => this.client.getObject({
1116
- id: objectId,
1117
- options
1118
- })
1119
- );
1120
- }
1121
- });
1122
- }
1123
- /**
1124
- * @description Provides cache for getObjects of the SuiKit.
1125
- * @param objectIds
1126
- * @returns Promise<SuiObjectData[]>
1127
- */
1128
- async queryGetObjects(objectIds, options = {
1129
- showContent: true
1130
- }) {
1131
- if (objectIds.length === 0)
1132
- return [];
1133
- return this.queryClient.fetchQuery({
1134
- queryKey: queryKeys.rpc.getObjects(
1135
- objectIds,
1136
- this.walletAddress,
1137
- options
1138
- ),
1139
- queryFn: async () => {
1140
- return await callWithRateLimit(
1141
- this.tokenBucket,
1142
- () => this.suiKit.getObjects(objectIds, options)
1143
- );
1144
- }
1145
- });
1318
+ // src/utils/util.ts
1319
+ var COIN_SET = Array.from(
1320
+ /* @__PURE__ */ new Set([
1321
+ ...SUPPORT_POOLS,
1322
+ ...SUPPORT_COLLATERALS,
1323
+ ...SUPPORT_SPOOLS_REWARDS,
1324
+ ...SUPPORT_BORROW_INCENTIVE_REWARDS,
1325
+ ...SUPPORT_SCOIN
1326
+ ])
1327
+ );
1328
+ var isMarketCoin = (coinName) => {
1329
+ const assetCoinName = coinName.slice(1).toLowerCase();
1330
+ return coinName.charAt(0).toLowerCase() === "s" && COIN_SET.includes(assetCoinName);
1331
+ };
1332
+ var isSuiBridgeAsset = (coinName) => {
1333
+ return SUPPORT_SUI_BRIDGE.includes(coinName);
1334
+ };
1335
+ var isWormholeAsset = (coinName) => {
1336
+ return SUPPORT_WORMHOLE.includes(coinName);
1337
+ };
1338
+ var parseAssetSymbol = (coinName) => {
1339
+ if (isWormholeAsset(coinName)) {
1340
+ return `w${coinName.slice(1).toUpperCase()}`;
1146
1341
  }
1147
- /**
1148
- * @description Provides cache for getOwnedObjects of the SuiKit.
1149
- * @param input
1150
- * @returns Promise<PaginatedObjectsResponse>
1151
- */
1152
- async queryGetOwnedObjects(input) {
1153
- return this.queryClient.fetchQuery({
1154
- queryKey: queryKeys.rpc.getOwnedObjects(input),
1155
- queryFn: async () => {
1156
- return await callWithRateLimit(
1157
- this.tokenBucket,
1158
- () => this.client.getOwnedObjects(input)
1159
- );
1160
- }
1161
- });
1342
+ if (isSuiBridgeAsset(coinName)) {
1343
+ return `sb${coinName.slice(2).toUpperCase()}`;
1162
1344
  }
1163
- async queryGetDynamicFields(input) {
1164
- return this.queryClient.fetchQuery({
1165
- queryKey: queryKeys.rpc.getDynamicFields(input),
1166
- queryFn: async () => {
1167
- return await callWithRateLimit(
1168
- this.tokenBucket,
1169
- () => this.client.getDynamicFields(input)
1170
- );
1171
- }
1172
- });
1345
+ if (isMarketCoin(coinName)) {
1346
+ const assetCoinName = coinName.slice(1).toLowerCase();
1347
+ return coinName.slice(0, 1).toLowerCase() + parseAssetSymbol(assetCoinName);
1173
1348
  }
1174
- async queryGetDynamicFieldObject(input) {
1175
- return this.queryClient.fetchQuery({
1176
- queryKey: queryKeys.rpc.getDynamicFieldObject(input),
1177
- queryFn: async () => {
1178
- return await callWithRateLimit(
1179
- this.tokenBucket,
1180
- () => this.client.getDynamicFieldObject(input)
1181
- );
1182
- }
1183
- });
1349
+ switch (coinName) {
1350
+ case "afsui":
1351
+ return "afSUI";
1352
+ case "hasui":
1353
+ return "haSUI";
1354
+ case "vsui":
1355
+ return "vSUI";
1356
+ default:
1357
+ return coinName.toUpperCase();
1184
1358
  }
1185
- async queryGetAllCoinBalances(owner) {
1186
- return this.queryClient.fetchQuery({
1187
- queryKey: queryKeys.rpc.getAllCoinBalances(owner),
1188
- queryFn: async () => {
1189
- const allBalances = await callWithRateLimit(
1190
- this.tokenBucket,
1191
- () => this.client.getAllBalances({ owner })
1192
- );
1193
- if (!allBalances)
1194
- return {};
1195
- const balances = allBalances.reduce(
1196
- (acc, coinBalance) => {
1197
- if (coinBalance.totalBalance !== "0") {
1198
- acc[normalizeStructTag2(coinBalance.coinType)] = coinBalance.totalBalance;
1199
- }
1200
- return acc;
1201
- },
1202
- {}
1203
- );
1204
- return balances;
1205
- }
1206
- });
1359
+ };
1360
+ var parseDataFromPythPriceFeed = (feed, address) => {
1361
+ const assetCoinNames = COIN_SET;
1362
+ const assetCoinName = assetCoinNames.find((assetCoinName2) => {
1363
+ return address.get(`core.coins.${assetCoinName2}.oracle.pyth.feed`) === feed.id;
1364
+ });
1365
+ if (assetCoinName) {
1366
+ const price = feed.price.price * 10 ** feed.price.expo;
1367
+ return {
1368
+ coinName: assetCoinName,
1369
+ price,
1370
+ publishTime: Number(feed.price.publishTime) * 10 ** 3
1371
+ };
1372
+ } else {
1373
+ throw new Error("Invalid feed id");
1207
1374
  }
1208
- async queryGetCoinBalance(input) {
1209
- if (!input.coinType)
1210
- return "0";
1211
- return (await this.queryGetAllCoinBalances(input.owner) || {})[normalizeStructTag2(input.coinType)] ?? "0";
1375
+ };
1376
+ var findClosestUnlockRound = (unlockAtInSecondTimestamp) => {
1377
+ const unlockDate = new Date(unlockAtInSecondTimestamp * 1e3);
1378
+ const closestTwelveAM = new Date(unlockAtInSecondTimestamp * 1e3);
1379
+ closestTwelveAM.setUTCHours(0, 0, 0, 0);
1380
+ if (unlockDate.getUTCHours() >= 0) {
1381
+ closestTwelveAM.setUTCDate(closestTwelveAM.getUTCDate() + 1);
1382
+ }
1383
+ const now = (/* @__PURE__ */ new Date()).getTime();
1384
+ if (closestTwelveAM.getTime() - now > MAX_LOCK_DURATION * 1e3) {
1385
+ closestTwelveAM.setUTCDate(closestTwelveAM.getUTCDate() - 1);
1212
1386
  }
1387
+ return Math.floor(closestTwelveAM.getTime() / 1e3);
1213
1388
  };
1214
1389
 
1215
- // src/models/scallopAddress.ts
1216
- import axios from "axios";
1390
+ // src/constants/tokenBucket.ts
1391
+ var DEFAULT_TOKENS_PER_INTERVAL = 50;
1392
+ var DEFAULT_INTERVAL_IN_MS = 300;
1217
1393
 
1218
- // src/constants/testAddress.ts
1219
- var TEST_ADDRESSES = {
1220
- core: {
1221
- // version:
1222
- // '0x07871c4b3c847a0f674510d4978d5cf6f960452795e8ff6f189fd2088a3f6ac7',
1223
- version: "0x6156d5cd1538bec8a167a40fe1209a4ec9cf8137921fe0a697f191ac561f0b09",
1224
- versionCap: "0x590a4011cb649b3878f3ea14b3a78674642a9548d79b7e091ef679574b158a07",
1225
- // object:
1226
- // '0xefe8b36d5b2e43728cc323298626b83177803521d195cfb11e15b910e892fddf',
1227
- object: "0x87ddec2984645dbbe2403a509cc6edf393a43acdba9b77d45da2bcbefcf733c1",
1228
- // market:
1229
- // '0xa757975255146dc9686aa823b7838b507f315d704f428cbadad2f4ea061939d9',
1230
- market: "0x8606ed145cc887985b8ed793f7753ff5dc762a42c379dac035f568e1bac58490",
1231
- adminCap: "0x09689d018e71c337d9db6d67cbca06b74ed92196103624028ccc3ecea411777c",
1232
- coinDecimalsRegistry: "0x200abe9bf19751cc566ae35aa58e2b7e4ff688fc1130f8d8909ea09bc137d668",
1233
- // obligationAccessStore:
1234
- // '0x733e30b7c94d619d78cb8f5bc4bfbb759ced9a531239028caabb2474e5be59c9',
1235
- obligationAccessStore: "0x48b472d68ca910c45f7f3b6c26836b6aa6d2569810d94b1b939023da05ae0a23",
1236
- coins: {
1237
- cetus: {
1238
- id: "0x06864a6f921804860930db6ddbe2e16acdf8504495ea7481637a1c8b9a8fe54b",
1239
- metaData: "0x4c0dce55eff2db5419bbd2d239d1aa22b4a400c01bbb648b058a9883989025da",
1240
- treasury: "",
1241
- oracle: {
1242
- supra: "",
1243
- switchboard: "",
1244
- pyth: {
1245
- feed: "e5b274b2611143df055d6e7cd8d93fe1961716bcd4dca1cad87a83bc1e78c1ef",
1246
- feedObject: "0x24c0247fb22457a719efac7f670cdc79be321b521460bd6bd2ccfa9f80713b14"
1247
- }
1248
- }
1249
- },
1250
- wapt: {
1251
- id: "0x3a5143bb1196e3bcdfab6203d1683ae29edd26294fc8bfeafe4aaa9d2704df37",
1252
- metaData: "0xc969c5251f372c0f34c32759f1d315cf1ea0ee5e4454b52aea08778eacfdd0a8",
1253
- treasury: "",
1254
- oracle: {
1255
- supra: "",
1256
- switchboard: "",
1257
- pyth: {
1258
- feed: "03ae4db29ed4ae33d323568895aa00337e658e348b37509f5372ae51f0af00d5",
1259
- feedObject: "0x7c5b7837c44a69b469325463ac0673ac1aa8435ff44ddb4191c9ae380463647f"
1260
- }
1261
- }
1262
- },
1263
- wsol: {
1264
- id: "0xb7844e289a8410e50fb3ca48d69eb9cf29e27d223ef90353fe1bd8e27ff8f3f8",
1265
- metaData: "0x4d2c39082b4477e3e79dc4562d939147ab90c42fc5f3e4acf03b94383cd69b6e",
1266
- treasury: "",
1267
- oracle: {
1268
- supra: "",
1269
- switchboard: "",
1270
- pyth: {
1271
- feed: "ef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d",
1272
- feedObject: "0x9d0d275efbd37d8a8855f6f2c761fa5983293dd8ce202ee5196626de8fcd4469"
1273
- }
1274
- }
1275
- },
1276
- wbtc: {
1277
- id: "0x027792d9fed7f9844eb4839566001bb6f6cb4804f66aa2da6fe1ee242d896881",
1278
- metaData: "0x5d3c6e60eeff8a05b693b481539e7847dfe33013e7070cdcb387f5c0cac05dfd",
1279
- treasury: "",
1280
- oracle: {
1281
- supra: "",
1282
- switchboard: "",
1283
- pyth: {
1284
- feed: "e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43",
1285
- feedObject: "0x9a62b4863bdeaabdc9500fce769cf7e72d5585eeb28a6d26e4cafadc13f76ab2"
1286
- }
1287
- }
1288
- },
1289
- weth: {
1290
- id: "0xaf8cd5edc19c4512f4259f0bee101a40d41ebed738ade5874359610ef8eeced5",
1291
- metaData: "0x8900e4ceede3363bef086d6b50ca89d816d0e90bf6bc46efefe1f8455e08f50f",
1292
- treasury: "",
1293
- oracle: {
1294
- supra: "",
1295
- switchboard: "",
1296
- pyth: {
1297
- feed: "ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace",
1298
- feedObject: "0x9193fd47f9a0ab99b6e365a464c8a9ae30e6150fc37ed2a89c1586631f6fc4ab"
1299
- }
1300
- }
1301
- },
1302
- wusdc: {
1303
- id: "0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf",
1304
- metaData: "0x4fbf84f3029bd0c0b77164b587963be957f853eccf834a67bb9ecba6ec80f189",
1305
- treasury: "",
1306
- oracle: {
1307
- supra: "",
1308
- switchboard: "",
1309
- pyth: {
1310
- feed: "eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a",
1311
- feedObject: "0x5dec622733a204ca27f5a90d8c2fad453cc6665186fd5dff13a83d0b6c9027ab"
1312
- }
1313
- }
1314
- },
1315
- wusdt: {
1316
- id: "0xc060006111016b8a020ad5b33834984a437aaa7d3c74c18e09a95d48aceab08c",
1317
- metaData: "0xfb0e3eb97dd158a5ae979dddfa24348063843c5b20eb8381dd5fa7c93699e45c",
1318
- treasury: "",
1319
- oracle: {
1320
- supra: "",
1321
- switchboard: "",
1322
- pyth: {
1323
- feed: "2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b",
1324
- feedObject: "0x985e3db9f93f76ee8bace7c3dd5cc676a096accd5d9e09e9ae0fb6e492b14572"
1325
- }
1326
- }
1327
- },
1328
- sui: {
1329
- id: "0x0000000000000000000000000000000000000000000000000000000000000002",
1330
- metaData: "0x9258181f5ceac8dbffb7030890243caed69a9599d2886d957a9cb7656af3bdb3",
1331
- treasury: "",
1332
- oracle: {
1333
- supra: "",
1334
- switchboard: "0xbca474133638352ba83ccf7b5c931d50f764b09550e16612c9f70f1e21f3f594",
1335
- pyth: {
1336
- feed: "23d7315113f5b1d3ba7a83604c44b94d79f4fd69af77f804fc7f920a6dc65744",
1337
- feedObject: "0x801dbc2f0053d34734814b2d6df491ce7807a725fe9a01ad74a07e9c51396c37"
1338
- }
1339
- }
1340
- },
1341
- afsui: {
1342
- id: "0xf325ce1300e8dac124071d3152c5c5ee6174914f8bc2161e88329cf579246efc",
1343
- metaData: "0x2f9217f533e51334873a39b8026a4aa6919497b47f49d0986a4f1aec66f8a34d",
1344
- treasury: "",
1345
- oracle: {
1346
- supra: "",
1347
- switchboard: "",
1348
- pyth: {
1349
- feed: "23d7315113f5b1d3ba7a83604c44b94d79f4fd69af77f804fc7f920a6dc65744",
1350
- feedObject: "0x801dbc2f0053d34734814b2d6df491ce7807a725fe9a01ad74a07e9c51396c37"
1351
- }
1352
- }
1353
- },
1354
- hasui: {
1355
- id: "0xbde4ba4c2e274a60ce15c1cfff9e5c42e41654ac8b6d906a57efa4bd3c29f47d",
1356
- metaData: "0x2c5f33af93f6511df699aaaa5822d823aac6ed99d4a0de2a4a50b3afa0172e24",
1357
- treasury: "",
1358
- oracle: {
1359
- supra: "",
1360
- switchboard: "",
1361
- pyth: {
1362
- feed: "23d7315113f5b1d3ba7a83604c44b94d79f4fd69af77f804fc7f920a6dc65744",
1363
- feedObject: "0x801dbc2f0053d34734814b2d6df491ce7807a725fe9a01ad74a07e9c51396c37"
1364
- }
1365
- }
1366
- },
1367
- vsui: {
1368
- id: "0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55",
1369
- metaData: "0xabd84a23467b33854ab25cf862006fd97479f8f6f53e50fe732c43a274d939bd",
1370
- treasury: "",
1371
- oracle: {
1372
- supra: "",
1373
- switchboard: "",
1374
- pyth: {
1375
- feed: "23d7315113f5b1d3ba7a83604c44b94d79f4fd69af77f804fc7f920a6dc65744",
1376
- feedObject: "0x801dbc2f0053d34734814b2d6df491ce7807a725fe9a01ad74a07e9c51396c37"
1377
- }
1378
- }
1379
- },
1380
- sca: {
1381
- id: "0x7016aae72cfc67f2fadf55769c0a7dd54291a583b63051a5ed71081cce836ac6",
1382
- metaData: "0x5d26a1e9a55c88147ac870bfa31b729d7f49f8804b8b3adfdf3582d301cca844",
1383
- treasury: "",
1384
- oracle: {
1385
- supra: "",
1386
- switchboard: "",
1387
- pyth: {
1388
- feed: "7e17f0ac105abe9214deb9944c30264f5986bf292869c6bd8e8da3ccd92d79bc",
1389
- feedObject: "0xf6de1d3279a269a597d813cbaca59aa906543ab9a8c64e84a4722f1a20863985"
1390
- }
1394
+ // src/utils/tokenBucket.ts
1395
+ var TokenBucket = class {
1396
+ constructor(tokensPerInterval, intervalInMs) {
1397
+ this.tokensPerInterval = tokensPerInterval;
1398
+ this.interval = intervalInMs;
1399
+ this.tokens = tokensPerInterval;
1400
+ this.lastRefill = Date.now();
1401
+ }
1402
+ refill() {
1403
+ const now = Date.now();
1404
+ const elapsed = now - this.lastRefill;
1405
+ if (elapsed > this.interval) {
1406
+ const tokensToAdd = Math.floor(elapsed / this.interval) * this.tokensPerInterval;
1407
+ this.tokens = Math.min(this.tokens + tokensToAdd, this.tokensPerInterval);
1408
+ this.lastRefill = now;
1409
+ }
1410
+ }
1411
+ removeTokens(count) {
1412
+ this.refill();
1413
+ if (this.tokens >= count) {
1414
+ this.tokens -= count;
1415
+ return true;
1416
+ }
1417
+ return false;
1418
+ }
1419
+ };
1420
+ var callWithRateLimit = async (tokenBucket, fn, retryDelayInMs = DEFAULT_INTERVAL_IN_MS, maxRetries = 15, backoffFactor = 1.25) => {
1421
+ let retries = 0;
1422
+ const tryRequest = async () => {
1423
+ if (tokenBucket.removeTokens(1)) {
1424
+ try {
1425
+ const result = await fn();
1426
+ if (result && result.status === 429) {
1427
+ throw new Error("Unexpected status code: 429");
1428
+ }
1429
+ return result;
1430
+ } catch (error) {
1431
+ if (error.message === "Unexpected status code: 429" && retries < maxRetries) {
1432
+ retries++;
1433
+ const delay = retryDelayInMs * Math.pow(backoffFactor, retries);
1434
+ await new Promise((resolve) => setTimeout(resolve, delay));
1435
+ return tryRequest();
1436
+ } else {
1437
+ console.error("An error occurred:", error.message);
1438
+ return null;
1391
1439
  }
1392
1440
  }
1393
- },
1394
- oracles: {
1395
- xOracle: "0x93d5bf0936b71eb27255941e532fac33b5a5c7759e377b4923af0a1359ad494f",
1396
- xOracleCap: "0x1edeae568fde99e090dbdec4bcdbd33a15f53a1ce1f87aeef1a560dedf4b4a90",
1397
- supra: { registry: "", registryCap: "", holder: "" },
1398
- switchboard: { registry: "", registryCap: "" },
1399
- pyth: {
1400
- registry: "0xedc293f9413a5a7a5d53bdba1fd889d0a4030894469228f0acdae4aa3c55a213",
1401
- registryCap: "0xbcb07141eb1f7e01fbda4130ecf5f5adaeabb77f5d9c32158b7532bcd2197acd",
1402
- state: "0x1f9310238ee9298fb703c3419030b35b22bb1cc37113e3bb5007c99aec79e5b8",
1403
- wormhole: "0x5306f64e312b581766351c07af79c72fcb1cd25147157fdc2f8ad76de9a3fb6a",
1404
- wormholeState: "0xaeab97f96cf9877fee2883315d459552b2b921edc16d7ceac6eab944dd88919c"
1405
- }
1406
- },
1407
- packages: {
1408
- coinDecimalsRegistry: {
1409
- id: "0xca5a5a62f01c79a104bf4d31669e29daa387f325c241de4edbe30986a9bc8b0d",
1410
- upgradeCap: "0x34e76a945d29f195bc53ca704fa70877d1cf3a5d7bbfdda1b13e633fff13c0f6"
1411
- },
1412
- math: {
1413
- id: "0xad013d5fde39e15eabda32b3dbdafd67dac32b798ce63237c27a8f73339b9b6f",
1414
- upgradeCap: "0x3a329598231de02e6135c62284b66005b41cad1d9ab7ca2dc79c08293aba2ec6"
1415
- },
1416
- whitelist: {
1417
- id: "0x1318fdc90319ec9c24df1456d960a447521b0a658316155895014a6e39b5482f",
1418
- upgradeCap: "0xf5a22aea23db664f7b69855b6a546747f17c1ec4230319cfc17225e462b05761"
1419
- },
1420
- x: {
1421
- id: "0x779b5c547976899f5474f3a5bc0db36ddf4697ad7e5a901db0415c2281d28162",
1422
- upgradeCap: "0x3f203f6fff6a69d151e4f1cd931f22b68c489ef2759765662fc7baf673943c9e"
1423
- },
1424
- protocol: {
1425
- id: "0x87ddec2984645dbbe2403a509cc6edf393a43acdba9b77d45da2bcbefcf733c1",
1426
- upgradeCap: "0x38527d154618d1fd5a644b90717fe07cf0e9f26b46b63e9568e611a3f86d5c1a"
1427
- },
1428
- // protocol: {
1429
- // id: '0x6e641f0dca8aedab3101d047e96439178f16301bf0b57fe8745086ff1195eb3e',
1430
- // upgradeCap:
1431
- // '0x38527d154618d1fd5a644b90717fe07cf0e9f26b46b63e9568e611a3f86d5c1a',
1432
- // },
1433
- protocolWhitelist: {
1434
- id: "0x4c262d9343dac53ecb28f482a2a3f62c73d0ebac5b5f03d57383d56ff219acdf",
1435
- upgradeCap: "0x4a5e88a75039b00988f633f811f58117f31b8627a46bf822aa114d9010049449"
1436
- },
1437
- // query: {
1438
- // id: '0xb8d603a39114a5efef3dd0bf84df0bed1be1fbd39b78b7dd6e8a61ccc5e6006f',
1439
- // upgradeCap:
1440
- // '0x0d535c35f608b9b01b7ccce11acf43b1dd80c1b72bf8b541744a6e28e8d2745f',
1441
- // },
1442
- query: {
1443
- id: "0xe4f9d62d17746d5b9dbf0d5557747430021a71575780b515161210cdba0a4c1c",
1444
- upgradeCap: "0x0d535c35f608b9b01b7ccce11acf43b1dd80c1b72bf8b541744a6e28e8d2745f"
1445
- },
1446
- supra: { id: "", upgradeCap: "" },
1447
- pyth: {
1448
- id: "0x910f30cbc7f601f75a5141a01265cd47c62d468707c5e1aecb32a18f448cb25a",
1449
- upgradeCap: "0xdf0ffbae1ea5bb25fbca5efba433dcf00c7cced65679af2f04728901275c6157"
1450
- },
1451
- switchboard: { id: "", upgradeCap: "" },
1452
- xOracle: {
1453
- id: "0x1478a432123e4b3d61878b629f2c692969fdb375644f1251cd278a4b1e7d7cd6",
1454
- upgradeCap: "0x0f928a6b2e26b73330fecaf9b44acfc9800a4a9794d6415c2a3153bc70e3c1f0"
1455
- },
1456
- testCoin: { id: "", upgradeCap: "" }
1441
+ } else if (retries < maxRetries) {
1442
+ retries++;
1443
+ const delay = retryDelayInMs * Math.pow(backoffFactor, retries);
1444
+ await new Promise((resolve) => setTimeout(resolve, delay));
1445
+ return tryRequest();
1446
+ } else {
1447
+ console.error("Maximum retries reached");
1448
+ return null;
1457
1449
  }
1458
- },
1459
- spool: {
1460
- // id: '0x7c4fdabe81c31b19a45d1e572a52a539997a90903fbb5bfab71480abe0fa62c3',
1461
- id: "0x1742655fe5872dfa6456673f9e38612a4965e6979e6cd7696a7f1225f28bae21",
1462
- adminCap: "0xdd8a047cbbf802bfcde5288b8ef1910965d789cc614da11d39af05fca0bd020a",
1463
- // object:
1464
- // '0xe87f1b2d498106a2c61421cec75b7b5c5e348512b0dc263949a0e7a3c256571a',
1465
- object: "0x1742655fe5872dfa6456673f9e38612a4965e6979e6cd7696a7f1225f28bae21",
1466
- pools: {
1467
- sweth: {
1468
- id: "0xeec40beccb07c575bebd842eeaabb835f77cd3dab73add433477e57f583a6787",
1469
- rewardPoolId: "0x957de68a18d87817de8309b30c1ec269a4d87ae513abbeed86b5619cb9ce1077"
1470
- },
1471
- ssui: {
1472
- // id: '0x4f0ba970d3c11db05c8f40c64a15b6a33322db3702d634ced6536960ab6f3ee4',
1473
- id: "0xb9617f83c06ebdeac0a8834782b1015e1cc7ea23739e30c132c4bfb95c37a579",
1474
- rewardPoolId: (
1475
- // '0x162250ef72393a4ad3d46294c4e1bdfcb03f04c869d390e7efbfc995353a7ee9',
1476
- "0xc3206071a8d43212efb6e3b5504f2321f8df97ab122b466c0bc7cfdf398dc13a"
1477
- )
1478
- },
1479
- swusdc: {
1480
- // id: '0x4ace6648ddc64e646ba47a957c562c32c9599b3bba8f5ac1aadb2ae23a2f8ca0',
1481
- id: "0xf1b383b9cf2e9f515fc69567df1053098f273849d09cd84b0278a773429bd2b2",
1482
- rewardPoolId: (
1483
- // '0xf4268cc9b9413b9bfe09e8966b8de650494c9e5784bf0930759cfef4904daff8',
1484
- "0xc71c53ee6505d928ba15bea4fe4f45d98c9c31eced94b72d00a7827d4b7ba3ff"
1485
- )
1486
- },
1487
- swusdt: {
1488
- // id: '0xcb328f7ffa7f9342ed85af3fdb2f22919e1a06dfb2f713c04c73543870d7548f',
1489
- id: "0xb5567dfa5c7fc17a249e959732664c50713dd8c23db1a11376b27df800c17418",
1490
- rewardPoolId: (
1491
- // '0x2c9f934d67a5baa586ceec2cc24163a2f049a6af3d5ba36b84d8ac40f25c4080',
1492
- "0x60768b0687ff0235e376a039709a683e4c436098785e473b67b32dbab47b69ab"
1493
- )
1494
- },
1495
- scetus: {
1496
- id: "0xac1bb13bf4472a637c18c2415fb0e3c1227ea2bcf35242e50563c98215bd298e",
1497
- rewardPoolId: "0x6835c1224126a45086fc6406adc249e3f30df18d779ca4f4e570e38716a17f3f"
1498
- },
1499
- safsui: {
1500
- // id: '0xeedf438abcaa6ce4d9625ffca110920592d5867e4c5637d84ad9f466c4feb800',
1501
- id: "0xc568bb4c991258e839aa54802ecda04fcd9838c826bc3b42b40af81b23c458c8",
1502
- rewardPoolId: (
1503
- // '0x89255a2f86ed7fbfef35ab8b7be48cc7667015975be2685dd9a55a9a64baf76e',
1504
- "0x389a3cbeda742b918941bb24fd00e077bad3367484394d6234f8209b9a6aa03d"
1505
- )
1506
- },
1507
- shasui: {
1508
- // id: '0xa6148bc1b623e936d39a952ceb5bea79e8b37228a8f595067bf1852efd3c34aa',
1509
- id: "0x93f3f4499bf89f2d05ddc1f8b15f51701a7c6c4d0ac0b9c3bc99462cbbd8e321",
1510
- rewardPoolId: (
1511
- // '0x6f3563644d3e2ef13176dbf9d865bd93479df60ccbe07b7e66db57f6309f5a66',
1512
- "0x94cee1be7f5ff34193f3aabef0b14142cb28af4d905fe487a9a7d85a15edb6aa"
1513
- )
1514
- },
1515
- svsui: {
1516
- // id: '0x69ce8e537e750a95381e6040794afa5ab1758353a1a2e1de7760391b01f91670',
1517
- id: "0xa970e9087f80cb59e9299b8e7af7175d977ad6c9af0322aa4440e138fbd7ae00",
1518
- rewardPoolId: (
1519
- // '0xbca914adce058ad0902c7f3cfcd698392a475f00dcfdc3f76001d0370b98777a',
1520
- "0x38eee9699c4fc132a6623e54b865f047df4fc6eb83af807300f44e8f4b235ff0"
1521
- )
1450
+ };
1451
+ return tryRequest();
1452
+ };
1453
+
1454
+ // src/utils/indexer.ts
1455
+ async function callMethodWithIndexerFallback(method, context, ...args) {
1456
+ const indexer = args[args.length - 1];
1457
+ if (indexer) {
1458
+ try {
1459
+ return await method.apply(context, args);
1460
+ } catch (e) {
1461
+ console.warn(`Indexer requests failed: ${e}. Retrying without indexer..`);
1462
+ return await method.apply(context, [...args.slice(0, -1), false]);
1463
+ }
1464
+ }
1465
+ return await method.apply(context, args);
1466
+ }
1467
+ function withIndexerFallback(method) {
1468
+ return (...args) => {
1469
+ return callMethodWithIndexerFallback(method, this, ...args);
1470
+ };
1471
+ }
1472
+
1473
+ // src/models/scallopCache.ts
1474
+ var ScallopCache = class {
1475
+ constructor(suiKit, walletAddress, cacheOptions, tokenBucket, queryClient) {
1476
+ this.queryClient = queryClient ?? new QueryClient(cacheOptions ?? DEFAULT_CACHE_OPTIONS);
1477
+ this._suiKit = suiKit;
1478
+ this.tokenBucket = tokenBucket ?? new TokenBucket(DEFAULT_TOKENS_PER_INTERVAL, DEFAULT_INTERVAL_IN_MS);
1479
+ this.walletAddress = walletAddress ?? suiKit.currentAddress();
1480
+ }
1481
+ get suiKit() {
1482
+ if (!this._suiKit) {
1483
+ throw new Error("SuiKit instance is not initialized");
1484
+ }
1485
+ return this._suiKit;
1486
+ }
1487
+ get client() {
1488
+ return this.suiKit.client();
1489
+ }
1490
+ /**
1491
+ * @description Invalidate cache based on the refetchType parameter
1492
+ * @param refetchType Determines the type of queries to be refetched. Defaults to `active`.
1493
+ *
1494
+ * - `active`: Only queries that match the refetch predicate and are actively being rendered via useQuery and related functions will be refetched in the background.
1495
+ * - `inactive`: Only queries that match the refetch predicate and are NOT actively being rendered via useQuery and related functions will be refetched in the background.
1496
+ * - `all`: All queries that match the refetch predicate will be refetched in the background.
1497
+ * - `none`: No queries will be refetched. Queries that match the refetch predicate will only be marked as invalid.
1498
+ */
1499
+ async invalidateAllCache() {
1500
+ return Object.values(queryKeys.rpc).map(
1501
+ (t) => this.queryClient.invalidateQueries({
1502
+ queryKey: t(),
1503
+ type: "all"
1504
+ })
1505
+ );
1506
+ }
1507
+ /**
1508
+ * @description Provides cache for inspectTxn of the SuiKit.
1509
+ * @param QueryInspectTxnParams
1510
+ * @param txBlock
1511
+ * @returns Promise<DevInspectResults>
1512
+ */
1513
+ async queryInspectTxn({
1514
+ queryTarget,
1515
+ args,
1516
+ typeArgs
1517
+ }) {
1518
+ const txBlock = new SuiTxBlock();
1519
+ txBlock.moveCall(queryTarget, args, typeArgs);
1520
+ const query = await this.queryClient.fetchQuery({
1521
+ queryKey: queryKeys.rpc.getInspectTxn(queryTarget, args, typeArgs),
1522
+ queryFn: async () => {
1523
+ return await callWithRateLimit(
1524
+ this.tokenBucket,
1525
+ () => this.suiKit.inspectTxn(txBlock)
1526
+ );
1527
+ }
1528
+ });
1529
+ return query;
1530
+ }
1531
+ /**
1532
+ * @description Provides cache for getObject of the SuiKit.
1533
+ * @param objectId
1534
+ * @param QueryObjectParams
1535
+ * @returns Promise<SuiObjectResponse>
1536
+ */
1537
+ async queryGetObject(objectId, options) {
1538
+ return this.queryClient.fetchQuery({
1539
+ queryKey: queryKeys.rpc.getObject(objectId, this.walletAddress, options),
1540
+ queryFn: async () => {
1541
+ return await callWithRateLimit(
1542
+ this.tokenBucket,
1543
+ () => this.client.getObject({
1544
+ id: objectId,
1545
+ options
1546
+ })
1547
+ );
1548
+ }
1549
+ });
1550
+ }
1551
+ /**
1552
+ * @description Provides cache for getObjects of the SuiKit.
1553
+ * @param objectIds
1554
+ * @returns Promise<SuiObjectData[]>
1555
+ */
1556
+ async queryGetObjects(objectIds, options = {
1557
+ showContent: true
1558
+ }) {
1559
+ if (objectIds.length === 0)
1560
+ return [];
1561
+ return this.queryClient.fetchQuery({
1562
+ queryKey: queryKeys.rpc.getObjects(
1563
+ objectIds,
1564
+ this.walletAddress,
1565
+ options
1566
+ ),
1567
+ queryFn: async () => {
1568
+ return await callWithRateLimit(
1569
+ this.tokenBucket,
1570
+ () => this.suiKit.getObjects(objectIds, options)
1571
+ );
1522
1572
  }
1523
- },
1524
- config: ""
1525
- },
1526
- borrowIncentive: {
1527
- id: "0x6152f696fc3a658f33c4b891764731a59153125ffedfa8bff7167c42823f58a9",
1528
- adminCap: "0xc486afa253646f4d381e81d7f1df8aa4723b845a6bb356f69bad635ffefffe2c",
1529
- object: "0x002875153e09f8145ab63527bc85c00f2bd102e12f9573c47f8cdf1a1cb62934",
1530
- query: "0x529edc54a3dce2207703ceebbccb0ac14133f7825c1f528775ba0d85a4063489",
1531
- incentivePools: "0x6547e143d406b5ccd5f46aae482497de279cc1a68c406f701df70a05f9212ab4",
1532
- incentiveAccounts: "0xc4701fdbc1c92f9a636d334d66012b3027659e9fb8aff27279a82edfb6b77d02",
1533
- config: "0xdf5d04b4691cc67e82fd4db8394d89ff44823a9de29716c924f74bb4f11cc1f7"
1534
- },
1535
- referral: {
1536
- id: "0xa3654ebb63eb06c0f4ff52f8aa6512df9f164f7772bdf15dac3709bd3798dda9",
1537
- object: "0x5658d4bf5ddcba27e4337b4262108b3ad1716643cac8c2054ac341538adc72ec",
1538
- adminCap: "0xc5dc06b9074291259f2cac460c940012c781c4430e42125c541cc43101c3bcbd",
1539
- referralBindings: "0xf63299d58789d99de94092b9011323466e55ca0c1ea1a7a3786a589af46e1c09",
1540
- bindingTableId: "0x1c8202b17267ec8d6cf97ca013615354181a04f179570e42601ff2dae19294b1",
1541
- referralRevenuePool: "0x6abd852caf90769c1b185cdf636d841673fa95528f0550f018b8a138bd283c07",
1542
- revenueTableId: "0x595baa3654c297bff84ab7786a2d250f019cefc66e8df8e89fd9d41e02bd30dd",
1543
- referralTiers: "0x962cb903d8d7346190c5204785ccbb91b61086aa764f674c8145df82335cf83e",
1544
- tiersTableId: "0xeac755a7a8b7798530905ac79e8c114f19d0f130f6eab012954f08faac29c75d",
1545
- // authorizedWitnessList:
1546
- // '0xf21b0ed043c9bb70842c0129159f4943dbcc3c9ef2f2f808af65f8be25cfd20e',
1547
- authorizedWitnessList: "0x9d6223dc52015b8a3986a573590ef2af8f1b8f3e4685513888c052f001b87e7f",
1548
- version: "0x1bd4b7285f72e11c316b828c7c47b3f4da18dcec9f9b3dba6d8629cbb6f93e5e"
1549
- },
1550
- vesca: {
1551
- id: "0xb15b6e0cdd85afb5028bea851dd249405e734d800a259147bbc24980629723a4",
1552
- object: "0xb15b6e0cdd85afb5028bea851dd249405e734d800a259147bbc24980629723a4",
1553
- adminCap: "0x8ffa76135c5b85c5fbd73a6448a4a733d826cb63a267ab817656acb77c72d4a5",
1554
- tableId: "0xe3153b2bf124be0b86cb8bd468346a861efd0da52fc42197b54d2f616488a311",
1555
- table: "0x611cb8d9d4d90867467b5ebdf4cc447a0047ed5b01334a28a29fcfe733e3d609",
1556
- treasury: "0xe8c112c09b88158dc6c8e23d1fbae5b3c7136cdee54b7dafc08e65db28c4a5bc",
1557
- config: "0xe0a2ff281e73c1d53cfa85807080f87e833e4f1a7f93dcf8800b3865269a76b9"
1558
- },
1559
- loyaltyProgram: {
1560
- id: "0xd17bcf8b5a59652c36225d478564a8593ae0ed7d650bcacdda1d6fe179127907",
1561
- object: "0xd17bcf8b5a59652c36225d478564a8593ae0ed7d650bcacdda1d6fe179127907",
1562
- rewardPool: "0xf9c090492ef476bd542109d0913ffe871cbfa28578b7114eca2a8c0e5671786f",
1563
- userRewardTableId: "0x748a80395849ed37db1b0e14f2ab5d1d96458d2359ab3a84eb079d0f4ac7cf2e"
1564
- },
1565
- scoin: {
1566
- id: "0xad2ca2aa5089df94bb2d444d5eb3520378c2f2dfb3a0bd2a2c994145ac4b0a53",
1567
- coins: {
1568
- ssui: {
1569
- coinType: "0xfac769100bccc0caebcf4f4e2d00ac2f8883f07f724be28940df90605f5e7e9a::scallop_sui::SCALLOP_SUI",
1570
- treasury: "0x9cb4551b36c17d37e19d700147fa819ea1c487ff8bcf18374de2cceb2e9d4845"
1571
- },
1572
- scetus: {
1573
- coinType: "0x8b71e6d323ed78515af2bead13bf3d0da1562ba4a99234eb7c4f14fd39ef0427::scallop_cetus::SCALLOP_CETUS",
1574
- treasury: "0xd786f4b2d26278cc7911a3445b1b085eab60f269ef9dbb6b87e803d52f155003"
1575
- },
1576
- ssca: {
1577
- coinType: "0x0a9d3c6c9af9f6e8def82921541bcbd17f73ed31bed3adcb684f2a4c267e42f0::scallop_sca::SCALLOP_SCA",
1578
- treasury: "0xe818636d1d6c46d6ea1a2dce9d94696d7cbc18ce27451b603eeaa47aba8d75e0"
1579
- },
1580
- swusdc: {
1581
- coinType: "0xaedc3ab75db8680b81a755015fa90124d217be93457b893c05bac033817defaf::scallop_wormhole_usdc::SCALLOP_WORMHOLE_USDC",
1582
- treasury: "0xfc6971648f867f7fd6928d1b873af71577e2eaf2c7543ef8bc82c431d833ae78"
1583
- },
1584
- swusdt: {
1585
- coinType: "0xbf02fc87ddc104b342ad8414c85ceadf5b0c823c055a06fb0ed776272c01a52a::scallop_wormhole_usdt::SCALLOP_WORMHOLE_USDT",
1586
- treasury: "0xb9593e2c3a0ba796ee815012b75ae46468ea78cda0188b9ac6816efe65503521"
1587
- },
1588
- sweth: {
1589
- coinType: "0x27d54f43e3eda701be56b82e5756e41c84467cd202f5cf713d5f9e45a9f1b6bc::scallop_wormhole_eth::SCALLOP_WORMHOLE_ETH",
1590
- treasury: "0x032b4c8fac94c038dbe986f7587e9b1e4ef580b5ee06d2ef249d85459b7ef05d"
1591
- },
1592
- safsui: {
1593
- coinType: "0xb75b46d975d8d80670b53a6bee90baaa8ce2e0b7d397f079447d641eef6b44ad::scallop_af_sui::SCALLOP_AF_SUI",
1594
- treasury: "0x21450ef0570ef3d224ffa3b873ab802e439ece7b93cc7efad10ae0c1e3b3fcfe"
1595
- },
1596
- shasui: {
1597
- coinType: "0xd973a723874e2c7cde196602a79155a1343a933f8cf87d9b1bb7408bc1acbc58::scallop_ha_sui::SCALLOP_HA_SUI",
1598
- treasury: "0xf822fc1402207e47d2e3ba8ff6e1e594bf1de777dc5ebd2744619cd2726e3b0d"
1599
- },
1600
- svsui: {
1601
- coinType: "0x97023a317320c4498cc4cd239dd02fd30c28246e5e8f81325d63f2bd8d70f6b3::scallop_v_sui::SCALLOP_V_SUI",
1602
- treasury: "0x327114f0bf3559d7e2de10282147ed76a236c7c6775029165c4db09a6062ead6\u0192"
1573
+ });
1574
+ }
1575
+ /**
1576
+ * @description Provides cache for getOwnedObjects of the SuiKit.
1577
+ * @param input
1578
+ * @returns Promise<PaginatedObjectsResponse>
1579
+ */
1580
+ async queryGetOwnedObjects(input) {
1581
+ return this.queryClient.fetchQuery({
1582
+ queryKey: queryKeys.rpc.getOwnedObjects(input),
1583
+ queryFn: async () => {
1584
+ return await callWithRateLimit(
1585
+ this.tokenBucket,
1586
+ () => this.client.getOwnedObjects(input)
1587
+ );
1603
1588
  }
1604
- }
1589
+ });
1590
+ }
1591
+ async queryGetDynamicFields(input) {
1592
+ return this.queryClient.fetchQuery({
1593
+ queryKey: queryKeys.rpc.getDynamicFields(input),
1594
+ queryFn: async () => {
1595
+ return await callWithRateLimit(
1596
+ this.tokenBucket,
1597
+ () => this.client.getDynamicFields(input)
1598
+ );
1599
+ }
1600
+ });
1601
+ }
1602
+ async queryGetDynamicFieldObject(input) {
1603
+ return this.queryClient.fetchQuery({
1604
+ queryKey: queryKeys.rpc.getDynamicFieldObject(input),
1605
+ queryFn: async () => {
1606
+ return await callWithRateLimit(
1607
+ this.tokenBucket,
1608
+ () => this.client.getDynamicFieldObject(input)
1609
+ );
1610
+ }
1611
+ });
1612
+ }
1613
+ async queryGetAllCoinBalances(owner) {
1614
+ return this.queryClient.fetchQuery({
1615
+ queryKey: queryKeys.rpc.getAllCoinBalances(owner),
1616
+ queryFn: async () => {
1617
+ const allBalances = await callWithRateLimit(
1618
+ this.tokenBucket,
1619
+ () => this.client.getAllBalances({ owner })
1620
+ );
1621
+ if (!allBalances)
1622
+ return {};
1623
+ const balances = allBalances.reduce(
1624
+ (acc, coinBalance) => {
1625
+ if (coinBalance.totalBalance !== "0") {
1626
+ acc[normalizeStructTag2(coinBalance.coinType)] = coinBalance.totalBalance;
1627
+ }
1628
+ return acc;
1629
+ },
1630
+ {}
1631
+ );
1632
+ return balances;
1633
+ }
1634
+ });
1635
+ }
1636
+ async queryGetCoinBalance(input) {
1637
+ if (!input.coinType)
1638
+ return "0";
1639
+ return (await this.queryGetAllCoinBalances(input.owner) || {})[normalizeStructTag2(input.coinType)] ?? "0";
1605
1640
  }
1606
1641
  };
1607
1642
 
1608
1643
  // src/models/scallopAddress.ts
1644
+ import axios from "axios";
1609
1645
  var EMPTY_ADDRESSES = {
1610
1646
  core: {
1611
1647
  version: "",
@@ -2331,10 +2367,11 @@ var isolatedAssetZod = zod2.object({
2331
2367
  value: zod2.boolean()
2332
2368
  })
2333
2369
  });
2334
- var ISOLATED_ASSET_KEY = "0x6e641f0dca8aedab3101d047e96439178f16301bf0b57fe8745086ff1195eb3e::market_dynamic_keys::IsolatedAssetKey";
2335
2370
  var getIsolatedAssets = async (address) => {
2336
2371
  try {
2337
2372
  const marketObject = address.get("core.market");
2373
+ const protocolObject = address.get("core.packages.protocol.id");
2374
+ const ISOLATED_ASSET_KEY = `${protocolObject}::market_dynamic_keys::IsolatedAssetKey`;
2338
2375
  const isolatedAssets = [];
2339
2376
  if (!marketObject)
2340
2377
  return isolatedAssets;
@@ -2369,6 +2406,8 @@ var getIsolatedAssets = async (address) => {
2369
2406
  var isIsolatedAsset = async (utils, coinName) => {
2370
2407
  try {
2371
2408
  const marketObject = utils.address.get("core.market");
2409
+ const protocolObject = utils.address.get("core.packages.protocol.id");
2410
+ const ISOLATED_ASSET_KEY = `${protocolObject}::market_dynamic_keys::IsolatedAssetKey`;
2372
2411
  const cachedData = utils.address.cache.queryClient.getQueryData([
2373
2412
  "getDynamicFields",
2374
2413
  marketObject
@@ -2424,7 +2463,7 @@ var queryMarket = async (query, indexer = false) => {
2424
2463
  const queryTarget = `${packageId}::market_query::market_data`;
2425
2464
  const args = [marketId];
2426
2465
  const queryResult = await query.cache.queryInspectTxn({ queryTarget, args });
2427
- const marketData = queryResult?.events[0].parsedJson;
2466
+ const marketData = queryResult?.events[0]?.parsedJson;
2428
2467
  for (const pool of marketData?.pools ?? []) {
2429
2468
  const coinType = normalizeStructTag3(pool.type.name);
2430
2469
  const poolCoinName = query.utils.parseCoinNameFromType(coinType);
@@ -2480,6 +2519,7 @@ var queryMarket = async (query, indexer = false) => {
2480
2519
  marketCoinSupplyAmount: parsedMarketPoolData.marketCoinSupplyAmount,
2481
2520
  minBorrowAmount: parsedMarketPoolData.minBorrowAmount,
2482
2521
  isIsolated: await isIsolatedAsset(query.utils, poolCoinName),
2522
+ // isIsolated: false,
2483
2523
  maxSupplyCoin,
2484
2524
  ...calculatedMarketPoolData
2485
2525
  };
@@ -2518,6 +2558,7 @@ var queryMarket = async (query, indexer = false) => {
2518
2558
  liquidationDiscount: parsedMarketCollateralData.liquidationDiscount,
2519
2559
  liquidationPanelty: parsedMarketCollateralData.liquidationPanelty,
2520
2560
  liquidationReserveFactor: parsedMarketCollateralData.liquidationReserveFactor,
2561
+ isIsolated: await isIsolatedAsset(query.utils, collateralCoinName),
2521
2562
  ...calculatedMarketCollateralData
2522
2563
  };
2523
2564
  }
@@ -2565,79 +2606,73 @@ var getMarketPools = async (query, poolCoinNames = [...SUPPORT_POOLS], indexer =
2565
2606
  return marketPools;
2566
2607
  };
2567
2608
  var getMarketPool = async (query, poolCoinName, indexer = false, marketObject, coinPrice) => {
2568
- let marketPool;
2569
- let balanceSheet;
2570
- let borrowIndex;
2571
- let interestModel;
2572
- let borrowFeeRate;
2573
- coinPrice = coinPrice || (await query.utils.getCoinPrices([poolCoinName]))?.[poolCoinName];
2574
- if (indexer) {
2575
- const marketPoolIndexer = await query.indexer.getMarketPool(poolCoinName);
2576
- marketPoolIndexer.coinPrice = coinPrice || marketPoolIndexer.coinPrice;
2577
- marketPoolIndexer.coinWrappedType = query.utils.getCoinWrappedType(
2578
- marketPoolIndexer.coinName
2579
- );
2580
- return marketPoolIndexer;
2581
- }
2582
- const marketId = query.address.get("core.market");
2583
- marketObject = marketObject || (await query.cache.queryGetObject(marketId, {
2584
- showContent: true
2585
- }))?.data;
2586
- if (marketObject) {
2587
- if (marketObject.content && "fields" in marketObject.content) {
2588
- const fields = marketObject.content.fields;
2589
- const coinType = query.utils.parseCoinType(poolCoinName);
2590
- const balanceSheetParentId = fields.vault.fields.balance_sheets.fields.table.fields.id.id;
2591
- const balanceSheetDynamicFieldObjectResponse = await query.cache.queryGetDynamicFieldObject({
2592
- parentId: balanceSheetParentId,
2593
- name: {
2594
- type: "0x1::type_name::TypeName",
2595
- value: {
2596
- name: coinType.substring(2)
2597
- }
2609
+ try {
2610
+ coinPrice = coinPrice || (await query.utils.getCoinPrices([poolCoinName]))?.[poolCoinName];
2611
+ if (indexer) {
2612
+ const marketPoolIndexer = await query.indexer.getMarketPool(poolCoinName);
2613
+ marketPoolIndexer.coinPrice = coinPrice || marketPoolIndexer.coinPrice;
2614
+ marketPoolIndexer.coinWrappedType = query.utils.getCoinWrappedType(
2615
+ marketPoolIndexer.coinName
2616
+ );
2617
+ return marketPoolIndexer;
2618
+ }
2619
+ const marketId = query.address.get("core.market");
2620
+ marketObject = marketObject || (await query.cache.queryGetObject(marketId, {
2621
+ showContent: true
2622
+ }))?.data;
2623
+ if (!(marketObject && marketObject.content?.dataType === "moveObject"))
2624
+ throw new Error(`Failed to fetch marketObject`);
2625
+ const fields = marketObject.content.fields;
2626
+ const coinType = query.utils.parseCoinType(poolCoinName);
2627
+ const balanceSheetParentId = fields.vault.fields.balance_sheets.fields.table.fields.id.id;
2628
+ const balanceSheetDynamicFieldObjectResponse = await query.cache.queryGetDynamicFieldObject({
2629
+ parentId: balanceSheetParentId,
2630
+ name: {
2631
+ type: "0x1::type_name::TypeName",
2632
+ value: {
2633
+ name: coinType.substring(2)
2598
2634
  }
2599
- });
2600
- if (!balanceSheetDynamicFieldObjectResponse)
2601
- return void 0;
2602
- const balanceSheetDynamicFieldObject = balanceSheetDynamicFieldObjectResponse.data;
2603
- if (balanceSheetDynamicFieldObject && balanceSheetDynamicFieldObject.content && "fields" in balanceSheetDynamicFieldObject.content) {
2604
- const dynamicFields = balanceSheetDynamicFieldObject.content.fields;
2605
- balanceSheet = dynamicFields.value.fields;
2606
2635
  }
2607
- const borrowIndexParentId = fields.borrow_dynamics.fields.table.fields.id.id;
2608
- const borrowIndexDynamicFieldObjectResponse = await query.cache.queryGetDynamicFieldObject({
2609
- parentId: borrowIndexParentId,
2610
- name: {
2611
- type: "0x1::type_name::TypeName",
2612
- value: {
2613
- name: coinType.substring(2)
2614
- }
2636
+ });
2637
+ const balanceSheetDynamicFieldObject = balanceSheetDynamicFieldObjectResponse?.data;
2638
+ if (!(balanceSheetDynamicFieldObject && balanceSheetDynamicFieldObject.content && "fields" in balanceSheetDynamicFieldObject.content))
2639
+ throw new Error(
2640
+ `Failed to fetch balanceSheetDynamicFieldObject for ${poolCoinName}: ${balanceSheetDynamicFieldObjectResponse?.error?.code.toString()}`
2641
+ );
2642
+ const balanceSheet = balanceSheetDynamicFieldObject.content.fields.value.fields;
2643
+ const borrowIndexParentId = fields.borrow_dynamics.fields.table.fields.id.id;
2644
+ const borrowIndexDynamicFieldObjectResponse = await query.cache.queryGetDynamicFieldObject({
2645
+ parentId: borrowIndexParentId,
2646
+ name: {
2647
+ type: "0x1::type_name::TypeName",
2648
+ value: {
2649
+ name: coinType.substring(2)
2615
2650
  }
2616
- });
2617
- if (!borrowIndexDynamicFieldObjectResponse)
2618
- return void 0;
2619
- const borrowIndexDynamicFieldObject = borrowIndexDynamicFieldObjectResponse.data;
2620
- if (borrowIndexDynamicFieldObject && borrowIndexDynamicFieldObject.content && "fields" in borrowIndexDynamicFieldObject.content) {
2621
- const dynamicFields = borrowIndexDynamicFieldObject.content.fields;
2622
- borrowIndex = dynamicFields.value.fields;
2623
2651
  }
2624
- const interestModelParentId = fields.interest_models.fields.table.fields.id.id;
2625
- const interestModelDynamicFieldObjectResponse = await query.cache.queryGetDynamicFieldObject({
2626
- parentId: interestModelParentId,
2627
- name: {
2628
- type: "0x1::type_name::TypeName",
2629
- value: {
2630
- name: coinType.substring(2)
2631
- }
2652
+ });
2653
+ const borrowIndexDynamicFieldObject = borrowIndexDynamicFieldObjectResponse?.data;
2654
+ if (!(borrowIndexDynamicFieldObject && borrowIndexDynamicFieldObject.content && "fields" in borrowIndexDynamicFieldObject.content))
2655
+ throw new Error(
2656
+ `Failed to fetch borrowIndexDynamicFieldObject for ${poolCoinName}`
2657
+ );
2658
+ const borrowIndex = borrowIndexDynamicFieldObject.content.fields.value.fields;
2659
+ const interestModelParentId = fields.interest_models.fields.table.fields.id.id;
2660
+ const interestModelDynamicFieldObjectResponse = await query.cache.queryGetDynamicFieldObject({
2661
+ parentId: interestModelParentId,
2662
+ name: {
2663
+ type: "0x1::type_name::TypeName",
2664
+ value: {
2665
+ name: coinType.substring(2)
2632
2666
  }
2633
- });
2634
- if (!interestModelDynamicFieldObjectResponse)
2635
- return void 0;
2636
- const interestModelDynamicFieldObject = interestModelDynamicFieldObjectResponse.data;
2637
- if (interestModelDynamicFieldObject && interestModelDynamicFieldObject.content && "fields" in interestModelDynamicFieldObject.content) {
2638
- const dynamicFields = interestModelDynamicFieldObject.content.fields;
2639
- interestModel = dynamicFields.value.fields;
2640
2667
  }
2668
+ });
2669
+ const interestModelDynamicFieldObject = interestModelDynamicFieldObjectResponse?.data;
2670
+ if (!(interestModelDynamicFieldObject && interestModelDynamicFieldObject.content && "fields" in interestModelDynamicFieldObject.content))
2671
+ throw new Error(
2672
+ `Failed to fetch interestModelDynamicFieldObject for ${poolCoinName}: ${interestModelDynamicFieldObject}`
2673
+ );
2674
+ const interestModel = interestModelDynamicFieldObject.content.fields.value.fields;
2675
+ const getBorrowFee = async () => {
2641
2676
  const borrowFeeDynamicFieldObjectResponse = await query.cache.queryGetDynamicFieldObject({
2642
2677
  parentId: marketId,
2643
2678
  name: {
@@ -2649,16 +2684,11 @@ var getMarketPool = async (query, poolCoinName, indexer = false, marketObject, c
2649
2684
  }
2650
2685
  }
2651
2686
  });
2652
- if (!borrowFeeDynamicFieldObjectResponse)
2653
- return void 0;
2654
- const borrowFeeDynamicFieldObject = borrowFeeDynamicFieldObjectResponse.data;
2655
- if (borrowFeeDynamicFieldObject && borrowFeeDynamicFieldObject.content && "fields" in borrowFeeDynamicFieldObject.content) {
2656
- const dynamicFields = borrowFeeDynamicFieldObject.content.fields;
2657
- borrowFeeRate = dynamicFields.value.fields;
2658
- }
2659
- }
2660
- }
2661
- if (balanceSheet && borrowIndex && interestModel && (USE_TEST_ADDRESS || borrowFeeRate)) {
2687
+ const borrowFeeDynamicFieldObject = borrowFeeDynamicFieldObjectResponse?.data;
2688
+ if (!(borrowFeeDynamicFieldObject && borrowFeeDynamicFieldObject.content && "fields" in borrowFeeDynamicFieldObject.content))
2689
+ return { value: "0" };
2690
+ return borrowFeeDynamicFieldObject.content.fields.value.fields;
2691
+ };
2662
2692
  const parsedMarketPoolData = parseOriginMarketPoolData({
2663
2693
  type: interestModel.type.fields,
2664
2694
  maxBorrowRate: interestModel.max_borrow_rate.fields,
@@ -2672,7 +2702,7 @@ var getMarketPool = async (query, poolCoinName, indexer = false, marketObject, c
2672
2702
  reserve: balanceSheet.revenue,
2673
2703
  reserveFactor: interestModel.revenue_factor.fields,
2674
2704
  borrowWeight: interestModel.borrow_weight.fields,
2675
- borrowFeeRate: borrowFeeRate || { value: "0" },
2705
+ borrowFeeRate: await getBorrowFee(),
2676
2706
  baseBorrowRatePerSec: interestModel.base_borrow_rate_per_sec.fields,
2677
2707
  borrowRateOnHighKink: interestModel.borrow_rate_on_high_kink.fields,
2678
2708
  borrowRateOnMidKink: interestModel.borrow_rate_on_mid_kink.fields,
@@ -2688,7 +2718,7 @@ var getMarketPool = async (query, poolCoinName, indexer = false, marketObject, c
2688
2718
  const maxSupplyCoin = BigNumber2(
2689
2719
  await getSupplyLimit(query.utils, poolCoinName) ?? "0"
2690
2720
  ).shiftedBy(-coinDecimal).toNumber();
2691
- marketPool = {
2721
+ return {
2692
2722
  coinName: poolCoinName,
2693
2723
  symbol: query.utils.parseSymbol(poolCoinName),
2694
2724
  coinType: query.utils.parseCoinType(poolCoinName),
@@ -2708,10 +2738,12 @@ var getMarketPool = async (query, poolCoinName, indexer = false, marketObject, c
2708
2738
  minBorrowAmount: parsedMarketPoolData.minBorrowAmount,
2709
2739
  maxSupplyCoin,
2710
2740
  isIsolated: await isIsolatedAsset(query.utils, poolCoinName),
2741
+ // isIsolated: false,
2711
2742
  ...calculatedMarketPoolData
2712
2743
  };
2744
+ } catch (e) {
2745
+ console.error(e);
2713
2746
  }
2714
- return marketPool;
2715
2747
  };
2716
2748
  var getMarketCollaterals = async (query, collateralCoinNames = [...SUPPORT_COLLATERALS], indexer = false) => {
2717
2749
  const marketId = query.address.get("core.market");
@@ -2760,85 +2792,76 @@ var getMarketCollateral = async (query, collateralCoinName, indexer = false, mar
2760
2792
  );
2761
2793
  return marketCollateralIndexer;
2762
2794
  }
2763
- let marketCollateral;
2764
- let riskModel;
2765
- let collateralStat;
2766
2795
  const marketId = query.address.get("core.market");
2767
2796
  marketObject = marketObject || (await query.cache.queryGetObject(marketId, {
2768
2797
  showContent: true
2769
2798
  }))?.data;
2770
- if (marketObject) {
2771
- if (marketObject.content && "fields" in marketObject.content) {
2772
- const fields = marketObject.content.fields;
2773
- const coinType = query.utils.parseCoinType(collateralCoinName);
2774
- const riskModelParentId = fields.risk_models.fields.table.fields.id.id;
2775
- const riskModelDynamicFieldObjectResponse = await query.cache.queryGetDynamicFieldObject({
2776
- parentId: riskModelParentId,
2777
- name: {
2778
- type: "0x1::type_name::TypeName",
2779
- value: {
2780
- name: coinType.substring(2)
2781
- }
2782
- }
2783
- });
2784
- if (!riskModelDynamicFieldObjectResponse)
2785
- return void 0;
2786
- const riskModelDynamicFieldObject = riskModelDynamicFieldObjectResponse.data;
2787
- if (riskModelDynamicFieldObject && riskModelDynamicFieldObject.content && "fields" in riskModelDynamicFieldObject.content) {
2788
- const dynamicFields = riskModelDynamicFieldObject.content.fields;
2789
- riskModel = dynamicFields.value.fields;
2799
+ if (!(marketObject && marketObject.content?.dataType === "moveObject"))
2800
+ throw new Error(`Failed to fetch marketObject`);
2801
+ const fields = marketObject.content.fields;
2802
+ const coinType = query.utils.parseCoinType(collateralCoinName);
2803
+ const riskModelParentId = fields.risk_models.fields.table.fields.id.id;
2804
+ const riskModelDynamicFieldObjectResponse = await query.cache.queryGetDynamicFieldObject({
2805
+ parentId: riskModelParentId,
2806
+ name: {
2807
+ type: "0x1::type_name::TypeName",
2808
+ value: {
2809
+ name: coinType.substring(2)
2790
2810
  }
2791
- const collateralStatParentId = fields.collateral_stats.fields.table.fields.id.id;
2792
- const collateralStatDynamicFieldObjectResponse = await query.cache.queryGetDynamicFieldObject({
2793
- parentId: collateralStatParentId,
2794
- name: {
2795
- type: "0x1::type_name::TypeName",
2796
- value: {
2797
- name: coinType.substring(2)
2798
- }
2799
- }
2800
- });
2801
- if (!collateralStatDynamicFieldObjectResponse)
2802
- return void 0;
2803
- const collateralStatDynamicFieldObject = collateralStatDynamicFieldObjectResponse.data;
2804
- if (collateralStatDynamicFieldObject && collateralStatDynamicFieldObject.content && "fields" in collateralStatDynamicFieldObject.content) {
2805
- const dynamicFields = collateralStatDynamicFieldObject.content.fields;
2806
- collateralStat = dynamicFields.value.fields;
2811
+ }
2812
+ });
2813
+ const riskModelDynamicFieldObject = riskModelDynamicFieldObjectResponse?.data;
2814
+ if (!(riskModelDynamicFieldObject && riskModelDynamicFieldObject.content && "fields" in riskModelDynamicFieldObject.content))
2815
+ throw new Error(
2816
+ `Failed to ftech riskModelDynamicFieldObject for ${riskModelDynamicFieldObjectResponse?.error?.code.toString()}: `
2817
+ );
2818
+ const riskModel = riskModelDynamicFieldObject.content.fields.value.fields;
2819
+ const collateralStatParentId = fields.collateral_stats.fields.table.fields.id.id;
2820
+ const collateralStatDynamicFieldObjectResponse = await query.cache.queryGetDynamicFieldObject({
2821
+ parentId: collateralStatParentId,
2822
+ name: {
2823
+ type: "0x1::type_name::TypeName",
2824
+ value: {
2825
+ name: coinType.substring(2)
2807
2826
  }
2808
2827
  }
2809
- }
2810
- if (riskModel && collateralStat) {
2811
- const parsedMarketCollateralData = parseOriginMarketCollateralData({
2812
- type: riskModel.type.fields,
2813
- collateralFactor: riskModel.collateral_factor.fields,
2814
- liquidationFactor: riskModel.liquidation_factor.fields,
2815
- liquidationDiscount: riskModel.liquidation_discount.fields,
2816
- liquidationPanelty: riskModel.liquidation_penalty.fields,
2817
- liquidationReserveFactor: riskModel.liquidation_revenue_factor.fields,
2818
- maxCollateralAmount: riskModel.max_collateral_amount,
2819
- totalCollateralAmount: collateralStat.amount
2820
- });
2821
- const calculatedMarketCollateralData = calculateMarketCollateralData(
2822
- query.utils,
2823
- parsedMarketCollateralData
2828
+ });
2829
+ const collateralStatDynamicFieldObject = collateralStatDynamicFieldObjectResponse?.data;
2830
+ if (!(collateralStatDynamicFieldObject && collateralStatDynamicFieldObject.content && "fields" in collateralStatDynamicFieldObject.content))
2831
+ throw new Error(
2832
+ `Failed to fetch collateralStatDynamicFieldObject for ${collateralCoinName}: ${collateralStatDynamicFieldObjectResponse?.error?.code.toString()}`
2824
2833
  );
2825
- marketCollateral = {
2826
- coinName: collateralCoinName,
2827
- symbol: query.utils.parseSymbol(collateralCoinName),
2828
- coinType: query.utils.parseCoinType(collateralCoinName),
2829
- marketCoinType: query.utils.parseMarketCoinType(collateralCoinName),
2830
- coinWrappedType: query.utils.getCoinWrappedType(collateralCoinName),
2831
- coinDecimal: query.utils.getCoinDecimal(collateralCoinName),
2832
- coinPrice: coinPrice ?? 0,
2833
- collateralFactor: parsedMarketCollateralData.collateralFactor,
2834
- liquidationFactor: parsedMarketCollateralData.liquidationFactor,
2835
- liquidationDiscount: parsedMarketCollateralData.liquidationDiscount,
2836
- liquidationPanelty: parsedMarketCollateralData.liquidationPanelty,
2837
- liquidationReserveFactor: parsedMarketCollateralData.liquidationReserveFactor,
2838
- ...calculatedMarketCollateralData
2839
- };
2840
- }
2841
- return marketCollateral;
2834
+ const collateralStat = collateralStatDynamicFieldObject.content.fields.value.fields;
2835
+ const parsedMarketCollateralData = parseOriginMarketCollateralData({
2836
+ type: riskModel.type.fields,
2837
+ collateralFactor: riskModel.collateral_factor.fields,
2838
+ liquidationFactor: riskModel.liquidation_factor.fields,
2839
+ liquidationDiscount: riskModel.liquidation_discount.fields,
2840
+ liquidationPanelty: riskModel.liquidation_penalty.fields,
2841
+ liquidationReserveFactor: riskModel.liquidation_revenue_factor.fields,
2842
+ maxCollateralAmount: riskModel.max_collateral_amount,
2843
+ totalCollateralAmount: collateralStat.amount
2844
+ });
2845
+ const calculatedMarketCollateralData = calculateMarketCollateralData(
2846
+ query.utils,
2847
+ parsedMarketCollateralData
2848
+ );
2849
+ return {
2850
+ coinName: collateralCoinName,
2851
+ symbol: query.utils.parseSymbol(collateralCoinName),
2852
+ coinType: query.utils.parseCoinType(collateralCoinName),
2853
+ marketCoinType: query.utils.parseMarketCoinType(collateralCoinName),
2854
+ coinWrappedType: query.utils.getCoinWrappedType(collateralCoinName),
2855
+ coinDecimal: query.utils.getCoinDecimal(collateralCoinName),
2856
+ coinPrice: coinPrice ?? 0,
2857
+ collateralFactor: parsedMarketCollateralData.collateralFactor,
2858
+ liquidationFactor: parsedMarketCollateralData.liquidationFactor,
2859
+ liquidationDiscount: parsedMarketCollateralData.liquidationDiscount,
2860
+ liquidationPanelty: parsedMarketCollateralData.liquidationPanelty,
2861
+ liquidationReserveFactor: parsedMarketCollateralData.liquidationReserveFactor,
2862
+ isIsolated: await isIsolatedAsset(query.utils, collateralCoinName),
2863
+ ...calculatedMarketCollateralData
2864
+ };
2842
2865
  };
2843
2866
  var getObligations = async ({
2844
2867
  address
@@ -3066,6 +3089,9 @@ var getSpools = async (query, stakeMarketCoinNames = [...SUPPORT_SPOOLS], indexe
3066
3089
  var getSpool = async (query, marketCoinName, indexer = false, marketPool, coinPrices) => {
3067
3090
  const coinName = query.utils.parseCoinName(marketCoinName);
3068
3091
  marketPool = marketPool || await query.getMarketPool(coinName, indexer);
3092
+ if (!marketPool) {
3093
+ throw new Error("Failed to fetch marketPool");
3094
+ }
3069
3095
  const poolId = query.address.get(`spool.pools.${marketCoinName}.id`);
3070
3096
  const rewardPoolId = query.address.get(
3071
3097
  `spool.pools.${marketCoinName}.rewardPoolId`
@@ -3075,10 +3101,10 @@ var getSpool = async (query, marketCoinName, indexer = false, marketPool, coinPr
3075
3101
  if (indexer) {
3076
3102
  const spoolIndexer = await query.indexer.getSpool(marketCoinName);
3077
3103
  const coinName2 = query.utils.parseCoinName(marketCoinName);
3078
- const rewardCoinName = query.utils.getSpoolRewardCoinName(marketCoinName);
3104
+ const rewardCoinName2 = query.utils.getSpoolRewardCoinName(marketCoinName);
3079
3105
  spoolIndexer.coinPrice = coinPrices?.[coinName2] || spoolIndexer.coinPrice;
3080
3106
  spoolIndexer.marketCoinPrice = (coinPrices?.[coinName2] ?? 0) * (marketPool ? marketPool.conversionRate : 0) || spoolIndexer.marketCoinPrice;
3081
- spoolIndexer.rewardCoinPrice = coinPrices?.[rewardCoinName] || spoolIndexer.rewardCoinPrice;
3107
+ spoolIndexer.rewardCoinPrice = coinPrices?.[rewardCoinName2] || spoolIndexer.rewardCoinPrice;
3082
3108
  return spoolIndexer;
3083
3109
  }
3084
3110
  const spoolObjectResponse = await query.cache.queryGetObjects(
@@ -3087,70 +3113,71 @@ var getSpool = async (query, marketCoinName, indexer = false, marketPool, coinPr
3087
3113
  showContent: true
3088
3114
  }
3089
3115
  );
3090
- if (marketPool && spoolObjectResponse[0] && spoolObjectResponse[1]) {
3091
- const rewardCoinName = query.utils.getSpoolRewardCoinName(marketCoinName);
3092
- coinPrices = coinPrices || await query.utils.getCoinPrices([coinName, rewardCoinName]);
3093
- const spoolObject = spoolObjectResponse[0];
3094
- const rewardPoolObject = spoolObjectResponse[1];
3095
- if (spoolObject.content && "fields" in spoolObject.content) {
3096
- const spoolFields = spoolObject.content.fields;
3097
- const parsedSpoolData = parseOriginSpoolData({
3098
- stakeType: spoolFields.stake_type,
3099
- maxDistributedPoint: spoolFields.max_distributed_point,
3100
- distributedPoint: spoolFields.distributed_point,
3101
- distributedPointPerPeriod: spoolFields.distributed_point_per_period,
3102
- pointDistributionTime: spoolFields.point_distribution_time,
3103
- maxStake: spoolFields.max_stakes,
3104
- stakes: spoolFields.stakes,
3105
- index: spoolFields.index,
3106
- createdAt: spoolFields.created_at,
3107
- lastUpdate: spoolFields.last_update
3116
+ if (!(spoolObjectResponse[0] && spoolObjectResponse[1])) {
3117
+ throw new Error("Fail to fetch spoolObjectResponse!");
3118
+ }
3119
+ const rewardCoinName = query.utils.getSpoolRewardCoinName(marketCoinName);
3120
+ coinPrices = coinPrices || await query.utils.getCoinPrices([coinName, rewardCoinName]);
3121
+ const spoolObject = spoolObjectResponse[0];
3122
+ const rewardPoolObject = spoolObjectResponse[1];
3123
+ if (spoolObject.content && "fields" in spoolObject.content) {
3124
+ const spoolFields = spoolObject.content.fields;
3125
+ const parsedSpoolData = parseOriginSpoolData({
3126
+ stakeType: spoolFields.stake_type,
3127
+ maxDistributedPoint: spoolFields.max_distributed_point,
3128
+ distributedPoint: spoolFields.distributed_point,
3129
+ distributedPointPerPeriod: spoolFields.distributed_point_per_period,
3130
+ pointDistributionTime: spoolFields.point_distribution_time,
3131
+ maxStake: spoolFields.max_stakes,
3132
+ stakes: spoolFields.stakes,
3133
+ index: spoolFields.index,
3134
+ createdAt: spoolFields.created_at,
3135
+ lastUpdate: spoolFields.last_update
3136
+ });
3137
+ const marketCoinPrice = (coinPrices?.[coinName] ?? 0) * marketPool.conversionRate;
3138
+ const marketCoinDecimal = query.utils.getCoinDecimal(marketCoinName);
3139
+ const calculatedSpoolData = calculateSpoolData(
3140
+ parsedSpoolData,
3141
+ marketCoinPrice,
3142
+ marketCoinDecimal
3143
+ );
3144
+ if (rewardPoolObject.content && "fields" in rewardPoolObject.content) {
3145
+ const rewardPoolFields = rewardPoolObject.content.fields;
3146
+ const parsedSpoolRewardPoolData = parseOriginSpoolRewardPoolData({
3147
+ claimed_rewards: rewardPoolFields.claimed_rewards,
3148
+ exchange_rate_numerator: rewardPoolFields.exchange_rate_numerator,
3149
+ exchange_rate_denominator: rewardPoolFields.exchange_rate_denominator,
3150
+ rewards: rewardPoolFields.rewards,
3151
+ spool_id: rewardPoolFields.spool_id
3108
3152
  });
3109
- const marketCoinPrice = (coinPrices?.[coinName] ?? 0) * marketPool.conversionRate;
3110
- const marketCoinDecimal = query.utils.getCoinDecimal(marketCoinName);
3111
- const calculatedSpoolData = calculateSpoolData(
3153
+ const rewardCoinPrice = coinPrices?.[rewardCoinName] ?? 0;
3154
+ const rewardCoinDecimal = query.utils.getCoinDecimal(rewardCoinName);
3155
+ const calculatedRewardPoolData = calculateSpoolRewardPoolData(
3112
3156
  parsedSpoolData,
3157
+ parsedSpoolRewardPoolData,
3158
+ calculatedSpoolData,
3159
+ rewardCoinPrice,
3160
+ rewardCoinDecimal
3161
+ );
3162
+ spool = {
3163
+ marketCoinName,
3164
+ symbol: query.utils.parseSymbol(marketCoinName),
3165
+ coinType: query.utils.parseCoinType(coinName),
3166
+ marketCoinType: query.utils.parseMarketCoinType(coinName),
3167
+ rewardCoinType: isMarketCoin(rewardCoinName) ? query.utils.parseMarketCoinType(rewardCoinName) : query.utils.parseCoinType(rewardCoinName),
3168
+ coinDecimal: query.utils.getCoinDecimal(coinName),
3169
+ rewardCoinDecimal: query.utils.getCoinDecimal(rewardCoinName),
3170
+ coinPrice: coinPrices?.[coinName] ?? 0,
3113
3171
  marketCoinPrice,
3114
- marketCoinDecimal
3115
- );
3116
- if (rewardPoolObject.content && "fields" in rewardPoolObject.content) {
3117
- const rewardPoolFields = rewardPoolObject.content.fields;
3118
- const parsedSpoolRewardPoolData = parseOriginSpoolRewardPoolData({
3119
- claimed_rewards: rewardPoolFields.claimed_rewards,
3120
- exchange_rate_numerator: rewardPoolFields.exchange_rate_numerator,
3121
- exchange_rate_denominator: rewardPoolFields.exchange_rate_denominator,
3122
- rewards: rewardPoolFields.rewards,
3123
- spool_id: rewardPoolFields.spool_id
3124
- });
3125
- const rewardCoinPrice = coinPrices?.[rewardCoinName] ?? 0;
3126
- const rewardCoinDecimal = query.utils.getCoinDecimal(rewardCoinName);
3127
- const calculatedRewardPoolData = calculateSpoolRewardPoolData(
3128
- parsedSpoolData,
3129
- parsedSpoolRewardPoolData,
3130
- calculatedSpoolData,
3131
- rewardCoinPrice,
3132
- rewardCoinDecimal
3133
- );
3134
- spool = {
3135
- marketCoinName,
3136
- symbol: query.utils.parseSymbol(marketCoinName),
3137
- coinType: query.utils.parseCoinType(coinName),
3138
- marketCoinType: query.utils.parseMarketCoinType(coinName),
3139
- rewardCoinType: isMarketCoin(rewardCoinName) ? query.utils.parseMarketCoinType(rewardCoinName) : query.utils.parseCoinType(rewardCoinName),
3140
- coinDecimal: query.utils.getCoinDecimal(coinName),
3141
- rewardCoinDecimal: query.utils.getCoinDecimal(rewardCoinName),
3142
- coinPrice: coinPrices?.[coinName] ?? 0,
3143
- marketCoinPrice,
3144
- rewardCoinPrice,
3145
- maxPoint: parsedSpoolData.maxPoint,
3146
- distributedPoint: parsedSpoolData.distributedPoint,
3147
- maxStake: parsedSpoolData.maxStake,
3148
- ...calculatedSpoolData,
3149
- exchangeRateNumerator: parsedSpoolRewardPoolData.exchangeRateNumerator,
3150
- exchangeRateDenominator: parsedSpoolRewardPoolData.exchangeRateDenominator,
3151
- ...calculatedRewardPoolData
3152
- };
3153
- }
3172
+ rewardCoinPrice,
3173
+ maxPoint: parsedSpoolData.maxPoint,
3174
+ distributedPoint: parsedSpoolData.distributedPoint,
3175
+ maxStake: parsedSpoolData.maxStake,
3176
+ ...calculatedSpoolData,
3177
+ exchangeRateNumerator: parsedSpoolRewardPoolData.exchangeRateNumerator,
3178
+ exchangeRateDenominator: parsedSpoolRewardPoolData.exchangeRateDenominator,
3179
+ ...calculatedRewardPoolData
3180
+ };
3154
3181
  }
3155
3182
  }
3156
3183
  return spool;
@@ -4258,7 +4285,7 @@ var getTotalVeScaTreasuryAmount = async (utils, veScaTreasury) => {
4258
4285
  }
4259
4286
  });
4260
4287
  const results = res.results;
4261
- if (results && results[1].returnValues) {
4288
+ if (results && results[1]?.returnValues) {
4262
4289
  const value = Uint8Array.from(results[1].returnValues[0][0]);
4263
4290
  const type = results[1].returnValues[0][1];
4264
4291
  assert(type === "u64", "Result type is not u64");
@@ -4428,10 +4455,10 @@ var ScallopUtils = class {
4428
4455
  * @param address - ScallopAddress instance.
4429
4456
  */
4430
4457
  async init(force = false, address) {
4431
- if (force || !this.address.getAddresses() || !address?.getAddresses()) {
4432
- await this.address.read();
4433
- } else {
4458
+ if (address && !this.address)
4434
4459
  this.address = address;
4460
+ if (force || !this.address.getAddresses()) {
4461
+ await this.address.read();
4435
4462
  }
4436
4463
  }
4437
4464
  /**
@@ -4731,30 +4758,38 @@ var ScallopUtils = class {
4731
4758
  const priceId = this.address.get(
4732
4759
  `core.coins.${coinName}.oracle.pyth.feed`
4733
4760
  );
4734
- acc[coinName] = priceId;
4761
+ if (priceId) {
4762
+ acc[coinName] = priceId;
4763
+ }
4735
4764
  return acc;
4736
4765
  },
4737
4766
  {}
4738
4767
  );
4739
4768
  await Promise.allSettled(
4740
- Object.entries(priceIds).map(async ([coinName, priceId]) => {
4769
+ Object.entries(priceIds).filter(([_, priceId]) => !!priceId).map(async ([coinName, priceId]) => {
4741
4770
  const pythConnection = new SuiPriceServiceConnection(endpoint);
4742
4771
  try {
4743
4772
  const feed = await this.cache.queryClient.fetchQuery({
4744
- queryKey: queryKeys.oracle.getPythLatestPriceFeed(priceId),
4773
+ queryKey: queryKeys.oracle.getPythLatestPriceFeed(
4774
+ priceId,
4775
+ endpoint
4776
+ ),
4745
4777
  queryFn: async () => {
4746
- return await pythConnection.getLatestPriceFeeds([priceId]);
4778
+ return await pythConnection.getLatestPriceFeeds([priceId]) ?? [];
4747
4779
  }
4748
4780
  });
4749
- if (feed) {
4750
- const data = parseDataFromPythPriceFeed(feed[0], this.address);
4781
+ if (feed[0]) {
4782
+ const data = parseDataFromPythPriceFeed(
4783
+ feed[0],
4784
+ this.address
4785
+ );
4751
4786
  this._priceMap.set(coinName, {
4752
4787
  price: data.price,
4753
4788
  publishTime: data.publishTime
4754
4789
  });
4755
4790
  coinPrices[coinName] = data.price;
4791
+ failedRequests.delete(coinName);
4756
4792
  }
4757
- failedRequests.delete(coinName);
4758
4793
  } catch (e) {
4759
4794
  console.warn(
4760
4795
  `Failed to get price ${coinName} feeds with endpoint ${endpoint}: ${e}`
@@ -5495,6 +5530,9 @@ var generateSpoolQuickMethod = ({
5495
5530
  stakeMarketCoinName,
5496
5531
  stakeAccountId
5497
5532
  );
5533
+ if (stakeAccountIds.length === 0) {
5534
+ throw new Error(`No stakeAccountIds found for user ${sender}`);
5535
+ }
5498
5536
  if (typeof amountOrMarketCoin === "number") {
5499
5537
  const stakedMarketCoinAmount = await stakeHelper(
5500
5538
  builder,
@@ -6633,7 +6671,7 @@ var getSCoinTotalSupply = async ({
6633
6671
  typeArgs
6634
6672
  });
6635
6673
  const results = queryResults?.results;
6636
- if (results && results[0].returnValues) {
6674
+ if (results && results[0]?.returnValues) {
6637
6675
  const value = Uint8Array.from(results[0].returnValues[0][0]);
6638
6676
  const type = results[0].returnValues[0][1];
6639
6677
  assert2(type === "u64", "Result type is not u64");
@@ -6777,11 +6815,12 @@ var ScallopQuery = class {
6777
6815
  * @param address - ScallopAddress instance.
6778
6816
  */
6779
6817
  async init(force = false, address) {
6780
- if (force || !this.address.getAddresses() || !address?.getAddresses()) {
6781
- await this.address.read();
6782
- } else {
6818
+ if (address && !this.address) {
6783
6819
  this.address = address;
6784
6820
  }
6821
+ if (force || !this.address.getAddresses()) {
6822
+ await this.address.read();
6823
+ }
6785
6824
  await this.utils.init(force, this.address);
6786
6825
  }
6787
6826
  /* ==================== Core Query Methods ==================== */
@@ -7289,10 +7328,10 @@ var ScallopBuilder = class {
7289
7328
  * @param address - ScallopAddress instance.
7290
7329
  */
7291
7330
  async init(force = false, address) {
7292
- if (force || !this.address.getAddresses() || !address?.getAddresses()) {
7293
- await this.address.read();
7294
- } else {
7331
+ if (address && !this.address)
7295
7332
  this.address = address;
7333
+ if (force || !this.address.getAddresses()) {
7334
+ await this.address.read();
7296
7335
  }
7297
7336
  await this.query.init(force, this.address);
7298
7337
  await this.utils.init(force, this.address);
@@ -7544,7 +7583,7 @@ var ScallopClient = class {
7544
7583
  const sender = walletAddress || this.walletAddress;
7545
7584
  txBlock.setSender(sender);
7546
7585
  const obligations = await this.query.getObligations(sender);
7547
- const specificObligationId = obligationId || obligations?.[0]?.id;
7586
+ const specificObligationId = obligationId || obligations[0]?.id;
7548
7587
  if (specificObligationId) {
7549
7588
  await txBlock.addCollateralQuick(
7550
7589
  amount,
@@ -7615,7 +7654,7 @@ var ScallopClient = class {
7615
7654
  txBlock.setSender(sender);
7616
7655
  const stakeMarketCoinName = this.utils.parseMarketCoinName(stakeCoinName);
7617
7656
  const stakeAccounts = await this.query.getStakeAccounts(stakeMarketCoinName);
7618
- const targetStakeAccount = stakeAccountId || stakeAccounts[0].id;
7657
+ const targetStakeAccount = stakeAccountId || stakeAccounts[0]?.id;
7619
7658
  const marketCoin = await txBlock.depositQuick(amount, stakeCoinName, false);
7620
7659
  if (targetStakeAccount) {
7621
7660
  await txBlock.stakeQuick(
@@ -7750,7 +7789,7 @@ var ScallopClient = class {
7750
7789
  const sender = walletAddress || this.walletAddress;
7751
7790
  txBlock.setSender(sender);
7752
7791
  const stakeAccounts = await this.query.getStakeAccounts(stakeMarketCoinName);
7753
- const targetStakeAccount = stakeAccountId || stakeAccounts[0].id;
7792
+ const targetStakeAccount = stakeAccountId || stakeAccounts[0]?.id;
7754
7793
  if (targetStakeAccount) {
7755
7794
  await txBlock.stakeQuick(amount, stakeMarketCoinName, targetStakeAccount);
7756
7795
  } else {
@@ -8206,6 +8245,7 @@ export {
8206
8245
  ScallopIndexer,
8207
8246
  ScallopQuery,
8208
8247
  ScallopUtils,
8248
+ TEST_ADDRESSES,
8209
8249
  UNLOCK_ROUND_DURATION,
8210
8250
  USE_TEST_ADDRESS,
8211
8251
  assetCoins,