@t2000/sdk 0.6.0 → 0.6.2

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/dist/index.cjs CHANGED
@@ -426,8 +426,6 @@ async function reportFee(agentAddress, operation, feeAmount, feeRate, txDigest)
426
426
  } catch {
427
427
  }
428
428
  }
429
-
430
- // src/protocols/navi.ts
431
429
  var USDC_TYPE = SUPPORTED_ASSETS.USDC.type;
432
430
  var RATE_DECIMALS = 27;
433
431
  var LTV_DECIMALS = 27;
@@ -497,6 +495,24 @@ async function getUsdcPool() {
497
495
  if (!usdc) throw new T2000Error("PROTOCOL_UNAVAILABLE", "USDC pool not found on NAVI");
498
496
  return usdc;
499
497
  }
498
+ function addOracleUpdate(tx, config, pool) {
499
+ const feed = config.oracle.feeds?.find((f2) => f2.assetId === pool.id);
500
+ if (!feed) {
501
+ throw new T2000Error("PROTOCOL_UNAVAILABLE", `Oracle feed not found for asset ${pool.token?.symbol ?? pool.id}`);
502
+ }
503
+ tx.moveCall({
504
+ target: `${config.oracle.packageId}::oracle_pro::update_single_price_v2`,
505
+ arguments: [
506
+ tx.object(CLOCK),
507
+ tx.object(config.oracle.oracleConfig),
508
+ tx.object(config.oracle.priceOracle),
509
+ tx.object(config.oracle.supraOracleHolder),
510
+ tx.object(feed.pythPriceInfoObject),
511
+ tx.object(config.oracle.switchboardAggregator),
512
+ tx.pure.address(feed.feedId)
513
+ ]
514
+ });
515
+ }
500
516
  function rateToApy(rawRate) {
501
517
  if (!rawRate || rawRate === "0") return 0;
502
518
  return Number(BigInt(rawRate)) / 10 ** RATE_DECIMALS * 100;
@@ -519,7 +535,7 @@ function compoundBalance(rawBalance, currentIndex) {
519
535
  if (!rawBalance || !currentIndex || currentIndex === "0") return 0;
520
536
  const scale = BigInt("1" + "0".repeat(RATE_DECIMALS));
521
537
  const half = scale / 2n;
522
- const result = (rawBalance * scale + half) / BigInt(currentIndex);
538
+ const result = (rawBalance * BigInt(currentIndex) + half) / scale;
523
539
  return Number(result) / 10 ** NAVI_BALANCE_DECIMALS;
524
540
  }
525
541
  async function getUserState(client, address) {
@@ -562,6 +578,9 @@ function mergeCoins(tx, coins) {
562
578
  return primary;
563
579
  }
564
580
  async function buildSaveTx(client, address, amount, options = {}) {
581
+ if (!amount || amount <= 0 || !Number.isFinite(amount)) {
582
+ throw new T2000Error("INVALID_AMOUNT", "Save amount must be a positive number");
583
+ }
565
584
  const rawAmount = Number(usdcToRaw(amount));
566
585
  const [config, pool] = await Promise.all([getConfig(), getUsdcPool()]);
567
586
  const coins = await fetchCoins(client, address, USDC_TYPE);
@@ -602,6 +621,7 @@ async function buildWithdrawTx(client, address, amount) {
602
621
  const rawAmount = Number(usdcToRaw(effectiveAmount));
603
622
  const tx = new transactions.Transaction();
604
623
  tx.setSender(address);
624
+ addOracleUpdate(tx, config, pool);
605
625
  const [balance] = tx.moveCall({
606
626
  target: `${config.package}::incentive_v3::withdraw_v2`,
607
627
  arguments: [
@@ -626,10 +646,14 @@ async function buildWithdrawTx(client, address, amount) {
626
646
  return { tx, effectiveAmount };
627
647
  }
628
648
  async function buildBorrowTx(client, address, amount, options = {}) {
649
+ if (!amount || amount <= 0 || !Number.isFinite(amount)) {
650
+ throw new T2000Error("INVALID_AMOUNT", "Borrow amount must be a positive number");
651
+ }
629
652
  const rawAmount = Number(usdcToRaw(amount));
630
653
  const [config, pool] = await Promise.all([getConfig(), getUsdcPool()]);
631
654
  const tx = new transactions.Transaction();
632
655
  tx.setSender(address);
656
+ addOracleUpdate(tx, config, pool);
633
657
  const [balance] = tx.moveCall({
634
658
  target: `${config.package}::incentive_v3::borrow_v2`,
635
659
  arguments: [
@@ -650,16 +674,23 @@ async function buildBorrowTx(client, address, amount, options = {}) {
650
674
  arguments: [balance],
651
675
  typeArguments: [pool.suiCoinType]
652
676
  });
677
+ if (options.collectFee) {
678
+ addCollectFeeToTx(tx, borrowedCoin, "borrow");
679
+ }
653
680
  tx.transferObjects([borrowedCoin], address);
654
681
  return tx;
655
682
  }
656
683
  async function buildRepayTx(client, address, amount) {
684
+ if (!amount || amount <= 0 || !Number.isFinite(amount)) {
685
+ throw new T2000Error("INVALID_AMOUNT", "Repay amount must be a positive number");
686
+ }
657
687
  const rawAmount = Number(usdcToRaw(amount));
658
688
  const [config, pool] = await Promise.all([getConfig(), getUsdcPool()]);
659
689
  const coins = await fetchCoins(client, address, USDC_TYPE);
660
690
  if (coins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", "No USDC coins to repay with");
661
691
  const tx = new transactions.Transaction();
662
692
  tx.setSender(address);
693
+ addOracleUpdate(tx, config, pool);
663
694
  const coinObj = mergeCoins(tx, coins);
664
695
  tx.moveCall({
665
696
  target: `${config.package}::incentive_v3::entry_repay`,
@@ -1030,7 +1061,7 @@ var ProtocolRegistry = class {
1030
1061
  }
1031
1062
  }
1032
1063
  if (candidates.length === 0) {
1033
- throw new Error(`No lending adapter supports saving ${asset}`);
1064
+ throw new T2000Error("ASSET_NOT_SUPPORTED", `No lending adapter supports saving ${asset}`);
1034
1065
  }
1035
1066
  candidates.sort((a, b) => b.rate.saveApy - a.rate.saveApy);
1036
1067
  return candidates[0];
@@ -1048,7 +1079,7 @@ var ProtocolRegistry = class {
1048
1079
  }
1049
1080
  }
1050
1081
  if (candidates.length === 0) {
1051
- throw new Error(`No lending adapter supports borrowing ${asset}`);
1082
+ throw new T2000Error("ASSET_NOT_SUPPORTED", `No lending adapter supports borrowing ${asset}`);
1052
1083
  }
1053
1084
  candidates.sort((a, b) => a.rate.borrowApy - b.rate.borrowApy);
1054
1085
  return candidates[0];
@@ -1065,7 +1096,7 @@ var ProtocolRegistry = class {
1065
1096
  }
1066
1097
  }
1067
1098
  if (candidates.length === 0) {
1068
- throw new Error(`No swap adapter supports ${from} \u2192 ${to}`);
1099
+ throw new T2000Error("ASSET_NOT_SUPPORTED", `No swap adapter supports ${from} \u2192 ${to}`);
1069
1100
  }
1070
1101
  candidates.sort((a, b) => b.quote.expectedOutput - a.quote.expectedOutput);
1071
1102
  return candidates[0];
@@ -1128,7 +1159,7 @@ var NaviAdapter = class {
1128
1159
  const rates = await getRates(this.client);
1129
1160
  const key = asset.toUpperCase();
1130
1161
  const r = rates[key];
1131
- if (!r) throw new Error(`NAVI does not support ${asset}`);
1162
+ if (!r) throw new T2000Error("ASSET_NOT_SUPPORTED", `NAVI does not support ${asset}`);
1132
1163
  return { asset, saveApy: r.saveApy, borrowApy: r.borrowApy };
1133
1164
  }
1134
1165
  async getPositions(address) {
@@ -2331,7 +2362,10 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
2331
2362
  return { positions };
2332
2363
  }
2333
2364
  async rates() {
2334
- return getRates(this.client);
2365
+ const allRatesResult = await this.registry.allRates("USDC");
2366
+ if (allRatesResult.length === 0) return { USDC: { saveApy: 0, borrowApy: 0 } };
2367
+ const best = allRatesResult.reduce((a, b) => b.rates.saveApy > a.rates.saveApy ? b : a);
2368
+ return { USDC: { saveApy: best.rates.saveApy, borrowApy: best.rates.borrowApy } };
2335
2369
  }
2336
2370
  async allRates(asset = "USDC") {
2337
2371
  return this.registry.allRates(asset);