@t2000/sdk 0.9.5 → 0.9.7

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.js CHANGED
@@ -9,6 +9,7 @@ import { access, mkdir, writeFile, readFile } from 'fs/promises';
9
9
  import { dirname, resolve } from 'path';
10
10
  import { homedir } from 'os';
11
11
  import { bcs } from '@mysten/sui/bcs';
12
+ import { SuiPriceServiceConnection, SuiPythClient } from '@pythnetwork/pyth-sui-js';
12
13
  import { AggregatorClient, Env } from '@cetusprotocol/aggregator-sdk';
13
14
 
14
15
  // src/t2000.ts
@@ -508,6 +509,7 @@ var NAVI_BALANCE_DECIMALS = 9;
508
509
  var CONFIG_API = "https://open-api.naviprotocol.io/api/navi/config?env=prod";
509
510
  var POOLS_API = "https://open-api.naviprotocol.io/api/navi/pools?env=prod";
510
511
  var PACKAGE_API = "https://open-api.naviprotocol.io/api/package";
512
+ var PYTH_HERMES_URL = "https://hermes.pyth.network/";
511
513
  var packageCache = null;
512
514
  function toBigInt(v) {
513
515
  if (typeof v === "bigint") return v;
@@ -602,18 +604,32 @@ function addOracleUpdate(tx, config, pool) {
602
604
  ]
603
605
  });
604
606
  }
605
- function addOracleUpdatesForPositions(tx, config, pools, states, primaryPool) {
606
- const updated = /* @__PURE__ */ new Set();
607
- addOracleUpdate(tx, config, primaryPool);
608
- updated.add(primaryPool.id);
609
- for (const state of states) {
610
- if (updated.has(state.assetId)) continue;
611
- const pool = pools.find((p) => p.id === state.assetId);
612
- if (!pool) continue;
613
- const feed = config.oracle.feeds?.find((f2) => f2.assetId === pool.id);
614
- if (!feed) continue;
607
+ async function refreshStableOracles(tx, client, config, pools) {
608
+ const stableTypes = STABLE_ASSETS.map((a) => SUPPORTED_ASSETS[a].type);
609
+ const stablePools = pools.filter((p) => {
610
+ const ct = p.suiCoinType || p.coinType || "";
611
+ return stableTypes.some((t) => matchesCoinType(ct, t));
612
+ });
613
+ const feeds = (config.oracle.feeds ?? []).filter(
614
+ (f2) => stablePools.some((p) => p.id === f2.assetId)
615
+ );
616
+ if (feeds.length === 0) return;
617
+ const pythFeedIds = feeds.map((f2) => f2.pythPriceFeedId).filter(Boolean);
618
+ if (pythFeedIds.length > 0 && config.oracle.pythStateId && config.oracle.wormholeStateId) {
619
+ try {
620
+ const connection = new SuiPriceServiceConnection(PYTH_HERMES_URL);
621
+ const priceUpdateData = await connection.getPriceFeedsUpdateData(pythFeedIds);
622
+ const pythClient = new SuiPythClient(
623
+ client,
624
+ config.oracle.pythStateId,
625
+ config.oracle.wormholeStateId
626
+ );
627
+ await pythClient.updatePriceFeeds(tx, priceUpdateData, pythFeedIds);
628
+ } catch {
629
+ }
630
+ }
631
+ for (const pool of stablePools) {
615
632
  addOracleUpdate(tx, config, pool);
616
- updated.add(pool.id);
617
633
  }
618
634
  }
619
635
  function rateToApy(rawRate) {
@@ -641,7 +657,7 @@ function compoundBalance(rawBalance, currentIndex) {
641
657
  const result = (rawBalance * BigInt(currentIndex) + half) / scale;
642
658
  return Number(result) / 10 ** NAVI_BALANCE_DECIMALS;
643
659
  }
644
- async function getUserState(client, address, includeZero = false) {
660
+ async function getUserState(client, address) {
645
661
  const config = await getConfig();
646
662
  const tx = new Transaction();
647
663
  tx.moveCall({
@@ -659,7 +675,6 @@ async function getUserState(client, address, includeZero = false) {
659
675
  supplyBalance: toBigInt(s.supply_balance),
660
676
  borrowBalance: toBigInt(s.borrow_balance)
661
677
  }));
662
- if (includeZero) return mapped;
663
678
  return mapped.filter((s) => s.supplyBalance !== 0n || s.borrowBalance !== 0n);
664
679
  }
665
680
  async function fetchCoins(client, owner, coinType) {
@@ -717,20 +732,20 @@ async function buildSaveTx(client, address, amount, options = {}) {
717
732
  async function buildWithdrawTx(client, address, amount, options = {}) {
718
733
  const asset = options.asset ?? "USDC";
719
734
  const assetInfo = SUPPORTED_ASSETS[asset];
720
- const [config, pool, pools, allStates] = await Promise.all([
735
+ const [config, pool, pools, states] = await Promise.all([
721
736
  getConfig(),
722
737
  getPool(asset),
723
738
  getPools(),
724
- getUserState(client, address, true)
739
+ getUserState(client, address)
725
740
  ]);
726
- const assetState = allStates.find((s) => s.assetId === pool.id);
741
+ const assetState = states.find((s) => s.assetId === pool.id);
727
742
  const deposited = assetState ? compoundBalance(assetState.supplyBalance, pool.currentSupplyIndex) : 0;
728
743
  const effectiveAmount = Math.min(amount, Math.max(0, deposited - WITHDRAW_DUST_BUFFER));
729
744
  if (effectiveAmount <= 0) throw new T2000Error("NO_COLLATERAL", `Nothing to withdraw for ${assetInfo.displayName} on NAVI`);
730
745
  const rawAmount = Number(stableToRaw(effectiveAmount, assetInfo.decimals));
731
746
  const tx = new Transaction();
732
747
  tx.setSender(address);
733
- addOracleUpdatesForPositions(tx, config, pools, allStates, pool);
748
+ await refreshStableOracles(tx, client, config, pools);
734
749
  const [balance] = tx.moveCall({
735
750
  target: `${config.package}::incentive_v3::withdraw_v2`,
736
751
  arguments: [
@@ -757,18 +772,18 @@ async function buildWithdrawTx(client, address, amount, options = {}) {
757
772
  async function addWithdrawToTx(tx, client, address, amount, options = {}) {
758
773
  const asset = options.asset ?? "USDC";
759
774
  const assetInfo = SUPPORTED_ASSETS[asset];
760
- const [config, pool, pools, allStates] = await Promise.all([
775
+ const [config, pool, pools, states] = await Promise.all([
761
776
  getConfig(),
762
777
  getPool(asset),
763
778
  getPools(),
764
- getUserState(client, address, true)
779
+ getUserState(client, address)
765
780
  ]);
766
- const assetState = allStates.find((s) => s.assetId === pool.id);
781
+ const assetState = states.find((s) => s.assetId === pool.id);
767
782
  const deposited = assetState ? compoundBalance(assetState.supplyBalance, pool.currentSupplyIndex) : 0;
768
783
  const effectiveAmount = Math.min(amount, Math.max(0, deposited - WITHDRAW_DUST_BUFFER));
769
784
  if (effectiveAmount <= 0) throw new T2000Error("NO_COLLATERAL", `Nothing to withdraw for ${assetInfo.displayName} on NAVI`);
770
785
  const rawAmount = Number(stableToRaw(effectiveAmount, assetInfo.decimals));
771
- addOracleUpdatesForPositions(tx, config, pools, allStates, pool);
786
+ await refreshStableOracles(tx, client, config, pools);
772
787
  const [balance] = tx.moveCall({
773
788
  target: `${config.package}::incentive_v3::withdraw_v2`,
774
789
  arguments: [
@@ -849,15 +864,14 @@ async function buildBorrowTx(client, address, amount, options = {}) {
849
864
  const asset = options.asset ?? "USDC";
850
865
  const assetInfo = SUPPORTED_ASSETS[asset];
851
866
  const rawAmount = Number(stableToRaw(amount, assetInfo.decimals));
852
- const [config, pool, pools, allStates] = await Promise.all([
867
+ const [config, pool, pools] = await Promise.all([
853
868
  getConfig(),
854
869
  getPool(asset),
855
- getPools(),
856
- getUserState(client, address, true)
870
+ getPools()
857
871
  ]);
858
872
  const tx = new Transaction();
859
873
  tx.setSender(address);
860
- addOracleUpdatesForPositions(tx, config, pools, allStates, pool);
874
+ await refreshStableOracles(tx, client, config, pools);
861
875
  const [balance] = tx.moveCall({
862
876
  target: `${config.package}::incentive_v3::borrow_v2`,
863
877
  arguments: [