@scallop-io/sui-scallop-sdk 0.46.55 → 0.46.56
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/constants/common.d.ts +1 -1
- package/dist/constants/pyth.d.ts +1 -1
- package/dist/index.js +1752 -1602
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1720 -1570
- package/dist/index.mjs.map +1 -1
- package/dist/models/scallop.d.ts +1 -1
- package/dist/models/scallopAddress.d.ts +4 -4
- package/dist/models/scallopBuilder.d.ts +2 -2
- package/dist/models/scallopCache.d.ts +2 -2
- package/dist/models/scallopClient.d.ts +7 -2
- package/dist/models/scallopIndexer.d.ts +3 -3
- package/dist/models/scallopPrice.d.ts +0 -0
- package/dist/models/scallopQuery.d.ts +10 -4
- package/dist/models/scallopUtils.d.ts +8 -7
- package/dist/queries/borrowIncentiveQuery.d.ts +10 -4
- package/dist/queries/coreQuery.d.ts +8 -4
- package/dist/queries/priceQuery.d.ts +7 -3
- package/dist/queries/referralQuery.d.ts +2 -2
- package/dist/queries/sCoinQuery.d.ts +18 -4
- package/dist/queries/spoolQuery.d.ts +10 -4
- package/dist/queries/vescaQuery.d.ts +7 -5
- package/dist/types/builder/vesca.d.ts +2 -1
- package/dist/types/model.d.ts +27 -12
- package/dist/types/query/core.d.ts +1 -0
- package/package.json +1 -1
- package/src/builders/borrowIncentiveBuilder.ts +19 -21
- package/src/builders/coreBuilder.ts +10 -8
- package/src/builders/spoolBuilder.ts +2 -2
- package/src/builders/vescaBuilder.ts +12 -4
- package/src/constants/common.ts +2 -0
- package/src/constants/enum.ts +4 -0
- package/src/constants/pyth.ts +2 -2
- package/src/models/scallop.ts +14 -20
- package/src/models/scallopAddress.ts +15 -5
- package/src/models/scallopBuilder.ts +29 -25
- package/src/models/scallopCache.ts +2 -2
- package/src/models/scallopClient.ts +91 -32
- package/src/models/scallopIndexer.ts +15 -8
- package/src/models/scallopPrice.ts +0 -0
- package/src/models/scallopQuery.ts +47 -25
- package/src/models/scallopUtils.ts +75 -74
- package/src/queries/borrowIncentiveQuery.ts +40 -29
- package/src/queries/coreQuery.ts +38 -24
- package/src/queries/portfolioQuery.ts +1 -2
- package/src/queries/priceQuery.ts +20 -9
- package/src/queries/referralQuery.ts +4 -4
- package/src/queries/sCoinQuery.ts +95 -17
- package/src/queries/spoolQuery.ts +26 -14
- package/src/queries/vescaQuery.ts +32 -26
- package/src/types/builder/vesca.ts +8 -1
- package/src/types/model.ts +40 -11
- package/src/types/query/core.ts +1 -0
package/src/queries/coreQuery.ts
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
} from '../utils';
|
|
16
16
|
import type { SuiObjectResponse, SuiObjectData } from '@mysten/sui.js/client';
|
|
17
17
|
import type { SuiAddressArg } from '@scallop-io/sui-kit';
|
|
18
|
-
import type { ScallopQuery } from '../models';
|
|
18
|
+
import type { ScallopAddress, ScallopCache, ScallopQuery } from '../models';
|
|
19
19
|
import {
|
|
20
20
|
Market,
|
|
21
21
|
MarketPools,
|
|
@@ -129,6 +129,9 @@ export const queryMarket = async (
|
|
|
129
129
|
symbol: query.utils.parseSymbol(poolCoinName),
|
|
130
130
|
coinType: coinType,
|
|
131
131
|
marketCoinType: query.utils.parseMarketCoinType(poolCoinName),
|
|
132
|
+
sCoinType: query.utils.parseSCoinType(
|
|
133
|
+
query.utils.parseMarketCoinName(poolCoinName)
|
|
134
|
+
),
|
|
132
135
|
coinWrappedType: query.utils.getCoinWrappedType(poolCoinName),
|
|
133
136
|
coinDecimal: query.utils.getCoinDecimal(poolCoinName),
|
|
134
137
|
coinPrice: coinPrice,
|
|
@@ -453,6 +456,9 @@ export const getMarketPool = async (
|
|
|
453
456
|
symbol: query.utils.parseSymbol(poolCoinName),
|
|
454
457
|
coinType: query.utils.parseCoinType(poolCoinName),
|
|
455
458
|
marketCoinType: query.utils.parseMarketCoinType(poolCoinName),
|
|
459
|
+
sCoinType: query.utils.parseSCoinType(
|
|
460
|
+
query.utils.parseMarketCoinName(poolCoinName)
|
|
461
|
+
),
|
|
456
462
|
coinWrappedType: query.utils.getCoinWrappedType(poolCoinName),
|
|
457
463
|
coinDecimal: query.utils.getCoinDecimal(poolCoinName),
|
|
458
464
|
coinPrice: coinPrice ?? 0,
|
|
@@ -683,24 +689,29 @@ export const getMarketCollateral = async (
|
|
|
683
689
|
* @return Owned obligations.
|
|
684
690
|
*/
|
|
685
691
|
export const getObligations = async (
|
|
686
|
-
|
|
687
|
-
|
|
692
|
+
{
|
|
693
|
+
address,
|
|
694
|
+
}: {
|
|
695
|
+
address: ScallopAddress;
|
|
696
|
+
},
|
|
697
|
+
ownerAddress: string
|
|
688
698
|
) => {
|
|
689
|
-
const owner = ownerAddress
|
|
690
|
-
const protocolObjectId =
|
|
691
|
-
query.address.get('core.object') || PROTOCOL_OBJECT_ID;
|
|
699
|
+
const owner = ownerAddress;
|
|
700
|
+
const protocolObjectId = address.get('core.object') || PROTOCOL_OBJECT_ID;
|
|
692
701
|
const keyObjectsResponse: SuiObjectResponse[] = [];
|
|
693
702
|
let hasNextPage = false;
|
|
694
703
|
let nextCursor: string | null | undefined = null;
|
|
695
704
|
do {
|
|
696
|
-
const paginatedKeyObjectsResponse =
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
705
|
+
const paginatedKeyObjectsResponse =
|
|
706
|
+
await address.cache.queryGetOwnedObjects({
|
|
707
|
+
owner,
|
|
708
|
+
filter: {
|
|
709
|
+
StructType: `${protocolObjectId}::obligation::ObligationKey`,
|
|
710
|
+
},
|
|
711
|
+
cursor: nextCursor,
|
|
712
|
+
});
|
|
713
|
+
|
|
714
|
+
if (!paginatedKeyObjectsResponse) break;
|
|
704
715
|
|
|
705
716
|
keyObjectsResponse.push(...paginatedKeyObjectsResponse.data);
|
|
706
717
|
if (
|
|
@@ -717,7 +728,7 @@ export const getObligations = async (
|
|
|
717
728
|
const keyObjectIds: string[] = keyObjectsResponse
|
|
718
729
|
.map((ref: any) => ref?.data?.objectId)
|
|
719
730
|
.filter((id: any) => id !== undefined);
|
|
720
|
-
const keyObjects = await
|
|
731
|
+
const keyObjects = await address.cache.queryGetObjects(keyObjectIds);
|
|
721
732
|
|
|
722
733
|
const obligations: Obligation[] = [];
|
|
723
734
|
await Promise.allSettled(
|
|
@@ -726,7 +737,7 @@ export const getObligations = async (
|
|
|
726
737
|
if (keyObject.content && 'fields' in keyObject.content) {
|
|
727
738
|
const fields = keyObject.content.fields as any;
|
|
728
739
|
const obligationId = String(fields.ownership.fields.of);
|
|
729
|
-
const locked = await getObligationLocked(
|
|
740
|
+
const locked = await getObligationLocked(address.cache, obligationId);
|
|
730
741
|
obligations.push({ id: obligationId, keyId, locked });
|
|
731
742
|
}
|
|
732
743
|
})
|
|
@@ -743,13 +754,12 @@ export const getObligations = async (
|
|
|
743
754
|
* @return Obligation locked status.
|
|
744
755
|
*/
|
|
745
756
|
export const getObligationLocked = async (
|
|
746
|
-
|
|
757
|
+
cache: ScallopCache,
|
|
747
758
|
obligationId: string
|
|
748
759
|
) => {
|
|
749
|
-
const obligationObjectResponse = await
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
);
|
|
760
|
+
const obligationObjectResponse = await cache.queryGetObject(obligationId, {
|
|
761
|
+
showContent: true,
|
|
762
|
+
});
|
|
753
763
|
let obligationLocked = false;
|
|
754
764
|
if (
|
|
755
765
|
obligationObjectResponse?.data &&
|
|
@@ -775,16 +785,20 @@ export const getObligationLocked = async (
|
|
|
775
785
|
* @return Obligation data.
|
|
776
786
|
*/
|
|
777
787
|
export const queryObligation = async (
|
|
778
|
-
|
|
788
|
+
{
|
|
789
|
+
address,
|
|
790
|
+
}: {
|
|
791
|
+
address: ScallopAddress;
|
|
792
|
+
},
|
|
779
793
|
obligationId: SuiAddressArg
|
|
780
794
|
) => {
|
|
781
|
-
const packageId =
|
|
795
|
+
const packageId = address.get('core.packages.query.id');
|
|
782
796
|
const queryTarget = `${packageId}::obligation_query::obligation_data`;
|
|
783
797
|
const args = [obligationId];
|
|
784
798
|
|
|
785
799
|
// const txBlock = new SuiKitTxBlock();
|
|
786
800
|
// txBlock.moveCall(queryTarget, args);
|
|
787
|
-
const queryResult = await
|
|
801
|
+
const queryResult = await address.cache.queryInspectTxn(
|
|
788
802
|
{ queryTarget, args }
|
|
789
803
|
// txBlock
|
|
790
804
|
);
|
|
@@ -38,11 +38,10 @@ import type {
|
|
|
38
38
|
*/
|
|
39
39
|
export const getLendings = async (
|
|
40
40
|
query: ScallopQuery,
|
|
41
|
-
poolCoinNames
|
|
41
|
+
poolCoinNames: SupportPoolCoins[] = [...SUPPORT_POOLS],
|
|
42
42
|
ownerAddress?: string,
|
|
43
43
|
indexer: boolean = false
|
|
44
44
|
) => {
|
|
45
|
-
poolCoinNames = poolCoinNames || [...SUPPORT_POOLS];
|
|
46
45
|
const marketCoinNames = poolCoinNames.map((poolCoinName) =>
|
|
47
46
|
query.utils.parseMarketCoinName(poolCoinName)
|
|
48
47
|
);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SuiObjectData } from '@mysten/sui.js/client';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ScallopAddress } from '../models';
|
|
3
3
|
import type { SupportAssetCoins } from '../types';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -10,17 +10,24 @@ import type { SupportAssetCoins } from '../types';
|
|
|
10
10
|
* @return Asset coin price.
|
|
11
11
|
*/
|
|
12
12
|
export const getPythPrice = async (
|
|
13
|
-
|
|
13
|
+
{
|
|
14
|
+
address,
|
|
15
|
+
}: {
|
|
16
|
+
address: ScallopAddress;
|
|
17
|
+
},
|
|
14
18
|
assetCoinName: SupportAssetCoins,
|
|
15
19
|
priceFeedObject?: SuiObjectData | null
|
|
16
20
|
) => {
|
|
17
|
-
const pythFeedObjectId =
|
|
21
|
+
const pythFeedObjectId = address.get(
|
|
18
22
|
`core.coins.${assetCoinName}.oracle.pyth.feedObject`
|
|
19
23
|
);
|
|
20
24
|
priceFeedObject =
|
|
21
25
|
priceFeedObject ||
|
|
22
|
-
(
|
|
23
|
-
|
|
26
|
+
(
|
|
27
|
+
await address.cache.queryGetObject(pythFeedObjectId, {
|
|
28
|
+
showContent: true,
|
|
29
|
+
})
|
|
30
|
+
)?.data;
|
|
24
31
|
|
|
25
32
|
if (priceFeedObject) {
|
|
26
33
|
const priceFeedPoolObject = priceFeedObject;
|
|
@@ -58,12 +65,16 @@ export const getPythPrice = async (
|
|
|
58
65
|
};
|
|
59
66
|
|
|
60
67
|
export const getPythPrices = async (
|
|
61
|
-
|
|
68
|
+
{
|
|
69
|
+
address,
|
|
70
|
+
}: {
|
|
71
|
+
address: ScallopAddress;
|
|
72
|
+
},
|
|
62
73
|
assetCoinNames: SupportAssetCoins[]
|
|
63
74
|
) => {
|
|
64
75
|
const pythPriceFeedIds = assetCoinNames.reduce(
|
|
65
76
|
(prev, assetCoinName) => {
|
|
66
|
-
const pythPriceFeed =
|
|
77
|
+
const pythPriceFeed = address.get(
|
|
67
78
|
`core.coins.${assetCoinName}.oracle.pyth.feedObject`
|
|
68
79
|
);
|
|
69
80
|
if (!prev[pythPriceFeed]) {
|
|
@@ -77,7 +88,7 @@ export const getPythPrices = async (
|
|
|
77
88
|
);
|
|
78
89
|
|
|
79
90
|
// Fetch multiple objects at once to save rpc calls
|
|
80
|
-
const priceFeedObjects = await
|
|
91
|
+
const priceFeedObjects = await address.cache.queryGetObjects(
|
|
81
92
|
Object.keys(pythPriceFeedIds),
|
|
82
93
|
{ showContent: true }
|
|
83
94
|
);
|
|
@@ -98,7 +109,7 @@ export const getPythPrices = async (
|
|
|
98
109
|
async ([assetCoinName, priceFeedObject]) => ({
|
|
99
110
|
coinName: assetCoinName,
|
|
100
111
|
price: await getPythPrice(
|
|
101
|
-
|
|
112
|
+
{ address },
|
|
102
113
|
assetCoinName as SupportAssetCoins,
|
|
103
114
|
priceFeedObject
|
|
104
115
|
),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ScallopAddress } from 'src/models';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Query the veScaKeyId from the referral bindings table using the borrower address
|
|
@@ -6,12 +6,12 @@ import { ScallopQuery } from 'src/models';
|
|
|
6
6
|
* @returns
|
|
7
7
|
*/
|
|
8
8
|
export const queryVeScaKeyIdFromReferralBindings = async (
|
|
9
|
-
|
|
9
|
+
address: ScallopAddress,
|
|
10
10
|
refereeAddress: string
|
|
11
11
|
): Promise<string | null> => {
|
|
12
|
-
const referralBindingTableId =
|
|
12
|
+
const referralBindingTableId = address.get('referral.bindingTableId');
|
|
13
13
|
|
|
14
|
-
const referralBindResponse = await
|
|
14
|
+
const referralBindResponse = await address.cache.queryGetDynamicFieldObject({
|
|
15
15
|
parentId: referralBindingTableId,
|
|
16
16
|
name: {
|
|
17
17
|
type: 'address',
|
|
@@ -2,7 +2,7 @@ import { bcs } from '@mysten/sui.js/bcs';
|
|
|
2
2
|
import assert from 'assert';
|
|
3
3
|
import BigNumber from 'bignumber.js';
|
|
4
4
|
import { SUPPORT_SCOIN } from 'src/constants';
|
|
5
|
-
import { ScallopQuery } from 'src/models';
|
|
5
|
+
import { ScallopQuery, ScallopUtils } from 'src/models';
|
|
6
6
|
import { OptionalKeys, SupportSCoin, sCoinBalance } from 'src/types';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -12,18 +12,22 @@ import { OptionalKeys, SupportSCoin, sCoinBalance } from 'src/types';
|
|
|
12
12
|
* @returns `number`
|
|
13
13
|
*/
|
|
14
14
|
export const getSCoinTotalSupply = async (
|
|
15
|
-
|
|
15
|
+
{
|
|
16
|
+
utils,
|
|
17
|
+
}: {
|
|
18
|
+
utils: ScallopUtils;
|
|
19
|
+
},
|
|
16
20
|
sCoinName: SupportSCoin
|
|
17
21
|
): Promise<sCoinBalance> => {
|
|
18
|
-
const sCoinPkgId =
|
|
22
|
+
const sCoinPkgId = utils.address.get('scoin.id');
|
|
19
23
|
// get treasury
|
|
20
|
-
const args = [
|
|
24
|
+
const args = [utils.getSCoinTreasury(sCoinName)];
|
|
21
25
|
const typeArgs = [
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
utils.parseSCoinType(sCoinName),
|
|
27
|
+
utils.parseUnderlyingSCoinType(sCoinName),
|
|
24
28
|
];
|
|
25
29
|
const queryTarget = `${sCoinPkgId}::s_coin_converter::total_supply`;
|
|
26
|
-
const queryResults = await
|
|
30
|
+
const queryResults = await utils.cache.queryInspectTxn({
|
|
27
31
|
queryTarget,
|
|
28
32
|
args,
|
|
29
33
|
typeArgs,
|
|
@@ -35,9 +39,7 @@ export const getSCoinTotalSupply = async (
|
|
|
35
39
|
assert(type === 'u64', 'Result type is not u64');
|
|
36
40
|
|
|
37
41
|
return BigNumber(bcs.de(type, value))
|
|
38
|
-
.shiftedBy(
|
|
39
|
-
query.utils.getCoinDecimal(query.utils.parseCoinName(sCoinName))
|
|
40
|
-
)
|
|
42
|
+
.shiftedBy(utils.getCoinDecimal(utils.parseCoinName(sCoinName)))
|
|
41
43
|
.toNumber();
|
|
42
44
|
}
|
|
43
45
|
|
|
@@ -53,17 +55,21 @@ export const getSCoinTotalSupply = async (
|
|
|
53
55
|
* @return All owned sCoins amount.
|
|
54
56
|
*/
|
|
55
57
|
export const getSCoinAmounts = async (
|
|
56
|
-
|
|
58
|
+
{
|
|
59
|
+
utils,
|
|
60
|
+
}: {
|
|
61
|
+
utils: ScallopUtils;
|
|
62
|
+
},
|
|
57
63
|
sCoinNames?: SupportSCoin[],
|
|
58
64
|
ownerAddress?: string
|
|
59
65
|
) => {
|
|
60
66
|
sCoinNames = sCoinNames || [...SUPPORT_SCOIN];
|
|
61
|
-
const owner = ownerAddress ||
|
|
67
|
+
const owner = ownerAddress || utils.suiKit.currentAddress();
|
|
62
68
|
const sCoins = {} as OptionalKeys<Record<SupportSCoin, number>>;
|
|
63
69
|
|
|
64
70
|
await Promise.allSettled(
|
|
65
71
|
sCoinNames.map(async (sCoinName) => {
|
|
66
|
-
const sCoin = await getSCoinAmount(
|
|
72
|
+
const sCoin = await getSCoinAmount({ utils }, sCoinName, owner);
|
|
67
73
|
sCoins[sCoinName] = sCoin;
|
|
68
74
|
})
|
|
69
75
|
);
|
|
@@ -80,15 +86,87 @@ export const getSCoinAmounts = async (
|
|
|
80
86
|
* @return Owned sCoin amount.
|
|
81
87
|
*/
|
|
82
88
|
export const getSCoinAmount = async (
|
|
83
|
-
|
|
89
|
+
{
|
|
90
|
+
utils,
|
|
91
|
+
}: {
|
|
92
|
+
utils: ScallopUtils;
|
|
93
|
+
},
|
|
84
94
|
sCoinName: SupportSCoin,
|
|
85
95
|
ownerAddress?: string
|
|
86
96
|
) => {
|
|
87
|
-
const owner = ownerAddress ||
|
|
88
|
-
const sCoinType =
|
|
89
|
-
const amount = await
|
|
97
|
+
const owner = ownerAddress || utils.suiKit.currentAddress();
|
|
98
|
+
const sCoinType = utils.parseSCoinType(sCoinName);
|
|
99
|
+
const amount = await utils.cache.queryGetCoinBalance({
|
|
90
100
|
owner,
|
|
91
101
|
coinType: sCoinType,
|
|
92
102
|
});
|
|
93
103
|
return BigNumber(amount).toNumber();
|
|
94
104
|
};
|
|
105
|
+
|
|
106
|
+
const isSupportStakeCoins = (value: string): value is SupportSCoin => {
|
|
107
|
+
return SUPPORT_SCOIN.includes(value as SupportSCoin);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const checkAssetParams = (fromSCoin: SupportSCoin, toSCoin: SupportSCoin) => {
|
|
111
|
+
if (fromSCoin === toSCoin)
|
|
112
|
+
throw new Error('fromAsset and toAsset must be different');
|
|
113
|
+
|
|
114
|
+
if (!isSupportStakeCoins(fromSCoin))
|
|
115
|
+
throw new Error('fromAsset is not supported');
|
|
116
|
+
|
|
117
|
+
if (!isSupportStakeCoins(toSCoin)) {
|
|
118
|
+
throw new Error('toAsset is not supported');
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
/* ==================== Get Swap Rate ==================== */
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Get swap rate from sCoin A to sCoin B.
|
|
126
|
+
* @param fromSCoin
|
|
127
|
+
* @param toSCoin
|
|
128
|
+
* @param underlyingCoinPrice - The price of the underlying coin. For example, if fromSCoin is sSUI and toSCoin is sUSDC, then underlyingCoinPrice represents the price of 1 SUI in USDC.
|
|
129
|
+
* @returns number
|
|
130
|
+
*/
|
|
131
|
+
export const getSCoinSwapRate = async (
|
|
132
|
+
query: ScallopQuery,
|
|
133
|
+
fromSCoin: SupportSCoin,
|
|
134
|
+
toSCoin: SupportSCoin,
|
|
135
|
+
underlyingCoinPrice?: number
|
|
136
|
+
) => {
|
|
137
|
+
checkAssetParams(fromSCoin, toSCoin);
|
|
138
|
+
const fromCoinName = query.utils.parseCoinName(fromSCoin);
|
|
139
|
+
const toCoinName = query.utils.parseCoinName(toSCoin);
|
|
140
|
+
|
|
141
|
+
// Get lending data for both sCoin A and sCoin B
|
|
142
|
+
const marketPools = await Promise.all([
|
|
143
|
+
query.getMarketPool(fromCoinName, false),
|
|
144
|
+
query.getMarketPool(toCoinName, false),
|
|
145
|
+
]);
|
|
146
|
+
if (marketPools.some((pool) => !pool))
|
|
147
|
+
throw new Error('Failed to fetch the lendings data');
|
|
148
|
+
|
|
149
|
+
if (marketPools.some((pool) => pool?.conversionRate === 0)) {
|
|
150
|
+
throw new Error('Conversion rate cannot be zero');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const ScoinAToARate = marketPools[0]!.conversionRate;
|
|
154
|
+
const BtoSCoinBRate = 1 / marketPools[1]!.conversionRate;
|
|
155
|
+
|
|
156
|
+
const calcAtoBRate = async () => {
|
|
157
|
+
const prices = await query.utils.getCoinPrices([fromCoinName, toCoinName]);
|
|
158
|
+
if (!prices[fromCoinName] || !prices[toCoinName]) {
|
|
159
|
+
throw new Error('Failed to fetch the coin prices');
|
|
160
|
+
}
|
|
161
|
+
if (prices[toCoinName] === 0) {
|
|
162
|
+
throw new Error('Price of toCoin cannot be zero');
|
|
163
|
+
}
|
|
164
|
+
return prices[fromCoinName]! / prices[toCoinName]!;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const AtoBRate = underlyingCoinPrice ?? (await calcAtoBRate());
|
|
168
|
+
return BigNumber(ScoinAToARate)
|
|
169
|
+
.multipliedBy(AtoBRate)
|
|
170
|
+
.multipliedBy(BtoSCoinBRate)
|
|
171
|
+
.toNumber();
|
|
172
|
+
};
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
isMarketCoin,
|
|
9
9
|
} from '../utils';
|
|
10
10
|
import type { SuiObjectResponse } from '@mysten/sui.js/client';
|
|
11
|
-
import type { ScallopQuery } from '../models';
|
|
11
|
+
import type { ScallopQuery, ScallopUtils } from '../models';
|
|
12
12
|
import type {
|
|
13
13
|
MarketPool,
|
|
14
14
|
Spools,
|
|
@@ -231,18 +231,22 @@ export const getSpool = async (
|
|
|
231
231
|
* @return Stake accounts.
|
|
232
232
|
*/
|
|
233
233
|
export const getStakeAccounts = async (
|
|
234
|
-
|
|
234
|
+
{
|
|
235
|
+
utils,
|
|
236
|
+
}: {
|
|
237
|
+
utils: ScallopUtils;
|
|
238
|
+
},
|
|
235
239
|
ownerAddress?: string
|
|
236
240
|
) => {
|
|
237
|
-
const owner = ownerAddress ||
|
|
238
|
-
const spoolObjectId =
|
|
241
|
+
const owner = ownerAddress || utils.suiKit.currentAddress();
|
|
242
|
+
const spoolObjectId = utils.address.get('spool.object');
|
|
239
243
|
const stakeAccountType = `${spoolObjectId}::spool_account::SpoolAccount`;
|
|
240
244
|
const stakeObjectsResponse: SuiObjectResponse[] = [];
|
|
241
245
|
let hasNextPage = false;
|
|
242
246
|
let nextCursor: string | null | undefined = null;
|
|
243
247
|
do {
|
|
244
248
|
const paginatedStakeObjectsResponse =
|
|
245
|
-
await
|
|
249
|
+
await utils.cache.queryGetOwnedObjects({
|
|
246
250
|
owner,
|
|
247
251
|
filter: { StructType: stakeAccountType },
|
|
248
252
|
options: {
|
|
@@ -281,8 +285,8 @@ export const getStakeAccounts = async (
|
|
|
281
285
|
Object.keys(stakeAccounts).reduce(
|
|
282
286
|
(types, stakeMarketCoinName) => {
|
|
283
287
|
const stakeCoinName =
|
|
284
|
-
|
|
285
|
-
const marketCoinType =
|
|
288
|
+
utils.parseCoinName<SupportStakeCoins>(stakeMarketCoinName);
|
|
289
|
+
const marketCoinType = utils.parseMarketCoinType(stakeCoinName);
|
|
286
290
|
|
|
287
291
|
types[
|
|
288
292
|
stakeMarketCoinName as SupportStakeMarketCoins
|
|
@@ -295,7 +299,7 @@ export const getStakeAccounts = async (
|
|
|
295
299
|
const stakeObjectIds: string[] = stakeObjectsResponse
|
|
296
300
|
.map((ref: any) => ref?.data?.objectId)
|
|
297
301
|
.filter((id: any) => id !== undefined);
|
|
298
|
-
const stakeObjects = await
|
|
302
|
+
const stakeObjects = await utils.cache.queryGetObjects(stakeObjectIds);
|
|
299
303
|
for (const stakeObject of stakeObjects) {
|
|
300
304
|
const id = stakeObject.objectId;
|
|
301
305
|
const type = stakeObject.type!;
|
|
@@ -413,12 +417,16 @@ export const getStakeAccounts = async (
|
|
|
413
417
|
* @return Stake pool data.
|
|
414
418
|
*/
|
|
415
419
|
export const getStakePool = async (
|
|
416
|
-
|
|
420
|
+
{
|
|
421
|
+
utils,
|
|
422
|
+
}: {
|
|
423
|
+
utils: ScallopUtils;
|
|
424
|
+
},
|
|
417
425
|
marketCoinName: SupportStakeMarketCoins
|
|
418
426
|
) => {
|
|
419
|
-
const poolId =
|
|
427
|
+
const poolId = utils.address.get(`spool.pools.${marketCoinName}.id`);
|
|
420
428
|
let stakePool: StakePool | undefined = undefined;
|
|
421
|
-
const stakePoolObjectResponse = await
|
|
429
|
+
const stakePoolObjectResponse = await utils.cache.queryGetObject(poolId, {
|
|
422
430
|
showContent: true,
|
|
423
431
|
showType: true,
|
|
424
432
|
});
|
|
@@ -469,14 +477,18 @@ export const getStakePool = async (
|
|
|
469
477
|
* @return Stake reward pool.
|
|
470
478
|
*/
|
|
471
479
|
export const getStakeRewardPool = async (
|
|
472
|
-
|
|
480
|
+
{
|
|
481
|
+
utils,
|
|
482
|
+
}: {
|
|
483
|
+
utils: ScallopUtils;
|
|
484
|
+
},
|
|
473
485
|
marketCoinName: SupportStakeMarketCoins
|
|
474
486
|
) => {
|
|
475
|
-
const poolId =
|
|
487
|
+
const poolId = utils.address.get(
|
|
476
488
|
`spool.pools.${marketCoinName}.rewardPoolId`
|
|
477
489
|
);
|
|
478
490
|
let stakeRewardPool: StakeRewardPool | undefined = undefined;
|
|
479
|
-
const stakeRewardPoolObjectResponse = await
|
|
491
|
+
const stakeRewardPoolObjectResponse = await utils.cache.queryGetObject(
|
|
480
492
|
poolId,
|
|
481
493
|
{
|
|
482
494
|
showContent: true,
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
type SuiObjectData,
|
|
6
6
|
DevInspectResults,
|
|
7
7
|
} from '@mysten/sui.js/client';
|
|
8
|
-
import type {
|
|
8
|
+
import type { ScallopUtils } from '../models';
|
|
9
9
|
import { MAX_LOCK_DURATION } from 'src/constants';
|
|
10
10
|
import { SUI_CLOCK_OBJECT_ID, SuiTxBlock } from '@scallop-io/sui-kit';
|
|
11
11
|
import { bcs } from '@mysten/sui.js/bcs';
|
|
@@ -18,17 +18,17 @@ import { z as zod } from 'zod';
|
|
|
18
18
|
* @return Owned veSca key.
|
|
19
19
|
*/
|
|
20
20
|
export const getVescaKeys = async (
|
|
21
|
-
|
|
21
|
+
utils: ScallopUtils,
|
|
22
22
|
ownerAddress?: string
|
|
23
23
|
) => {
|
|
24
|
-
const owner = ownerAddress ||
|
|
25
|
-
const veScaObjId =
|
|
24
|
+
const owner = ownerAddress || utils.suiKit.currentAddress();
|
|
25
|
+
const veScaObjId = utils.address.get('vesca.object');
|
|
26
26
|
const veScaKeyType = `${veScaObjId}::ve_sca::VeScaKey`;
|
|
27
27
|
const keyObjectsResponse: SuiObjectResponse[] = [];
|
|
28
28
|
let hasNextPage = false;
|
|
29
29
|
let nextCursor: string | null | undefined = null;
|
|
30
30
|
do {
|
|
31
|
-
const paginatedKeyObjectsResponse = await
|
|
31
|
+
const paginatedKeyObjectsResponse = await utils.cache.queryGetOwnedObjects({
|
|
32
32
|
owner,
|
|
33
33
|
filter: {
|
|
34
34
|
StructType: veScaKeyType,
|
|
@@ -63,12 +63,19 @@ export const getVescaKeys = async (
|
|
|
63
63
|
* @param ownerAddress - The owner address.
|
|
64
64
|
* @return Owned veScas.
|
|
65
65
|
*/
|
|
66
|
-
export const getVeScas = async (
|
|
67
|
-
|
|
66
|
+
export const getVeScas = async (
|
|
67
|
+
{
|
|
68
|
+
utils,
|
|
69
|
+
}: {
|
|
70
|
+
utils: ScallopUtils;
|
|
71
|
+
},
|
|
72
|
+
ownerAddress?: string
|
|
73
|
+
) => {
|
|
74
|
+
const keyObjectDatas = await getVescaKeys(utils, ownerAddress);
|
|
68
75
|
|
|
69
76
|
const veScas: Vesca[] = Array(keyObjectDatas.length).fill(null);
|
|
70
77
|
const tasks = keyObjectDatas.map(async (veScaKey, idx) => {
|
|
71
|
-
const veSca = await getVeSca(
|
|
78
|
+
const veSca = await getVeSca(utils, veScaKey);
|
|
72
79
|
if (veSca) {
|
|
73
80
|
veScas[idx] = veSca;
|
|
74
81
|
}
|
|
@@ -96,12 +103,12 @@ type SuiObjectRefType = zod.infer<typeof SuiObjectRefZod>;
|
|
|
96
103
|
* @returns Vesca data.
|
|
97
104
|
*/
|
|
98
105
|
export const getVeSca = async (
|
|
99
|
-
|
|
106
|
+
utils: ScallopUtils,
|
|
100
107
|
veScaKey?: string | SuiObjectData,
|
|
101
108
|
ownerAddress?: string
|
|
102
109
|
) => {
|
|
103
|
-
const tableId =
|
|
104
|
-
veScaKey = veScaKey || (await getVescaKeys(
|
|
110
|
+
const tableId = utils.address.get(`vesca.tableId`);
|
|
111
|
+
veScaKey = veScaKey || (await getVescaKeys(utils, ownerAddress))[0];
|
|
105
112
|
|
|
106
113
|
if (!veScaKey) return undefined;
|
|
107
114
|
if (typeof veScaKey === 'object') {
|
|
@@ -111,7 +118,7 @@ export const getVeSca = async (
|
|
|
111
118
|
let vesca: Vesca | undefined = undefined;
|
|
112
119
|
|
|
113
120
|
const veScaDynamicFieldObjectResponse =
|
|
114
|
-
await
|
|
121
|
+
await utils.cache.queryGetDynamicFieldObject({
|
|
115
122
|
parentId: tableId,
|
|
116
123
|
name: {
|
|
117
124
|
type: '0x2::object::ID',
|
|
@@ -162,12 +169,12 @@ export const getVeSca = async (
|
|
|
162
169
|
* Get current total veSca treasury amount.
|
|
163
170
|
*/
|
|
164
171
|
const getTotalVeScaTreasuryAmount = async (
|
|
165
|
-
|
|
172
|
+
utils: ScallopUtils,
|
|
166
173
|
veScaTreasury: SuiObjectData
|
|
167
174
|
): Promise<string> => {
|
|
168
|
-
const veScaPkgId =
|
|
169
|
-
const veScaConfig =
|
|
170
|
-
veScaTreasury = veScaTreasury ??
|
|
175
|
+
const veScaPkgId = utils.address.get('vesca.id');
|
|
176
|
+
const veScaConfig = utils.address.get('vesca.config');
|
|
177
|
+
veScaTreasury = veScaTreasury ?? utils.address.get('vesca.treasury');
|
|
171
178
|
|
|
172
179
|
// refresh query
|
|
173
180
|
const refreshQueryTarget = `${veScaPkgId}::treasury::refresh`;
|
|
@@ -181,7 +188,7 @@ const getTotalVeScaTreasuryAmount = async (
|
|
|
181
188
|
const resolvedRefreshArgs = await Promise.all(
|
|
182
189
|
refreshArgs.map(async (arg) => {
|
|
183
190
|
if (typeof arg === 'string') {
|
|
184
|
-
return (await
|
|
191
|
+
return (await utils.cache.queryGetObject(arg, { showContent: true }))
|
|
185
192
|
?.data;
|
|
186
193
|
}
|
|
187
194
|
return arg;
|
|
@@ -191,7 +198,7 @@ const getTotalVeScaTreasuryAmount = async (
|
|
|
191
198
|
const resolvedVeScaAmountArgs = await Promise.all(
|
|
192
199
|
veScaAmountArgs.map(async (arg) => {
|
|
193
200
|
if (typeof arg === 'string') {
|
|
194
|
-
return (await
|
|
201
|
+
return (await utils.cache.queryGetObject(arg, { showContent: true }))
|
|
195
202
|
?.data;
|
|
196
203
|
}
|
|
197
204
|
return arg;
|
|
@@ -204,19 +211,18 @@ const getTotalVeScaTreasuryAmount = async (
|
|
|
204
211
|
txb.moveCall(veScaAmountQueryTarget, resolvedVeScaAmountArgs);
|
|
205
212
|
|
|
206
213
|
const txBytes = await txb.txBlock.build({
|
|
207
|
-
client:
|
|
214
|
+
client: utils.suiKit.client(),
|
|
208
215
|
onlyTransactionKind: true,
|
|
209
|
-
protocolConfig: (await query.cache.getProtocolConfig()) ?? undefined,
|
|
210
216
|
});
|
|
211
217
|
|
|
212
218
|
// return result
|
|
213
|
-
const res = await
|
|
219
|
+
const res = await utils.cache.queryClient.fetchQuery<DevInspectResults>({
|
|
214
220
|
queryKey: [
|
|
215
221
|
'getTotalVeScaTreasuryAmount',
|
|
216
222
|
JSON.stringify([...refreshArgs, ...veScaAmountArgs]),
|
|
217
223
|
],
|
|
218
224
|
queryFn: async () => {
|
|
219
|
-
return await
|
|
225
|
+
return await utils.suiKit.inspectTxn(txBytes);
|
|
220
226
|
},
|
|
221
227
|
});
|
|
222
228
|
|
|
@@ -236,10 +242,10 @@ const getTotalVeScaTreasuryAmount = async (
|
|
|
236
242
|
* @returns VeScaTreasuryInfo
|
|
237
243
|
*/
|
|
238
244
|
export const getVeScaTreasuryInfo = async (
|
|
239
|
-
|
|
245
|
+
utils: ScallopUtils
|
|
240
246
|
): Promise<VeScaTreasuryInfo | null> => {
|
|
241
|
-
const veScaTreasuryId =
|
|
242
|
-
const veScaTreasury = await
|
|
247
|
+
const veScaTreasuryId = utils.address.get('vesca.treasury');
|
|
248
|
+
const veScaTreasury = await utils.cache.queryGetObject(veScaTreasuryId, {
|
|
243
249
|
showContent: true,
|
|
244
250
|
});
|
|
245
251
|
|
|
@@ -255,7 +261,7 @@ export const getVeScaTreasuryInfo = async (
|
|
|
255
261
|
.shiftedBy(-9)
|
|
256
262
|
.toNumber();
|
|
257
263
|
const totalVeSca = BigNumber(
|
|
258
|
-
(await getTotalVeScaTreasuryAmount(
|
|
264
|
+
(await getTotalVeScaTreasuryAmount(utils, veScaTreasury.data)) ?? 0
|
|
259
265
|
)
|
|
260
266
|
.shiftedBy(-9)
|
|
261
267
|
.toNumber();
|
|
@@ -32,6 +32,10 @@ export type VeScaNormalMethods = {
|
|
|
32
32
|
mintEmptyVeSca: () => TransactionResult;
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
+
export type RedeemScaQuickReturnType<T extends boolean> = T extends true
|
|
36
|
+
? void
|
|
37
|
+
: TransactionResult | undefined;
|
|
38
|
+
|
|
35
39
|
export type VeScaQuickMethods = {
|
|
36
40
|
/**
|
|
37
41
|
* Quick methods to automate
|
|
@@ -70,7 +74,10 @@ export type VeScaQuickMethods = {
|
|
|
70
74
|
veScaKey?: SuiObjectArg,
|
|
71
75
|
autoCheck?: boolean
|
|
72
76
|
) => Promise<void>;
|
|
73
|
-
redeemScaQuick:
|
|
77
|
+
redeemScaQuick: <T extends boolean>(
|
|
78
|
+
veSCaKey?: SuiObjectArg,
|
|
79
|
+
transferSca?: T
|
|
80
|
+
) => Promise<RedeemScaQuickReturnType<T>>;
|
|
74
81
|
};
|
|
75
82
|
|
|
76
83
|
export type SuiTxBlockWithVeScaNormalMethods = SuiKitTxBlock &
|