@t2000/sdk 0.50.3 → 0.51.1

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,12 +1,12 @@
1
1
  import { EventEmitter } from 'eventemitter3';
2
2
  import { SuiJsonRpcClient } from '@mysten/sui/jsonRpc';
3
3
  import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
4
- import { T as T2000Error, aC as SafeguardEnforcer, Q as TransactionSigner, a0 as ZkLoginProof, y as SupportedAsset } from './token-registry-BYXTvp_b.cjs';
5
- export { A as ALL_NAVI_ASSETS, a as AutoTopUpResult, aD as BORROW_FEE_BPS, B as BPS_DENOMINATOR, aE as CETUS_USDC_SUI_POOL, C as CLOCK_ID, b as COIN_REGISTRY, c as ClassifyBalanceChange, d as ClassifyResult, e as CoinMeta, D as DEFAULT_NETWORK, f as DEFAULT_SAFEGUARD_CONFIG, E as ETH_TYPE, g as ExtractedTransfer, F as FeeOperation, G as GAS_RESERVE_MIN, h as GasExecutionResult, i as GasRequestType, j as GasSponsorResponse, k as GasStatusResponse, I as IKA_TYPE, K as KNOWN_TARGETS, l as KeypairSigner, L as LABEL_PATTERNS, m as LOFI_TYPE, M as MANIFEST_TYPE, n as MIST_PER_SUI, N as NAVX_TYPE, aF as OPERATION_ASSETS, O as OUTBOUND_OPS, aG as Operation, P as ProtocolFeeInfo, aH as SAVE_FEE_BPS, S as STABLE_ASSETS, o as SUI_DECIMALS, p as SUI_TYPE, q as SUPPORTED_ASSETS, r as SafeguardConfig, s as SafeguardError, t as SafeguardErrorDetails, u as SafeguardRule, v as SimulationResult, w as StableAsset, x as SuiRpcTxBlock, z as T2000ErrorCode, H as T2000ErrorData, J as TOKEN_MAP, R as TxDirection, U as TxMetadata, V as USDC_DECIMALS, W as USDC_TYPE, X as USDE_TYPE, Y as USDSUI_TYPE, Z as USDT_TYPE, _ as WAL_TYPE, $ as WBTC_TYPE, a1 as ZkLoginSigner, a2 as addCollectFeeToTx, aI as assertAllowedAsset, a3 as calculateFee, a4 as classifyAction, a5 as classifyLabel, a6 as classifyTransaction, a7 as executeAutoTopUp, a8 as executeWithGas, a9 as extractTransferDetails, aa as extractTxCommands, ab as extractTxSender, ac as fallbackLabel, ad as formatAssetAmount, ae as formatSui, af as formatUsd, ag as getDecimals, ah as getDecimalsForCoinType, ai as getGasStatus, aj as getTier, aJ as isAllowedAsset, ak as isSupported, al as isTier1, am as isTier2, an as mapMoveAbortCode, ao as mapWalletError, ap as mistToSui, aK as normalizeCoinType, aq as parseSuiRpcTx, aL as queryHistory, aM as queryTransaction, ar as rawToStable, as as rawToUsdc, at as refineLendingLabel, au as resolveSymbol, av as resolveTokenType, aw as shouldAutoTopUp, aN as simulateTransaction, ax as stableToRaw, ay as suiToMist, aO as throwIfSimulationFailed, az as truncateAddress, aA as usdcToRaw, aB as validateAddress } from './token-registry-BYXTvp_b.cjs';
4
+ import { T as T2000Error, aC as SafeguardEnforcer, Q as TransactionSigner, a0 as ZkLoginProof, y as SupportedAsset } from './token-registry-DWRdYf6m.cjs';
5
+ export { A as ALL_NAVI_ASSETS, a as AutoTopUpResult, aD as BORROW_FEE_BPS, B as BPS_DENOMINATOR, aE as CETUS_USDC_SUI_POOL, C as CLOCK_ID, b as COIN_REGISTRY, c as ClassifyBalanceChange, d as ClassifyResult, e as CoinMeta, D as DEFAULT_NETWORK, f as DEFAULT_SAFEGUARD_CONFIG, E as ETH_TYPE, g as ExtractedTransfer, F as FeeOperation, G as GAS_RESERVE_MIN, h as GasExecutionResult, i as GasRequestType, j as GasSponsorResponse, k as GasStatusResponse, I as IKA_TYPE, K as KNOWN_TARGETS, l as KeypairSigner, L as LABEL_PATTERNS, m as LOFI_TYPE, M as MANIFEST_TYPE, n as MIST_PER_SUI, N as NAVX_TYPE, aF as OPERATION_ASSETS, O as OUTBOUND_OPS, aG as Operation, P as ProtocolFeeInfo, aH as SAVE_FEE_BPS, S as STABLE_ASSETS, o as SUI_DECIMALS, p as SUI_TYPE, q as SUPPORTED_ASSETS, r as SafeguardConfig, s as SafeguardError, t as SafeguardErrorDetails, u as SafeguardRule, v as SimulationResult, w as StableAsset, x as SuiRpcTxBlock, z as T2000ErrorCode, H as T2000ErrorData, J as TOKEN_MAP, R as TxDirection, U as TxMetadata, V as USDC_DECIMALS, W as USDC_TYPE, X as USDE_TYPE, Y as USDSUI_TYPE, Z as USDT_TYPE, _ as WAL_TYPE, $ as WBTC_TYPE, a1 as ZkLoginSigner, a2 as addCollectFeeToTx, aI as assertAllowedAsset, a3 as calculateFee, a4 as classifyAction, a5 as classifyLabel, a6 as classifyTransaction, a7 as executeAutoTopUp, a8 as executeWithGas, a9 as extractTransferDetails, aa as extractTxCommands, ab as extractTxSender, ac as fallbackLabel, ad as formatAssetAmount, ae as formatSui, af as formatUsd, ag as getDecimals, ah as getDecimalsForCoinType, ai as getGasStatus, aj as getTier, aJ as isAllowedAsset, ak as isSupported, al as isTier1, am as isTier2, an as mapMoveAbortCode, ao as mapWalletError, ap as mistToSui, aK as normalizeCoinType, aq as parseSuiRpcTx, aL as queryHistory, aM as queryTransaction, ar as rawToStable, as as rawToUsdc, at as refineLendingLabel, au as resolveSymbol, av as resolveTokenType, aw as shouldAutoTopUp, aN as simulateTransaction, ax as stableToRaw, ay as suiToMist, aO as throwIfSimulationFailed, az as truncateAddress, aA as usdcToRaw, aB as validateAddress } from './token-registry-DWRdYf6m.cjs';
6
6
  import { L as LendingAdapter, a as LendingRates, P as PendingReward$1 } from './descriptors-DkKhitk_.cjs';
7
7
  export { A as AdapterCapability, b as AdapterPositions, c as AdapterTxResult, H as HealthInfo, d as ProtocolDescriptor, e as allDescriptors, n as naviDescriptor } from './descriptors-DkKhitk_.cjs';
8
- import { j as T2000Options, P as PayOptions, d as PayResult, k as StakeVSuiResult, U as UnstakeVSuiResult, l as SwapResult, m as SwapQuoteResult, i as SendResult, B as BalanceResponse, T as TransactionRecord, D as DepositInfo, n as PaymentRequest, S as SaveResult, W as WithdrawResult, c as MaxWithdrawResult, a as BorrowResult, h as RepayResult, M as MaxBorrowResult, H as HealthFactorResult, e as PendingReward, C as ClaimRewardsResult, o as CompoundRewardsResult, g as PositionsResult, R as RatesResult, E as EarningsResult, F as FundStatusResult, p as FinancialSummary } from './types-DIgyNKqV.cjs';
9
- export { A as AssetRates, G as GasMethod, b as GasReserve, q as HFAlertLevel, f as PositionEntry } from './types-DIgyNKqV.cjs';
8
+ import { j as T2000Options, P as PayOptions, d as PayResult, k as StakeVSuiResult, U as UnstakeVSuiResult, l as SwapResult, m as SwapQuoteResult, i as SendResult, B as BalanceResponse, T as TransactionRecord, D as DepositInfo, n as PaymentRequest, S as SaveResult, W as WithdrawResult, c as MaxWithdrawResult, a as BorrowResult, h as RepayResult, M as MaxBorrowResult, H as HealthFactorResult, e as PendingReward, C as ClaimRewardsResult, o as CompoundRewardsResult, g as PositionsResult, R as RatesResult, E as EarningsResult, F as FundStatusResult, p as FinancialSummary } from './types-DVVns7_w.cjs';
9
+ export { A as AssetRates, G as GasMethod, b as GasReserve, q as HFAlertLevel, f as PositionEntry } from './types-DVVns7_w.cjs';
10
10
  import { RouterDataV3 } from '@cetusprotocol/aggregator-sdk';
11
11
  import { Transaction, TransactionObjectArgument } from '@mysten/sui/transactions';
12
12
  export { NaviAdapter, ProtocolRegistry } from './adapters/index.cjs';
@@ -161,6 +161,17 @@ declare class T2000 extends EventEmitter<T2000Events> {
161
161
  protocol?: string;
162
162
  }): Promise<WithdrawResult>;
163
163
  private withdrawAllProtocols;
164
+ /**
165
+ * [v0.51.0] Per-asset wallet balance lookup.
166
+ *
167
+ * `queryBalance.available` rolls up only `STABLE_ASSETS` (USDC), so it cannot
168
+ * answer "do they have enough USDsui to save 10?". This helper hits
169
+ * `getBalance` for the specific coin type — same mechanism `queryBalance`
170
+ * uses internally — and converts to a human-readable amount using the asset's
171
+ * decimals. Returns 0 (not a throw) when the address holds none of the asset,
172
+ * matching the caller's existing "insufficient balance" error path.
173
+ */
174
+ private _queryAssetBalance;
164
175
  private _fetchCoins;
165
176
  private _mergeCoinsInTx;
166
177
  private _lastFundDigest;
@@ -168,10 +179,12 @@ declare class T2000 extends EventEmitter<T2000Events> {
168
179
  maxWithdraw(): Promise<MaxWithdrawResult>;
169
180
  borrow(params: {
170
181
  amount: number;
182
+ asset?: SupportedAsset;
171
183
  protocol?: string;
172
184
  }): Promise<BorrowResult>;
173
185
  repay(params: {
174
186
  amount: number | 'all';
187
+ asset?: SupportedAsset;
175
188
  protocol?: string;
176
189
  }): Promise<RepayResult>;
177
190
  private _repayAllBorrows;
package/dist/index.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import { EventEmitter } from 'eventemitter3';
2
2
  import { SuiJsonRpcClient } from '@mysten/sui/jsonRpc';
3
3
  import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
4
- import { T as T2000Error, aC as SafeguardEnforcer, Q as TransactionSigner, a0 as ZkLoginProof, y as SupportedAsset } from './token-registry-DbI2moHp.js';
5
- export { A as ALL_NAVI_ASSETS, a as AutoTopUpResult, aD as BORROW_FEE_BPS, B as BPS_DENOMINATOR, aE as CETUS_USDC_SUI_POOL, C as CLOCK_ID, b as COIN_REGISTRY, c as ClassifyBalanceChange, d as ClassifyResult, e as CoinMeta, D as DEFAULT_NETWORK, f as DEFAULT_SAFEGUARD_CONFIG, E as ETH_TYPE, g as ExtractedTransfer, F as FeeOperation, G as GAS_RESERVE_MIN, h as GasExecutionResult, i as GasRequestType, j as GasSponsorResponse, k as GasStatusResponse, I as IKA_TYPE, K as KNOWN_TARGETS, l as KeypairSigner, L as LABEL_PATTERNS, m as LOFI_TYPE, M as MANIFEST_TYPE, n as MIST_PER_SUI, N as NAVX_TYPE, aF as OPERATION_ASSETS, O as OUTBOUND_OPS, aG as Operation, P as ProtocolFeeInfo, aH as SAVE_FEE_BPS, S as STABLE_ASSETS, o as SUI_DECIMALS, p as SUI_TYPE, q as SUPPORTED_ASSETS, r as SafeguardConfig, s as SafeguardError, t as SafeguardErrorDetails, u as SafeguardRule, v as SimulationResult, w as StableAsset, x as SuiRpcTxBlock, z as T2000ErrorCode, H as T2000ErrorData, J as TOKEN_MAP, R as TxDirection, U as TxMetadata, V as USDC_DECIMALS, W as USDC_TYPE, X as USDE_TYPE, Y as USDSUI_TYPE, Z as USDT_TYPE, _ as WAL_TYPE, $ as WBTC_TYPE, a1 as ZkLoginSigner, a2 as addCollectFeeToTx, aI as assertAllowedAsset, a3 as calculateFee, a4 as classifyAction, a5 as classifyLabel, a6 as classifyTransaction, a7 as executeAutoTopUp, a8 as executeWithGas, a9 as extractTransferDetails, aa as extractTxCommands, ab as extractTxSender, ac as fallbackLabel, ad as formatAssetAmount, ae as formatSui, af as formatUsd, ag as getDecimals, ah as getDecimalsForCoinType, ai as getGasStatus, aj as getTier, aJ as isAllowedAsset, ak as isSupported, al as isTier1, am as isTier2, an as mapMoveAbortCode, ao as mapWalletError, ap as mistToSui, aK as normalizeCoinType, aq as parseSuiRpcTx, aL as queryHistory, aM as queryTransaction, ar as rawToStable, as as rawToUsdc, at as refineLendingLabel, au as resolveSymbol, av as resolveTokenType, aw as shouldAutoTopUp, aN as simulateTransaction, ax as stableToRaw, ay as suiToMist, aO as throwIfSimulationFailed, az as truncateAddress, aA as usdcToRaw, aB as validateAddress } from './token-registry-DbI2moHp.js';
4
+ import { T as T2000Error, aC as SafeguardEnforcer, Q as TransactionSigner, a0 as ZkLoginProof, y as SupportedAsset } from './token-registry-BortlMRr.js';
5
+ export { A as ALL_NAVI_ASSETS, a as AutoTopUpResult, aD as BORROW_FEE_BPS, B as BPS_DENOMINATOR, aE as CETUS_USDC_SUI_POOL, C as CLOCK_ID, b as COIN_REGISTRY, c as ClassifyBalanceChange, d as ClassifyResult, e as CoinMeta, D as DEFAULT_NETWORK, f as DEFAULT_SAFEGUARD_CONFIG, E as ETH_TYPE, g as ExtractedTransfer, F as FeeOperation, G as GAS_RESERVE_MIN, h as GasExecutionResult, i as GasRequestType, j as GasSponsorResponse, k as GasStatusResponse, I as IKA_TYPE, K as KNOWN_TARGETS, l as KeypairSigner, L as LABEL_PATTERNS, m as LOFI_TYPE, M as MANIFEST_TYPE, n as MIST_PER_SUI, N as NAVX_TYPE, aF as OPERATION_ASSETS, O as OUTBOUND_OPS, aG as Operation, P as ProtocolFeeInfo, aH as SAVE_FEE_BPS, S as STABLE_ASSETS, o as SUI_DECIMALS, p as SUI_TYPE, q as SUPPORTED_ASSETS, r as SafeguardConfig, s as SafeguardError, t as SafeguardErrorDetails, u as SafeguardRule, v as SimulationResult, w as StableAsset, x as SuiRpcTxBlock, z as T2000ErrorCode, H as T2000ErrorData, J as TOKEN_MAP, R as TxDirection, U as TxMetadata, V as USDC_DECIMALS, W as USDC_TYPE, X as USDE_TYPE, Y as USDSUI_TYPE, Z as USDT_TYPE, _ as WAL_TYPE, $ as WBTC_TYPE, a1 as ZkLoginSigner, a2 as addCollectFeeToTx, aI as assertAllowedAsset, a3 as calculateFee, a4 as classifyAction, a5 as classifyLabel, a6 as classifyTransaction, a7 as executeAutoTopUp, a8 as executeWithGas, a9 as extractTransferDetails, aa as extractTxCommands, ab as extractTxSender, ac as fallbackLabel, ad as formatAssetAmount, ae as formatSui, af as formatUsd, ag as getDecimals, ah as getDecimalsForCoinType, ai as getGasStatus, aj as getTier, aJ as isAllowedAsset, ak as isSupported, al as isTier1, am as isTier2, an as mapMoveAbortCode, ao as mapWalletError, ap as mistToSui, aK as normalizeCoinType, aq as parseSuiRpcTx, aL as queryHistory, aM as queryTransaction, ar as rawToStable, as as rawToUsdc, at as refineLendingLabel, au as resolveSymbol, av as resolveTokenType, aw as shouldAutoTopUp, aN as simulateTransaction, ax as stableToRaw, ay as suiToMist, aO as throwIfSimulationFailed, az as truncateAddress, aA as usdcToRaw, aB as validateAddress } from './token-registry-BortlMRr.js';
6
6
  import { L as LendingAdapter, a as LendingRates, P as PendingReward$1 } from './descriptors-DkKhitk_.js';
7
7
  export { A as AdapterCapability, b as AdapterPositions, c as AdapterTxResult, H as HealthInfo, d as ProtocolDescriptor, e as allDescriptors, n as naviDescriptor } from './descriptors-DkKhitk_.js';
8
- import { j as T2000Options, P as PayOptions, d as PayResult, k as StakeVSuiResult, U as UnstakeVSuiResult, l as SwapResult, m as SwapQuoteResult, i as SendResult, B as BalanceResponse, T as TransactionRecord, D as DepositInfo, n as PaymentRequest, S as SaveResult, W as WithdrawResult, c as MaxWithdrawResult, a as BorrowResult, h as RepayResult, M as MaxBorrowResult, H as HealthFactorResult, e as PendingReward, C as ClaimRewardsResult, o as CompoundRewardsResult, g as PositionsResult, R as RatesResult, E as EarningsResult, F as FundStatusResult, p as FinancialSummary } from './types-DIgyNKqV.js';
9
- export { A as AssetRates, G as GasMethod, b as GasReserve, q as HFAlertLevel, f as PositionEntry } from './types-DIgyNKqV.js';
8
+ import { j as T2000Options, P as PayOptions, d as PayResult, k as StakeVSuiResult, U as UnstakeVSuiResult, l as SwapResult, m as SwapQuoteResult, i as SendResult, B as BalanceResponse, T as TransactionRecord, D as DepositInfo, n as PaymentRequest, S as SaveResult, W as WithdrawResult, c as MaxWithdrawResult, a as BorrowResult, h as RepayResult, M as MaxBorrowResult, H as HealthFactorResult, e as PendingReward, C as ClaimRewardsResult, o as CompoundRewardsResult, g as PositionsResult, R as RatesResult, E as EarningsResult, F as FundStatusResult, p as FinancialSummary } from './types-DVVns7_w.js';
9
+ export { A as AssetRates, G as GasMethod, b as GasReserve, q as HFAlertLevel, f as PositionEntry } from './types-DVVns7_w.js';
10
10
  import { RouterDataV3 } from '@cetusprotocol/aggregator-sdk';
11
11
  import { Transaction, TransactionObjectArgument } from '@mysten/sui/transactions';
12
12
  export { NaviAdapter, ProtocolRegistry } from './adapters/index.js';
@@ -161,6 +161,17 @@ declare class T2000 extends EventEmitter<T2000Events> {
161
161
  protocol?: string;
162
162
  }): Promise<WithdrawResult>;
163
163
  private withdrawAllProtocols;
164
+ /**
165
+ * [v0.51.0] Per-asset wallet balance lookup.
166
+ *
167
+ * `queryBalance.available` rolls up only `STABLE_ASSETS` (USDC), so it cannot
168
+ * answer "do they have enough USDsui to save 10?". This helper hits
169
+ * `getBalance` for the specific coin type — same mechanism `queryBalance`
170
+ * uses internally — and converts to a human-readable amount using the asset's
171
+ * decimals. Returns 0 (not a throw) when the address holds none of the asset,
172
+ * matching the caller's existing "insufficient balance" error path.
173
+ */
174
+ private _queryAssetBalance;
164
175
  private _fetchCoins;
165
176
  private _mergeCoinsInTx;
166
177
  private _lastFundDigest;
@@ -168,10 +179,12 @@ declare class T2000 extends EventEmitter<T2000Events> {
168
179
  maxWithdraw(): Promise<MaxWithdrawResult>;
169
180
  borrow(params: {
170
181
  amount: number;
182
+ asset?: SupportedAsset;
171
183
  protocol?: string;
172
184
  }): Promise<BorrowResult>;
173
185
  repay(params: {
174
186
  amount: number | 'all';
187
+ asset?: SupportedAsset;
175
188
  protocol?: string;
176
189
  }): Promise<RepayResult>;
177
190
  private _repayAllBorrows;
package/dist/index.js CHANGED
@@ -874,8 +874,8 @@ var SUPPORTED_ASSETS = {
874
874
  var STABLE_ASSETS = ["USDC"];
875
875
  var ALL_NAVI_ASSETS = Object.keys(SUPPORTED_ASSETS);
876
876
  var OPERATION_ASSETS = {
877
- save: ["USDC"],
878
- borrow: ["USDC"],
877
+ save: ["USDC", "USDsui"],
878
+ borrow: ["USDC", "USDsui"],
879
879
  withdraw: "*",
880
880
  repay: "*",
881
881
  send: "*",
@@ -884,7 +884,8 @@ var OPERATION_ASSETS = {
884
884
  function isAllowedAsset(op, asset) {
885
885
  const allowed = OPERATION_ASSETS[op];
886
886
  if (allowed === "*") return true;
887
- return allowed.includes(asset.toUpperCase());
887
+ const target = asset.toLowerCase();
888
+ return allowed.some((a) => a.toLowerCase() === target);
888
889
  }
889
890
  function assertAllowedAsset(op, asset) {
890
891
  if (!asset) return;
@@ -893,7 +894,7 @@ function assertAllowedAsset(op, asset) {
893
894
  const list = Array.isArray(allowed) ? allowed.join(", ") : "any";
894
895
  throw new T2000Error(
895
896
  "INVALID_ASSET",
896
- `${op} only supports ${list}. Cannot use ${asset}.${op === "save" ? " Swap to USDC first." : ""}`
897
+ `${op} only supports ${list}. Cannot use ${asset}.${op === "save" ? " Swap to USDC or USDsui first." : ""}`
897
898
  );
898
899
  }
899
900
  }
@@ -6813,23 +6814,26 @@ var T2000 = class _T2000 extends EventEmitter {
6813
6814
  async save(params) {
6814
6815
  this.enforcer.assertNotLocked();
6815
6816
  assertAllowedAsset("save", params.asset);
6816
- const asset = "USDC";
6817
+ const asset = params.asset ?? "USDC";
6817
6818
  const assetInfo = SUPPORTED_ASSETS[asset];
6818
6819
  let amount;
6819
6820
  if (params.amount === "all") {
6820
- const bal = await queryBalance(this.client, this._address);
6821
- amount = (bal.available ?? 0) - 1;
6821
+ const assetBalance = await this._queryAssetBalance(assetInfo.type, assetInfo.decimals);
6822
+ amount = assetBalance - 1;
6822
6823
  if (amount <= 0) {
6823
- throw new T2000Error("INSUFFICIENT_BALANCE", `No USDC available to save`, {
6824
+ throw new T2000Error("INSUFFICIENT_BALANCE", `No ${assetInfo.displayName} available to save`, {
6824
6825
  reason: "insufficient_balance",
6825
6826
  asset
6826
6827
  });
6827
6828
  }
6828
6829
  } else {
6829
6830
  amount = params.amount;
6830
- const bal = await queryBalance(this.client, this._address);
6831
- if (amount > (bal.available ?? 0)) {
6832
- throw new T2000Error("INSUFFICIENT_BALANCE", `Insufficient balance. Available: $${(bal.available ?? 0).toFixed(2)}, requested: $${amount.toFixed(2)}`);
6831
+ const assetBalance = await this._queryAssetBalance(assetInfo.type, assetInfo.decimals);
6832
+ if (amount > assetBalance) {
6833
+ throw new T2000Error(
6834
+ "INSUFFICIENT_BALANCE",
6835
+ `Insufficient ${assetInfo.displayName} balance. Available: ${assetBalance.toFixed(assetInfo.decimals === 6 ? 2 : 4)}, requested: ${amount.toFixed(assetInfo.decimals === 6 ? 2 : 4)}`
6836
+ );
6833
6837
  }
6834
6838
  }
6835
6839
  const fee = calculateFee("save", amount);
@@ -6841,7 +6845,7 @@ var T2000 = class _T2000 extends EventEmitter {
6841
6845
  const tx2 = new Transaction();
6842
6846
  tx2.setSender(this._address);
6843
6847
  const coins = await this._fetchCoins(assetInfo.type);
6844
- if (coins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", "No USDC coins found");
6848
+ if (coins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", `No ${assetInfo.displayName} coins found`);
6845
6849
  const merged = this._mergeCoinsInTx(tx2, coins);
6846
6850
  const rawAmount = BigInt(Math.floor(saveAmount * 10 ** assetInfo.decimals));
6847
6851
  const [inputCoin] = tx2.splitCoins(merged, [rawAmount]);
@@ -7025,6 +7029,24 @@ var T2000 = class _T2000 extends EventEmitter {
7025
7029
  gasMethod: gasResult.gasMethod
7026
7030
  };
7027
7031
  }
7032
+ /**
7033
+ * [v0.51.0] Per-asset wallet balance lookup.
7034
+ *
7035
+ * `queryBalance.available` rolls up only `STABLE_ASSETS` (USDC), so it cannot
7036
+ * answer "do they have enough USDsui to save 10?". This helper hits
7037
+ * `getBalance` for the specific coin type — same mechanism `queryBalance`
7038
+ * uses internally — and converts to a human-readable amount using the asset's
7039
+ * decimals. Returns 0 (not a throw) when the address holds none of the asset,
7040
+ * matching the caller's existing "insufficient balance" error path.
7041
+ */
7042
+ async _queryAssetBalance(coinType, decimals) {
7043
+ try {
7044
+ const bal = await this.client.getBalance({ owner: this._address, coinType });
7045
+ return Number(bal.totalBalance) / 10 ** decimals;
7046
+ } catch {
7047
+ return 0;
7048
+ }
7049
+ }
7028
7050
  async _fetchCoins(coinType) {
7029
7051
  const all = [];
7030
7052
  let cursor;
@@ -7107,7 +7129,8 @@ var T2000 = class _T2000 extends EventEmitter {
7107
7129
  // -- Borrowing --
7108
7130
  async borrow(params) {
7109
7131
  this.enforcer.assertNotLocked();
7110
- const asset = "USDC";
7132
+ assertAllowedAsset("borrow", params.asset);
7133
+ const asset = params.asset ?? "USDC";
7111
7134
  const adapter = await this.resolveLending(params.protocol, asset, "borrow");
7112
7135
  const maxResult = await adapter.maxBorrow(this._address, asset);
7113
7136
  if (maxResult.maxAmount <= 0) {
@@ -7132,6 +7155,7 @@ var T2000 = class _T2000 extends EventEmitter {
7132
7155
  success: true,
7133
7156
  tx: gasResult.digest,
7134
7157
  amount: borrowAmount,
7158
+ asset,
7135
7159
  fee: fee.amount,
7136
7160
  healthFactor: hf.healthFactor,
7137
7161
  gasCost: gasResult.gasCostSui,
@@ -7154,19 +7178,24 @@ var T2000 = class _T2000 extends EventEmitter {
7154
7178
  if (params.amount === "all") {
7155
7179
  return this._repayAllBorrows(borrows);
7156
7180
  }
7157
- borrows.sort((a, b2) => b2.apy - a.apy);
7158
- const target = borrows[0];
7181
+ const eligible = params.asset ? borrows.filter((b2) => b2.asset === params.asset) : borrows;
7182
+ if (eligible.length === 0) {
7183
+ throw new T2000Error("NO_COLLATERAL", `No outstanding ${params.asset} borrow to repay`);
7184
+ }
7185
+ eligible.sort((a, b2) => b2.apy - a.apy);
7186
+ const target = eligible[0];
7159
7187
  const adapter = this.registry.getLending(target.protocolId);
7160
7188
  if (!adapter) throw new T2000Error("PROTOCOL_UNAVAILABLE", `Protocol ${target.protocolId} not found`);
7161
7189
  const repayAmount = Math.min(params.amount, target.amount);
7190
+ const targetAssetInfo = SUPPORTED_ASSETS[target.asset] ?? SUPPORTED_ASSETS.USDC;
7162
7191
  const gasResult = await executeWithGas(this.client, this._signer, async () => {
7163
7192
  if (adapter.addRepayToTx) {
7164
7193
  const tx2 = new Transaction();
7165
7194
  tx2.setSender(this._address);
7166
- const usdcCoins = await this._fetchCoins(SUPPORTED_ASSETS.USDC.type);
7167
- if (usdcCoins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", "No USDC coins");
7168
- const merged = this._mergeCoinsInTx(tx2, usdcCoins);
7169
- const raw = BigInt(Math.floor(repayAmount * 10 ** SUPPORTED_ASSETS.USDC.decimals));
7195
+ const coins = await this._fetchCoins(targetAssetInfo.type);
7196
+ if (coins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", `No ${targetAssetInfo.displayName} coins`);
7197
+ const merged = this._mergeCoinsInTx(tx2, coins);
7198
+ const raw = BigInt(Math.floor(repayAmount * 10 ** targetAssetInfo.decimals));
7170
7199
  const [repayCoin] = tx2.splitCoins(merged, [raw]);
7171
7200
  await adapter.addRepayToTx(tx2, this._address, repayCoin, target.asset);
7172
7201
  return tx2;
@@ -7175,11 +7204,12 @@ var T2000 = class _T2000 extends EventEmitter {
7175
7204
  return tx;
7176
7205
  });
7177
7206
  const hf = await adapter.getHealth(this._address);
7178
- this.emitBalanceChange("USDC", repayAmount, "repay", gasResult.digest);
7207
+ this.emitBalanceChange(target.asset, repayAmount, "repay", gasResult.digest);
7179
7208
  return {
7180
7209
  success: true,
7181
7210
  tx: gasResult.digest,
7182
7211
  amount: repayAmount,
7212
+ asset: target.asset,
7183
7213
  remainingDebt: hf.borrowed,
7184
7214
  gasCost: gasResult.gasCostSui,
7185
7215
  gasMethod: gasResult.gasMethod
@@ -7198,15 +7228,20 @@ var T2000 = class _T2000 extends EventEmitter {
7198
7228
  if (canPTB) {
7199
7229
  const tx = new Transaction();
7200
7230
  tx.setSender(this._address);
7201
- const usdcCoins = await this._fetchCoins(SUPPORTED_ASSETS.USDC.type);
7202
- let usdcMerged;
7203
- if (usdcCoins.length > 0) {
7204
- usdcMerged = this._mergeCoinsInTx(tx, usdcCoins);
7231
+ const assetMerged = /* @__PURE__ */ new Map();
7232
+ const uniqueAssets = Array.from(new Set(entries.map((e) => e.borrow.asset)));
7233
+ for (const asset of uniqueAssets) {
7234
+ const info = SUPPORTED_ASSETS[asset];
7235
+ if (!info) throw new T2000Error("ASSET_NOT_SUPPORTED", `Cannot repay unknown asset: ${asset}`);
7236
+ const coins = await this._fetchCoins(info.type);
7237
+ if (coins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", `No ${info.displayName} coins for repayment`);
7238
+ assetMerged.set(asset, this._mergeCoinsInTx(tx, coins));
7205
7239
  }
7206
7240
  for (const { borrow, adapter } of entries) {
7207
- const raw = BigInt(Math.floor(borrow.amount * 10 ** SUPPORTED_ASSETS.USDC.decimals));
7208
- if (!usdcMerged) throw new T2000Error("INSUFFICIENT_BALANCE", "No USDC for repayment");
7209
- const [repayCoin] = tx.splitCoins(usdcMerged, [raw]);
7241
+ const info = SUPPORTED_ASSETS[borrow.asset];
7242
+ const merged = assetMerged.get(borrow.asset);
7243
+ const raw = BigInt(Math.floor(borrow.amount * 10 ** info.decimals));
7244
+ const [repayCoin] = tx.splitCoins(merged, [raw]);
7210
7245
  await adapter.addRepayToTx(tx, this._address, repayCoin, borrow.asset);
7211
7246
  totalRepaid += borrow.amount;
7212
7247
  }
@@ -7222,11 +7257,13 @@ var T2000 = class _T2000 extends EventEmitter {
7222
7257
  });
7223
7258
  const firstAdapter = entries[0]?.adapter;
7224
7259
  const hf = firstAdapter ? await firstAdapter.getHealth(this._address) : { borrowed: 0 };
7225
- this.emitBalanceChange("USDC", totalRepaid, "repay", gasResult.digest);
7260
+ const dominantAsset = entries.reduce((acc, e) => acc.amount >= e.borrow.amount ? acc : e.borrow, entries[0]?.borrow ?? { asset: "USDC", amount: 0 }).asset;
7261
+ this.emitBalanceChange(dominantAsset, totalRepaid, "repay", gasResult.digest);
7226
7262
  return {
7227
7263
  success: true,
7228
7264
  tx: gasResult.digest,
7229
7265
  amount: totalRepaid,
7266
+ asset: dominantAsset,
7230
7267
  remainingDebt: hf.borrowed,
7231
7268
  gasCost: gasResult.gasCostSui,
7232
7269
  gasMethod: gasResult.gasMethod