@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.
- package/dist/builders/borrowIncentiveBuilder.d.ts +12 -0
- package/dist/builders/coreBuilder.d.ts +12 -0
- package/dist/builders/index.d.ts +12 -0
- package/dist/builders/loyaltyProgramBuilder.d.ts +12 -0
- package/dist/builders/oracle.d.ts +14 -0
- package/dist/builders/referralBuilder.d.ts +12 -0
- package/dist/builders/sCoinBuilder.d.ts +4 -0
- package/dist/builders/spoolBuilder.d.ts +12 -0
- package/dist/builders/vescaBuilder.d.ts +25 -0
- package/dist/constants/cache.d.ts +14 -0
- package/dist/constants/coinGecko.d.ts +2 -0
- package/dist/constants/common.d.ts +20 -0
- package/dist/constants/enum.d.ts +14 -0
- package/dist/constants/flashloan.d.ts +2 -0
- package/dist/constants/index.d.ts +12 -0
- package/dist/constants/poolAddress.d.ts +5 -0
- package/dist/constants/pyth.d.ts +5 -0
- package/dist/constants/queryKeys.d.ts +56 -0
- package/dist/constants/rpc.d.ts +1 -0
- package/dist/constants/testAddress.d.ts +2 -0
- package/dist/constants/tokenBucket.d.ts +2 -0
- package/dist/constants/vesca.d.ts +5 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1462 -1464
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1461 -1464
- package/dist/index.mjs.map +1 -1
- package/dist/models/index.d.ts +8 -0
- package/dist/models/scallop.d.ts +74 -0
- package/dist/models/scallopAddress.d.ts +150 -0
- package/dist/models/scallopBuilder.d.ts +89 -0
- package/dist/models/scallopCache.d.ts +74 -0
- package/dist/models/scallopClient.d.ts +321 -0
- package/dist/models/scallopIndexer.d.ts +89 -0
- package/dist/models/scallopQuery.d.ts +489 -0
- package/dist/models/scallopUtils.d.ts +227 -0
- package/dist/models/suiKit.d.ts +2 -0
- package/dist/queries/borrowIncentiveQuery.d.ts +61 -0
- package/dist/queries/coreQuery.d.ts +167 -0
- package/dist/queries/index.d.ts +11 -0
- package/dist/queries/isolatedAssetQuery.d.ts +14 -0
- package/dist/queries/loyaltyProgramQuery.d.ts +10 -0
- package/dist/queries/portfolioQuery.d.ts +73 -0
- package/dist/queries/priceQuery.d.ts +16 -0
- package/dist/queries/referralQuery.d.ts +7 -0
- package/dist/queries/sCoinQuery.d.ts +41 -0
- package/dist/queries/spoolQuery.d.ts +70 -0
- package/dist/queries/supplyLimitQuery.d.ts +9 -0
- package/dist/queries/vescaQuery.d.ts +36 -0
- package/dist/test.d.ts +0 -0
- package/dist/types/address.d.ts +107 -0
- package/dist/types/builder/borrowIncentive.d.ts +35 -0
- package/dist/types/builder/core.d.ts +56 -0
- package/dist/types/builder/index.d.ts +25 -0
- package/dist/types/builder/loyaltyProgram.d.ts +23 -0
- package/dist/types/builder/referral.d.ts +30 -0
- package/dist/types/builder/sCoin.d.ts +37 -0
- package/dist/types/builder/spool.d.ts +29 -0
- package/dist/types/builder/vesca.d.ts +51 -0
- package/dist/types/constant/common.d.ts +24 -0
- package/dist/types/constant/enum.d.ts +48 -0
- package/dist/types/constant/index.d.ts +2 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/model.d.ts +54 -0
- package/dist/types/query/borrowIncentive.d.ts +124 -0
- package/dist/types/query/core.d.ts +361 -0
- package/dist/types/query/index.d.ts +7 -0
- package/dist/types/query/loyaltyProgram.d.ts +5 -0
- package/dist/types/query/portfolio.d.ts +115 -0
- package/dist/types/query/sCoin.d.ts +1 -0
- package/dist/types/query/spool.d.ts +122 -0
- package/dist/types/query/vesca.d.ts +26 -0
- package/dist/types/utils.d.ts +21 -0
- package/dist/utils/builder.d.ts +15 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/indexer.d.ts +17 -0
- package/dist/utils/query.d.ts +62 -0
- package/dist/utils/tokenBucket.d.ts +11 -0
- package/dist/utils/util.d.ts +26 -0
- package/package.json +2 -2
- package/src/builders/borrowIncentiveBuilder.ts +8 -8
- package/src/builders/coreBuilder.ts +5 -5
- package/src/builders/index.ts +2 -2
- package/src/builders/oracle.ts +4 -4
- package/src/builders/referralBuilder.ts +1 -1
- package/src/builders/spoolBuilder.ts +6 -6
- package/src/builders/vescaBuilder.ts +4 -4
- package/src/constants/coinGecko.ts +1 -1
- package/src/constants/enum.ts +1 -1
- package/src/constants/index.ts +1 -0
- package/src/models/scallop.ts +5 -5
- package/src/models/scallopAddress.ts +9 -6
- package/src/models/scallopBuilder.ts +4 -5
- package/src/models/scallopCache.ts +4 -4
- package/src/models/scallopClient.ts +4 -4
- package/src/models/scallopIndexer.ts +3 -4
- package/src/models/scallopQuery.ts +13 -6
- package/src/models/scallopUtils.ts +11 -8
- package/src/models/suiKit.ts +1 -1
- package/src/queries/borrowIncentiveQuery.ts +5 -5
- package/src/queries/coreQuery.ts +5 -5
- package/src/queries/index.ts +8 -5
- package/src/queries/portfolioQuery.ts +4 -4
- package/src/queries/priceQuery.ts +2 -2
- package/src/queries/spoolQuery.ts +5 -5
- package/src/queries/vescaQuery.ts +2 -2
- package/src/test.ts +30 -0
- package/src/types/address.ts +1 -1
- package/src/types/builder/borrowIncentive.ts +3 -3
- package/src/types/builder/core.ts +3 -3
- package/src/types/builder/index.ts +5 -4
- package/src/types/builder/referral.ts +1 -1
- package/src/types/builder/sCoin.ts +1 -1
- package/src/types/builder/spool.ts +2 -2
- package/src/types/constant/common.ts +1 -1
- package/src/types/model.ts +2 -2
- package/src/types/query/borrowIncentive.ts +2 -2
- package/src/types/query/core.ts +1 -1
- package/src/types/query/portfolio.ts +2 -2
- package/src/types/query/spool.ts +1 -1
- package/src/utils/builder.ts +1 -1
- package/src/utils/index.ts +2 -2
- package/src/utils/query.ts +3 -3
- package/src/utils/tokenBucket.ts +1 -1
- package/src/utils/util.ts +4 -4
- /package/src/queries/{isolatedAsset.ts → isolatedAssetQuery.ts} +0 -0
- /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/
|
|
2389
|
+
// src/queries/borrowIncentiveQuery.ts
|
|
2373
2390
|
import { normalizeStructTag as normalizeStructTag3 } from "@mysten/sui/utils";
|
|
2374
2391
|
import BigNumber2 from "bignumber.js";
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
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
|
|
2406
|
-
|
|
2407
|
-
return null;
|
|
2408
|
-
return parsedData.data.fields.value;
|
|
2401
|
+
const borrowIncentivePoolsQueryData = queryResult?.events[0].parsedJson;
|
|
2402
|
+
return borrowIncentivePoolsQueryData;
|
|
2409
2403
|
};
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
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
|
|
2418
|
-
const
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
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
|
|
2436
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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/
|
|
3043
|
-
import {
|
|
3044
|
-
var
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
)
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
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
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
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
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
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
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
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
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
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
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
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
|
-
}
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
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
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
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
|
|
3232
|
-
(
|
|
3233
|
-
reversedTypes[value] = key;
|
|
3234
|
-
return reversedTypes;
|
|
3235
|
-
},
|
|
3236
|
-
{}
|
|
3378
|
+
const stakeMarketCoinNames = marketCoinNames.filter(
|
|
3379
|
+
(marketCoinName) => SUPPORT_SPOOLS.includes(marketCoinName)
|
|
3237
3380
|
);
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
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
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
const
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
const
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
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
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
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
|
-
|
|
3332
|
-
|
|
3429
|
+
marketPool,
|
|
3430
|
+
coinPrices: {
|
|
3431
|
+
[poolCoinName]: coinPrice
|
|
3432
|
+
}
|
|
3333
3433
|
}
|
|
3334
|
-
);
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
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
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
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
|
-
|
|
3399
|
-
|
|
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
|
-
|
|
3497
|
-
|
|
3498
|
-
const
|
|
3499
|
-
const
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
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
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
const
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
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
|
-
|
|
3562
|
-
|
|
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
|
|
3565
|
-
|
|
3618
|
+
const requiredCollateralValue2 = depositedValue.multipliedBy(
|
|
3619
|
+
marketCollateral.liquidationFactor
|
|
3566
3620
|
);
|
|
3567
|
-
const
|
|
3568
|
-
|
|
3621
|
+
const poolSizeAmount = BigNumber5(marketCollateral.maxDepositAmount).minus(
|
|
3622
|
+
marketCollateral.depositAmount
|
|
3569
3623
|
);
|
|
3570
|
-
|
|
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
|
-
|
|
3584
|
-
|
|
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
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
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
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
)
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
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
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
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
|
-
|
|
3731
|
-
|
|
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
|
|
3734
|
-
const
|
|
3735
|
-
|
|
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
|
-
|
|
3741
|
-
|
|
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
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
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
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
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
|
-
|
|
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
|
|
3829
|
-
const
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
const
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
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
|
-
|
|
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
|
|
3872
|
-
|
|
3921
|
+
const priceMagnitude = Number(
|
|
3922
|
+
fields.price_info.fields.price_feed.fields.price.fields.price.fields.magnitude
|
|
3873
3923
|
);
|
|
3874
|
-
const
|
|
3875
|
-
|
|
3924
|
+
const priceNegative = Number(
|
|
3925
|
+
fields.price_info.fields.price_feed.fields.price.fields.price.fields.negative
|
|
3876
3926
|
);
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
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
|
|
3882
|
-
|
|
4110
|
+
const rewardCoinName = query.utils.getSpoolRewardCoinName(
|
|
4111
|
+
spool.marketCoinName
|
|
3883
4112
|
);
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
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
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
coinDecimal,
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
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
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
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
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
);
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
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
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
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
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
const
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
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
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
const
|
|
4090
|
-
if (
|
|
4091
|
-
const
|
|
4092
|
-
|
|
4093
|
-
)
|
|
4094
|
-
|
|
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
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
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
|
|
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
|
|
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
|
|
4159
|
-
import
|
|
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 =
|
|
4208
|
-
objectId:
|
|
4209
|
-
digest:
|
|
4210
|
-
version:
|
|
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 =
|
|
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:
|
|
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
|
-
|
|
4297
|
-
return
|
|
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 =
|
|
4566
|
+
const totalLockedSca = BigNumber7(
|
|
4310
4567
|
treasuryFields.unlock_schedule.fields.locked_sca_amount
|
|
4311
4568
|
).shiftedBy(-9).toNumber();
|
|
4312
|
-
const totalVeSca =
|
|
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,
|