@scallop-io/sui-scallop-sdk 2.0.4 → 2.0.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scallop-io/sui-scallop-sdk",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "description": "Typescript sdk for interacting with Scallop contract on SUI",
5
5
  "keywords": [
6
6
  "sui",
@@ -359,51 +359,28 @@ const generateCoreQuickMethod: GenerateCoreQuickMethod = ({
359
359
  },
360
360
  withdrawQuick: async (amount, poolCoinName) => {
361
361
  const sender = requireSender(txBlock);
362
- const marketCoinName = builder.utils.parseMarketCoinName(poolCoinName);
363
-
364
362
  const sCoinName = builder.utils.parseSCoinName(poolCoinName);
365
363
  if (!sCoinName) throw new Error(`No sCoin for ${poolCoinName}`);
366
364
 
367
- // check if user has sCoin instead of marketCoin
368
- const {
369
- leftCoin,
370
- takeCoin: sCoins,
371
- totalAmount,
372
- } = await builder.selectSCoin(txBlock, sCoinName, amount, sender);
373
- if (totalAmount === 0) {
374
- const { leftCoin, takeCoin: walletMarketCoins } =
375
- await builder.selectMarketCoin(
376
- txBlock,
377
- marketCoinName,
378
- amount,
379
- sender
380
- );
381
- txBlock.transferObjects([leftCoin], sender);
382
- return txBlock.withdraw(walletMarketCoins, poolCoinName);
383
- }
384
-
385
- txBlock.transferObjects([leftCoin], sender);
386
- const marketCoins = txBlock.burnSCoin(sCoinName, sCoins);
365
+ // eslint-disable-next-line prefer-const
366
+ let { sCoin, marketCoin } = await builder.selectSCoinOrMarketCoin(
367
+ txBlock,
368
+ sCoinName,
369
+ amount,
370
+ sender
371
+ );
387
372
 
388
- // check amount
389
- amount -= totalAmount;
390
- try {
391
- if (amount > 0) {
392
- // sCoin is not enough, try market coin
393
- const { leftCoin, takeCoin: walletMarketCoins } =
394
- await builder.selectMarketCoin(
395
- txBlock,
396
- marketCoinName,
397
- amount,
398
- sender
399
- );
400
- txBlock.transferObjects([leftCoin], sender);
401
- txBlock.mergeCoins(marketCoins, [walletMarketCoins]);
373
+ if (sCoin) {
374
+ const newMarketCoin = txBlock.burnSCoin(sCoinName, sCoin);
375
+ if (marketCoin) {
376
+ txBlock.mergeCoins(marketCoin, newMarketCoin);
377
+ } else {
378
+ marketCoin = newMarketCoin;
402
379
  }
403
- } catch (_e) {
404
- // ignore
405
380
  }
406
- return txBlock.withdraw(marketCoins, poolCoinName);
381
+
382
+ if (!marketCoin) throw new Error(`No market coin for ${poolCoinName}`);
383
+ return txBlock.withdraw(marketCoin, poolCoinName);
407
384
  },
408
385
  borrowQuick: async (amount, poolCoinName, obligationId, obligationKey) => {
409
386
  const obligationInfo = await requireObligationInfo(
@@ -61,7 +61,7 @@ const generateSCoinQuickMethod: GenerateSCoinQuickMethod = ({
61
61
  );
62
62
 
63
63
  txBlock.transferObjects([leftCoin], sender);
64
- return await txBlock.mintSCoin(marketCoinName, takeCoin);
64
+ return txBlock.mintSCoin(marketCoinName, takeCoin);
65
65
  },
66
66
  burnSCoinQuick: async (sCoinName, amount) => {
67
67
  const sender = requireSender(txBlock);
@@ -73,7 +73,7 @@ const generateSCoinQuickMethod: GenerateSCoinQuickMethod = ({
73
73
  );
74
74
 
75
75
  txBlock.transferObjects([leftCoin], sender);
76
- return await txBlock.burnSCoin(sCoinName, takeCoin);
76
+ return txBlock.burnSCoin(sCoinName, takeCoin);
77
77
  },
78
78
  };
79
79
  };
@@ -5,7 +5,10 @@ import { ScallopAddress } from './scallopAddress';
5
5
  import { ScallopQuery } from './scallopQuery';
6
6
  import { ScallopUtils } from './scallopUtils';
7
7
  import type { SuiTransactionBlockResponse } from '@mysten/sui/client';
8
- import type { Transaction } from '@mysten/sui/transactions';
8
+ import type {
9
+ Transaction,
10
+ TransactionObjectArgument,
11
+ } from '@mysten/sui/transactions';
9
12
  import type {
10
13
  SuiAmountsArg,
11
14
  SuiTxBlock as SuiKitTxBlock,
@@ -201,6 +204,79 @@ export class ScallopBuilder {
201
204
  };
202
205
  }
203
206
 
207
+ /**
208
+ * Select sCoin or market coin automatically. Prioritize sCoin first
209
+ */
210
+ public async selectSCoinOrMarketCoin(
211
+ txBlock: ScallopTxBlock | SuiKitTxBlock,
212
+ sCoinName: string,
213
+ amount: number,
214
+ sender: string = this.walletAddress
215
+ ) {
216
+ let totalAmount = amount;
217
+ const result = {
218
+ sCoins: [] as TransactionObjectArgument[],
219
+ marketCoins: [] as TransactionObjectArgument[],
220
+ leftCoins: [] as TransactionObjectArgument[],
221
+ };
222
+ try {
223
+ // try sCoin first
224
+ const {
225
+ leftCoin,
226
+ takeCoin,
227
+ totalAmount: sCoinAmount,
228
+ } = await this.selectSCoin(txBlock, sCoinName, totalAmount, sender);
229
+ result.leftCoins.push(leftCoin);
230
+ result.sCoins.push(takeCoin);
231
+ totalAmount -= sCoinAmount;
232
+
233
+ if (totalAmount > 0) {
234
+ // sCoin is not enough, try market coin
235
+ const { leftCoin, takeCoin: marketCoin } = await this.selectMarketCoin(
236
+ txBlock,
237
+ sCoinName,
238
+ amount,
239
+ sender
240
+ );
241
+ txBlock.transferObjects([leftCoin], sender);
242
+ result.marketCoins.push(marketCoin);
243
+ }
244
+ } catch (_e) {
245
+ // no sCoin, try market coin
246
+ const { takeCoin: marketCoin, leftCoin } = await this.selectMarketCoin(
247
+ txBlock,
248
+ sCoinName,
249
+ amount,
250
+ sender
251
+ );
252
+ result.leftCoins.push(leftCoin);
253
+ result.marketCoins.push(marketCoin);
254
+ }
255
+
256
+ txBlock.transferObjects(result.leftCoins, sender);
257
+
258
+ // merge sCoins and marketCoins
259
+ const mergedMarketCoins =
260
+ result.marketCoins.length > 0
261
+ ? result.marketCoins.length > 1
262
+ ? txBlock.mergeCoins(
263
+ result.marketCoins[0],
264
+ result.marketCoins.slice(1)
265
+ )
266
+ : result.marketCoins[0]
267
+ : undefined;
268
+ const mergedSCoins =
269
+ result.sCoins.length > 0
270
+ ? result.sCoins.length > 1
271
+ ? txBlock.mergeCoins(result.sCoins[0], result.sCoins.slice(1))
272
+ : result.sCoins[0]
273
+ : undefined;
274
+ return {
275
+ sCoin: mergedSCoins,
276
+ marketCoin: mergedMarketCoins,
277
+ };
278
+ }
279
+
204
280
  /**
205
281
  * Execute Scallop txBlock using the `signAndSendTxn` methods in suikit.
206
282
  *
@@ -82,7 +82,7 @@ export class ScallopCache {
82
82
  private lastRefill: number;
83
83
 
84
84
  public constructor(
85
- params: ScallopCacheParams,
85
+ params: ScallopCacheParams = {},
86
86
  instance?: ScallopCacheInstanceParams
87
87
  ) {
88
88
  this.params = params;
@@ -210,7 +210,7 @@ export class ScallopConstants {
210
210
  if (this.isEmptyObject(this._coinNameToOldMarketCoinTypeMap))
211
211
  this._coinNameToOldMarketCoinTypeMap = Object.fromEntries(
212
212
  Object.entries(this.poolAddresses)
213
- .filter(([_, value]) => !!value && value.spool)
213
+ .filter(([_, value]) => !!value)
214
214
  .map(([_, value]) => [
215
215
  value!.coinName,
216
216
  this.parseToOldMarketCoin(value!.coinType),
@@ -852,7 +852,7 @@ export const getUserPortfolio = async (
852
852
  walletAddress: string,
853
853
  indexer: boolean = false
854
854
  ) => {
855
- const coinPrices = await query.utils.getCoinPrices();
855
+ const coinPrices = await query.getAllCoinPrices({ indexer });
856
856
  const market = await query.getMarketPools(undefined, { indexer, coinPrices });
857
857
 
858
858
  const [lendings, obligationAccounts, borrowIncentivePools, veScas] =
@@ -953,19 +953,22 @@ export const getUserPortfolio = async (
953
953
  };
954
954
  });
955
955
 
956
+ const LENDING_SPOOL_REWARD_COIN_NAME = 'sui' as const;
957
+ const LENDING_SPOOL_REWARD_COIN_SYMBOL = 'SUI' as const;
956
958
  const pendingLendingRewards = Object.values(lendings).reduce(
957
959
  (acc, reward) => {
958
960
  if (reward) {
959
961
  if (reward.availableClaimCoin === 0) return acc;
960
- if (!acc[reward.symbol]) {
961
- acc[reward.symbol] = {
962
- symbol: reward.symbol,
962
+ if (!acc[LENDING_SPOOL_REWARD_COIN_NAME]) {
963
+ acc[LENDING_SPOOL_REWARD_COIN_NAME] = {
964
+ symbol: LENDING_SPOOL_REWARD_COIN_SYMBOL,
963
965
  coinType: normalizeStructTag(SUI_TYPE_ARG), // @TODO: for now lending reward is all in SUI
964
- coinPrice: reward.coinPrice,
966
+ coinPrice: coinPrices[LENDING_SPOOL_REWARD_COIN_NAME] ?? 0,
965
967
  pendingRewardInCoin: reward.availableClaimCoin,
966
968
  };
967
969
  } else {
968
- acc[reward.symbol].pendingRewardInCoin += reward.availableClaimCoin;
970
+ acc[LENDING_SPOOL_REWARD_COIN_NAME].pendingRewardInCoin +=
971
+ reward.availableClaimCoin;
969
972
  }
970
973
  }
971
974
  return acc;
@@ -1054,10 +1057,10 @@ export const getUserPortfolio = async (
1054
1057
  borrowings: parsedObligationAccounts,
1055
1058
  pendingRewards: {
1056
1059
  lendings: Object.entries(pendingLendingRewards).reduce(
1057
- (acc, [key, value]) => {
1060
+ (acc, [_, value]) => {
1058
1061
  acc.push({
1059
1062
  ...value,
1060
- coinName: key,
1063
+ coinName: 'sui',
1061
1064
  pendingRewardInUsd: value.coinPrice * value.pendingRewardInCoin,
1062
1065
  });
1063
1066
  return acc;