@t2000/sdk 0.6.0 → 0.7.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.
@@ -1,3 +1,4 @@
1
- export { A as AdapterCapability, l as AdapterPositions, m as AdapterTxResult, C as CetusAdapter, o as HealthInfo, L as LendingAdapter, h as LendingRates, N as NaviAdapter, q as ProtocolRegistry, r as SuilendAdapter, b as SwapAdapter, s as SwapQuote } from '../index-DMDq8uxe.cjs';
1
+ export { A as AdapterCapability, k as AdapterPositions, l as AdapterTxResult, C as CetusAdapter, n as HealthInfo, L as LendingAdapter, h as LendingRates, N as NaviAdapter, p as ProtocolDescriptor, q as ProtocolRegistry, s as SuilendAdapter, b as SwapAdapter, t as SwapQuote, u as allDescriptors, v as cetusDescriptor, y as naviDescriptor, J as sentinelDescriptor, Q as suilendDescriptor } from '../index-rT0oHn8M.cjs';
2
2
  import '@mysten/sui/transactions';
3
3
  import '@mysten/sui/jsonRpc';
4
+ import '@mysten/sui/keypairs/ed25519';
@@ -1,3 +1,4 @@
1
- export { A as AdapterCapability, l as AdapterPositions, m as AdapterTxResult, C as CetusAdapter, o as HealthInfo, L as LendingAdapter, h as LendingRates, N as NaviAdapter, q as ProtocolRegistry, r as SuilendAdapter, b as SwapAdapter, s as SwapQuote } from '../index-DMDq8uxe.js';
1
+ export { A as AdapterCapability, k as AdapterPositions, l as AdapterTxResult, C as CetusAdapter, n as HealthInfo, L as LendingAdapter, h as LendingRates, N as NaviAdapter, p as ProtocolDescriptor, q as ProtocolRegistry, s as SuilendAdapter, b as SwapAdapter, t as SwapQuote, u as allDescriptors, v as cetusDescriptor, y as naviDescriptor, J as sentinelDescriptor, Q as suilendDescriptor } from '../index-rT0oHn8M.js';
2
2
  import '@mysten/sui/transactions';
3
3
  import '@mysten/sui/jsonRpc';
4
+ import '@mysten/sui/keypairs/ed25519';
@@ -3,6 +3,28 @@ import { bcs } from '@mysten/sui/bcs';
3
3
  import { AggregatorClient, Env } from '@cetusprotocol/aggregator-sdk';
4
4
  import { normalizeStructTag } from '@mysten/sui/utils';
5
5
 
6
+ // src/errors.ts
7
+ var T2000Error = class extends Error {
8
+ code;
9
+ data;
10
+ retryable;
11
+ constructor(code, message, data, retryable = false) {
12
+ super(message);
13
+ this.name = "T2000Error";
14
+ this.code = code;
15
+ this.data = data;
16
+ this.retryable = retryable;
17
+ }
18
+ toJSON() {
19
+ return {
20
+ error: this.code,
21
+ message: this.message,
22
+ ...this.data && { data: this.data },
23
+ retryable: this.retryable
24
+ };
25
+ }
26
+ };
27
+
6
28
  // src/adapters/registry.ts
7
29
  var ProtocolRegistry = class {
8
30
  lending = /* @__PURE__ */ new Map();
@@ -25,7 +47,7 @@ var ProtocolRegistry = class {
25
47
  }
26
48
  }
27
49
  if (candidates.length === 0) {
28
- throw new Error(`No lending adapter supports saving ${asset}`);
50
+ throw new T2000Error("ASSET_NOT_SUPPORTED", `No lending adapter supports saving ${asset}`);
29
51
  }
30
52
  candidates.sort((a, b) => b.rate.saveApy - a.rate.saveApy);
31
53
  return candidates[0];
@@ -43,7 +65,7 @@ var ProtocolRegistry = class {
43
65
  }
44
66
  }
45
67
  if (candidates.length === 0) {
46
- throw new Error(`No lending adapter supports borrowing ${asset}`);
68
+ throw new T2000Error("ASSET_NOT_SUPPORTED", `No lending adapter supports borrowing ${asset}`);
47
69
  }
48
70
  candidates.sort((a, b) => a.rate.borrowApy - b.rate.borrowApy);
49
71
  return candidates[0];
@@ -60,7 +82,7 @@ var ProtocolRegistry = class {
60
82
  }
61
83
  }
62
84
  if (candidates.length === 0) {
63
- throw new Error(`No swap adapter supports ${from} \u2192 ${to}`);
85
+ throw new T2000Error("ASSET_NOT_SUPPORTED", `No swap adapter supports ${from} \u2192 ${to}`);
64
86
  }
65
87
  candidates.sort((a, b) => b.quote.expectedOutput - a.quote.expectedOutput);
66
88
  return candidates[0];
@@ -126,28 +148,9 @@ var T2000_CONFIG_ID = process.env.T2000_CONFIG_ID ?? "0x408add9aa9322f93cfd87523
126
148
  var T2000_TREASURY_ID = process.env.T2000_TREASURY_ID ?? "0x3bb501b8300125dca59019247941a42af6b292a150ce3cfcce9449456be2ec91";
127
149
  process.env.T2000_API_URL ?? "https://api.t2000.ai";
128
150
  var CETUS_USDC_SUI_POOL = "0x51e883ba7c0b566a26cbc8a94cd33eb0abd418a77cc1e60ad22fd9b1f29cd2ab";
129
-
130
- // src/errors.ts
131
- var T2000Error = class extends Error {
132
- code;
133
- data;
134
- retryable;
135
- constructor(code, message, data, retryable = false) {
136
- super(message);
137
- this.name = "T2000Error";
138
- this.code = code;
139
- this.data = data;
140
- this.retryable = retryable;
141
- }
142
- toJSON() {
143
- return {
144
- error: this.code,
145
- message: this.message,
146
- ...this.data && { data: this.data },
147
- retryable: this.retryable
148
- };
149
- }
150
- };
151
+ var CETUS_PACKAGE = "0x1eabed72c53feb3805120a081dc15963c204dc8d091542592abaf7a35689b2fb";
152
+ var SENTINEL = {
153
+ PACKAGE: "0x88b83f36dafcd5f6dcdcf1d2cb5889b03f61264ab3cee9cae35db7aa940a21b7"};
151
154
 
152
155
  // src/utils/format.ts
153
156
  function usdcToRaw(amount) {
@@ -250,6 +253,24 @@ async function getUsdcPool() {
250
253
  if (!usdc) throw new T2000Error("PROTOCOL_UNAVAILABLE", "USDC pool not found on NAVI");
251
254
  return usdc;
252
255
  }
256
+ function addOracleUpdate(tx, config, pool) {
257
+ const feed = config.oracle.feeds?.find((f2) => f2.assetId === pool.id);
258
+ if (!feed) {
259
+ throw new T2000Error("PROTOCOL_UNAVAILABLE", `Oracle feed not found for asset ${pool.token?.symbol ?? pool.id}`);
260
+ }
261
+ tx.moveCall({
262
+ target: `${config.oracle.packageId}::oracle_pro::update_single_price_v2`,
263
+ arguments: [
264
+ tx.object(CLOCK),
265
+ tx.object(config.oracle.oracleConfig),
266
+ tx.object(config.oracle.priceOracle),
267
+ tx.object(config.oracle.supraOracleHolder),
268
+ tx.object(feed.pythPriceInfoObject),
269
+ tx.object(config.oracle.switchboardAggregator),
270
+ tx.pure.address(feed.feedId)
271
+ ]
272
+ });
273
+ }
253
274
  function rateToApy(rawRate) {
254
275
  if (!rawRate || rawRate === "0") return 0;
255
276
  return Number(BigInt(rawRate)) / 10 ** RATE_DECIMALS * 100;
@@ -272,7 +293,7 @@ function compoundBalance(rawBalance, currentIndex) {
272
293
  if (!rawBalance || !currentIndex || currentIndex === "0") return 0;
273
294
  const scale = BigInt("1" + "0".repeat(RATE_DECIMALS));
274
295
  const half = scale / 2n;
275
- const result = (rawBalance * scale + half) / BigInt(currentIndex);
296
+ const result = (rawBalance * BigInt(currentIndex) + half) / scale;
276
297
  return Number(result) / 10 ** NAVI_BALANCE_DECIMALS;
277
298
  }
278
299
  async function getUserState(client, address) {
@@ -315,6 +336,9 @@ function mergeCoins(tx, coins) {
315
336
  return primary;
316
337
  }
317
338
  async function buildSaveTx(client, address, amount, options = {}) {
339
+ if (!amount || amount <= 0 || !Number.isFinite(amount)) {
340
+ throw new T2000Error("INVALID_AMOUNT", "Save amount must be a positive number");
341
+ }
318
342
  const rawAmount = Number(usdcToRaw(amount));
319
343
  const [config, pool] = await Promise.all([getConfig(), getUsdcPool()]);
320
344
  const coins = await fetchCoins(client, address, USDC_TYPE);
@@ -355,6 +379,7 @@ async function buildWithdrawTx(client, address, amount) {
355
379
  const rawAmount = Number(usdcToRaw(effectiveAmount));
356
380
  const tx = new Transaction();
357
381
  tx.setSender(address);
382
+ addOracleUpdate(tx, config, pool);
358
383
  const [balance] = tx.moveCall({
359
384
  target: `${config.package}::incentive_v3::withdraw_v2`,
360
385
  arguments: [
@@ -379,10 +404,14 @@ async function buildWithdrawTx(client, address, amount) {
379
404
  return { tx, effectiveAmount };
380
405
  }
381
406
  async function buildBorrowTx(client, address, amount, options = {}) {
407
+ if (!amount || amount <= 0 || !Number.isFinite(amount)) {
408
+ throw new T2000Error("INVALID_AMOUNT", "Borrow amount must be a positive number");
409
+ }
382
410
  const rawAmount = Number(usdcToRaw(amount));
383
411
  const [config, pool] = await Promise.all([getConfig(), getUsdcPool()]);
384
412
  const tx = new Transaction();
385
413
  tx.setSender(address);
414
+ addOracleUpdate(tx, config, pool);
386
415
  const [balance] = tx.moveCall({
387
416
  target: `${config.package}::incentive_v3::borrow_v2`,
388
417
  arguments: [
@@ -403,16 +432,23 @@ async function buildBorrowTx(client, address, amount, options = {}) {
403
432
  arguments: [balance],
404
433
  typeArguments: [pool.suiCoinType]
405
434
  });
435
+ if (options.collectFee) {
436
+ addCollectFeeToTx(tx, borrowedCoin, "borrow");
437
+ }
406
438
  tx.transferObjects([borrowedCoin], address);
407
439
  return tx;
408
440
  }
409
441
  async function buildRepayTx(client, address, amount) {
442
+ if (!amount || amount <= 0 || !Number.isFinite(amount)) {
443
+ throw new T2000Error("INVALID_AMOUNT", "Repay amount must be a positive number");
444
+ }
410
445
  const rawAmount = Number(usdcToRaw(amount));
411
446
  const [config, pool] = await Promise.all([getConfig(), getUsdcPool()]);
412
447
  const coins = await fetchCoins(client, address, USDC_TYPE);
413
448
  if (coins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", "No USDC coins to repay with");
414
449
  const tx = new Transaction();
415
450
  tx.setSender(address);
451
+ addOracleUpdate(tx, config, pool);
416
452
  const coinObj = mergeCoins(tx, coins);
417
453
  tx.moveCall({
418
454
  target: `${config.package}::incentive_v3::entry_repay`,
@@ -551,6 +587,22 @@ async function maxBorrowAmount(client, addressOrKeypair) {
551
587
  }
552
588
 
553
589
  // src/adapters/navi.ts
590
+ var descriptor = {
591
+ id: "navi",
592
+ name: "NAVI Protocol",
593
+ packages: [],
594
+ dynamicPackageId: true,
595
+ actionMap: {
596
+ "incentive_v3::entry_deposit": "save",
597
+ "incentive_v3::deposit": "save",
598
+ "incentive_v3::withdraw_v2": "withdraw",
599
+ "incentive_v3::entry_withdraw": "withdraw",
600
+ "incentive_v3::borrow_v2": "borrow",
601
+ "incentive_v3::entry_borrow": "borrow",
602
+ "incentive_v3::entry_repay": "repay",
603
+ "incentive_v3::repay": "repay"
604
+ }
605
+ };
554
606
  var NaviAdapter = class {
555
607
  id = "navi";
556
608
  name = "NAVI Protocol";
@@ -569,7 +621,7 @@ var NaviAdapter = class {
569
621
  const rates = await getRates(this.client);
570
622
  const key = asset.toUpperCase();
571
623
  const r = rates[key];
572
- if (!r) throw new Error(`NAVI does not support ${asset}`);
624
+ if (!r) throw new T2000Error("ASSET_NOT_SUPPORTED", `NAVI does not support ${asset}`);
573
625
  return { asset, saveApy: r.saveApy, borrowApy: r.borrowApy };
574
626
  }
575
627
  async getPositions(address) {
@@ -695,6 +747,18 @@ function fallbackQuote(fromAsset, amount, poolPrice) {
695
747
  }
696
748
 
697
749
  // src/adapters/cetus.ts
750
+ var descriptor2 = {
751
+ id: "cetus",
752
+ name: "Cetus DEX",
753
+ packages: [CETUS_PACKAGE],
754
+ actionMap: {
755
+ "router::swap": "swap",
756
+ "router::swap_ab_bc": "swap",
757
+ "router::swap_ab_cb": "swap",
758
+ "router::swap_ba_bc": "swap",
759
+ "router::swap_ba_cb": "swap"
760
+ }
761
+ };
698
762
  var CetusAdapter = class {
699
763
  id = "cetus";
700
764
  name = "Cetus";
@@ -749,6 +813,20 @@ var LENDING_MARKET_TYPE = "0xf95b06141ed4a174f239417323bde3f209b972f5930d8521ea3
749
813
  var SUILEND_PACKAGE = "0xf95b06141ed4a174f239417323bde3f209b972f5930d8521ea38a52aff3a6ddf";
750
814
  var UPGRADE_CAP_ID = "0x3d4ef1859c3ee9fc72858f588b56a09da5466e64f8cc4e90a7b3b909fba8a7ae";
751
815
  var FALLBACK_PUBLISHED_AT = "0xd2a67633ccb8de063163e25bcfca242929caf5cf1a26c2929dab519ee0b8f331";
816
+ var descriptor3 = {
817
+ id: "suilend",
818
+ name: "Suilend",
819
+ packages: [SUILEND_PACKAGE],
820
+ actionMap: {
821
+ "lending_market::deposit_liquidity_and_mint_ctokens": "save",
822
+ "lending_market::deposit_ctokens_into_obligation": "save",
823
+ "lending_market::create_obligation": "save",
824
+ "lending_market::withdraw_ctokens": "withdraw",
825
+ "lending_market::redeem_ctokens_and_withdraw_liquidity": "withdraw",
826
+ "lending_market::borrow": "borrow",
827
+ "lending_market::repay": "repay"
828
+ }
829
+ };
752
830
  function interpolateRate(utilBreakpoints, aprBreakpoints, utilizationPct) {
753
831
  if (utilBreakpoints.length === 0) return 0;
754
832
  if (utilizationPct <= utilBreakpoints[0]) return aprBreakpoints[0];
@@ -1126,7 +1204,24 @@ var SuilendAdapter = class {
1126
1204
  return all;
1127
1205
  }
1128
1206
  };
1207
+ var descriptor4 = {
1208
+ id: "sentinel",
1209
+ name: "Sui Sentinel",
1210
+ packages: [SENTINEL.PACKAGE],
1211
+ actionMap: {
1212
+ "sentinel::request_attack": "sentinel_attack",
1213
+ "sentinel::consume_prompt": "sentinel_settle"
1214
+ }
1215
+ };
1216
+
1217
+ // src/adapters/index.ts
1218
+ var allDescriptors = [
1219
+ descriptor,
1220
+ descriptor3,
1221
+ descriptor2,
1222
+ descriptor4
1223
+ ];
1129
1224
 
1130
- export { CetusAdapter, NaviAdapter, ProtocolRegistry, SuilendAdapter };
1225
+ export { CetusAdapter, NaviAdapter, ProtocolRegistry, SuilendAdapter, allDescriptors, descriptor2 as cetusDescriptor, descriptor as naviDescriptor, descriptor4 as sentinelDescriptor, descriptor3 as suilendDescriptor };
1131
1226
  //# sourceMappingURL=index.js.map
1132
1227
  //# sourceMappingURL=index.js.map