@suilend/sdk 14.2.1-next.gbfd3a97 → 14.3.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/README.md CHANGED
@@ -2,6 +2,45 @@
2
2
 
3
3
  A TypeScript SDK for interacting with the Suilend program published on npm as [`@suilend/sdk`](https://www.npmjs.com/package/@suilend/sdk).
4
4
 
5
+ ### Other networks
6
+
7
+ The SDK targets mainnet by default. A process that runs against localnet calls
8
+ `setSuilendNetwork` once at startup, before it builds any client:
9
+
10
+ ```ts
11
+ import { SUILEND_MAINNET_NETWORK, setSuilendNetwork } from "@suilend/sdk";
12
+ import { freshPublishEnv } from "@suilend/sui-core";
13
+
14
+ setSuilendNetwork({
15
+ name: "localnet",
16
+ env: freshPublishEnv(SUILEND_MAINNET_NETWORK.env, { suilend: suilendPackageId }),
17
+ mainLendingMarket: { id: lendingMarketId, type: lendingMarketType },
18
+ suilendUpgradeCapId,
19
+ latestMarketVersion: BigInt(8),
20
+ publishedAtByMarketVersion: new Map(),
21
+ pythStateId,
22
+ wormholeStateId,
23
+ });
24
+ ```
25
+
26
+ Give `freshPublishEnv` every dependency the localnet publish replaced as well,
27
+ such as `liquid-staking` and `sprungsui`. Call `setSpringSuiNetwork` from
28
+ `@suilend/springsui-sdk` at startup too: `setSuilendNetwork` does not set it,
29
+ and strategy and LST reads such as `fetchStrategyLstMap` take the SpringSui
30
+ UpgradeCap from it. `SuilendClient.initialize` then reads
31
+ that network's MAIN market and UpgradeCap, and generated move calls and type
32
+ names follow its package env.
33
+ Exported constants such as `LENDING_MARKET_ID` stay the mainnet values; read
34
+ `getSuilendNetwork()` for the active ones. The SDK's Suilend API reads, such as
35
+ the strategy TVL and LST info, build their URL from `getApiUrl()` in
36
+ `@suilend/sui-core`, so `setApiUrl` moves them with sui-core's own helpers. Strategies on MAIN use the active
37
+ network's MAIN market. Without `strategyWrapper`, strategy calls throw, and
38
+ owned-obligation reads skip strategy owner caps. Setting a network with the same
39
+ name, UpgradeCaps and suilend original id and published-at again keeps the package
40
+ `SuilendClient.initialize` resolved; any other network drops it, so initialize
41
+ again after switching. The name `mainnet` belongs to the generated mainnet env. A mainnet fork keeps
42
+ `SUILEND_MAINNET_NETWORK`.
43
+
5
44
  ### Pyth access
6
45
 
7
46
  Public Hermes requires a Pyth API key, so `initializeSuilend` and `initializeSuilendAll` need yours. Without it, every price read fails with 401. The Suilend API's Pyth routes, `/proxy/latest-prices` and `/proxy/price-update-data`, spend our key and only answer Suilend's own frontends, so a third-party browser page cannot use them.
package/api/events.js CHANGED
@@ -1,10 +1,11 @@
1
- import { API_URL } from "@suilend/sui-core";
1
+ import { assertResponseOk, getApiUrl } from "@suilend/sui-core";
2
2
  /**
3
3
  * Note: This SDK function is experimental and may change or require authentication in the future.
4
4
  */
5
5
  export const fetchDownsampledApiReserveAssetDataEvents = async (reserveId, days, sampleIntervalS) => {
6
- const url = `${API_URL}/events/downsampled-reserve-asset-data?reserveId=${reserveId}&days=${days}&sampleIntervalS=${sampleIntervalS}`;
6
+ const url = `${getApiUrl()}/events/downsampled-reserve-asset-data?reserveId=${reserveId}&days=${days}&sampleIntervalS=${sampleIntervalS}`;
7
7
  const res = await fetch(url);
8
+ assertResponseOk(res, "Downsampled reserve asset data events request");
8
9
  const json = await res.json();
9
10
  return json;
10
11
  };
package/client.js CHANGED
@@ -6,9 +6,7 @@ import { extractCTokenCoinType, getAllCoins, getSpendableCoin, } from "@suilend/
6
6
  import { phantom } from "./_generated/_framework/reified.js";
7
7
  import { Decimal } from "./_generated/suilend/decimal/structs.js";
8
8
  import { confidenceShare, decimalToBigNumber, } from "./utils/simulate.js";
9
- import { PKG_V10, setPublishedAt } from "./_generated/suilend/index.js";
10
- import { getPublishedAt } from "./_generated/_envs/index.js";
11
- import { PACKAGE_ID } from "./_generated/suilend/index.js";
9
+ import { getOriginalId, getPublishedAt, getTypeOrigin, } from "./_generated/_envs/index.js";
12
10
  import { addPoolReward, borrowRequest, cancelPoolReward, claimFees, claimRewards, claimRewardsAndDeposit, closePoolReward, depositCtokensIntoObligation, depositLiquidityAndMintCtokens, fulfillLiquidityRequest, liquidate, migrate, newObligationOwnerCap, rebalanceStaker, redeemCtokensAndWithdrawLiquidityRequest, repay, reserveConfigBuilder, setFeeReceivers, unstakeSuiFromStaker, updateRateLimiterConfig, updateReserveConfig, withdrawCtokens, } from "./_generated/suilend/lending-market/functions.js";
13
11
  import { LendingMarket, ObligationOwnerCap, } from "./_generated/suilend/lending-market/structs.js";
14
12
  import { createLendingMarket } from "./_generated/suilend/lending-market-registry/functions.js";
@@ -18,21 +16,11 @@ import { build as buildReserveConfig, createReserveConfig, setBorrowFeeBps, setB
18
16
  import { addReserveProCompatible, addReserveV2ProCompatible, changeReservePriceFeedProCompatible, priceInfoPublishTime, refreshReservePriceProCompatible, } from "./lib/proCompatible.js";
19
17
  import { resolvePriceUpdateDataSource, } from "./lib/pyth.js";
20
18
  import { Side } from "./lib/types.js";
19
+ import { SUILEND_MAINNET_NETWORK, getStrategyWrapperNetwork, getSuilendNetwork, isSameSuilendNetwork, setPublishedAt, } from "./network.js";
21
20
  import { chunkedMultiGet } from "./utils/obligation.js";
22
21
  const SUI_COINTYPE = "0x2::sui::SUI";
23
22
  const NORMALIZED_SUI_COINTYPE = normalizeStructTag(SUI_COINTYPE);
24
23
  const isSui = (coinType) => normalizeStructTag(coinType) === NORMALIZED_SUI_COINTYPE;
25
- // Pyth Core's 2026-08-18 upgrade. These are the UPGRADED state objects, which
26
- // pair with the pro-compatible Pyth package the Move contracts now link against
27
- // (see move/contracts/suilend/Move.toml). The pre-upgrade values were
28
- // Wormhole 0xaeab97f9… and Pyth 0x1f931023….
29
- //
30
- // MUST ship in the same release as the suilend package upgrade. Pointing the
31
- // SDK at the upgraded state while the published package still links the legacy
32
- // Pyth package breaks every on-chain price update -- the object passed to
33
- // refresh would come from a package the contract does not accept.
34
- const WORMHOLE_STATE_ID = "0xdbca52b9fb4f712e25f61f974586d93ac541bcf8389564f0323bb07215168b5c";
35
- const PYTH_STATE_ID = "0x03719fae774ddab3cfcaa53bbc046f0cbe21410019b6280811bf3f9f4b05839d";
36
24
  const normalizePriceIdentifier = (id) => id.toLowerCase().replace(/^0x/, "");
37
25
  // Mirrors suilend::oracles's MAX_FORWARD_SECONDS (move/contracts/suilend/sources/oracles.move);
38
26
  // `refresh_reserve_price` now rejects a forward-dated price the same as a stale one.
@@ -48,36 +36,28 @@ export function needsPriceRefresh(stalenessSeconds) {
48
36
  return stalenessSeconds > 20 || stalenessSeconds < -MAX_FORWARD_SECONDS;
49
37
  }
50
38
  export const ADMIN_ADDRESS = "0xb1ffbc2e1915f44b8f271a703becc1bf8aa79bc22431a58900a102892b783c25";
51
- const SUILEND_UPGRADE_CAP_ID = "0x3d4ef1859c3ee9fc72858f588b56a09da5466e64f8cc4e90a7b3b909fba8a7ae";
52
- // A suilend package accepts only markets whose `version` equals the
53
- // CURRENT_VERSION it was compiled with, and the UpgradeCap names the newest
54
- // package before any market migrates to it. So only the newest market version
55
- // follows the cap; each older version pins the last package built for it.
56
- const LATEST_MARKET_VERSION = BigInt(8);
57
- const PUBLISHED_AT_BY_MARKET_VERSION = new Map([
58
- [
59
- BigInt(7),
60
- "0x59672975e15c58ffc9450f5236b6aa9fa2407d94b8081e634778aa01957d8c6f",
61
- ],
62
- ]);
63
- const STRATEGY_WRAPPER_UPGRADE_CAP_ID = "0x486ef016bd357fadf981aba35a6c31df8d4c0c4136b2e78fdda87cb2832f3033";
64
- const STRATEGY_WRAPPER_PACKAGE_ID_V7 = "0x864b66441e95323c320ee7584592769930a2d236b45d731011ee7a98eb785b35";
65
- const STRATEGY_WRAPPER_PACKAGE_ID_BY_MARKET_VERSION = new Map([
66
- [BigInt(7), STRATEGY_WRAPPER_PACKAGE_ID_V7],
67
- ]);
68
- let strategyWrapperPackage = STRATEGY_WRAPPER_PACKAGE_ID_V7;
39
+ let strategyWrapperPackage;
69
40
  export function getStrategyWrapperPackageId() {
70
- if (typeof strategyWrapperPackage !== "string")
71
- throw new Error(`The strategy_wrapper package is unresolved: reading its UpgradeCap ${STRATEGY_WRAPPER_UPGRADE_CAP_ID} failed at MAIN lending market version ${LATEST_MARKET_VERSION}. Retry SuilendClient.initialize before building strategy transactions.`, { cause: strategyWrapperPackage.readError });
72
- return strategyWrapperPackage;
41
+ const network = getSuilendNetwork();
42
+ const strategyWrapper = getStrategyWrapperNetwork();
43
+ const resolved = strategyWrapperPackage &&
44
+ isSameSuilendNetwork(strategyWrapperPackage.network, network)
45
+ ? strategyWrapperPackage.resolved
46
+ : strategyWrapper.defaultPackageId;
47
+ if (typeof resolved !== "string")
48
+ throw new Error(`The strategy_wrapper package is unresolved: reading its UpgradeCap ${strategyWrapper.upgradeCapId} failed at MAIN lending market version ${network.latestMarketVersion}. Retry SuilendClient.initialize before building strategy transactions.`, { cause: resolved.readError });
49
+ return resolved;
73
50
  }
74
51
  export function setStrategyWrapperPackageId(packageId) {
75
- strategyWrapperPackage = packageId;
52
+ strategyWrapperPackage = {
53
+ network: getSuilendNetwork(),
54
+ resolved: packageId,
55
+ };
76
56
  }
77
57
  export const LENDING_MARKET_REGISTRY_ID = "0x64faff8d91a56c4f55debbb44767b009ee744a70bc2cc8e3bbd2718c92f85931";
78
58
  export const [LENDING_MARKET_ID, LENDING_MARKET_TYPE] = [
79
- "0x84030d26d85eaa7035084a057f2f11f701b7e2e4eda87551becbc7c97505ece1",
80
- "0xf95b06141ed4a174f239417323bde3f209b972f5930d8521ea38a52aff3a6ddf::suilend::MAIN_POOL",
59
+ SUILEND_MAINNET_NETWORK.mainLendingMarket.id,
60
+ SUILEND_MAINNET_NETWORK.mainLendingMarket.type,
81
61
  ];
82
62
  export const [STEAMM_LM_LENDING_MARKET_ID, STEAMM_LM_LENDING_MARKET_TYPE] = [
83
63
  "0xc1888ec1b81a414e427a44829310508352aec38252ee0daa9f8b181b6947de9f",
@@ -258,44 +238,57 @@ function applyPublishedAt(publishedAt, logPackageId) {
258
238
  console.log("@suilend/sdk | publishedAt:", publishedAt);
259
239
  setPublishedAt(publishedAt);
260
240
  }
261
- function startLatestPackageIdRead(suiGrpcClient) {
262
- const latestPackageId = getLatestPackageId(suiGrpcClient, SUILEND_UPGRADE_CAP_ID);
241
+ function startLatestPackageIdRead(suiGrpcClient, network) {
242
+ const latestPackageId = getLatestPackageId(suiGrpcClient, network.suilendUpgradeCapId);
263
243
  // Read eagerly to overlap the market fetch, but unused while MAIN's version
264
244
  // is pinned: an unobserved rejection would crash a bun process.
265
245
  latestPackageId.catch(() => { });
266
246
  return latestPackageId;
267
247
  }
268
- async function applyPackagesForMainVersion(suiGrpcClient, mainVersion, latestPackageId, logPackageId) {
269
- if (mainVersion === LATEST_MARKET_VERSION) {
270
- const [publishedAt, strategyWrapper] = await Promise.all([
248
+ function assertNetworkUnchanged(network) {
249
+ const active = getSuilendNetwork();
250
+ if (!isSameSuilendNetwork(active, network))
251
+ throw new Error(`The Suilend network changed from ${network.name} to ${active.name} while SuilendClient.initialize ran. Call initialize again.`);
252
+ }
253
+ async function applyPackagesForMainVersion(suiGrpcClient, network, mainVersion, latestPackageId, logPackageId) {
254
+ const { strategyWrapper } = network;
255
+ if (mainVersion === network.latestMarketVersion) {
256
+ const [publishedAt, strategyWrapperResolved] = await Promise.all([
271
257
  latestPackageId,
272
- getLatestPackageId(suiGrpcClient, STRATEGY_WRAPPER_UPGRADE_CAP_ID).catch((readError) => ({ readError })),
258
+ strategyWrapper &&
259
+ getLatestPackageId(suiGrpcClient, strategyWrapper.upgradeCapId).catch((readError) => ({ readError })),
273
260
  ]);
261
+ assertNetworkUnchanged(network);
274
262
  applyPublishedAt(publishedAt, logPackageId);
275
- strategyWrapperPackage = strategyWrapper;
263
+ if (strategyWrapperResolved)
264
+ strategyWrapperPackage = { network, resolved: strategyWrapperResolved };
276
265
  return;
277
266
  }
278
- const publishedAt = PUBLISHED_AT_BY_MARKET_VERSION.get(mainVersion);
279
- const strategyWrapper = STRATEGY_WRAPPER_PACKAGE_ID_BY_MARKET_VERSION.get(mainVersion);
280
- if (!publishedAt || !strategyWrapper) {
267
+ const publishedAt = network.publishedAtByMarketVersion.get(mainVersion);
268
+ const strategyWrapperPackageId = strategyWrapper?.packageIdByMarketVersion.get(mainVersion);
269
+ const missingStrategyWrapper = !!strategyWrapper && !strategyWrapperPackageId;
270
+ if (!publishedAt || missingStrategyWrapper) {
281
271
  const unknown = [
282
272
  ...(publishedAt ? [] : ["suilend"]),
283
- ...(strategyWrapper ? [] : ["strategy_wrapper"]),
273
+ ...(missingStrategyWrapper ? ["strategy_wrapper"] : []),
284
274
  ];
285
- throw new Error(`No ${unknown.join(" or ")} package is known for lending market version ${mainVersion} (MAIN ${LENDING_MARKET_ID})`);
275
+ throw new Error(`No ${unknown.join(" or ")} package is known for lending market version ${mainVersion} (MAIN ${network.mainLendingMarket.id})`);
286
276
  }
277
+ assertNetworkUnchanged(network);
287
278
  applyPublishedAt(publishedAt, logPackageId);
288
- strategyWrapperPackage = strategyWrapper;
279
+ if (strategyWrapperPackageId)
280
+ strategyWrapperPackage = { network, resolved: strategyWrapperPackageId };
289
281
  }
290
- async function readMainVersion(suiGrpcClient) {
282
+ async function readMainVersion(suiGrpcClient, network) {
283
+ const { mainLendingMarket } = network;
291
284
  const { object } = await suiGrpcClient.getObject({
292
- objectId: LENDING_MARKET_ID,
285
+ objectId: mainLendingMarket.id,
293
286
  include: { content: true },
294
287
  });
295
- const expectedType = `${PACKAGE_ID}::lending_market::LendingMarket<${LENDING_MARKET_TYPE}>`;
288
+ const expectedType = `${getOriginalId("suilend")}::lending_market::LendingMarket<${mainLendingMarket.type}>`;
296
289
  if (!object.type ||
297
290
  normalizeStructTag(object.type) !== normalizeStructTag(expectedType))
298
- throw new Error(`object at id ${LENDING_MARKET_ID} is not a ${expectedType} (got ${object.type})`);
291
+ throw new Error(`object at id ${mainLendingMarket.id} is not a ${expectedType} (got ${object.type})`);
299
292
  // LendingMarket's BCS starts with its 32-byte UID, then `version: u64`, so
300
293
  // the version is read without decoding every reserve.
301
294
  return BigInt(bcs.u64().parse(object.content.subarray(32, 40)));
@@ -304,20 +297,23 @@ async function readMainVersion(suiGrpcClient) {
304
297
  // once share one MAIN read, and nothing outlives settlement, so a long-running
305
298
  // process sees a migrate on its next initialize.
306
299
  const mainVersionInFlight = new WeakMap();
307
- function fetchMainVersion(suiGrpcClient) {
300
+ function fetchMainVersion(suiGrpcClient, network) {
308
301
  const inFlight = mainVersionInFlight.get(suiGrpcClient);
309
- if (inFlight)
310
- return inFlight;
311
- const promise = readMainVersion(suiGrpcClient).finally(() => mainVersionInFlight.delete(suiGrpcClient));
312
- mainVersionInFlight.set(suiGrpcClient, promise);
302
+ if (inFlight?.network === network)
303
+ return inFlight.promise;
304
+ const promise = readMainVersion(suiGrpcClient, network).finally(() => {
305
+ if (mainVersionInFlight.get(suiGrpcClient)?.promise === promise)
306
+ mainVersionInFlight.delete(suiGrpcClient);
307
+ });
308
+ mainVersionInFlight.set(suiGrpcClient, { network, promise });
313
309
  return promise;
314
310
  }
315
- function isMainMarket(lendingMarketId) {
311
+ function isMainMarket(lendingMarketId, network) {
316
312
  return (normalizeSuiObjectId(lendingMarketId) ===
317
- normalizeSuiObjectId(LENDING_MARKET_ID));
313
+ normalizeSuiObjectId(network.mainLendingMarket.id));
318
314
  }
319
- function versionMismatch(lendingMarketId, version, mainVersion) {
320
- 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`;
315
+ function versionMismatch(lendingMarketId, version, mainVersion, network) {
316
+ return `lending market ${lendingMarketId} is at version ${version}, but MAIN ${network.mainLendingMarket.id} is at version ${mainVersion}, so the suilend package chosen for MAIN aborts on its writes`;
321
317
  }
322
318
  function clientsFromObjects(lendingMarkets, objects, suiGrpcClient) {
323
319
  // Paired by objectId rather than by position: BatchGetObjectsResponse
@@ -343,7 +339,7 @@ function clientsFromObjects(lendingMarkets, objects, suiGrpcClient) {
343
339
  // Compares the full parameterized type, not just the struct name: an
344
340
  // id/type pair built from two drifted lists would otherwise pass and
345
341
  // decode under the wrong phantom type.
346
- const expectedType = normalizeStructTag(`${PACKAGE_ID}::lending_market::LendingMarket<${type}>`);
342
+ const expectedType = normalizeStructTag(`${getOriginalId("suilend")}::lending_market::LendingMarket<${type}>`);
347
343
  if (normalizeStructTag(object.type) !== expectedType)
348
344
  throw new Error(`object at id ${id} is not a LendingMarket<${type}> (got ${object.type})`);
349
345
  const lendingMarket = LendingMarket.fromBcs(phantom(type), object.content);
@@ -383,27 +379,22 @@ export class SuilendClient {
383
379
  // 'getDynamicField')". That is the on-chain price-update path, i.e. every
384
380
  // deposit/withdraw/borrow/repay, and nothing read-only touches it, so a
385
381
  // typecheck and every page-load check stay green while writes are broken.
386
- this.pythClient = new SuiPythClient(suiGrpcClient, PYTH_STATE_ID, WORMHOLE_STATE_ID);
387
- // Deliberately NOT a public-Hermes connection, which is what stood here.
388
- // `WORMHOLE_STATE_ID` above is unconditionally the pro-compatible
389
- // deployment, and public Hermes signs with a guardian set that deployment
390
- // does not hold — so that default could not produce a usable update for any
391
- // feed, and only looked harmless because `refreshAll` skips the update
392
- // entirely while a feed is fresh. See `resolvePriceUpdateDataSource`.
382
+ this.pythClient = new SuiPythClient(suiGrpcClient, getSuilendNetwork().pythStateId, getSuilendNetwork().wormholeStateId);
393
383
  this.pythConnection = resolvePriceUpdateDataSource();
394
384
  }
395
385
  static async initialize(lendingMarketId, lendingMarketType, suiGrpcClient, logPackageId) {
396
- const latestPackageId = startLatestPackageIdRead(suiGrpcClient);
386
+ const network = getSuilendNetwork();
387
+ const latestPackageId = startLatestPackageIdRead(suiGrpcClient, network);
397
388
  const [lendingMarket, fetchedMainVersion] = await Promise.all([
398
389
  LendingMarket.fetch(suiGrpcClient, phantom(lendingMarketType), lendingMarketId),
399
- isMainMarket(lendingMarketId)
390
+ isMainMarket(lendingMarketId, network)
400
391
  ? undefined
401
- : fetchMainVersion(suiGrpcClient),
392
+ : fetchMainVersion(suiGrpcClient, network),
402
393
  ]);
403
394
  const mainVersion = fetchedMainVersion ?? lendingMarket.version;
404
395
  if (lendingMarket.version !== mainVersion)
405
- throw new Error(versionMismatch(lendingMarketId, lendingMarket.version, mainVersion));
406
- await applyPackagesForMainVersion(suiGrpcClient, mainVersion, latestPackageId, logPackageId);
396
+ throw new Error(versionMismatch(lendingMarketId, lendingMarket.version, mainVersion, network));
397
+ await applyPackagesForMainVersion(suiGrpcClient, network, mainVersion, latestPackageId, logPackageId);
407
398
  return new SuilendClient(lendingMarket, suiGrpcClient);
408
399
  }
409
400
  /**
@@ -414,8 +405,9 @@ export class SuilendClient {
414
405
  // Chosen even for an empty list: move-call targets are built off the
415
406
  // published-at override regardless of how many clients came back. Like
416
407
  // initialize(), a call that fails at any read leaves it unchanged.
417
- const latestPackageId = startLatestPackageIdRead(suiGrpcClient);
418
- const mainRequested = lendingMarkets.some(({ id }) => isMainMarket(id));
408
+ const network = getSuilendNetwork();
409
+ const latestPackageId = startLatestPackageIdRead(suiGrpcClient, network);
410
+ const mainRequested = lendingMarkets.some(({ id }) => isMainMarket(id, network));
419
411
  const [objects, fetchedMainVersion] = await Promise.all([
420
412
  lendingMarkets.length === 0
421
413
  ? []
@@ -425,16 +417,16 @@ export class SuilendClient {
425
417
  include: { content: true },
426
418
  })
427
419
  .then((response) => response.objects),
428
- mainRequested ? undefined : fetchMainVersion(suiGrpcClient),
420
+ mainRequested ? undefined : fetchMainVersion(suiGrpcClient, network),
429
421
  ]);
430
422
  const clients = clientsFromObjects(lendingMarkets, objects, suiGrpcClient);
431
423
  const mainVersion = fetchedMainVersion ??
432
- clients[lendingMarkets.findIndex(({ id }) => isMainMarket(id))]
424
+ clients[lendingMarkets.findIndex(({ id }) => isMainMarket(id, network))]
433
425
  .lendingMarket.version;
434
- await applyPackagesForMainVersion(suiGrpcClient, mainVersion, latestPackageId, logPackageId);
426
+ await applyPackagesForMainVersion(suiGrpcClient, network, mainVersion, latestPackageId, logPackageId);
435
427
  for (const { lendingMarket } of clients)
436
428
  if (lendingMarket.version !== mainVersion)
437
- console.warn(`@suilend/sdk | ${versionMismatch(lendingMarket.id, lendingMarket.version, mainVersion)}`);
429
+ console.warn(`@suilend/sdk | ${versionMismatch(lendingMarket.id, lendingMarket.version, mainVersion, network)}`);
438
430
  return clients;
439
431
  }
440
432
  /**
@@ -451,7 +443,7 @@ export class SuilendClient {
451
443
  return clients;
452
444
  }
453
445
  static async getFeeReceivers(suiGrpcClient, lendingMarketId) {
454
- const json = await fetchDynamicFieldJson(suiGrpcClient, lendingMarketId, `${PKG_V10}::lending_market::FeeReceiversKey`);
446
+ const json = await fetchDynamicFieldJson(suiGrpcClient, lendingMarketId, `${getTypeOrigin("suilend", "lending_market::FeeReceiversKey")}::lending_market::FeeReceiversKey`);
455
447
  const receivers = json?.value?.receivers;
456
448
  const weights = json?.value?.weights;
457
449
  return { receivers, weights };
@@ -503,8 +495,8 @@ export class SuilendClient {
503
495
  return ownerCap;
504
496
  }
505
497
  static async getObligationOwnerCaps(ownerId, lendingMarketTypeArgs, suiGrpcClient) {
506
- const allObjs = await listAllOwnedObjects(suiGrpcClient, ownerId, `${PACKAGE_ID}::lending_market::ObligationOwnerCap`, { content: true });
507
- const type = normalizeStructTag(`${PACKAGE_ID}::lending_market::ObligationOwnerCap<${lendingMarketTypeArgs[0]}>`);
498
+ const allObjs = await listAllOwnedObjects(suiGrpcClient, ownerId, `${getOriginalId("suilend")}::lending_market::ObligationOwnerCap`, { content: true });
499
+ const type = normalizeStructTag(`${getOriginalId("suilend")}::lending_market::ObligationOwnerCap<${lendingMarketTypeArgs[0]}>`);
508
500
  return allObjs
509
501
  .filter((obj) => normalizeStructTag(obj.type) === type)
510
502
  .map((obj) => ObligationOwnerCap.fromBcs(phantom(lendingMarketTypeArgs[0]), obj.content));
@@ -533,8 +525,8 @@ export class SuilendClient {
533
525
  return SuilendClient.getObligation(obligationId, this.lendingMarket.$typeArgs, this.suiGrpcClient);
534
526
  }
535
527
  static async getLendingMarketOwnerCapId(ownerId, lendingMarketTypeArgs, suiGrpcClient) {
536
- const allObjs = await listAllOwnedObjects(suiGrpcClient, ownerId, `${PACKAGE_ID}::lending_market::LendingMarketOwnerCap`);
537
- const type = normalizeStructTag(`${PACKAGE_ID}::lending_market::LendingMarketOwnerCap<${lendingMarketTypeArgs[0]}>`);
528
+ const allObjs = await listAllOwnedObjects(suiGrpcClient, ownerId, `${getOriginalId("suilend")}::lending_market::LendingMarketOwnerCap`);
529
+ const type = normalizeStructTag(`${getOriginalId("suilend")}::lending_market::LendingMarketOwnerCap<${lendingMarketTypeArgs[0]}>`);
538
530
  return allObjs.find((obj) => normalizeStructTag(obj.type) === type)
539
531
  ?.objectId;
540
532
  }
@@ -867,7 +859,7 @@ export class SuilendClient {
867
859
  const [exemption] = transaction.moveCall({
868
860
  target: `0x1::option::none`,
869
861
  typeArguments: [
870
- `${PACKAGE_ID}::lending_market::RateLimiterExemption<${this.lendingMarket.$typeArgs[0]}, ${coinType}>`,
862
+ `${getTypeOrigin("suilend", "lending_market::RateLimiterExemption")}::lending_market::RateLimiterExemption<${this.lendingMarket.$typeArgs[0]}, ${coinType}>`,
871
863
  ],
872
864
  arguments: [],
873
865
  });
@@ -951,7 +943,7 @@ export class SuilendClient {
951
943
  const [optionalExemption] = transaction.moveCall({
952
944
  target: `0x1::option::some`,
953
945
  typeArguments: [
954
- `${getPublishedAt("suilend")}::lending_market::RateLimiterExemption<${this.lendingMarket.$typeArgs[0]}, ${withdrawCoinType}>`,
946
+ `${getTypeOrigin("suilend", "lending_market::RateLimiterExemption")}::lending_market::RateLimiterExemption<${this.lendingMarket.$typeArgs[0]}, ${withdrawCoinType}>`,
955
947
  ],
956
948
  arguments: [exemption],
957
949
  });
@@ -1000,7 +992,7 @@ export class SuilendClient {
1000
992
  const [exemption] = transaction.moveCall({
1001
993
  target: `0x1::option::none`,
1002
994
  typeArguments: [
1003
- `${PACKAGE_ID}::lending_market::RateLimiterExemption<${this.lendingMarket.$typeArgs[0]}, ${coinType}>`,
995
+ `${getTypeOrigin("suilend", "lending_market::RateLimiterExemption")}::lending_market::RateLimiterExemption<${this.lendingMarket.$typeArgs[0]}, ${coinType}>`,
1004
996
  ],
1005
997
  arguments: [],
1006
998
  });
package/index.d.ts CHANGED
@@ -5,3 +5,4 @@ export * from "./strategies";
5
5
  export * from "./swap";
6
6
  export * from "./utils";
7
7
  export * from "./client";
8
+ export * from "./network";
package/index.js CHANGED
@@ -5,3 +5,4 @@ export * from "./strategies.js";
5
5
  export * from "./swap/index.js";
6
6
  export * from "./utils/index.js";
7
7
  export * from "./client.js";
8
+ export * from "./network.js";
@@ -0,0 +1,6 @@
1
+ import type { AggregatorClient } from "@cetusprotocol/aggregator-sdk";
2
+ import type { Transaction, TransactionArgument } from "@mysten/sui/transactions";
3
+ type CetusSwapParams = Parameters<AggregatorClient["routerSwap"]>[0];
4
+ export declare const cetusTransaction: (transaction: Transaction) => CetusSwapParams["txb"];
5
+ export declare const cetusInputCoin: (coin: TransactionArgument) => CetusSwapParams["inputCoin"];
6
+ export {};
@@ -0,0 +1,2 @@
1
+ export const cetusTransaction = (transaction) => transaction;
2
+ export const cetusInputCoin = (coin) => coin;
package/lib/initialize.js CHANGED
@@ -3,7 +3,7 @@ import BigNumber from "bignumber.js";
3
3
  import pLimit from "p-limit";
4
4
  import { NORMALIZED_ALKIMI_COINTYPE, NORMALIZED_AUSD_COINTYPE, NORMALIZED_BLUE_COINTYPE, NORMALIZED_BUCK_COINTYPE, NORMALIZED_DEEP_COINTYPE, NORMALIZED_DMC_COINTYPE, NORMALIZED_FUD_COINTYPE, NORMALIZED_HAEDAL_COINTYPE, NORMALIZED_HIPPO_COINTYPE, NORMALIZED_IKA_COINTYPE, NORMALIZED_KOBAN_COINTYPE, NORMALIZED_LBTC_COINTYPE, NORMALIZED_NS_COINTYPE, NORMALIZED_SEND_COINTYPE, NORMALIZED_SEND_POINTS_S1_COINTYPE, NORMALIZED_SEND_POINTS_S2_COINTYPE, NORMALIZED_SOL_COINTYPE, NORMALIZED_SUI_COINTYPE, NORMALIZED_UP_COINTYPE, NORMALIZED_USDB_COINTYPE, NORMALIZED_USDC_COINTYPE, NORMALIZED_USDsui_COINTYPE, NORMALIZED_WAL_COINTYPE, NORMALIZED_WBTC_COINTYPE, NORMALIZED_WETH_COINTYPE, NORMALIZED_XAUm_COINTYPE, NORMALIZED_eEARN_COINTYPE, NORMALIZED_eTHIRD_COINTYPE, NORMALIZED_flSUI_COINTYPE, NORMALIZED_fpSUI_COINTYPE, NORMALIZED_fudSUI_COINTYPE, NORMALIZED_iSUI_COINTYPE, NORMALIZED_jugSUI_COINTYPE, NORMALIZED_kSUI_COINTYPE, NORMALIZED_mSUI_COINTYPE, NORMALIZED_mUSD_COINTYPE, NORMALIZED_oshiSUI_COINTYPE, NORMALIZED_sSUI_COINTYPE, NORMALIZED_sdeUSD_COINTYPE, NORMALIZED_stratSUI_COINTYPE, NORMALIZED_suiETH_COINTYPE, NORMALIZED_suiUSDT_COINTYPE, NORMALIZED_suiUSDe_COINTYPE, NORMALIZED_suiWBTC_COINTYPE, NORMALIZED_trevinSUI_COINTYPE, NORMALIZED_upSUI_COINTYPE, NORMALIZED_wUSDC_COINTYPE, NORMALIZED_wUSDT_COINTYPE, NORMALIZED_xBTC_COINTYPE, NORMALIZED_yapSUI_COINTYPE, TEMPORARY_PYTH_PRICE_FEED_COINTYPES, getCoinMetadataMapPartial, getPrices, isSendPoints, isSteammPoints, } from "@suilend/sui-core";
5
5
  import { phantom } from "../_generated/_framework/reified.js";
6
- import { PACKAGE_ID } from "../_generated/suilend/index.js";
6
+ import { getOriginalId } from "../_generated/_envs/index.js";
7
7
  import { ObligationOwnerCap } from "../_generated/suilend/lending-market/structs.js";
8
8
  import { Obligation } from "../_generated/suilend/obligation/structs.js";
9
9
  import { LENDING_MARKET_ID, SuilendClient, listAllOwnedObjects, } from "../client.js";
@@ -12,7 +12,8 @@ import { chunkedMultiGetSettled } from "../utils/obligation.js";
12
12
  import * as simulate from "../utils/simulate.js";
13
13
  import { WAD } from "./constants.js";
14
14
  import { resolvePythConnection } from "./pyth.js";
15
- import { STRATEGY_TYPE_INFO_MAP, STRATEGY_WRAPPER_PACKAGE_ID_V1, } from "./strategyOwnerCap.js";
15
+ import { getStrategyWrapperNetwork, getSuilendNetwork } from "../network.js";
16
+ import { STRATEGY_TYPE_INFO_MAP } from "./strategyOwnerCap.js";
16
17
  const BITWISE_LENDING_MARKET_ID = "0x2d7a85c0ad7c4d3c9c89a3785e32aa8d83ef3034148f49ce2d7c441bbba227be";
17
18
  const EMBER_LENDING_MARKET_ID = "0x74d92cb095b618f344486f77bcce87fbffc0fe0b46584bb1828bb291a222dda8";
18
19
  const SECURITIZE_LENDING_MARKET_ID = "0x13ec4438ef30dce971edde6e542b82c17a87fc2afeeee4be383b49f66d97a73b";
@@ -485,8 +486,8 @@ const toStrategyOwnerCap = (json) => {
485
486
  obligationId: cap.inner_cap.obligation_id,
486
487
  };
487
488
  };
488
- const OBLIGATION_OWNER_CAP_TYPE = `${PACKAGE_ID}::lending_market::ObligationOwnerCap`;
489
- const STRATEGY_OWNER_CAP_TYPE = `${STRATEGY_WRAPPER_PACKAGE_ID_V1}::strategy_wrapper::StrategyOwnerCap`;
489
+ const obligationOwnerCapStruct = () => `${getOriginalId("suilend")}::lending_market::ObligationOwnerCap`;
490
+ const strategyOwnerCapStruct = () => `${getStrategyWrapperNetwork().typeOriginId}::strategy_wrapper::StrategyOwnerCap`;
490
491
  const capType = (capStructType, lendingMarketType) => normalizeStructTag(`${capStructType}<${lendingMarketType}>`);
491
492
  const lendingMarketTypeOf = (type) => {
492
493
  const [lendingMarketType] = parseStructTag(type).typeParams;
@@ -496,15 +497,17 @@ const lendingMarketTypeOf = (type) => {
496
497
  ? lendingMarketType
497
498
  : normalizeStructTag(lendingMarketType);
498
499
  };
499
- const hasStrategies = (suilendClient) => Object.values(STRATEGY_TYPE_INFO_MAP).some((info) => info.lendingMarketId === suilendClient.lendingMarket.id);
500
+ const hasStrategyWrapper = () => !!getSuilendNetwork().strategyWrapper;
501
+ const hasStrategies = (suilendClient) => hasStrategyWrapper() &&
502
+ Object.values(STRATEGY_TYPE_INFO_MAP).some((info) => info.lendingMarketId === suilendClient.lendingMarket.id);
500
503
  const listOwnedCaps = async (suiGrpcClient, address, includeStrategyOwnerCaps) => {
501
504
  const [strategyObjects, ownerCapObjects] = await Promise.all([
502
505
  includeStrategyOwnerCaps
503
- ? listAllOwnedObjects(suiGrpcClient, address, STRATEGY_OWNER_CAP_TYPE, {
506
+ ? listAllOwnedObjects(suiGrpcClient, address, strategyOwnerCapStruct(), {
504
507
  json: true,
505
508
  })
506
509
  : [],
507
- listAllOwnedObjects(suiGrpcClient, address, OBLIGATION_OWNER_CAP_TYPE, {
510
+ listAllOwnedObjects(suiGrpcClient, address, obligationOwnerCapStruct(), {
508
511
  content: true,
509
512
  }),
510
513
  ]);
@@ -527,12 +530,15 @@ const listOwnedCaps = async (suiGrpcClient, address, includeStrategyOwnerCaps) =
527
530
  };
528
531
  const selectMarketCaps = (owned, suilendClient) => {
529
532
  const lendingMarketType = suilendClient.lendingMarket.$typeArgs[0];
530
- const strategyOwnerCapType = capType(STRATEGY_OWNER_CAP_TYPE, lendingMarketType);
531
- const obligationOwnerCapType = capType(OBLIGATION_OWNER_CAP_TYPE, lendingMarketType);
533
+ const obligationOwnerCapType = capType(obligationOwnerCapStruct(), lendingMarketType);
534
+ const strategyCapStruct = hasStrategies(suilendClient)
535
+ ? strategyOwnerCapStruct()
536
+ : undefined;
537
+ const strategyOwnerCapType = strategyCapStruct && capType(strategyCapStruct, lendingMarketType);
532
538
  return {
533
- strategyOwnerCaps: hasStrategies(suilendClient)
539
+ strategyOwnerCaps: strategyCapStruct
534
540
  ? owned.strategyOwnerCaps
535
- .filter((soc) => capType(STRATEGY_OWNER_CAP_TYPE, soc.lendingMarketType) ===
541
+ .filter((soc) => capType(strategyCapStruct, soc.lendingMarketType) ===
536
542
  strategyOwnerCapType)
537
543
  .map(({ id, strategyType, obligationOwnerCapId, obligationId }) => ({
538
544
  id,
@@ -541,7 +547,7 @@ const selectMarketCaps = (owned, suilendClient) => {
541
547
  obligationId,
542
548
  }))
543
549
  : [],
544
- obligationOwnerCaps: owned.obligationOwnerCaps.filter((ownerCap) => capType(OBLIGATION_OWNER_CAP_TYPE, ownerCap.$typeArgs[0]) ===
550
+ obligationOwnerCaps: owned.obligationOwnerCaps.filter((ownerCap) => capType(obligationOwnerCapStruct(), ownerCap.$typeArgs[0]) ===
545
551
  obligationOwnerCapType),
546
552
  };
547
553
  };
@@ -564,7 +570,7 @@ const parseMarketObligations = (rawObligations, { strategyOwnerCaps, obligationO
564
570
  };
565
571
  };
566
572
  export const fetchOwnedObligations = async (suiGrpcClient, address) => {
567
- const { strategyOwnerCaps, obligationOwnerCaps } = await listOwnedCaps(suiGrpcClient, address, true);
573
+ const { strategyOwnerCaps, obligationOwnerCaps } = await listOwnedCaps(suiGrpcClient, address, hasStrategyWrapper());
568
574
  const lendingMarketTypeByObligationId = new Map();
569
575
  for (const { obligationId, lendingMarketType } of [
570
576
  ...strategyOwnerCaps,
@@ -3,7 +3,7 @@ import { Transaction, TransactionObjectArgument, TransactionObjectInput, Transac
3
3
  import BigNumber from "bignumber.js";
4
4
  import { ParsedObligation, ParsedReserve } from "../parsers";
5
5
  import { RewardsMap, StrategyOwnerCap } from "./types";
6
- export declare const STRATEGY_WRAPPER_PACKAGE_ID_V1 = "0xba97dc73a07638d03d77ad2161484eb21db577edc9cadcd7035fef4b4f2f6fa1";
6
+ export declare const STRATEGY_WRAPPER_PACKAGE_ID_V1: string;
7
7
  export declare enum StrategyType {
8
8
  sSUI_SUI_LOOPING = "1",
9
9
  USDC_sSUI_SUI_LOOPING = "3",
@@ -2,9 +2,11 @@ import { SUI_CLOCK_OBJECT_ID, SUI_SYSTEM_STATE_OBJECT_ID, } from "@mysten/sui/ut
2
2
  import BigNumber from "bignumber.js";
3
3
  import BN from "bn.js";
4
4
  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-core";
5
- import { getStrategyWrapperPackageId, LENDING_MARKET_ID, LENDING_MARKET_TYPE, } from "../client.js";
5
+ import { getStrategyWrapperPackageId } from "../client.js";
6
+ import { SUILEND_MAINNET_NETWORK, getSuilendNetwork } from "../network.js";
6
7
  import { Side } from "./types.js";
7
- export const STRATEGY_WRAPPER_PACKAGE_ID_V1 = "0xba97dc73a07638d03d77ad2161484eb21db577edc9cadcd7035fef4b4f2f6fa1";
8
+ import { cetusInputCoin, cetusTransaction } from "./cetusArguments.js";
9
+ export const STRATEGY_WRAPPER_PACKAGE_ID_V1 = SUILEND_MAINNET_NETWORK.strategyWrapper.typeOriginId;
8
10
  export var StrategyType;
9
11
  (function (StrategyType) {
10
12
  StrategyType["sSUI_SUI_LOOPING"] = "1";
@@ -21,10 +23,18 @@ export var StrategyType;
21
23
  StrategyType["USDsui_sSUI_SUI_LOOPING"] = "9";
22
24
  StrategyType["stratSUI_SUI_LOOPING"] = "2";
23
25
  })(StrategyType || (StrategyType = {}));
26
+ const onMainLendingMarket = (info) => Object.defineProperties(info, {
27
+ lendingMarketId: {
28
+ enumerable: true,
29
+ get: () => getSuilendNetwork().mainLendingMarket.id,
30
+ },
31
+ lendingMarketType: {
32
+ enumerable: true,
33
+ get: () => getSuilendNetwork().mainLendingMarket.type,
34
+ },
35
+ });
24
36
  export const STRATEGY_TYPE_INFO_MAP = {
25
- [StrategyType.sSUI_SUI_LOOPING]: {
26
- lendingMarketId: LENDING_MARKET_ID,
27
- lendingMarketType: LENDING_MARKET_TYPE,
37
+ [StrategyType.sSUI_SUI_LOOPING]: onMainLendingMarket({
28
38
  queryParam: "sSUI-SUI-looping",
29
39
  header: {
30
40
  coinTypes: [NORMALIZED_sSUI_COINTYPE, NORMALIZED_SUI_COINTYPE],
@@ -37,10 +47,8 @@ export const STRATEGY_TYPE_INFO_MAP = {
37
47
  borrowCoinType: NORMALIZED_SUI_COINTYPE,
38
48
  currencyCoinTypes: [NORMALIZED_SUI_COINTYPE, NORMALIZED_sSUI_COINTYPE],
39
49
  defaultCurrencyCoinType: NORMALIZED_SUI_COINTYPE,
40
- },
41
- [StrategyType.USDC_sSUI_SUI_LOOPING]: {
42
- lendingMarketId: LENDING_MARKET_ID,
43
- lendingMarketType: LENDING_MARKET_TYPE,
50
+ }),
51
+ [StrategyType.USDC_sSUI_SUI_LOOPING]: onMainLendingMarket({
44
52
  queryParam: "USDC-sSUI-SUI-looping",
45
53
  header: {
46
54
  coinTypes: [NORMALIZED_USDC_COINTYPE],
@@ -53,10 +61,8 @@ export const STRATEGY_TYPE_INFO_MAP = {
53
61
  borrowCoinType: NORMALIZED_SUI_COINTYPE,
54
62
  currencyCoinTypes: [NORMALIZED_USDC_COINTYPE],
55
63
  defaultCurrencyCoinType: NORMALIZED_USDC_COINTYPE,
56
- },
57
- [StrategyType.USDsui_USDC_LOOPING]: {
58
- lendingMarketId: LENDING_MARKET_ID,
59
- lendingMarketType: LENDING_MARKET_TYPE,
64
+ }),
65
+ [StrategyType.USDsui_USDC_LOOPING]: onMainLendingMarket({
60
66
  queryParam: "USDsui-USDC-looping",
61
67
  header: {
62
68
  coinTypes: [NORMALIZED_USDsui_COINTYPE, NORMALIZED_USDC_COINTYPE],
@@ -69,7 +75,7 @@ export const STRATEGY_TYPE_INFO_MAP = {
69
75
  borrowCoinType: NORMALIZED_USDC_COINTYPE,
70
76
  currencyCoinTypes: [NORMALIZED_USDsui_COINTYPE, NORMALIZED_USDC_COINTYPE],
71
77
  defaultCurrencyCoinType: NORMALIZED_USDsui_COINTYPE,
72
- },
78
+ }),
73
79
  [StrategyType.eEARN_USDC_LOOPING]: {
74
80
  lendingMarketId: "0x74d92cb095b618f344486f77bcce87fbffc0fe0b46584bb1828bb291a222dda8",
75
81
  lendingMarketType: "0x423f05ea163ae1bc5c03d75ef70d3e5d887455084118e46c4f76878530a03619::ember_market::EMBER_MARKET",
@@ -86,9 +92,7 @@ export const STRATEGY_TYPE_INFO_MAP = {
86
92
  currencyCoinTypes: [NORMALIZED_eEARN_COINTYPE, NORMALIZED_USDC_COINTYPE],
87
93
  defaultCurrencyCoinType: NORMALIZED_eEARN_COINTYPE,
88
94
  },
89
- [StrategyType.AUSD_sSUI_SUI_LOOPING]: {
90
- lendingMarketId: LENDING_MARKET_ID,
91
- lendingMarketType: LENDING_MARKET_TYPE,
95
+ [StrategyType.AUSD_sSUI_SUI_LOOPING]: onMainLendingMarket({
92
96
  queryParam: "AUSD-sSUI-SUI-looping",
93
97
  header: {
94
98
  coinTypes: [NORMALIZED_AUSD_COINTYPE],
@@ -101,10 +105,8 @@ export const STRATEGY_TYPE_INFO_MAP = {
101
105
  borrowCoinType: NORMALIZED_SUI_COINTYPE,
102
106
  currencyCoinTypes: [NORMALIZED_AUSD_COINTYPE],
103
107
  defaultCurrencyCoinType: NORMALIZED_AUSD_COINTYPE,
104
- },
105
- [StrategyType.xBTC_sSUI_SUI_LOOPING]: {
106
- lendingMarketId: LENDING_MARKET_ID,
107
- lendingMarketType: LENDING_MARKET_TYPE,
108
+ }),
109
+ [StrategyType.xBTC_sSUI_SUI_LOOPING]: onMainLendingMarket({
108
110
  queryParam: "xBTC-sSUI-SUI-looping",
109
111
  header: {
110
112
  coinTypes: [NORMALIZED_xBTC_COINTYPE],
@@ -117,10 +119,8 @@ export const STRATEGY_TYPE_INFO_MAP = {
117
119
  borrowCoinType: NORMALIZED_SUI_COINTYPE,
118
120
  currencyCoinTypes: [NORMALIZED_xBTC_COINTYPE],
119
121
  defaultCurrencyCoinType: NORMALIZED_xBTC_COINTYPE,
120
- },
121
- [StrategyType.xBTC_suiWBTC_LOOPING]: {
122
- lendingMarketId: LENDING_MARKET_ID,
123
- lendingMarketType: LENDING_MARKET_TYPE,
122
+ }),
123
+ [StrategyType.xBTC_suiWBTC_LOOPING]: onMainLendingMarket({
124
124
  queryParam: "xBTC-suiWBTC-looping",
125
125
  header: {
126
126
  coinTypes: [NORMALIZED_xBTC_COINTYPE, NORMALIZED_suiWBTC_COINTYPE],
@@ -133,10 +133,8 @@ export const STRATEGY_TYPE_INFO_MAP = {
133
133
  borrowCoinType: NORMALIZED_suiWBTC_COINTYPE,
134
134
  currencyCoinTypes: [NORMALIZED_xBTC_COINTYPE, NORMALIZED_suiWBTC_COINTYPE],
135
135
  defaultCurrencyCoinType: NORMALIZED_xBTC_COINTYPE,
136
- },
137
- [StrategyType.suiUSDT_sSUI_SUI_LOOPING]: {
138
- lendingMarketId: LENDING_MARKET_ID,
139
- lendingMarketType: LENDING_MARKET_TYPE,
136
+ }),
137
+ [StrategyType.suiUSDT_sSUI_SUI_LOOPING]: onMainLendingMarket({
140
138
  queryParam: "suiUSDT-sSUI-SUI-looping",
141
139
  header: {
142
140
  coinTypes: [NORMALIZED_suiUSDT_COINTYPE],
@@ -149,10 +147,8 @@ export const STRATEGY_TYPE_INFO_MAP = {
149
147
  borrowCoinType: NORMALIZED_SUI_COINTYPE,
150
148
  currencyCoinTypes: [NORMALIZED_suiUSDT_COINTYPE],
151
149
  defaultCurrencyCoinType: NORMALIZED_suiUSDT_COINTYPE,
152
- },
153
- [StrategyType.AUSD_USDC_LOOPING]: {
154
- lendingMarketId: LENDING_MARKET_ID,
155
- lendingMarketType: LENDING_MARKET_TYPE,
150
+ }),
151
+ [StrategyType.AUSD_USDC_LOOPING]: onMainLendingMarket({
156
152
  queryParam: "AUSD-USDC-looping",
157
153
  header: {
158
154
  coinTypes: [NORMALIZED_AUSD_COINTYPE, NORMALIZED_USDC_COINTYPE],
@@ -165,10 +161,8 @@ export const STRATEGY_TYPE_INFO_MAP = {
165
161
  borrowCoinType: NORMALIZED_USDC_COINTYPE,
166
162
  currencyCoinTypes: [NORMALIZED_AUSD_COINTYPE, NORMALIZED_USDC_COINTYPE],
167
163
  defaultCurrencyCoinType: NORMALIZED_AUSD_COINTYPE,
168
- },
169
- [StrategyType.AUSD_suiUSDT_LOOPING]: {
170
- lendingMarketId: LENDING_MARKET_ID,
171
- lendingMarketType: LENDING_MARKET_TYPE,
164
+ }),
165
+ [StrategyType.AUSD_suiUSDT_LOOPING]: onMainLendingMarket({
172
166
  queryParam: "AUSD-suiUSDT-looping",
173
167
  header: {
174
168
  coinTypes: [NORMALIZED_AUSD_COINTYPE, NORMALIZED_suiUSDT_COINTYPE],
@@ -181,10 +175,8 @@ export const STRATEGY_TYPE_INFO_MAP = {
181
175
  borrowCoinType: NORMALIZED_suiUSDT_COINTYPE,
182
176
  currencyCoinTypes: [NORMALIZED_AUSD_COINTYPE, NORMALIZED_suiUSDT_COINTYPE],
183
177
  defaultCurrencyCoinType: NORMALIZED_AUSD_COINTYPE,
184
- },
185
- [StrategyType.USDC_suiUSDT_LOOPING]: {
186
- lendingMarketId: LENDING_MARKET_ID,
187
- lendingMarketType: LENDING_MARKET_TYPE,
178
+ }),
179
+ [StrategyType.USDC_suiUSDT_LOOPING]: onMainLendingMarket({
188
180
  queryParam: "USDC-suiUSDT-looping",
189
181
  header: {
190
182
  coinTypes: [NORMALIZED_USDC_COINTYPE, NORMALIZED_suiUSDT_COINTYPE],
@@ -197,10 +189,8 @@ export const STRATEGY_TYPE_INFO_MAP = {
197
189
  borrowCoinType: NORMALIZED_suiUSDT_COINTYPE,
198
190
  currencyCoinTypes: [NORMALIZED_USDC_COINTYPE, NORMALIZED_suiUSDT_COINTYPE],
199
191
  defaultCurrencyCoinType: NORMALIZED_USDC_COINTYPE,
200
- },
201
- [StrategyType.USDsui_sSUI_SUI_LOOPING]: {
202
- lendingMarketId: LENDING_MARKET_ID,
203
- lendingMarketType: LENDING_MARKET_TYPE,
192
+ }),
193
+ [StrategyType.USDsui_sSUI_SUI_LOOPING]: onMainLendingMarket({
204
194
  queryParam: "USDsui-sSUI-SUI-looping",
205
195
  header: {
206
196
  coinTypes: [NORMALIZED_USDsui_COINTYPE],
@@ -213,10 +203,8 @@ export const STRATEGY_TYPE_INFO_MAP = {
213
203
  borrowCoinType: NORMALIZED_SUI_COINTYPE,
214
204
  currencyCoinTypes: [NORMALIZED_USDsui_COINTYPE],
215
205
  defaultCurrencyCoinType: NORMALIZED_USDsui_COINTYPE,
216
- },
217
- [StrategyType.stratSUI_SUI_LOOPING]: {
218
- lendingMarketId: LENDING_MARKET_ID,
219
- lendingMarketType: LENDING_MARKET_TYPE,
206
+ }),
207
+ [StrategyType.stratSUI_SUI_LOOPING]: onMainLendingMarket({
220
208
  queryParam: "stratSUI-SUI-looping",
221
209
  header: {
222
210
  coinTypes: [NORMALIZED_stratSUI_COINTYPE, NORMALIZED_SUI_COINTYPE],
@@ -229,7 +217,7 @@ export const STRATEGY_TYPE_INFO_MAP = {
229
217
  borrowCoinType: NORMALIZED_SUI_COINTYPE,
230
218
  currencyCoinTypes: [NORMALIZED_SUI_COINTYPE, NORMALIZED_stratSUI_COINTYPE],
231
219
  defaultCurrencyCoinType: NORMALIZED_SUI_COINTYPE,
232
- },
220
+ }),
233
221
  };
234
222
  const getStrategyLendingMarket = (strategyType) => {
235
223
  const info = STRATEGY_TYPE_INFO_MAP[strategyType];
@@ -398,9 +386,9 @@ depositReserve, strategyOwnerCap, transaction) => {
398
386
  try {
399
387
  coinOut = (await cetusSdk.fixableRouterSwapV3({
400
388
  router: routers,
401
- inputCoin: coinIn,
389
+ inputCoin: cetusInputCoin(coinIn),
402
390
  slippage: 3 / 100,
403
- txb: transaction,
391
+ txb: cetusTransaction(transaction),
404
392
  partner: cetusPartnerId,
405
393
  }));
406
394
  }
package/network.d.ts ADDED
@@ -0,0 +1,27 @@
1
+ import { type EnvConfig } from "./_generated/_envs";
2
+ export type StrategyWrapperNetwork = {
3
+ upgradeCapId: string;
4
+ typeOriginId: string;
5
+ defaultPackageId: string;
6
+ packageIdByMarketVersion: ReadonlyMap<bigint, string>;
7
+ };
8
+ export type SuilendNetwork = {
9
+ name: string;
10
+ env: EnvConfig;
11
+ mainLendingMarket: {
12
+ id: string;
13
+ type: string;
14
+ };
15
+ suilendUpgradeCapId: string;
16
+ latestMarketVersion: bigint;
17
+ publishedAtByMarketVersion: ReadonlyMap<bigint, string>;
18
+ strategyWrapper?: StrategyWrapperNetwork;
19
+ pythStateId: string;
20
+ wormholeStateId: string;
21
+ };
22
+ export declare const SUILEND_MAINNET_NETWORK: SuilendNetwork;
23
+ export declare const getSuilendNetwork: () => SuilendNetwork;
24
+ export declare const isSameSuilendNetwork: (a: SuilendNetwork, b: SuilendNetwork) => boolean;
25
+ export declare function setSuilendNetwork(next: SuilendNetwork): void;
26
+ export declare function getStrategyWrapperNetwork(): StrategyWrapperNetwork;
27
+ export declare function setPublishedAt(publishedAt: string): void;
package/network.js ADDED
@@ -0,0 +1,59 @@
1
+ import { getOriginalId, getPublishedAt, mainnetEnv, setActiveEnv, } from "./_generated/_envs/index.js";
2
+ import { registerEnv } from "./_generated/_framework/env.js";
3
+ const STRATEGY_WRAPPER_PACKAGE_ID_V7 = "0x864b66441e95323c320ee7584592769930a2d236b45d731011ee7a98eb785b35";
4
+ export const SUILEND_MAINNET_NETWORK = Object.freeze({
5
+ name: "mainnet",
6
+ env: mainnetEnv,
7
+ mainLendingMarket: Object.freeze({
8
+ id: "0x84030d26d85eaa7035084a057f2f11f701b7e2e4eda87551becbc7c97505ece1",
9
+ type: "0xf95b06141ed4a174f239417323bde3f209b972f5930d8521ea38a52aff3a6ddf::suilend::MAIN_POOL",
10
+ }),
11
+ suilendUpgradeCapId: "0x3d4ef1859c3ee9fc72858f588b56a09da5466e64f8cc4e90a7b3b909fba8a7ae",
12
+ latestMarketVersion: BigInt(8),
13
+ publishedAtByMarketVersion: new Map([
14
+ [
15
+ BigInt(7),
16
+ "0x59672975e15c58ffc9450f5236b6aa9fa2407d94b8081e634778aa01957d8c6f",
17
+ ],
18
+ ]),
19
+ strategyWrapper: Object.freeze({
20
+ upgradeCapId: "0x486ef016bd357fadf981aba35a6c31df8d4c0c4136b2e78fdda87cb2832f3033",
21
+ typeOriginId: "0xba97dc73a07638d03d77ad2161484eb21db577edc9cadcd7035fef4b4f2f6fa1",
22
+ defaultPackageId: STRATEGY_WRAPPER_PACKAGE_ID_V7,
23
+ packageIdByMarketVersion: new Map([
24
+ [BigInt(7), STRATEGY_WRAPPER_PACKAGE_ID_V7],
25
+ ]),
26
+ }),
27
+ pythStateId: "0x03719fae774ddab3cfcaa53bbc046f0cbe21410019b6280811bf3f9f4b05839d",
28
+ wormholeStateId: "0xdbca52b9fb4f712e25f61f974586d93ac541bcf8389564f0323bb07215168b5c",
29
+ });
30
+ let network = SUILEND_MAINNET_NETWORK;
31
+ let publishedAtOverride;
32
+ export const getSuilendNetwork = () => network;
33
+ export const isSameSuilendNetwork = (a, b) => a === b ||
34
+ (a.name === b.name &&
35
+ a.suilendUpgradeCapId === b.suilendUpgradeCapId &&
36
+ a.strategyWrapper?.upgradeCapId === b.strategyWrapper?.upgradeCapId &&
37
+ getOriginalId("suilend", a.env) === getOriginalId("suilend", b.env) &&
38
+ getPublishedAt("suilend", a.env) === getPublishedAt("suilend", b.env));
39
+ export function setSuilendNetwork(next) {
40
+ if (next.name === SUILEND_MAINNET_NETWORK.name &&
41
+ next.env !== SUILEND_MAINNET_NETWORK.env)
42
+ throw new Error(`setSuilendNetwork: the name "${next.name}" belongs to the generated mainnet env. Give this network another name.`);
43
+ if (publishedAtOverride &&
44
+ !isSameSuilendNetwork(publishedAtOverride.network, next))
45
+ publishedAtOverride = undefined;
46
+ registerEnv(next.name, next.env);
47
+ setActiveEnv(next.name, publishedAtOverride && { suilend: publishedAtOverride.id });
48
+ network = next;
49
+ }
50
+ export function getStrategyWrapperNetwork() {
51
+ const { name, strategyWrapper } = network;
52
+ if (!strategyWrapper)
53
+ throw new Error(`strategy_wrapper is not deployed on the ${name} network.`);
54
+ return strategyWrapper;
55
+ }
56
+ export function setPublishedAt(publishedAt) {
57
+ publishedAtOverride = { network, id: publishedAt };
58
+ setActiveEnv(network.name, { suilend: publishedAt });
59
+ }
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@suilend/sdk","version":"14.2.1-next.gbfd3a97","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/interpolate":"./utils/interpolate.js","./utils/obligation":"./utils/obligation.js","./utils/priceGuard":"./utils/priceGuard.js","./utils/simulate":"./utils/simulate.js","./_generated/_envs":"./_generated/_envs/index.js","./_generated/_envs/mainnet":"./_generated/_envs/mainnet.js","./_generated/_framework/env":"./_generated/_framework/env.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/pyth-2/price-identifier/structs":"./_generated/_dependencies/pyth-2/price-identifier/structs.js","./_generated/_dependencies/std/ascii/structs":"./_generated/_dependencies/std/ascii/structs.js","./_generated/_dependencies/std/option/structs":"./_generated/_dependencies/std/option/structs.js","./_generated/_dependencies/std/type-name/structs":"./_generated/_dependencies/std/type-name/structs.js","./_generated/_dependencies/sui/bag/structs":"./_generated/_dependencies/sui/bag/structs.js","./_generated/_dependencies/sui/balance/structs":"./_generated/_dependencies/sui/balance/structs.js","./_generated/_dependencies/sui/object/structs":"./_generated/_dependencies/sui/object/structs.js","./_generated/_dependencies/sui/object-table/structs":"./_generated/_dependencies/sui/object-table/structs.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"},"types":"./index.d.ts","scripts":{"codegen":"node ./codegen.js","codegen:install":"node ./install-codegen.js","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":{"@cetusprotocol/aggregator-sdk":"1.7.5","@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.3"},"devDependencies":{"@mysten/bcs":"2.1.3","@mysten/sui":"2.37.0","@suilend/sui-core":"2.2.0","@tsconfig/recommended":"1.0.13","@types/bn.js":"5.2.0","@types/lodash":"4.17.27","@types/node":"26.6.5","fast-check":"4.10.2","prettier":"3.9.10","ts-node":"10.9.2","typescript":"6.0.3","vite":"8.3.5","vitest":"5.0.5"},"peerDependencies":{"@mysten/bcs":"^2.1.1","@mysten/sui":">=2.31.3 <3","@suilend/sui-core":"^2.0.1"},"type":"module"}
1
+ {"name":"@suilend/sdk","version":"14.3.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","./network":"./network.js","./strategies":"./strategies.js","./api/events":"./api/events.js","./api":"./api/index.js","./lib/cetusArguments":"./lib/cetusArguments.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/interpolate":"./utils/interpolate.js","./utils/obligation":"./utils/obligation.js","./utils/priceGuard":"./utils/priceGuard.js","./utils/simulate":"./utils/simulate.js","./_generated/_envs":"./_generated/_envs/index.js","./_generated/_envs/mainnet":"./_generated/_envs/mainnet.js","./_generated/_framework/env":"./_generated/_framework/env.js","./_generated/_framework/reified":"./_generated/_framework/reified.js","./_generated/_framework/util":"./_generated/_framework/util.js","./_generated/_framework/vector":"./_generated/_framework/vector.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/pyth-2/price-identifier/structs":"./_generated/_dependencies/pyth-2/price-identifier/structs.js","./_generated/_dependencies/std/ascii/structs":"./_generated/_dependencies/std/ascii/structs.js","./_generated/_dependencies/std/option/structs":"./_generated/_dependencies/std/option/structs.js","./_generated/_dependencies/std/type-name/structs":"./_generated/_dependencies/std/type-name/structs.js","./_generated/_dependencies/sui/bag/structs":"./_generated/_dependencies/sui/bag/structs.js","./_generated/_dependencies/sui/balance/structs":"./_generated/_dependencies/sui/balance/structs.js","./_generated/_dependencies/sui/object/structs":"./_generated/_dependencies/sui/object/structs.js","./_generated/_dependencies/sui/object-table/structs":"./_generated/_dependencies/sui/object-table/structs.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"},"types":"./index.d.ts","scripts":{"codegen":"node ./codegen.js","codegen:install":"node ./install-codegen.js","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":{"@cetusprotocol/aggregator-sdk":"1.7.5","@flowx-finance/sdk":"2.1.0","@pythnetwork/hermes-client":"3.1.0","@pythnetwork/pyth-sui-js":"4.0.0","@suilend/springsui-sdk":"5.0.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.3"},"devDependencies":{"@mysten/bcs":"2.1.3","@mysten/sui":"2.37.0","@suilend/sui-core":"2.3.0","@tsconfig/recommended":"1.0.13","@types/bn.js":"5.2.0","@types/lodash":"4.17.27","@types/node":"26.6.5","fast-check":"4.10.2","prettier":"3.9.10","ts-node":"10.9.2","typescript":"6.0.3","vite":"8.3.5","vitest":"5.0.5"},"peerDependencies":{"@mysten/bcs":"^2.1.1","@mysten/sui":">=2.31.3 <3","@suilend/sui-core":"^2.3.0"},"type":"module"}
package/strategies.d.ts CHANGED
@@ -4,7 +4,7 @@ import { SuiGrpcClient } from "@mysten/sui/grpc";
4
4
  import { Transaction, TransactionArgument, TransactionObjectArgument, TransactionObjectInput } from "@mysten/sui/transactions";
5
5
  import BigNumber from "bignumber.js";
6
6
  import { LstClient } from "@suilend/springsui-sdk";
7
- import { LiquidStakingInfo } from "@suilend/springsui-sdk/_generated/liquid_staking/liquid-staking/structs";
7
+ import { LiquidStakingInfo } from "@suilend/springsui-sdk/_generated/liquid-staking/liquid-staking/structs";
8
8
  import { SuilendClient } from "./client";
9
9
  import { RewardsMap } from "./lib";
10
10
  import { RewardMap } from "./lib/liquidityMining";
package/strategies.js CHANGED
@@ -4,13 +4,14 @@ import { SUI_DECIMALS } from "@mysten/sui/utils";
4
4
  import BigNumber from "bignumber.js";
5
5
  import { BN } from "bn.js";
6
6
  import cloneDeep from "lodash/cloneDeep.js";
7
- import { LstClient, SPRING_SUI_UPGRADE_CAP_ID, getLatestPackageId as getLatestSpringSuiPackageId, } from "@suilend/springsui-sdk";
8
- import { API_URL, MAX_U64, MS_PER_YEAR, NORMALIZED_AUSD_COINTYPE, NORMALIZED_SUI_COINTYPE, NORMALIZED_USDC_COINTYPE, NORMALIZED_sSUI_COINTYPE, NORMALIZED_suiUSDT_COINTYPE, NORMALIZED_suiWBTC_COINTYPE, NORMALIZED_xBTC_COINTYPE, getSpendableCoin, isSui, } from "@suilend/sui-core";
7
+ import { LstClient, getLatestPackageId as getLatestSpringSuiPackageId, getSpringSuiNetwork, } from "@suilend/springsui-sdk";
8
+ import { MAX_U64, MS_PER_YEAR, NORMALIZED_AUSD_COINTYPE, NORMALIZED_SUI_COINTYPE, NORMALIZED_USDC_COINTYPE, NORMALIZED_sSUI_COINTYPE, NORMALIZED_suiUSDT_COINTYPE, NORMALIZED_suiWBTC_COINTYPE, NORMALIZED_xBTC_COINTYPE, assertResponseOk, getApiUrl, getSpendableCoin, isSui, } from "@suilend/sui-core";
9
9
  import { getNetAprPercent } from "./lib/index.js";
10
10
  import { getRewardsMap } from "./lib/liquidityMining.js";
11
11
  import { STRATEGY_TYPE_INFO_MAP, StrategyType, strategyBorrow, strategyClaimRewardsAndMergeCoins, strategyDeposit, strategyWithdraw, } from "./lib/strategyOwnerCap.js";
12
12
  import { MMT_CONTRACT_PACKAGE_ID, MMT_VERSION_OBJECT_ID } from "./mmt.js";
13
13
  import { bisectionMethod, getWeightedBorrowsUsd } from "./utils/index.js";
14
+ import { cetusInputCoin, cetusTransaction } from "./lib/cetusArguments.js";
14
15
  export const STRATEGY_E = 10 ** -7;
15
16
  export const STRATEGY_FLASH_REPAY_MAX_RESIDUAL_USD = 0.1;
16
17
  export const STRATEGY_RATE_LIMITED_ERROR_MESSAGE = "This withdrawal exceeds the lending market's outflow limit for now. Withdraw a smaller amount, or wait and try again.";
@@ -314,14 +315,13 @@ export const fetchStrategyLstMap = async (suiGrpcClient) => {
314
315
  // LSTs that will be/are/have been used as rewards
315
316
  NORMALIZED_sSUI_COINTYPE,
316
317
  ]));
317
- const publishedAt = await getLatestSpringSuiPackageId(suiGrpcClient, SPRING_SUI_UPGRADE_CAP_ID);
318
- const lstInfoUrl = `${API_URL}/springsui/lst-info?${new URLSearchParams({
318
+ const publishedAt = await getLatestSpringSuiPackageId(suiGrpcClient, getSpringSuiNetwork().upgradeCapId);
319
+ const lstInfoUrl = `${getApiUrl()}/springsui/lst-info?${new URLSearchParams({
319
320
  coinTypes: lstCoinTypes.join(","),
320
321
  })}`;
321
322
  const lstInfoRes = await fetch(lstInfoUrl);
323
+ assertResponseOk(lstInfoRes, "LST info request");
322
324
  const lstInfoJson = await lstInfoRes.json();
323
- if (lstInfoRes?.statusCode === 500)
324
- throw new Error("Failed to fetch LST info");
325
325
  const lstInfoMap = Object.fromEntries(Object.entries(lstInfoJson).map(([lstCoinType, lstInfo]) => {
326
326
  return [lstCoinType, lstInfo];
327
327
  }));
@@ -332,10 +332,9 @@ export const fetchStrategyLstMap = async (suiGrpcClient) => {
332
332
  0).div(100);
333
333
  const redeemFeePercent = new BigNumber(lstInfo.liquidStakingInfo.feeConfig.element?.redeemFeeBps.toString() ??
334
334
  0).div(100);
335
- const res = await fetch(`${API_URL}/springsui/historical-rates?coinType=${lstCoinType}&timestamps=${Math.floor(Date.now() / 1000)}`);
335
+ const res = await fetch(`${getApiUrl()}/springsui/historical-rates?coinType=${lstCoinType}&timestamps=${Math.floor(Date.now() / 1000)}`);
336
+ assertResponseOk(res, `Historical LST to SUI exchange rates request for ${lstCoinType}`);
336
337
  const json = await res.json();
337
- if (json?.statusCode === 500)
338
- throw new Error(`Failed to fetch historical LST to SUI exchange rates for ${lstCoinType}`);
339
338
  const suiToLstExchangeRate = !new BigNumber(json[0].value).eq(0)
340
339
  ? new BigNumber(1).div(new BigNumber(json[0].value))
341
340
  : new BigNumber(1);
@@ -888,11 +887,10 @@ lstMap, strategyType, _deposits, _borrowedAmount, deposit, targetExposure) => {
888
887
  // Stats - Global TVL
889
888
  export const fetchStrategyGlobalTvlAmountUsdMap = async () => {
890
889
  try {
891
- const url = `${API_URL}/strategies/tvl`;
890
+ const url = `${getApiUrl()}/strategies/tvl`;
892
891
  const res = await fetch(url);
892
+ assertResponseOk(res, "Strategies TVL request");
893
893
  const json = await res.json();
894
- if (json?.statusCode === 500)
895
- throw new Error("Failed to fetch Strategies TVL");
896
894
  const result = Object.values(StrategyType).reduce((acc, strategyType) => {
897
895
  const entry = json.strategies.find((s) => `${s.strategyType}` === strategyType);
898
896
  const tvlUsd = entry
@@ -1246,7 +1244,7 @@ transaction) => {
1246
1244
  router: routers,
1247
1245
  inputCoin: stepBorrowedCoin,
1248
1246
  slippage: slippagePercent / 100,
1249
- txb: transaction,
1247
+ txb: cetusTransaction(transaction),
1250
1248
  partner: cetusPartnerId,
1251
1249
  }));
1252
1250
  }
@@ -1397,7 +1395,7 @@ dryRunTransaction) => {
1397
1395
  router: routers,
1398
1396
  inputCoin: stepWithdrawnCoin,
1399
1397
  slippage: slippagePercent / 100,
1400
- txb: transaction,
1398
+ txb: cetusTransaction(transaction),
1401
1399
  partner: cetusPartnerId,
1402
1400
  }));
1403
1401
  const txCopy = Transaction.from(transaction);
@@ -1563,7 +1561,7 @@ dryRunTransaction) => {
1563
1561
  router: routers,
1564
1562
  inputCoin: withdrawnRemainingLstCoin,
1565
1563
  slippage: 100 / 100,
1566
- txb: transaction,
1564
+ txb: cetusTransaction(transaction),
1567
1565
  partner: cetusPartnerId,
1568
1566
  }));
1569
1567
  }
@@ -1695,7 +1693,7 @@ dryRunTransaction) => {
1695
1693
  router: routers,
1696
1694
  inputCoin: withdrawnBaseCoin,
1697
1695
  slippage: fullRepaySlippagePercent / 100,
1698
- txb: transaction,
1696
+ txb: cetusTransaction(transaction),
1699
1697
  partner: cetusPartnerId,
1700
1698
  }));
1701
1699
  }
@@ -2065,7 +2063,7 @@ dryRunTransaction) => {
2065
2063
  router: routers,
2066
2064
  inputCoin: stepWithdrawnCoin,
2067
2065
  slippage: slippagePercent / 100,
2068
- txb: transaction,
2066
+ txb: cetusTransaction(transaction),
2069
2067
  partner: cetusPartnerId,
2070
2068
  }));
2071
2069
  }
@@ -2272,9 +2270,9 @@ lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _a
2272
2270
  try {
2273
2271
  baseCoin = (await cetusSdk.fixableRouterSwapV3({
2274
2272
  router: routers,
2275
- inputCoin: otherCoin,
2273
+ inputCoin: cetusInputCoin(otherCoin),
2276
2274
  slippage: slippagePercent / 100,
2277
- txb: transaction,
2275
+ txb: cetusTransaction(transaction),
2278
2276
  partner: cetusPartnerId,
2279
2277
  }));
2280
2278
  }
@@ -2421,7 +2419,7 @@ const swapStrategyWithdrawnCoin = async (cetusSdk, cetusPartnerId, transaction,
2421
2419
  router: routers,
2422
2420
  inputCoin: coin,
2423
2421
  slippage: slippagePercent / 100,
2424
- txb: swapTransaction,
2422
+ txb: cetusTransaction(swapTransaction),
2425
2423
  partner: cetusPartnerId,
2426
2424
  }));
2427
2425
  return {
@@ -2693,7 +2691,7 @@ lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _a
2693
2691
  router: routers,
2694
2692
  inputCoin: withdrawnCoin,
2695
2693
  slippage: slippagePercent / 100,
2696
- txb: transaction,
2694
+ txb: cetusTransaction(transaction),
2697
2695
  partner: cetusPartnerId,
2698
2696
  }));
2699
2697
  }
@@ -2944,7 +2942,7 @@ lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _a
2944
2942
  router: routers,
2945
2943
  inputCoin: withdrawnCoin,
2946
2944
  slippage: slippagePercent / 100,
2947
- txb: transaction,
2945
+ txb: cetusTransaction(transaction),
2948
2946
  partner: cetusPartnerId,
2949
2947
  }));
2950
2948
  }
@@ -3144,7 +3142,7 @@ lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _a
3144
3142
  router: routers,
3145
3143
  inputCoin: flashLoanBorrowedCoin,
3146
3144
  slippage: adjustRepaySlippagePercent / 100,
3147
- txb: transaction,
3145
+ txb: cetusTransaction(transaction),
3148
3146
  partner: cetusPartnerId,
3149
3147
  }));
3150
3148
  }
@@ -3213,9 +3211,9 @@ lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _a
3213
3211
  try {
3214
3212
  flashLoanRepayCoin = (await cetusSdk.fixableRouterSwapV3({
3215
3213
  router: repayRouters,
3216
- inputCoin: flashLoanRepayCoin,
3214
+ inputCoin: cetusInputCoin(flashLoanRepayCoin),
3217
3215
  slippage: repayLegSlippagePercent / 100,
3218
- txb: transaction,
3216
+ txb: cetusTransaction(transaction),
3219
3217
  partner: cetusPartnerId,
3220
3218
  }));
3221
3219
  }
@@ -3365,7 +3363,7 @@ lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _a
3365
3363
  router: depositRouters,
3366
3364
  inputCoin: flashLoanBorrowedCoin,
3367
3365
  slippage: depositLegSlippagePercent / 100,
3368
- txb: transaction,
3366
+ txb: cetusTransaction(transaction),
3369
3367
  partner: cetusPartnerId,
3370
3368
  }));
3371
3369
  }
@@ -3441,9 +3439,9 @@ lstMap, strategyType, suiGrpcClient, suilendClient, cetusSdk, cetusPartnerId, _a
3441
3439
  try {
3442
3440
  flashLoanRepayCoin = (await cetusSdk.fixableRouterSwapV3({
3443
3441
  router: repayRouters,
3444
- inputCoin: flashLoanRepayCoin,
3442
+ inputCoin: cetusInputCoin(flashLoanRepayCoin),
3445
3443
  slippage: repayLegSlippagePercent / 100,
3446
- txb: transaction,
3444
+ txb: cetusTransaction(transaction),
3447
3445
  partner: cetusPartnerId,
3448
3446
  }));
3449
3447
  }
@@ -1,5 +1,6 @@
1
1
  import { getSpendableCoin } from "@suilend/sui-core";
2
2
  import { QuoteProvider } from "./quote.js";
3
+ import { cetusInputCoin, cetusTransaction } from "../lib/cetusArguments.js";
3
4
  const getSwapTransactionWrapper = async (provider, getSwapTransaction) => {
4
5
  console.log(`[getSwapTransactionWrapper] fetching transaction for ${provider} quote`);
5
6
  try {
@@ -20,13 +21,13 @@ export const getSwapTransaction = async (suiGrpcClient, address, quote, slippage
20
21
  }
21
22
  const coinOut = await sdkMap[QuoteProvider.CETUS].routerSwap({
22
23
  router: quote.quote,
23
- inputCoin: coinIn,
24
+ inputCoin: cetusInputCoin(coinIn),
24
25
  slippage: slippagePercent / 100,
25
- txb: transaction,
26
+ txb: cetusTransaction(transaction),
26
27
  partner: partnerIdMap[QuoteProvider.CETUS],
27
28
  });
28
29
  return {
29
- transaction: transaction,
30
+ transaction,
30
31
  coinOut: coinOut,
31
32
  };
32
33
  });
@@ -57,7 +58,7 @@ export const getSwapTransaction = async (suiGrpcClient, address, quote, slippage
57
58
  .commission(new FlowXCommission(partnerIdMap[QuoteProvider.FLOWX], new FlowXCoin(quote.out.coinType), FlowXCommissionType.PERCENTAGE, 0, false))
58
59
  .build();
59
60
  const coinOut = await trade.swap({
60
- coinIn: coinIn,
61
+ coinIn,
61
62
  client: suiGrpcClient,
62
63
  tx: transaction,
63
64
  });
@@ -2,9 +2,8 @@ import { normalizeSuiAddress } from "@mysten/sui/utils";
2
2
  import { BigNumber } from "bignumber.js";
3
3
  import pLimit from "p-limit";
4
4
  import { phantom } from "../_generated/_framework/reified.js";
5
- import { PACKAGE_ID } from "../_generated/suilend/index.js";
5
+ import { getOriginalId } from "../_generated/_envs/index.js";
6
6
  import { Obligation } from "../_generated/suilend/obligation/structs.js";
7
- const NORMALIZED_PACKAGE_ID = normalizeSuiAddress(PACKAGE_ID);
8
7
  export async function fetchAllObligationsForMarketWithHandler(suiGrpcClient, lendingMarketId, lendingMarketType, chunkHandler) {
9
8
  const limit = pLimit(30);
10
9
  const { object: rawLendingMarket } = await suiGrpcClient.getObject({
@@ -150,9 +149,11 @@ export async function getObligationHistoryPage(suiGraphQLClient, obligationId, m
150
149
  return { cursor: null, history: [] };
151
150
  }
152
151
  let formattedEvents = [];
152
+ const packageId = getOriginalId("suilend");
153
+ const normalizedPackageId = normalizeSuiAddress(packageId);
153
154
  for (const txNode of payload.nodes) {
154
- const events = txNode.effects.events.nodes.filter((e) => e.contents?.type.repr.startsWith(`${PACKAGE_ID}::`) ||
155
- e.contents?.type.repr.startsWith(`${NORMALIZED_PACKAGE_ID}::`));
155
+ const events = txNode.effects.events.nodes.filter((e) => e.contents?.type.repr.startsWith(`${packageId}::`) ||
156
+ e.contents?.type.repr.startsWith(`${normalizedPackageId}::`));
156
157
  formattedEvents = formattedEvents.concat(formatEventsToHistory(obligationId, txNode, events));
157
158
  }
158
159
  return {
@@ -1,6 +0,0 @@
1
- export declare const PACKAGE_ID = "0xf95b06141ed4a174f239417323bde3f209b972f5930d8521ea38a52aff3a6ddf";
2
- export declare const PKG_V1 = "0xf95b06141ed4a174f239417323bde3f209b972f5930d8521ea38a52aff3a6ddf";
3
- export declare const PKG_V8 = "0x5b54b47971238403d6ade3c8c2cc75814cb55145a5184af916bb5b12aaf184cb";
4
- export declare const PKG_V10 = "0xe37cc7bb50fd9b6dbd3873df66fa2c554e973697f50ef97707311dc78bd08444";
5
- export declare const PKG_V11 = "0xd2a67633ccb8de063163e25bcfca242929caf5cf1a26c2929dab519ee0b8f331";
6
- export declare function setPublishedAt(publishedAt: string): void;
@@ -1,12 +0,0 @@
1
- import { setActiveEnv } from "../_envs/index.js";
2
- export const PACKAGE_ID = "0xf95b06141ed4a174f239417323bde3f209b972f5930d8521ea38a52aff3a6ddf";
3
- export const PKG_V1 = "0xf95b06141ed4a174f239417323bde3f209b972f5930d8521ea38a52aff3a6ddf";
4
- export const PKG_V8 = "0x5b54b47971238403d6ade3c8c2cc75814cb55145a5184af916bb5b12aaf184cb";
5
- export const PKG_V10 = "0xe37cc7bb50fd9b6dbd3873df66fa2c554e973697f50ef97707311dc78bd08444";
6
- export const PKG_V11 = "0xd2a67633ccb8de063163e25bcfca242929caf5cf1a26c2929dab519ee0b8f331";
7
- // Hand-maintained: sui-client-gen does not emit this file, and a run with its
8
- // clean option would delete it. Generated calls resolve their target through
9
- // getPublishedAt, so the override has to go through setActiveEnv as well.
10
- export function setPublishedAt(publishedAt) {
11
- setActiveEnv("mainnet", { suilend: publishedAt });
12
- }