@suilend/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/client.js CHANGED
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import { SUI_CLOCK_OBJECT_ID, SUI_SYSTEM_STATE_OBJECT_ID, fromBase64, normalizeStructTag, toHex, } from "@mysten/sui/utils";
11
11
  import { SuiPriceServiceConnection, SuiPythClient, } from "@pythnetwork/pyth-sui-js";
12
- import { extractCTokenCoinType, getAllCoins, mergeAllCoins, } from "@suilend/sui-fe";
12
+ import { extractCTokenCoinType, getAllCoins, getSpendableCoin, } from "@suilend/sui-fe";
13
13
  import { PriceInfoObject } from "./_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-info/structs";
14
14
  import { phantom } from "./_generated/_framework/reified";
15
15
  import { PKG_V10, setPublishedAt } from "./_generated/suilend";
@@ -221,16 +221,7 @@ export class SuilendClient {
221
221
  }
222
222
  addReward(ownerId_1, lendingMarketOwnerCapId_1, reserveArrayIndex_1, isDepositReward_1, rewardCoinType_1, rewardValue_1, startTimeMs_1, endTimeMs_1, transaction_1) {
223
223
  return __awaiter(this, arguments, void 0, function* (ownerId, lendingMarketOwnerCapId, reserveArrayIndex, isDepositReward, rewardCoinType, rewardValue, startTimeMs, endTimeMs, transaction, mergeCoins = true) {
224
- const coins = (yield this.client.getCoins({
225
- owner: ownerId,
226
- coinType: rewardCoinType,
227
- })).data;
228
- if (coins.length > 1 && !isSui(rewardCoinType) && mergeCoins) {
229
- transaction.mergeCoins(transaction.object(coins[0].coinObjectId), coins.map((c) => transaction.object(c.coinObjectId)).slice(1));
230
- }
231
- const [rewardCoin] = transaction.splitCoins(isSui(rewardCoinType)
232
- ? transaction.gas
233
- : transaction.object(coins[0].coinObjectId), [rewardValue]);
224
+ const rewardCoin = yield getSpendableCoin(this.client, ownerId, rewardCoinType, rewardValue, transaction);
234
225
  return addPoolReward(transaction, [this.lendingMarket.$typeArgs[0], rewardCoinType], {
235
226
  lendingMarketOwnerCap: transaction.object(lendingMarketOwnerCapId),
236
227
  lendingMarket: transaction.object(this.lendingMarket.id),
@@ -454,21 +445,13 @@ export class SuilendClient {
454
445
  }
455
446
  depositIntoObligation(ownerId, coinType, value, transaction, obligationOwnerCap) {
456
447
  return __awaiter(this, void 0, void 0, function* () {
457
- const coins = yield getAllCoins(this.client, ownerId, coinType);
458
- const mergeCoin = mergeAllCoins(coinType, transaction, coins);
459
- const [sendCoin] = transaction.splitCoins(isSui(coinType)
460
- ? transaction.gas
461
- : transaction.object(mergeCoin.coinObjectId), [value]);
448
+ const sendCoin = yield getSpendableCoin(this.client, ownerId, coinType, value, transaction);
462
449
  this.deposit(sendCoin, coinType, obligationOwnerCap, transaction);
463
450
  });
464
451
  }
465
452
  depositLiquidityAndGetCTokens(ownerId, coinType, value, transaction) {
466
453
  return __awaiter(this, void 0, void 0, function* () {
467
- const coins = yield getAllCoins(this.client, ownerId, coinType);
468
- const mergeCoin = mergeAllCoins(coinType, transaction, coins);
469
- const [sendCoin] = transaction.splitCoins(isSui(coinType)
470
- ? transaction.gas
471
- : transaction.object(mergeCoin.coinObjectId), [value]);
454
+ const sendCoin = yield getSpendableCoin(this.client, ownerId, coinType, value, transaction);
472
455
  const [ctokens] = depositLiquidityAndMintCtokens(transaction, [this.lendingMarket.$typeArgs[0], coinType], {
473
456
  lendingMarket: transaction.object(this.lendingMarket.id),
474
457
  reserveArrayIndex: transaction.pure.u64(this.findReserveArrayIndex(coinType)),
@@ -578,11 +561,7 @@ export class SuilendClient {
578
561
  }
579
562
  repayIntoObligation(ownerId, obligationId, coinType, value, transaction) {
580
563
  return __awaiter(this, void 0, void 0, function* () {
581
- const coins = yield getAllCoins(this.client, ownerId, coinType);
582
- const mergeCoin = mergeAllCoins(coinType, transaction, coins);
583
- const [sendCoin] = transaction.splitCoins(isSui(coinType)
584
- ? transaction.gas
585
- : transaction.object(mergeCoin.coinObjectId), [value]);
564
+ const sendCoin = yield getSpendableCoin(this.client, ownerId, coinType, value, transaction);
586
565
  const result = this.repay(obligationId, coinType, sendCoin, transaction);
587
566
  transaction.transferObjects([sendCoin], transaction.pure.address(ownerId));
588
567
  return result;
@@ -637,13 +616,12 @@ export class SuilendClient {
637
616
  }
638
617
  redeemCtokensAndWithdrawLiquidity(ownerId, ctokenCoinTypes, transaction) {
639
618
  return __awaiter(this, void 0, void 0, function* () {
640
- const mergeCoinMap = {};
641
619
  for (const ctokenCoinType of ctokenCoinTypes) {
642
620
  const coins = yield getAllCoins(this.client, ownerId, ctokenCoinType);
643
- const mergeCoin = mergeAllCoins(ctokenCoinType, transaction, coins);
644
- mergeCoinMap[ctokenCoinType] = mergeCoin;
645
- }
646
- for (const [ctokenCoinType, mergeCoin] of Object.entries(mergeCoinMap)) {
621
+ const totalBalance = coins.reduce((sum, c) => sum + BigInt(c.balance), BigInt(0));
622
+ if (totalBalance === BigInt(0))
623
+ throw new Error(`No ${ctokenCoinType} coins found for redeem`);
624
+ const ctokenCoin = yield getSpendableCoin(this.client, ownerId, ctokenCoinType, totalBalance.toString(), transaction);
647
625
  const coinType = extractCTokenCoinType(ctokenCoinType);
648
626
  const [exemption] = transaction.moveCall({
649
627
  target: `0x1::option::none`,
@@ -652,7 +630,7 @@ export class SuilendClient {
652
630
  ],
653
631
  arguments: [],
654
632
  });
655
- const [redeemCoin] = this.redeem(transaction.object(mergeCoin.coinObjectId), coinType, exemption, transaction);
633
+ const [redeemCoin] = this.redeem(ctokenCoin, coinType, exemption, transaction);
656
634
  transaction.transferObjects([redeemCoin], transaction.pure.address(ownerId));
657
635
  }
658
636
  });
package/lib/initialize.js CHANGED
@@ -16,7 +16,7 @@ import { parseLendingMarket, parseObligation } from "../parsers";
16
16
  import * as simulate from "../utils/simulate";
17
17
  import { WAD } from "./constants";
18
18
  import { getWorkingPythEndpoint } from "./pyth";
19
- import { STRATEGY_WRAPPER_PACKAGE_ID_V1, } from "./strategyOwnerCap";
19
+ import { STRATEGY_TYPE_INFO_MAP, STRATEGY_WRAPPER_PACKAGE_ID_V1, } from "./strategyOwnerCap";
20
20
  export const RESERVES_CUSTOM_ORDER = {
21
21
  [LENDING_MARKET_ID]: [
22
22
  // MAIN ASSETS
@@ -232,8 +232,9 @@ export const initializeObligations = (suiClient, suilendClient, refreshedRawRese
232
232
  };
233
233
  const [strategyOwnerCaps, obligationOwnerCaps] = yield Promise.all([
234
234
  (() => __awaiter(void 0, void 0, void 0, function* () {
235
- if (suilendClient.lendingMarket.id !== LENDING_MARKET_ID)
236
- return []; // Only main lending market has strategy owner caps
235
+ const hasStrategies = Object.values(STRATEGY_TYPE_INFO_MAP).some((info) => info.lendingMarketId === suilendClient.lendingMarket.id);
236
+ if (!hasStrategies)
237
+ return [];
237
238
  const objects = yield getAllOwnedObjects(suiClient, address, {
238
239
  StructType: `${STRATEGY_WRAPPER_PACKAGE_ID_V1}::strategy_wrapper::StrategyOwnerCap<${suilendClient.lendingMarket.$typeArgs[0]}>`,
239
240
  });
@@ -1,22 +1,27 @@
1
1
  import { AggregatorClient as CetusSdk } from "@cetusprotocol/aggregator-sdk";
2
- import { Transaction, TransactionObjectInput, TransactionResult } from "@mysten/sui/transactions";
2
+ import { Transaction, TransactionObjectArgument, TransactionObjectInput, TransactionResult } from "@mysten/sui/transactions";
3
3
  import BigNumber from "bignumber.js";
4
4
  import { ParsedObligation, ParsedReserve } from "../parsers";
5
5
  import { RewardsMap, StrategyOwnerCap } from "./types";
6
6
  export declare const STRATEGY_WRAPPER_PACKAGE_ID_V1 = "0xba97dc73a07638d03d77ad2161484eb21db577edc9cadcd7035fef4b4f2f6fa1";
7
7
  export declare enum StrategyType {
8
8
  sSUI_SUI_LOOPING = "1",
9
- stratSUI_SUI_LOOPING = "2",
10
9
  USDC_sSUI_SUI_LOOPING = "3",
10
+ USDsui_USDC_LOOPING = "10",
11
+ eEARN_USDC_LOOPING = "11",
11
12
  AUSD_sSUI_SUI_LOOPING = "4",
12
13
  xBTC_sSUI_SUI_LOOPING = "100",// Used to be for Slush Strategies #0
13
14
  xBTC_suiWBTC_LOOPING = "101",// Used to be for Slush Strategies #1
14
15
  suiUSDT_sSUI_SUI_LOOPING = "5",
15
16
  AUSD_USDC_LOOPING = "6",
16
17
  AUSD_suiUSDT_LOOPING = "7",
17
- USDC_suiUSDT_LOOPING = "8"
18
+ USDC_suiUSDT_LOOPING = "8",
19
+ USDsui_sSUI_SUI_LOOPING = "9",
20
+ stratSUI_SUI_LOOPING = "2"
18
21
  }
19
22
  export declare const STRATEGY_TYPE_INFO_MAP: Record<StrategyType, {
23
+ lendingMarketId: string;
24
+ lendingMarketType: string;
20
25
  queryParam: string;
21
26
  header: {
22
27
  coinTypes: string[];
@@ -30,10 +35,10 @@ export declare const STRATEGY_TYPE_INFO_MAP: Record<StrategyType, {
30
35
  currencyCoinTypes: string[];
31
36
  defaultCurrencyCoinType: string;
32
37
  }>;
33
- export declare const strategyDeposit: (coin: TransactionObjectInput, coinType: string, strategyOwnerCap: TransactionObjectInput, reserveArrayIndex: bigint, transaction: Transaction) => TransactionResult;
34
- export declare const strategyBorrow: (coinType: string, strategyOwnerCap: TransactionObjectInput, reserveArrayIndex: bigint, value: bigint, transaction: Transaction) => TransactionResult;
35
- export declare const strategyWithdraw: (coinType: string, strategyOwnerCap: TransactionObjectInput, reserveArrayIndex: bigint, value: bigint, transaction: Transaction) => TransactionResult;
36
- export declare const strategyClaimRewardsAndSwapForCoinType: (address: string, cetusSdk: CetusSdk, cetusPartnerId: string, rewardsMap: RewardsMap, rewardPriceMap: Record<string, BigNumber | undefined>, depositReserve: ParsedReserve, strategyOwnerCap: TransactionObjectInput, isDepositing: boolean, transaction: Transaction) => Promise<void>;
38
+ export declare const strategyDeposit: (strategyType: StrategyType, coin: TransactionObjectInput, coinType: string, strategyOwnerCap: TransactionObjectInput, reserveArrayIndex: bigint, transaction: Transaction) => TransactionResult;
39
+ export declare const strategyBorrow: (strategyType: StrategyType, coinType: string, strategyOwnerCap: TransactionObjectInput, reserveArrayIndex: bigint, value: bigint, transaction: Transaction) => TransactionResult;
40
+ export declare const strategyWithdraw: (strategyType: StrategyType, coinType: string, strategyOwnerCap: TransactionObjectInput, reserveArrayIndex: bigint, value: bigint, transaction: Transaction) => TransactionResult;
41
+ export declare const strategyClaimRewardsAndMergeCoins: (strategyType: StrategyType, rewardsMap: RewardsMap, strategyOwnerCap: TransactionObjectInput, transaction: Transaction) => Record<string, TransactionObjectArgument>;
37
42
  export declare const strategySwapSomeDepositsForCoinType: (strategyType: StrategyType, cetusSdk: CetusSdk, cetusPartnerId: string, obligation: ParsedObligation, noSwapCoinTypes: string[], // coinTypes to not swap for depositReserve.coinType
38
43
  swapPercent: BigNumber, // percent of deposit to swap for depositReserve.coinType (0-100)
39
44
  depositReserve: ParsedReserve, strategyOwnerCap: TransactionObjectInput, transaction: Transaction) => Promise<void>;
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  import { SUI_CLOCK_OBJECT_ID, SUI_SYSTEM_STATE_OBJECT_ID, } from "@mysten/sui/utils";
11
11
  import BigNumber from "bignumber.js";
12
12
  import BN from "bn.js";
13
- import { MAX_U64, NORMALIZED_AUSD_COINTYPE, NORMALIZED_SUI_COINTYPE, NORMALIZED_USDC_COINTYPE, NORMALIZED_sSUI_COINTYPE, NORMALIZED_stratSUI_COINTYPE, NORMALIZED_suiUSDT_COINTYPE, NORMALIZED_suiWBTC_COINTYPE, NORMALIZED_xBTC_COINTYPE, isSui, } from "@suilend/sui-fe";
13
+ import { MAX_U64, NORMALIZED_AUSD_COINTYPE, NORMALIZED_SUI_COINTYPE, NORMALIZED_USDC_COINTYPE, NORMALIZED_USDsui_COINTYPE, NORMALIZED_eEARN_COINTYPE, NORMALIZED_sSUI_COINTYPE, NORMALIZED_stratSUI_COINTYPE, NORMALIZED_suiUSDT_COINTYPE, NORMALIZED_suiWBTC_COINTYPE, NORMALIZED_xBTC_COINTYPE, isSui, } from "@suilend/sui-fe";
14
14
  import { LENDING_MARKET_ID, LENDING_MARKET_TYPE, } from "../client";
15
15
  import { Side } from "./types";
16
16
  export const STRATEGY_WRAPPER_PACKAGE_ID_V1 = "0xba97dc73a07638d03d77ad2161484eb21db577edc9cadcd7035fef4b4f2f6fa1";
@@ -18,8 +18,9 @@ const STRATEGY_WRAPPER_PACKAGE_ID_V7 = "0x864b66441e95323c320ee7584592769930a2d2
18
18
  export var StrategyType;
19
19
  (function (StrategyType) {
20
20
  StrategyType["sSUI_SUI_LOOPING"] = "1";
21
- StrategyType["stratSUI_SUI_LOOPING"] = "2";
22
21
  StrategyType["USDC_sSUI_SUI_LOOPING"] = "3";
22
+ StrategyType["USDsui_USDC_LOOPING"] = "10";
23
+ StrategyType["eEARN_USDC_LOOPING"] = "11";
23
24
  StrategyType["AUSD_sSUI_SUI_LOOPING"] = "4";
24
25
  StrategyType["xBTC_sSUI_SUI_LOOPING"] = "100";
25
26
  StrategyType["xBTC_suiWBTC_LOOPING"] = "101";
@@ -27,9 +28,13 @@ export var StrategyType;
27
28
  StrategyType["AUSD_USDC_LOOPING"] = "6";
28
29
  StrategyType["AUSD_suiUSDT_LOOPING"] = "7";
29
30
  StrategyType["USDC_suiUSDT_LOOPING"] = "8";
31
+ StrategyType["USDsui_sSUI_SUI_LOOPING"] = "9";
32
+ StrategyType["stratSUI_SUI_LOOPING"] = "2";
30
33
  })(StrategyType || (StrategyType = {}));
31
34
  export const STRATEGY_TYPE_INFO_MAP = {
32
35
  [StrategyType.sSUI_SUI_LOOPING]: {
36
+ lendingMarketId: LENDING_MARKET_ID,
37
+ lendingMarketType: LENDING_MARKET_TYPE,
33
38
  queryParam: "sSUI-SUI-looping",
34
39
  header: {
35
40
  coinTypes: [NORMALIZED_sSUI_COINTYPE, NORMALIZED_SUI_COINTYPE],
@@ -43,21 +48,9 @@ export const STRATEGY_TYPE_INFO_MAP = {
43
48
  currencyCoinTypes: [NORMALIZED_SUI_COINTYPE, NORMALIZED_sSUI_COINTYPE],
44
49
  defaultCurrencyCoinType: NORMALIZED_SUI_COINTYPE,
45
50
  },
46
- [StrategyType.stratSUI_SUI_LOOPING]: {
47
- queryParam: "stratSUI-SUI-looping",
48
- header: {
49
- coinTypes: [NORMALIZED_stratSUI_COINTYPE, NORMALIZED_SUI_COINTYPE],
50
- title: "stratSUI/SUI",
51
- tooltip: "Sets up a stratSUI/SUI Looping strategy by depositing stratSUI and borrowing SUI to the desired leverage",
52
- type: "Looping",
53
- },
54
- depositBaseCoinType: undefined,
55
- depositLstCoinType: NORMALIZED_stratSUI_COINTYPE,
56
- borrowCoinType: NORMALIZED_SUI_COINTYPE,
57
- currencyCoinTypes: [NORMALIZED_SUI_COINTYPE, NORMALIZED_stratSUI_COINTYPE],
58
- defaultCurrencyCoinType: NORMALIZED_SUI_COINTYPE,
59
- },
60
51
  [StrategyType.USDC_sSUI_SUI_LOOPING]: {
52
+ lendingMarketId: LENDING_MARKET_ID,
53
+ lendingMarketType: LENDING_MARKET_TYPE,
61
54
  queryParam: "USDC-sSUI-SUI-looping",
62
55
  header: {
63
56
  coinTypes: [NORMALIZED_USDC_COINTYPE],
@@ -71,7 +64,41 @@ export const STRATEGY_TYPE_INFO_MAP = {
71
64
  currencyCoinTypes: [NORMALIZED_USDC_COINTYPE],
72
65
  defaultCurrencyCoinType: NORMALIZED_USDC_COINTYPE,
73
66
  },
67
+ [StrategyType.USDsui_USDC_LOOPING]: {
68
+ lendingMarketId: LENDING_MARKET_ID,
69
+ lendingMarketType: LENDING_MARKET_TYPE,
70
+ queryParam: "USDsui-USDC-looping",
71
+ header: {
72
+ coinTypes: [NORMALIZED_USDsui_COINTYPE, NORMALIZED_USDC_COINTYPE],
73
+ title: "USDsui/USDC",
74
+ tooltip: "Sets up an USDsui/USDC Looping strategy by depositing USDsui and borrowing USDC to the desired leverage",
75
+ type: "Looping",
76
+ },
77
+ depositBaseCoinType: NORMALIZED_USDsui_COINTYPE,
78
+ depositLstCoinType: undefined,
79
+ borrowCoinType: NORMALIZED_USDC_COINTYPE,
80
+ currencyCoinTypes: [NORMALIZED_USDsui_COINTYPE, NORMALIZED_USDC_COINTYPE],
81
+ defaultCurrencyCoinType: NORMALIZED_USDsui_COINTYPE,
82
+ },
83
+ [StrategyType.eEARN_USDC_LOOPING]: {
84
+ lendingMarketId: "0x74d92cb095b618f344486f77bcce87fbffc0fe0b46584bb1828bb291a222dda8",
85
+ lendingMarketType: "0x423f05ea163ae1bc5c03d75ef70d3e5d887455084118e46c4f76878530a03619::ember_market::EMBER_MARKET",
86
+ queryParam: "eEARN-USDC-looping",
87
+ header: {
88
+ coinTypes: [NORMALIZED_eEARN_COINTYPE, NORMALIZED_USDC_COINTYPE],
89
+ title: "eEARN/USDC",
90
+ tooltip: "Sets up an eEARN/USDC Looping strategy by depositing eEARN and borrowing USDC to the desired leverage",
91
+ type: "Looping",
92
+ },
93
+ depositBaseCoinType: NORMALIZED_eEARN_COINTYPE,
94
+ depositLstCoinType: undefined,
95
+ borrowCoinType: NORMALIZED_USDC_COINTYPE,
96
+ currencyCoinTypes: [NORMALIZED_eEARN_COINTYPE, NORMALIZED_USDC_COINTYPE],
97
+ defaultCurrencyCoinType: NORMALIZED_eEARN_COINTYPE,
98
+ },
74
99
  [StrategyType.AUSD_sSUI_SUI_LOOPING]: {
100
+ lendingMarketId: LENDING_MARKET_ID,
101
+ lendingMarketType: LENDING_MARKET_TYPE,
75
102
  queryParam: "AUSD-sSUI-SUI-looping",
76
103
  header: {
77
104
  coinTypes: [NORMALIZED_AUSD_COINTYPE],
@@ -86,6 +113,8 @@ export const STRATEGY_TYPE_INFO_MAP = {
86
113
  defaultCurrencyCoinType: NORMALIZED_AUSD_COINTYPE,
87
114
  },
88
115
  [StrategyType.xBTC_sSUI_SUI_LOOPING]: {
116
+ lendingMarketId: LENDING_MARKET_ID,
117
+ lendingMarketType: LENDING_MARKET_TYPE,
89
118
  queryParam: "xBTC-sSUI-SUI-looping",
90
119
  header: {
91
120
  coinTypes: [NORMALIZED_xBTC_COINTYPE],
@@ -100,6 +129,8 @@ export const STRATEGY_TYPE_INFO_MAP = {
100
129
  defaultCurrencyCoinType: NORMALIZED_xBTC_COINTYPE,
101
130
  },
102
131
  [StrategyType.xBTC_suiWBTC_LOOPING]: {
132
+ lendingMarketId: LENDING_MARKET_ID,
133
+ lendingMarketType: LENDING_MARKET_TYPE,
103
134
  queryParam: "xBTC-suiWBTC-looping",
104
135
  header: {
105
136
  coinTypes: [NORMALIZED_xBTC_COINTYPE, NORMALIZED_suiWBTC_COINTYPE],
@@ -114,6 +145,8 @@ export const STRATEGY_TYPE_INFO_MAP = {
114
145
  defaultCurrencyCoinType: NORMALIZED_xBTC_COINTYPE,
115
146
  },
116
147
  [StrategyType.suiUSDT_sSUI_SUI_LOOPING]: {
148
+ lendingMarketId: LENDING_MARKET_ID,
149
+ lendingMarketType: LENDING_MARKET_TYPE,
117
150
  queryParam: "suiUSDT-sSUI-SUI-looping",
118
151
  header: {
119
152
  coinTypes: [NORMALIZED_suiUSDT_COINTYPE],
@@ -128,6 +161,8 @@ export const STRATEGY_TYPE_INFO_MAP = {
128
161
  defaultCurrencyCoinType: NORMALIZED_suiUSDT_COINTYPE,
129
162
  },
130
163
  [StrategyType.AUSD_USDC_LOOPING]: {
164
+ lendingMarketId: LENDING_MARKET_ID,
165
+ lendingMarketType: LENDING_MARKET_TYPE,
131
166
  queryParam: "AUSD-USDC-looping",
132
167
  header: {
133
168
  coinTypes: [NORMALIZED_AUSD_COINTYPE, NORMALIZED_USDC_COINTYPE],
@@ -142,6 +177,8 @@ export const STRATEGY_TYPE_INFO_MAP = {
142
177
  defaultCurrencyCoinType: NORMALIZED_AUSD_COINTYPE,
143
178
  },
144
179
  [StrategyType.AUSD_suiUSDT_LOOPING]: {
180
+ lendingMarketId: LENDING_MARKET_ID,
181
+ lendingMarketType: LENDING_MARKET_TYPE,
145
182
  queryParam: "AUSD-suiUSDT-looping",
146
183
  header: {
147
184
  coinTypes: [NORMALIZED_AUSD_COINTYPE, NORMALIZED_suiUSDT_COINTYPE],
@@ -156,6 +193,8 @@ export const STRATEGY_TYPE_INFO_MAP = {
156
193
  defaultCurrencyCoinType: NORMALIZED_AUSD_COINTYPE,
157
194
  },
158
195
  [StrategyType.USDC_suiUSDT_LOOPING]: {
196
+ lendingMarketId: LENDING_MARKET_ID,
197
+ lendingMarketType: LENDING_MARKET_TYPE,
159
198
  queryParam: "USDC-suiUSDT-looping",
160
199
  header: {
161
200
  coinTypes: [NORMALIZED_USDC_COINTYPE, NORMALIZED_suiUSDT_COINTYPE],
@@ -169,66 +208,117 @@ export const STRATEGY_TYPE_INFO_MAP = {
169
208
  currencyCoinTypes: [NORMALIZED_USDC_COINTYPE, NORMALIZED_suiUSDT_COINTYPE],
170
209
  defaultCurrencyCoinType: NORMALIZED_USDC_COINTYPE,
171
210
  },
211
+ [StrategyType.USDsui_sSUI_SUI_LOOPING]: {
212
+ lendingMarketId: LENDING_MARKET_ID,
213
+ lendingMarketType: LENDING_MARKET_TYPE,
214
+ queryParam: "USDsui-sSUI-SUI-looping",
215
+ header: {
216
+ coinTypes: [NORMALIZED_USDsui_COINTYPE],
217
+ title: "USDsui sSUI/SUI",
218
+ tooltip: "Sets up a USDsui sSUI/SUI Looping strategy by depositing USDsui and looping sSUI/SUI to the desired leverage",
219
+ type: "Looping",
220
+ },
221
+ depositBaseCoinType: NORMALIZED_USDsui_COINTYPE,
222
+ depositLstCoinType: NORMALIZED_sSUI_COINTYPE,
223
+ borrowCoinType: NORMALIZED_SUI_COINTYPE,
224
+ currencyCoinTypes: [NORMALIZED_USDsui_COINTYPE],
225
+ defaultCurrencyCoinType: NORMALIZED_USDsui_COINTYPE,
226
+ },
227
+ [StrategyType.stratSUI_SUI_LOOPING]: {
228
+ lendingMarketId: LENDING_MARKET_ID,
229
+ lendingMarketType: LENDING_MARKET_TYPE,
230
+ queryParam: "stratSUI-SUI-looping",
231
+ header: {
232
+ coinTypes: [NORMALIZED_stratSUI_COINTYPE, NORMALIZED_SUI_COINTYPE],
233
+ title: "stratSUI/SUI",
234
+ tooltip: "Sets up a stratSUI/SUI Looping strategy by depositing stratSUI and borrowing SUI to the desired leverage",
235
+ type: "Looping",
236
+ },
237
+ depositBaseCoinType: undefined,
238
+ depositLstCoinType: NORMALIZED_stratSUI_COINTYPE,
239
+ borrowCoinType: NORMALIZED_SUI_COINTYPE,
240
+ currencyCoinTypes: [NORMALIZED_SUI_COINTYPE, NORMALIZED_stratSUI_COINTYPE],
241
+ defaultCurrencyCoinType: NORMALIZED_SUI_COINTYPE,
242
+ },
172
243
  };
173
- export const strategyDeposit = (coin, coinType, strategyOwnerCap, reserveArrayIndex, transaction) => transaction.moveCall({
174
- target: `${STRATEGY_WRAPPER_PACKAGE_ID_V7}::strategy_wrapper::deposit_liquidity_and_deposit_into_obligation`,
175
- typeArguments: [LENDING_MARKET_TYPE, coinType],
176
- arguments: [
177
- transaction.object(strategyOwnerCap),
178
- transaction.object(LENDING_MARKET_ID),
179
- transaction.pure.u64(reserveArrayIndex),
180
- transaction.object(SUI_CLOCK_OBJECT_ID),
181
- transaction.object(coin),
182
- ],
183
- });
184
- export const strategyBorrow = (coinType, strategyOwnerCap, reserveArrayIndex, value, transaction) => isSui(coinType)
185
- ? transaction.moveCall({
186
- target: `${STRATEGY_WRAPPER_PACKAGE_ID_V7}::strategy_wrapper::borrow_sui_from_obligation`,
187
- typeArguments: [LENDING_MARKET_TYPE],
244
+ const getStrategyLendingMarket = (strategyType) => {
245
+ const info = STRATEGY_TYPE_INFO_MAP[strategyType];
246
+ return {
247
+ lendingMarketId: info.lendingMarketId,
248
+ lendingMarketType: info.lendingMarketType,
249
+ };
250
+ };
251
+ export const strategyDeposit = (strategyType, coin, coinType, strategyOwnerCap, reserveArrayIndex, transaction) => {
252
+ const { lendingMarketId, lendingMarketType } = getStrategyLendingMarket(strategyType);
253
+ return transaction.moveCall({
254
+ target: `${STRATEGY_WRAPPER_PACKAGE_ID_V7}::strategy_wrapper::deposit_liquidity_and_deposit_into_obligation`,
255
+ typeArguments: [lendingMarketType, coinType],
188
256
  arguments: [
189
257
  transaction.object(strategyOwnerCap),
190
- transaction.object(LENDING_MARKET_ID),
258
+ transaction.object(lendingMarketId),
191
259
  transaction.pure.u64(reserveArrayIndex),
192
260
  transaction.object(SUI_CLOCK_OBJECT_ID),
193
- transaction.pure.u64(value),
194
- transaction.object(SUI_SYSTEM_STATE_OBJECT_ID),
261
+ transaction.object(coin),
195
262
  ],
196
- })
197
- : transaction.moveCall({
198
- target: `${STRATEGY_WRAPPER_PACKAGE_ID_V7}::strategy_wrapper::borrow_from_obligation`,
199
- typeArguments: [LENDING_MARKET_TYPE, coinType],
263
+ });
264
+ };
265
+ export const strategyBorrow = (strategyType, coinType, strategyOwnerCap, reserveArrayIndex, value, transaction) => {
266
+ const { lendingMarketId, lendingMarketType } = getStrategyLendingMarket(strategyType);
267
+ return isSui(coinType)
268
+ ? transaction.moveCall({
269
+ target: `${STRATEGY_WRAPPER_PACKAGE_ID_V7}::strategy_wrapper::borrow_sui_from_obligation`,
270
+ typeArguments: [lendingMarketType],
271
+ arguments: [
272
+ transaction.object(strategyOwnerCap),
273
+ transaction.object(lendingMarketId),
274
+ transaction.pure.u64(reserveArrayIndex),
275
+ transaction.object(SUI_CLOCK_OBJECT_ID),
276
+ transaction.pure.u64(value),
277
+ transaction.object(SUI_SYSTEM_STATE_OBJECT_ID),
278
+ ],
279
+ })
280
+ : transaction.moveCall({
281
+ target: `${STRATEGY_WRAPPER_PACKAGE_ID_V7}::strategy_wrapper::borrow_from_obligation`,
282
+ typeArguments: [lendingMarketType, coinType],
283
+ arguments: [
284
+ transaction.object(strategyOwnerCap),
285
+ transaction.object(lendingMarketId),
286
+ transaction.pure.u64(reserveArrayIndex),
287
+ transaction.object(SUI_CLOCK_OBJECT_ID),
288
+ transaction.pure.u64(value),
289
+ ],
290
+ });
291
+ };
292
+ export const strategyWithdraw = (strategyType, coinType, strategyOwnerCap, reserveArrayIndex, value, transaction) => {
293
+ const { lendingMarketId, lendingMarketType } = getStrategyLendingMarket(strategyType);
294
+ return transaction.moveCall({
295
+ target: `${STRATEGY_WRAPPER_PACKAGE_ID_V7}::strategy_wrapper::withdraw_from_obligation_and_redeem`,
296
+ typeArguments: [lendingMarketType, coinType],
200
297
  arguments: [
201
298
  transaction.object(strategyOwnerCap),
202
- transaction.object(LENDING_MARKET_ID),
299
+ transaction.object(lendingMarketId),
203
300
  transaction.pure.u64(reserveArrayIndex),
204
301
  transaction.object(SUI_CLOCK_OBJECT_ID),
205
302
  transaction.pure.u64(value),
206
303
  ],
207
304
  });
208
- export const strategyWithdraw = (coinType, strategyOwnerCap, reserveArrayIndex, value, transaction) => transaction.moveCall({
209
- target: `${STRATEGY_WRAPPER_PACKAGE_ID_V7}::strategy_wrapper::withdraw_from_obligation_and_redeem`,
210
- typeArguments: [LENDING_MARKET_TYPE, coinType],
211
- arguments: [
212
- transaction.object(strategyOwnerCap),
213
- transaction.object(LENDING_MARKET_ID),
214
- transaction.pure.u64(reserveArrayIndex),
215
- transaction.object(SUI_CLOCK_OBJECT_ID),
216
- transaction.pure.u64(value),
217
- ],
218
- });
219
- const strategyClaimRewards = (coinType, strategyOwnerCap, reserveArrayIndex, rewardIndex, side, transaction) => transaction.moveCall({
220
- target: `${STRATEGY_WRAPPER_PACKAGE_ID_V7}::strategy_wrapper::claim_rewards`,
221
- typeArguments: [LENDING_MARKET_TYPE, coinType],
222
- arguments: [
223
- transaction.object(strategyOwnerCap),
224
- transaction.object(LENDING_MARKET_ID),
225
- transaction.object(SUI_CLOCK_OBJECT_ID),
226
- transaction.pure.u64(reserveArrayIndex),
227
- transaction.pure.u64(rewardIndex),
228
- transaction.pure.bool(side === Side.DEPOSIT),
229
- ],
230
- });
231
- const strategyClaimRewardsAndMergeCoins = (rewardsMap, strategyOwnerCap, transaction) => {
305
+ };
306
+ const strategyClaimRewards = (strategyType, coinType, strategyOwnerCap, reserveArrayIndex, rewardIndex, side, transaction) => {
307
+ const { lendingMarketId, lendingMarketType } = getStrategyLendingMarket(strategyType);
308
+ return transaction.moveCall({
309
+ target: `${STRATEGY_WRAPPER_PACKAGE_ID_V7}::strategy_wrapper::claim_rewards`,
310
+ typeArguments: [lendingMarketType, coinType],
311
+ arguments: [
312
+ transaction.object(strategyOwnerCap),
313
+ transaction.object(lendingMarketId),
314
+ transaction.object(SUI_CLOCK_OBJECT_ID),
315
+ transaction.pure.u64(reserveArrayIndex),
316
+ transaction.pure.u64(rewardIndex),
317
+ transaction.pure.bool(side === Side.DEPOSIT),
318
+ ],
319
+ });
320
+ };
321
+ export const strategyClaimRewardsAndMergeCoins = (strategyType, rewardsMap, strategyOwnerCap, transaction) => {
232
322
  // 1) Get rewards
233
323
  const rewards = Object.values(rewardsMap)
234
324
  .flatMap((r) => r.rewards)
@@ -241,7 +331,7 @@ const strategyClaimRewardsAndMergeCoins = (rewardsMap, strategyOwnerCap, transac
241
331
  // 2) Claim rewards and merge coins
242
332
  const mergeCoinsMap = {};
243
333
  for (const reward of rewards) {
244
- const [claimedCoin] = strategyClaimRewards(reward.rewardCoinType, strategyOwnerCap, reward.reserveArrayIndex, reward.rewardIndex, reward.side, transaction);
334
+ const [claimedCoin] = strategyClaimRewards(strategyType, reward.rewardCoinType, strategyOwnerCap, reward.reserveArrayIndex, reward.rewardIndex, reward.side, transaction);
245
335
  if (mergeCoinsMap[reward.rewardCoinType] === undefined)
246
336
  mergeCoinsMap[reward.rewardCoinType] = [];
247
337
  mergeCoinsMap[reward.rewardCoinType].push(claimedCoin);
@@ -255,94 +345,6 @@ const strategyClaimRewardsAndMergeCoins = (rewardsMap, strategyOwnerCap, transac
255
345
  }
256
346
  return mergedCoinsMap;
257
347
  };
258
- export const strategyClaimRewardsAndSwapForCoinType = (address, cetusSdk, cetusPartnerId, rewardsMap, rewardPriceMap, depositReserve, strategyOwnerCap, isDepositing, transaction) => __awaiter(void 0, void 0, void 0, function* () {
259
- const filteredRewardsMap = Object.fromEntries(Object.entries(rewardsMap).filter(([coinType]) => {
260
- var _a;
261
- return ((_a = rewardPriceMap[coinType]) !== null && _a !== void 0 ? _a : new BigNumber(0))
262
- .times(rewardsMap[coinType].amount)
263
- .gte(0.01);
264
- }));
265
- // 1) Claim rewards and merge coins
266
- const mergedCoinsMap = strategyClaimRewardsAndMergeCoins(filteredRewardsMap, strategyOwnerCap, transaction);
267
- // 2) Prepare
268
- const nonSwappedCoinTypes = Object.keys(mergedCoinsMap).filter((coinType) => coinType === depositReserve.coinType);
269
- const swappedCoinTypes = Object.keys(mergedCoinsMap).filter((coinType) => coinType !== depositReserve.coinType);
270
- let resultCoin = undefined;
271
- // 3.1) Non-swapped coins
272
- for (const [coinType, coin] of Object.entries(mergedCoinsMap).filter(([coinType]) => nonSwappedCoinTypes.includes(coinType))) {
273
- if (resultCoin)
274
- transaction.mergeCoins(resultCoin, [coin]);
275
- else
276
- resultCoin = coin;
277
- }
278
- // 3.2) Swapped coins
279
- // 3.2.1) Get routers
280
- const amountsAndSortedQuotesMap = Object.fromEntries(yield Promise.all(Object.entries(mergedCoinsMap)
281
- .filter(([coinType]) => swappedCoinTypes.includes(coinType))
282
- .map(([coinType, coin]) => (() => __awaiter(void 0, void 0, void 0, function* () {
283
- try {
284
- // Get amount
285
- const { rawAmount: amount } = filteredRewardsMap[coinType]; // Use underestimate (rewards keep accruing)
286
- // Get routes
287
- const routers = yield cetusSdk.findRouters({
288
- from: coinType,
289
- target: depositReserve.coinType,
290
- amount: new BN(amount.toString()), // Underestimate (rewards keep accruing)
291
- byAmountIn: true,
292
- });
293
- if (!routers)
294
- throw new Error(`No swap quote found for ${coinType}`);
295
- console.log("[strategyClaimRewardsAndSwapForCoinType] routers", {
296
- coinType,
297
- routers,
298
- });
299
- return [coinType, { coin, routers }];
300
- }
301
- catch (err) {
302
- console.error(err);
303
- return [coinType, { coin, routers: undefined }];
304
- }
305
- }))())));
306
- console.log("[strategyClaimRewardsAndSwapForCoinType] amountsAndSortedQuotesMap", { amountsAndSortedQuotesMap });
307
- // 3.2.2) Swap
308
- for (const [coinType, { coin: coinIn, routers }] of Object.entries(amountsAndSortedQuotesMap)) {
309
- if (routers === undefined)
310
- continue; // Skip coin if no swap quote found
311
- console.log("[strategyClaimRewardsAndSwapForCoinType] swapping coinType", coinType);
312
- try {
313
- let coinOut;
314
- try {
315
- coinOut = (yield cetusSdk.fixableRouterSwapV3({
316
- router: routers,
317
- inputCoin: coinIn,
318
- slippage: 3 / 100,
319
- txb: transaction,
320
- partner: cetusPartnerId,
321
- }));
322
- if (resultCoin)
323
- transaction.mergeCoins(resultCoin, [coinOut]);
324
- else
325
- resultCoin = coinOut;
326
- }
327
- catch (err) {
328
- throw new Error(`No swap quote found for ${coinType}`);
329
- }
330
- }
331
- catch (err) {
332
- console.error(err);
333
- continue; // Skip coin if swap fails
334
- }
335
- }
336
- // 4) Deposit
337
- if (!resultCoin)
338
- throw new Error("No coin to deposit or transfer");
339
- if (isDepositing) {
340
- strategyDeposit(resultCoin, depositReserve.coinType, strategyOwnerCap, depositReserve.arrayIndex, transaction);
341
- }
342
- else {
343
- transaction.transferObjects([resultCoin], transaction.pure.address(address));
344
- }
345
- });
346
348
  export const strategySwapSomeDepositsForCoinType = (strategyType, cetusSdk, cetusPartnerId, obligation, noSwapCoinTypes, // coinTypes to not swap for depositReserve.coinType
347
349
  swapPercent, // percent of deposit to swap for depositReserve.coinType (0-100)
348
350
  depositReserve, strategyOwnerCap, transaction) => __awaiter(void 0, void 0, void 0, function* () {
@@ -352,7 +354,7 @@ depositReserve, strategyOwnerCap, transaction) => __awaiter(void 0, void 0, void
352
354
  return;
353
355
  const withdrawnCoinsMap = {};
354
356
  for (const deposit of swapCoinTypeDeposits) {
355
- const [withdrawnCoin] = strategyWithdraw(deposit.coinType, strategyOwnerCap, deposit.reserve.arrayIndex, swapPercent.eq(100)
357
+ const [withdrawnCoin] = strategyWithdraw(strategyType, deposit.coinType, strategyOwnerCap, deposit.reserve.arrayIndex, swapPercent.eq(100)
356
358
  ? BigInt(MAX_U64.toString())
357
359
  : BigInt(new BigNumber(new BigNumber(deposit.depositedAmount.times(swapPercent.div(100)))
358
360
  .times(10 ** deposit.reserve.token.decimals)
@@ -429,9 +431,10 @@ depositReserve, strategyOwnerCap, transaction) => __awaiter(void 0, void 0, void
429
431
  if (!resultCoin)
430
432
  throw new Error("No coin to deposit or transfer");
431
433
  console.log("[strategySwapSomeDepositsForCoinType] depositing resultCoin");
432
- strategyDeposit(resultCoin, depositReserve.coinType, strategyOwnerCap, depositReserve.arrayIndex, transaction);
434
+ strategyDeposit(strategyType, resultCoin, depositReserve.coinType, strategyOwnerCap, depositReserve.arrayIndex, transaction);
433
435
  });
434
436
  export const createStrategyOwnerCapIfNoneExists = (strategyType, strategyOwnerCap, transaction) => {
437
+ const { lendingMarketId, lendingMarketType } = getStrategyLendingMarket(strategyType);
435
438
  let strategyOwnerCapId;
436
439
  let didCreate = false;
437
440
  if (strategyOwnerCap)
@@ -439,9 +442,9 @@ export const createStrategyOwnerCapIfNoneExists = (strategyType, strategyOwnerCa
439
442
  else {
440
443
  strategyOwnerCapId = transaction.moveCall({
441
444
  target: `${STRATEGY_WRAPPER_PACKAGE_ID_V7}::strategy_wrapper::create_strategy_owner_cap`,
442
- typeArguments: [LENDING_MARKET_TYPE],
445
+ typeArguments: [lendingMarketType],
443
446
  arguments: [
444
- transaction.object(LENDING_MARKET_ID),
447
+ transaction.object(lendingMarketId),
445
448
  transaction.pure.u8(+strategyType),
446
449
  ],
447
450
  });