@scallop-io/sui-scallop-sdk 1.5.3 → 2.0.0-alpha.10
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 +509 -602
- package/dist/index.d.ts +509 -602
- package/dist/index.js +28 -59
- package/dist/index.mjs +7 -7
- package/package.json +1 -1
- package/src/builders/coreBuilder.ts +33 -33
- package/src/builders/loyaltyProgramBuilder.ts +5 -3
- package/src/builders/{oracle.ts → oracles/index.ts} +48 -60
- package/src/builders/oracles/pyth.ts +44 -0
- package/src/builders/oracles/switchboard.ts +270 -0
- 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/constants/testAddress.ts +36 -487
- package/src/models/index.ts +1 -0
- package/src/models/scallop.ts +23 -19
- package/src/models/scallopAddress.ts +17 -5
- package/src/models/scallopBuilder.ts +36 -41
- package/src/models/scallopCache.ts +3 -3
- package/src/models/scallopClient.ts +93 -98
- package/src/models/scallopConstants.ts +399 -0
- package/src/models/scallopIndexer.ts +11 -24
- package/src/models/scallopQuery.ts +76 -79
- package/src/models/scallopUtils.ts +126 -250
- package/src/queries/borrowIncentiveQuery.ts +25 -58
- package/src/queries/borrowLimitQuery.ts +3 -6
- package/src/queries/coreQuery.ts +98 -114
- package/src/queries/flashloanFeeQuery.ts +86 -0
- package/src/queries/index.ts +1 -0
- package/src/queries/isolatedAssetQuery.ts +12 -11
- package/src/queries/poolAddressesQuery.ts +211 -117
- package/src/queries/portfolioQuery.ts +60 -70
- 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/switchboardQuery.ts +64 -0
- package/src/queries/xOracleQuery.ts +29 -32
- package/src/types/address.ts +21 -19
- 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 +44 -49
- package/src/types/constant/enum.ts +15 -27
- package/src/types/constant/xOracle.ts +3 -2
- package/src/types/model.ts +49 -28
- package/src/types/query/borrowIncentive.ts +7 -24
- package/src/types/query/core.ts +8 -18
- package/src/types/query/portfolio.ts +9 -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 +15 -23
- 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
- package/src/models/scallopPrice.ts +0 -0
|
@@ -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,51 @@ export class ScallopUtils {
|
|
|
82
59
|
};
|
|
83
60
|
this.walletAddress =
|
|
84
61
|
params.walletAddress ?? instance?.suiKit?.currentAddress() ?? '';
|
|
85
|
-
this.suiKit =
|
|
86
|
-
instance?.suiKit ?? instance?.address?.cache.suiKit ?? newSuiKit(params);
|
|
87
62
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
63
|
+
this.suiKit =
|
|
64
|
+
instance?.suiKit ??
|
|
65
|
+
instance?.constants?.cache.suiKit ??
|
|
66
|
+
newSuiKit(params);
|
|
67
|
+
|
|
68
|
+
this.cache =
|
|
69
|
+
instance?.constants?.cache ??
|
|
70
|
+
instance?.cache ??
|
|
71
|
+
new ScallopCache(this.params, {
|
|
93
72
|
suiKit: this.suiKit,
|
|
94
73
|
});
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
this.isTestnet = params.networkType
|
|
109
|
-
? params.networkType === 'testnet'
|
|
110
|
-
: false;
|
|
74
|
+
|
|
75
|
+
this.address =
|
|
76
|
+
instance?.constants?.address ??
|
|
77
|
+
new ScallopAddress(this.params, {
|
|
78
|
+
cache: this.cache,
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
this.constants =
|
|
82
|
+
instance?.constants ??
|
|
83
|
+
new ScallopConstants(this.params, {
|
|
84
|
+
address: this.address,
|
|
85
|
+
});
|
|
111
86
|
}
|
|
87
|
+
|
|
88
|
+
get whitelist() {
|
|
89
|
+
return this.constants.whitelist;
|
|
90
|
+
}
|
|
91
|
+
|
|
112
92
|
// -------------- TYPE GUARDS --------------
|
|
113
|
-
public isSuiBridgeAsset(coinName: any)
|
|
114
|
-
return
|
|
93
|
+
public isSuiBridgeAsset(coinName: any) {
|
|
94
|
+
return this.constants.whitelist.suiBridge.has(coinName);
|
|
115
95
|
}
|
|
116
96
|
|
|
117
|
-
public isWormholeAsset(coinName: any)
|
|
118
|
-
return
|
|
97
|
+
public isWormholeAsset(coinName: any) {
|
|
98
|
+
return this.constants.whitelist.wormhole.has(coinName);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public isMarketCoin(coinName: string) {
|
|
102
|
+
const assetCoinName = coinName.slice(1).toLowerCase() as string;
|
|
103
|
+
return (
|
|
104
|
+
coinName.charAt(0).toLowerCase() === 's' &&
|
|
105
|
+
this.whitelist.lending.has(assetCoinName)
|
|
106
|
+
);
|
|
119
107
|
}
|
|
120
108
|
|
|
121
109
|
/**
|
|
@@ -124,10 +112,9 @@ export class ScallopUtils {
|
|
|
124
112
|
* @param force - Whether to force initialization.
|
|
125
113
|
* @param address - ScallopAddress instance.
|
|
126
114
|
*/
|
|
127
|
-
public async init(force: boolean = false
|
|
128
|
-
if (
|
|
129
|
-
|
|
130
|
-
await this.address.read();
|
|
115
|
+
public async init(force: boolean = false) {
|
|
116
|
+
if (force || !this.constants.isInitialized) {
|
|
117
|
+
await this.constants.init();
|
|
131
118
|
}
|
|
132
119
|
}
|
|
133
120
|
|
|
@@ -137,8 +124,11 @@ 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.isMarketCoin(coinName)
|
|
129
|
+
? (this.constants.poolAddresses[this.parseCoinName(coinName)]
|
|
130
|
+
?.sCoinSymbol ?? '')
|
|
131
|
+
: (this.constants.poolAddresses[coinName]?.symbol ?? '');
|
|
142
132
|
}
|
|
143
133
|
|
|
144
134
|
/**
|
|
@@ -152,60 +142,11 @@ export class ScallopUtils {
|
|
|
152
142
|
* @param coinName - Specific support coin name.
|
|
153
143
|
* @return Coin type.
|
|
154
144
|
*/
|
|
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()}`;
|
|
145
|
+
public parseCoinType(coinName: string, useOldMarketCoin: boolean = false) {
|
|
146
|
+
if (useOldMarketCoin) {
|
|
147
|
+
return this.constants.coinNameToOldMarketCoinTypeMap[coinName] ?? '';
|
|
208
148
|
}
|
|
149
|
+
return this.constants.coinTypes[coinName] ?? '';
|
|
209
150
|
}
|
|
210
151
|
|
|
211
152
|
/**
|
|
@@ -214,18 +155,13 @@ export class ScallopUtils {
|
|
|
214
155
|
* @param coinName - Specific support coin name.
|
|
215
156
|
* @return sCoin name.
|
|
216
157
|
*/
|
|
217
|
-
public parseSCoinName<T extends
|
|
218
|
-
coinName: SupportCoins | SupportMarketCoins
|
|
219
|
-
) {
|
|
158
|
+
public parseSCoinName<T extends string>(coinName: string) {
|
|
220
159
|
// need more check because swapt has no sCoin type
|
|
221
|
-
if (
|
|
222
|
-
isMarketCoin(coinName) &&
|
|
223
|
-
SUPPORT_SCOIN.includes(coinName as SupportSCoin)
|
|
224
|
-
) {
|
|
160
|
+
if (this.isMarketCoin(coinName) && this.whitelist.scoin.has(coinName)) {
|
|
225
161
|
return coinName as T;
|
|
226
162
|
} else {
|
|
227
163
|
const marketCoinName = `s${coinName}`;
|
|
228
|
-
if (
|
|
164
|
+
if (this.whitelist.scoin.has(marketCoinName)) {
|
|
229
165
|
return marketCoinName as T;
|
|
230
166
|
}
|
|
231
167
|
return undefined;
|
|
@@ -240,7 +176,7 @@ export class ScallopUtils {
|
|
|
240
176
|
* @return sCoin name
|
|
241
177
|
*/
|
|
242
178
|
public parseSCoinTypeNameToMarketCoinName(coinName: string) {
|
|
243
|
-
return
|
|
179
|
+
return this.constants.sCoinRawNameToScoinNameMap[coinName] ?? coinName;
|
|
244
180
|
}
|
|
245
181
|
|
|
246
182
|
/**
|
|
@@ -248,8 +184,8 @@ export class ScallopUtils {
|
|
|
248
184
|
* @param sCoinName
|
|
249
185
|
* @returns sCoin type
|
|
250
186
|
*/
|
|
251
|
-
public parseSCoinType(sCoinName:
|
|
252
|
-
return
|
|
187
|
+
public parseSCoinType(sCoinName: string) {
|
|
188
|
+
return this.constants.sCoinTypes[sCoinName] ?? '';
|
|
253
189
|
}
|
|
254
190
|
|
|
255
191
|
/**
|
|
@@ -258,7 +194,7 @@ export class ScallopUtils {
|
|
|
258
194
|
* @returns sCoin name
|
|
259
195
|
*/
|
|
260
196
|
public parseSCoinNameFromType(sCoinType: string) {
|
|
261
|
-
return
|
|
197
|
+
return this.constants.sCoinTypeToSCoinNameMap[sCoinType];
|
|
262
198
|
}
|
|
263
199
|
|
|
264
200
|
/**
|
|
@@ -266,7 +202,7 @@ export class ScallopUtils {
|
|
|
266
202
|
* @param sCoinName
|
|
267
203
|
* @returns coin type
|
|
268
204
|
*/
|
|
269
|
-
public parseUnderlyingSCoinType(sCoinName:
|
|
205
|
+
public parseUnderlyingSCoinType(sCoinName: string) {
|
|
270
206
|
const coinName = this.parseCoinName(sCoinName);
|
|
271
207
|
return this.parseCoinType(coinName);
|
|
272
208
|
}
|
|
@@ -276,7 +212,7 @@ export class ScallopUtils {
|
|
|
276
212
|
* @param sCoinName
|
|
277
213
|
* @returns sCoin treasury id
|
|
278
214
|
*/
|
|
279
|
-
public getSCoinTreasury(sCoinName:
|
|
215
|
+
public getSCoinTreasury(sCoinName: string) {
|
|
280
216
|
return this.address.get(`scoin.coins.${sCoinName}.treasury`);
|
|
281
217
|
}
|
|
282
218
|
|
|
@@ -287,11 +223,12 @@ export class ScallopUtils {
|
|
|
287
223
|
* @param coinName - Specific support coin name.
|
|
288
224
|
* @return Market coin type.
|
|
289
225
|
*/
|
|
290
|
-
public parseMarketCoinType(coinName:
|
|
291
|
-
const
|
|
292
|
-
this.
|
|
293
|
-
|
|
294
|
-
|
|
226
|
+
public parseMarketCoinType(coinName: string) {
|
|
227
|
+
const coinType = this.parseCoinType(
|
|
228
|
+
this.isMarketCoin(coinName) ? this.parseCoinName(coinName) : coinName,
|
|
229
|
+
true
|
|
230
|
+
);
|
|
231
|
+
return coinType;
|
|
295
232
|
}
|
|
296
233
|
|
|
297
234
|
/**
|
|
@@ -304,74 +241,28 @@ export class ScallopUtils {
|
|
|
304
241
|
* @param coinType - Specific support coin type.
|
|
305
242
|
* @return Coin Name.
|
|
306
243
|
*/
|
|
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
244
|
public parseCoinNameFromType(coinType: string) {
|
|
320
245
|
coinType = normalizeStructTag(coinType);
|
|
321
|
-
|
|
322
|
-
|
|
246
|
+
const { address, module, name, typeParams } = parseStructTag(coinType);
|
|
247
|
+
const isMarketCoinType =
|
|
248
|
+
address === this.constants.protocolObjectId &&
|
|
249
|
+
module === 'reserve' &&
|
|
250
|
+
name === 'MarketCoin';
|
|
251
|
+
|
|
252
|
+
if (isMarketCoinType) {
|
|
253
|
+
return this.parseMarketCoinName(
|
|
254
|
+
(typeof typeParams[0] === 'string'
|
|
255
|
+
? parseStructTag(typeParams[0])
|
|
256
|
+
: typeParams[0]
|
|
257
|
+
).name.toLowerCase()
|
|
258
|
+
);
|
|
323
259
|
}
|
|
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
260
|
const assetCoinName =
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
return isMarketCoinType
|
|
373
|
-
? this.parseMarketCoinName(assetCoinName)
|
|
374
|
-
: assetCoinName;
|
|
261
|
+
this.constants.coinTypeToCoinNameMap[coinType] ||
|
|
262
|
+
this.constants.sCoinTypeToSCoinNameMap[coinType] ||
|
|
263
|
+
parseStructTag(coinType).name.toLowerCase();
|
|
264
|
+
|
|
265
|
+
return assetCoinName;
|
|
375
266
|
}
|
|
376
267
|
|
|
377
268
|
/**
|
|
@@ -380,7 +271,7 @@ export class ScallopUtils {
|
|
|
380
271
|
* @param marketCoinName - Specific support market coin name.
|
|
381
272
|
* @return Coin Name.
|
|
382
273
|
*/
|
|
383
|
-
public parseCoinName<T extends
|
|
274
|
+
public parseCoinName<T extends string>(marketCoinName: string) {
|
|
384
275
|
return marketCoinName.slice(1) as T;
|
|
385
276
|
}
|
|
386
277
|
|
|
@@ -390,9 +281,7 @@ export class ScallopUtils {
|
|
|
390
281
|
* @param coinName - Specific support coin name.
|
|
391
282
|
* @return Market coin name.
|
|
392
283
|
*/
|
|
393
|
-
public parseMarketCoinName<T extends
|
|
394
|
-
coinName: SupportCoins
|
|
395
|
-
) {
|
|
284
|
+
public parseMarketCoinName<T extends string>(coinName: string) {
|
|
396
285
|
return `s${coinName}` as T;
|
|
397
286
|
}
|
|
398
287
|
|
|
@@ -402,10 +291,8 @@ export class ScallopUtils {
|
|
|
402
291
|
* @param stakeMarketCoinName - Support stake market coin.
|
|
403
292
|
* @return Spool reward coin name.
|
|
404
293
|
*/
|
|
405
|
-
public getSpoolRewardCoinName = (
|
|
406
|
-
|
|
407
|
-
) => {
|
|
408
|
-
return spoolRewardCoins[stakeMarketCoinName];
|
|
294
|
+
public getSpoolRewardCoinName = () => {
|
|
295
|
+
return 'sui'; // No further plan to incentivize other spools
|
|
409
296
|
};
|
|
410
297
|
|
|
411
298
|
/**
|
|
@@ -413,8 +300,8 @@ export class ScallopUtils {
|
|
|
413
300
|
*
|
|
414
301
|
* return Coin decimal.
|
|
415
302
|
*/
|
|
416
|
-
public getCoinDecimal(coinName:
|
|
417
|
-
return coinDecimals[coinName];
|
|
303
|
+
public getCoinDecimal(coinName: string) {
|
|
304
|
+
return this.constants.coinDecimals[coinName] ?? 0;
|
|
418
305
|
}
|
|
419
306
|
|
|
420
307
|
/**
|
|
@@ -422,7 +309,7 @@ export class ScallopUtils {
|
|
|
422
309
|
*
|
|
423
310
|
* return Coin wrapped type.
|
|
424
311
|
*/
|
|
425
|
-
public getCoinWrappedType(assetCoinName:
|
|
312
|
+
public getCoinWrappedType(assetCoinName: string): CoinWrappedType {
|
|
426
313
|
if (this.isSuiBridgeAsset(assetCoinName)) {
|
|
427
314
|
return {
|
|
428
315
|
from: 'Sui Bridge',
|
|
@@ -531,35 +418,33 @@ export class ScallopUtils {
|
|
|
531
418
|
* @return Asset coin price.
|
|
532
419
|
*/
|
|
533
420
|
public async getCoinPrices(
|
|
534
|
-
|
|
535
|
-
...new Set([
|
|
536
|
-
|
|
421
|
+
coinNames: string[] = [
|
|
422
|
+
...new Set([
|
|
423
|
+
...this.constants.whitelist.lending,
|
|
424
|
+
...this.constants.whitelist.collateral,
|
|
425
|
+
]),
|
|
426
|
+
] as string[]
|
|
537
427
|
) {
|
|
538
428
|
let coinPrices: CoinPrices = {};
|
|
539
429
|
|
|
540
|
-
const endpoints =
|
|
541
|
-
this.params.pythEndpoints ??
|
|
542
|
-
PYTH_ENDPOINTS[this.isTestnet ? 'testnet' : 'mainnet'];
|
|
430
|
+
const endpoints = this.params.pythEndpoints ?? PYTH_ENDPOINTS['mainnet'];
|
|
543
431
|
|
|
544
|
-
const failedRequests: Set<
|
|
545
|
-
...SUPPORT_POOLS,
|
|
546
|
-
...SUPPORT_COLLATERALS,
|
|
547
|
-
]);
|
|
432
|
+
const failedRequests: Set<string> = new Set(coinNames);
|
|
548
433
|
|
|
549
434
|
for (const endpoint of endpoints) {
|
|
550
435
|
const priceIdPairs = Array.from(failedRequests.values()).reduce(
|
|
551
436
|
(acc, coinName) => {
|
|
552
437
|
const priceId =
|
|
553
438
|
this.address.get(`core.coins.${coinName}.oracle.pyth.feed`) ??
|
|
554
|
-
|
|
439
|
+
this.constants.poolAddresses[coinName]?.pythFeed;
|
|
555
440
|
acc.push([coinName, priceId]);
|
|
556
441
|
return acc;
|
|
557
442
|
},
|
|
558
443
|
[] as [string, string][]
|
|
559
444
|
);
|
|
445
|
+
if (priceIdPairs.length === 0) break;
|
|
560
446
|
|
|
561
447
|
const priceIds = priceIdPairs.map(([_, priceId]) => priceId);
|
|
562
|
-
|
|
563
448
|
const pythConnection = new SuiPriceServiceConnection(endpoint, {
|
|
564
449
|
timeout: 4000,
|
|
565
450
|
});
|
|
@@ -575,10 +460,10 @@ export class ScallopUtils {
|
|
|
575
460
|
});
|
|
576
461
|
if (feeds) {
|
|
577
462
|
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
|
|
463
|
+
const coinName = priceIdPairs[idx][0] as string;
|
|
464
|
+
const data = parseDataFromPythPriceFeed(feed, this.constants);
|
|
465
|
+
coinPrices[coinName as string] = data.price;
|
|
466
|
+
failedRequests.delete(coinName as string); // remove success price feed to prevent duplicate request on the next endpoint
|
|
582
467
|
});
|
|
583
468
|
}
|
|
584
469
|
} catch (e: any) {
|
|
@@ -666,20 +551,11 @@ export class ScallopUtils {
|
|
|
666
551
|
* Get detailed contract address and price id information for supported pool in Scallop
|
|
667
552
|
* @returns Supported pool informations
|
|
668
553
|
*/
|
|
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
|
-
});
|
|
554
|
+
public getSupportedPoolAddresses(): PoolAddress[] {
|
|
555
|
+
return this.constants.poolAddresses
|
|
556
|
+
? Object.values(this.constants.poolAddresses).filter(
|
|
557
|
+
(address): address is PoolAddress => address !== undefined
|
|
558
|
+
)
|
|
559
|
+
: [];
|
|
684
560
|
}
|
|
685
561
|
}
|