@suilend/sdk 2.0.3 → 2.0.5
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 +11 -32
- package/lib/coin.d.ts +3 -0
- package/lib/coin.js +67 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/initialize.js +4 -3
- package/lib/strategyOwnerCap.d.ts +12 -7
- package/lib/strategyOwnerCap.js +159 -156
- package/package.json +1 -1
- package/strategies.d.ts +1 -1
- package/strategies.js +302 -82
- package/swap/transaction.js +3 -11
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
|
|
12
|
+
import { extractCTokenCoinType, getAllCoins } 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";
|
|
@@ -20,6 +20,7 @@ import { createLendingMarket } from "./_generated/suilend/lending-market-registr
|
|
|
20
20
|
import { Obligation } from "./_generated/suilend/obligation/structs";
|
|
21
21
|
import { newConfig as createRateLimiterConfig, } from "./_generated/suilend/rate-limiter/functions";
|
|
22
22
|
import { createReserveConfig, } from "./_generated/suilend/reserve-config/functions";
|
|
23
|
+
import { getSpendableCoin } from "./lib/coin";
|
|
23
24
|
import { PRIMARY_PYTH_ENDPOINT } from "./lib/pyth";
|
|
24
25
|
import { Side } from "./lib/types";
|
|
25
26
|
const SUI_COINTYPE = "0x2::sui::SUI";
|
|
@@ -221,16 +222,7 @@ export class SuilendClient {
|
|
|
221
222
|
}
|
|
222
223
|
addReward(ownerId_1, lendingMarketOwnerCapId_1, reserveArrayIndex_1, isDepositReward_1, rewardCoinType_1, rewardValue_1, startTimeMs_1, endTimeMs_1, transaction_1) {
|
|
223
224
|
return __awaiter(this, arguments, void 0, function* (ownerId, lendingMarketOwnerCapId, reserveArrayIndex, isDepositReward, rewardCoinType, rewardValue, startTimeMs, endTimeMs, transaction, mergeCoins = true) {
|
|
224
|
-
const
|
|
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]);
|
|
225
|
+
const rewardCoin = yield getSpendableCoin(this.client, ownerId, rewardCoinType, rewardValue, transaction);
|
|
234
226
|
return addPoolReward(transaction, [this.lendingMarket.$typeArgs[0], rewardCoinType], {
|
|
235
227
|
lendingMarketOwnerCap: transaction.object(lendingMarketOwnerCapId),
|
|
236
228
|
lendingMarket: transaction.object(this.lendingMarket.id),
|
|
@@ -454,21 +446,13 @@ export class SuilendClient {
|
|
|
454
446
|
}
|
|
455
447
|
depositIntoObligation(ownerId, coinType, value, transaction, obligationOwnerCap) {
|
|
456
448
|
return __awaiter(this, void 0, void 0, function* () {
|
|
457
|
-
const
|
|
458
|
-
const mergeCoin = mergeAllCoins(coinType, transaction, coins);
|
|
459
|
-
const [sendCoin] = transaction.splitCoins(isSui(coinType)
|
|
460
|
-
? transaction.gas
|
|
461
|
-
: transaction.object(mergeCoin.coinObjectId), [value]);
|
|
449
|
+
const sendCoin = yield getSpendableCoin(this.client, ownerId, coinType, value, transaction);
|
|
462
450
|
this.deposit(sendCoin, coinType, obligationOwnerCap, transaction);
|
|
463
451
|
});
|
|
464
452
|
}
|
|
465
453
|
depositLiquidityAndGetCTokens(ownerId, coinType, value, transaction) {
|
|
466
454
|
return __awaiter(this, void 0, void 0, function* () {
|
|
467
|
-
const
|
|
468
|
-
const mergeCoin = mergeAllCoins(coinType, transaction, coins);
|
|
469
|
-
const [sendCoin] = transaction.splitCoins(isSui(coinType)
|
|
470
|
-
? transaction.gas
|
|
471
|
-
: transaction.object(mergeCoin.coinObjectId), [value]);
|
|
455
|
+
const sendCoin = yield getSpendableCoin(this.client, ownerId, coinType, value, transaction);
|
|
472
456
|
const [ctokens] = depositLiquidityAndMintCtokens(transaction, [this.lendingMarket.$typeArgs[0], coinType], {
|
|
473
457
|
lendingMarket: transaction.object(this.lendingMarket.id),
|
|
474
458
|
reserveArrayIndex: transaction.pure.u64(this.findReserveArrayIndex(coinType)),
|
|
@@ -578,11 +562,7 @@ export class SuilendClient {
|
|
|
578
562
|
}
|
|
579
563
|
repayIntoObligation(ownerId, obligationId, coinType, value, transaction) {
|
|
580
564
|
return __awaiter(this, void 0, void 0, function* () {
|
|
581
|
-
const
|
|
582
|
-
const mergeCoin = mergeAllCoins(coinType, transaction, coins);
|
|
583
|
-
const [sendCoin] = transaction.splitCoins(isSui(coinType)
|
|
584
|
-
? transaction.gas
|
|
585
|
-
: transaction.object(mergeCoin.coinObjectId), [value]);
|
|
565
|
+
const sendCoin = yield getSpendableCoin(this.client, ownerId, coinType, value, transaction);
|
|
586
566
|
const result = this.repay(obligationId, coinType, sendCoin, transaction);
|
|
587
567
|
transaction.transferObjects([sendCoin], transaction.pure.address(ownerId));
|
|
588
568
|
return result;
|
|
@@ -637,13 +617,12 @@ export class SuilendClient {
|
|
|
637
617
|
}
|
|
638
618
|
redeemCtokensAndWithdrawLiquidity(ownerId, ctokenCoinTypes, transaction) {
|
|
639
619
|
return __awaiter(this, void 0, void 0, function* () {
|
|
640
|
-
const mergeCoinMap = {};
|
|
641
620
|
for (const ctokenCoinType of ctokenCoinTypes) {
|
|
642
621
|
const coins = yield getAllCoins(this.client, ownerId, ctokenCoinType);
|
|
643
|
-
const
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
622
|
+
const totalBalance = coins.reduce((sum, c) => sum + BigInt(c.balance), BigInt(0));
|
|
623
|
+
if (totalBalance === BigInt(0))
|
|
624
|
+
throw new Error(`No ${ctokenCoinType} coins found for redeem`);
|
|
625
|
+
const ctokenCoin = yield getSpendableCoin(this.client, ownerId, ctokenCoinType, totalBalance.toString(), transaction);
|
|
647
626
|
const coinType = extractCTokenCoinType(ctokenCoinType);
|
|
648
627
|
const [exemption] = transaction.moveCall({
|
|
649
628
|
target: `0x1::option::none`,
|
|
@@ -652,7 +631,7 @@ export class SuilendClient {
|
|
|
652
631
|
],
|
|
653
632
|
arguments: [],
|
|
654
633
|
});
|
|
655
|
-
const [redeemCoin] = this.redeem(
|
|
634
|
+
const [redeemCoin] = this.redeem(ctokenCoin, coinType, exemption, transaction);
|
|
656
635
|
transaction.transferObjects([redeemCoin], transaction.pure.address(ownerId));
|
|
657
636
|
}
|
|
658
637
|
});
|
package/lib/coin.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { SuiJsonRpcClient } from "@mysten/sui/jsonRpc";
|
|
2
|
+
import { Transaction, TransactionObjectArgument } from "@mysten/sui/transactions";
|
|
3
|
+
export declare const getSpendableCoin: (suiClient: SuiJsonRpcClient, address: string, coinType: string, value: string, transaction: Transaction) => Promise<TransactionObjectArgument>;
|
package/lib/coin.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { getAllCoins, isSui, mergeAllCoins } from "@suilend/sui-fe";
|
|
11
|
+
// Build a spendable coin using owned coin objects, address balance, or both.
|
|
12
|
+
export const getSpendableCoin = (suiClient, address, coinType, value, transaction) => __awaiter(void 0, void 0, void 0, function* () {
|
|
13
|
+
var _a;
|
|
14
|
+
const spendValue = BigInt(value);
|
|
15
|
+
if (spendValue <= BigInt(0)) {
|
|
16
|
+
throw new Error("Spend amount must be positive");
|
|
17
|
+
}
|
|
18
|
+
// Address-balance withdrawals resolve against the transaction sender.
|
|
19
|
+
transaction.setSenderIfNotSet(address);
|
|
20
|
+
const [coins, balance] = yield Promise.all([
|
|
21
|
+
getAllCoins(suiClient, address, coinType),
|
|
22
|
+
suiClient.getBalance({ owner: address, coinType }),
|
|
23
|
+
]);
|
|
24
|
+
const nonZeroCoins = coins.filter((c) => BigInt(c.balance) > BigInt(0));
|
|
25
|
+
const objectCoinBalance = nonZeroCoins.reduce((sum, c) => sum + BigInt(c.balance), BigInt(0));
|
|
26
|
+
const addressBalanceAvailable = BigInt((_a = balance.fundsInAddressBalance) !== null && _a !== void 0 ? _a : "0");
|
|
27
|
+
const totalAvailable = BigInt(balance.totalBalance);
|
|
28
|
+
if (totalAvailable < spendValue) {
|
|
29
|
+
throw new Error(`Insufficient ${coinType} balance: need ${value}, have ${balance.totalBalance} (${objectCoinBalance.toString()} in coins, ${addressBalanceAvailable.toString()} in address)`);
|
|
30
|
+
}
|
|
31
|
+
const objectCoinSpend = objectCoinBalance >= spendValue ? spendValue : objectCoinBalance;
|
|
32
|
+
const addressBalanceSpend = spendValue - objectCoinSpend;
|
|
33
|
+
console.log(`[getSpendableCoin] ${coinType} requested=${value} coinObjects=${objectCoinSpend.toString()} addressBalance=${addressBalanceSpend.toString()}`);
|
|
34
|
+
// Address balance only.
|
|
35
|
+
if (objectCoinSpend === BigInt(0)) {
|
|
36
|
+
return transaction.moveCall({
|
|
37
|
+
target: "0x2::coin::redeem_funds",
|
|
38
|
+
typeArguments: [coinType],
|
|
39
|
+
arguments: [transaction.withdrawal({ amount: value, type: coinType })],
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const mergedCoin = mergeAllCoins(coinType, transaction, nonZeroCoins);
|
|
43
|
+
const coinSource = isSui(coinType)
|
|
44
|
+
? transaction.gas
|
|
45
|
+
: transaction.object(mergedCoin.coinObjectId);
|
|
46
|
+
// Coin objects only.
|
|
47
|
+
if (addressBalanceSpend === BigInt(0)) {
|
|
48
|
+
const [sendCoin] = transaction.splitCoins(coinSource, [value]);
|
|
49
|
+
return sendCoin;
|
|
50
|
+
}
|
|
51
|
+
// Mixed: split from coin objects, redeem the rest from address balance, merge.
|
|
52
|
+
const [objectCoin] = transaction.splitCoins(coinSource, [
|
|
53
|
+
objectCoinSpend.toString(),
|
|
54
|
+
]);
|
|
55
|
+
const addressCoin = transaction.moveCall({
|
|
56
|
+
target: "0x2::coin::redeem_funds",
|
|
57
|
+
typeArguments: [coinType],
|
|
58
|
+
arguments: [
|
|
59
|
+
transaction.withdrawal({
|
|
60
|
+
amount: addressBalanceSpend.toString(),
|
|
61
|
+
type: coinType,
|
|
62
|
+
}),
|
|
63
|
+
],
|
|
64
|
+
});
|
|
65
|
+
transaction.mergeCoins(objectCoin, [addressCoin]);
|
|
66
|
+
return objectCoin;
|
|
67
|
+
});
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
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
|
-
|
|
236
|
-
|
|
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
|
|
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>;
|