@scallop-io/sui-scallop-sdk 1.3.4-alpha.3 → 1.3.4-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/dist/builders/borrowIncentiveBuilder.d.ts +12 -0
  2. package/dist/builders/coreBuilder.d.ts +12 -0
  3. package/dist/builders/index.d.ts +12 -0
  4. package/dist/builders/loyaltyProgramBuilder.d.ts +12 -0
  5. package/dist/builders/oracle.d.ts +14 -0
  6. package/dist/builders/referralBuilder.d.ts +12 -0
  7. package/dist/builders/sCoinBuilder.d.ts +4 -0
  8. package/dist/builders/spoolBuilder.d.ts +12 -0
  9. package/dist/builders/vescaBuilder.d.ts +25 -0
  10. package/dist/constants/cache.d.ts +14 -0
  11. package/dist/constants/coinGecko.d.ts +2 -0
  12. package/dist/constants/common.d.ts +20 -0
  13. package/dist/constants/enum.d.ts +14 -0
  14. package/dist/constants/flashloan.d.ts +2 -0
  15. package/dist/constants/index.d.ts +12 -0
  16. package/dist/constants/poolAddress.d.ts +5 -0
  17. package/dist/constants/pyth.d.ts +5 -0
  18. package/dist/constants/queryKeys.d.ts +56 -0
  19. package/dist/constants/rpc.d.ts +1 -0
  20. package/dist/constants/testAddress.d.ts +2 -0
  21. package/dist/constants/tokenBucket.d.ts +2 -0
  22. package/dist/constants/vesca.d.ts +5 -0
  23. package/dist/index.d.ts +3 -0
  24. package/dist/index.js +1462 -1464
  25. package/dist/index.js.map +1 -1
  26. package/dist/index.mjs +1461 -1464
  27. package/dist/index.mjs.map +1 -1
  28. package/dist/models/index.d.ts +8 -0
  29. package/dist/models/scallop.d.ts +74 -0
  30. package/dist/models/scallopAddress.d.ts +150 -0
  31. package/dist/models/scallopBuilder.d.ts +89 -0
  32. package/dist/models/scallopCache.d.ts +74 -0
  33. package/dist/models/scallopClient.d.ts +321 -0
  34. package/dist/models/scallopIndexer.d.ts +89 -0
  35. package/dist/models/scallopQuery.d.ts +489 -0
  36. package/dist/models/scallopUtils.d.ts +227 -0
  37. package/dist/models/suiKit.d.ts +2 -0
  38. package/dist/queries/borrowIncentiveQuery.d.ts +61 -0
  39. package/dist/queries/coreQuery.d.ts +167 -0
  40. package/dist/queries/index.d.ts +11 -0
  41. package/dist/queries/isolatedAssetQuery.d.ts +14 -0
  42. package/dist/queries/loyaltyProgramQuery.d.ts +10 -0
  43. package/dist/queries/portfolioQuery.d.ts +73 -0
  44. package/dist/queries/priceQuery.d.ts +16 -0
  45. package/dist/queries/referralQuery.d.ts +7 -0
  46. package/dist/queries/sCoinQuery.d.ts +41 -0
  47. package/dist/queries/spoolQuery.d.ts +70 -0
  48. package/dist/queries/supplyLimitQuery.d.ts +9 -0
  49. package/dist/queries/vescaQuery.d.ts +36 -0
  50. package/dist/test.d.ts +0 -0
  51. package/dist/types/address.d.ts +107 -0
  52. package/dist/types/builder/borrowIncentive.d.ts +35 -0
  53. package/dist/types/builder/core.d.ts +56 -0
  54. package/dist/types/builder/index.d.ts +25 -0
  55. package/dist/types/builder/loyaltyProgram.d.ts +23 -0
  56. package/dist/types/builder/referral.d.ts +30 -0
  57. package/dist/types/builder/sCoin.d.ts +37 -0
  58. package/dist/types/builder/spool.d.ts +29 -0
  59. package/dist/types/builder/vesca.d.ts +51 -0
  60. package/dist/types/constant/common.d.ts +24 -0
  61. package/dist/types/constant/enum.d.ts +48 -0
  62. package/dist/types/constant/index.d.ts +2 -0
  63. package/dist/types/index.d.ts +6 -0
  64. package/dist/types/model.d.ts +54 -0
  65. package/dist/types/query/borrowIncentive.d.ts +124 -0
  66. package/dist/types/query/core.d.ts +361 -0
  67. package/dist/types/query/index.d.ts +7 -0
  68. package/dist/types/query/loyaltyProgram.d.ts +5 -0
  69. package/dist/types/query/portfolio.d.ts +115 -0
  70. package/dist/types/query/sCoin.d.ts +1 -0
  71. package/dist/types/query/spool.d.ts +122 -0
  72. package/dist/types/query/vesca.d.ts +26 -0
  73. package/dist/types/utils.d.ts +21 -0
  74. package/dist/utils/builder.d.ts +15 -0
  75. package/dist/utils/index.d.ts +5 -0
  76. package/dist/utils/indexer.d.ts +17 -0
  77. package/dist/utils/query.d.ts +62 -0
  78. package/dist/utils/tokenBucket.d.ts +11 -0
  79. package/dist/utils/util.d.ts +26 -0
  80. package/package.json +2 -2
  81. package/src/builders/borrowIncentiveBuilder.ts +8 -8
  82. package/src/builders/coreBuilder.ts +5 -5
  83. package/src/builders/index.ts +2 -2
  84. package/src/builders/oracle.ts +4 -4
  85. package/src/builders/referralBuilder.ts +1 -1
  86. package/src/builders/spoolBuilder.ts +6 -6
  87. package/src/builders/vescaBuilder.ts +4 -4
  88. package/src/constants/coinGecko.ts +1 -1
  89. package/src/constants/enum.ts +1 -1
  90. package/src/constants/index.ts +1 -0
  91. package/src/models/scallop.ts +5 -5
  92. package/src/models/scallopAddress.ts +9 -6
  93. package/src/models/scallopBuilder.ts +4 -5
  94. package/src/models/scallopCache.ts +4 -4
  95. package/src/models/scallopClient.ts +4 -4
  96. package/src/models/scallopIndexer.ts +3 -4
  97. package/src/models/scallopQuery.ts +13 -6
  98. package/src/models/scallopUtils.ts +11 -8
  99. package/src/models/suiKit.ts +1 -1
  100. package/src/queries/borrowIncentiveQuery.ts +5 -5
  101. package/src/queries/coreQuery.ts +5 -5
  102. package/src/queries/index.ts +8 -5
  103. package/src/queries/portfolioQuery.ts +4 -4
  104. package/src/queries/priceQuery.ts +2 -2
  105. package/src/queries/spoolQuery.ts +5 -5
  106. package/src/queries/vescaQuery.ts +2 -2
  107. package/src/test.ts +30 -0
  108. package/src/types/address.ts +1 -1
  109. package/src/types/builder/borrowIncentive.ts +3 -3
  110. package/src/types/builder/core.ts +3 -3
  111. package/src/types/builder/index.ts +5 -4
  112. package/src/types/builder/referral.ts +1 -1
  113. package/src/types/builder/sCoin.ts +1 -1
  114. package/src/types/builder/spool.ts +2 -2
  115. package/src/types/constant/common.ts +1 -1
  116. package/src/types/model.ts +2 -2
  117. package/src/types/query/borrowIncentive.ts +2 -2
  118. package/src/types/query/core.ts +1 -1
  119. package/src/types/query/portfolio.ts +2 -2
  120. package/src/types/query/spool.ts +1 -1
  121. package/src/utils/builder.ts +1 -1
  122. package/src/utils/index.ts +2 -2
  123. package/src/utils/query.ts +3 -3
  124. package/src/utils/tokenBucket.ts +1 -1
  125. package/src/utils/util.ts +4 -4
  126. /package/src/queries/{isolatedAsset.ts → isolatedAssetQuery.ts} +0 -0
  127. /package/src/queries/{supplyLimit.ts → supplyLimitQuery.ts} +0 -0
package/dist/index.mjs CHANGED
@@ -881,6 +881,23 @@ var MAX_LOCK_DURATION = MAX_LOCK_ROUNDS * UNLOCK_ROUND_DURATION;
881
881
  var MIN_INITIAL_LOCK_AMOUNT = 1e10;
882
882
  var MIN_TOP_UP_AMOUNT = 1e9;
883
883
 
884
+ // src/constants/rpc.ts
885
+ import { getFullnodeUrl } from "@mysten/sui/client";
886
+ var RPC_PROVIDERS = [
887
+ getFullnodeUrl("mainnet"),
888
+ "https://sui-mainnet.public.blastapi.io",
889
+ "https://sui-mainnet-ca-2.cosmostation.io",
890
+ "https://sui-mainnet-eu-4.cosmostation.io",
891
+ "https://sui-mainnet-endpoint.blockvision.org",
892
+ "https://sui-rpc.publicnode.com",
893
+ "https://sui-mainnet-rpc.allthatnode.com",
894
+ "https://mainnet.suiet.app",
895
+ "https://mainnet.sui.rpcpool.com",
896
+ "https://sui1mainnet-rpc.chainode.tech",
897
+ "https://fullnode.mainnet.apis.scallop.io",
898
+ "https://sui-mainnet-us-2.cosmostation.io"
899
+ ];
900
+
884
901
  // src/models/scallopAddress.ts
885
902
  import { SuiKit } from "@scallop-io/sui-kit";
886
903
 
@@ -994,6 +1011,25 @@ var checkRenewExpiredVeSca = (scaAmount, lockPeriodInDays, prevUnlockAtInMillisT
994
1011
  }
995
1012
  };
996
1013
 
1014
+ // src/utils/indexer.ts
1015
+ async function callMethodWithIndexerFallback(method, context, ...args) {
1016
+ const indexer = args[args.length - 1];
1017
+ if (indexer) {
1018
+ try {
1019
+ return await method.apply(context, args);
1020
+ } catch (e) {
1021
+ console.warn(`Indexer requests failed: ${e}. Retrying without indexer..`);
1022
+ return await method.apply(context, [...args.slice(0, -1), false]);
1023
+ }
1024
+ }
1025
+ return await method.apply(context, args);
1026
+ }
1027
+ function withIndexerFallback(method) {
1028
+ return (...args) => {
1029
+ return callMethodWithIndexerFallback(method, this, ...args);
1030
+ };
1031
+ }
1032
+
997
1033
  // src/utils/query.ts
998
1034
  import BigNumber from "bignumber.js";
999
1035
  import { normalizeStructTag, parseStructTag } from "@mysten/sui/utils";
@@ -1378,6 +1414,66 @@ var estimatedFactor = (amount, scaleStep, type) => {
1378
1414
  return adjustFactor;
1379
1415
  };
1380
1416
 
1417
+ // src/utils/tokenBucket.ts
1418
+ var TokenBucket = class {
1419
+ constructor(tokensPerInterval, intervalInMs) {
1420
+ this.tokensPerInterval = tokensPerInterval;
1421
+ this.interval = intervalInMs;
1422
+ this.tokens = tokensPerInterval;
1423
+ this.lastRefill = Date.now();
1424
+ }
1425
+ refill() {
1426
+ const now = Date.now();
1427
+ const elapsed = now - this.lastRefill;
1428
+ if (elapsed > this.interval) {
1429
+ const tokensToAdd = Math.floor(elapsed / this.interval) * this.tokensPerInterval;
1430
+ this.tokens = Math.min(this.tokens + tokensToAdd, this.tokensPerInterval);
1431
+ this.lastRefill = now;
1432
+ }
1433
+ }
1434
+ removeTokens(count) {
1435
+ this.refill();
1436
+ if (this.tokens >= count) {
1437
+ this.tokens -= count;
1438
+ return true;
1439
+ }
1440
+ return false;
1441
+ }
1442
+ };
1443
+ var callWithRateLimit = async (tokenBucket, fn, retryDelayInMs = DEFAULT_INTERVAL_IN_MS, maxRetries = 30, backoffFactor = 1.25) => {
1444
+ let retries = 0;
1445
+ const tryRequest = async () => {
1446
+ if (tokenBucket.removeTokens(1)) {
1447
+ try {
1448
+ const result = await fn();
1449
+ if (result && result.status === 429) {
1450
+ throw new Error("Unexpected status code: 429");
1451
+ }
1452
+ return result;
1453
+ } catch (error) {
1454
+ if (error.message === "Unexpected status code: 429" && retries < maxRetries) {
1455
+ retries++;
1456
+ const delay = retryDelayInMs * Math.pow(backoffFactor, retries);
1457
+ await new Promise((resolve) => setTimeout(resolve, delay));
1458
+ return tryRequest();
1459
+ } else {
1460
+ console.error("An error occurred:", error.message);
1461
+ return null;
1462
+ }
1463
+ }
1464
+ } else if (retries < maxRetries) {
1465
+ retries++;
1466
+ const delay = retryDelayInMs * Math.pow(backoffFactor, retries);
1467
+ await new Promise((resolve) => setTimeout(resolve, delay));
1468
+ return tryRequest();
1469
+ } else {
1470
+ console.error("Maximum retries reached");
1471
+ return null;
1472
+ }
1473
+ };
1474
+ return tryRequest();
1475
+ };
1476
+
1381
1477
  // src/utils/util.ts
1382
1478
  var COIN_SET = Array.from(
1383
1479
  /* @__PURE__ */ new Set([
@@ -1450,85 +1546,6 @@ var findClosestUnlockRound = (unlockAtInSecondTimestamp) => {
1450
1546
  return Math.floor(closestTwelveAM.getTime() / 1e3);
1451
1547
  };
1452
1548
 
1453
- // src/utils/tokenBucket.ts
1454
- var TokenBucket = class {
1455
- constructor(tokensPerInterval, intervalInMs) {
1456
- this.tokensPerInterval = tokensPerInterval;
1457
- this.interval = intervalInMs;
1458
- this.tokens = tokensPerInterval;
1459
- this.lastRefill = Date.now();
1460
- }
1461
- refill() {
1462
- const now = Date.now();
1463
- const elapsed = now - this.lastRefill;
1464
- if (elapsed > this.interval) {
1465
- const tokensToAdd = Math.floor(elapsed / this.interval) * this.tokensPerInterval;
1466
- this.tokens = Math.min(this.tokens + tokensToAdd, this.tokensPerInterval);
1467
- this.lastRefill = now;
1468
- }
1469
- }
1470
- removeTokens(count) {
1471
- this.refill();
1472
- if (this.tokens >= count) {
1473
- this.tokens -= count;
1474
- return true;
1475
- }
1476
- return false;
1477
- }
1478
- };
1479
- var callWithRateLimit = async (tokenBucket, fn, retryDelayInMs = DEFAULT_INTERVAL_IN_MS, maxRetries = 30, backoffFactor = 1.25) => {
1480
- let retries = 0;
1481
- const tryRequest = async () => {
1482
- if (tokenBucket.removeTokens(1)) {
1483
- try {
1484
- const result = await fn();
1485
- if (result && result.status === 429) {
1486
- throw new Error("Unexpected status code: 429");
1487
- }
1488
- return result;
1489
- } catch (error) {
1490
- if (error.message === "Unexpected status code: 429" && retries < maxRetries) {
1491
- retries++;
1492
- const delay = retryDelayInMs * Math.pow(backoffFactor, retries);
1493
- await new Promise((resolve) => setTimeout(resolve, delay));
1494
- return tryRequest();
1495
- } else {
1496
- console.error("An error occurred:", error.message);
1497
- return null;
1498
- }
1499
- }
1500
- } else if (retries < maxRetries) {
1501
- retries++;
1502
- const delay = retryDelayInMs * Math.pow(backoffFactor, retries);
1503
- await new Promise((resolve) => setTimeout(resolve, delay));
1504
- return tryRequest();
1505
- } else {
1506
- console.error("Maximum retries reached");
1507
- return null;
1508
- }
1509
- };
1510
- return tryRequest();
1511
- };
1512
-
1513
- // src/utils/indexer.ts
1514
- async function callMethodWithIndexerFallback(method, context, ...args) {
1515
- const indexer = args[args.length - 1];
1516
- if (indexer) {
1517
- try {
1518
- return await method.apply(context, args);
1519
- } catch (e) {
1520
- console.warn(`Indexer requests failed: ${e}. Retrying without indexer..`);
1521
- return await method.apply(context, [...args.slice(0, -1), false]);
1522
- }
1523
- }
1524
- return await method.apply(context, args);
1525
- }
1526
- function withIndexerFallback(method) {
1527
- return (...args) => {
1528
- return callMethodWithIndexerFallback(method, this, ...args);
1529
- };
1530
- }
1531
-
1532
1549
  // src/models/scallopCache.ts
1533
1550
  var ScallopCache = class {
1534
1551
  constructor(suiKit, walletAddress, cacheOptions, tokenBucket, queryClient) {
@@ -2369,77 +2386,259 @@ import { normalizeSuiAddress as normalizeSuiAddress3 } from "@mysten/sui/utils";
2369
2386
  import { SUI_TYPE_ARG, normalizeStructTag as normalizeStructTag6 } from "@mysten/sui/utils";
2370
2387
  import { SuiPriceServiceConnection } from "@pythnetwork/pyth-sui-js";
2371
2388
 
2372
- // src/queries/coreQuery.ts
2389
+ // src/queries/borrowIncentiveQuery.ts
2373
2390
  import { normalizeStructTag as normalizeStructTag3 } from "@mysten/sui/utils";
2374
2391
  import BigNumber2 from "bignumber.js";
2375
-
2376
- // src/queries/supplyLimit.ts
2377
- import { z as zod } from "zod";
2378
- var supplyLimitZod = zod.object({
2379
- dataType: zod.string(),
2380
- type: zod.string(),
2381
- hasPublicTransfer: zod.boolean(),
2382
- fields: zod.object({
2383
- id: zod.object({
2384
- id: zod.string()
2385
- }),
2386
- name: zod.object({
2387
- type: zod.string()
2388
- }),
2389
- value: zod.string()
2390
- })
2391
- });
2392
- var SUPPLY_LIMIT_KEY = "0x6e641f0dca8aedab3101d047e96439178f16301bf0b57fe8745086ff1195eb3e::market_dynamic_keys::SupplyLimitKey";
2393
- var getSupplyLimit = async (utils, poolName) => {
2394
- const poolCoinType = utils.parseCoinType(poolName).slice(2);
2395
- const marketObject = utils.address.get("core.market");
2396
- if (!marketObject)
2397
- return null;
2398
- const object = await utils.cache.queryGetDynamicFieldObject({
2399
- parentId: marketObject,
2400
- name: {
2401
- type: SUPPLY_LIMIT_KEY,
2402
- value: poolCoinType
2403
- }
2392
+ var queryBorrowIncentivePools = async (address) => {
2393
+ const queryPkgId = address.get("borrowIncentive.query");
2394
+ const incentivePoolsId = address.get("borrowIncentive.incentivePools");
2395
+ const queryTarget = `${queryPkgId}::incentive_pools_query::incentive_pools_data`;
2396
+ const args = [incentivePoolsId];
2397
+ const queryResult = await address.cache.queryInspectTxn({
2398
+ queryTarget,
2399
+ args
2404
2400
  });
2405
- const parsedData = supplyLimitZod.safeParse(object?.data?.content);
2406
- if (!parsedData.success)
2407
- return null;
2408
- return parsedData.data.fields.value;
2401
+ const borrowIncentivePoolsQueryData = queryResult?.events[0].parsedJson;
2402
+ return borrowIncentivePoolsQueryData;
2409
2403
  };
2410
-
2411
- // src/queries/coreQuery.ts
2412
- var queryMarket = async (query, indexer = false, coinPrices) => {
2404
+ var getBorrowIncentivePools = async (query, borrowIncentiveCoinNames = [
2405
+ ...SUPPORT_BORROW_INCENTIVE_POOLS
2406
+ ], indexer = false, coinPrices) => {
2407
+ const borrowIncentivePools = {};
2413
2408
  coinPrices = coinPrices ?? await query.utils.getCoinPrices() ?? {};
2414
- const pools = {};
2415
- const collaterals = {};
2416
2409
  if (indexer) {
2417
- const marketIndexer = await query.indexer.getMarket();
2418
- const updatePools = (item) => {
2419
- item.coinPrice = coinPrices[item.coinName] ?? item.coinPrice;
2420
- item.coinWrappedType = query.utils.getCoinWrappedType(item.coinName);
2421
- pools[item.coinName] = item;
2422
- };
2423
- const updateCollaterals = (item) => {
2424
- item.coinPrice = coinPrices[item.coinName] ?? item.coinPrice;
2425
- item.coinWrappedType = query.utils.getCoinWrappedType(item.coinName);
2426
- collaterals[item.coinName] = item;
2427
- };
2428
- Object.values(marketIndexer.pools).forEach(updatePools);
2429
- Object.values(marketIndexer.collaterals).forEach(updateCollaterals);
2430
- return {
2431
- pools,
2432
- collaterals
2410
+ const borrowIncentivePoolsIndexer = await query.indexer.getBorrowIncentivePools();
2411
+ const updateBorrowIncentivePool = (pool) => {
2412
+ if (!borrowIncentiveCoinNames.includes(pool.coinName))
2413
+ return;
2414
+ pool.coinPrice = coinPrices[pool.coinName] ?? pool.coinPrice;
2415
+ borrowIncentivePools[pool.coinName] = pool;
2433
2416
  };
2417
+ Object.values(borrowIncentivePoolsIndexer).forEach(
2418
+ updateBorrowIncentivePool
2419
+ );
2420
+ return borrowIncentivePools;
2434
2421
  }
2435
- const packageId = query.address.get("core.packages.query.id");
2436
- const marketId = query.address.get("core.market");
2422
+ const borrowIncentivePoolsQueryData = await queryBorrowIncentivePools(
2423
+ query.address
2424
+ );
2425
+ for (const pool of borrowIncentivePoolsQueryData?.incentive_pools ?? []) {
2426
+ const borrowIncentivePoolPoints = {};
2427
+ const parsedBorrowIncentivePoolData = parseOriginBorrowIncentivePoolData(pool);
2428
+ const poolCoinType = normalizeStructTag3(pool.pool_type.name);
2429
+ const poolCoinName = query.utils.parseCoinNameFromType(
2430
+ poolCoinType
2431
+ );
2432
+ const poolCoinPrice = coinPrices?.[poolCoinName] ?? 0;
2433
+ const poolCoinDecimal = query.utils.getCoinDecimal(poolCoinName);
2434
+ if (!borrowIncentiveCoinNames.includes(poolCoinName)) {
2435
+ continue;
2436
+ }
2437
+ for (const [coinName, poolPoint] of Object.entries(
2438
+ parsedBorrowIncentivePoolData.poolPoints
2439
+ )) {
2440
+ const rewardCoinType = normalizeStructTag3(poolPoint.pointType);
2441
+ const rewardCoinName = query.utils.parseCoinNameFromType(
2442
+ rewardCoinType
2443
+ );
2444
+ const rewardCoinPrice = coinPrices?.[rewardCoinName] ?? 0;
2445
+ const rewardCoinDecimal = query.utils.getCoinDecimal(rewardCoinName);
2446
+ const symbol = query.utils.parseSymbol(rewardCoinName);
2447
+ const coinDecimal = query.utils.getCoinDecimal(rewardCoinName);
2448
+ const calculatedPoolPoint = calculateBorrowIncentivePoolPointData(
2449
+ // parsedBorrowIncentivePoolData,
2450
+ poolPoint,
2451
+ rewardCoinPrice,
2452
+ rewardCoinDecimal,
2453
+ poolCoinPrice,
2454
+ poolCoinDecimal
2455
+ );
2456
+ borrowIncentivePoolPoints[coinName] = {
2457
+ symbol,
2458
+ coinName: rewardCoinName,
2459
+ coinType: rewardCoinType,
2460
+ coinDecimal,
2461
+ coinPrice: rewardCoinPrice,
2462
+ points: poolPoint.points,
2463
+ distributedPoint: poolPoint.distributedPoint,
2464
+ weightedAmount: poolPoint.weightedAmount,
2465
+ ...calculatedPoolPoint
2466
+ };
2467
+ }
2468
+ const stakedAmount = BigNumber2(parsedBorrowIncentivePoolData.staked);
2469
+ const stakedCoin = stakedAmount.shiftedBy(-1 * poolCoinDecimal);
2470
+ const stakedValue = stakedCoin.multipliedBy(poolCoinPrice);
2471
+ borrowIncentivePools[poolCoinName] = {
2472
+ coinName: poolCoinName,
2473
+ symbol: query.utils.parseSymbol(poolCoinName),
2474
+ coinType: poolCoinType,
2475
+ coinDecimal: poolCoinDecimal,
2476
+ coinPrice: poolCoinPrice,
2477
+ stakedAmount: stakedAmount.toNumber(),
2478
+ stakedCoin: stakedCoin.toNumber(),
2479
+ stakedValue: stakedValue.toNumber(),
2480
+ points: borrowIncentivePoolPoints
2481
+ };
2482
+ }
2483
+ return borrowIncentivePools;
2484
+ };
2485
+ var queryBorrowIncentiveAccounts = async ({
2486
+ utils
2487
+ }, obligationId, borrowIncentiveCoinNames = [
2488
+ ...SUPPORT_BORROW_INCENTIVE_POOLS
2489
+ ]) => {
2490
+ const queryPkgId = utils.address.get("borrowIncentive.query");
2491
+ const incentiveAccountsId = utils.address.get(
2492
+ "borrowIncentive.incentiveAccounts"
2493
+ );
2494
+ const queryTarget = `${queryPkgId}::incentive_account_query::incentive_account_data`;
2495
+ const args = [incentiveAccountsId, obligationId];
2496
+ const queryResult = await utils.cache.queryInspectTxn({ queryTarget, args });
2497
+ const borrowIncentiveAccountsQueryData = queryResult?.events[0]?.parsedJson;
2498
+ const borrowIncentiveAccounts = Object.values(
2499
+ borrowIncentiveAccountsQueryData?.pool_records ?? []
2500
+ ).reduce((accounts, accountData) => {
2501
+ const parsedBorrowIncentiveAccount = parseOriginBorrowIncentiveAccountData(accountData);
2502
+ const poolType = parsedBorrowIncentiveAccount.poolType;
2503
+ const coinName = utils.parseCoinNameFromType(poolType);
2504
+ if (borrowIncentiveCoinNames && borrowIncentiveCoinNames.includes(coinName)) {
2505
+ accounts[coinName] = parsedBorrowIncentiveAccount;
2506
+ }
2507
+ return accounts;
2508
+ }, {});
2509
+ return borrowIncentiveAccounts;
2510
+ };
2511
+ var getBindedObligationId = async ({
2512
+ address
2513
+ }, veScaKeyId) => {
2514
+ const borrowIncentiveObjectId = address.get("borrowIncentive.object");
2515
+ const incentivePoolsId = address.get("borrowIncentive.incentivePools");
2516
+ const veScaObjId = address.get("vesca.object");
2517
+ const incentivePoolsResponse = await address.cache.queryGetObject(
2518
+ incentivePoolsId,
2519
+ {
2520
+ showContent: true
2521
+ }
2522
+ );
2523
+ if (incentivePoolsResponse?.data?.content?.dataType !== "moveObject")
2524
+ return null;
2525
+ const incentivePoolFields = incentivePoolsResponse.data.content.fields;
2526
+ const veScaBindTableId = incentivePoolFields.ve_sca_bind.fields.id.id;
2527
+ const keyType = `${borrowIncentiveObjectId}::typed_id::TypedID<${veScaObjId}::ve_sca::VeScaKey>`;
2528
+ const veScaBindTableResponse = await address.cache.queryGetDynamicFieldObject(
2529
+ {
2530
+ parentId: veScaBindTableId,
2531
+ name: {
2532
+ type: keyType,
2533
+ value: veScaKeyId
2534
+ }
2535
+ }
2536
+ );
2537
+ if (veScaBindTableResponse?.data?.content?.dataType !== "moveObject")
2538
+ return null;
2539
+ const veScaBindTableFields = veScaBindTableResponse.data.content.fields;
2540
+ const obligationId = veScaBindTableFields.value.fields.id;
2541
+ return obligationId;
2542
+ };
2543
+ var getBindedVeScaKey = async ({
2544
+ address
2545
+ }, obligationId) => {
2546
+ const borrowIncentiveObjectId = address.get("borrowIncentive.object");
2547
+ const incentiveAccountsId = address.get("borrowIncentive.incentiveAccounts");
2548
+ const corePkg = address.get("core.object");
2549
+ const incentiveAccountsObject = await address.cache.queryGetObject(
2550
+ incentiveAccountsId,
2551
+ {
2552
+ showContent: true
2553
+ }
2554
+ );
2555
+ if (incentiveAccountsObject?.data?.content?.dataType !== "moveObject")
2556
+ return null;
2557
+ const incentiveAccountsTableId = incentiveAccountsObject.data.content.fields.accounts.fields.id.id;
2558
+ const bindedIncentiveAcc = await address.cache.queryGetDynamicFieldObject({
2559
+ parentId: incentiveAccountsTableId,
2560
+ name: {
2561
+ type: `${borrowIncentiveObjectId}::typed_id::TypedID<${corePkg}::obligation::Obligation>`,
2562
+ value: obligationId
2563
+ }
2564
+ });
2565
+ if (bindedIncentiveAcc?.data?.content?.dataType !== "moveObject")
2566
+ return null;
2567
+ const bindedIncentiveAccFields = bindedIncentiveAcc.data.content.fields;
2568
+ return bindedIncentiveAccFields.value.fields.binded_ve_sca_key?.fields.id ?? null;
2569
+ };
2570
+
2571
+ // src/queries/coreQuery.ts
2572
+ import { normalizeStructTag as normalizeStructTag4 } from "@mysten/sui/utils";
2573
+ import BigNumber3 from "bignumber.js";
2574
+
2575
+ // src/queries/supplyLimitQuery.ts
2576
+ import { z as zod } from "zod";
2577
+ var supplyLimitZod = zod.object({
2578
+ dataType: zod.string(),
2579
+ type: zod.string(),
2580
+ hasPublicTransfer: zod.boolean(),
2581
+ fields: zod.object({
2582
+ id: zod.object({
2583
+ id: zod.string()
2584
+ }),
2585
+ name: zod.object({
2586
+ type: zod.string()
2587
+ }),
2588
+ value: zod.string()
2589
+ })
2590
+ });
2591
+ var SUPPLY_LIMIT_KEY = "0x6e641f0dca8aedab3101d047e96439178f16301bf0b57fe8745086ff1195eb3e::market_dynamic_keys::SupplyLimitKey";
2592
+ var getSupplyLimit = async (utils, poolName) => {
2593
+ const poolCoinType = utils.parseCoinType(poolName).slice(2);
2594
+ const marketObject = utils.address.get("core.market");
2595
+ if (!marketObject)
2596
+ return null;
2597
+ const object = await utils.cache.queryGetDynamicFieldObject({
2598
+ parentId: marketObject,
2599
+ name: {
2600
+ type: SUPPLY_LIMIT_KEY,
2601
+ value: poolCoinType
2602
+ }
2603
+ });
2604
+ const parsedData = supplyLimitZod.safeParse(object?.data?.content);
2605
+ if (!parsedData.success)
2606
+ return null;
2607
+ return parsedData.data.fields.value;
2608
+ };
2609
+
2610
+ // src/queries/coreQuery.ts
2611
+ var queryMarket = async (query, indexer = false, coinPrices) => {
2612
+ coinPrices = coinPrices ?? await query.utils.getCoinPrices() ?? {};
2613
+ const pools = {};
2614
+ const collaterals = {};
2615
+ if (indexer) {
2616
+ const marketIndexer = await query.indexer.getMarket();
2617
+ const updatePools = (item) => {
2618
+ item.coinPrice = coinPrices[item.coinName] ?? item.coinPrice;
2619
+ item.coinWrappedType = query.utils.getCoinWrappedType(item.coinName);
2620
+ pools[item.coinName] = item;
2621
+ };
2622
+ const updateCollaterals = (item) => {
2623
+ item.coinPrice = coinPrices[item.coinName] ?? item.coinPrice;
2624
+ item.coinWrappedType = query.utils.getCoinWrappedType(item.coinName);
2625
+ collaterals[item.coinName] = item;
2626
+ };
2627
+ Object.values(marketIndexer.pools).forEach(updatePools);
2628
+ Object.values(marketIndexer.collaterals).forEach(updateCollaterals);
2629
+ return {
2630
+ pools,
2631
+ collaterals
2632
+ };
2633
+ }
2634
+ const packageId = query.address.get("core.packages.query.id");
2635
+ const marketId = query.address.get("core.market");
2437
2636
  const queryTarget = `${packageId}::market_query::market_data`;
2438
2637
  const args = [marketId];
2439
2638
  const queryResult = await query.cache.queryInspectTxn({ queryTarget, args });
2440
2639
  const marketData = queryResult?.events[0]?.parsedJson;
2441
2640
  for (const pool of marketData?.pools ?? []) {
2442
- const coinType = normalizeStructTag3(pool.type.name);
2641
+ const coinType = normalizeStructTag4(pool.type.name);
2443
2642
  const poolCoinName = query.utils.parseCoinNameFromType(coinType);
2444
2643
  const coinPrice = coinPrices[poolCoinName] ?? 0;
2445
2644
  if (!SUPPORT_POOLS.includes(poolCoinName)) {
@@ -2471,7 +2670,7 @@ var queryMarket = async (query, indexer = false, coinPrices) => {
2471
2670
  parsedMarketPoolData
2472
2671
  );
2473
2672
  const coinDecimal = query.utils.getCoinDecimal(poolCoinName);
2474
- const maxSupplyCoin = BigNumber2(
2673
+ const maxSupplyCoin = BigNumber3(
2475
2674
  await getSupplyLimit(query.utils, poolCoinName) ?? "0"
2476
2675
  ).shiftedBy(-coinDecimal).toNumber();
2477
2676
  pools[poolCoinName] = {
@@ -2499,7 +2698,7 @@ var queryMarket = async (query, indexer = false, coinPrices) => {
2499
2698
  };
2500
2699
  }
2501
2700
  for (const collateral of marketData?.collaterals ?? []) {
2502
- const coinType = normalizeStructTag3(collateral.type.name);
2701
+ const coinType = normalizeStructTag4(collateral.type.name);
2503
2702
  const collateralCoinName = query.utils.parseCoinNameFromType(coinType);
2504
2703
  const coinPrice = coinPrices[collateralCoinName] ?? 0;
2505
2704
  if (!SUPPORT_COLLATERALS.includes(collateralCoinName)) {
@@ -2707,7 +2906,7 @@ var getMarketPool = async (query, poolCoinName, indexer = false, marketObject, c
2707
2906
  parsedMarketPoolData
2708
2907
  );
2709
2908
  const coinDecimal = query.utils.getCoinDecimal(poolCoinName);
2710
- const maxSupplyCoin = BigNumber2(
2909
+ const maxSupplyCoin = BigNumber3(
2711
2910
  await getSupplyLimit(query.utils, poolCoinName) ?? "0"
2712
2911
  ).shiftedBy(-coinDecimal).toNumber();
2713
2912
  marketPool = {
@@ -2951,7 +3150,7 @@ var getCoinAmount = async (query, assetCoinName, ownerAddress) => {
2951
3150
  owner,
2952
3151
  coinType
2953
3152
  });
2954
- return BigNumber2(amount).toNumber();
3153
+ return BigNumber3(amount).toNumber();
2955
3154
  };
2956
3155
  var getMarketCoinAmounts = async (query, marketCoinNames, ownerAddress) => {
2957
3156
  marketCoinNames = marketCoinNames || [...SUPPORT_POOLS].map(
@@ -2978,7 +3177,7 @@ var getMarketCoinAmount = async (query, marketCoinName, ownerAddress) => {
2978
3177
  owner,
2979
3178
  coinType: marketCoinType
2980
3179
  });
2981
- return BigNumber2(amount).toNumber();
3180
+ return BigNumber3(amount).toNumber();
2982
3181
  };
2983
3182
  var getFlashLoanFees = async (query, assetNames) => {
2984
3183
  const FEE_RATE = 1e4;
@@ -3039,1124 +3238,1182 @@ var getFlashLoanFees = async (query, assetNames) => {
3039
3238
  );
3040
3239
  };
3041
3240
 
3042
- // src/queries/spoolQuery.ts
3043
- import { normalizeStructTag as normalizeStructTag4 } from "@mysten/sui/utils";
3044
- var getSpools = async (query, stakeMarketCoinNames = [...SUPPORT_SPOOLS], indexer = false, marketPools, coinPrices) => {
3045
- const stakeCoinNames = stakeMarketCoinNames.map(
3046
- (stakeMarketCoinName) => query.utils.parseCoinName(stakeMarketCoinName)
3047
- );
3048
- coinPrices = coinPrices ?? await query.utils.getCoinPrices() ?? {};
3049
- marketPools = marketPools ?? await query.getMarketPools(stakeCoinNames, indexer);
3050
- if (!marketPools)
3051
- throw new Error(`Fail to fetch marketPools for ${stakeCoinNames}`);
3052
- const spools = {};
3053
- if (indexer) {
3054
- const spoolsIndexer = await query.indexer.getSpools();
3055
- const updateSpools = (spool) => {
3056
- if (!stakeMarketCoinNames.includes(spool.marketCoinName))
3057
- return;
3058
- const coinName = query.utils.parseCoinName(
3059
- spool.marketCoinName
3060
- );
3061
- const rewardCoinName = query.utils.getSpoolRewardCoinName(
3062
- spool.marketCoinName
3063
- );
3064
- const marketPool = marketPools[coinName];
3065
- spool.coinPrice = coinPrices[coinName] ?? spool.coinPrice;
3066
- spool.marketCoinPrice = coinPrices[coinName] ? (coinPrices[coinName] ?? 0) * (marketPool ? marketPool.conversionRate : 0) : spool.marketCoinPrice;
3067
- spool.rewardCoinPrice = coinPrices[rewardCoinName] ?? spool.rewardCoinPrice;
3068
- spools[spool.marketCoinName] = spool;
3241
+ // src/queries/isolatedAssetQuery.ts
3242
+ import { z as zod2 } from "zod";
3243
+ var isolatedAssetZod = zod2.object({
3244
+ dataType: zod2.string(),
3245
+ type: zod2.string(),
3246
+ hasPublicTransfer: zod2.boolean(),
3247
+ fields: zod2.object({
3248
+ id: zod2.object({
3249
+ id: zod2.string()
3250
+ }),
3251
+ name: zod2.object({
3252
+ type: zod2.string()
3253
+ }),
3254
+ value: zod2.boolean()
3255
+ })
3256
+ });
3257
+ var ISOLATED_ASSET_KEY = "0x6e641f0dca8aedab3101d047e96439178f16301bf0b57fe8745086ff1195eb3e::market_dynamic_keys::IsolatedAssetKey";
3258
+ var getIsolatedAssets = async (address) => {
3259
+ try {
3260
+ const marketObject = address.get("core.market");
3261
+ const isolatedAssets = [];
3262
+ if (!marketObject)
3263
+ return isolatedAssets;
3264
+ let hasNextPage = false;
3265
+ let nextCursor = null;
3266
+ const isIsolatedDynamicField = (dynamicField) => {
3267
+ return dynamicField.name.type === ISOLATED_ASSET_KEY;
3069
3268
  };
3070
- Object.values(spoolsIndexer).forEach(updateSpools);
3071
- return spools;
3072
- }
3073
- for (const stakeMarketCoinName of stakeMarketCoinNames) {
3074
- const stakeCoinName = query.utils.parseCoinName(stakeMarketCoinName);
3075
- const spool = await getSpool(
3076
- query,
3077
- stakeMarketCoinName,
3078
- indexer,
3079
- marketPools[stakeCoinName],
3080
- coinPrices
3081
- );
3082
- if (spool) {
3083
- spools[stakeMarketCoinName] = spool;
3084
- }
3269
+ do {
3270
+ const response = await address.cache.queryGetDynamicFields({
3271
+ parentId: marketObject,
3272
+ cursor: nextCursor,
3273
+ limit: 10
3274
+ });
3275
+ if (!response)
3276
+ break;
3277
+ const isolatedAssetCoinTypes = response.data.filter(isIsolatedDynamicField).map(({ name }) => `0x${name.value.type.name}`);
3278
+ isolatedAssets.push(...isolatedAssetCoinTypes);
3279
+ if (response && response.hasNextPage && response.nextCursor) {
3280
+ hasNextPage = true;
3281
+ nextCursor = response.nextCursor;
3282
+ } else {
3283
+ hasNextPage = false;
3284
+ }
3285
+ } while (hasNextPage);
3286
+ return isolatedAssets;
3287
+ } catch (e) {
3288
+ console.error(e);
3289
+ return [];
3085
3290
  }
3086
- return spools;
3087
3291
  };
3088
- var getSpool = async (query, marketCoinName, indexer = false, marketPool, coinPrices) => {
3089
- const coinName = query.utils.parseCoinName(marketCoinName);
3090
- marketPool = marketPool || await query.getMarketPool(coinName, indexer);
3091
- if (!marketPool) {
3092
- throw new Error(`Fail to fetch marketPool for ${coinName}`);
3093
- }
3094
- const poolId = query.address.get(`spool.pools.${marketCoinName}.id`);
3095
- const rewardPoolId = query.address.get(
3096
- `spool.pools.${marketCoinName}.rewardPoolId`
3097
- );
3098
- let spool = void 0;
3099
- coinPrices = coinPrices || await query.utils.getCoinPrices([coinName]);
3100
- if (indexer) {
3101
- const spoolIndexer = await query.indexer.getSpool(marketCoinName);
3102
- const coinName2 = query.utils.parseCoinName(marketCoinName);
3103
- const rewardCoinName2 = query.utils.getSpoolRewardCoinName(marketCoinName);
3104
- spoolIndexer.coinPrice = coinPrices?.[coinName2] || spoolIndexer.coinPrice;
3105
- spoolIndexer.marketCoinPrice = (coinPrices?.[coinName2] ?? 0) * (marketPool ? marketPool.conversionRate : 0) || spoolIndexer.marketCoinPrice;
3106
- spoolIndexer.rewardCoinPrice = coinPrices?.[rewardCoinName2] || spoolIndexer.rewardCoinPrice;
3107
- return spoolIndexer;
3108
- }
3109
- const spoolObjectResponse = await query.cache.queryGetObjects(
3110
- [poolId, rewardPoolId],
3111
- {
3112
- showContent: true
3292
+ var isIsolatedAsset = async (utils, coinName) => {
3293
+ try {
3294
+ const marketObject = utils.address.get("core.market");
3295
+ const cachedData = utils.address.cache.queryClient.getQueryData([
3296
+ "getDynamicFields",
3297
+ marketObject
3298
+ ]);
3299
+ if (cachedData) {
3300
+ const coinType2 = utils.parseCoinType(coinName);
3301
+ return cachedData.includes(coinType2);
3113
3302
  }
3114
- );
3115
- if (!(spoolObjectResponse[0] && spoolObjectResponse[1])) {
3116
- throw new Error("Fail to fetch spoolObjectResponse!");
3117
- }
3118
- const rewardCoinName = query.utils.getSpoolRewardCoinName(marketCoinName);
3119
- coinPrices = coinPrices || await query.utils.getCoinPrices([coinName, rewardCoinName]);
3120
- const spoolObject = spoolObjectResponse[0];
3121
- const rewardPoolObject = spoolObjectResponse[1];
3122
- if (spoolObject.content && "fields" in spoolObject.content) {
3123
- const spoolFields = spoolObject.content.fields;
3124
- const parsedSpoolData = parseOriginSpoolData({
3125
- stakeType: spoolFields.stake_type,
3126
- maxDistributedPoint: spoolFields.max_distributed_point,
3127
- distributedPoint: spoolFields.distributed_point,
3128
- distributedPointPerPeriod: spoolFields.distributed_point_per_period,
3129
- pointDistributionTime: spoolFields.point_distribution_time,
3130
- maxStake: spoolFields.max_stakes,
3131
- stakes: spoolFields.stakes,
3132
- index: spoolFields.index,
3133
- createdAt: spoolFields.created_at,
3134
- lastUpdate: spoolFields.last_update
3303
+ const coinType = utils.parseCoinType(coinName).slice(2);
3304
+ const object = await utils.cache.queryGetDynamicFieldObject({
3305
+ parentId: marketObject,
3306
+ name: {
3307
+ type: ISOLATED_ASSET_KEY,
3308
+ value: coinType
3309
+ }
3135
3310
  });
3136
- const marketCoinPrice = (coinPrices?.[coinName] ?? 0) * marketPool.conversionRate;
3137
- const marketCoinDecimal = query.utils.getCoinDecimal(marketCoinName);
3138
- const calculatedSpoolData = calculateSpoolData(
3139
- parsedSpoolData,
3140
- marketCoinPrice,
3141
- marketCoinDecimal
3142
- );
3143
- if (rewardPoolObject.content && "fields" in rewardPoolObject.content) {
3144
- const rewardPoolFields = rewardPoolObject.content.fields;
3145
- const parsedSpoolRewardPoolData = parseOriginSpoolRewardPoolData({
3146
- claimed_rewards: rewardPoolFields.claimed_rewards,
3147
- exchange_rate_numerator: rewardPoolFields.exchange_rate_numerator,
3148
- exchange_rate_denominator: rewardPoolFields.exchange_rate_denominator,
3149
- rewards: rewardPoolFields.rewards,
3150
- spool_id: rewardPoolFields.spool_id
3151
- });
3152
- const rewardCoinPrice = coinPrices?.[rewardCoinName] ?? 0;
3153
- const rewardCoinDecimal = query.utils.getCoinDecimal(rewardCoinName);
3154
- const calculatedRewardPoolData = calculateSpoolRewardPoolData(
3155
- parsedSpoolData,
3156
- parsedSpoolRewardPoolData,
3157
- calculatedSpoolData,
3158
- rewardCoinPrice,
3159
- rewardCoinDecimal
3160
- );
3161
- spool = {
3162
- marketCoinName,
3163
- symbol: query.utils.parseSymbol(marketCoinName),
3164
- coinType: query.utils.parseCoinType(coinName),
3165
- marketCoinType: query.utils.parseMarketCoinType(coinName),
3166
- rewardCoinType: isMarketCoin(rewardCoinName) ? query.utils.parseMarketCoinType(rewardCoinName) : query.utils.parseCoinType(rewardCoinName),
3167
- sCoinType: marketPool.sCoinType,
3168
- coinDecimal: query.utils.getCoinDecimal(coinName),
3169
- rewardCoinDecimal: query.utils.getCoinDecimal(rewardCoinName),
3170
- coinPrice: coinPrices?.[coinName] ?? 0,
3171
- marketCoinPrice,
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
- };
3181
- }
3311
+ const parsedData = isolatedAssetZod.safeParse(object?.data?.content);
3312
+ if (!parsedData.success)
3313
+ return false;
3314
+ return parsedData.data.fields.value;
3315
+ } catch (e) {
3316
+ console.error(e);
3317
+ return false;
3182
3318
  }
3183
- return spool;
3184
3319
  };
3185
- var getStakeAccounts = async ({
3186
- utils
3187
- }, ownerAddress) => {
3188
- const owner = ownerAddress || utils.suiKit.currentAddress();
3189
- const spoolObjectId = utils.address.get("spool.object");
3190
- const stakeAccountType = `${spoolObjectId}::spool_account::SpoolAccount`;
3191
- const stakeObjectsResponse = [];
3192
- let hasNextPage = false;
3193
- let nextCursor = null;
3194
- do {
3195
- const paginatedStakeObjectsResponse = await utils.cache.queryGetOwnedObjects({
3196
- owner,
3197
- filter: { StructType: stakeAccountType },
3198
- options: {
3199
- showContent: true,
3200
- showType: true
3201
- },
3202
- cursor: nextCursor,
3203
- limit: 10
3204
- });
3205
- if (!paginatedStakeObjectsResponse)
3206
- continue;
3207
- stakeObjectsResponse.push(...paginatedStakeObjectsResponse.data);
3208
- if (paginatedStakeObjectsResponse.hasNextPage && paginatedStakeObjectsResponse.nextCursor) {
3209
- hasNextPage = true;
3210
- nextCursor = paginatedStakeObjectsResponse.nextCursor;
3211
- } else {
3212
- hasNextPage = false;
3320
+
3321
+ // src/queries/loyaltyProgramQuery.ts
3322
+ import BigNumber4 from "bignumber.js";
3323
+ import { z as zod3 } from "zod";
3324
+ var rewardPoolFieldsZod = zod3.object({
3325
+ balance: zod3.string(),
3326
+ enable_claim: zod3.boolean()
3327
+ }).transform((value) => ({
3328
+ totalPoolReward: BigNumber4(value.balance).shiftedBy(-9).toNumber(),
3329
+ isClaimEnabled: value.enable_claim
3330
+ }));
3331
+ var userRewardFieldsZod = zod3.object({
3332
+ value: zod3.string()
3333
+ }).transform((value) => BigNumber4(value.value).shiftedBy(-9).toNumber());
3334
+ var getLoyaltyProgramInformations = async (query, veScaKey) => {
3335
+ const rewardPool = query.address.get("loyaltyProgram.rewardPool");
3336
+ const rewardPoolObject = await query.cache.queryGetObject(rewardPool, {
3337
+ showContent: true
3338
+ });
3339
+ if (rewardPoolObject?.data?.content?.dataType !== "moveObject")
3340
+ return null;
3341
+ const rewardPoolFields = rewardPoolObject.data.content.fields;
3342
+ const { isClaimEnabled, totalPoolReward } = rewardPoolFieldsZod.parse(
3343
+ rewardPoolFields
3344
+ );
3345
+ const result = {
3346
+ pendingReward: 0,
3347
+ totalPoolReward,
3348
+ isClaimEnabled
3349
+ };
3350
+ veScaKey = veScaKey ?? (await query.getVeScas())[0]?.keyObject;
3351
+ if (!veScaKey)
3352
+ return result;
3353
+ const userRewardTableId = query.address.get(
3354
+ "loyaltyProgram.userRewardTableId"
3355
+ );
3356
+ const userRewardObject = await query.cache.queryGetDynamicFieldObject({
3357
+ parentId: userRewardTableId,
3358
+ name: {
3359
+ type: "0x2::object::ID",
3360
+ value: typeof veScaKey === "string" ? veScaKey : veScaKey.objectId
3213
3361
  }
3214
- } while (hasNextPage);
3215
- const stakeAccounts = SUPPORT_SPOOLS.reduce(
3216
- (acc, stakeName) => {
3217
- acc[stakeName] = [];
3218
- return acc;
3219
- },
3220
- {}
3362
+ });
3363
+ if (userRewardObject?.data?.content?.dataType !== "moveObject")
3364
+ return result;
3365
+ const userRewardFields = userRewardObject.data.content.fields;
3366
+ result.pendingReward = userRewardFieldsZod.parse(
3367
+ userRewardFields
3221
3368
  );
3222
- const stakeMarketCoinTypes = Object.keys(stakeAccounts).reduce(
3223
- (types, stakeMarketCoinName) => {
3224
- const stakeCoinName = utils.parseCoinName(stakeMarketCoinName);
3225
- const marketCoinType = utils.parseMarketCoinType(stakeCoinName);
3226
- types[stakeMarketCoinName] = `${spoolObjectId}::spool_account::SpoolAccount<${marketCoinType}>`;
3227
- return types;
3228
- },
3229
- {}
3369
+ return result;
3370
+ };
3371
+
3372
+ // src/queries/portfolioQuery.ts
3373
+ import BigNumber5 from "bignumber.js";
3374
+ var getLendings = async (query, poolCoinNames = [...SUPPORT_POOLS], ownerAddress, indexer = false) => {
3375
+ const marketCoinNames = poolCoinNames.map(
3376
+ (poolCoinName) => query.utils.parseMarketCoinName(poolCoinName)
3230
3377
  );
3231
- const reversedStakeMarketCoinTypes = Object.entries(stakeMarketCoinTypes).reduce(
3232
- (reversedTypes, [key, value]) => {
3233
- reversedTypes[value] = key;
3234
- return reversedTypes;
3235
- },
3236
- {}
3378
+ const stakeMarketCoinNames = marketCoinNames.filter(
3379
+ (marketCoinName) => SUPPORT_SPOOLS.includes(marketCoinName)
3237
3380
  );
3238
- for (const stakeObject of stakeObjectsResponse.map((ref) => ref.data)) {
3239
- const id = stakeObject?.objectId;
3240
- const type = stakeObject?.type;
3241
- if (id && stakeObject?.content && "fields" in stakeObject.content) {
3242
- const fields = stakeObject.content.fields;
3243
- const stakePoolId = String(fields.spool_id);
3244
- const stakeType = String(fields.stake_type.fields.name);
3245
- const staked = Number(fields.stakes);
3246
- const index = Number(fields.index);
3247
- const points = Number(fields.points);
3248
- const totalPoints = Number(fields.total_points);
3249
- const stakeMarketCoinTypeMap = {
3250
- sweth: stakeAccounts.sweth,
3251
- ssui: stakeAccounts.ssui,
3252
- swusdc: stakeAccounts.swusdc,
3253
- swusdt: stakeAccounts.swusdt,
3254
- scetus: stakeAccounts.scetus,
3255
- safsui: stakeAccounts.safsui,
3256
- shasui: stakeAccounts.shasui,
3257
- svsui: stakeAccounts.svsui,
3258
- susdc: stakeAccounts.susdc
3259
- };
3260
- const normalizedType = normalizeStructTag4(type);
3261
- const stakeAccountArray = stakeMarketCoinTypeMap[reversedStakeMarketCoinTypes[normalizedType]];
3262
- if (stakeAccountArray) {
3263
- stakeAccountArray.push({
3264
- id,
3265
- type: normalizedType,
3266
- stakePoolId,
3267
- stakeType: normalizeStructTag4(stakeType),
3268
- staked,
3269
- index,
3270
- points,
3271
- totalPoints
3272
- });
3273
- }
3274
- }
3275
- }
3276
- return stakeAccounts;
3277
- };
3278
- var getStakePool = async ({
3279
- utils
3280
- }, marketCoinName) => {
3281
- const poolId = utils.address.get(`spool.pools.${marketCoinName}.id`);
3282
- let stakePool = void 0;
3283
- const stakePoolObjectResponse = await utils.cache.queryGetObject(poolId, {
3284
- showContent: true,
3285
- showType: true
3381
+ const coinPrices = await query.utils.getCoinPrices(poolCoinNames);
3382
+ const marketPools = await query.getMarketPools(poolCoinNames, indexer, {
3383
+ coinPrices
3286
3384
  });
3287
- if (stakePoolObjectResponse?.data) {
3288
- const stakePoolObject = stakePoolObjectResponse.data;
3289
- const id = stakePoolObject.objectId;
3290
- const type = stakePoolObject.type;
3291
- if (stakePoolObject.content && "fields" in stakePoolObject.content) {
3292
- const fields = stakePoolObject.content.fields;
3293
- const maxPoint = Number(fields.max_distributed_point);
3294
- const distributedPoint = Number(fields.distributed_point);
3295
- const pointPerPeriod = Number(fields.distributed_point_per_period);
3296
- const period = Number(fields.point_distribution_time);
3297
- const maxStake = Number(fields.max_stakes);
3298
- const stakeType = String(fields.stake_type.fields.name);
3299
- const totalStaked = Number(fields.stakes);
3300
- const index = Number(fields.index);
3301
- const createdAt = Number(fields.created_at);
3302
- const lastUpdate = Number(fields.last_update);
3303
- stakePool = {
3304
- id,
3305
- type: normalizeStructTag4(type),
3306
- maxPoint,
3307
- distributedPoint,
3308
- pointPerPeriod,
3309
- period,
3310
- maxStake,
3311
- stakeType: normalizeStructTag4(stakeType),
3312
- totalStaked,
3313
- index,
3314
- createdAt,
3315
- lastUpdate
3316
- };
3317
- }
3318
- }
3319
- return stakePool;
3320
- };
3321
- var getStakeRewardPool = async ({
3322
- utils
3323
- }, marketCoinName) => {
3324
- const poolId = utils.address.get(
3325
- `spool.pools.${marketCoinName}.rewardPoolId`
3385
+ const spools = await query.getSpools(stakeMarketCoinNames, indexer, {
3386
+ marketPools,
3387
+ coinPrices
3388
+ });
3389
+ const [coinAmounts, marketCoinAmounts, allStakeAccounts] = await Promise.all([
3390
+ query.getCoinAmounts(poolCoinNames, ownerAddress),
3391
+ query.getMarketCoinAmounts(marketCoinNames, ownerAddress),
3392
+ query.getAllStakeAccounts(ownerAddress)
3393
+ ]);
3394
+ const lendings = {};
3395
+ await Promise.allSettled(
3396
+ poolCoinNames.map(async (poolCoinName) => {
3397
+ const stakeMarketCoinName = stakeMarketCoinNames.find(
3398
+ (marketCoinName2) => marketCoinName2 === query.utils.parseMarketCoinName(poolCoinName)
3399
+ );
3400
+ const marketCoinName = query.utils.parseMarketCoinName(poolCoinName);
3401
+ lendings[poolCoinName] = await getLending(
3402
+ query,
3403
+ poolCoinName,
3404
+ ownerAddress,
3405
+ indexer,
3406
+ marketPools?.[poolCoinName],
3407
+ stakeMarketCoinName ? spools[stakeMarketCoinName] : void 0,
3408
+ stakeMarketCoinName ? allStakeAccounts[stakeMarketCoinName] : [],
3409
+ coinAmounts?.[poolCoinName],
3410
+ marketCoinAmounts?.[marketCoinName],
3411
+ coinPrices?.[poolCoinName] ?? 0
3412
+ );
3413
+ })
3326
3414
  );
3327
- let stakeRewardPool = void 0;
3328
- const stakeRewardPoolObjectResponse = await utils.cache.queryGetObject(
3329
- poolId,
3415
+ return lendings;
3416
+ };
3417
+ var getLending = async (query, poolCoinName, ownerAddress, indexer = false, marketPool, spool, stakeAccounts, coinAmount, marketCoinAmount, coinPrice, sCoinAmount) => {
3418
+ const marketCoinName = query.utils.parseMarketCoinName(poolCoinName);
3419
+ coinPrice = coinPrice ?? (await query.utils.getCoinPrices([poolCoinName]))?.[poolCoinName] ?? 0;
3420
+ marketPool = marketPool ?? await query.getMarketPool(poolCoinName, indexer, {
3421
+ coinPrice
3422
+ });
3423
+ if (!marketPool)
3424
+ throw new Error(`Failed to fetch marketPool for ${poolCoinName}`);
3425
+ spool = spool ?? SUPPORT_SPOOLS.includes(marketCoinName) ? await query.getSpool(
3426
+ marketCoinName,
3427
+ indexer,
3330
3428
  {
3331
- showContent: true,
3332
- showType: true
3429
+ marketPool,
3430
+ coinPrices: {
3431
+ [poolCoinName]: coinPrice
3432
+ }
3333
3433
  }
3334
- );
3335
- if (stakeRewardPoolObjectResponse?.data) {
3336
- const stakeRewardPoolObject = stakeRewardPoolObjectResponse.data;
3337
- const id = stakeRewardPoolObject.objectId;
3338
- const type = stakeRewardPoolObject.type;
3339
- if (stakeRewardPoolObject.content && "fields" in stakeRewardPoolObject.content) {
3340
- const rewardPoolFields = stakeRewardPoolObject.content.fields;
3341
- const stakePoolId = String(rewardPoolFields.spool_id);
3342
- const ratioNumerator = Number(rewardPoolFields.exchange_rate_numerator);
3343
- const ratioDenominator = Number(
3344
- rewardPoolFields.exchange_rate_denominator
3434
+ ) : void 0;
3435
+ stakeAccounts = stakeAccounts || SUPPORT_SPOOLS.includes(marketCoinName) ? await query.getStakeAccounts(
3436
+ marketCoinName,
3437
+ ownerAddress
3438
+ ) : [];
3439
+ coinAmount = coinAmount || await query.getCoinAmount(poolCoinName, ownerAddress);
3440
+ marketCoinAmount = marketCoinAmount || await query.getMarketCoinAmount(marketCoinName, ownerAddress);
3441
+ sCoinAmount = sCoinAmount || await query.getSCoinAmount(marketCoinName, ownerAddress);
3442
+ const coinDecimal = query.utils.getCoinDecimal(poolCoinName);
3443
+ let stakedMarketAmount = BigNumber5(0);
3444
+ let stakedMarketCoin = BigNumber5(0);
3445
+ let stakedAmount = BigNumber5(0);
3446
+ let stakedCoin = BigNumber5(0);
3447
+ let stakedValue = BigNumber5(0);
3448
+ let availableUnstakeAmount = BigNumber5(0);
3449
+ let availableUnstakeCoin = BigNumber5(0);
3450
+ let availableClaimAmount = BigNumber5(0);
3451
+ let availableClaimCoin = BigNumber5(0);
3452
+ if (spool) {
3453
+ for (const stakeAccount of stakeAccounts) {
3454
+ const accountStakedMarketCoinAmount = BigNumber5(stakeAccount.staked);
3455
+ const accountStakedMarketCoin = accountStakedMarketCoinAmount.shiftedBy(
3456
+ -1 * spool.coinDecimal
3457
+ );
3458
+ const accountStakedAmount = accountStakedMarketCoinAmount.multipliedBy(
3459
+ marketPool?.conversionRate ?? 1
3460
+ );
3461
+ const accountStakedCoin = accountStakedAmount.shiftedBy(
3462
+ -1 * spool.coinDecimal
3463
+ );
3464
+ const accountStakedValue = accountStakedCoin.multipliedBy(
3465
+ spool.coinPrice
3466
+ );
3467
+ stakedMarketAmount = stakedMarketAmount.plus(
3468
+ accountStakedMarketCoinAmount
3469
+ );
3470
+ stakedMarketCoin = stakedMarketCoin.plus(accountStakedMarketCoin);
3471
+ stakedAmount = stakedAmount.plus(accountStakedAmount);
3472
+ stakedCoin = stakedCoin.plus(accountStakedCoin);
3473
+ stakedValue = stakedValue.plus(accountStakedValue);
3474
+ availableUnstakeAmount = availableUnstakeAmount.plus(
3475
+ accountStakedMarketCoinAmount
3476
+ );
3477
+ availableUnstakeCoin = availableUnstakeAmount.shiftedBy(
3478
+ -1 * spool.coinDecimal
3479
+ );
3480
+ const baseIndexRate = 1e9;
3481
+ const increasedPointRate = spool.currentPointIndex ? BigNumber5(spool.currentPointIndex - stakeAccount.index).dividedBy(
3482
+ baseIndexRate
3483
+ ) : 1;
3484
+ availableClaimAmount = availableClaimAmount.plus(
3485
+ accountStakedMarketCoinAmount.multipliedBy(increasedPointRate).plus(stakeAccount.points).multipliedBy(spool.exchangeRateNumerator).dividedBy(spool.exchangeRateDenominator)
3486
+ );
3487
+ availableClaimCoin = availableClaimAmount.shiftedBy(
3488
+ -1 * spool.rewardCoinDecimal
3345
3489
  );
3346
- const rewards = Number(rewardPoolFields.rewards);
3347
- const claimedRewards = Number(rewardPoolFields.claimed_rewards);
3348
- stakeRewardPool = {
3349
- id,
3350
- type: normalizeStructTag4(type),
3351
- stakePoolId,
3352
- ratioNumerator,
3353
- ratioDenominator,
3354
- rewards,
3355
- claimedRewards
3356
- };
3357
3490
  }
3358
3491
  }
3359
- return stakeRewardPool;
3360
- };
3361
-
3362
- // src/queries/borrowIncentiveQuery.ts
3363
- import { normalizeStructTag as normalizeStructTag5 } from "@mysten/sui/utils";
3364
- import BigNumber3 from "bignumber.js";
3365
- var queryBorrowIncentivePools = async (address) => {
3366
- const queryPkgId = address.get("borrowIncentive.query");
3367
- const incentivePoolsId = address.get("borrowIncentive.incentivePools");
3368
- const queryTarget = `${queryPkgId}::incentive_pools_query::incentive_pools_data`;
3369
- const args = [incentivePoolsId];
3370
- const queryResult = await address.cache.queryInspectTxn({
3371
- queryTarget,
3372
- args
3373
- });
3374
- const borrowIncentivePoolsQueryData = queryResult?.events[0].parsedJson;
3375
- return borrowIncentivePoolsQueryData;
3376
- };
3377
- var getBorrowIncentivePools = async (query, borrowIncentiveCoinNames = [
3378
- ...SUPPORT_BORROW_INCENTIVE_POOLS
3379
- ], indexer = false, coinPrices) => {
3380
- const borrowIncentivePools = {};
3381
- coinPrices = coinPrices ?? await query.utils.getCoinPrices() ?? {};
3382
- if (indexer) {
3383
- const borrowIncentivePoolsIndexer = await query.indexer.getBorrowIncentivePools();
3384
- const updateBorrowIncentivePool = (pool) => {
3385
- if (!borrowIncentiveCoinNames.includes(pool.coinName))
3386
- return;
3387
- pool.coinPrice = coinPrices[pool.coinName] ?? pool.coinPrice;
3388
- borrowIncentivePools[pool.coinName] = pool;
3389
- };
3390
- Object.values(borrowIncentivePoolsIndexer).forEach(
3391
- updateBorrowIncentivePool
3392
- );
3393
- return borrowIncentivePools;
3394
- }
3395
- const borrowIncentivePoolsQueryData = await queryBorrowIncentivePools(
3396
- query.address
3492
+ const suppliedAmount = BigNumber5(marketCoinAmount).plus(BigNumber5(sCoinAmount)).multipliedBy(marketPool?.conversionRate ?? 1);
3493
+ const suppliedCoin = suppliedAmount.shiftedBy(-1 * coinDecimal);
3494
+ const suppliedValue = suppliedCoin.multipliedBy(coinPrice ?? 0);
3495
+ const marketCoinPrice = BigNumber5(coinPrice ?? 0).multipliedBy(
3496
+ marketPool?.conversionRate ?? 1
3397
3497
  );
3398
- for (const pool of borrowIncentivePoolsQueryData?.incentive_pools ?? []) {
3399
- const borrowIncentivePoolPoints = {};
3400
- const parsedBorrowIncentivePoolData = parseOriginBorrowIncentivePoolData(pool);
3401
- const poolCoinType = normalizeStructTag5(pool.pool_type.name);
3402
- const poolCoinName = query.utils.parseCoinNameFromType(
3403
- poolCoinType
3404
- );
3405
- const poolCoinPrice = coinPrices?.[poolCoinName] ?? 0;
3406
- const poolCoinDecimal = query.utils.getCoinDecimal(poolCoinName);
3407
- if (!borrowIncentiveCoinNames.includes(poolCoinName)) {
3408
- continue;
3409
- }
3410
- for (const [coinName, poolPoint] of Object.entries(
3411
- parsedBorrowIncentivePoolData.poolPoints
3412
- )) {
3413
- const rewardCoinType = normalizeStructTag5(poolPoint.pointType);
3414
- const rewardCoinName = query.utils.parseCoinNameFromType(
3415
- rewardCoinType
3416
- );
3417
- const rewardCoinPrice = coinPrices?.[rewardCoinName] ?? 0;
3418
- const rewardCoinDecimal = query.utils.getCoinDecimal(rewardCoinName);
3419
- const symbol = query.utils.parseSymbol(rewardCoinName);
3420
- const coinDecimal = query.utils.getCoinDecimal(rewardCoinName);
3421
- const calculatedPoolPoint = calculateBorrowIncentivePoolPointData(
3422
- // parsedBorrowIncentivePoolData,
3423
- poolPoint,
3424
- rewardCoinPrice,
3425
- rewardCoinDecimal,
3426
- poolCoinPrice,
3427
- poolCoinDecimal
3428
- );
3429
- borrowIncentivePoolPoints[coinName] = {
3430
- symbol,
3431
- coinName: rewardCoinName,
3432
- coinType: rewardCoinType,
3433
- coinDecimal,
3434
- coinPrice: rewardCoinPrice,
3435
- points: poolPoint.points,
3436
- distributedPoint: poolPoint.distributedPoint,
3437
- weightedAmount: poolPoint.weightedAmount,
3438
- ...calculatedPoolPoint
3439
- };
3440
- }
3441
- const stakedAmount = BigNumber3(parsedBorrowIncentivePoolData.staked);
3442
- const stakedCoin = stakedAmount.shiftedBy(-1 * poolCoinDecimal);
3443
- const stakedValue = stakedCoin.multipliedBy(poolCoinPrice);
3444
- borrowIncentivePools[poolCoinName] = {
3445
- coinName: poolCoinName,
3446
- symbol: query.utils.parseSymbol(poolCoinName),
3447
- coinType: poolCoinType,
3448
- coinDecimal: poolCoinDecimal,
3449
- coinPrice: poolCoinPrice,
3450
- stakedAmount: stakedAmount.toNumber(),
3451
- stakedCoin: stakedCoin.toNumber(),
3452
- stakedValue: stakedValue.toNumber(),
3453
- points: borrowIncentivePoolPoints
3454
- };
3455
- }
3456
- return borrowIncentivePools;
3457
- };
3458
- var queryBorrowIncentiveAccounts = async ({
3459
- utils
3460
- }, obligationId, borrowIncentiveCoinNames = [
3461
- ...SUPPORT_BORROW_INCENTIVE_POOLS
3462
- ]) => {
3463
- const queryPkgId = utils.address.get("borrowIncentive.query");
3464
- const incentiveAccountsId = utils.address.get(
3465
- "borrowIncentive.incentiveAccounts"
3466
- );
3467
- const queryTarget = `${queryPkgId}::incentive_account_query::incentive_account_data`;
3468
- const args = [incentiveAccountsId, obligationId];
3469
- const queryResult = await utils.cache.queryInspectTxn({ queryTarget, args });
3470
- const borrowIncentiveAccountsQueryData = queryResult?.events[0]?.parsedJson;
3471
- const borrowIncentiveAccounts = Object.values(
3472
- borrowIncentiveAccountsQueryData?.pool_records ?? []
3473
- ).reduce((accounts, accountData) => {
3474
- const parsedBorrowIncentiveAccount = parseOriginBorrowIncentiveAccountData(accountData);
3475
- const poolType = parsedBorrowIncentiveAccount.poolType;
3476
- const coinName = utils.parseCoinNameFromType(poolType);
3477
- if (borrowIncentiveCoinNames && borrowIncentiveCoinNames.includes(coinName)) {
3478
- accounts[coinName] = parsedBorrowIncentiveAccount;
3479
- }
3480
- return accounts;
3481
- }, {});
3482
- return borrowIncentiveAccounts;
3483
- };
3484
- var getBindedObligationId = async ({
3485
- address
3486
- }, veScaKeyId) => {
3487
- const borrowIncentiveObjectId = address.get("borrowIncentive.object");
3488
- const incentivePoolsId = address.get("borrowIncentive.incentivePools");
3489
- const veScaObjId = address.get("vesca.object");
3490
- const incentivePoolsResponse = await address.cache.queryGetObject(
3491
- incentivePoolsId,
3492
- {
3493
- showContent: true
3494
- }
3498
+ const unstakedMarketAmount = BigNumber5(marketCoinAmount).plus(
3499
+ BigNumber5(sCoinAmount)
3495
3500
  );
3496
- if (incentivePoolsResponse?.data?.content?.dataType !== "moveObject")
3497
- return null;
3498
- const incentivePoolFields = incentivePoolsResponse.data.content.fields;
3499
- const veScaBindTableId = incentivePoolFields.ve_sca_bind.fields.id.id;
3500
- const keyType = `${borrowIncentiveObjectId}::typed_id::TypedID<${veScaObjId}::ve_sca::VeScaKey>`;
3501
- const veScaBindTableResponse = await address.cache.queryGetDynamicFieldObject(
3502
- {
3503
- parentId: veScaBindTableId,
3504
- name: {
3505
- type: keyType,
3506
- value: veScaKeyId
3507
- }
3508
- }
3509
- );
3510
- if (veScaBindTableResponse?.data?.content?.dataType !== "moveObject")
3511
- return null;
3512
- const veScaBindTableFields = veScaBindTableResponse.data.content.fields;
3513
- const obligationId = veScaBindTableFields.value.fields.id;
3514
- return obligationId;
3501
+ const unstakedMarketCoin = unstakedMarketAmount.shiftedBy(-1 * coinDecimal);
3502
+ const availableSupplyAmount = BigNumber5(coinAmount);
3503
+ const availableSupplyCoin = availableSupplyAmount.shiftedBy(-1 * coinDecimal);
3504
+ const availableWithdrawAmount = minBigNumber(
3505
+ suppliedAmount,
3506
+ marketPool?.supplyAmount ?? Infinity
3507
+ ).plus(stakedAmount);
3508
+ const availableWithdrawCoin = minBigNumber(
3509
+ suppliedCoin,
3510
+ marketPool?.supplyCoin ?? Infinity
3511
+ ).plus(stakedCoin);
3512
+ const lending = {
3513
+ coinName: poolCoinName,
3514
+ symbol: query.utils.parseSymbol(poolCoinName),
3515
+ coinType: query.utils.parseCoinType(poolCoinName),
3516
+ marketCoinType: query.utils.parseMarketCoinType(poolCoinName),
3517
+ sCoinType: marketPool?.sCoinType ?? "",
3518
+ coinDecimal,
3519
+ coinPrice: coinPrice ?? 0,
3520
+ conversionRate: marketPool?.conversionRate ?? 1,
3521
+ marketCoinPrice: marketCoinPrice.toNumber(),
3522
+ supplyApr: marketPool?.supplyApr ?? 0,
3523
+ supplyApy: marketPool?.supplyApy ?? 0,
3524
+ rewardApr: spool?.rewardApr ?? 0,
3525
+ suppliedAmount: suppliedAmount.plus(stakedAmount).toNumber(),
3526
+ suppliedCoin: suppliedCoin.plus(stakedCoin).toNumber(),
3527
+ suppliedValue: suppliedValue.plus(stakedValue).toNumber(),
3528
+ stakedMarketAmount: stakedMarketAmount.toNumber(),
3529
+ stakedMarketCoin: stakedMarketCoin.toNumber(),
3530
+ stakedAmount: stakedAmount.toNumber(),
3531
+ stakedCoin: stakedCoin.toNumber(),
3532
+ stakedValue: stakedValue.toNumber(),
3533
+ unstakedMarketAmount: unstakedMarketAmount.toNumber(),
3534
+ unstakedMarketCoin: unstakedMarketCoin.toNumber(),
3535
+ unstakedAmount: suppliedAmount.toNumber(),
3536
+ unstakedCoin: suppliedCoin.toNumber(),
3537
+ unstakedValue: suppliedValue.toNumber(),
3538
+ availableSupplyAmount: availableSupplyAmount.toNumber(),
3539
+ availableSupplyCoin: availableSupplyCoin.toNumber(),
3540
+ availableWithdrawAmount: availableWithdrawAmount.toNumber(),
3541
+ availableWithdrawCoin: availableWithdrawCoin.toNumber(),
3542
+ availableStakeAmount: unstakedMarketAmount.toNumber(),
3543
+ availableStakeCoin: unstakedMarketCoin.toNumber(),
3544
+ availableUnstakeAmount: availableUnstakeAmount.toNumber(),
3545
+ availableUnstakeCoin: availableUnstakeCoin.toNumber(),
3546
+ availableClaimAmount: availableClaimAmount.toNumber(),
3547
+ availableClaimCoin: availableClaimCoin.toNumber(),
3548
+ isIsolated: marketPool ? marketPool.isIsolated : false
3549
+ };
3550
+ return lending;
3515
3551
  };
3516
- var getBindedVeScaKey = async ({
3517
- address
3518
- }, obligationId) => {
3519
- const borrowIncentiveObjectId = address.get("borrowIncentive.object");
3520
- const incentiveAccountsId = address.get("borrowIncentive.incentiveAccounts");
3521
- const corePkg = address.get("core.object");
3522
- const incentiveAccountsObject = await address.cache.queryGetObject(
3523
- incentiveAccountsId,
3524
- {
3525
- showContent: true
3526
- }
3552
+ var getObligationAccounts = async (query, ownerAddress, indexer = false) => {
3553
+ const coinPrices = await query.utils.getCoinPrices();
3554
+ const market = await query.queryMarket(indexer, { coinPrices });
3555
+ const [coinAmounts, obligations] = await Promise.all([
3556
+ query.getCoinAmounts(void 0, ownerAddress),
3557
+ query.getObligations(ownerAddress)
3558
+ ]);
3559
+ const obligationAccounts = {};
3560
+ await Promise.allSettled(
3561
+ obligations.map(async (obligation) => {
3562
+ obligationAccounts[obligation.keyId] = await getObligationAccount(
3563
+ query,
3564
+ obligation.id,
3565
+ ownerAddress,
3566
+ indexer,
3567
+ market,
3568
+ coinPrices,
3569
+ coinAmounts
3570
+ );
3571
+ })
3527
3572
  );
3528
- if (incentiveAccountsObject?.data?.content?.dataType !== "moveObject")
3529
- return null;
3530
- const incentiveAccountsTableId = incentiveAccountsObject.data.content.fields.accounts.fields.id.id;
3531
- const bindedIncentiveAcc = await address.cache.queryGetDynamicFieldObject({
3532
- parentId: incentiveAccountsTableId,
3533
- name: {
3534
- type: `${borrowIncentiveObjectId}::typed_id::TypedID<${corePkg}::obligation::Obligation>`,
3535
- value: obligationId
3536
- }
3537
- });
3538
- if (bindedIncentiveAcc?.data?.content?.dataType !== "moveObject")
3539
- return null;
3540
- const bindedIncentiveAccFields = bindedIncentiveAcc.data.content.fields;
3541
- return bindedIncentiveAccFields.value.fields.binded_ve_sca_key?.fields.id ?? null;
3573
+ return obligationAccounts;
3542
3574
  };
3543
-
3544
- // src/queries/priceQuery.ts
3545
- var getPythPrice = async ({
3546
- address
3547
- }, assetCoinName, priceFeedObject) => {
3548
- const pythFeedObjectId = address.get(
3549
- `core.coins.${assetCoinName}.oracle.pyth.feedObject`
3550
- );
3551
- priceFeedObject = priceFeedObject || (await address.cache.queryGetObject(pythFeedObjectId, {
3552
- showContent: true
3553
- }))?.data;
3554
- if (priceFeedObject) {
3555
- const priceFeedPoolObject = priceFeedObject;
3556
- if (priceFeedPoolObject.content && "fields" in priceFeedPoolObject.content) {
3557
- const fields = priceFeedPoolObject.content.fields;
3558
- const expoMagnitude = Number(
3559
- fields.price_info.fields.price_feed.fields.price.fields.expo.fields.magnitude
3575
+ var getObligationAccount = async (query, obligationId, ownerAddress, indexer = false, market, coinPrices, coinAmounts) => {
3576
+ const collateralAssetCoinNames = [
3577
+ ...SUPPORT_COLLATERALS
3578
+ ];
3579
+ coinPrices = coinPrices ?? await query.utils.getCoinPrices(collateralAssetCoinNames);
3580
+ market = market ?? await query.queryMarket(indexer, { coinPrices });
3581
+ coinAmounts = coinAmounts || await query.getCoinAmounts(collateralAssetCoinNames, ownerAddress);
3582
+ const [obligationQuery, borrowIncentivePools, borrowIncentiveAccounts] = await Promise.all([
3583
+ query.queryObligation(obligationId),
3584
+ query.getBorrowIncentivePools(void 0, indexer, {
3585
+ coinPrices
3586
+ }),
3587
+ query.getBorrowIncentiveAccounts(obligationId)
3588
+ ]);
3589
+ const collaterals = {};
3590
+ const debts = {};
3591
+ const borrowIncentives = {};
3592
+ let totalDepositedPools = 0;
3593
+ let totalDepositedValue = BigNumber5(0);
3594
+ let totalBorrowCapacityValue = BigNumber5(0);
3595
+ let totalRequiredCollateralValue = BigNumber5(0);
3596
+ let totalBorrowedPools = 0;
3597
+ let totalRewardedPools = 0;
3598
+ let totalBorrowedValue = BigNumber5(0);
3599
+ let totalBorrowedValueWithWeight = BigNumber5(0);
3600
+ for (const assetCoinName of collateralAssetCoinNames) {
3601
+ const collateral = obligationQuery?.collaterals.find((collateral2) => {
3602
+ const collateralCoinName = query.utils.parseCoinNameFromType(
3603
+ collateral2.type.name
3560
3604
  );
3561
- const expoNegative = Number(
3562
- fields.price_info.fields.price_feed.fields.price.fields.expo.fields.negative
3605
+ return assetCoinName === collateralCoinName;
3606
+ });
3607
+ const marketCollateral = market.collaterals[assetCoinName];
3608
+ const coinDecimal = query.utils.getCoinDecimal(assetCoinName);
3609
+ const coinPrice = coinPrices?.[assetCoinName];
3610
+ const coinAmount = coinAmounts?.[assetCoinName] ?? 0;
3611
+ if (marketCollateral && coinPrice) {
3612
+ const depositedAmount = BigNumber5(collateral?.amount ?? 0);
3613
+ const depositedCoin = depositedAmount.shiftedBy(-1 * coinDecimal);
3614
+ const depositedValue = depositedCoin.multipliedBy(coinPrice);
3615
+ const borrowCapacityValue = depositedValue.multipliedBy(
3616
+ marketCollateral.collateralFactor
3563
3617
  );
3564
- const priceMagnitude = Number(
3565
- fields.price_info.fields.price_feed.fields.price.fields.price.fields.magnitude
3618
+ const requiredCollateralValue2 = depositedValue.multipliedBy(
3619
+ marketCollateral.liquidationFactor
3566
3620
  );
3567
- const priceNegative = Number(
3568
- fields.price_info.fields.price_feed.fields.price.fields.price.fields.negative
3621
+ const poolSizeAmount = BigNumber5(marketCollateral.maxDepositAmount).minus(
3622
+ marketCollateral.depositAmount
3569
3623
  );
3570
- return priceMagnitude * 10 ** ((expoNegative ? -1 : 1) * expoMagnitude) * (priceNegative ? -1 : 1);
3571
- }
3572
- }
3573
- return 0;
3574
- };
3575
- var getPythPrices = async ({
3576
- address
3577
- }, assetCoinNames) => {
3578
- const pythPriceFeedIds = assetCoinNames.reduce(
3579
- (prev, assetCoinName) => {
3580
- const pythPriceFeed = address.get(
3581
- `core.coins.${assetCoinName}.oracle.pyth.feedObject`
3624
+ const availableDepositAmount = minBigNumber(
3625
+ BigNumber5(coinAmount),
3626
+ poolSizeAmount
3582
3627
  );
3583
- if (!prev[pythPriceFeed]) {
3584
- prev[pythPriceFeed] = [assetCoinName];
3585
- } else {
3586
- prev[pythPriceFeed].push(assetCoinName);
3587
- }
3588
- return prev;
3589
- },
3590
- {}
3591
- );
3592
- const priceFeedObjects = await address.cache.queryGetObjects(
3593
- Object.keys(pythPriceFeedIds),
3594
- { showContent: true }
3595
- );
3596
- const assetToPriceFeedMapping = priceFeedObjects.reduce(
3597
- (prev, priceFeedObject) => {
3598
- pythPriceFeedIds[priceFeedObject.objectId].forEach((assetCoinName) => {
3599
- prev[assetCoinName] = priceFeedObject;
3600
- });
3601
- return prev;
3602
- },
3603
- {}
3604
- );
3605
- return (await Promise.all(
3606
- Object.entries(assetToPriceFeedMapping).map(
3607
- async ([assetCoinName, priceFeedObject]) => ({
3608
- coinName: assetCoinName,
3609
- price: await getPythPrice(
3610
- { address },
3611
- assetCoinName,
3612
- priceFeedObject
3613
- )
3614
- })
3615
- )
3616
- )).reduce(
3617
- (prev, curr) => {
3618
- prev[curr.coinName] = curr.price;
3619
- return prev;
3620
- },
3621
- {}
3622
- );
3623
- };
3624
-
3625
- // src/queries/portfolioQuery.ts
3626
- import BigNumber4 from "bignumber.js";
3627
- var getLendings = async (query, poolCoinNames = [...SUPPORT_POOLS], ownerAddress, indexer = false) => {
3628
- const marketCoinNames = poolCoinNames.map(
3629
- (poolCoinName) => query.utils.parseMarketCoinName(poolCoinName)
3630
- );
3631
- const stakeMarketCoinNames = marketCoinNames.filter(
3632
- (marketCoinName) => SUPPORT_SPOOLS.includes(marketCoinName)
3633
- );
3634
- const coinPrices = await query.utils.getCoinPrices(poolCoinNames);
3635
- const marketPools = await query.getMarketPools(poolCoinNames, indexer, {
3636
- coinPrices
3637
- });
3638
- const spools = await query.getSpools(stakeMarketCoinNames, indexer, {
3639
- marketPools,
3640
- coinPrices
3641
- });
3642
- const [coinAmounts, marketCoinAmounts, allStakeAccounts] = await Promise.all([
3643
- query.getCoinAmounts(poolCoinNames, ownerAddress),
3644
- query.getMarketCoinAmounts(marketCoinNames, ownerAddress),
3645
- query.getAllStakeAccounts(ownerAddress)
3646
- ]);
3647
- const lendings = {};
3648
- await Promise.allSettled(
3649
- poolCoinNames.map(async (poolCoinName) => {
3650
- const stakeMarketCoinName = stakeMarketCoinNames.find(
3651
- (marketCoinName2) => marketCoinName2 === query.utils.parseMarketCoinName(poolCoinName)
3628
+ const availableDepositCoin = availableDepositAmount.shiftedBy(
3629
+ -1 * coinDecimal
3652
3630
  );
3653
- const marketCoinName = query.utils.parseMarketCoinName(poolCoinName);
3654
- lendings[poolCoinName] = await getLending(
3655
- query,
3656
- poolCoinName,
3657
- ownerAddress,
3658
- indexer,
3659
- marketPools?.[poolCoinName],
3660
- stakeMarketCoinName ? spools[stakeMarketCoinName] : void 0,
3661
- stakeMarketCoinName ? allStakeAccounts[stakeMarketCoinName] : [],
3662
- coinAmounts?.[poolCoinName],
3663
- marketCoinAmounts?.[marketCoinName],
3664
- coinPrices?.[poolCoinName] ?? 0
3631
+ totalDepositedValue = totalDepositedValue.plus(depositedValue);
3632
+ totalBorrowCapacityValue = totalBorrowCapacityValue.plus(borrowCapacityValue);
3633
+ totalRequiredCollateralValue = totalRequiredCollateralValue.plus(
3634
+ requiredCollateralValue2
3665
3635
  );
3666
- })
3667
- );
3668
- return lendings;
3669
- };
3670
- var getLending = async (query, poolCoinName, ownerAddress, indexer = false, marketPool, spool, stakeAccounts, coinAmount, marketCoinAmount, coinPrice, sCoinAmount) => {
3671
- const marketCoinName = query.utils.parseMarketCoinName(poolCoinName);
3672
- coinPrice = coinPrice ?? (await query.utils.getCoinPrices([poolCoinName]))?.[poolCoinName] ?? 0;
3673
- marketPool = marketPool ?? await query.getMarketPool(poolCoinName, indexer, {
3674
- coinPrice
3675
- });
3676
- if (!marketPool)
3677
- throw new Error(`Failed to fetch marketPool for ${poolCoinName}`);
3678
- spool = spool ?? SUPPORT_SPOOLS.includes(marketCoinName) ? await query.getSpool(
3679
- marketCoinName,
3680
- indexer,
3681
- {
3682
- marketPool,
3683
- coinPrices: {
3684
- [poolCoinName]: coinPrice
3636
+ if (depositedAmount.isGreaterThan(0)) {
3637
+ totalDepositedPools++;
3685
3638
  }
3639
+ collaterals[assetCoinName] = {
3640
+ coinName: assetCoinName,
3641
+ coinType: query.utils.parseCoinType(assetCoinName),
3642
+ symbol: query.utils.parseSymbol(assetCoinName),
3643
+ coinDecimal,
3644
+ coinPrice,
3645
+ depositedAmount: depositedAmount.toNumber(),
3646
+ depositedCoin: depositedCoin.toNumber(),
3647
+ depositedValue: depositedValue.toNumber(),
3648
+ borrowCapacityValue: borrowCapacityValue.toNumber(),
3649
+ requiredCollateralValue: requiredCollateralValue2.toNumber(),
3650
+ availableDepositAmount: availableDepositAmount.toNumber(),
3651
+ availableDepositCoin: availableDepositCoin.toNumber(),
3652
+ availableWithdrawAmount: 0,
3653
+ availableWithdrawCoin: 0
3654
+ };
3686
3655
  }
3687
- ) : void 0;
3688
- stakeAccounts = stakeAccounts || SUPPORT_SPOOLS.includes(marketCoinName) ? await query.getStakeAccounts(
3689
- marketCoinName,
3690
- ownerAddress
3691
- ) : [];
3692
- coinAmount = coinAmount || await query.getCoinAmount(poolCoinName, ownerAddress);
3693
- marketCoinAmount = marketCoinAmount || await query.getMarketCoinAmount(marketCoinName, ownerAddress);
3694
- sCoinAmount = sCoinAmount || await query.getSCoinAmount(marketCoinName, ownerAddress);
3695
- const coinDecimal = query.utils.getCoinDecimal(poolCoinName);
3696
- let stakedMarketAmount = BigNumber4(0);
3697
- let stakedMarketCoin = BigNumber4(0);
3698
- let stakedAmount = BigNumber4(0);
3699
- let stakedCoin = BigNumber4(0);
3700
- let stakedValue = BigNumber4(0);
3701
- let availableUnstakeAmount = BigNumber4(0);
3702
- let availableUnstakeCoin = BigNumber4(0);
3703
- let availableClaimAmount = BigNumber4(0);
3704
- let availableClaimCoin = BigNumber4(0);
3705
- if (spool) {
3706
- for (const stakeAccount of stakeAccounts) {
3707
- const accountStakedMarketCoinAmount = BigNumber4(stakeAccount.staked);
3708
- const accountStakedMarketCoin = accountStakedMarketCoinAmount.shiftedBy(
3709
- -1 * spool.coinDecimal
3710
- );
3711
- const accountStakedAmount = accountStakedMarketCoinAmount.multipliedBy(
3712
- marketPool?.conversionRate ?? 1
3713
- );
3714
- const accountStakedCoin = accountStakedAmount.shiftedBy(
3715
- -1 * spool.coinDecimal
3716
- );
3717
- const accountStakedValue = accountStakedCoin.multipliedBy(
3718
- spool.coinPrice
3719
- );
3720
- stakedMarketAmount = stakedMarketAmount.plus(
3721
- accountStakedMarketCoinAmount
3656
+ }
3657
+ const borrowAssetCoinNames = [
3658
+ .../* @__PURE__ */ new Set([...Object.values(market.pools).map((pool) => pool.coinName)])
3659
+ ];
3660
+ for (const assetCoinName of borrowAssetCoinNames) {
3661
+ const debt = obligationQuery?.debts.find((debt2) => {
3662
+ const poolCoinName = query.utils.parseCoinNameFromType(
3663
+ debt2.type.name
3722
3664
  );
3723
- stakedMarketCoin = stakedMarketCoin.plus(accountStakedMarketCoin);
3724
- stakedAmount = stakedAmount.plus(accountStakedAmount);
3725
- stakedCoin = stakedCoin.plus(accountStakedCoin);
3726
- stakedValue = stakedValue.plus(accountStakedValue);
3727
- availableUnstakeAmount = availableUnstakeAmount.plus(
3728
- accountStakedMarketCoinAmount
3665
+ return assetCoinName === poolCoinName;
3666
+ });
3667
+ const marketPool = market.pools[assetCoinName];
3668
+ const coinDecimal = query.utils.getCoinDecimal(assetCoinName);
3669
+ const coinPrice = coinPrices?.[assetCoinName];
3670
+ const coinAmount = coinAmounts?.[assetCoinName] ?? 0;
3671
+ if (marketPool && coinPrice) {
3672
+ const increasedRate = debt?.borrowIndex ? marketPool.borrowIndex / Number(debt.borrowIndex) - 1 : 0;
3673
+ const borrowedAmount = BigNumber5(debt?.amount ?? 0).multipliedBy(
3674
+ increasedRate + 1
3729
3675
  );
3730
- availableUnstakeCoin = availableUnstakeAmount.shiftedBy(
3731
- -1 * spool.coinDecimal
3676
+ const borrowedCoin = borrowedAmount.shiftedBy(-1 * coinDecimal);
3677
+ const requiredRepayAmount = borrowedAmount;
3678
+ const requiredRepayCoin = requiredRepayAmount.shiftedBy(-1 * coinDecimal);
3679
+ const availableRepayAmount = BigNumber5(coinAmount);
3680
+ const availableRepayCoin = availableRepayAmount.shiftedBy(
3681
+ -1 * coinDecimal
3732
3682
  );
3733
- const baseIndexRate = 1e9;
3734
- const increasedPointRate = spool.currentPointIndex ? BigNumber4(spool.currentPointIndex - stakeAccount.index).dividedBy(
3735
- baseIndexRate
3736
- ) : 1;
3737
- availableClaimAmount = availableClaimAmount.plus(
3738
- accountStakedMarketCoinAmount.multipliedBy(increasedPointRate).plus(stakeAccount.points).multipliedBy(spool.exchangeRateNumerator).dividedBy(spool.exchangeRateDenominator)
3683
+ const borrowedValue = requiredRepayCoin.multipliedBy(coinPrice);
3684
+ const borrowedValueWithWeight = borrowedValue.multipliedBy(
3685
+ marketPool.borrowWeight
3739
3686
  );
3740
- availableClaimCoin = availableClaimAmount.shiftedBy(
3741
- -1 * spool.rewardCoinDecimal
3687
+ totalBorrowedValue = totalBorrowedValue.plus(borrowedValue);
3688
+ totalBorrowedValueWithWeight = totalBorrowedValueWithWeight.plus(
3689
+ borrowedValueWithWeight
3742
3690
  );
3691
+ if (borrowedAmount.isGreaterThan(0)) {
3692
+ totalBorrowedPools++;
3693
+ }
3694
+ debts[assetCoinName] = {
3695
+ coinName: assetCoinName,
3696
+ coinType: query.utils.parseCoinType(assetCoinName),
3697
+ symbol: query.utils.parseSymbol(assetCoinName),
3698
+ coinDecimal,
3699
+ coinPrice,
3700
+ borrowedAmount: borrowedAmount.toNumber(),
3701
+ borrowedCoin: borrowedCoin.toNumber(),
3702
+ borrowedValue: borrowedValue.toNumber(),
3703
+ borrowedValueWithWeight: borrowedValueWithWeight.toNumber(),
3704
+ borrowIndex: Number(debt?.borrowIndex ?? 0),
3705
+ requiredRepayAmount: requiredRepayAmount.toNumber(),
3706
+ requiredRepayCoin: requiredRepayCoin.toNumber(),
3707
+ availableBorrowAmount: 0,
3708
+ availableBorrowCoin: 0,
3709
+ availableRepayAmount: availableRepayAmount.toNumber(),
3710
+ availableRepayCoin: availableRepayCoin.toNumber()
3711
+ };
3743
3712
  }
3744
3713
  }
3745
- const suppliedAmount = BigNumber4(marketCoinAmount).plus(BigNumber4(sCoinAmount)).multipliedBy(marketPool?.conversionRate ?? 1);
3746
- const suppliedCoin = suppliedAmount.shiftedBy(-1 * coinDecimal);
3747
- const suppliedValue = suppliedCoin.multipliedBy(coinPrice ?? 0);
3748
- const marketCoinPrice = BigNumber4(coinPrice ?? 0).multipliedBy(
3749
- marketPool?.conversionRate ?? 1
3750
- );
3751
- const unstakedMarketAmount = BigNumber4(marketCoinAmount).plus(
3752
- BigNumber4(sCoinAmount)
3753
- );
3754
- const unstakedMarketCoin = unstakedMarketAmount.shiftedBy(-1 * coinDecimal);
3755
- const availableSupplyAmount = BigNumber4(coinAmount);
3756
- const availableSupplyCoin = availableSupplyAmount.shiftedBy(-1 * coinDecimal);
3757
- const availableWithdrawAmount = minBigNumber(
3758
- suppliedAmount,
3759
- marketPool?.supplyAmount ?? Infinity
3760
- ).plus(stakedAmount);
3761
- const availableWithdrawCoin = minBigNumber(
3762
- suppliedCoin,
3763
- marketPool?.supplyCoin ?? Infinity
3764
- ).plus(stakedCoin);
3765
- const lending = {
3766
- coinName: poolCoinName,
3767
- symbol: query.utils.parseSymbol(poolCoinName),
3768
- coinType: query.utils.parseCoinType(poolCoinName),
3769
- marketCoinType: query.utils.parseMarketCoinType(poolCoinName),
3770
- sCoinType: marketPool?.sCoinType ?? "",
3771
- coinDecimal,
3772
- coinPrice: coinPrice ?? 0,
3773
- conversionRate: marketPool?.conversionRate ?? 1,
3774
- marketCoinPrice: marketCoinPrice.toNumber(),
3775
- supplyApr: marketPool?.supplyApr ?? 0,
3776
- supplyApy: marketPool?.supplyApy ?? 0,
3777
- rewardApr: spool?.rewardApr ?? 0,
3778
- suppliedAmount: suppliedAmount.plus(stakedAmount).toNumber(),
3779
- suppliedCoin: suppliedCoin.plus(stakedCoin).toNumber(),
3780
- suppliedValue: suppliedValue.plus(stakedValue).toNumber(),
3781
- stakedMarketAmount: stakedMarketAmount.toNumber(),
3782
- stakedMarketCoin: stakedMarketCoin.toNumber(),
3783
- stakedAmount: stakedAmount.toNumber(),
3784
- stakedCoin: stakedCoin.toNumber(),
3785
- stakedValue: stakedValue.toNumber(),
3786
- unstakedMarketAmount: unstakedMarketAmount.toNumber(),
3787
- unstakedMarketCoin: unstakedMarketCoin.toNumber(),
3788
- unstakedAmount: suppliedAmount.toNumber(),
3789
- unstakedCoin: suppliedCoin.toNumber(),
3790
- unstakedValue: suppliedValue.toNumber(),
3791
- availableSupplyAmount: availableSupplyAmount.toNumber(),
3792
- availableSupplyCoin: availableSupplyCoin.toNumber(),
3793
- availableWithdrawAmount: availableWithdrawAmount.toNumber(),
3794
- availableWithdrawCoin: availableWithdrawCoin.toNumber(),
3795
- availableStakeAmount: unstakedMarketAmount.toNumber(),
3796
- availableStakeCoin: unstakedMarketCoin.toNumber(),
3797
- availableUnstakeAmount: availableUnstakeAmount.toNumber(),
3798
- availableUnstakeCoin: availableUnstakeCoin.toNumber(),
3799
- availableClaimAmount: availableClaimAmount.toNumber(),
3800
- availableClaimCoin: availableClaimCoin.toNumber(),
3801
- isIsolated: marketPool ? marketPool.isIsolated : false
3714
+ for (const [poolCoinName, borrowIncentiveAccount] of Object.entries(
3715
+ borrowIncentiveAccounts
3716
+ )) {
3717
+ const coinName = poolCoinName;
3718
+ const borrowIncentivePool = borrowIncentivePools[coinName];
3719
+ if (borrowIncentivePool) {
3720
+ const rewards = [];
3721
+ for (const rewardCoinName of SUPPORT_BORROW_INCENTIVE_REWARDS) {
3722
+ const accountPoint = borrowIncentiveAccount.pointList[rewardCoinName];
3723
+ const poolPoint = borrowIncentivePool.points[rewardCoinName];
3724
+ if (accountPoint && poolPoint) {
3725
+ let availableClaimAmount = BigNumber5(0);
3726
+ let availableClaimCoin = BigNumber5(0);
3727
+ const accountBorrowedAmount = BigNumber5(accountPoint.weightedAmount);
3728
+ const baseIndexRate = 1e9;
3729
+ const increasedPointRate = poolPoint.currentPointIndex ? Math.max(
3730
+ BigNumber5(poolPoint.currentPointIndex - accountPoint.index).dividedBy(baseIndexRate).toNumber(),
3731
+ 0
3732
+ ) : 1;
3733
+ availableClaimAmount = availableClaimAmount.plus(
3734
+ accountBorrowedAmount.multipliedBy(increasedPointRate).plus(accountPoint.points)
3735
+ );
3736
+ availableClaimCoin = availableClaimAmount.shiftedBy(
3737
+ -1 * poolPoint.coinDecimal
3738
+ );
3739
+ const weightScale = BigNumber5(1e12);
3740
+ const boostValue = BigNumber5(accountPoint.weightedAmount).div(
3741
+ BigNumber5(borrowIncentiveAccount.debtAmount).multipliedBy(poolPoint.baseWeight).dividedBy(weightScale)
3742
+ ).isFinite() ? BigNumber5(accountPoint.weightedAmount).div(
3743
+ BigNumber5(borrowIncentiveAccount.debtAmount).multipliedBy(poolPoint.baseWeight).dividedBy(weightScale)
3744
+ ).toNumber() : 1;
3745
+ if (availableClaimAmount.isGreaterThanOrEqualTo(0)) {
3746
+ rewards.push({
3747
+ coinName: poolPoint.coinName,
3748
+ coinType: poolPoint.coinType,
3749
+ symbol: poolPoint.symbol,
3750
+ coinDecimal: poolPoint.coinDecimal,
3751
+ coinPrice: poolPoint.coinPrice,
3752
+ availableClaimAmount: availableClaimAmount.toNumber(),
3753
+ availableClaimCoin: availableClaimCoin.toNumber(),
3754
+ boostValue
3755
+ });
3756
+ }
3757
+ }
3758
+ }
3759
+ if (Object.keys(borrowIncentivePool.points).some((coinName2) => {
3760
+ const rewardApr = borrowIncentivePool.points[coinName2]?.rewardApr;
3761
+ return rewardApr !== Infinity && typeof rewardApr == "number" && rewardApr > 0;
3762
+ }) && borrowIncentiveAccount.debtAmount > 0) {
3763
+ totalRewardedPools++;
3764
+ }
3765
+ borrowIncentives[coinName] = {
3766
+ coinName: borrowIncentivePool.coinName,
3767
+ coinType: borrowIncentivePool.coinType,
3768
+ symbol: borrowIncentivePool.symbol,
3769
+ coinDecimal: borrowIncentivePool.coinDecimal,
3770
+ coinPrice: borrowIncentivePool.coinPrice,
3771
+ rewards
3772
+ };
3773
+ }
3774
+ }
3775
+ let riskLevel = totalRequiredCollateralValue.isZero() ? BigNumber5(0) : totalBorrowedValueWithWeight.dividedBy(totalRequiredCollateralValue);
3776
+ riskLevel = riskLevel.isLessThan(1) ? riskLevel : BigNumber5(1);
3777
+ const accountBalanceValue = totalDepositedValue.minus(totalBorrowedValue).isGreaterThan(0) ? totalDepositedValue.minus(totalBorrowedValue) : BigNumber5(0);
3778
+ const availableCollateralValue = totalBorrowCapacityValue.minus(totalBorrowedValueWithWeight).isGreaterThan(0) ? totalBorrowCapacityValue.minus(totalBorrowedValueWithWeight) : BigNumber5(0);
3779
+ const requiredCollateralValue = totalBorrowedValueWithWeight.isGreaterThan(0) ? totalRequiredCollateralValue : BigNumber5(0);
3780
+ const unhealthyCollateralValue = totalBorrowedValueWithWeight.minus(requiredCollateralValue).isGreaterThan(0) ? totalBorrowedValueWithWeight.minus(requiredCollateralValue) : BigNumber5(0);
3781
+ const obligationAccount = {
3782
+ obligationId,
3783
+ // Deposited collateral value (collateral balance)
3784
+ totalDepositedValue: totalDepositedValue.toNumber(),
3785
+ // Borrowed debt value (liabilities balance)
3786
+ totalBorrowedValue: totalBorrowedValue.toNumber(),
3787
+ // The difference between the user’s actual deposit and loan (remaining balance)
3788
+ totalBalanceValue: accountBalanceValue.toNumber(),
3789
+ // Effective collateral value (the actual collateral value included in the calculation).
3790
+ totalBorrowCapacityValue: totalBorrowCapacityValue.toNumber(),
3791
+ // Available collateral value (the remaining collateral value that can be borrowed).
3792
+ totalAvailableCollateralValue: availableCollateralValue.toNumber(),
3793
+ // Available debt value (the actual borrowing value included in the calculation).
3794
+ totalBorrowedValueWithWeight: totalBorrowedValueWithWeight.toNumber(),
3795
+ // Required collateral value (avoid be liquidated).
3796
+ totalRequiredCollateralValue: requiredCollateralValue.toNumber(),
3797
+ // Unliquidated collateral value (pending liquidation).
3798
+ totalUnhealthyCollateralValue: unhealthyCollateralValue.toNumber(),
3799
+ totalRiskLevel: riskLevel.toNumber(),
3800
+ totalDepositedPools,
3801
+ totalBorrowedPools,
3802
+ totalRewardedPools,
3803
+ collaterals,
3804
+ debts,
3805
+ borrowIncentives
3802
3806
  };
3803
- return lending;
3804
- };
3805
- var getObligationAccounts = async (query, ownerAddress, indexer = false) => {
3806
- const coinPrices = await query.utils.getCoinPrices();
3807
- const market = await query.queryMarket(indexer, { coinPrices });
3808
- const [coinAmounts, obligations] = await Promise.all([
3809
- query.getCoinAmounts(void 0, ownerAddress),
3810
- query.getObligations(ownerAddress)
3811
- ]);
3812
- const obligationAccounts = {};
3813
- await Promise.allSettled(
3814
- obligations.map(async (obligation) => {
3815
- obligationAccounts[obligation.keyId] = await getObligationAccount(
3816
- query,
3817
- obligation.id,
3818
- ownerAddress,
3819
- indexer,
3820
- market,
3821
- coinPrices,
3822
- coinAmounts
3807
+ for (const [collateralCoinName, obligationCollateral] of Object.entries(
3808
+ obligationAccount.collaterals
3809
+ )) {
3810
+ const marketCollateral = market.collaterals[collateralCoinName];
3811
+ if (marketCollateral) {
3812
+ let estimatedAvailableWithdrawAmount = BigNumber5(
3813
+ obligationAccount.totalAvailableCollateralValue
3814
+ ).dividedBy(marketCollateral.collateralFactor).dividedBy(marketCollateral.coinPrice).shiftedBy(marketCollateral.coinDecimal);
3815
+ estimatedAvailableWithdrawAmount = obligationAccount.totalBorrowedValueWithWeight === 0 ? (
3816
+ // Note: when there is no debt record, there is no need to estimate and the deposited amount is directly used as available withdraw.
3817
+ BigNumber5(obligationCollateral.depositedAmount)
3818
+ ) : minBigNumber(
3819
+ estimatedAvailableWithdrawAmount.multipliedBy(
3820
+ estimatedFactor(
3821
+ BigNumber5(obligationAccount.totalAvailableCollateralValue).dividedBy(marketCollateral.collateralFactor).toNumber(),
3822
+ 3,
3823
+ "increase"
3824
+ )
3825
+ ).toNumber(),
3826
+ obligationCollateral.depositedAmount,
3827
+ marketCollateral.depositAmount
3823
3828
  );
3824
- })
3825
- );
3826
- return obligationAccounts;
3829
+ obligationCollateral.availableWithdrawAmount = estimatedAvailableWithdrawAmount.toNumber();
3830
+ obligationCollateral.availableWithdrawCoin = estimatedAvailableWithdrawAmount.shiftedBy(-1 * obligationCollateral.coinDecimal).toNumber();
3831
+ }
3832
+ }
3833
+ for (const [poolCoinName, obligationDebt] of Object.entries(
3834
+ obligationAccount.debts
3835
+ )) {
3836
+ const marketPool = market.pools[poolCoinName];
3837
+ if (marketPool) {
3838
+ const estimatedRequiredRepayAmount = BigNumber5(
3839
+ obligationDebt.requiredRepayAmount
3840
+ ).multipliedBy(
3841
+ estimatedFactor(obligationDebt.borrowedValue, 3, "decrease")
3842
+ );
3843
+ let estimatedAvailableBorrowAmount = BigNumber5(
3844
+ obligationAccount.totalAvailableCollateralValue
3845
+ ).dividedBy(marketPool.borrowWeight).shiftedBy(marketPool.coinDecimal).dividedBy(marketPool.coinPrice);
3846
+ estimatedAvailableBorrowAmount = obligationAccount.totalAvailableCollateralValue !== 0 ? minBigNumber(
3847
+ estimatedAvailableBorrowAmount.multipliedBy(
3848
+ estimatedFactor(
3849
+ estimatedAvailableBorrowAmount.shiftedBy(-1 * marketPool.coinDecimal).multipliedBy(marketPool.coinPrice).toNumber(),
3850
+ 3,
3851
+ "increase"
3852
+ )
3853
+ ).toNumber(),
3854
+ marketPool.supplyAmount
3855
+ ) : BigNumber5(0);
3856
+ obligationDebt.availableBorrowAmount = estimatedAvailableBorrowAmount.toNumber();
3857
+ obligationDebt.availableBorrowCoin = estimatedAvailableBorrowAmount.shiftedBy(-1 * obligationDebt.coinDecimal).toNumber();
3858
+ obligationDebt.requiredRepayAmount = estimatedRequiredRepayAmount.toNumber();
3859
+ obligationDebt.requiredRepayCoin = estimatedRequiredRepayAmount.shiftedBy(-1 * obligationDebt.coinDecimal).toNumber();
3860
+ }
3861
+ }
3862
+ return obligationAccount;
3827
3863
  };
3828
- var getObligationAccount = async (query, obligationId, ownerAddress, indexer = false, market, coinPrices, coinAmounts) => {
3829
- const collateralAssetCoinNames = [
3830
- ...SUPPORT_COLLATERALS
3831
- ];
3832
- coinPrices = coinPrices ?? await query.utils.getCoinPrices(collateralAssetCoinNames);
3833
- market = market ?? await query.queryMarket(indexer, { coinPrices });
3834
- coinAmounts = coinAmounts || await query.getCoinAmounts(collateralAssetCoinNames, ownerAddress);
3835
- const [obligationQuery, borrowIncentivePools, borrowIncentiveAccounts] = await Promise.all([
3836
- query.queryObligation(obligationId),
3837
- query.getBorrowIncentivePools(void 0, indexer, {
3838
- coinPrices
3839
- }),
3840
- query.getBorrowIncentiveAccounts(obligationId)
3841
- ]);
3842
- const collaterals = {};
3843
- const debts = {};
3844
- const borrowIncentives = {};
3845
- let totalDepositedPools = 0;
3846
- let totalDepositedValue = BigNumber4(0);
3847
- let totalBorrowCapacityValue = BigNumber4(0);
3848
- let totalRequiredCollateralValue = BigNumber4(0);
3849
- let totalBorrowedPools = 0;
3850
- let totalRewardedPools = 0;
3851
- let totalBorrowedValue = BigNumber4(0);
3852
- let totalBorrowedValueWithWeight = BigNumber4(0);
3853
- for (const assetCoinName of collateralAssetCoinNames) {
3854
- const collateral = obligationQuery?.collaterals.find((collateral2) => {
3855
- const collateralCoinName = query.utils.parseCoinNameFromType(
3856
- collateral2.type.name
3864
+ var getTotalValueLocked = async (query, indexer = false) => {
3865
+ const market = await query.queryMarket(indexer);
3866
+ let supplyValue = BigNumber5(0);
3867
+ let borrowValue = BigNumber5(0);
3868
+ if (indexer) {
3869
+ const tvlIndexer = await query.indexer.getTotalValueLocked();
3870
+ const tvl2 = {
3871
+ supplyValue: tvlIndexer.supplyValue,
3872
+ supplyValueChangeRatio: tvlIndexer.supplyValueChangeRatio,
3873
+ borrowValue: tvlIndexer.borrowValue,
3874
+ borrowValueChangeRatio: tvlIndexer.borrowValueChangeRatio,
3875
+ totalValue: tvlIndexer.totalValue,
3876
+ totalValueChangeRatio: tvlIndexer.totalValueChangeRatio
3877
+ };
3878
+ return tvl2;
3879
+ }
3880
+ for (const pool of Object.values(market.pools)) {
3881
+ supplyValue = supplyValue.plus(
3882
+ BigNumber5(pool.supplyCoin).multipliedBy(pool.coinPrice)
3883
+ );
3884
+ borrowValue = borrowValue.plus(
3885
+ BigNumber5(pool.borrowCoin).multipliedBy(pool.coinPrice)
3886
+ );
3887
+ }
3888
+ for (const collateral of Object.values(market.collaterals)) {
3889
+ supplyValue = supplyValue.plus(
3890
+ BigNumber5(collateral.depositCoin).multipliedBy(collateral.coinPrice)
3891
+ );
3892
+ }
3893
+ const tvl = {
3894
+ supplyValue: supplyValue.toNumber(),
3895
+ borrowValue: borrowValue.toNumber(),
3896
+ totalValue: supplyValue.minus(borrowValue).toNumber()
3897
+ };
3898
+ return tvl;
3899
+ };
3900
+
3901
+ // src/queries/priceQuery.ts
3902
+ var getPythPrice = async ({
3903
+ address
3904
+ }, assetCoinName, priceFeedObject) => {
3905
+ const pythFeedObjectId = address.get(
3906
+ `core.coins.${assetCoinName}.oracle.pyth.feedObject`
3907
+ );
3908
+ priceFeedObject = priceFeedObject || (await address.cache.queryGetObject(pythFeedObjectId, {
3909
+ showContent: true
3910
+ }))?.data;
3911
+ if (priceFeedObject) {
3912
+ const priceFeedPoolObject = priceFeedObject;
3913
+ if (priceFeedPoolObject.content && "fields" in priceFeedPoolObject.content) {
3914
+ const fields = priceFeedPoolObject.content.fields;
3915
+ const expoMagnitude = Number(
3916
+ fields.price_info.fields.price_feed.fields.price.fields.expo.fields.magnitude
3857
3917
  );
3858
- return assetCoinName === collateralCoinName;
3859
- });
3860
- const marketCollateral = market.collaterals[assetCoinName];
3861
- const coinDecimal = query.utils.getCoinDecimal(assetCoinName);
3862
- const coinPrice = coinPrices?.[assetCoinName];
3863
- const coinAmount = coinAmounts?.[assetCoinName] ?? 0;
3864
- if (marketCollateral && coinPrice) {
3865
- const depositedAmount = BigNumber4(collateral?.amount ?? 0);
3866
- const depositedCoin = depositedAmount.shiftedBy(-1 * coinDecimal);
3867
- const depositedValue = depositedCoin.multipliedBy(coinPrice);
3868
- const borrowCapacityValue = depositedValue.multipliedBy(
3869
- marketCollateral.collateralFactor
3918
+ const expoNegative = Number(
3919
+ fields.price_info.fields.price_feed.fields.price.fields.expo.fields.negative
3870
3920
  );
3871
- const requiredCollateralValue2 = depositedValue.multipliedBy(
3872
- marketCollateral.liquidationFactor
3921
+ const priceMagnitude = Number(
3922
+ fields.price_info.fields.price_feed.fields.price.fields.price.fields.magnitude
3873
3923
  );
3874
- const poolSizeAmount = BigNumber4(marketCollateral.maxDepositAmount).minus(
3875
- marketCollateral.depositAmount
3924
+ const priceNegative = Number(
3925
+ fields.price_info.fields.price_feed.fields.price.fields.price.fields.negative
3876
3926
  );
3877
- const availableDepositAmount = minBigNumber(
3878
- BigNumber4(coinAmount),
3879
- poolSizeAmount
3927
+ return priceMagnitude * 10 ** ((expoNegative ? -1 : 1) * expoMagnitude) * (priceNegative ? -1 : 1);
3928
+ }
3929
+ }
3930
+ return 0;
3931
+ };
3932
+ var getPythPrices = async ({
3933
+ address
3934
+ }, assetCoinNames) => {
3935
+ const pythPriceFeedIds = assetCoinNames.reduce(
3936
+ (prev, assetCoinName) => {
3937
+ const pythPriceFeed = address.get(
3938
+ `core.coins.${assetCoinName}.oracle.pyth.feedObject`
3939
+ );
3940
+ if (!prev[pythPriceFeed]) {
3941
+ prev[pythPriceFeed] = [assetCoinName];
3942
+ } else {
3943
+ prev[pythPriceFeed].push(assetCoinName);
3944
+ }
3945
+ return prev;
3946
+ },
3947
+ {}
3948
+ );
3949
+ const priceFeedObjects = await address.cache.queryGetObjects(
3950
+ Object.keys(pythPriceFeedIds),
3951
+ { showContent: true }
3952
+ );
3953
+ const assetToPriceFeedMapping = priceFeedObjects.reduce(
3954
+ (prev, priceFeedObject) => {
3955
+ pythPriceFeedIds[priceFeedObject.objectId].forEach((assetCoinName) => {
3956
+ prev[assetCoinName] = priceFeedObject;
3957
+ });
3958
+ return prev;
3959
+ },
3960
+ {}
3961
+ );
3962
+ return (await Promise.all(
3963
+ Object.entries(assetToPriceFeedMapping).map(
3964
+ async ([assetCoinName, priceFeedObject]) => ({
3965
+ coinName: assetCoinName,
3966
+ price: await getPythPrice(
3967
+ { address },
3968
+ assetCoinName,
3969
+ priceFeedObject
3970
+ )
3971
+ })
3972
+ )
3973
+ )).reduce(
3974
+ (prev, curr) => {
3975
+ prev[curr.coinName] = curr.price;
3976
+ return prev;
3977
+ },
3978
+ {}
3979
+ );
3980
+ };
3981
+
3982
+ // src/queries/referralQuery.ts
3983
+ var queryVeScaKeyIdFromReferralBindings = async (address, refereeAddress) => {
3984
+ const referralBindingTableId = address.get("referral.bindingTableId");
3985
+ const referralBindResponse = await address.cache.queryGetDynamicFieldObject({
3986
+ parentId: referralBindingTableId,
3987
+ name: {
3988
+ type: "address",
3989
+ value: refereeAddress
3990
+ }
3991
+ });
3992
+ if (referralBindResponse?.data?.content?.dataType !== "moveObject")
3993
+ return null;
3994
+ const fields = referralBindResponse.data.content.fields;
3995
+ return fields.value;
3996
+ };
3997
+
3998
+ // src/queries/sCoinQuery.ts
3999
+ import { bcs } from "@mysten/sui/bcs";
4000
+ import assert from "assert";
4001
+ import BigNumber6 from "bignumber.js";
4002
+ var getSCoinTotalSupply = async ({
4003
+ utils
4004
+ }, sCoinName) => {
4005
+ const sCoinPkgId = utils.address.get("scoin.id");
4006
+ const args = [utils.getSCoinTreasury(sCoinName)];
4007
+ const typeArgs = [
4008
+ utils.parseSCoinType(sCoinName),
4009
+ utils.parseUnderlyingSCoinType(sCoinName)
4010
+ ];
4011
+ const queryTarget = `${sCoinPkgId}::s_coin_converter::total_supply`;
4012
+ const queryResults = await utils.cache.queryInspectTxn({
4013
+ queryTarget,
4014
+ args,
4015
+ typeArgs
4016
+ });
4017
+ const results = queryResults?.results;
4018
+ if (results && results[0]?.returnValues) {
4019
+ const value = Uint8Array.from(results[0].returnValues[0][0]);
4020
+ const type = results[0].returnValues[0][1];
4021
+ assert(type === "u64", "Result type is not u64");
4022
+ return BigNumber6(bcs.u64().parse(value)).shiftedBy(utils.getCoinDecimal(utils.parseCoinName(sCoinName))).toNumber();
4023
+ }
4024
+ return 0;
4025
+ };
4026
+ var getSCoinAmounts = async ({
4027
+ utils
4028
+ }, sCoinNames = [...SUPPORT_SCOIN], ownerAddress) => {
4029
+ const owner = ownerAddress || utils.suiKit.currentAddress();
4030
+ const sCoins2 = {};
4031
+ await Promise.allSettled(
4032
+ sCoinNames.map(async (sCoinName) => {
4033
+ const sCoin = await getSCoinAmount({ utils }, sCoinName, owner);
4034
+ sCoins2[sCoinName] = sCoin;
4035
+ })
4036
+ );
4037
+ return sCoins2;
4038
+ };
4039
+ var getSCoinAmount = async ({
4040
+ utils
4041
+ }, sCoinName, ownerAddress) => {
4042
+ const owner = ownerAddress || utils.suiKit.currentAddress();
4043
+ const sCoinType = utils.parseSCoinType(sCoinName);
4044
+ const amount = await utils.cache.queryGetCoinBalance({
4045
+ owner,
4046
+ coinType: sCoinType
4047
+ });
4048
+ return BigNumber6(amount).toNumber();
4049
+ };
4050
+ var isSupportStakeCoins = (value) => {
4051
+ return SUPPORT_SCOIN.includes(value);
4052
+ };
4053
+ var checkAssetParams = (fromSCoin, toSCoin) => {
4054
+ if (fromSCoin === toSCoin)
4055
+ throw new Error("fromAsset and toAsset must be different");
4056
+ if (!isSupportStakeCoins(fromSCoin))
4057
+ throw new Error("fromAsset is not supported");
4058
+ if (!isSupportStakeCoins(toSCoin)) {
4059
+ throw new Error("toAsset is not supported");
4060
+ }
4061
+ };
4062
+ var getSCoinSwapRate = async (query, fromSCoin, toSCoin, underlyingCoinPrice) => {
4063
+ checkAssetParams(fromSCoin, toSCoin);
4064
+ const fromCoinName = query.utils.parseCoinName(fromSCoin);
4065
+ const toCoinName = query.utils.parseCoinName(toSCoin);
4066
+ const marketPools = await Promise.all([
4067
+ query.getMarketPool(fromCoinName, false),
4068
+ query.getMarketPool(toCoinName, false)
4069
+ ]);
4070
+ if (marketPools.some((pool) => !pool))
4071
+ throw new Error("Failed to fetch the lendings data");
4072
+ if (marketPools.some((pool) => pool?.conversionRate === 0)) {
4073
+ throw new Error("Conversion rate cannot be zero");
4074
+ }
4075
+ const ScoinAToARate = marketPools[0].conversionRate;
4076
+ const BtoSCoinBRate = 1 / marketPools[1].conversionRate;
4077
+ const calcAtoBRate = async () => {
4078
+ const prices = await query.utils.getCoinPrices([fromCoinName, toCoinName]);
4079
+ if (!prices[fromCoinName] || !prices[toCoinName]) {
4080
+ throw new Error("Failed to fetch the coin prices");
4081
+ }
4082
+ if (prices[toCoinName] === 0) {
4083
+ throw new Error("Price of toCoin cannot be zero");
4084
+ }
4085
+ return prices[fromCoinName] / prices[toCoinName];
4086
+ };
4087
+ const AtoBRate = underlyingCoinPrice ?? await calcAtoBRate();
4088
+ return BigNumber6(ScoinAToARate).multipliedBy(AtoBRate).multipliedBy(BtoSCoinBRate).toNumber();
4089
+ };
4090
+
4091
+ // src/queries/spoolQuery.ts
4092
+ import { normalizeStructTag as normalizeStructTag5 } from "@mysten/sui/utils";
4093
+ var getSpools = async (query, stakeMarketCoinNames = [...SUPPORT_SPOOLS], indexer = false, marketPools, coinPrices) => {
4094
+ const stakeCoinNames = stakeMarketCoinNames.map(
4095
+ (stakeMarketCoinName) => query.utils.parseCoinName(stakeMarketCoinName)
4096
+ );
4097
+ coinPrices = coinPrices ?? await query.utils.getCoinPrices() ?? {};
4098
+ marketPools = marketPools ?? await query.getMarketPools(stakeCoinNames, indexer);
4099
+ if (!marketPools)
4100
+ throw new Error(`Fail to fetch marketPools for ${stakeCoinNames}`);
4101
+ const spools = {};
4102
+ if (indexer) {
4103
+ const spoolsIndexer = await query.indexer.getSpools();
4104
+ const updateSpools = (spool) => {
4105
+ if (!stakeMarketCoinNames.includes(spool.marketCoinName))
4106
+ return;
4107
+ const coinName = query.utils.parseCoinName(
4108
+ spool.marketCoinName
3880
4109
  );
3881
- const availableDepositCoin = availableDepositAmount.shiftedBy(
3882
- -1 * coinDecimal
4110
+ const rewardCoinName = query.utils.getSpoolRewardCoinName(
4111
+ spool.marketCoinName
3883
4112
  );
3884
- totalDepositedValue = totalDepositedValue.plus(depositedValue);
3885
- totalBorrowCapacityValue = totalBorrowCapacityValue.plus(borrowCapacityValue);
3886
- totalRequiredCollateralValue = totalRequiredCollateralValue.plus(
3887
- requiredCollateralValue2
4113
+ const marketPool = marketPools[coinName];
4114
+ spool.coinPrice = coinPrices[coinName] ?? spool.coinPrice;
4115
+ spool.marketCoinPrice = coinPrices[coinName] ? (coinPrices[coinName] ?? 0) * (marketPool ? marketPool.conversionRate : 0) : spool.marketCoinPrice;
4116
+ spool.rewardCoinPrice = coinPrices[rewardCoinName] ?? spool.rewardCoinPrice;
4117
+ spools[spool.marketCoinName] = spool;
4118
+ };
4119
+ Object.values(spoolsIndexer).forEach(updateSpools);
4120
+ return spools;
4121
+ }
4122
+ for (const stakeMarketCoinName of stakeMarketCoinNames) {
4123
+ const stakeCoinName = query.utils.parseCoinName(stakeMarketCoinName);
4124
+ const spool = await getSpool(
4125
+ query,
4126
+ stakeMarketCoinName,
4127
+ indexer,
4128
+ marketPools[stakeCoinName],
4129
+ coinPrices
4130
+ );
4131
+ if (spool) {
4132
+ spools[stakeMarketCoinName] = spool;
4133
+ }
4134
+ }
4135
+ return spools;
4136
+ };
4137
+ var getSpool = async (query, marketCoinName, indexer = false, marketPool, coinPrices) => {
4138
+ const coinName = query.utils.parseCoinName(marketCoinName);
4139
+ marketPool = marketPool || await query.getMarketPool(coinName, indexer);
4140
+ if (!marketPool) {
4141
+ throw new Error(`Fail to fetch marketPool for ${coinName}`);
4142
+ }
4143
+ const poolId = query.address.get(`spool.pools.${marketCoinName}.id`);
4144
+ const rewardPoolId = query.address.get(
4145
+ `spool.pools.${marketCoinName}.rewardPoolId`
4146
+ );
4147
+ let spool = void 0;
4148
+ coinPrices = coinPrices || await query.utils.getCoinPrices([coinName]);
4149
+ if (indexer) {
4150
+ const spoolIndexer = await query.indexer.getSpool(marketCoinName);
4151
+ const coinName2 = query.utils.parseCoinName(marketCoinName);
4152
+ const rewardCoinName2 = query.utils.getSpoolRewardCoinName(marketCoinName);
4153
+ spoolIndexer.coinPrice = coinPrices?.[coinName2] || spoolIndexer.coinPrice;
4154
+ spoolIndexer.marketCoinPrice = (coinPrices?.[coinName2] ?? 0) * (marketPool ? marketPool.conversionRate : 0) || spoolIndexer.marketCoinPrice;
4155
+ spoolIndexer.rewardCoinPrice = coinPrices?.[rewardCoinName2] || spoolIndexer.rewardCoinPrice;
4156
+ return spoolIndexer;
4157
+ }
4158
+ const spoolObjectResponse = await query.cache.queryGetObjects(
4159
+ [poolId, rewardPoolId],
4160
+ {
4161
+ showContent: true
4162
+ }
4163
+ );
4164
+ if (!(spoolObjectResponse[0] && spoolObjectResponse[1])) {
4165
+ throw new Error("Fail to fetch spoolObjectResponse!");
4166
+ }
4167
+ const rewardCoinName = query.utils.getSpoolRewardCoinName(marketCoinName);
4168
+ coinPrices = coinPrices || await query.utils.getCoinPrices([coinName, rewardCoinName]);
4169
+ const spoolObject = spoolObjectResponse[0];
4170
+ const rewardPoolObject = spoolObjectResponse[1];
4171
+ if (spoolObject.content && "fields" in spoolObject.content) {
4172
+ const spoolFields = spoolObject.content.fields;
4173
+ const parsedSpoolData = parseOriginSpoolData({
4174
+ stakeType: spoolFields.stake_type,
4175
+ maxDistributedPoint: spoolFields.max_distributed_point,
4176
+ distributedPoint: spoolFields.distributed_point,
4177
+ distributedPointPerPeriod: spoolFields.distributed_point_per_period,
4178
+ pointDistributionTime: spoolFields.point_distribution_time,
4179
+ maxStake: spoolFields.max_stakes,
4180
+ stakes: spoolFields.stakes,
4181
+ index: spoolFields.index,
4182
+ createdAt: spoolFields.created_at,
4183
+ lastUpdate: spoolFields.last_update
4184
+ });
4185
+ const marketCoinPrice = (coinPrices?.[coinName] ?? 0) * marketPool.conversionRate;
4186
+ const marketCoinDecimal = query.utils.getCoinDecimal(marketCoinName);
4187
+ const calculatedSpoolData = calculateSpoolData(
4188
+ parsedSpoolData,
4189
+ marketCoinPrice,
4190
+ marketCoinDecimal
4191
+ );
4192
+ if (rewardPoolObject.content && "fields" in rewardPoolObject.content) {
4193
+ const rewardPoolFields = rewardPoolObject.content.fields;
4194
+ const parsedSpoolRewardPoolData = parseOriginSpoolRewardPoolData({
4195
+ claimed_rewards: rewardPoolFields.claimed_rewards,
4196
+ exchange_rate_numerator: rewardPoolFields.exchange_rate_numerator,
4197
+ exchange_rate_denominator: rewardPoolFields.exchange_rate_denominator,
4198
+ rewards: rewardPoolFields.rewards,
4199
+ spool_id: rewardPoolFields.spool_id
4200
+ });
4201
+ const rewardCoinPrice = coinPrices?.[rewardCoinName] ?? 0;
4202
+ const rewardCoinDecimal = query.utils.getCoinDecimal(rewardCoinName);
4203
+ const calculatedRewardPoolData = calculateSpoolRewardPoolData(
4204
+ parsedSpoolData,
4205
+ parsedSpoolRewardPoolData,
4206
+ calculatedSpoolData,
4207
+ rewardCoinPrice,
4208
+ rewardCoinDecimal
3888
4209
  );
3889
- if (depositedAmount.isGreaterThan(0)) {
3890
- totalDepositedPools++;
3891
- }
3892
- collaterals[assetCoinName] = {
3893
- coinName: assetCoinName,
3894
- coinType: query.utils.parseCoinType(assetCoinName),
3895
- symbol: query.utils.parseSymbol(assetCoinName),
3896
- coinDecimal,
3897
- coinPrice,
3898
- depositedAmount: depositedAmount.toNumber(),
3899
- depositedCoin: depositedCoin.toNumber(),
3900
- depositedValue: depositedValue.toNumber(),
3901
- borrowCapacityValue: borrowCapacityValue.toNumber(),
3902
- requiredCollateralValue: requiredCollateralValue2.toNumber(),
3903
- availableDepositAmount: availableDepositAmount.toNumber(),
3904
- availableDepositCoin: availableDepositCoin.toNumber(),
3905
- availableWithdrawAmount: 0,
3906
- availableWithdrawCoin: 0
4210
+ spool = {
4211
+ marketCoinName,
4212
+ symbol: query.utils.parseSymbol(marketCoinName),
4213
+ coinType: query.utils.parseCoinType(coinName),
4214
+ marketCoinType: query.utils.parseMarketCoinType(coinName),
4215
+ rewardCoinType: isMarketCoin(rewardCoinName) ? query.utils.parseMarketCoinType(rewardCoinName) : query.utils.parseCoinType(rewardCoinName),
4216
+ sCoinType: marketPool.sCoinType,
4217
+ coinDecimal: query.utils.getCoinDecimal(coinName),
4218
+ rewardCoinDecimal: query.utils.getCoinDecimal(rewardCoinName),
4219
+ coinPrice: coinPrices?.[coinName] ?? 0,
4220
+ marketCoinPrice,
4221
+ rewardCoinPrice,
4222
+ maxPoint: parsedSpoolData.maxPoint,
4223
+ distributedPoint: parsedSpoolData.distributedPoint,
4224
+ maxStake: parsedSpoolData.maxStake,
4225
+ ...calculatedSpoolData,
4226
+ exchangeRateNumerator: parsedSpoolRewardPoolData.exchangeRateNumerator,
4227
+ exchangeRateDenominator: parsedSpoolRewardPoolData.exchangeRateDenominator,
4228
+ ...calculatedRewardPoolData
3907
4229
  };
3908
4230
  }
3909
4231
  }
3910
- const borrowAssetCoinNames = [
3911
- .../* @__PURE__ */ new Set([...Object.values(market.pools).map((pool) => pool.coinName)])
3912
- ];
3913
- for (const assetCoinName of borrowAssetCoinNames) {
3914
- const debt = obligationQuery?.debts.find((debt2) => {
3915
- const poolCoinName = query.utils.parseCoinNameFromType(
3916
- debt2.type.name
3917
- );
3918
- return assetCoinName === poolCoinName;
4232
+ return spool;
4233
+ };
4234
+ var getStakeAccounts = async ({
4235
+ utils
4236
+ }, ownerAddress) => {
4237
+ const owner = ownerAddress || utils.suiKit.currentAddress();
4238
+ const spoolObjectId = utils.address.get("spool.object");
4239
+ const stakeAccountType = `${spoolObjectId}::spool_account::SpoolAccount`;
4240
+ const stakeObjectsResponse = [];
4241
+ let hasNextPage = false;
4242
+ let nextCursor = null;
4243
+ do {
4244
+ const paginatedStakeObjectsResponse = await utils.cache.queryGetOwnedObjects({
4245
+ owner,
4246
+ filter: { StructType: stakeAccountType },
4247
+ options: {
4248
+ showContent: true,
4249
+ showType: true
4250
+ },
4251
+ cursor: nextCursor,
4252
+ limit: 10
3919
4253
  });
3920
- const marketPool = market.pools[assetCoinName];
3921
- const coinDecimal = query.utils.getCoinDecimal(assetCoinName);
3922
- const coinPrice = coinPrices?.[assetCoinName];
3923
- const coinAmount = coinAmounts?.[assetCoinName] ?? 0;
3924
- if (marketPool && coinPrice) {
3925
- const increasedRate = debt?.borrowIndex ? marketPool.borrowIndex / Number(debt.borrowIndex) - 1 : 0;
3926
- const borrowedAmount = BigNumber4(debt?.amount ?? 0).multipliedBy(
3927
- increasedRate + 1
3928
- );
3929
- const borrowedCoin = borrowedAmount.shiftedBy(-1 * coinDecimal);
3930
- const requiredRepayAmount = borrowedAmount;
3931
- const requiredRepayCoin = requiredRepayAmount.shiftedBy(-1 * coinDecimal);
3932
- const availableRepayAmount = BigNumber4(coinAmount);
3933
- const availableRepayCoin = availableRepayAmount.shiftedBy(
3934
- -1 * coinDecimal
3935
- );
3936
- const borrowedValue = requiredRepayCoin.multipliedBy(coinPrice);
3937
- const borrowedValueWithWeight = borrowedValue.multipliedBy(
3938
- marketPool.borrowWeight
3939
- );
3940
- totalBorrowedValue = totalBorrowedValue.plus(borrowedValue);
3941
- totalBorrowedValueWithWeight = totalBorrowedValueWithWeight.plus(
3942
- borrowedValueWithWeight
3943
- );
3944
- if (borrowedAmount.isGreaterThan(0)) {
3945
- totalBorrowedPools++;
3946
- }
3947
- debts[assetCoinName] = {
3948
- coinName: assetCoinName,
3949
- coinType: query.utils.parseCoinType(assetCoinName),
3950
- symbol: query.utils.parseSymbol(assetCoinName),
3951
- coinDecimal,
3952
- coinPrice,
3953
- borrowedAmount: borrowedAmount.toNumber(),
3954
- borrowedCoin: borrowedCoin.toNumber(),
3955
- borrowedValue: borrowedValue.toNumber(),
3956
- borrowedValueWithWeight: borrowedValueWithWeight.toNumber(),
3957
- borrowIndex: Number(debt?.borrowIndex ?? 0),
3958
- requiredRepayAmount: requiredRepayAmount.toNumber(),
3959
- requiredRepayCoin: requiredRepayCoin.toNumber(),
3960
- availableBorrowAmount: 0,
3961
- availableBorrowCoin: 0,
3962
- availableRepayAmount: availableRepayAmount.toNumber(),
3963
- availableRepayCoin: availableRepayCoin.toNumber()
4254
+ if (!paginatedStakeObjectsResponse)
4255
+ continue;
4256
+ stakeObjectsResponse.push(...paginatedStakeObjectsResponse.data);
4257
+ if (paginatedStakeObjectsResponse.hasNextPage && paginatedStakeObjectsResponse.nextCursor) {
4258
+ hasNextPage = true;
4259
+ nextCursor = paginatedStakeObjectsResponse.nextCursor;
4260
+ } else {
4261
+ hasNextPage = false;
4262
+ }
4263
+ } while (hasNextPage);
4264
+ const stakeAccounts = SUPPORT_SPOOLS.reduce(
4265
+ (acc, stakeName) => {
4266
+ acc[stakeName] = [];
4267
+ return acc;
4268
+ },
4269
+ {}
4270
+ );
4271
+ const stakeMarketCoinTypes = Object.keys(stakeAccounts).reduce(
4272
+ (types, stakeMarketCoinName) => {
4273
+ const stakeCoinName = utils.parseCoinName(stakeMarketCoinName);
4274
+ const marketCoinType = utils.parseMarketCoinType(stakeCoinName);
4275
+ types[stakeMarketCoinName] = `${spoolObjectId}::spool_account::SpoolAccount<${marketCoinType}>`;
4276
+ return types;
4277
+ },
4278
+ {}
4279
+ );
4280
+ const reversedStakeMarketCoinTypes = Object.entries(stakeMarketCoinTypes).reduce(
4281
+ (reversedTypes, [key, value]) => {
4282
+ reversedTypes[value] = key;
4283
+ return reversedTypes;
4284
+ },
4285
+ {}
4286
+ );
4287
+ for (const stakeObject of stakeObjectsResponse.map((ref) => ref.data)) {
4288
+ const id = stakeObject?.objectId;
4289
+ const type = stakeObject?.type;
4290
+ if (id && stakeObject?.content && "fields" in stakeObject.content) {
4291
+ const fields = stakeObject.content.fields;
4292
+ const stakePoolId = String(fields.spool_id);
4293
+ const stakeType = String(fields.stake_type.fields.name);
4294
+ const staked = Number(fields.stakes);
4295
+ const index = Number(fields.index);
4296
+ const points = Number(fields.points);
4297
+ const totalPoints = Number(fields.total_points);
4298
+ const stakeMarketCoinTypeMap = {
4299
+ sweth: stakeAccounts.sweth,
4300
+ ssui: stakeAccounts.ssui,
4301
+ swusdc: stakeAccounts.swusdc,
4302
+ swusdt: stakeAccounts.swusdt,
4303
+ scetus: stakeAccounts.scetus,
4304
+ safsui: stakeAccounts.safsui,
4305
+ shasui: stakeAccounts.shasui,
4306
+ svsui: stakeAccounts.svsui,
4307
+ susdc: stakeAccounts.susdc
3964
4308
  };
4309
+ const normalizedType = normalizeStructTag5(type);
4310
+ const stakeAccountArray = stakeMarketCoinTypeMap[reversedStakeMarketCoinTypes[normalizedType]];
4311
+ if (stakeAccountArray) {
4312
+ stakeAccountArray.push({
4313
+ id,
4314
+ type: normalizedType,
4315
+ stakePoolId,
4316
+ stakeType: normalizeStructTag5(stakeType),
4317
+ staked,
4318
+ index,
4319
+ points,
4320
+ totalPoints
4321
+ });
4322
+ }
3965
4323
  }
3966
4324
  }
3967
- for (const [poolCoinName, borrowIncentiveAccount] of Object.entries(
3968
- borrowIncentiveAccounts
3969
- )) {
3970
- const coinName = poolCoinName;
3971
- const borrowIncentivePool = borrowIncentivePools[coinName];
3972
- if (borrowIncentivePool) {
3973
- const rewards = [];
3974
- for (const rewardCoinName of SUPPORT_BORROW_INCENTIVE_REWARDS) {
3975
- const accountPoint = borrowIncentiveAccount.pointList[rewardCoinName];
3976
- const poolPoint = borrowIncentivePool.points[rewardCoinName];
3977
- if (accountPoint && poolPoint) {
3978
- let availableClaimAmount = BigNumber4(0);
3979
- let availableClaimCoin = BigNumber4(0);
3980
- const accountBorrowedAmount = BigNumber4(accountPoint.weightedAmount);
3981
- const baseIndexRate = 1e9;
3982
- const increasedPointRate = poolPoint.currentPointIndex ? Math.max(
3983
- BigNumber4(poolPoint.currentPointIndex - accountPoint.index).dividedBy(baseIndexRate).toNumber(),
3984
- 0
3985
- ) : 1;
3986
- availableClaimAmount = availableClaimAmount.plus(
3987
- accountBorrowedAmount.multipliedBy(increasedPointRate).plus(accountPoint.points)
3988
- );
3989
- availableClaimCoin = availableClaimAmount.shiftedBy(
3990
- -1 * poolPoint.coinDecimal
3991
- );
3992
- const weightScale = BigNumber4(1e12);
3993
- const boostValue = BigNumber4(accountPoint.weightedAmount).div(
3994
- BigNumber4(borrowIncentiveAccount.debtAmount).multipliedBy(poolPoint.baseWeight).dividedBy(weightScale)
3995
- ).isFinite() ? BigNumber4(accountPoint.weightedAmount).div(
3996
- BigNumber4(borrowIncentiveAccount.debtAmount).multipliedBy(poolPoint.baseWeight).dividedBy(weightScale)
3997
- ).toNumber() : 1;
3998
- if (availableClaimAmount.isGreaterThanOrEqualTo(0)) {
3999
- rewards.push({
4000
- coinName: poolPoint.coinName,
4001
- coinType: poolPoint.coinType,
4002
- symbol: poolPoint.symbol,
4003
- coinDecimal: poolPoint.coinDecimal,
4004
- coinPrice: poolPoint.coinPrice,
4005
- availableClaimAmount: availableClaimAmount.toNumber(),
4006
- availableClaimCoin: availableClaimCoin.toNumber(),
4007
- boostValue
4008
- });
4009
- }
4010
- }
4011
- }
4012
- if (Object.keys(borrowIncentivePool.points).some((coinName2) => {
4013
- const rewardApr = borrowIncentivePool.points[coinName2]?.rewardApr;
4014
- return rewardApr !== Infinity && typeof rewardApr == "number" && rewardApr > 0;
4015
- }) && borrowIncentiveAccount.debtAmount > 0) {
4016
- totalRewardedPools++;
4017
- }
4018
- borrowIncentives[coinName] = {
4019
- coinName: borrowIncentivePool.coinName,
4020
- coinType: borrowIncentivePool.coinType,
4021
- symbol: borrowIncentivePool.symbol,
4022
- coinDecimal: borrowIncentivePool.coinDecimal,
4023
- coinPrice: borrowIncentivePool.coinPrice,
4024
- rewards
4325
+ return stakeAccounts;
4326
+ };
4327
+ var getStakePool = async ({
4328
+ utils
4329
+ }, marketCoinName) => {
4330
+ const poolId = utils.address.get(`spool.pools.${marketCoinName}.id`);
4331
+ let stakePool = void 0;
4332
+ const stakePoolObjectResponse = await utils.cache.queryGetObject(poolId, {
4333
+ showContent: true,
4334
+ showType: true
4335
+ });
4336
+ if (stakePoolObjectResponse?.data) {
4337
+ const stakePoolObject = stakePoolObjectResponse.data;
4338
+ const id = stakePoolObject.objectId;
4339
+ const type = stakePoolObject.type;
4340
+ if (stakePoolObject.content && "fields" in stakePoolObject.content) {
4341
+ const fields = stakePoolObject.content.fields;
4342
+ const maxPoint = Number(fields.max_distributed_point);
4343
+ const distributedPoint = Number(fields.distributed_point);
4344
+ const pointPerPeriod = Number(fields.distributed_point_per_period);
4345
+ const period = Number(fields.point_distribution_time);
4346
+ const maxStake = Number(fields.max_stakes);
4347
+ const stakeType = String(fields.stake_type.fields.name);
4348
+ const totalStaked = Number(fields.stakes);
4349
+ const index = Number(fields.index);
4350
+ const createdAt = Number(fields.created_at);
4351
+ const lastUpdate = Number(fields.last_update);
4352
+ stakePool = {
4353
+ id,
4354
+ type: normalizeStructTag5(type),
4355
+ maxPoint,
4356
+ distributedPoint,
4357
+ pointPerPeriod,
4358
+ period,
4359
+ maxStake,
4360
+ stakeType: normalizeStructTag5(stakeType),
4361
+ totalStaked,
4362
+ index,
4363
+ createdAt,
4364
+ lastUpdate
4025
4365
  };
4026
4366
  }
4027
4367
  }
4028
- let riskLevel = totalRequiredCollateralValue.isZero() ? BigNumber4(0) : totalBorrowedValueWithWeight.dividedBy(totalRequiredCollateralValue);
4029
- riskLevel = riskLevel.isLessThan(1) ? riskLevel : BigNumber4(1);
4030
- const accountBalanceValue = totalDepositedValue.minus(totalBorrowedValue).isGreaterThan(0) ? totalDepositedValue.minus(totalBorrowedValue) : BigNumber4(0);
4031
- const availableCollateralValue = totalBorrowCapacityValue.minus(totalBorrowedValueWithWeight).isGreaterThan(0) ? totalBorrowCapacityValue.minus(totalBorrowedValueWithWeight) : BigNumber4(0);
4032
- const requiredCollateralValue = totalBorrowedValueWithWeight.isGreaterThan(0) ? totalRequiredCollateralValue : BigNumber4(0);
4033
- const unhealthyCollateralValue = totalBorrowedValueWithWeight.minus(requiredCollateralValue).isGreaterThan(0) ? totalBorrowedValueWithWeight.minus(requiredCollateralValue) : BigNumber4(0);
4034
- const obligationAccount = {
4035
- obligationId,
4036
- // Deposited collateral value (collateral balance)
4037
- totalDepositedValue: totalDepositedValue.toNumber(),
4038
- // Borrowed debt value (liabilities balance)
4039
- totalBorrowedValue: totalBorrowedValue.toNumber(),
4040
- // The difference between the user’s actual deposit and loan (remaining balance)
4041
- totalBalanceValue: accountBalanceValue.toNumber(),
4042
- // Effective collateral value (the actual collateral value included in the calculation).
4043
- totalBorrowCapacityValue: totalBorrowCapacityValue.toNumber(),
4044
- // Available collateral value (the remaining collateral value that can be borrowed).
4045
- totalAvailableCollateralValue: availableCollateralValue.toNumber(),
4046
- // Available debt value (the actual borrowing value included in the calculation).
4047
- totalBorrowedValueWithWeight: totalBorrowedValueWithWeight.toNumber(),
4048
- // Required collateral value (avoid be liquidated).
4049
- totalRequiredCollateralValue: requiredCollateralValue.toNumber(),
4050
- // Unliquidated collateral value (pending liquidation).
4051
- totalUnhealthyCollateralValue: unhealthyCollateralValue.toNumber(),
4052
- totalRiskLevel: riskLevel.toNumber(),
4053
- totalDepositedPools,
4054
- totalBorrowedPools,
4055
- totalRewardedPools,
4056
- collaterals,
4057
- debts,
4058
- borrowIncentives
4059
- };
4060
- for (const [collateralCoinName, obligationCollateral] of Object.entries(
4061
- obligationAccount.collaterals
4062
- )) {
4063
- const marketCollateral = market.collaterals[collateralCoinName];
4064
- if (marketCollateral) {
4065
- let estimatedAvailableWithdrawAmount = BigNumber4(
4066
- obligationAccount.totalAvailableCollateralValue
4067
- ).dividedBy(marketCollateral.collateralFactor).dividedBy(marketCollateral.coinPrice).shiftedBy(marketCollateral.coinDecimal);
4068
- estimatedAvailableWithdrawAmount = obligationAccount.totalBorrowedValueWithWeight === 0 ? (
4069
- // Note: when there is no debt record, there is no need to estimate and the deposited amount is directly used as available withdraw.
4070
- BigNumber4(obligationCollateral.depositedAmount)
4071
- ) : minBigNumber(
4072
- estimatedAvailableWithdrawAmount.multipliedBy(
4073
- estimatedFactor(
4074
- BigNumber4(obligationAccount.totalAvailableCollateralValue).dividedBy(marketCollateral.collateralFactor).toNumber(),
4075
- 3,
4076
- "increase"
4077
- )
4078
- ).toNumber(),
4079
- obligationCollateral.depositedAmount,
4080
- marketCollateral.depositAmount
4081
- );
4082
- obligationCollateral.availableWithdrawAmount = estimatedAvailableWithdrawAmount.toNumber();
4083
- obligationCollateral.availableWithdrawCoin = estimatedAvailableWithdrawAmount.shiftedBy(-1 * obligationCollateral.coinDecimal).toNumber();
4368
+ return stakePool;
4369
+ };
4370
+ var getStakeRewardPool = async ({
4371
+ utils
4372
+ }, marketCoinName) => {
4373
+ const poolId = utils.address.get(
4374
+ `spool.pools.${marketCoinName}.rewardPoolId`
4375
+ );
4376
+ let stakeRewardPool = void 0;
4377
+ const stakeRewardPoolObjectResponse = await utils.cache.queryGetObject(
4378
+ poolId,
4379
+ {
4380
+ showContent: true,
4381
+ showType: true
4084
4382
  }
4085
- }
4086
- for (const [poolCoinName, obligationDebt] of Object.entries(
4087
- obligationAccount.debts
4088
- )) {
4089
- const marketPool = market.pools[poolCoinName];
4090
- if (marketPool) {
4091
- const estimatedRequiredRepayAmount = BigNumber4(
4092
- obligationDebt.requiredRepayAmount
4093
- ).multipliedBy(
4094
- estimatedFactor(obligationDebt.borrowedValue, 3, "decrease")
4383
+ );
4384
+ if (stakeRewardPoolObjectResponse?.data) {
4385
+ const stakeRewardPoolObject = stakeRewardPoolObjectResponse.data;
4386
+ const id = stakeRewardPoolObject.objectId;
4387
+ const type = stakeRewardPoolObject.type;
4388
+ if (stakeRewardPoolObject.content && "fields" in stakeRewardPoolObject.content) {
4389
+ const rewardPoolFields = stakeRewardPoolObject.content.fields;
4390
+ const stakePoolId = String(rewardPoolFields.spool_id);
4391
+ const ratioNumerator = Number(rewardPoolFields.exchange_rate_numerator);
4392
+ const ratioDenominator = Number(
4393
+ rewardPoolFields.exchange_rate_denominator
4095
4394
  );
4096
- let estimatedAvailableBorrowAmount = BigNumber4(
4097
- obligationAccount.totalAvailableCollateralValue
4098
- ).dividedBy(marketPool.borrowWeight).shiftedBy(marketPool.coinDecimal).dividedBy(marketPool.coinPrice);
4099
- estimatedAvailableBorrowAmount = obligationAccount.totalAvailableCollateralValue !== 0 ? minBigNumber(
4100
- estimatedAvailableBorrowAmount.multipliedBy(
4101
- estimatedFactor(
4102
- estimatedAvailableBorrowAmount.shiftedBy(-1 * marketPool.coinDecimal).multipliedBy(marketPool.coinPrice).toNumber(),
4103
- 3,
4104
- "increase"
4105
- )
4106
- ).toNumber(),
4107
- marketPool.supplyAmount
4108
- ) : BigNumber4(0);
4109
- obligationDebt.availableBorrowAmount = estimatedAvailableBorrowAmount.toNumber();
4110
- obligationDebt.availableBorrowCoin = estimatedAvailableBorrowAmount.shiftedBy(-1 * obligationDebt.coinDecimal).toNumber();
4111
- obligationDebt.requiredRepayAmount = estimatedRequiredRepayAmount.toNumber();
4112
- obligationDebt.requiredRepayCoin = estimatedRequiredRepayAmount.shiftedBy(-1 * obligationDebt.coinDecimal).toNumber();
4395
+ const rewards = Number(rewardPoolFields.rewards);
4396
+ const claimedRewards = Number(rewardPoolFields.claimed_rewards);
4397
+ stakeRewardPool = {
4398
+ id,
4399
+ type: normalizeStructTag5(type),
4400
+ stakePoolId,
4401
+ ratioNumerator,
4402
+ ratioDenominator,
4403
+ rewards,
4404
+ claimedRewards
4405
+ };
4113
4406
  }
4114
4407
  }
4115
- return obligationAccount;
4116
- };
4117
- var getTotalValueLocked = async (query, indexer = false) => {
4118
- const market = await query.queryMarket(indexer);
4119
- let supplyValue = BigNumber4(0);
4120
- let borrowValue = BigNumber4(0);
4121
- if (indexer) {
4122
- const tvlIndexer = await query.indexer.getTotalValueLocked();
4123
- const tvl2 = {
4124
- supplyValue: tvlIndexer.supplyValue,
4125
- supplyValueChangeRatio: tvlIndexer.supplyValueChangeRatio,
4126
- borrowValue: tvlIndexer.borrowValue,
4127
- borrowValueChangeRatio: tvlIndexer.borrowValueChangeRatio,
4128
- totalValue: tvlIndexer.totalValue,
4129
- totalValueChangeRatio: tvlIndexer.totalValueChangeRatio
4130
- };
4131
- return tvl2;
4132
- }
4133
- for (const pool of Object.values(market.pools)) {
4134
- supplyValue = supplyValue.plus(
4135
- BigNumber4(pool.supplyCoin).multipliedBy(pool.coinPrice)
4136
- );
4137
- borrowValue = borrowValue.plus(
4138
- BigNumber4(pool.borrowCoin).multipliedBy(pool.coinPrice)
4139
- );
4140
- }
4141
- for (const collateral of Object.values(market.collaterals)) {
4142
- supplyValue = supplyValue.plus(
4143
- BigNumber4(collateral.depositCoin).multipliedBy(collateral.coinPrice)
4144
- );
4145
- }
4146
- const tvl = {
4147
- supplyValue: supplyValue.toNumber(),
4148
- borrowValue: borrowValue.toNumber(),
4149
- totalValue: supplyValue.minus(borrowValue).toNumber()
4150
- };
4151
- return tvl;
4408
+ return stakeRewardPool;
4152
4409
  };
4153
4410
 
4154
4411
  // src/queries/vescaQuery.ts
4155
- import BigNumber5 from "bignumber.js";
4412
+ import BigNumber7 from "bignumber.js";
4156
4413
  import { SUI_CLOCK_OBJECT_ID, SuiTxBlock as SuiTxBlock2 } from "@scallop-io/sui-kit";
4157
- import { bcs } from "@mysten/sui/bcs";
4158
- import { z as zod2 } from "zod";
4159
- import assert from "assert";
4414
+ import { bcs as bcs2 } from "@mysten/sui/bcs";
4415
+ import { z as zod4 } from "zod";
4416
+ import assert2 from "assert";
4160
4417
  var getVescaKeys = async (utils, ownerAddress) => {
4161
4418
  const owner = ownerAddress || utils.suiKit.currentAddress();
4162
4419
  const veScaObjId = utils.address.get("vesca.object");
@@ -4204,10 +4461,10 @@ var getVeScas = async ({
4204
4461
  }
4205
4462
  return result;
4206
4463
  };
4207
- var SuiObjectRefZod = zod2.object({
4208
- objectId: zod2.string(),
4209
- digest: zod2.string(),
4210
- version: zod2.string()
4464
+ var SuiObjectRefZod = zod4.object({
4465
+ objectId: zod4.string(),
4466
+ digest: zod4.string(),
4467
+ version: zod4.string()
4211
4468
  });
4212
4469
  var getVeSca = async (utils, veScaKey) => {
4213
4470
  const tableId = utils.address.get(`vesca.tableId`);
@@ -4234,7 +4491,7 @@ var getVeSca = async (utils, veScaKey) => {
4234
4491
  0
4235
4492
  );
4236
4493
  const lockedScaAmount = String(dynamicFields.locked_sca_amount);
4237
- const lockedScaCoin = BigNumber5(dynamicFields.locked_sca_amount).shiftedBy(-9).toNumber();
4494
+ const lockedScaCoin = BigNumber7(dynamicFields.locked_sca_amount).shiftedBy(-9).toNumber();
4238
4495
  const currentVeScaBalance = lockedScaCoin * (Math.floor(remainingLockPeriodInMilliseconds / 1e3) / MAX_LOCK_DURATION);
4239
4496
  vesca = {
4240
4497
  id: veScaDynamicFieldObject.objectId,
@@ -4244,7 +4501,7 @@ var getVeSca = async (utils, veScaKey) => {
4244
4501
  lockedScaAmount,
4245
4502
  lockedScaCoin,
4246
4503
  currentVeScaBalance,
4247
- unlockAt: BigNumber5(dynamicFields.unlock_at * 1e3).toNumber()
4504
+ unlockAt: BigNumber7(dynamicFields.unlock_at * 1e3).toNumber()
4248
4505
  };
4249
4506
  }
4250
4507
  return vesca;
@@ -4293,8 +4550,8 @@ var getTotalVeScaTreasuryAmount = async (utils, veScaTreasury) => {
4293
4550
  if (results && results[1]?.returnValues) {
4294
4551
  const value = Uint8Array.from(results[1].returnValues[0][0]);
4295
4552
  const type = results[1].returnValues[0][1];
4296
- assert(type === "u64", "Result type is not u64");
4297
- return bcs.u64().parse(value);
4553
+ assert2(type === "u64", "Result type is not u64");
4554
+ return bcs2.u64().parse(value);
4298
4555
  }
4299
4556
  return "0";
4300
4557
  };
@@ -4306,10 +4563,10 @@ var getVeScaTreasuryInfo = async (utils) => {
4306
4563
  if (!veScaTreasury || veScaTreasury.data?.content?.dataType !== "moveObject")
4307
4564
  return null;
4308
4565
  const treasuryFields = veScaTreasury.data.content.fields;
4309
- const totalLockedSca = BigNumber5(
4566
+ const totalLockedSca = BigNumber7(
4310
4567
  treasuryFields.unlock_schedule.fields.locked_sca_amount
4311
4568
  ).shiftedBy(-9).toNumber();
4312
- const totalVeSca = BigNumber5(
4569
+ const totalVeSca = BigNumber7(
4313
4570
  await getTotalVeScaTreasuryAmount(utils, veScaTreasury.data) ?? 0
4314
4571
  ).shiftedBy(-9).toNumber();
4315
4572
  const averageLockingPeriod = totalLockedSca > 0 ? totalVeSca / totalLockedSca * 4 : 0;
@@ -4322,94 +4579,8 @@ var getVeScaTreasuryInfo = async (utils) => {
4322
4579
  };
4323
4580
  };
4324
4581
 
4325
- // src/queries/referralQuery.ts
4326
- var queryVeScaKeyIdFromReferralBindings = async (address, refereeAddress) => {
4327
- const referralBindingTableId = address.get("referral.bindingTableId");
4328
- const referralBindResponse = await address.cache.queryGetDynamicFieldObject({
4329
- parentId: referralBindingTableId,
4330
- name: {
4331
- type: "address",
4332
- value: refereeAddress
4333
- }
4334
- });
4335
- if (referralBindResponse?.data?.content?.dataType !== "moveObject")
4336
- return null;
4337
- const fields = referralBindResponse.data.content.fields;
4338
- return fields.value;
4339
- };
4340
-
4341
- // src/queries/loyaltyProgramQuery.ts
4342
- import BigNumber6 from "bignumber.js";
4343
- import { z as zod3 } from "zod";
4344
- var rewardPoolFieldsZod = zod3.object({
4345
- balance: zod3.string(),
4346
- enable_claim: zod3.boolean()
4347
- }).transform((value) => ({
4348
- totalPoolReward: BigNumber6(value.balance).shiftedBy(-9).toNumber(),
4349
- isClaimEnabled: value.enable_claim
4350
- }));
4351
- var userRewardFieldsZod = zod3.object({
4352
- value: zod3.string()
4353
- }).transform((value) => BigNumber6(value.value).shiftedBy(-9).toNumber());
4354
- var getLoyaltyProgramInformations = async (query, veScaKey) => {
4355
- const rewardPool = query.address.get("loyaltyProgram.rewardPool");
4356
- const rewardPoolObject = await query.cache.queryGetObject(rewardPool, {
4357
- showContent: true
4358
- });
4359
- if (rewardPoolObject?.data?.content?.dataType !== "moveObject")
4360
- return null;
4361
- const rewardPoolFields = rewardPoolObject.data.content.fields;
4362
- const { isClaimEnabled, totalPoolReward } = rewardPoolFieldsZod.parse(
4363
- rewardPoolFields
4364
- );
4365
- const result = {
4366
- pendingReward: 0,
4367
- totalPoolReward,
4368
- isClaimEnabled
4369
- };
4370
- veScaKey = veScaKey ?? (await query.getVeScas())[0]?.keyObject;
4371
- if (!veScaKey)
4372
- return result;
4373
- const userRewardTableId = query.address.get(
4374
- "loyaltyProgram.userRewardTableId"
4375
- );
4376
- const userRewardObject = await query.cache.queryGetDynamicFieldObject({
4377
- parentId: userRewardTableId,
4378
- name: {
4379
- type: "0x2::object::ID",
4380
- value: typeof veScaKey === "string" ? veScaKey : veScaKey.objectId
4381
- }
4382
- });
4383
- if (userRewardObject?.data?.content?.dataType !== "moveObject")
4384
- return result;
4385
- const userRewardFields = userRewardObject.data.content.fields;
4386
- result.pendingReward = userRewardFieldsZod.parse(
4387
- userRewardFields
4388
- );
4389
- return result;
4390
- };
4391
-
4392
4582
  // src/models/suiKit.ts
4393
4583
  import { SuiKit as SuiKit2 } from "@scallop-io/sui-kit";
4394
-
4395
- // src/constants/rpc.ts
4396
- import { getFullnodeUrl } from "@mysten/sui/client";
4397
- var RPC_PROVIDERS = [
4398
- getFullnodeUrl("mainnet"),
4399
- "https://sui-mainnet.public.blastapi.io",
4400
- "https://sui-mainnet-ca-2.cosmostation.io",
4401
- "https://sui-mainnet-eu-4.cosmostation.io",
4402
- "https://sui-mainnet-endpoint.blockvision.org",
4403
- "https://sui-rpc.publicnode.com",
4404
- "https://sui-mainnet-rpc.allthatnode.com",
4405
- "https://mainnet.suiet.app",
4406
- "https://mainnet.sui.rpcpool.com",
4407
- "https://sui1mainnet-rpc.chainode.tech",
4408
- "https://fullnode.mainnet.apis.scallop.io",
4409
- "https://sui-mainnet-us-2.cosmostation.io"
4410
- ];
4411
-
4412
- // src/models/suiKit.ts
4413
4584
  var newSuiKit = (params) => {
4414
4585
  return new SuiKit2({
4415
4586
  ...params,
@@ -6677,183 +6848,8 @@ var ScallopIndexer = class {
6677
6848
  }
6678
6849
  };
6679
6850
 
6680
- // src/queries/sCoinQuery.ts
6681
- import { bcs as bcs2 } from "@mysten/sui/bcs";
6682
- import assert2 from "assert";
6683
- import BigNumber7 from "bignumber.js";
6684
- var getSCoinTotalSupply = async ({
6685
- utils
6686
- }, sCoinName) => {
6687
- const sCoinPkgId = utils.address.get("scoin.id");
6688
- const args = [utils.getSCoinTreasury(sCoinName)];
6689
- const typeArgs = [
6690
- utils.parseSCoinType(sCoinName),
6691
- utils.parseUnderlyingSCoinType(sCoinName)
6692
- ];
6693
- const queryTarget = `${sCoinPkgId}::s_coin_converter::total_supply`;
6694
- const queryResults = await utils.cache.queryInspectTxn({
6695
- queryTarget,
6696
- args,
6697
- typeArgs
6698
- });
6699
- const results = queryResults?.results;
6700
- if (results && results[0]?.returnValues) {
6701
- const value = Uint8Array.from(results[0].returnValues[0][0]);
6702
- const type = results[0].returnValues[0][1];
6703
- assert2(type === "u64", "Result type is not u64");
6704
- return BigNumber7(bcs2.u64().parse(value)).shiftedBy(utils.getCoinDecimal(utils.parseCoinName(sCoinName))).toNumber();
6705
- }
6706
- return 0;
6707
- };
6708
- var getSCoinAmounts = async ({
6709
- utils
6710
- }, sCoinNames = [...SUPPORT_SCOIN], ownerAddress) => {
6711
- const owner = ownerAddress || utils.suiKit.currentAddress();
6712
- const sCoins2 = {};
6713
- await Promise.allSettled(
6714
- sCoinNames.map(async (sCoinName) => {
6715
- const sCoin = await getSCoinAmount({ utils }, sCoinName, owner);
6716
- sCoins2[sCoinName] = sCoin;
6717
- })
6718
- );
6719
- return sCoins2;
6720
- };
6721
- var getSCoinAmount = async ({
6722
- utils
6723
- }, sCoinName, ownerAddress) => {
6724
- const owner = ownerAddress || utils.suiKit.currentAddress();
6725
- const sCoinType = utils.parseSCoinType(sCoinName);
6726
- const amount = await utils.cache.queryGetCoinBalance({
6727
- owner,
6728
- coinType: sCoinType
6729
- });
6730
- return BigNumber7(amount).toNumber();
6731
- };
6732
- var isSupportStakeCoins = (value) => {
6733
- return SUPPORT_SCOIN.includes(value);
6734
- };
6735
- var checkAssetParams = (fromSCoin, toSCoin) => {
6736
- if (fromSCoin === toSCoin)
6737
- throw new Error("fromAsset and toAsset must be different");
6738
- if (!isSupportStakeCoins(fromSCoin))
6739
- throw new Error("fromAsset is not supported");
6740
- if (!isSupportStakeCoins(toSCoin)) {
6741
- throw new Error("toAsset is not supported");
6742
- }
6743
- };
6744
- var getSCoinSwapRate = async (query, fromSCoin, toSCoin, underlyingCoinPrice) => {
6745
- checkAssetParams(fromSCoin, toSCoin);
6746
- const fromCoinName = query.utils.parseCoinName(fromSCoin);
6747
- const toCoinName = query.utils.parseCoinName(toSCoin);
6748
- const marketPools = await Promise.all([
6749
- query.getMarketPool(fromCoinName, false),
6750
- query.getMarketPool(toCoinName, false)
6751
- ]);
6752
- if (marketPools.some((pool) => !pool))
6753
- throw new Error("Failed to fetch the lendings data");
6754
- if (marketPools.some((pool) => pool?.conversionRate === 0)) {
6755
- throw new Error("Conversion rate cannot be zero");
6756
- }
6757
- const ScoinAToARate = marketPools[0].conversionRate;
6758
- const BtoSCoinBRate = 1 / marketPools[1].conversionRate;
6759
- const calcAtoBRate = async () => {
6760
- const prices = await query.utils.getCoinPrices([fromCoinName, toCoinName]);
6761
- if (!prices[fromCoinName] || !prices[toCoinName]) {
6762
- throw new Error("Failed to fetch the coin prices");
6763
- }
6764
- if (prices[toCoinName] === 0) {
6765
- throw new Error("Price of toCoin cannot be zero");
6766
- }
6767
- return prices[fromCoinName] / prices[toCoinName];
6768
- };
6769
- const AtoBRate = underlyingCoinPrice ?? await calcAtoBRate();
6770
- return BigNumber7(ScoinAToARate).multipliedBy(AtoBRate).multipliedBy(BtoSCoinBRate).toNumber();
6771
- };
6772
-
6773
6851
  // src/models/scallopQuery.ts
6774
6852
  import { normalizeSuiAddress } from "@mysten/sui/utils";
6775
-
6776
- // src/queries/isolatedAsset.ts
6777
- import { z as zod4 } from "zod";
6778
- var isolatedAssetZod = zod4.object({
6779
- dataType: zod4.string(),
6780
- type: zod4.string(),
6781
- hasPublicTransfer: zod4.boolean(),
6782
- fields: zod4.object({
6783
- id: zod4.object({
6784
- id: zod4.string()
6785
- }),
6786
- name: zod4.object({
6787
- type: zod4.string()
6788
- }),
6789
- value: zod4.boolean()
6790
- })
6791
- });
6792
- var ISOLATED_ASSET_KEY = "0x6e641f0dca8aedab3101d047e96439178f16301bf0b57fe8745086ff1195eb3e::market_dynamic_keys::IsolatedAssetKey";
6793
- var getIsolatedAssets = async (address) => {
6794
- try {
6795
- const marketObject = address.get("core.market");
6796
- const isolatedAssets = [];
6797
- if (!marketObject)
6798
- return isolatedAssets;
6799
- let hasNextPage = false;
6800
- let nextCursor = null;
6801
- const isIsolatedDynamicField = (dynamicField) => {
6802
- return dynamicField.name.type === ISOLATED_ASSET_KEY;
6803
- };
6804
- do {
6805
- const response = await address.cache.queryGetDynamicFields({
6806
- parentId: marketObject,
6807
- cursor: nextCursor,
6808
- limit: 10
6809
- });
6810
- if (!response)
6811
- break;
6812
- const isolatedAssetCoinTypes = response.data.filter(isIsolatedDynamicField).map(({ name }) => `0x${name.value.type.name}`);
6813
- isolatedAssets.push(...isolatedAssetCoinTypes);
6814
- if (response && response.hasNextPage && response.nextCursor) {
6815
- hasNextPage = true;
6816
- nextCursor = response.nextCursor;
6817
- } else {
6818
- hasNextPage = false;
6819
- }
6820
- } while (hasNextPage);
6821
- return isolatedAssets;
6822
- } catch (e) {
6823
- console.error(e);
6824
- return [];
6825
- }
6826
- };
6827
- var isIsolatedAsset = async (utils, coinName) => {
6828
- try {
6829
- const marketObject = utils.address.get("core.market");
6830
- const cachedData = utils.address.cache.queryClient.getQueryData([
6831
- "getDynamicFields",
6832
- marketObject
6833
- ]);
6834
- if (cachedData) {
6835
- const coinType2 = utils.parseCoinType(coinName);
6836
- return cachedData.includes(coinType2);
6837
- }
6838
- const coinType = utils.parseCoinType(coinName).slice(2);
6839
- const object = await utils.cache.queryGetDynamicFieldObject({
6840
- parentId: marketObject,
6841
- name: {
6842
- type: ISOLATED_ASSET_KEY,
6843
- value: coinType
6844
- }
6845
- });
6846
- const parsedData = isolatedAssetZod.safeParse(object?.data?.content);
6847
- if (!parsedData.success)
6848
- return false;
6849
- return parsedData.data.fields.value;
6850
- } catch (e) {
6851
- console.error(e);
6852
- return false;
6853
- }
6854
- };
6855
-
6856
- // src/models/scallopQuery.ts
6857
6853
  var ScallopQuery = class {
6858
6854
  constructor(params, instance) {
6859
6855
  this.params = params;
@@ -8369,6 +8365,7 @@ export {
8369
8365
  PROTOCOL_OBJECT_ID,
8370
8366
  PYTH_ENDPOINTS,
8371
8367
  PYTH_FEED_IDS,
8368
+ RPC_PROVIDERS,
8372
8369
  SCA_COIN_TYPE,
8373
8370
  SDK_API_BASE_URL,
8374
8371
  SUPPORT_BORROW_INCENTIVE_POOLS,