@t2000/sdk 0.11.1 → 0.13.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.d.cts CHANGED
@@ -1,11 +1,11 @@
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 T2000Options, S as SendResult, B as BalanceResponse, a as TransactionRecord, D as DepositInfo, L as LendingAdapter, b as SwapAdapter, c as SaveResult, W as WithdrawResult, M as MaxWithdrawResult, d as BorrowResult, R as RepayResult, e as MaxBorrowResult, H as HealthFactorResult, f as SwapResult, P as PositionsResult, g as RatesResult, h as LendingRates, i as RebalanceResult, E as EarningsResult, F as FundStatusResult, j as SentinelAgent, k as SentinelAttackResult, G as GasMethod } from './index-UOQejD-B.cjs';
5
- export { A as AdapterCapability, l as AdapterPositions, m as AdapterTxResult, n as AssetRates, C as CetusAdapter, o as GasReserve, p as HealthInfo, N as NaviAdapter, q as PositionEntry, r as ProtocolDescriptor, s as ProtocolRegistry, t as RebalanceStep, u as SentinelVerdict, v as SuilendAdapter, w as SwapQuote, x as allDescriptors, y as cetusDescriptor, z as getSentinelInfo, I as listSentinels, J as naviDescriptor, K as requestAttack, O as sentinelAttack, Q as sentinelDescriptor, U as settleAttack, V as submitPrompt, X as suilendDescriptor } from './index-UOQejD-B.cjs';
4
+ import { T as T2000Options, S as SendResult, B as BalanceResponse, a as TransactionRecord, D as DepositInfo, L as LendingAdapter, b as SwapAdapter, c as SaveResult, W as WithdrawResult, M as MaxWithdrawResult, d as BorrowResult, R as RepayResult, e as MaxBorrowResult, H as HealthFactorResult, f as SwapResult, P as PositionsResult, g as RatesResult, h as LendingRates, i as RebalanceResult, E as EarningsResult, F as FundStatusResult, j as SentinelAgent, k as SentinelAttackResult, G as GasMethod } from './index-Dd4EvUGr.cjs';
5
+ export { A as AdapterCapability, l as AdapterPositions, m as AdapterTxResult, n as AssetRates, C as CetusAdapter, o as GasReserve, p as HealthInfo, N as NaviAdapter, q as PositionEntry, r as ProtocolDescriptor, s as ProtocolRegistry, t as RebalanceStep, u as SentinelVerdict, v as SuilendAdapter, w as SwapQuote, x as allDescriptors, y as cetusDescriptor, z as getSentinelInfo, I as listSentinels, J as naviDescriptor, K as requestAttack, O as sentinelAttack, Q as sentinelDescriptor, U as settleAttack, V as submitPrompt, X as suilendDescriptor } from './index-Dd4EvUGr.cjs';
6
6
  import { Transaction, TransactionObjectArgument } from '@mysten/sui/transactions';
7
7
 
8
- type T2000ErrorCode = 'INSUFFICIENT_BALANCE' | 'INSUFFICIENT_GAS' | 'INVALID_ADDRESS' | 'INVALID_AMOUNT' | 'WALLET_NOT_FOUND' | 'WALLET_LOCKED' | 'WALLET_EXISTS' | 'SPONSOR_FAILED' | 'SPONSOR_RATE_LIMITED' | 'GAS_STATION_UNAVAILABLE' | 'GAS_FEE_EXCEEDED' | 'SIMULATION_FAILED' | 'TRANSACTION_FAILED' | 'ASSET_NOT_SUPPORTED' | 'SWAP_FAILED' | 'SLIPPAGE_EXCEEDED' | 'HEALTH_FACTOR_TOO_LOW' | 'WITHDRAW_WOULD_LIQUIDATE' | 'NO_COLLATERAL' | 'PROTOCOL_PAUSED' | 'PROTOCOL_UNAVAILABLE' | 'RPC_ERROR' | 'RPC_UNREACHABLE' | 'SPONSOR_UNAVAILABLE' | 'AUTO_TOPUP_FAILED' | 'PRICE_EXCEEDS_LIMIT' | 'UNSUPPORTED_NETWORK' | 'PAYMENT_EXPIRED' | 'DUPLICATE_PAYMENT' | 'FACILITATOR_REJECTION' | 'FACILITATOR_TIMEOUT' | 'SENTINEL_API_ERROR' | 'SENTINEL_NOT_FOUND' | 'SENTINEL_TX_FAILED' | 'SENTINEL_TEE_ERROR' | 'SAFEGUARD_BLOCKED' | 'UNKNOWN';
8
+ type T2000ErrorCode = 'INSUFFICIENT_BALANCE' | 'INSUFFICIENT_GAS' | 'INVALID_ADDRESS' | 'INVALID_AMOUNT' | 'WALLET_NOT_FOUND' | 'WALLET_LOCKED' | 'WALLET_EXISTS' | 'SPONSOR_FAILED' | 'SPONSOR_RATE_LIMITED' | 'GAS_STATION_UNAVAILABLE' | 'GAS_FEE_EXCEEDED' | 'SIMULATION_FAILED' | 'TRANSACTION_FAILED' | 'ASSET_NOT_SUPPORTED' | 'SWAP_FAILED' | 'SLIPPAGE_EXCEEDED' | 'HEALTH_FACTOR_TOO_LOW' | 'WITHDRAW_WOULD_LIQUIDATE' | 'NO_COLLATERAL' | 'PROTOCOL_PAUSED' | 'PROTOCOL_UNAVAILABLE' | 'RPC_ERROR' | 'RPC_UNREACHABLE' | 'SPONSOR_UNAVAILABLE' | 'AUTO_TOPUP_FAILED' | 'PRICE_EXCEEDS_LIMIT' | 'UNSUPPORTED_NETWORK' | 'PAYMENT_EXPIRED' | 'DUPLICATE_PAYMENT' | 'FACILITATOR_REJECTION' | 'CONTACT_NOT_FOUND' | 'INVALID_CONTACT_NAME' | 'FACILITATOR_TIMEOUT' | 'SENTINEL_API_ERROR' | 'SENTINEL_NOT_FOUND' | 'SENTINEL_TX_FAILED' | 'SENTINEL_TEE_ERROR' | 'SAFEGUARD_BLOCKED' | 'UNKNOWN';
9
9
  interface T2000ErrorData {
10
10
  reason?: string;
11
11
  [key: string]: unknown;
@@ -56,6 +56,31 @@ declare class SafeguardEnforcer {
56
56
  private save;
57
57
  }
58
58
 
59
+ interface Contact {
60
+ name: string;
61
+ address: string;
62
+ }
63
+ type ContactMap = Record<string, Contact>;
64
+ declare class ContactManager {
65
+ private contacts;
66
+ private readonly filePath;
67
+ private readonly dir;
68
+ constructor(configDir?: string);
69
+ private load;
70
+ private save;
71
+ add(name: string, address: string): {
72
+ action: 'added' | 'updated';
73
+ };
74
+ remove(name: string): boolean;
75
+ get(name: string): Contact | undefined;
76
+ list(): Contact[];
77
+ resolve(nameOrAddress: string): {
78
+ address: string;
79
+ contactName?: string;
80
+ };
81
+ private validateName;
82
+ }
83
+
59
84
  interface T2000Events {
60
85
  balanceChange: (event: {
61
86
  asset: string;
@@ -97,6 +122,7 @@ declare class T2000 extends EventEmitter<T2000Events> {
97
122
  private readonly _address;
98
123
  private readonly registry;
99
124
  readonly enforcer: SafeguardEnforcer;
125
+ readonly contacts: ContactManager;
100
126
  private constructor();
101
127
  private static createDefaultRegistry;
102
128
  static create(options?: T2000Options): Promise<T2000>;
@@ -375,4 +401,4 @@ interface GasStatusResponse {
375
401
  }
376
402
  declare function getGasStatus(address?: string): Promise<GasStatusResponse>;
377
403
 
378
- export { type AutoTopUpResult, BPS_DENOMINATOR, BalanceResponse, BorrowResult, CLOCK_ID, DEFAULT_NETWORK, DEFAULT_SAFEGUARD_CONFIG, DepositInfo, EarningsResult, type FeeOperation, FundStatusResult, type GasExecutionResult, GasMethod, type GasRequestType, type GasSponsorResponse, type GasStatusResponse, HealthFactorResult, LendingAdapter, LendingRates, MIST_PER_SUI, MaxBorrowResult, MaxWithdrawResult, OUTBOUND_OPS, PositionsResult, type ProtocolFeeInfo, RatesResult, RebalanceResult, RepayResult, SENTINEL, SUI_DECIMALS, SUPPORTED_ASSETS, type SafeguardConfig, SafeguardEnforcer, SafeguardError, type SafeguardErrorDetails, type SafeguardRule, SaveResult, SendResult, SentinelAgent, SentinelAttackResult, type SimulationResult, type SupportedAsset, SwapAdapter, SwapResult, T2000, T2000Error, type T2000ErrorCode, type T2000ErrorData, T2000Options, TransactionRecord, type TxMetadata, USDC_DECIMALS, WithdrawResult, addCollectFeeToTx, calculateFee, executeAutoTopUp, executeWithGas, exportPrivateKey, formatSui, formatUsd, generateKeypair, getAddress, getDecimals, getGasStatus, getPoolPrice, getRates, keypairFromPrivateKey, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, rawToStable, rawToUsdc, saveKey, shouldAutoTopUp, simulateTransaction, solveHashcash, stableToRaw, suiToMist, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, walletExists };
404
+ export { type AutoTopUpResult, BPS_DENOMINATOR, BalanceResponse, BorrowResult, CLOCK_ID, type Contact, ContactManager, type ContactMap, DEFAULT_NETWORK, DEFAULT_SAFEGUARD_CONFIG, DepositInfo, EarningsResult, type FeeOperation, FundStatusResult, type GasExecutionResult, GasMethod, type GasRequestType, type GasSponsorResponse, type GasStatusResponse, HealthFactorResult, LendingAdapter, LendingRates, MIST_PER_SUI, MaxBorrowResult, MaxWithdrawResult, OUTBOUND_OPS, PositionsResult, type ProtocolFeeInfo, RatesResult, RebalanceResult, RepayResult, SENTINEL, SUI_DECIMALS, SUPPORTED_ASSETS, type SafeguardConfig, SafeguardEnforcer, SafeguardError, type SafeguardErrorDetails, type SafeguardRule, SaveResult, SendResult, SentinelAgent, SentinelAttackResult, type SimulationResult, type SupportedAsset, SwapAdapter, SwapResult, T2000, T2000Error, type T2000ErrorCode, type T2000ErrorData, T2000Options, TransactionRecord, type TxMetadata, USDC_DECIMALS, WithdrawResult, addCollectFeeToTx, calculateFee, executeAutoTopUp, executeWithGas, exportPrivateKey, formatSui, formatUsd, generateKeypair, getAddress, getDecimals, getGasStatus, getPoolPrice, getRates, keypairFromPrivateKey, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, rawToStable, rawToUsdc, saveKey, shouldAutoTopUp, simulateTransaction, solveHashcash, stableToRaw, suiToMist, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, walletExists };
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
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 T2000Options, S as SendResult, B as BalanceResponse, a as TransactionRecord, D as DepositInfo, L as LendingAdapter, b as SwapAdapter, c as SaveResult, W as WithdrawResult, M as MaxWithdrawResult, d as BorrowResult, R as RepayResult, e as MaxBorrowResult, H as HealthFactorResult, f as SwapResult, P as PositionsResult, g as RatesResult, h as LendingRates, i as RebalanceResult, E as EarningsResult, F as FundStatusResult, j as SentinelAgent, k as SentinelAttackResult, G as GasMethod } from './index-UOQejD-B.js';
5
- export { A as AdapterCapability, l as AdapterPositions, m as AdapterTxResult, n as AssetRates, C as CetusAdapter, o as GasReserve, p as HealthInfo, N as NaviAdapter, q as PositionEntry, r as ProtocolDescriptor, s as ProtocolRegistry, t as RebalanceStep, u as SentinelVerdict, v as SuilendAdapter, w as SwapQuote, x as allDescriptors, y as cetusDescriptor, z as getSentinelInfo, I as listSentinels, J as naviDescriptor, K as requestAttack, O as sentinelAttack, Q as sentinelDescriptor, U as settleAttack, V as submitPrompt, X as suilendDescriptor } from './index-UOQejD-B.js';
4
+ import { T as T2000Options, S as SendResult, B as BalanceResponse, a as TransactionRecord, D as DepositInfo, L as LendingAdapter, b as SwapAdapter, c as SaveResult, W as WithdrawResult, M as MaxWithdrawResult, d as BorrowResult, R as RepayResult, e as MaxBorrowResult, H as HealthFactorResult, f as SwapResult, P as PositionsResult, g as RatesResult, h as LendingRates, i as RebalanceResult, E as EarningsResult, F as FundStatusResult, j as SentinelAgent, k as SentinelAttackResult, G as GasMethod } from './index-Dd4EvUGr.js';
5
+ export { A as AdapterCapability, l as AdapterPositions, m as AdapterTxResult, n as AssetRates, C as CetusAdapter, o as GasReserve, p as HealthInfo, N as NaviAdapter, q as PositionEntry, r as ProtocolDescriptor, s as ProtocolRegistry, t as RebalanceStep, u as SentinelVerdict, v as SuilendAdapter, w as SwapQuote, x as allDescriptors, y as cetusDescriptor, z as getSentinelInfo, I as listSentinels, J as naviDescriptor, K as requestAttack, O as sentinelAttack, Q as sentinelDescriptor, U as settleAttack, V as submitPrompt, X as suilendDescriptor } from './index-Dd4EvUGr.js';
6
6
  import { Transaction, TransactionObjectArgument } from '@mysten/sui/transactions';
7
7
 
8
- type T2000ErrorCode = 'INSUFFICIENT_BALANCE' | 'INSUFFICIENT_GAS' | 'INVALID_ADDRESS' | 'INVALID_AMOUNT' | 'WALLET_NOT_FOUND' | 'WALLET_LOCKED' | 'WALLET_EXISTS' | 'SPONSOR_FAILED' | 'SPONSOR_RATE_LIMITED' | 'GAS_STATION_UNAVAILABLE' | 'GAS_FEE_EXCEEDED' | 'SIMULATION_FAILED' | 'TRANSACTION_FAILED' | 'ASSET_NOT_SUPPORTED' | 'SWAP_FAILED' | 'SLIPPAGE_EXCEEDED' | 'HEALTH_FACTOR_TOO_LOW' | 'WITHDRAW_WOULD_LIQUIDATE' | 'NO_COLLATERAL' | 'PROTOCOL_PAUSED' | 'PROTOCOL_UNAVAILABLE' | 'RPC_ERROR' | 'RPC_UNREACHABLE' | 'SPONSOR_UNAVAILABLE' | 'AUTO_TOPUP_FAILED' | 'PRICE_EXCEEDS_LIMIT' | 'UNSUPPORTED_NETWORK' | 'PAYMENT_EXPIRED' | 'DUPLICATE_PAYMENT' | 'FACILITATOR_REJECTION' | 'FACILITATOR_TIMEOUT' | 'SENTINEL_API_ERROR' | 'SENTINEL_NOT_FOUND' | 'SENTINEL_TX_FAILED' | 'SENTINEL_TEE_ERROR' | 'SAFEGUARD_BLOCKED' | 'UNKNOWN';
8
+ type T2000ErrorCode = 'INSUFFICIENT_BALANCE' | 'INSUFFICIENT_GAS' | 'INVALID_ADDRESS' | 'INVALID_AMOUNT' | 'WALLET_NOT_FOUND' | 'WALLET_LOCKED' | 'WALLET_EXISTS' | 'SPONSOR_FAILED' | 'SPONSOR_RATE_LIMITED' | 'GAS_STATION_UNAVAILABLE' | 'GAS_FEE_EXCEEDED' | 'SIMULATION_FAILED' | 'TRANSACTION_FAILED' | 'ASSET_NOT_SUPPORTED' | 'SWAP_FAILED' | 'SLIPPAGE_EXCEEDED' | 'HEALTH_FACTOR_TOO_LOW' | 'WITHDRAW_WOULD_LIQUIDATE' | 'NO_COLLATERAL' | 'PROTOCOL_PAUSED' | 'PROTOCOL_UNAVAILABLE' | 'RPC_ERROR' | 'RPC_UNREACHABLE' | 'SPONSOR_UNAVAILABLE' | 'AUTO_TOPUP_FAILED' | 'PRICE_EXCEEDS_LIMIT' | 'UNSUPPORTED_NETWORK' | 'PAYMENT_EXPIRED' | 'DUPLICATE_PAYMENT' | 'FACILITATOR_REJECTION' | 'CONTACT_NOT_FOUND' | 'INVALID_CONTACT_NAME' | 'FACILITATOR_TIMEOUT' | 'SENTINEL_API_ERROR' | 'SENTINEL_NOT_FOUND' | 'SENTINEL_TX_FAILED' | 'SENTINEL_TEE_ERROR' | 'SAFEGUARD_BLOCKED' | 'UNKNOWN';
9
9
  interface T2000ErrorData {
10
10
  reason?: string;
11
11
  [key: string]: unknown;
@@ -56,6 +56,31 @@ declare class SafeguardEnforcer {
56
56
  private save;
57
57
  }
58
58
 
59
+ interface Contact {
60
+ name: string;
61
+ address: string;
62
+ }
63
+ type ContactMap = Record<string, Contact>;
64
+ declare class ContactManager {
65
+ private contacts;
66
+ private readonly filePath;
67
+ private readonly dir;
68
+ constructor(configDir?: string);
69
+ private load;
70
+ private save;
71
+ add(name: string, address: string): {
72
+ action: 'added' | 'updated';
73
+ };
74
+ remove(name: string): boolean;
75
+ get(name: string): Contact | undefined;
76
+ list(): Contact[];
77
+ resolve(nameOrAddress: string): {
78
+ address: string;
79
+ contactName?: string;
80
+ };
81
+ private validateName;
82
+ }
83
+
59
84
  interface T2000Events {
60
85
  balanceChange: (event: {
61
86
  asset: string;
@@ -97,6 +122,7 @@ declare class T2000 extends EventEmitter<T2000Events> {
97
122
  private readonly _address;
98
123
  private readonly registry;
99
124
  readonly enforcer: SafeguardEnforcer;
125
+ readonly contacts: ContactManager;
100
126
  private constructor();
101
127
  private static createDefaultRegistry;
102
128
  static create(options?: T2000Options): Promise<T2000>;
@@ -375,4 +401,4 @@ interface GasStatusResponse {
375
401
  }
376
402
  declare function getGasStatus(address?: string): Promise<GasStatusResponse>;
377
403
 
378
- export { type AutoTopUpResult, BPS_DENOMINATOR, BalanceResponse, BorrowResult, CLOCK_ID, DEFAULT_NETWORK, DEFAULT_SAFEGUARD_CONFIG, DepositInfo, EarningsResult, type FeeOperation, FundStatusResult, type GasExecutionResult, GasMethod, type GasRequestType, type GasSponsorResponse, type GasStatusResponse, HealthFactorResult, LendingAdapter, LendingRates, MIST_PER_SUI, MaxBorrowResult, MaxWithdrawResult, OUTBOUND_OPS, PositionsResult, type ProtocolFeeInfo, RatesResult, RebalanceResult, RepayResult, SENTINEL, SUI_DECIMALS, SUPPORTED_ASSETS, type SafeguardConfig, SafeguardEnforcer, SafeguardError, type SafeguardErrorDetails, type SafeguardRule, SaveResult, SendResult, SentinelAgent, SentinelAttackResult, type SimulationResult, type SupportedAsset, SwapAdapter, SwapResult, T2000, T2000Error, type T2000ErrorCode, type T2000ErrorData, T2000Options, TransactionRecord, type TxMetadata, USDC_DECIMALS, WithdrawResult, addCollectFeeToTx, calculateFee, executeAutoTopUp, executeWithGas, exportPrivateKey, formatSui, formatUsd, generateKeypair, getAddress, getDecimals, getGasStatus, getPoolPrice, getRates, keypairFromPrivateKey, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, rawToStable, rawToUsdc, saveKey, shouldAutoTopUp, simulateTransaction, solveHashcash, stableToRaw, suiToMist, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, walletExists };
404
+ export { type AutoTopUpResult, BPS_DENOMINATOR, BalanceResponse, BorrowResult, CLOCK_ID, type Contact, ContactManager, type ContactMap, DEFAULT_NETWORK, DEFAULT_SAFEGUARD_CONFIG, DepositInfo, EarningsResult, type FeeOperation, FundStatusResult, type GasExecutionResult, GasMethod, type GasRequestType, type GasSponsorResponse, type GasStatusResponse, HealthFactorResult, LendingAdapter, LendingRates, MIST_PER_SUI, MaxBorrowResult, MaxWithdrawResult, OUTBOUND_OPS, PositionsResult, type ProtocolFeeInfo, RatesResult, RebalanceResult, RepayResult, SENTINEL, SUI_DECIMALS, SUPPORTED_ASSETS, type SafeguardConfig, SafeguardEnforcer, SafeguardError, type SafeguardErrorDetails, type SafeguardRule, SaveResult, SendResult, SentinelAgent, SentinelAttackResult, type SimulationResult, type SupportedAsset, SwapAdapter, SwapResult, T2000, T2000Error, type T2000ErrorCode, type T2000ErrorData, T2000Options, TransactionRecord, type TxMetadata, USDC_DECIMALS, WithdrawResult, addCollectFeeToTx, calculateFee, executeAutoTopUp, executeWithGas, exportPrivateKey, formatSui, formatUsd, generateKeypair, getAddress, getDecimals, getGasStatus, getPoolPrice, getRates, keypairFromPrivateKey, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, rawToStable, rawToUsdc, saveKey, shouldAutoTopUp, simulateTransaction, solveHashcash, stableToRaw, suiToMist, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, walletExists };
package/dist/index.js CHANGED
@@ -403,6 +403,7 @@ async function queryBalance(client, address) {
403
403
  return {
404
404
  available: totalStables,
405
405
  savings,
406
+ debt: 0,
406
407
  gasReserve: {
407
408
  sui: suiAmount,
408
409
  usdEquiv
@@ -2696,6 +2697,83 @@ var SafeguardEnforcer = class {
2696
2697
  }
2697
2698
  }
2698
2699
  };
2700
+ var RESERVED_NAMES = /* @__PURE__ */ new Set(["to", "all", "address"]);
2701
+ var ContactManager = class {
2702
+ contacts = {};
2703
+ filePath;
2704
+ dir;
2705
+ constructor(configDir) {
2706
+ this.dir = configDir ?? join(homedir(), ".t2000");
2707
+ this.filePath = join(this.dir, "contacts.json");
2708
+ this.load();
2709
+ }
2710
+ load() {
2711
+ try {
2712
+ if (existsSync(this.filePath)) {
2713
+ this.contacts = JSON.parse(readFileSync(this.filePath, "utf-8"));
2714
+ }
2715
+ } catch {
2716
+ this.contacts = {};
2717
+ }
2718
+ }
2719
+ save() {
2720
+ if (!existsSync(this.dir)) mkdirSync(this.dir, { recursive: true });
2721
+ writeFileSync(this.filePath, JSON.stringify(this.contacts, null, 2));
2722
+ }
2723
+ add(name, address) {
2724
+ this.validateName(name);
2725
+ const normalized = validateAddress(address);
2726
+ const key = name.toLowerCase();
2727
+ const existed = key in this.contacts;
2728
+ this.contacts[key] = { name, address: normalized };
2729
+ this.save();
2730
+ return { action: existed ? "updated" : "added" };
2731
+ }
2732
+ remove(name) {
2733
+ const key = name.toLowerCase();
2734
+ if (!(key in this.contacts)) return false;
2735
+ delete this.contacts[key];
2736
+ this.save();
2737
+ return true;
2738
+ }
2739
+ get(name) {
2740
+ this.load();
2741
+ return this.contacts[name.toLowerCase()];
2742
+ }
2743
+ list() {
2744
+ this.load();
2745
+ return Object.values(this.contacts);
2746
+ }
2747
+ resolve(nameOrAddress) {
2748
+ this.load();
2749
+ if (nameOrAddress.startsWith("0x") && nameOrAddress.length >= 42) {
2750
+ return { address: validateAddress(nameOrAddress) };
2751
+ }
2752
+ const contact = this.contacts[nameOrAddress.toLowerCase()];
2753
+ if (contact) {
2754
+ return { address: contact.address, contactName: contact.name };
2755
+ }
2756
+ throw new T2000Error(
2757
+ "CONTACT_NOT_FOUND",
2758
+ `"${nameOrAddress}" is not a valid Sui address or saved contact.
2759
+ Add it: t2000 contacts add ${nameOrAddress} 0x...`
2760
+ );
2761
+ }
2762
+ validateName(name) {
2763
+ if (name.startsWith("0x")) {
2764
+ throw new T2000Error("INVALID_CONTACT_NAME", "Contact names cannot start with 0x");
2765
+ }
2766
+ if (!/^[a-zA-Z0-9_]+$/.test(name)) {
2767
+ throw new T2000Error("INVALID_CONTACT_NAME", "Contact names can only contain letters, numbers, and underscores");
2768
+ }
2769
+ if (name.length > 32) {
2770
+ throw new T2000Error("INVALID_CONTACT_NAME", "Contact names must be 32 characters or fewer");
2771
+ }
2772
+ if (RESERVED_NAMES.has(name.toLowerCase())) {
2773
+ throw new T2000Error("INVALID_CONTACT_NAME", `"${name}" is a reserved name and cannot be used as a contact`);
2774
+ }
2775
+ }
2776
+ };
2699
2777
  var DEFAULT_CONFIG_DIR = join(homedir(), ".t2000");
2700
2778
  var T2000 = class _T2000 extends EventEmitter {
2701
2779
  keypair;
@@ -2703,6 +2781,7 @@ var T2000 = class _T2000 extends EventEmitter {
2703
2781
  _address;
2704
2782
  registry;
2705
2783
  enforcer;
2784
+ contacts;
2706
2785
  constructor(keypair, client, registry, configDir) {
2707
2786
  super();
2708
2787
  this.keypair = keypair;
@@ -2711,6 +2790,7 @@ var T2000 = class _T2000 extends EventEmitter {
2711
2790
  this.registry = registry ?? _T2000.createDefaultRegistry(client);
2712
2791
  this.enforcer = new SafeguardEnforcer(configDir);
2713
2792
  this.enforcer.load();
2793
+ this.contacts = new ContactManager(configDir);
2714
2794
  }
2715
2795
  static createDefaultRegistry(client) {
2716
2796
  const registry = new ProtocolRegistry();
@@ -2790,8 +2870,9 @@ var T2000 = class _T2000 extends EventEmitter {
2790
2870
  if (!(asset in SUPPORTED_ASSETS)) {
2791
2871
  throw new T2000Error("ASSET_NOT_SUPPORTED", `Asset ${asset} is not supported`);
2792
2872
  }
2873
+ const resolved = this.contacts.resolve(params.to);
2793
2874
  const sendAmount = params.amount;
2794
- const sendTo = params.to;
2875
+ const sendTo = resolved.address;
2795
2876
  const gasResult = await executeWithGas(
2796
2877
  this.client,
2797
2878
  this.keypair,
@@ -2805,7 +2886,8 @@ var T2000 = class _T2000 extends EventEmitter {
2805
2886
  success: true,
2806
2887
  tx: gasResult.digest,
2807
2888
  amount: sendAmount,
2808
- to: params.to,
2889
+ to: resolved.address,
2890
+ contactName: resolved.contactName,
2809
2891
  gasCost: gasResult.gasCostSui,
2810
2892
  gasCostUnit: "SUI",
2811
2893
  gasMethod: gasResult.gasMethod,
@@ -2817,8 +2899,10 @@ var T2000 = class _T2000 extends EventEmitter {
2817
2899
  try {
2818
2900
  const positions = await this.positions();
2819
2901
  const savings = positions.positions.filter((p) => p.type === "save").reduce((sum, p) => sum + p.amount, 0);
2902
+ const debt = positions.positions.filter((p) => p.type === "borrow").reduce((sum, p) => sum + p.amount, 0);
2820
2903
  bal.savings = savings;
2821
- bal.total = bal.available + savings + bal.gasReserve.usdEquiv;
2904
+ bal.debt = debt;
2905
+ bal.total = bal.available + savings - debt + bal.gasReserve.usdEquiv;
2822
2906
  } catch {
2823
2907
  }
2824
2908
  return bal;
@@ -3909,6 +3993,6 @@ var allDescriptors = [
3909
3993
  descriptor
3910
3994
  ];
3911
3995
 
3912
- export { BPS_DENOMINATOR, CLOCK_ID, CetusAdapter, DEFAULT_NETWORK, DEFAULT_SAFEGUARD_CONFIG, MIST_PER_SUI, NaviAdapter, OUTBOUND_OPS, ProtocolRegistry, SENTINEL, SUI_DECIMALS, SUPPORTED_ASSETS, SafeguardEnforcer, SafeguardError, SuilendAdapter, T2000, T2000Error, USDC_DECIMALS, addCollectFeeToTx, allDescriptors, calculateFee, descriptor3 as cetusDescriptor, executeAutoTopUp, executeWithGas, exportPrivateKey, formatSui, formatUsd, generateKeypair, getAddress, getDecimals, getGasStatus, getPoolPrice, getRates, getSentinelInfo, keypairFromPrivateKey, listSentinels, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, descriptor2 as naviDescriptor, rawToStable, rawToUsdc, requestAttack, saveKey, attack as sentinelAttack, descriptor as sentinelDescriptor, settleAttack, shouldAutoTopUp, simulateTransaction, solveHashcash, stableToRaw, submitPrompt, suiToMist, descriptor4 as suilendDescriptor, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, walletExists };
3996
+ export { BPS_DENOMINATOR, CLOCK_ID, CetusAdapter, ContactManager, DEFAULT_NETWORK, DEFAULT_SAFEGUARD_CONFIG, MIST_PER_SUI, NaviAdapter, OUTBOUND_OPS, ProtocolRegistry, SENTINEL, SUI_DECIMALS, SUPPORTED_ASSETS, SafeguardEnforcer, SafeguardError, SuilendAdapter, T2000, T2000Error, USDC_DECIMALS, addCollectFeeToTx, allDescriptors, calculateFee, descriptor3 as cetusDescriptor, executeAutoTopUp, executeWithGas, exportPrivateKey, formatSui, formatUsd, generateKeypair, getAddress, getDecimals, getGasStatus, getPoolPrice, getRates, getSentinelInfo, keypairFromPrivateKey, listSentinels, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, descriptor2 as naviDescriptor, rawToStable, rawToUsdc, requestAttack, saveKey, attack as sentinelAttack, descriptor as sentinelDescriptor, settleAttack, shouldAutoTopUp, simulateTransaction, solveHashcash, stableToRaw, submitPrompt, suiToMist, descriptor4 as suilendDescriptor, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, walletExists };
3913
3997
  //# sourceMappingURL=index.js.map
3914
3998
  //# sourceMappingURL=index.js.map