@suilend/sdk 3.0.7 → 4.0.0
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/_generated/_dependencies/source/0x1/ascii/structs.d.ts +4 -4
- package/_generated/_dependencies/source/0x1/ascii/structs.js +42 -41
- package/_generated/_dependencies/source/0x1/option/structs.js +22 -26
- package/_generated/_dependencies/source/0x1/type-name/structs.d.ts +3 -3
- package/_generated/_dependencies/source/0x1/type-name/structs.js +21 -25
- package/_generated/_dependencies/source/0x2/bag/structs.d.ts +5 -5
- package/_generated/_dependencies/source/0x2/bag/structs.js +22 -25
- package/_generated/_dependencies/source/0x2/balance/structs.d.ts +4 -4
- package/_generated/_dependencies/source/0x2/balance/structs.js +42 -41
- package/_generated/_dependencies/source/0x2/object/structs.d.ts +5 -5
- package/_generated/_dependencies/source/0x2/object/structs.js +42 -41
- package/_generated/_dependencies/source/0x2/object-table/structs.d.ts +5 -5
- package/_generated/_dependencies/source/0x2/object-table/structs.js +22 -25
- package/_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/i64/structs.d.ts +3 -3
- package/_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/i64/structs.js +22 -25
- package/_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price/structs.d.ts +9 -9
- package/_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price/structs.js +24 -25
- package/_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-feed/structs.d.ts +21 -21
- package/_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-feed/structs.js +23 -25
- package/_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-identifier/structs.d.ts +2 -2
- package/_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-identifier/structs.js +21 -25
- package/_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-info/structs.d.ts +52 -52
- package/_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-info/structs.js +45 -41
- package/_generated/_framework/vector.js +9 -6
- package/_generated/suilend/cell/structs.d.ts +1 -1
- package/_generated/suilend/cell/structs.js +21 -25
- package/_generated/suilend/decimal/structs.d.ts +2 -2
- package/_generated/suilend/decimal/structs.js +21 -25
- package/_generated/suilend/lending-market/structs.d.ts +129 -129
- package/_generated/suilend/lending-market/structs.js +391 -265
- package/_generated/suilend/liquidity-mining/structs.d.ts +44 -44
- package/_generated/suilend/liquidity-mining/structs.js +122 -89
- package/_generated/suilend/obligation/structs.d.ts +98 -98
- package/_generated/suilend/obligation/structs.js +194 -121
- package/_generated/suilend/rate-limiter/structs.d.ts +12 -12
- package/_generated/suilend/rate-limiter/structs.js +46 -41
- package/_generated/suilend/reserve/structs.d.ts +128 -128
- package/_generated/suilend/reserve/structs.js +243 -153
- package/_generated/suilend/reserve-config/structs.d.ts +30 -30
- package/_generated/suilend/reserve-config/structs.js +60 -41
- package/api/events.js +5 -14
- package/client.js +267 -319
- package/lib/initialize.d.ts +2 -2
- package/lib/initialize.js +26 -31
- package/lib/liquidityMining.js +15 -19
- package/lib/pyth.js +6 -15
- package/lib/pythAdapter.js +96 -112
- package/lib/strategyOwnerCap.js +8 -17
- package/margin/margin/admin_cap.d.ts +2 -2
- package/margin/margin/deps/std/type_name.d.ts +1 -1
- package/margin/margin/deps/suilend/lending_market.d.ts +2 -2
- package/margin/margin/market.d.ts +11 -11
- package/margin/margin/market.js +22 -22
- package/margin/margin/permissions.js +14 -14
- package/margin/margin/position.d.ts +47 -47
- package/margin/margin/position.js +10 -10
- package/margin/margin/router.d.ts +5 -5
- package/margin/margin/router.js +16 -16
- package/margin/margin/version.d.ts +1 -1
- package/margin/utils/index.js +22 -36
- package/package.json +1 -1
- package/parsers/apiReserveAssetDataEvent.js +4 -1
- package/parsers/lendingMarket.js +3 -4
- package/parsers/reserve.js +4 -1
- package/strategies.js +188 -204
- package/swap/quote.d.ts +1 -1
- package/swap/quote.js +28 -39
- package/swap/transaction.js +17 -26
- package/utils/events.js +20 -32
- package/utils/obligation.js +111 -135
- package/utils/simulate.js +16 -24
package/client.js
CHANGED
|
@@ -1,15 +1,6 @@
|
|
|
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
1
|
import { SUI_CLOCK_OBJECT_ID, SUI_SYSTEM_STATE_OBJECT_ID, normalizeStructTag, toHex, } from "@mysten/sui/utils";
|
|
11
2
|
import { SuiPriceServiceConnection, SuiPythClient, } from "@pythnetwork/pyth-sui-js";
|
|
12
|
-
import { extractCTokenCoinType, getAllCoins, getSpendableCoin, } from "@suilend/sui-
|
|
3
|
+
import { extractCTokenCoinType, getAllCoins, getSpendableCoin, } from "@suilend/sui-core";
|
|
13
4
|
import { PriceInfoObject } from "./_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-info/structs.js";
|
|
14
5
|
import { phantom } from "./_generated/_framework/reified.js";
|
|
15
6
|
import { PKG_V10, setPublishedAt } from "./_generated/suilend/index.js";
|
|
@@ -55,16 +46,18 @@ export const [STEAMM_LM_LENDING_MARKET_ID, STEAMM_LM_LENDING_MARKET_TYPE] = proc
|
|
|
55
46
|
"0xc1888ec1b81a414e427a44829310508352aec38252ee0daa9f8b181b6947de9f",
|
|
56
47
|
"0x0a071f4976abae1a7f722199cf0bfcbe695ef9408a878e7d12a7ca87b7e582a6::lp_rewards::LP_REWARDS",
|
|
57
48
|
];
|
|
58
|
-
function getLatestPackageId(suiGrpcClient, upgradeCapId) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
include: { json: true },
|
|
63
|
-
});
|
|
64
|
-
return object.json.package;
|
|
49
|
+
async function getLatestPackageId(suiGrpcClient, upgradeCapId) {
|
|
50
|
+
const { object } = await suiGrpcClient.getObject({
|
|
51
|
+
objectId: upgradeCapId,
|
|
52
|
+
include: { json: true },
|
|
65
53
|
});
|
|
54
|
+
return object.json.package;
|
|
66
55
|
}
|
|
67
56
|
export class SuilendClient {
|
|
57
|
+
lendingMarket;
|
|
58
|
+
suiGrpcClient;
|
|
59
|
+
pythClient;
|
|
60
|
+
pythConnection;
|
|
68
61
|
constructor(lendingMarket, suiGrpcClient) {
|
|
69
62
|
this.lendingMarket = lendingMarket;
|
|
70
63
|
this.suiGrpcClient = suiGrpcClient;
|
|
@@ -74,35 +67,30 @@ export class SuilendClient {
|
|
|
74
67
|
timeout: 30 * 1000,
|
|
75
68
|
});
|
|
76
69
|
}
|
|
77
|
-
static initialize(lendingMarketId, lendingMarketType, suiGrpcClient, logPackageId) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
});
|
|
97
|
-
const { object } = yield suiGrpcClient.getObject({
|
|
98
|
-
objectId: dynamicField.fieldId,
|
|
99
|
-
include: { json: true },
|
|
100
|
-
});
|
|
101
|
-
const json = object.json;
|
|
102
|
-
const receivers = (_a = json === null || json === void 0 ? void 0 : json.value) === null || _a === void 0 ? void 0 : _a.receivers;
|
|
103
|
-
const weights = (_b = json === null || json === void 0 ? void 0 : json.value) === null || _b === void 0 ? void 0 : _b.weights;
|
|
104
|
-
return { receivers, weights };
|
|
70
|
+
static async initialize(lendingMarketId, lendingMarketType, suiGrpcClient, logPackageId) {
|
|
71
|
+
const lendingMarket = await LendingMarket.fetch(suiGrpcClient, phantom(lendingMarketType), lendingMarketId);
|
|
72
|
+
const publishedAt = await getLatestPackageId(suiGrpcClient, SUILEND_UPGRADE_CAP_ID);
|
|
73
|
+
if (logPackageId)
|
|
74
|
+
console.log("@suilend/sdk | publishedAt:", publishedAt);
|
|
75
|
+
setPublishedAt(publishedAt);
|
|
76
|
+
return new SuilendClient(lendingMarket, suiGrpcClient);
|
|
77
|
+
}
|
|
78
|
+
static async getFeeReceivers(suiGrpcClient, lendingMarketId) {
|
|
79
|
+
const { dynamicField } = await suiGrpcClient.getDynamicField({
|
|
80
|
+
parentId: lendingMarketId,
|
|
81
|
+
name: {
|
|
82
|
+
type: `${PKG_V10}::lending_market::FeeReceiversKey`,
|
|
83
|
+
bcs: new Uint8Array([0]),
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
const { object } = await suiGrpcClient.getObject({
|
|
87
|
+
objectId: dynamicField.fieldId,
|
|
88
|
+
include: { json: true },
|
|
105
89
|
});
|
|
90
|
+
const json = object.json;
|
|
91
|
+
const receivers = json?.value?.receivers;
|
|
92
|
+
const weights = json?.value?.weights;
|
|
93
|
+
return { receivers, weights };
|
|
106
94
|
}
|
|
107
95
|
static createNewLendingMarket(registryId, lendingMarketType, transaction) {
|
|
108
96
|
const [ownerCap, lendingMarket] = createLendingMarket(transaction, lendingMarketType, transaction.object(registryId));
|
|
@@ -113,96 +101,82 @@ export class SuilendClient {
|
|
|
113
101
|
});
|
|
114
102
|
return ownerCap;
|
|
115
103
|
}
|
|
116
|
-
static getObligationOwnerCaps(ownerId, lendingMarketTypeArgs, suiGrpcClient) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
type: `${PACKAGE_ID}::lending_market::ObligationOwnerCap<${lendingMarketTypeArgs[0]}>`,
|
|
126
|
-
include: { content: true },
|
|
127
|
-
});
|
|
128
|
-
allObjs.push(...objs.objects);
|
|
129
|
-
cursor = objs.cursor;
|
|
130
|
-
hasNextPage = objs.hasNextPage;
|
|
131
|
-
}
|
|
132
|
-
return allObjs.map((obj) => ObligationOwnerCap.fromBcs(phantom(lendingMarketTypeArgs[0]), obj.content));
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
static getObligation(obligationId, lendingMarketTypeArgs, suiGrpcClient) {
|
|
136
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
137
|
-
const { object } = yield suiGrpcClient.getObject({
|
|
138
|
-
objectId: obligationId,
|
|
104
|
+
static async getObligationOwnerCaps(ownerId, lendingMarketTypeArgs, suiGrpcClient) {
|
|
105
|
+
const allObjs = [];
|
|
106
|
+
let cursor = null;
|
|
107
|
+
let hasNextPage = true;
|
|
108
|
+
while (hasNextPage) {
|
|
109
|
+
const objs = await suiGrpcClient.listOwnedObjects({
|
|
110
|
+
owner: ownerId,
|
|
111
|
+
cursor,
|
|
112
|
+
type: `${PACKAGE_ID}::lending_market::ObligationOwnerCap<${lendingMarketTypeArgs[0]}>`,
|
|
139
113
|
include: { content: true },
|
|
140
114
|
});
|
|
141
|
-
|
|
115
|
+
allObjs.push(...objs.objects);
|
|
116
|
+
cursor = objs.cursor;
|
|
117
|
+
hasNextPage = objs.hasNextPage;
|
|
118
|
+
}
|
|
119
|
+
return allObjs.map((obj) => ObligationOwnerCap.fromBcs(phantom(lendingMarketTypeArgs[0]), obj.content));
|
|
120
|
+
}
|
|
121
|
+
static async getObligation(obligationId, lendingMarketTypeArgs, suiGrpcClient) {
|
|
122
|
+
const { object } = await suiGrpcClient.getObject({
|
|
123
|
+
objectId: obligationId,
|
|
124
|
+
include: { content: true },
|
|
142
125
|
});
|
|
126
|
+
return Obligation.fromBcs(phantom(lendingMarketTypeArgs[0]), object.content);
|
|
143
127
|
}
|
|
144
|
-
getObligation(obligationId) {
|
|
145
|
-
return
|
|
146
|
-
|
|
128
|
+
async getObligation(obligationId) {
|
|
129
|
+
return SuilendClient.getObligation(obligationId, this.lendingMarket.$typeArgs, this.suiGrpcClient);
|
|
130
|
+
}
|
|
131
|
+
static async getLendingMarketOwnerCapId(ownerId, lendingMarketTypeArgs, suiGrpcClient) {
|
|
132
|
+
const objs = await suiGrpcClient.listOwnedObjects({
|
|
133
|
+
owner: ownerId,
|
|
134
|
+
type: `${PACKAGE_ID}::lending_market::LendingMarketOwnerCap<${lendingMarketTypeArgs[0]}>`,
|
|
147
135
|
});
|
|
136
|
+
if (objs.objects.length > 0)
|
|
137
|
+
return objs.objects[0].objectId;
|
|
138
|
+
else
|
|
139
|
+
return undefined;
|
|
148
140
|
}
|
|
149
|
-
|
|
150
|
-
return
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
coinType: coinType,
|
|
176
|
-
});
|
|
177
|
-
console.log("[createReserve] coinMetadata", coinMetadata);
|
|
178
|
-
if (!coinMetadata)
|
|
179
|
-
throw new Error("Error: CoinMetadata not found");
|
|
180
|
-
if (!coinMetadata.id)
|
|
181
|
-
throw new Error("Error: CoinMetadata.id not found");
|
|
182
|
-
const addReserveFn = useV2 ? addReserveV2 : addReserve;
|
|
183
|
-
return addReserveFn(transaction, [this.lendingMarket.$typeArgs[0], coinType], {
|
|
184
|
-
lendingMarketOwnerCap: transaction.object(lendingMarketOwnerCapId),
|
|
185
|
-
lendingMarket: transaction.object(this.lendingMarket.id),
|
|
186
|
-
priceInfo: transaction.object(priceInfoObjectIds[0]),
|
|
187
|
-
config: transaction.object(config),
|
|
188
|
-
coinMetadata: transaction.object(coinMetadata.id),
|
|
189
|
-
clock: transaction.object(SUI_CLOCK_OBJECT_ID),
|
|
190
|
-
});
|
|
141
|
+
async getLendingMarketOwnerCapId(ownerId) {
|
|
142
|
+
return SuilendClient.getLendingMarketOwnerCapId(ownerId, this.lendingMarket.$typeArgs, this.suiGrpcClient);
|
|
143
|
+
}
|
|
144
|
+
async createReserve(lendingMarketOwnerCapId, transaction, pythPriceId, coinType, createReserveConfigArgs, useV2) {
|
|
145
|
+
const [config] = createReserveConfig(transaction, createReserveConfigArgs);
|
|
146
|
+
// Assumes the pyth price feed exists
|
|
147
|
+
const priceUpdateData = await this.pythConnection.getPriceFeedsUpdateData([
|
|
148
|
+
pythPriceId,
|
|
149
|
+
]);
|
|
150
|
+
const priceInfoObjectIds = await this.pythClient.updatePriceFeeds(transaction, priceUpdateData, [pythPriceId]);
|
|
151
|
+
const { coinMetadata } = await this.suiGrpcClient.getCoinMetadata({
|
|
152
|
+
coinType: coinType,
|
|
153
|
+
});
|
|
154
|
+
console.log("[createReserve] coinMetadata", coinMetadata);
|
|
155
|
+
if (!coinMetadata)
|
|
156
|
+
throw new Error("Error: CoinMetadata not found");
|
|
157
|
+
if (!coinMetadata.id)
|
|
158
|
+
throw new Error("Error: CoinMetadata.id not found");
|
|
159
|
+
const addReserveFn = useV2 ? addReserveV2 : addReserve;
|
|
160
|
+
return addReserveFn(transaction, [this.lendingMarket.$typeArgs[0], coinType], {
|
|
161
|
+
lendingMarketOwnerCap: transaction.object(lendingMarketOwnerCapId),
|
|
162
|
+
lendingMarket: transaction.object(this.lendingMarket.id),
|
|
163
|
+
priceInfo: transaction.object(priceInfoObjectIds[0]),
|
|
164
|
+
config: transaction.object(config),
|
|
165
|
+
coinMetadata: transaction.object(coinMetadata.id),
|
|
166
|
+
clock: transaction.object(SUI_CLOCK_OBJECT_ID),
|
|
191
167
|
});
|
|
192
168
|
}
|
|
193
|
-
addReward(
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
clock: transaction.object(SUI_CLOCK_OBJECT_ID),
|
|
205
|
-
});
|
|
169
|
+
async addReward(ownerId, lendingMarketOwnerCapId, reserveArrayIndex, isDepositReward, rewardCoinType, rewardValue, startTimeMs, endTimeMs, transaction, mergeCoins = true) {
|
|
170
|
+
const rewardCoin = await getSpendableCoin(this.suiGrpcClient, ownerId, rewardCoinType, rewardValue, transaction, mergeCoins);
|
|
171
|
+
return addPoolReward(transaction, [this.lendingMarket.$typeArgs[0], rewardCoinType], {
|
|
172
|
+
lendingMarketOwnerCap: transaction.object(lendingMarketOwnerCapId),
|
|
173
|
+
lendingMarket: transaction.object(this.lendingMarket.id),
|
|
174
|
+
reserveArrayIndex: transaction.pure.u64(reserveArrayIndex),
|
|
175
|
+
isDepositReward: transaction.pure.bool(isDepositReward),
|
|
176
|
+
rewards: transaction.object(rewardCoin),
|
|
177
|
+
startTimeMs: transaction.pure.u64(startTimeMs),
|
|
178
|
+
endTimeMs: transaction.pure.u64(endTimeMs),
|
|
179
|
+
clock: transaction.object(SUI_CLOCK_OBJECT_ID),
|
|
206
180
|
});
|
|
207
181
|
}
|
|
208
182
|
cancelReward(lendingMarketOwnerCapId, reserveArrayIndex, isDepositReward, rewardIndex, rewardCoinType, transaction) {
|
|
@@ -307,19 +281,17 @@ export class SuilendClient {
|
|
|
307
281
|
config: transaction.object(config),
|
|
308
282
|
});
|
|
309
283
|
}
|
|
310
|
-
changeReservePriceFeed(lendingMarketOwnerCapId, coinType, pythPriceId, transaction) {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
clock: transaction.object(SUI_CLOCK_OBJECT_ID),
|
|
322
|
-
});
|
|
284
|
+
async changeReservePriceFeed(lendingMarketOwnerCapId, coinType, pythPriceId, transaction) {
|
|
285
|
+
const priceUpdateData = await this.pythConnection.getPriceFeedsUpdateData([
|
|
286
|
+
pythPriceId,
|
|
287
|
+
]);
|
|
288
|
+
const priceInfoObjectIds = await this.pythClient.updatePriceFeeds(transaction, priceUpdateData, [pythPriceId]);
|
|
289
|
+
return changeReservePriceFeed(transaction, [this.lendingMarket.$typeArgs[0], coinType], {
|
|
290
|
+
lendingMarketOwnerCap: transaction.object(lendingMarketOwnerCapId),
|
|
291
|
+
lendingMarket: transaction.object(this.lendingMarket.id),
|
|
292
|
+
reserveArrayIndex: transaction.pure.u64(this.findReserveArrayIndex(coinType)),
|
|
293
|
+
priceInfoObj: transaction.object(priceInfoObjectIds[0]),
|
|
294
|
+
clock: transaction.object(SUI_CLOCK_OBJECT_ID),
|
|
323
295
|
});
|
|
324
296
|
}
|
|
325
297
|
createObligation(transaction) {
|
|
@@ -329,67 +301,63 @@ export class SuilendClient {
|
|
|
329
301
|
typeArguments: this.lendingMarket.$typeArgs,
|
|
330
302
|
});
|
|
331
303
|
}
|
|
332
|
-
refreshAll(transaction, obligation, coinTypes) {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
reserveArrayIndexToPriceId.set(reserveArrayIndex, toHex(new Uint8Array(reserve.priceIdentifier.bytes)));
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
const tuples = Array.from(reserveArrayIndexToPriceId.entries()).sort();
|
|
356
|
-
const reserveArrayIndexes = tuples.map((tuple) => tuple[0]);
|
|
357
|
-
const priceIdentifiers = tuples.map((tuple) => tuple[1]);
|
|
358
|
-
const priceInfoObjectIds = {};
|
|
359
|
-
yield Promise.all(priceIdentifiers.map((_, i) => (() => __awaiter(this, void 0, void 0, function* () {
|
|
360
|
-
const priceInfoObjectId = yield this.pythClient.getPriceFeedObjectId(priceIdentifiers[i]);
|
|
361
|
-
priceInfoObjectIds[i] = priceInfoObjectId;
|
|
362
|
-
}))()));
|
|
363
|
-
const stalePriceIdentifiers = [];
|
|
364
|
-
yield Promise.all(Object.entries(priceInfoObjectIds).map(([i, priceInfoObjectId]) => (() => __awaiter(this, void 0, void 0, function* () {
|
|
365
|
-
const priceInfoObject = yield PriceInfoObject.fetch(this.suiGrpcClient, priceInfoObjectId);
|
|
366
|
-
const publishTime = priceInfoObject.priceInfo.priceFeed.price.timestamp;
|
|
367
|
-
const stalenessSeconds = Date.now() / 1000 - Number(publishTime);
|
|
368
|
-
if (stalenessSeconds > 20) {
|
|
369
|
-
const reserve = this.lendingMarket.reserves[Number(reserveArrayIndexes[+i])];
|
|
370
|
-
stalePriceIdentifiers.push(priceIdentifiers[+i]);
|
|
304
|
+
async refreshAll(transaction, obligation, coinTypes) {
|
|
305
|
+
const reserveArrayIndexToPriceId = new Map();
|
|
306
|
+
if (obligation) {
|
|
307
|
+
obligation.deposits.forEach((deposit) => {
|
|
308
|
+
const reserve = this.lendingMarket.reserves[Number(deposit.reserveArrayIndex)];
|
|
309
|
+
reserveArrayIndexToPriceId.set(deposit.reserveArrayIndex, toHex(new Uint8Array(reserve.priceIdentifier.bytes)));
|
|
310
|
+
});
|
|
311
|
+
obligation.borrows.forEach((borrow) => {
|
|
312
|
+
const reserve = this.lendingMarket.reserves[Number(borrow.reserveArrayIndex)];
|
|
313
|
+
reserveArrayIndexToPriceId.set(borrow.reserveArrayIndex, toHex(new Uint8Array(reserve.priceIdentifier.bytes)));
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
if (coinTypes !== undefined) {
|
|
317
|
+
for (const coinType of coinTypes) {
|
|
318
|
+
const reserveArrayIndex = this.findReserveArrayIndex(coinType);
|
|
319
|
+
if (reserveArrayIndex >= 0 &&
|
|
320
|
+
reserveArrayIndex < BigInt(this.lendingMarket.reserves.length)) {
|
|
321
|
+
const reserve = this.lendingMarket.reserves[Number(reserveArrayIndex)];
|
|
322
|
+
reserveArrayIndexToPriceId.set(reserveArrayIndex, toHex(new Uint8Array(reserve.priceIdentifier.bytes)));
|
|
371
323
|
}
|
|
372
|
-
}))()));
|
|
373
|
-
if (stalePriceIdentifiers.length > 0) {
|
|
374
|
-
const stalePriceUpdateData = yield this.pythConnection.getPriceFeedsUpdateData(stalePriceIdentifiers);
|
|
375
|
-
yield this.pythClient.updatePriceFeeds(transaction, stalePriceUpdateData, stalePriceIdentifiers);
|
|
376
324
|
}
|
|
377
|
-
|
|
378
|
-
|
|
325
|
+
}
|
|
326
|
+
const tuples = Array.from(reserveArrayIndexToPriceId.entries()).sort();
|
|
327
|
+
const reserveArrayIndexes = tuples.map((tuple) => tuple[0]);
|
|
328
|
+
const priceIdentifiers = tuples.map((tuple) => tuple[1]);
|
|
329
|
+
const priceInfoObjectIds = {};
|
|
330
|
+
await Promise.all(priceIdentifiers.map((_, i) => (async () => {
|
|
331
|
+
const priceInfoObjectId = await this.pythClient.getPriceFeedObjectId(priceIdentifiers[i]);
|
|
332
|
+
priceInfoObjectIds[i] = priceInfoObjectId;
|
|
333
|
+
})()));
|
|
334
|
+
const stalePriceIdentifiers = [];
|
|
335
|
+
await Promise.all(Object.entries(priceInfoObjectIds).map(([i, priceInfoObjectId]) => (async () => {
|
|
336
|
+
const priceInfoObject = await PriceInfoObject.fetch(this.suiGrpcClient, priceInfoObjectId);
|
|
337
|
+
const publishTime = priceInfoObject.priceInfo.priceFeed.price.timestamp;
|
|
338
|
+
const stalenessSeconds = Date.now() / 1000 - Number(publishTime);
|
|
339
|
+
if (stalenessSeconds > 20) {
|
|
340
|
+
const reserve = this.lendingMarket.reserves[Number(reserveArrayIndexes[+i])];
|
|
341
|
+
stalePriceIdentifiers.push(priceIdentifiers[+i]);
|
|
379
342
|
}
|
|
380
|
-
});
|
|
343
|
+
})()));
|
|
344
|
+
if (stalePriceIdentifiers.length > 0) {
|
|
345
|
+
const stalePriceUpdateData = await this.pythConnection.getPriceFeedsUpdateData(stalePriceIdentifiers);
|
|
346
|
+
await this.pythClient.updatePriceFeeds(transaction, stalePriceUpdateData, stalePriceIdentifiers);
|
|
347
|
+
}
|
|
348
|
+
for (let i = 0; i < reserveArrayIndexes.length; i++) {
|
|
349
|
+
this.refreshReservePrices(transaction, priceInfoObjectIds[i], reserveArrayIndexes[i]);
|
|
350
|
+
}
|
|
381
351
|
}
|
|
382
|
-
refreshReservePrices(transaction, priceInfoObjectId, reserveArrayIndex) {
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
priceInfo: transaction.object(priceInfoObjectId),
|
|
392
|
-
});
|
|
352
|
+
async refreshReservePrices(transaction, priceInfoObjectId, reserveArrayIndex) {
|
|
353
|
+
if (priceInfoObjectId == null) {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
refreshReservePrice(transaction, this.lendingMarket.$typeArgs[0], {
|
|
357
|
+
lendingMarket: transaction.object(this.lendingMarket.id),
|
|
358
|
+
reserveArrayIndex: transaction.pure.u64(reserveArrayIndex),
|
|
359
|
+
clock: transaction.object(SUI_CLOCK_OBJECT_ID),
|
|
360
|
+
priceInfo: transaction.object(priceInfoObjectId),
|
|
393
361
|
});
|
|
394
362
|
}
|
|
395
363
|
deposit(sendCoin, coinType, obligationOwnerCap, transaction) {
|
|
@@ -414,48 +382,42 @@ export class SuilendClient {
|
|
|
414
382
|
});
|
|
415
383
|
}
|
|
416
384
|
}
|
|
417
|
-
depositIntoObligation(ownerId, coinType, value, transaction, obligationOwnerCap) {
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
this.deposit(sendCoin, coinType, obligationOwnerCap, transaction);
|
|
421
|
-
});
|
|
385
|
+
async depositIntoObligation(ownerId, coinType, value, transaction, obligationOwnerCap) {
|
|
386
|
+
const sendCoin = await getSpendableCoin(this.suiGrpcClient, ownerId, coinType, value, transaction);
|
|
387
|
+
this.deposit(sendCoin, coinType, obligationOwnerCap, transaction);
|
|
422
388
|
}
|
|
423
|
-
depositLiquidityAndGetCTokens(ownerId, coinType, value, transaction) {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
deposit: sendCoin,
|
|
431
|
-
});
|
|
432
|
-
transaction.transferObjects([ctokens], transaction.pure.address(ownerId));
|
|
389
|
+
async depositLiquidityAndGetCTokens(ownerId, coinType, value, transaction) {
|
|
390
|
+
const sendCoin = await getSpendableCoin(this.suiGrpcClient, ownerId, coinType, value, transaction);
|
|
391
|
+
const [ctokens] = depositLiquidityAndMintCtokens(transaction, [this.lendingMarket.$typeArgs[0], coinType], {
|
|
392
|
+
lendingMarket: transaction.object(this.lendingMarket.id),
|
|
393
|
+
reserveArrayIndex: transaction.pure.u64(this.findReserveArrayIndex(coinType)),
|
|
394
|
+
clock: transaction.object(SUI_CLOCK_OBJECT_ID),
|
|
395
|
+
deposit: sendCoin,
|
|
433
396
|
});
|
|
397
|
+
transaction.transferObjects([ctokens], transaction.pure.address(ownerId));
|
|
434
398
|
}
|
|
435
|
-
withdraw(
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
arguments: [],
|
|
456
|
-
});
|
|
457
|
-
return this.redeem(ctokens, coinType, exemption, transaction);
|
|
399
|
+
async withdraw(obligationOwnerCap, obligationId, coinType, value, transaction, addRefreshCalls = true) {
|
|
400
|
+
if (addRefreshCalls) {
|
|
401
|
+
const obligation = await this.getObligation(obligationId);
|
|
402
|
+
if (!obligation)
|
|
403
|
+
throw new Error("Error: no obligation");
|
|
404
|
+
await this.refreshAll(transaction, obligation);
|
|
405
|
+
}
|
|
406
|
+
const [ctokens] = withdrawCtokens(transaction, [this.lendingMarket.$typeArgs[0], coinType], {
|
|
407
|
+
lendingMarket: transaction.object(this.lendingMarket.id),
|
|
408
|
+
reserveArrayIndex: transaction.pure.u64(this.findReserveArrayIndex(coinType)),
|
|
409
|
+
obligationOwnerCap,
|
|
410
|
+
clock: transaction.object(SUI_CLOCK_OBJECT_ID),
|
|
411
|
+
amount: BigInt(value),
|
|
412
|
+
});
|
|
413
|
+
const [exemption] = transaction.moveCall({
|
|
414
|
+
target: `0x1::option::none`,
|
|
415
|
+
typeArguments: [
|
|
416
|
+
`${PACKAGE_ID}::lending_market::RateLimiterExemption<${this.lendingMarket.$typeArgs[0]}, ${coinType}>`,
|
|
417
|
+
],
|
|
418
|
+
arguments: [],
|
|
458
419
|
});
|
|
420
|
+
return this.redeem(ctokens, coinType, exemption, transaction);
|
|
459
421
|
}
|
|
460
422
|
redeem(ctokens, coinType, exemption, transaction) {
|
|
461
423
|
const [liquidityRequest] = redeemCtokensAndWithdrawLiquidityRequest(transaction, [this.lendingMarket.$typeArgs[0], coinType], {
|
|
@@ -479,47 +441,41 @@ export class SuilendClient {
|
|
|
479
441
|
liquidityRequest,
|
|
480
442
|
});
|
|
481
443
|
}
|
|
482
|
-
withdrawAndSendToUser(ownerId, obligationOwnerCap, obligationId, coinType, value, transaction) {
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
transaction.transferObjects([withdrawCoin], transaction.pure.address(ownerId));
|
|
486
|
-
});
|
|
444
|
+
async withdrawAndSendToUser(ownerId, obligationOwnerCap, obligationId, coinType, value, transaction) {
|
|
445
|
+
const [withdrawCoin] = await this.withdraw(obligationOwnerCap, obligationId, coinType, value, transaction);
|
|
446
|
+
transaction.transferObjects([withdrawCoin], transaction.pure.address(ownerId));
|
|
487
447
|
}
|
|
488
|
-
borrow(
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
unstakeSuiFromStaker(transaction, this.lendingMarket.$typeArgs[0], {
|
|
505
|
-
lendingMarket: transaction.object(this.lendingMarket.id),
|
|
506
|
-
suiReserveArrayIndex: transaction.pure.u64(this.findReserveArrayIndex(coinType)),
|
|
507
|
-
liquidityRequest,
|
|
508
|
-
systemState: transaction.object(SUI_SYSTEM_STATE_OBJECT_ID),
|
|
509
|
-
});
|
|
510
|
-
}
|
|
511
|
-
return fulfillLiquidityRequest(transaction, [this.lendingMarket.$typeArgs[0], coinType], {
|
|
448
|
+
async borrow(obligationOwnerCap, obligationId, coinType, value, transaction, addRefreshCalls = true) {
|
|
449
|
+
if (addRefreshCalls) {
|
|
450
|
+
const obligation = await this.getObligation(obligationId);
|
|
451
|
+
if (!obligation)
|
|
452
|
+
throw new Error("Error: no obligation");
|
|
453
|
+
await this.refreshAll(transaction, obligation, [coinType]);
|
|
454
|
+
}
|
|
455
|
+
const [liquidityRequest] = borrowRequest(transaction, [this.lendingMarket.$typeArgs[0], coinType], {
|
|
456
|
+
lendingMarket: transaction.object(this.lendingMarket.id),
|
|
457
|
+
reserveArrayIndex: transaction.pure.u64(this.findReserveArrayIndex(coinType)),
|
|
458
|
+
obligationOwnerCap,
|
|
459
|
+
clock: transaction.object(SUI_CLOCK_OBJECT_ID),
|
|
460
|
+
amount: BigInt(value),
|
|
461
|
+
});
|
|
462
|
+
if (isSui(coinType)) {
|
|
463
|
+
unstakeSuiFromStaker(transaction, this.lendingMarket.$typeArgs[0], {
|
|
512
464
|
lendingMarket: transaction.object(this.lendingMarket.id),
|
|
513
|
-
|
|
465
|
+
suiReserveArrayIndex: transaction.pure.u64(this.findReserveArrayIndex(coinType)),
|
|
514
466
|
liquidityRequest,
|
|
467
|
+
systemState: transaction.object(SUI_SYSTEM_STATE_OBJECT_ID),
|
|
515
468
|
});
|
|
469
|
+
}
|
|
470
|
+
return fulfillLiquidityRequest(transaction, [this.lendingMarket.$typeArgs[0], coinType], {
|
|
471
|
+
lendingMarket: transaction.object(this.lendingMarket.id),
|
|
472
|
+
reserveArrayIndex: transaction.pure.u64(this.findReserveArrayIndex(coinType)),
|
|
473
|
+
liquidityRequest,
|
|
516
474
|
});
|
|
517
475
|
}
|
|
518
|
-
borrowAndSendToUser(ownerId, obligationOwnerCap, obligationId, coinType, value, transaction) {
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
transaction.transferObjects([borrowCoin], transaction.pure.address(ownerId));
|
|
522
|
-
});
|
|
476
|
+
async borrowAndSendToUser(ownerId, obligationOwnerCap, obligationId, coinType, value, transaction) {
|
|
477
|
+
const [borrowCoin] = await this.borrow(obligationOwnerCap, obligationId, coinType, value, transaction);
|
|
478
|
+
transaction.transferObjects([borrowCoin], transaction.pure.address(ownerId));
|
|
523
479
|
}
|
|
524
480
|
repay(obligationId, coinType, coin, transaction) {
|
|
525
481
|
return repay(transaction, [this.lendingMarket.$typeArgs[0], coinType], {
|
|
@@ -530,38 +486,32 @@ export class SuilendClient {
|
|
|
530
486
|
maxRepayCoins: coin,
|
|
531
487
|
});
|
|
532
488
|
}
|
|
533
|
-
repayIntoObligation(ownerId, obligationId, coinType, value, transaction) {
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
return result;
|
|
539
|
-
});
|
|
489
|
+
async repayIntoObligation(ownerId, obligationId, coinType, value, transaction) {
|
|
490
|
+
const sendCoin = await getSpendableCoin(this.suiGrpcClient, ownerId, coinType, value, transaction);
|
|
491
|
+
const result = this.repay(obligationId, coinType, sendCoin, transaction);
|
|
492
|
+
transaction.transferObjects([sendCoin], transaction.pure.address(ownerId));
|
|
493
|
+
return result;
|
|
540
494
|
}
|
|
541
|
-
liquidateAndRedeem(transaction, obligation, repayCoinType, withdrawCoinType, repayCoinId) {
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
arguments: [exemption],
|
|
550
|
-
});
|
|
551
|
-
return this.redeem(ctokens, withdrawCoinType, optionalExemption, transaction);
|
|
495
|
+
async liquidateAndRedeem(transaction, obligation, repayCoinType, withdrawCoinType, repayCoinId) {
|
|
496
|
+
const [ctokens, exemption] = await this.liquidate(transaction, obligation, repayCoinType, withdrawCoinType, repayCoinId);
|
|
497
|
+
const [optionalExemption] = transaction.moveCall({
|
|
498
|
+
target: `0x1::option::some`,
|
|
499
|
+
typeArguments: [
|
|
500
|
+
`${PUBLISHED_AT}::lending_market::RateLimiterExemption<${this.lendingMarket.$typeArgs[0]}, ${withdrawCoinType}>`,
|
|
501
|
+
],
|
|
502
|
+
arguments: [exemption],
|
|
552
503
|
});
|
|
504
|
+
return this.redeem(ctokens, withdrawCoinType, optionalExemption, transaction);
|
|
553
505
|
}
|
|
554
|
-
liquidate(transaction, obligation, repayCoinType, withdrawCoinType, repayCoinId) {
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
repayCoins: repayCoinId,
|
|
564
|
-
});
|
|
506
|
+
async liquidate(transaction, obligation, repayCoinType, withdrawCoinType, repayCoinId) {
|
|
507
|
+
await this.refreshAll(transaction, obligation);
|
|
508
|
+
return liquidate(transaction, [this.lendingMarket.$typeArgs[0], repayCoinType, withdrawCoinType], {
|
|
509
|
+
lendingMarket: transaction.object(this.lendingMarket.id),
|
|
510
|
+
obligationId: obligation.id,
|
|
511
|
+
repayReserveArrayIndex: transaction.pure.u64(this.findReserveArrayIndex(repayCoinType)),
|
|
512
|
+
withdrawReserveArrayIndex: transaction.pure.u64(this.findReserveArrayIndex(withdrawCoinType)),
|
|
513
|
+
clock: transaction.object(SUI_CLOCK_OBJECT_ID),
|
|
514
|
+
repayCoins: repayCoinId,
|
|
565
515
|
});
|
|
566
516
|
}
|
|
567
517
|
migrate(transaction, lendingMarketOwnerCapId) {
|
|
@@ -585,25 +535,23 @@ export class SuilendClient {
|
|
|
585
535
|
weights,
|
|
586
536
|
});
|
|
587
537
|
}
|
|
588
|
-
redeemCtokensAndWithdrawLiquidity(ownerId, ctokenCoinTypes, transaction) {
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
}
|
|
607
|
-
});
|
|
538
|
+
async redeemCtokensAndWithdrawLiquidity(ownerId, ctokenCoinTypes, transaction) {
|
|
539
|
+
for (const ctokenCoinType of ctokenCoinTypes) {
|
|
540
|
+
const coins = await getAllCoins(this.suiGrpcClient, ownerId, ctokenCoinType);
|
|
541
|
+
const totalBalance = coins.reduce((sum, c) => sum + BigInt(c.balance), BigInt(0));
|
|
542
|
+
if (totalBalance === BigInt(0))
|
|
543
|
+
throw new Error(`No ${ctokenCoinType} coins found for redeem`);
|
|
544
|
+
const ctokenCoin = await getSpendableCoin(this.suiGrpcClient, ownerId, ctokenCoinType, totalBalance.toString(), transaction);
|
|
545
|
+
const coinType = extractCTokenCoinType(ctokenCoinType);
|
|
546
|
+
const [exemption] = transaction.moveCall({
|
|
547
|
+
target: `0x1::option::none`,
|
|
548
|
+
typeArguments: [
|
|
549
|
+
`${PACKAGE_ID}::lending_market::RateLimiterExemption<${this.lendingMarket.$typeArgs[0]}, ${coinType}>`,
|
|
550
|
+
],
|
|
551
|
+
arguments: [],
|
|
552
|
+
});
|
|
553
|
+
const [redeemCoin] = this.redeem(ctokenCoin, coinType, exemption, transaction);
|
|
554
|
+
transaction.transferObjects([redeemCoin], transaction.pure.address(ownerId));
|
|
555
|
+
}
|
|
608
556
|
}
|
|
609
557
|
}
|