@t2000/sdk 0.19.19 → 0.19.21

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.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { T as TransactionSigner, I as InvestmentRecord, S as StrategyDefinition, A as AutoInvestSchedule, a as AutoInvestStatus, b as T2000Options, P as PayOptions, c as PayResult, d as SendResult, B as BalanceResponse, e as TransactionRecord, D as DepositInfo, L as LendingAdapter, f as SwapAdapter, g as SaveResult, W as WithdrawResult, M as MaxWithdrawResult, h as BorrowResult, R as RepayResult, i as MaxBorrowResult, H as HealthFactorResult, j as SwapResult, k as InvestResult, l as InvestEarnResult, m as InvestRebalanceResult, n as PendingReward, C as ClaimRewardsResult, o as StrategyBuyResult, p as StrategySellResult, q as StrategyRebalanceResult, r as StrategyStatusResult, s as AutoInvestRunResult, t as PortfolioResult, u as InvestmentPosition, v as PositionsResult, w as RatesResult, x as LendingRates, y as RebalanceResult, E as EarningsResult, F as FundStatusResult, z as SentinelAgent, G as SentinelAttackResult, J as GasMethod } from './index-DAxuyiS2.cjs';
2
- export { K as AdapterCapability, N as AdapterPositions, O as AdapterTxResult, Q as AssetRates, U as CetusAdapter, V as GasReserve, X as HealthInfo, Y as InvestRebalanceMove, Z as NaviAdapter, _ as PerpsAdapter, $ as PerpsPosition, a0 as PerpsPositionsResult, a1 as PerpsTradeResult, a2 as PositionEntry, a3 as PositionSide, a4 as ProtocolDescriptor, a5 as ProtocolRegistry, a6 as RebalanceStep, a7 as SentinelVerdict, a8 as SuilendAdapter, a9 as SwapQuote, aa as allDescriptors, ab as cetusDescriptor, ac as getSentinelInfo, ad as listSentinels, ae as naviDescriptor, af as requestAttack, ag as sentinelAttack, ah as sentinelDescriptor, ai as settleAttack, aj as submitPrompt, ak as suilendDescriptor } from './index-DAxuyiS2.cjs';
1
+ import { T as TransactionSigner, I as InvestmentRecord, S as StrategyDefinition, A as AutoInvestSchedule, a as AutoInvestStatus, b as T2000Options, P as PayOptions, c as PayResult, d as SendResult, B as BalanceResponse, e as TransactionRecord, D as DepositInfo, L as LendingAdapter, f as SwapAdapter, g as SaveResult, W as WithdrawResult, M as MaxWithdrawResult, h as BorrowResult, R as RepayResult, i as MaxBorrowResult, H as HealthFactorResult, j as SwapResult, k as InvestResult, l as InvestEarnResult, m as InvestRebalanceResult, n as PendingReward, C as ClaimRewardsResult, o as StrategyBuyResult, p as StrategySellResult, q as StrategyRebalanceResult, r as StrategyStatusResult, s as AutoInvestRunResult, t as PortfolioResult, u as InvestmentPosition, v as PositionsResult, w as RatesResult, x as LendingRates, y as RebalanceResult, E as EarningsResult, F as FundStatusResult, z as SentinelAgent, G as SentinelAttackResult, J as GasMethod } from './index-CRyFiIZm.cjs';
2
+ export { K as AdapterCapability, N as AdapterPositions, O as AdapterTxResult, Q as AssetRates, U as CetusAdapter, V as GasReserve, X as HealthInfo, Y as InvestRebalanceMove, Z as NaviAdapter, _ as PerpsAdapter, $ as PerpsPosition, a0 as PerpsPositionsResult, a1 as PerpsTradeResult, a2 as PositionEntry, a3 as PositionSide, a4 as ProtocolDescriptor, a5 as ProtocolRegistry, a6 as RebalanceStep, a7 as SentinelVerdict, a8 as SuilendAdapter, a9 as SwapQuote, aa as allDescriptors, ab as cetusDescriptor, ac as getSentinelInfo, ad as listSentinels, ae as naviDescriptor, af as requestAttack, ag as sentinelAttack, ah as sentinelDescriptor, ai as settleAttack, aj as submitPrompt, ak as suilendDescriptor } from './index-CRyFiIZm.cjs';
3
3
  import { EventEmitter } from 'eventemitter3';
4
4
  import { SuiJsonRpcClient } from '@mysten/sui/jsonRpc';
5
5
  import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { T as TransactionSigner, I as InvestmentRecord, S as StrategyDefinition, A as AutoInvestSchedule, a as AutoInvestStatus, b as T2000Options, P as PayOptions, c as PayResult, d as SendResult, B as BalanceResponse, e as TransactionRecord, D as DepositInfo, L as LendingAdapter, f as SwapAdapter, g as SaveResult, W as WithdrawResult, M as MaxWithdrawResult, h as BorrowResult, R as RepayResult, i as MaxBorrowResult, H as HealthFactorResult, j as SwapResult, k as InvestResult, l as InvestEarnResult, m as InvestRebalanceResult, n as PendingReward, C as ClaimRewardsResult, o as StrategyBuyResult, p as StrategySellResult, q as StrategyRebalanceResult, r as StrategyStatusResult, s as AutoInvestRunResult, t as PortfolioResult, u as InvestmentPosition, v as PositionsResult, w as RatesResult, x as LendingRates, y as RebalanceResult, E as EarningsResult, F as FundStatusResult, z as SentinelAgent, G as SentinelAttackResult, J as GasMethod } from './index-DAxuyiS2.js';
2
- export { K as AdapterCapability, N as AdapterPositions, O as AdapterTxResult, Q as AssetRates, U as CetusAdapter, V as GasReserve, X as HealthInfo, Y as InvestRebalanceMove, Z as NaviAdapter, _ as PerpsAdapter, $ as PerpsPosition, a0 as PerpsPositionsResult, a1 as PerpsTradeResult, a2 as PositionEntry, a3 as PositionSide, a4 as ProtocolDescriptor, a5 as ProtocolRegistry, a6 as RebalanceStep, a7 as SentinelVerdict, a8 as SuilendAdapter, a9 as SwapQuote, aa as allDescriptors, ab as cetusDescriptor, ac as getSentinelInfo, ad as listSentinels, ae as naviDescriptor, af as requestAttack, ag as sentinelAttack, ah as sentinelDescriptor, ai as settleAttack, aj as submitPrompt, ak as suilendDescriptor } from './index-DAxuyiS2.js';
1
+ import { T as TransactionSigner, I as InvestmentRecord, S as StrategyDefinition, A as AutoInvestSchedule, a as AutoInvestStatus, b as T2000Options, P as PayOptions, c as PayResult, d as SendResult, B as BalanceResponse, e as TransactionRecord, D as DepositInfo, L as LendingAdapter, f as SwapAdapter, g as SaveResult, W as WithdrawResult, M as MaxWithdrawResult, h as BorrowResult, R as RepayResult, i as MaxBorrowResult, H as HealthFactorResult, j as SwapResult, k as InvestResult, l as InvestEarnResult, m as InvestRebalanceResult, n as PendingReward, C as ClaimRewardsResult, o as StrategyBuyResult, p as StrategySellResult, q as StrategyRebalanceResult, r as StrategyStatusResult, s as AutoInvestRunResult, t as PortfolioResult, u as InvestmentPosition, v as PositionsResult, w as RatesResult, x as LendingRates, y as RebalanceResult, E as EarningsResult, F as FundStatusResult, z as SentinelAgent, G as SentinelAttackResult, J as GasMethod } from './index-CRyFiIZm.js';
2
+ export { K as AdapterCapability, N as AdapterPositions, O as AdapterTxResult, Q as AssetRates, U as CetusAdapter, V as GasReserve, X as HealthInfo, Y as InvestRebalanceMove, Z as NaviAdapter, _ as PerpsAdapter, $ as PerpsPosition, a0 as PerpsPositionsResult, a1 as PerpsTradeResult, a2 as PositionEntry, a3 as PositionSide, a4 as ProtocolDescriptor, a5 as ProtocolRegistry, a6 as RebalanceStep, a7 as SentinelVerdict, a8 as SuilendAdapter, a9 as SwapQuote, aa as allDescriptors, ab as cetusDescriptor, ac as getSentinelInfo, ad as listSentinels, ae as naviDescriptor, af as requestAttack, ag as sentinelAttack, ah as sentinelDescriptor, ai as settleAttack, aj as submitPrompt, ak as suilendDescriptor } from './index-CRyFiIZm.js';
3
3
  import { EventEmitter } from 'eventemitter3';
4
4
  import { SuiJsonRpcClient } from '@mysten/sui/jsonRpc';
5
5
  import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
package/dist/index.js CHANGED
@@ -557,7 +557,7 @@ async function queryBalance(client, address) {
557
557
  var SUI_TYPE = "0x2::sui::SUI";
558
558
  var KNOWN_TARGETS = [
559
559
  [/::suilend|::obligation/, "lending"],
560
- [/::navi|::incentive_v2/, "lending"],
560
+ [/::navi|::incentive_v\d+|::oracle_pro/, "lending"],
561
561
  [/::cetus|::pool/, "swap"],
562
562
  [/::deepbook/, "swap"],
563
563
  [/::transfer::public_transfer/, "send"]
@@ -711,6 +711,7 @@ function sdkOptions(client) {
711
711
  return { env: "prod", client, cacheTime: 0, disableCache: true };
712
712
  }
713
713
  async function refreshOracle(tx, client, address, options) {
714
+ if (options?.skipOracle) return;
714
715
  const origInfo = console.info;
715
716
  const origWarn = console.warn;
716
717
  console.info = (...args) => {
@@ -878,13 +879,14 @@ async function buildSaveTx(client, address, amount, options = {}) {
878
879
  const assetInfo = resolveAssetInfo(asset);
879
880
  const coins = await fetchCoins(client, address, assetInfo.type);
880
881
  if (coins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", `No ${assetInfo.displayName} coins found`);
882
+ const totalBalance = coins.reduce((sum, c) => sum + BigInt(c.balance), 0n);
881
883
  const tx = new Transaction();
882
884
  tx.setSender(address);
883
885
  const coinObj = mergeCoins(tx, coins);
884
886
  if (options.collectFee) {
885
887
  addCollectFeeToTx(tx, coinObj, "save");
886
888
  }
887
- const rawAmount = Number(stableToRaw(amount, assetInfo.decimals));
889
+ const rawAmount = Math.min(Number(stableToRaw(amount, assetInfo.decimals)), Number(totalBalance));
888
890
  try {
889
891
  await depositCoinPTB(tx, assetInfo.type, coinObj, {
890
892
  ...sdkOptions(client),
@@ -1005,12 +1007,16 @@ async function buildRepayTx(client, address, amount, options = {}) {
1005
1007
  const assetInfo = resolveAssetInfo(asset);
1006
1008
  const coins = await fetchCoins(client, address, assetInfo.type);
1007
1009
  if (coins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", `No ${assetInfo.displayName} coins to repay with`);
1010
+ const totalBalance = coins.reduce((sum, c) => sum + BigInt(c.balance), 0n);
1008
1011
  const tx = new Transaction();
1009
1012
  tx.setSender(address);
1010
1013
  const coinObj = mergeCoins(tx, coins);
1011
- const rawAmount = Number(stableToRaw(amount, assetInfo.decimals));
1014
+ const rawAmount = Math.min(Number(stableToRaw(amount, assetInfo.decimals)), Number(totalBalance));
1012
1015
  const [repayCoin] = tx.splitCoins(coinObj, [rawAmount]);
1013
- await refreshOracle(tx, client, address, { skipPythUpdate: options.sponsored });
1016
+ await refreshOracle(tx, client, address, {
1017
+ skipPythUpdate: options.sponsored,
1018
+ skipOracle: options.skipOracle
1019
+ });
1014
1020
  try {
1015
1021
  await repayCoinPTB(tx, assetInfo.type, repayCoin, {
1016
1022
  ...sdkOptions(client),
@@ -1535,7 +1541,11 @@ var NaviAdapter = class {
1535
1541
  }
1536
1542
  async buildRepayTx(address, amount, asset, options) {
1537
1543
  const normalized = normalizeAsset(asset);
1538
- const tx = await buildRepayTx(this.client, address, amount, { asset: normalized, sponsored: options?.sponsored });
1544
+ const tx = await buildRepayTx(this.client, address, amount, {
1545
+ asset: normalized,
1546
+ sponsored: options?.sponsored,
1547
+ skipOracle: options?.skipOracle
1548
+ });
1539
1549
  return { tx };
1540
1550
  }
1541
1551
  async maxWithdraw(address, _asset) {
@@ -2208,16 +2218,23 @@ var SuilendAdapter = class {
2208
2218
  if (obligationOwnerCaps.length === 0 || obligations.length === 0) return [];
2209
2219
  const ob = obligations[0];
2210
2220
  const rewards = [];
2221
+ const WAD = 1e18;
2211
2222
  for (const dep of ob.deposits) {
2212
- for (const rw of dep.reserve.depositsPoolRewardManager.poolRewards) {
2223
+ const urm = dep.userRewardManager;
2224
+ for (const rw of dep.reserve.depositsPoolRewardManager?.poolRewards ?? []) {
2213
2225
  if (rw.endTimeMs <= Date.now()) continue;
2226
+ let claimableAmount = 0;
2227
+ const userReward = urm?.rewards?.[rw.rewardIndex];
2228
+ if (userReward?.earnedRewards) {
2229
+ claimableAmount = Number(BigInt(userReward.earnedRewards.value.toString())) / WAD / 10 ** rw.mintDecimals;
2230
+ }
2214
2231
  const symbol = rw.symbol || rw.coinType.split("::").pop() || "UNKNOWN";
2215
2232
  rewards.push({
2216
2233
  protocol: "suilend",
2217
2234
  asset: this.resolveSymbol(dep.coinType),
2218
2235
  coinType: rw.coinType,
2219
2236
  symbol,
2220
- amount: 0,
2237
+ amount: claimableAmount,
2221
2238
  estimatedValueUsd: 0
2222
2239
  });
2223
2240
  }
@@ -2901,6 +2918,7 @@ var ContactManager = class {
2901
2918
  }
2902
2919
  }
2903
2920
  };
2921
+ var UNSAFE_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
2904
2922
  function emptyData() {
2905
2923
  return { positions: {}, strategies: {}, realizedPnL: 0 };
2906
2924
  }
@@ -3056,25 +3074,34 @@ var PortfolioManager = class {
3056
3074
  }
3057
3075
  // --- Strategy position tracking ---
3058
3076
  recordStrategyBuy(strategyKey, trade) {
3077
+ if (UNSAFE_KEYS.has(strategyKey) || UNSAFE_KEYS.has(trade.asset)) {
3078
+ throw new T2000Error("ASSET_NOT_SUPPORTED", "Invalid strategy key or asset name");
3079
+ }
3059
3080
  this.load();
3060
- if (!this.data.strategies[strategyKey]) {
3061
- this.data.strategies[strategyKey] = {};
3081
+ if (!Object.hasOwn(this.data.strategies, strategyKey)) {
3082
+ this.data.strategies[strategyKey] = /* @__PURE__ */ Object.create(null);
3062
3083
  }
3063
3084
  const bucket = this.data.strategies[strategyKey];
3064
- const pos = bucket[trade.asset] ?? { totalAmount: 0, costBasis: 0, avgPrice: 0, trades: [] };
3085
+ const pos = Object.hasOwn(bucket, trade.asset) ? bucket[trade.asset] : { totalAmount: 0, costBasis: 0, avgPrice: 0, trades: [] };
3065
3086
  pos.totalAmount += trade.amount;
3066
3087
  pos.costBasis += trade.usdValue;
3067
3088
  pos.avgPrice = pos.costBasis / pos.totalAmount;
3068
3089
  pos.trades.push(trade);
3069
- bucket[trade.asset] = pos;
3090
+ Object.defineProperty(bucket, trade.asset, { value: pos, writable: true, enumerable: true, configurable: true });
3070
3091
  this.save();
3071
3092
  }
3072
3093
  recordStrategySell(strategyKey, trade) {
3094
+ if (UNSAFE_KEYS.has(strategyKey) || UNSAFE_KEYS.has(trade.asset)) {
3095
+ throw new T2000Error("ASSET_NOT_SUPPORTED", "Invalid strategy key or asset name");
3096
+ }
3073
3097
  this.load();
3074
3098
  const bucket = this.data.strategies[strategyKey];
3075
3099
  if (!bucket) {
3076
3100
  throw new T2000Error("STRATEGY_NOT_FOUND", `No positions for strategy '${strategyKey}'`);
3077
3101
  }
3102
+ if (!Object.hasOwn(bucket, trade.asset)) {
3103
+ throw new T2000Error("INSUFFICIENT_INVESTMENT", `No ${trade.asset} position in strategy '${strategyKey}'`);
3104
+ }
3078
3105
  const pos = bucket[trade.asset];
3079
3106
  if (!pos || pos.totalAmount <= 0) {
3080
3107
  throw new T2000Error("INSUFFICIENT_INVESTMENT", `No ${trade.asset} position in strategy '${strategyKey}'`);
@@ -3091,7 +3118,7 @@ var PortfolioManager = class {
3091
3118
  pos.avgPrice = 0;
3092
3119
  }
3093
3120
  pos.trades.push(trade);
3094
- bucket[trade.asset] = pos;
3121
+ Object.defineProperty(bucket, trade.asset, { value: pos, writable: true, enumerable: true, configurable: true });
3095
3122
  const hasPositions = Object.values(bucket).some((p) => p.totalAmount > 0);
3096
3123
  if (!hasPositions) {
3097
3124
  delete this.data.strategies[strategyKey];