@suilend/sdk 12.5.0 → 12.6.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/client.js +87 -14
- package/package.json +1 -1
package/client.js
CHANGED
|
@@ -50,6 +50,17 @@ export const ADMIN_ADDRESS = process.env.NEXT_PUBLIC_SUILEND_USE_BETA_MARKET ===
|
|
|
50
50
|
const SUILEND_UPGRADE_CAP_ID = process.env.NEXT_PUBLIC_SUILEND_USE_BETA_MARKET === "true"
|
|
51
51
|
? "0x05da14368a42a351e106806c09727968ae26be77a6741a018239ef0f99d5185e"
|
|
52
52
|
: "0x3d4ef1859c3ee9fc72858f588b56a09da5466e64f8cc4e90a7b3b909fba8a7ae";
|
|
53
|
+
// A suilend package accepts only markets whose `version` equals the
|
|
54
|
+
// CURRENT_VERSION it was compiled with, and the UpgradeCap names the newest
|
|
55
|
+
// package before any market migrates to it. So only the newest market version
|
|
56
|
+
// follows the cap; each older version pins the last package built for it.
|
|
57
|
+
const LATEST_MARKET_VERSION = BigInt(8);
|
|
58
|
+
const PUBLISHED_AT_BY_MARKET_VERSION = new Map([
|
|
59
|
+
[
|
|
60
|
+
BigInt(7),
|
|
61
|
+
"0x59672975e15c58ffc9450f5236b6aa9fa2407d94b8081e634778aa01957d8c6f",
|
|
62
|
+
],
|
|
63
|
+
]);
|
|
53
64
|
export const LENDING_MARKET_REGISTRY_ID = process.env.NEXT_PUBLIC_SUILEND_USE_BETA_MARKET === "true"
|
|
54
65
|
? "0x925c9a2336b02fc2b68099837bd66f6b5b4d45cd460e0a4b81708bac6c440eff"
|
|
55
66
|
: "0x64faff8d91a56c4f55debbb44767b009ee744a70bc2cc8e3bbd2718c92f85931";
|
|
@@ -242,6 +253,54 @@ function applyPublishedAt(publishedAt, logPackageId) {
|
|
|
242
253
|
console.log("@suilend/sdk | publishedAt:", publishedAt);
|
|
243
254
|
setPublishedAt(publishedAt);
|
|
244
255
|
}
|
|
256
|
+
function startLatestPackageIdRead(suiGrpcClient) {
|
|
257
|
+
const latestPackageId = getLatestPackageId(suiGrpcClient, SUILEND_UPGRADE_CAP_ID);
|
|
258
|
+
// Read eagerly to overlap the market fetch, but unused while MAIN's version
|
|
259
|
+
// is pinned: an unobserved rejection would crash a bun process.
|
|
260
|
+
latestPackageId.catch(() => { });
|
|
261
|
+
return latestPackageId;
|
|
262
|
+
}
|
|
263
|
+
async function publishedAtForMainVersion(mainVersion, latestPackageId) {
|
|
264
|
+
if (process.env.NEXT_PUBLIC_SUILEND_USE_BETA_MARKET === "true" ||
|
|
265
|
+
mainVersion === LATEST_MARKET_VERSION)
|
|
266
|
+
return latestPackageId;
|
|
267
|
+
const pinned = PUBLISHED_AT_BY_MARKET_VERSION.get(mainVersion);
|
|
268
|
+
if (!pinned)
|
|
269
|
+
throw new Error(`No suilend package is known for lending market version ${mainVersion} (MAIN ${LENDING_MARKET_ID})`);
|
|
270
|
+
return pinned;
|
|
271
|
+
}
|
|
272
|
+
async function readMainVersion(suiGrpcClient) {
|
|
273
|
+
const { object } = await suiGrpcClient.getObject({
|
|
274
|
+
objectId: LENDING_MARKET_ID,
|
|
275
|
+
include: { content: true },
|
|
276
|
+
});
|
|
277
|
+
const expectedType = `${PACKAGE_ID}::lending_market::LendingMarket<${LENDING_MARKET_TYPE}>`;
|
|
278
|
+
if (!object.type ||
|
|
279
|
+
normalizeStructTag(object.type) !== normalizeStructTag(expectedType))
|
|
280
|
+
throw new Error(`object at id ${LENDING_MARKET_ID} is not a ${expectedType} (got ${object.type})`);
|
|
281
|
+
// LendingMarket's BCS starts with its 32-byte UID, then `version: u64`, so
|
|
282
|
+
// the version is read without decoding every reserve.
|
|
283
|
+
return BigInt(bcs.u64().parse(object.content.subarray(32, 40)));
|
|
284
|
+
}
|
|
285
|
+
// Same in-flight-only contract as ownedObjectsCache: N markets initializing at
|
|
286
|
+
// once share one MAIN read, and nothing outlives settlement, so a long-running
|
|
287
|
+
// process sees a migrate on its next initialize.
|
|
288
|
+
const mainVersionInFlight = new WeakMap();
|
|
289
|
+
function fetchMainVersion(suiGrpcClient) {
|
|
290
|
+
const inFlight = mainVersionInFlight.get(suiGrpcClient);
|
|
291
|
+
if (inFlight)
|
|
292
|
+
return inFlight;
|
|
293
|
+
const promise = readMainVersion(suiGrpcClient).finally(() => mainVersionInFlight.delete(suiGrpcClient));
|
|
294
|
+
mainVersionInFlight.set(suiGrpcClient, promise);
|
|
295
|
+
return promise;
|
|
296
|
+
}
|
|
297
|
+
function isMainMarket(lendingMarketId) {
|
|
298
|
+
return (normalizeSuiObjectId(lendingMarketId) ===
|
|
299
|
+
normalizeSuiObjectId(LENDING_MARKET_ID));
|
|
300
|
+
}
|
|
301
|
+
function versionMismatch(lendingMarketId, version, mainVersion) {
|
|
302
|
+
return `lending market ${lendingMarketId} is at version ${version}, but MAIN ${LENDING_MARKET_ID} is at version ${mainVersion}, so the suilend package chosen for MAIN aborts on its writes`;
|
|
303
|
+
}
|
|
245
304
|
function clientsFromObjects(lendingMarkets, objects, suiGrpcClient) {
|
|
246
305
|
// Paired by objectId rather than by position: BatchGetObjectsResponse
|
|
247
306
|
// documents no ordering guarantee, and every object here is a
|
|
@@ -316,9 +375,17 @@ export class SuilendClient {
|
|
|
316
375
|
this.pythConnection = resolvePriceUpdateDataSource();
|
|
317
376
|
}
|
|
318
377
|
static async initialize(lendingMarketId, lendingMarketType, suiGrpcClient, logPackageId) {
|
|
319
|
-
const
|
|
320
|
-
const
|
|
321
|
-
|
|
378
|
+
const latestPackageId = startLatestPackageIdRead(suiGrpcClient);
|
|
379
|
+
const [lendingMarket, fetchedMainVersion] = await Promise.all([
|
|
380
|
+
LendingMarket.fetch(suiGrpcClient, phantom(lendingMarketType), lendingMarketId),
|
|
381
|
+
isMainMarket(lendingMarketId)
|
|
382
|
+
? undefined
|
|
383
|
+
: fetchMainVersion(suiGrpcClient),
|
|
384
|
+
]);
|
|
385
|
+
const mainVersion = fetchedMainVersion ?? lendingMarket.version;
|
|
386
|
+
if (lendingMarket.version !== mainVersion)
|
|
387
|
+
throw new Error(versionMismatch(lendingMarketId, lendingMarket.version, mainVersion));
|
|
388
|
+
applyPublishedAt(await publishedAtForMainVersion(mainVersion, latestPackageId), logPackageId);
|
|
322
389
|
return new SuilendClient(lendingMarket, suiGrpcClient);
|
|
323
390
|
}
|
|
324
391
|
/**
|
|
@@ -326,25 +393,31 @@ export class SuilendClient {
|
|
|
326
393
|
* request rather than one per market.
|
|
327
394
|
*/
|
|
328
395
|
static async initializeAll(lendingMarkets, suiGrpcClient, logPackageId) {
|
|
329
|
-
//
|
|
330
|
-
//
|
|
331
|
-
//
|
|
332
|
-
const
|
|
333
|
-
|
|
396
|
+
// Chosen even for an empty list: move-call targets are built off the
|
|
397
|
+
// PUBLISHED_AT module global regardless of how many clients came back. Like
|
|
398
|
+
// initialize(), a call that fails at any read leaves it unchanged.
|
|
399
|
+
const latestPackageId = startLatestPackageIdRead(suiGrpcClient);
|
|
400
|
+
const mainRequested = lendingMarkets.some(({ id }) => isMainMarket(id));
|
|
401
|
+
const [objects, fetchedMainVersion] = await Promise.all([
|
|
334
402
|
lendingMarkets.length === 0
|
|
335
403
|
? []
|
|
336
404
|
: suiGrpcClient
|
|
337
405
|
.getObjects({
|
|
338
|
-
objectIds: lendingMarkets.map((
|
|
406
|
+
objectIds: lendingMarkets.map(({ id }) => id),
|
|
339
407
|
include: { content: true },
|
|
340
408
|
})
|
|
341
409
|
.then((response) => response.objects),
|
|
410
|
+
mainRequested ? undefined : fetchMainVersion(suiGrpcClient),
|
|
342
411
|
]);
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
412
|
+
const clients = clientsFromObjects(lendingMarkets, objects, suiGrpcClient);
|
|
413
|
+
const mainVersion = fetchedMainVersion ??
|
|
414
|
+
clients[lendingMarkets.findIndex(({ id }) => isMainMarket(id))]
|
|
415
|
+
.lendingMarket.version;
|
|
416
|
+
applyPublishedAt(await publishedAtForMainVersion(mainVersion, latestPackageId), logPackageId);
|
|
417
|
+
for (const { lendingMarket } of clients)
|
|
418
|
+
if (lendingMarket.version !== mainVersion)
|
|
419
|
+
console.warn(`@suilend/sdk | ${versionMismatch(lendingMarket.id, lendingMarket.version, mainVersion)}`);
|
|
420
|
+
return clients;
|
|
348
421
|
}
|
|
349
422
|
static initializeAllFromObjects(lendingMarkets, objects, publishedAt, suiGrpcClient, logPackageId) {
|
|
350
423
|
if (!isValidSuiAddress(publishedAt))
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@suilend/sdk","version":"12.
|
|
1
|
+
{"name":"@suilend/sdk","version":"12.6.0","private":false,"description":"A TypeScript SDK for interacting with the Suilend program","author":"Suilend","license":"MIT","main":"./index.js","exports":{".":"./index.js","./client":"./client.js","./mmt":"./mmt.js","./strategies":"./strategies.js","./api/events":"./api/events.js","./api":"./api/index.js","./lib/constants":"./lib/constants.js","./lib":"./lib/index.js","./lib/initialize":"./lib/initialize.js","./lib/liquidityMining":"./lib/liquidityMining.js","./lib/proCompatible":"./lib/proCompatible.js","./lib/pyth":"./lib/pyth.js","./lib/strategyOwnerCap":"./lib/strategyOwnerCap.js","./lib/transactions":"./lib/transactions.js","./lib/types":"./lib/types.js","./margin":"./margin/index.js","./parsers/apiReserveAssetDataEvent":"./parsers/apiReserveAssetDataEvent.js","./parsers":"./parsers/index.js","./parsers/lendingMarket":"./parsers/lendingMarket.js","./parsers/obligation":"./parsers/obligation.js","./parsers/rateLimiter":"./parsers/rateLimiter.js","./parsers/reserve":"./parsers/reserve.js","./swap":"./swap/index.js","./swap/quote":"./swap/quote.js","./swap/transaction":"./swap/transaction.js","./utils/events":"./utils/events.js","./utils/feedId":"./utils/feedId.js","./utils":"./utils/index.js","./utils/obligation":"./utils/obligation.js","./utils/simulate":"./utils/simulate.js","./_generated/_framework/reified":"./_generated/_framework/reified.js","./_generated/_framework/util":"./_generated/_framework/util.js","./_generated/_framework/vector":"./_generated/_framework/vector.js","./_generated/suilend":"./_generated/suilend/index.js","./margin/margin/admin_cap":"./margin/margin/admin_cap.js","./margin/margin/market":"./margin/margin/market.js","./margin/margin/permissions":"./margin/margin/permissions.js","./margin/margin/position":"./margin/margin/position.js","./margin/margin/router":"./margin/margin/router.js","./margin/margin/version":"./margin/margin/version.js","./margin/utils":"./margin/utils/index.js","./_generated/suilend/cell/structs":"./_generated/suilend/cell/structs.js","./_generated/suilend/decimal/structs":"./_generated/suilend/decimal/structs.js","./_generated/suilend/lending-market/functions":"./_generated/suilend/lending-market/functions.js","./_generated/suilend/lending-market/structs":"./_generated/suilend/lending-market/structs.js","./_generated/suilend/lending-market-registry/functions":"./_generated/suilend/lending-market-registry/functions.js","./_generated/suilend/liquidity-mining/structs":"./_generated/suilend/liquidity-mining/structs.js","./_generated/suilend/obligation/structs":"./_generated/suilend/obligation/structs.js","./_generated/suilend/rate-limiter/functions":"./_generated/suilend/rate-limiter/functions.js","./_generated/suilend/rate-limiter/structs":"./_generated/suilend/rate-limiter/structs.js","./_generated/suilend/reserve/structs":"./_generated/suilend/reserve/structs.js","./_generated/suilend/reserve-config/functions":"./_generated/suilend/reserve-config/functions.js","./_generated/suilend/reserve-config/structs":"./_generated/suilend/reserve-config/structs.js","./_generated/_dependencies/source/0x1":"./_generated/_dependencies/source/0x1/index.js","./_generated/_dependencies/source/0x2":"./_generated/_dependencies/source/0x2/index.js","./_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e":"./_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/index.js","./margin/margin/deps/std/type_name":"./margin/margin/deps/std/type_name.js","./margin/margin/deps/sui/vec_set":"./margin/margin/deps/sui/vec_set.js","./margin/margin/deps/suilend/lending_market":"./margin/margin/deps/suilend/lending_market.js","./_generated/_dependencies/source/0x1/ascii/structs":"./_generated/_dependencies/source/0x1/ascii/structs.js","./_generated/_dependencies/source/0x1/option/structs":"./_generated/_dependencies/source/0x1/option/structs.js","./_generated/_dependencies/source/0x1/type-name/structs":"./_generated/_dependencies/source/0x1/type-name/structs.js","./_generated/_dependencies/source/0x2/bag/structs":"./_generated/_dependencies/source/0x2/bag/structs.js","./_generated/_dependencies/source/0x2/balance/structs":"./_generated/_dependencies/source/0x2/balance/structs.js","./_generated/_dependencies/source/0x2/object/structs":"./_generated/_dependencies/source/0x2/object/structs.js","./_generated/_dependencies/source/0x2/object-table/structs":"./_generated/_dependencies/source/0x2/object-table/structs.js","./_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-identifier/structs":"./_generated/_dependencies/source/0x8d97f1cd6ac663735be08d1d2b6d02a159e711586461306ce60a2b7a6a565a9e/price-identifier/structs.js"},"types":"./index.d.ts","scripts":{"build":"rm -rf ./dist && tsc && node ./fix-esm-imports.js","typecheck":"tsc --noEmit && tsc --noEmit -p tsconfig.test.json","test":"vitest run","lint:ci":"yarn run typecheck","prettier":"prettier --write src/ tests/","release":"yarn run build && node ./release.js && cd ./dist && npm publish --access public"},"repository":{"type":"git","url":"git+https://github.com/fireflyprotocol/lending-mono.git","directory":"ts/sdks/sdk"},"dependencies":{"@bluefin-exchange/bluefin7k-aggregator-sdk":"7.6.3","@cetusprotocol/aggregator-sdk":"1.7.3","@flowx-finance/sdk":"2.1.0","@pythnetwork/hermes-client":"3.1.0","@pythnetwork/pyth-sui-js":"4.0.0","@suilend/springsui-sdk":"4.1.0","bignumber.js":"11.1.5","bn.js":"5.2.5","crypto-js":"4.2.0","lodash":"4.18.1","p-limit":"7.3.3","uuid":"14.0.2"},"devDependencies":{"@mysten/bcs":"2.1.1","@mysten/sui":"2.29.0","@suilend/sui-core":"2.1.0","@tsconfig/recommended":"1.0.13","@types/bn.js":"5.2.0","@types/lodash":"4.17.25","@types/node":"26.5.1","fast-check":"4.10.2","prettier":"3.9.9","ts-node":"10.9.2","typescript":"6.0.3","vite":"8.3.0","vitest":"5.0.1"},"peerDependencies":{"@mysten/bcs":"^2.1.1","@mysten/sui":">=2.22.1 <3","@suilend/sui-core":"^2.0.1"},"type":"module"}
|