@t2000/sdk 0.9.8 → 0.10.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/dist/index.js CHANGED
@@ -9,7 +9,6 @@ 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';
13
12
  import { AggregatorClient, Env } from '@cetusprotocol/aggregator-sdk';
14
13
 
15
14
  // src/t2000.ts
@@ -126,7 +125,7 @@ function mapMoveAbortCode(code) {
126
125
  10: "Already at current version",
127
126
  // NAVI Protocol abort codes
128
127
  1502: "Oracle price is stale \u2014 try again in a moment",
129
- 1503: "Oracle validation failed during withdrawal \u2014 try again in a moment",
128
+ 1503: 'Withdrawal amount is invalid (zero or dust) \u2014 try a specific amount instead of "all"',
130
129
  1600: "Health factor too low \u2014 withdrawal would risk liquidation",
131
130
  1605: "Asset borrowing is disabled or at capacity on this protocol",
132
131
  // Cetus DEX abort codes
@@ -509,7 +508,6 @@ var NAVI_BALANCE_DECIMALS = 9;
509
508
  var CONFIG_API = "https://open-api.naviprotocol.io/api/navi/config?env=prod";
510
509
  var POOLS_API = "https://open-api.naviprotocol.io/api/navi/pools?env=prod";
511
510
  var PACKAGE_API = "https://open-api.naviprotocol.io/api/package";
512
- var PYTH_HERMES_URL = "https://hermes.pyth.network/";
513
511
  var packageCache = null;
514
512
  function toBigInt(v) {
515
513
  if (typeof v === "bigint") return v;
@@ -604,31 +602,12 @@ function addOracleUpdate(tx, config, pool) {
604
602
  ]
605
603
  });
606
604
  }
607
- async function refreshStableOracles(tx, client, config, pools) {
605
+ function refreshStableOracles(tx, config, pools) {
608
606
  const stableTypes = STABLE_ASSETS.map((a) => SUPPORTED_ASSETS[a].type);
609
607
  const stablePools = pools.filter((p) => {
610
608
  const ct = p.suiCoinType || p.coinType || "";
611
609
  return stableTypes.some((t) => matchesCoinType(ct, t));
612
610
  });
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 (err) {
629
- console.error("[t2000] Pyth oracle push failed, falling back to cached prices:", err.message ?? err);
630
- }
631
- }
632
611
  for (const pool of stablePools) {
633
612
  addOracleUpdate(tx, config, pool);
634
613
  }
@@ -745,12 +724,11 @@ async function buildWithdrawTx(client, address, amount, options = {}) {
745
724
  if (effectiveAmount <= 0) throw new T2000Error("NO_COLLATERAL", `Nothing to withdraw for ${assetInfo.displayName} on NAVI`);
746
725
  const rawAmount = Number(stableToRaw(effectiveAmount, assetInfo.decimals));
747
726
  if (rawAmount <= 0) {
748
- throw new T2000Error("INVALID_AMOUNT", `Withdrawal amount too small to represent (effective=${effectiveAmount}, raw=${rawAmount}, decimals=${assetInfo.decimals})`);
727
+ throw new T2000Error("INVALID_AMOUNT", `Withdrawal amount rounds to zero \u2014 balance is dust`);
749
728
  }
750
- console.error(`[t2000] withdraw: asset=${asset} poolId=${pool.id} amount=${amount} deposited=${deposited} effective=${effectiveAmount} raw=${rawAmount} supplyBal=${assetState?.supplyBalance} index=${pool.currentSupplyIndex}`);
751
729
  const tx = new Transaction();
752
730
  tx.setSender(address);
753
- await refreshStableOracles(tx, client, config, pools);
731
+ refreshStableOracles(tx, config, pools);
754
732
  const [balance] = tx.moveCall({
755
733
  target: `${config.package}::incentive_v3::withdraw_v2`,
756
734
  arguments: [
@@ -789,10 +767,13 @@ async function addWithdrawToTx(tx, client, address, amount, options = {}) {
789
767
  if (effectiveAmount <= 0) throw new T2000Error("NO_COLLATERAL", `Nothing to withdraw for ${assetInfo.displayName} on NAVI`);
790
768
  const rawAmount = Number(stableToRaw(effectiveAmount, assetInfo.decimals));
791
769
  if (rawAmount <= 0) {
792
- throw new T2000Error("INVALID_AMOUNT", `Withdrawal amount too small to represent (effective=${effectiveAmount}, raw=${rawAmount}, decimals=${assetInfo.decimals})`);
770
+ const [coin2] = tx.moveCall({
771
+ target: "0x2::coin::zero",
772
+ typeArguments: [pool.suiCoinType]
773
+ });
774
+ return { coin: coin2, effectiveAmount: 0 };
793
775
  }
794
- console.error(`[t2000] withdraw: asset=${asset} poolId=${pool.id} amount=${amount} deposited=${deposited} effective=${effectiveAmount} raw=${rawAmount} supplyBal=${assetState?.supplyBalance} index=${pool.currentSupplyIndex}`);
795
- await refreshStableOracles(tx, client, config, pools);
776
+ refreshStableOracles(tx, config, pools);
796
777
  const [balance] = tx.moveCall({
797
778
  target: `${config.package}::incentive_v3::withdraw_v2`,
798
779
  arguments: [
@@ -880,7 +861,7 @@ async function buildBorrowTx(client, address, amount, options = {}) {
880
861
  ]);
881
862
  const tx = new Transaction();
882
863
  tx.setSender(address);
883
- await refreshStableOracles(tx, client, config, pools);
864
+ refreshStableOracles(tx, config, pools);
884
865
  const [balance] = tx.moveCall({
885
866
  target: `${config.package}::incentive_v3::borrow_v2`,
886
867
  arguments: [
@@ -2883,7 +2864,7 @@ var T2000 = class _T2000 extends EventEmitter {
2883
2864
  const withdrawable = [];
2884
2865
  for (const pos of allPositions) {
2885
2866
  for (const supply of pos.positions.supplies) {
2886
- if (supply.amount > 1e-3) {
2867
+ if (supply.amount > 0.01) {
2887
2868
  withdrawable.push({ protocolId: pos.protocolId, asset: supply.asset, amount: supply.amount });
2888
2869
  }
2889
2870
  }
@@ -2896,8 +2877,9 @@ var T2000 = class _T2000 extends EventEmitter {
2896
2877
  const adapter = this.registry.getLending(entry.protocolId);
2897
2878
  if (!adapter) continue;
2898
2879
  const maxResult = await adapter.maxWithdraw(this._address, entry.asset);
2899
- if (maxResult.maxAmount > 1e-3) {
2900
- entries.push({ ...entry, maxAmount: maxResult.maxAmount, adapter });
2880
+ const perAssetMax = Math.min(entry.amount, maxResult.maxAmount);
2881
+ if (perAssetMax > 0.01) {
2882
+ entries.push({ ...entry, maxAmount: perAssetMax, adapter });
2901
2883
  }
2902
2884
  }
2903
2885
  if (entries.length === 0) {