@scallop-io/sui-scallop-sdk 1.5.3 → 2.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +446 -599
- package/dist/index.d.ts +446 -599
- package/dist/index.js +29 -60
- package/dist/index.mjs +6 -6
- package/package.json +1 -1
- package/src/builders/loyaltyProgramBuilder.ts +5 -3
- package/src/builders/oracle.ts +10 -24
- package/src/builders/referralBuilder.ts +5 -9
- package/src/builders/sCoinBuilder.ts +9 -8
- package/src/builders/spoolBuilder.ts +4 -6
- package/src/constants/common.ts +114 -126
- package/src/constants/index.ts +0 -5
- package/src/constants/pyth.ts +25 -34
- package/src/constants/queryKeys.ts +2 -0
- package/src/models/index.ts +1 -0
- package/src/models/scallop.ts +23 -19
- package/src/models/scallopAddress.ts +7 -4
- package/src/models/scallopBuilder.ts +32 -35
- package/src/models/scallopCache.ts +1 -1
- package/src/models/scallopClient.ts +87 -89
- package/src/models/scallopConstants.ts +341 -0
- package/src/models/scallopIndexer.ts +11 -24
- package/src/models/scallopQuery.ts +65 -70
- package/src/models/scallopUtils.ts +114 -244
- package/src/queries/borrowIncentiveQuery.ts +21 -56
- package/src/queries/borrowLimitQuery.ts +3 -6
- package/src/queries/coreQuery.ts +94 -112
- package/src/queries/flashloanFeeQuery.ts +86 -0
- package/src/queries/isolatedAssetQuery.ts +12 -11
- package/src/queries/poolAddressesQuery.ts +187 -112
- package/src/queries/portfolioQuery.ts +65 -67
- package/src/queries/priceQuery.ts +16 -22
- package/src/queries/sCoinQuery.ts +15 -16
- package/src/queries/spoolQuery.ts +49 -59
- package/src/queries/supplyLimitQuery.ts +2 -6
- package/src/queries/xOracleQuery.ts +4 -15
- package/src/types/address.ts +12 -18
- package/src/types/builder/borrowIncentive.ts +2 -3
- package/src/types/builder/core.ts +20 -27
- package/src/types/builder/index.ts +1 -2
- package/src/types/builder/referral.ts +4 -8
- package/src/types/builder/sCoin.ts +4 -8
- package/src/types/builder/spool.ts +7 -10
- package/src/types/constant/common.ts +43 -49
- package/src/types/constant/enum.ts +15 -27
- package/src/types/constant/xOracle.ts +3 -5
- package/src/types/model.ts +47 -28
- package/src/types/query/borrowIncentive.ts +7 -24
- package/src/types/query/core.ts +8 -18
- package/src/types/query/portfolio.ts +8 -17
- package/src/types/query/spool.ts +5 -11
- package/src/types/utils.ts +1 -21
- package/src/utils/core.ts +1 -1
- package/src/utils/query.ts +13 -20
- package/src/utils/util.ts +6 -84
- package/src/constants/coinGecko.ts +0 -34
- package/src/constants/enum.ts +0 -268
- package/src/constants/flashloan.ts +0 -18
- package/src/constants/poolAddress.ts +0 -898
|
@@ -1,55 +1,32 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
SUI_TYPE_ARG,
|
|
3
|
+
normalizeStructTag,
|
|
4
|
+
parseStructTag,
|
|
5
|
+
} from '@mysten/sui/utils';
|
|
2
6
|
import { SuiKit } from '@scallop-io/sui-kit';
|
|
3
7
|
import { SuiPriceServiceConnection } from '@pythnetwork/pyth-sui-js';
|
|
4
8
|
import { ScallopAddress } from './scallopAddress';
|
|
5
|
-
import {
|
|
6
|
-
ADDRESS_ID,
|
|
7
|
-
PROTOCOL_OBJECT_ID,
|
|
8
|
-
SUPPORT_POOLS,
|
|
9
|
-
SUPPORT_COLLATERALS,
|
|
10
|
-
spoolRewardCoins,
|
|
11
|
-
coinDecimals,
|
|
12
|
-
wormholeCoinIds,
|
|
13
|
-
voloCoinIds,
|
|
14
|
-
coinIds,
|
|
15
|
-
UNLOCK_ROUND_DURATION,
|
|
16
|
-
MAX_LOCK_DURATION,
|
|
17
|
-
SUPPORT_SCOIN,
|
|
18
|
-
sCoinIds,
|
|
19
|
-
suiBridgeCoins,
|
|
20
|
-
COIN_GECKGO_IDS,
|
|
21
|
-
POOL_ADDRESSES,
|
|
22
|
-
sCoinTypeToName,
|
|
23
|
-
sCoinRawNameToName,
|
|
24
|
-
} from '../constants';
|
|
9
|
+
import { UNLOCK_ROUND_DURATION, MAX_LOCK_DURATION } from '../constants';
|
|
25
10
|
import { getPythPrices, queryObligation } from '../queries';
|
|
26
|
-
import {
|
|
27
|
-
parseDataFromPythPriceFeed,
|
|
28
|
-
isMarketCoin,
|
|
29
|
-
parseAssetSymbol,
|
|
30
|
-
findClosestUnlockRound,
|
|
31
|
-
isSuiBridgeAsset,
|
|
32
|
-
isWormholeAsset,
|
|
33
|
-
} from '../utils';
|
|
34
|
-
import { PYTH_ENDPOINTS, PYTH_FEED_IDS } from 'src/constants/pyth';
|
|
11
|
+
import { parseDataFromPythPriceFeed, findClosestUnlockRound } from '../utils';
|
|
35
12
|
import { ScallopCache } from './scallopCache';
|
|
36
13
|
import type {
|
|
37
14
|
ScallopUtilsParams,
|
|
38
|
-
SupportCoins,
|
|
39
|
-
SupportAssetCoins,
|
|
40
|
-
SupportMarketCoins,
|
|
41
|
-
SupportStakeMarketCoins,
|
|
42
15
|
CoinPrices,
|
|
43
16
|
CoinWrappedType,
|
|
44
|
-
SupportSCoin,
|
|
45
17
|
ScallopUtilsInstanceParams,
|
|
46
|
-
|
|
47
|
-
SupportWormholeCoins,
|
|
48
|
-
PoolAddressInfo,
|
|
18
|
+
PoolAddress,
|
|
49
19
|
} from '../types';
|
|
50
20
|
import { queryKeys } from 'src/constants';
|
|
51
21
|
import type { SuiObjectArg, SuiTxBlock } from '@scallop-io/sui-kit';
|
|
52
22
|
import { newSuiKit } from './suiKit';
|
|
23
|
+
import { ScallopConstants } from './scallopConstants';
|
|
24
|
+
|
|
25
|
+
const PYTH_ENDPOINTS: {
|
|
26
|
+
[k in 'mainnet']: string[];
|
|
27
|
+
} = {
|
|
28
|
+
mainnet: ['https://hermes.pyth.network', 'https://scallop.rpc.p2p.world'],
|
|
29
|
+
};
|
|
53
30
|
|
|
54
31
|
/**
|
|
55
32
|
* @description
|
|
@@ -65,11 +42,11 @@ import { newSuiKit } from './suiKit';
|
|
|
65
42
|
*/
|
|
66
43
|
export class ScallopUtils {
|
|
67
44
|
public readonly params: ScallopUtilsParams;
|
|
68
|
-
public readonly isTestnet: boolean;
|
|
69
45
|
|
|
70
46
|
public suiKit: SuiKit;
|
|
71
47
|
public address: ScallopAddress;
|
|
72
48
|
public cache: ScallopCache;
|
|
49
|
+
public constants: ScallopConstants;
|
|
73
50
|
public walletAddress: string;
|
|
74
51
|
|
|
75
52
|
public constructor(
|
|
@@ -82,40 +59,50 @@ export class ScallopUtils {
|
|
|
82
59
|
};
|
|
83
60
|
this.walletAddress =
|
|
84
61
|
params.walletAddress ?? instance?.suiKit?.currentAddress() ?? '';
|
|
62
|
+
|
|
85
63
|
this.suiKit =
|
|
86
|
-
instance?.suiKit ??
|
|
64
|
+
instance?.suiKit ??
|
|
65
|
+
instance?.constants?.cache.suiKit ??
|
|
66
|
+
newSuiKit(params);
|
|
87
67
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
this.
|
|
91
|
-
} else {
|
|
92
|
-
this.cache = new ScallopCache(this.params, {
|
|
68
|
+
this.cache =
|
|
69
|
+
instance?.constants?.cache ??
|
|
70
|
+
new ScallopCache(this.params, {
|
|
93
71
|
suiKit: this.suiKit,
|
|
94
72
|
});
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
this.isTestnet = params.networkType
|
|
109
|
-
? params.networkType === 'testnet'
|
|
110
|
-
: false;
|
|
73
|
+
|
|
74
|
+
this.address =
|
|
75
|
+
instance?.constants?.address ??
|
|
76
|
+
new ScallopAddress(this.params, {
|
|
77
|
+
cache: this.cache,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
this.constants =
|
|
81
|
+
instance?.constants ??
|
|
82
|
+
new ScallopConstants(this.params, {
|
|
83
|
+
address: this.address,
|
|
84
|
+
});
|
|
111
85
|
}
|
|
86
|
+
|
|
87
|
+
get whitelist() {
|
|
88
|
+
return this.constants.whitelist;
|
|
89
|
+
}
|
|
90
|
+
|
|
112
91
|
// -------------- TYPE GUARDS --------------
|
|
113
|
-
public isSuiBridgeAsset(coinName: any)
|
|
114
|
-
return
|
|
92
|
+
public isSuiBridgeAsset(coinName: any) {
|
|
93
|
+
return this.constants.whitelist.suiBridge.has(coinName);
|
|
115
94
|
}
|
|
116
95
|
|
|
117
|
-
public isWormholeAsset(coinName: any)
|
|
118
|
-
return
|
|
96
|
+
public isWormholeAsset(coinName: any) {
|
|
97
|
+
return this.constants.whitelist.wormhole.has(coinName);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public isMarketCoin(coinName: string) {
|
|
101
|
+
const assetCoinName = coinName.slice(1).toLowerCase() as string;
|
|
102
|
+
return (
|
|
103
|
+
coinName.charAt(0).toLowerCase() === 's' &&
|
|
104
|
+
this.whitelist.lending.has(assetCoinName)
|
|
105
|
+
);
|
|
119
106
|
}
|
|
120
107
|
|
|
121
108
|
/**
|
|
@@ -137,8 +124,8 @@ export class ScallopUtils {
|
|
|
137
124
|
* @param coinName - Specific support coin name.
|
|
138
125
|
* @return Symbol string.
|
|
139
126
|
*/
|
|
140
|
-
public parseSymbol(coinName:
|
|
141
|
-
return
|
|
127
|
+
public parseSymbol(coinName: string) {
|
|
128
|
+
return this.constants.poolAddresses[coinName]?.symbol ?? '';
|
|
142
129
|
}
|
|
143
130
|
|
|
144
131
|
/**
|
|
@@ -152,60 +139,11 @@ export class ScallopUtils {
|
|
|
152
139
|
* @param coinName - Specific support coin name.
|
|
153
140
|
* @return Coin type.
|
|
154
141
|
*/
|
|
155
|
-
public parseCoinType(
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
) {
|
|
159
|
-
// try parse scoin first
|
|
160
|
-
if (sCoinIds[coinName as SupportSCoin] && !useOldMarketCoin) {
|
|
161
|
-
return sCoinIds[coinName as SupportSCoin];
|
|
162
|
-
}
|
|
163
|
-
coinName = isMarketCoin(coinName) ? this.parseCoinName(coinName) : coinName;
|
|
164
|
-
const coinPackageId =
|
|
165
|
-
this.address.get(`core.coins.${coinName}.id`) ||
|
|
166
|
-
coinIds[coinName] ||
|
|
167
|
-
undefined;
|
|
168
|
-
if (!coinPackageId) {
|
|
169
|
-
throw Error(`Coin ${coinName} is not supported`);
|
|
170
|
-
}
|
|
171
|
-
if (coinName === 'sui')
|
|
172
|
-
return normalizeStructTag(`${coinPackageId}::sui::SUI`);
|
|
173
|
-
if (coinName === 'blub')
|
|
174
|
-
return normalizeStructTag(`${coinPackageId}::BLUB::BLUB`);
|
|
175
|
-
if (coinName === 'sbwbtc')
|
|
176
|
-
return normalizeStructTag(`${coinPackageId}::btc::BTC`);
|
|
177
|
-
|
|
178
|
-
const wormHolePackageIds = [
|
|
179
|
-
this.address.get('core.coins.wusdc.id') ?? wormholeCoinIds.wusdc,
|
|
180
|
-
this.address.get('core.coins.wusdt.id') ?? wormholeCoinIds.wusdt,
|
|
181
|
-
this.address.get('core.coins.weth.id') ?? wormholeCoinIds.weth,
|
|
182
|
-
this.address.get('core.coins.wbtc.id') ?? wormholeCoinIds.wbtc,
|
|
183
|
-
this.address.get('core.coins.wsol.id') ?? wormholeCoinIds.wsol,
|
|
184
|
-
this.address.get('core.coins.wapt.id') ?? wormholeCoinIds.wapt,
|
|
185
|
-
];
|
|
186
|
-
const voloPackageIds = [
|
|
187
|
-
this.address.get('core.coins.vsui.id') ?? voloCoinIds.vsui,
|
|
188
|
-
];
|
|
189
|
-
|
|
190
|
-
const suiBridgePackageIds = Object.values<SupportSuiBridgeCoins>(
|
|
191
|
-
suiBridgeCoins
|
|
192
|
-
).reduce((curr, coinName) => {
|
|
193
|
-
curr.push(
|
|
194
|
-
this.address.get(`core.coins.${coinName}.id`) ?? coinIds[coinName]
|
|
195
|
-
);
|
|
196
|
-
return curr;
|
|
197
|
-
}, [] as string[]);
|
|
198
|
-
if (wormHolePackageIds.includes(coinPackageId)) {
|
|
199
|
-
return `${coinPackageId}::coin::COIN`;
|
|
200
|
-
} else if (voloPackageIds.includes(coinPackageId)) {
|
|
201
|
-
return `${coinPackageId}::cert::CERT`;
|
|
202
|
-
} else if (suiBridgePackageIds.includes(coinPackageId)) {
|
|
203
|
-
// handle sui bridge assets
|
|
204
|
-
const typeCoinName = coinName.slice(2);
|
|
205
|
-
return `${coinPackageId}::${typeCoinName}::${typeCoinName.toUpperCase()}`;
|
|
206
|
-
} else {
|
|
207
|
-
return `${coinPackageId}::${coinName}::${coinName.toUpperCase()}`;
|
|
142
|
+
public parseCoinType(coinName: string, useOldMarketCoin: boolean = false) {
|
|
143
|
+
if (useOldMarketCoin) {
|
|
144
|
+
return this.constants.coinNameToOldMarketCoinTypeMap[coinName] ?? '';
|
|
208
145
|
}
|
|
146
|
+
return this.constants.coinNameToCoinTypeMap[coinName] ?? '';
|
|
209
147
|
}
|
|
210
148
|
|
|
211
149
|
/**
|
|
@@ -214,18 +152,13 @@ export class ScallopUtils {
|
|
|
214
152
|
* @param coinName - Specific support coin name.
|
|
215
153
|
* @return sCoin name.
|
|
216
154
|
*/
|
|
217
|
-
public parseSCoinName<T extends
|
|
218
|
-
coinName: SupportCoins | SupportMarketCoins
|
|
219
|
-
) {
|
|
155
|
+
public parseSCoinName<T extends string>(coinName: string) {
|
|
220
156
|
// need more check because swapt has no sCoin type
|
|
221
|
-
if (
|
|
222
|
-
isMarketCoin(coinName) &&
|
|
223
|
-
SUPPORT_SCOIN.includes(coinName as SupportSCoin)
|
|
224
|
-
) {
|
|
157
|
+
if (this.isMarketCoin(coinName) && this.whitelist.scoin.has(coinName)) {
|
|
225
158
|
return coinName as T;
|
|
226
159
|
} else {
|
|
227
160
|
const marketCoinName = `s${coinName}`;
|
|
228
|
-
if (
|
|
161
|
+
if (this.whitelist.scoin.has(marketCoinName)) {
|
|
229
162
|
return marketCoinName as T;
|
|
230
163
|
}
|
|
231
164
|
return undefined;
|
|
@@ -240,7 +173,7 @@ export class ScallopUtils {
|
|
|
240
173
|
* @return sCoin name
|
|
241
174
|
*/
|
|
242
175
|
public parseSCoinTypeNameToMarketCoinName(coinName: string) {
|
|
243
|
-
return
|
|
176
|
+
return this.constants.sCoinRawNameToScoinNameMap[coinName] ?? coinName;
|
|
244
177
|
}
|
|
245
178
|
|
|
246
179
|
/**
|
|
@@ -248,8 +181,8 @@ export class ScallopUtils {
|
|
|
248
181
|
* @param sCoinName
|
|
249
182
|
* @returns sCoin type
|
|
250
183
|
*/
|
|
251
|
-
public parseSCoinType(sCoinName:
|
|
252
|
-
return
|
|
184
|
+
public parseSCoinType(sCoinName: string) {
|
|
185
|
+
return this.constants.sCoinTypes[sCoinName] ?? '';
|
|
253
186
|
}
|
|
254
187
|
|
|
255
188
|
/**
|
|
@@ -258,7 +191,7 @@ export class ScallopUtils {
|
|
|
258
191
|
* @returns sCoin name
|
|
259
192
|
*/
|
|
260
193
|
public parseSCoinNameFromType(sCoinType: string) {
|
|
261
|
-
return
|
|
194
|
+
return this.constants.sCoinTypeToSCoinNameMap[sCoinType];
|
|
262
195
|
}
|
|
263
196
|
|
|
264
197
|
/**
|
|
@@ -266,7 +199,7 @@ export class ScallopUtils {
|
|
|
266
199
|
* @param sCoinName
|
|
267
200
|
* @returns coin type
|
|
268
201
|
*/
|
|
269
|
-
public parseUnderlyingSCoinType(sCoinName:
|
|
202
|
+
public parseUnderlyingSCoinType(sCoinName: string) {
|
|
270
203
|
const coinName = this.parseCoinName(sCoinName);
|
|
271
204
|
return this.parseCoinType(coinName);
|
|
272
205
|
}
|
|
@@ -276,7 +209,7 @@ export class ScallopUtils {
|
|
|
276
209
|
* @param sCoinName
|
|
277
210
|
* @returns sCoin treasury id
|
|
278
211
|
*/
|
|
279
|
-
public getSCoinTreasury(sCoinName:
|
|
212
|
+
public getSCoinTreasury(sCoinName: string) {
|
|
280
213
|
return this.address.get(`scoin.coins.${sCoinName}.treasury`);
|
|
281
214
|
}
|
|
282
215
|
|
|
@@ -287,11 +220,12 @@ export class ScallopUtils {
|
|
|
287
220
|
* @param coinName - Specific support coin name.
|
|
288
221
|
* @return Market coin type.
|
|
289
222
|
*/
|
|
290
|
-
public parseMarketCoinType(coinName:
|
|
291
|
-
const
|
|
292
|
-
this.
|
|
293
|
-
|
|
294
|
-
|
|
223
|
+
public parseMarketCoinType(coinName: string) {
|
|
224
|
+
const coinType = this.parseCoinType(
|
|
225
|
+
this.isMarketCoin(coinName) ? this.parseCoinName(coinName) : coinName,
|
|
226
|
+
true
|
|
227
|
+
);
|
|
228
|
+
return coinType;
|
|
295
229
|
}
|
|
296
230
|
|
|
297
231
|
/**
|
|
@@ -304,74 +238,25 @@ export class ScallopUtils {
|
|
|
304
238
|
* @param coinType - Specific support coin type.
|
|
305
239
|
* @return Coin Name.
|
|
306
240
|
*/
|
|
307
|
-
public parseCoinNameFromType<T extends SupportAssetCoins>(
|
|
308
|
-
coinType: string
|
|
309
|
-
): T extends SupportAssetCoins ? T : SupportAssetCoins;
|
|
310
|
-
public parseCoinNameFromType<T extends SupportMarketCoins>(
|
|
311
|
-
coinType: string
|
|
312
|
-
): T extends SupportMarketCoins ? T : SupportMarketCoins;
|
|
313
|
-
public parseCoinNameFromType<T extends SupportCoins>(
|
|
314
|
-
coinType: string
|
|
315
|
-
): T extends SupportCoins ? T : SupportCoins;
|
|
316
|
-
public parseCoinNameFromType<T extends SupportSCoin>(
|
|
317
|
-
coinType: string
|
|
318
|
-
): T extends SupportSCoin ? T : SupportSCoin;
|
|
319
241
|
public parseCoinNameFromType(coinType: string) {
|
|
320
242
|
coinType = normalizeStructTag(coinType);
|
|
321
|
-
|
|
322
|
-
|
|
243
|
+
const { address, module, name, typeParams } = parseStructTag(coinType);
|
|
244
|
+
const isMarketCoinType =
|
|
245
|
+
address === this.constants.protocolObjectId &&
|
|
246
|
+
module === 'reserve' &&
|
|
247
|
+
name === 'MarketCoin';
|
|
248
|
+
|
|
249
|
+
if (isMarketCoinType) {
|
|
250
|
+
return this.parseMarketCoinName(
|
|
251
|
+
parseStructTag(typeParams as any).name.toLowerCase()
|
|
252
|
+
);
|
|
323
253
|
}
|
|
324
|
-
|
|
325
|
-
const coinTypeRegex = new RegExp(`((0x[^:]+::[^:]+::[^<>]+))(?![^<>]*<)`);
|
|
326
|
-
const coinTypeMatch = coinType.match(coinTypeRegex);
|
|
327
|
-
const isMarketCoinType = coinType.includes('reserve::MarketCoin');
|
|
328
|
-
coinType = coinTypeMatch?.[1] ?? coinType;
|
|
329
|
-
|
|
330
|
-
const wormholeCoinTypeMap: Record<string, SupportAssetCoins> = {
|
|
331
|
-
[`${
|
|
332
|
-
this.address.get('core.coins.wusdc.id') ?? wormholeCoinIds.wusdc
|
|
333
|
-
}::coin::COIN`]: 'wusdc',
|
|
334
|
-
[`${
|
|
335
|
-
this.address.get('core.coins.wusdt.id') ?? wormholeCoinIds.wusdt
|
|
336
|
-
}::coin::COIN`]: 'wusdt',
|
|
337
|
-
[`${
|
|
338
|
-
this.address.get('core.coins.weth.id') ?? wormholeCoinIds.weth
|
|
339
|
-
}::coin::COIN`]: 'weth',
|
|
340
|
-
[`${
|
|
341
|
-
this.address.get('core.coins.wbtc.id') ?? wormholeCoinIds.wbtc
|
|
342
|
-
}::coin::COIN`]: 'wbtc',
|
|
343
|
-
[`${
|
|
344
|
-
this.address.get('core.coins.wsol.id') ?? wormholeCoinIds.wsol
|
|
345
|
-
}::coin::COIN`]: 'wsol',
|
|
346
|
-
[`${
|
|
347
|
-
this.address.get('core.coins.wapt.id') ?? wormholeCoinIds.wapt
|
|
348
|
-
}::coin::COIN`]: 'wapt',
|
|
349
|
-
};
|
|
350
|
-
const voloCoinTypeMap: Record<string, SupportAssetCoins> = {
|
|
351
|
-
[`${
|
|
352
|
-
this.address.get('core.coins.vsui.id') ?? voloCoinIds.vsui
|
|
353
|
-
}::cert::CERT`]: 'vsui',
|
|
354
|
-
};
|
|
355
|
-
|
|
356
|
-
const suiBridgeTypeMap = Object.values<SupportSuiBridgeCoins>(
|
|
357
|
-
suiBridgeCoins
|
|
358
|
-
).reduce(
|
|
359
|
-
(curr, coinName) => {
|
|
360
|
-
curr[this.parseCoinType(coinName)] = coinName;
|
|
361
|
-
return curr;
|
|
362
|
-
},
|
|
363
|
-
{} as Record<string, SupportSuiBridgeCoins>
|
|
364
|
-
);
|
|
365
|
-
|
|
366
254
|
const assetCoinName =
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
return isMarketCoinType
|
|
373
|
-
? this.parseMarketCoinName(assetCoinName)
|
|
374
|
-
: assetCoinName;
|
|
255
|
+
this.constants.coinTypeToCoinNameMap[coinType] ||
|
|
256
|
+
this.constants.sCoinTypeToSCoinNameMap[coinType] ||
|
|
257
|
+
parseStructTag(coinType).name.toLowerCase();
|
|
258
|
+
|
|
259
|
+
return assetCoinName;
|
|
375
260
|
}
|
|
376
261
|
|
|
377
262
|
/**
|
|
@@ -380,7 +265,7 @@ export class ScallopUtils {
|
|
|
380
265
|
* @param marketCoinName - Specific support market coin name.
|
|
381
266
|
* @return Coin Name.
|
|
382
267
|
*/
|
|
383
|
-
public parseCoinName<T extends
|
|
268
|
+
public parseCoinName<T extends string>(marketCoinName: string) {
|
|
384
269
|
return marketCoinName.slice(1) as T;
|
|
385
270
|
}
|
|
386
271
|
|
|
@@ -390,9 +275,7 @@ export class ScallopUtils {
|
|
|
390
275
|
* @param coinName - Specific support coin name.
|
|
391
276
|
* @return Market coin name.
|
|
392
277
|
*/
|
|
393
|
-
public parseMarketCoinName<T extends
|
|
394
|
-
coinName: SupportCoins
|
|
395
|
-
) {
|
|
278
|
+
public parseMarketCoinName<T extends string>(coinName: string) {
|
|
396
279
|
return `s${coinName}` as T;
|
|
397
280
|
}
|
|
398
281
|
|
|
@@ -402,10 +285,8 @@ export class ScallopUtils {
|
|
|
402
285
|
* @param stakeMarketCoinName - Support stake market coin.
|
|
403
286
|
* @return Spool reward coin name.
|
|
404
287
|
*/
|
|
405
|
-
public getSpoolRewardCoinName = (
|
|
406
|
-
|
|
407
|
-
) => {
|
|
408
|
-
return spoolRewardCoins[stakeMarketCoinName];
|
|
288
|
+
public getSpoolRewardCoinName = () => {
|
|
289
|
+
return 'sui'; // No further plan to incentivize other spools
|
|
409
290
|
};
|
|
410
291
|
|
|
411
292
|
/**
|
|
@@ -413,8 +294,8 @@ export class ScallopUtils {
|
|
|
413
294
|
*
|
|
414
295
|
* return Coin decimal.
|
|
415
296
|
*/
|
|
416
|
-
public getCoinDecimal(coinName:
|
|
417
|
-
return coinDecimals[coinName];
|
|
297
|
+
public getCoinDecimal(coinName: string) {
|
|
298
|
+
return this.constants.coinDecimals[coinName] ?? 0;
|
|
418
299
|
}
|
|
419
300
|
|
|
420
301
|
/**
|
|
@@ -422,7 +303,7 @@ export class ScallopUtils {
|
|
|
422
303
|
*
|
|
423
304
|
* return Coin wrapped type.
|
|
424
305
|
*/
|
|
425
|
-
public getCoinWrappedType(assetCoinName:
|
|
306
|
+
public getCoinWrappedType(assetCoinName: string): CoinWrappedType {
|
|
426
307
|
if (this.isSuiBridgeAsset(assetCoinName)) {
|
|
427
308
|
return {
|
|
428
309
|
from: 'Sui Bridge',
|
|
@@ -531,27 +412,25 @@ export class ScallopUtils {
|
|
|
531
412
|
* @return Asset coin price.
|
|
532
413
|
*/
|
|
533
414
|
public async getCoinPrices(
|
|
534
|
-
|
|
535
|
-
...new Set([
|
|
536
|
-
|
|
415
|
+
coinNames: string[] = [
|
|
416
|
+
...new Set([
|
|
417
|
+
...this.constants.whitelist.lending,
|
|
418
|
+
...this.constants.whitelist.collateral,
|
|
419
|
+
]),
|
|
420
|
+
] as string[]
|
|
537
421
|
) {
|
|
538
422
|
let coinPrices: CoinPrices = {};
|
|
539
423
|
|
|
540
|
-
const endpoints =
|
|
541
|
-
this.params.pythEndpoints ??
|
|
542
|
-
PYTH_ENDPOINTS[this.isTestnet ? 'testnet' : 'mainnet'];
|
|
424
|
+
const endpoints = this.params.pythEndpoints ?? PYTH_ENDPOINTS['mainnet'];
|
|
543
425
|
|
|
544
|
-
const failedRequests: Set<
|
|
545
|
-
...SUPPORT_POOLS,
|
|
546
|
-
...SUPPORT_COLLATERALS,
|
|
547
|
-
]);
|
|
426
|
+
const failedRequests: Set<string> = new Set(coinNames);
|
|
548
427
|
|
|
549
428
|
for (const endpoint of endpoints) {
|
|
550
429
|
const priceIdPairs = Array.from(failedRequests.values()).reduce(
|
|
551
430
|
(acc, coinName) => {
|
|
552
431
|
const priceId =
|
|
553
432
|
this.address.get(`core.coins.${coinName}.oracle.pyth.feed`) ??
|
|
554
|
-
|
|
433
|
+
this.constants.poolAddresses[coinName]?.pythFeed;
|
|
555
434
|
acc.push([coinName, priceId]);
|
|
556
435
|
return acc;
|
|
557
436
|
},
|
|
@@ -575,10 +454,10 @@ export class ScallopUtils {
|
|
|
575
454
|
});
|
|
576
455
|
if (feeds) {
|
|
577
456
|
feeds.forEach((feed, idx) => {
|
|
578
|
-
const coinName = priceIdPairs[idx][0] as
|
|
579
|
-
const data = parseDataFromPythPriceFeed(feed, this.
|
|
580
|
-
coinPrices[coinName as
|
|
581
|
-
failedRequests.delete(coinName as
|
|
457
|
+
const coinName = priceIdPairs[idx][0] as string;
|
|
458
|
+
const data = parseDataFromPythPriceFeed(feed, this.constants);
|
|
459
|
+
coinPrices[coinName as string] = data.price;
|
|
460
|
+
failedRequests.delete(coinName as string); // remove success price feed to prevent duplicate request on the next endpoint
|
|
582
461
|
});
|
|
583
462
|
}
|
|
584
463
|
} catch (e: any) {
|
|
@@ -666,20 +545,11 @@ export class ScallopUtils {
|
|
|
666
545
|
* Get detailed contract address and price id information for supported pool in Scallop
|
|
667
546
|
* @returns Supported pool informations
|
|
668
547
|
*/
|
|
669
|
-
public getSupportedPoolAddresses():
|
|
670
|
-
return
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
decimal: coinDecimals[poolName],
|
|
676
|
-
pythFeedId: PYTH_FEED_IDS[poolName],
|
|
677
|
-
...POOL_ADDRESSES[poolName],
|
|
678
|
-
sCoinAddress: sCoinIds[sCoinName],
|
|
679
|
-
marketCoinAddress: this.parseMarketCoinType(poolName),
|
|
680
|
-
coinAddress: this.parseCoinType(poolName),
|
|
681
|
-
sCoinName: sCoinName ? this.parseSymbol(sCoinName) : undefined,
|
|
682
|
-
};
|
|
683
|
-
});
|
|
548
|
+
public getSupportedPoolAddresses(): PoolAddress[] {
|
|
549
|
+
return this.constants.poolAddresses
|
|
550
|
+
? Object.values(this.constants.poolAddresses).filter(
|
|
551
|
+
(address): address is PoolAddress => address !== undefined
|
|
552
|
+
)
|
|
553
|
+
: [];
|
|
684
554
|
}
|
|
685
555
|
}
|
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
import { normalizeStructTag } from '@mysten/sui/utils';
|
|
2
|
-
import {
|
|
3
|
-
SUPPORT_BORROW_INCENTIVE_POOLS,
|
|
4
|
-
SUPPORT_BORROW_INCENTIVE_REWARDS,
|
|
5
|
-
} from '../constants';
|
|
6
2
|
import {
|
|
7
3
|
parseOriginBorrowIncentivePoolData,
|
|
8
4
|
parseOriginBorrowIncentiveAccountData,
|
|
@@ -14,11 +10,8 @@ import type {
|
|
|
14
10
|
BorrowIncentivePools,
|
|
15
11
|
BorrowIncentiveAccountsQueryInterface,
|
|
16
12
|
BorrowIncentiveAccounts,
|
|
17
|
-
SupportBorrowIncentiveCoins,
|
|
18
|
-
SupportBorrowIncentiveRewardCoins,
|
|
19
13
|
BorrowIncentivePoolPoints,
|
|
20
14
|
OptionalKeys,
|
|
21
|
-
BorrowIncentivePool,
|
|
22
15
|
CoinPrices,
|
|
23
16
|
MarketPools,
|
|
24
17
|
} from '../types';
|
|
@@ -56,9 +49,7 @@ export const queryBorrowIncentivePools = async (address: ScallopAddress) => {
|
|
|
56
49
|
*/
|
|
57
50
|
export const getBorrowIncentivePools = async (
|
|
58
51
|
query: ScallopQuery,
|
|
59
|
-
borrowIncentiveCoinNames:
|
|
60
|
-
...SUPPORT_BORROW_INCENTIVE_POOLS,
|
|
61
|
-
],
|
|
52
|
+
borrowIncentiveCoinNames: string[] = [...query.constants.whitelist.lending],
|
|
62
53
|
indexer: boolean = false,
|
|
63
54
|
marketPools?: MarketPools,
|
|
64
55
|
coinPrices?: CoinPrices
|
|
@@ -69,36 +60,13 @@ export const getBorrowIncentivePools = async (
|
|
|
69
60
|
(await query.getMarketPools(undefined, { coinPrices, indexer })).pools;
|
|
70
61
|
coinPrices = coinPrices ?? (await query.getAllCoinPrices({ marketPools }));
|
|
71
62
|
|
|
72
|
-
if (indexer) {
|
|
73
|
-
const borrowIncentivePoolsIndexer =
|
|
74
|
-
await query.indexer.getBorrowIncentivePools();
|
|
75
|
-
|
|
76
|
-
const updateBorrowIncentivePool = (pool: BorrowIncentivePool) => {
|
|
77
|
-
if (!borrowIncentiveCoinNames.includes(pool.coinName)) return;
|
|
78
|
-
pool.coinPrice = coinPrices[pool.coinName] || pool.coinPrice;
|
|
79
|
-
for (const sCoinName of SUPPORT_BORROW_INCENTIVE_REWARDS) {
|
|
80
|
-
if (pool.points[sCoinName]) {
|
|
81
|
-
pool.points[sCoinName].coinPrice =
|
|
82
|
-
coinPrices[sCoinName] ?? pool.points[sCoinName].coinPrice;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
borrowIncentivePools[pool.coinName] = pool;
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
Object.values(borrowIncentivePoolsIndexer).forEach(
|
|
89
|
-
updateBorrowIncentivePool
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
return borrowIncentivePools;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
63
|
const borrowIncentivePoolsQueryData = await queryBorrowIncentivePools(
|
|
96
64
|
query.address
|
|
97
65
|
);
|
|
98
66
|
|
|
99
67
|
for (const pool of borrowIncentivePoolsQueryData?.incentive_pools ?? []) {
|
|
100
68
|
const borrowIncentivePoolPoints: OptionalKeys<
|
|
101
|
-
Record<
|
|
69
|
+
Record<string, BorrowIncentivePoolPoints>
|
|
102
70
|
> = {};
|
|
103
71
|
const parsedBorrowIncentivePoolData = parseOriginBorrowIncentivePoolData(
|
|
104
72
|
query.utils,
|
|
@@ -106,10 +74,7 @@ export const getBorrowIncentivePools = async (
|
|
|
106
74
|
);
|
|
107
75
|
|
|
108
76
|
const poolCoinType = normalizeStructTag(pool.pool_type.name);
|
|
109
|
-
const poolCoinName =
|
|
110
|
-
query.utils.parseCoinNameFromType<SupportBorrowIncentiveCoins>(
|
|
111
|
-
poolCoinType
|
|
112
|
-
);
|
|
77
|
+
const poolCoinName = query.utils.parseCoinNameFromType(poolCoinType);
|
|
113
78
|
const poolCoinPrice = coinPrices?.[poolCoinName] ?? 0;
|
|
114
79
|
const poolCoinDecimal = query.utils.getCoinDecimal(poolCoinName);
|
|
115
80
|
|
|
@@ -122,12 +87,16 @@ export const getBorrowIncentivePools = async (
|
|
|
122
87
|
for (const [coinName, poolPoint] of Object.entries(
|
|
123
88
|
parsedBorrowIncentivePoolData.poolPoints
|
|
124
89
|
)) {
|
|
90
|
+
if (!poolPoint) continue;
|
|
125
91
|
const rewardCoinType = poolPoint.pointType;
|
|
126
92
|
const rewardCoinName = query.utils.parseCoinNameFromType(
|
|
127
93
|
rewardCoinType
|
|
128
|
-
) as
|
|
94
|
+
) as string;
|
|
129
95
|
// handle for scoin name
|
|
130
96
|
const rewardCoinDecimal = query.utils.getCoinDecimal(rewardCoinName);
|
|
97
|
+
if (rewardCoinDecimal === undefined)
|
|
98
|
+
throw new Error(`Coin decimal not found for ${rewardCoinName}`);
|
|
99
|
+
|
|
131
100
|
const rewardCoinPrice = coinPrices?.[rewardCoinName] ?? 0;
|
|
132
101
|
|
|
133
102
|
const symbol = query.utils.parseSymbol(rewardCoinName);
|
|
@@ -142,18 +111,17 @@ export const getBorrowIncentivePools = async (
|
|
|
142
111
|
poolCoinDecimal
|
|
143
112
|
);
|
|
144
113
|
|
|
145
|
-
borrowIncentivePoolPoints[coinName as
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
};
|
|
114
|
+
borrowIncentivePoolPoints[coinName as string] = {
|
|
115
|
+
symbol,
|
|
116
|
+
coinName: rewardCoinName,
|
|
117
|
+
coinType: rewardCoinType,
|
|
118
|
+
coinDecimal,
|
|
119
|
+
coinPrice: rewardCoinPrice,
|
|
120
|
+
points: poolPoint.points,
|
|
121
|
+
distributedPoint: poolPoint.distributedPoint,
|
|
122
|
+
weightedAmount: poolPoint.weightedAmount,
|
|
123
|
+
...calculatedPoolPoint,
|
|
124
|
+
};
|
|
157
125
|
}
|
|
158
126
|
|
|
159
127
|
const stakedAmount = BigNumber(parsedBorrowIncentivePoolData.staked);
|
|
@@ -190,9 +158,7 @@ export const queryBorrowIncentiveAccounts = async (
|
|
|
190
158
|
utils: ScallopUtils;
|
|
191
159
|
},
|
|
192
160
|
obligationId: string | SuiObjectRef,
|
|
193
|
-
borrowIncentiveCoinNames:
|
|
194
|
-
...SUPPORT_BORROW_INCENTIVE_POOLS,
|
|
195
|
-
]
|
|
161
|
+
borrowIncentiveCoinNames: string[] = [...utils.constants.whitelist.lending]
|
|
196
162
|
) => {
|
|
197
163
|
const queryPkgId = utils.address.get('borrowIncentive.query');
|
|
198
164
|
const incentiveAccountsId = utils.address.get(
|
|
@@ -211,8 +177,7 @@ export const queryBorrowIncentiveAccounts = async (
|
|
|
211
177
|
const parsedBorrowIncentiveAccount =
|
|
212
178
|
parseOriginBorrowIncentiveAccountData(accountData);
|
|
213
179
|
const poolType = parsedBorrowIncentiveAccount.poolType;
|
|
214
|
-
const coinName =
|
|
215
|
-
utils.parseCoinNameFromType<SupportBorrowIncentiveCoins>(poolType);
|
|
180
|
+
const coinName = utils.parseCoinNameFromType(poolType);
|
|
216
181
|
|
|
217
182
|
if (
|
|
218
183
|
borrowIncentiveCoinNames &&
|