@t2000/sdk 2.18.1 → 2.19.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,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 { Q as TxMetadata, o as SafeguardConfig, T as T2000Error, H as TransactionSigner, _ as ZkLoginProof, v as SupportedAsset } from './types-C2Va_r0h.cjs';
5
- export { A as ALL_NAVI_ASSETS, B as BORROW_FEE_BPS, a as BPS_DENOMINATOR, ax 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, I as IKA_TYPE, K as KNOWN_TARGETS, h as KeypairSigner, L as LABEL_PATTERNS, i as LOFI_TYPE, M as MANIFEST_TYPE, j as MIST_PER_SUI, N as NAVX_TYPE, ay as OPERATION_ASSETS, O as OUTBOUND_OPS, az as Operation, P as ProtocolFeeInfo, S as SAVE_FEE_BPS, k as STABLE_ASSETS, l as SUI_DECIMALS, m as SUI_TYPE, n as SUPPORTED_ASSETS, p as SafeguardError, q as SafeguardErrorDetails, r as SafeguardRule, s as SimulationResult, t as StableAsset, u as SuiRpcTxBlock, w as T2000ErrorCode, x as T2000ErrorData, y as T2000_OVERLAY_FEE_WALLET, z as TOKEN_MAP, J as TxDirection, U as USDC_DECIMALS, R as USDC_TYPE, V as USDE_TYPE, W as USDSUI_TYPE, X as USDT_TYPE, Y as WAL_TYPE, Z as WBTC_TYPE, $ as ZkLoginSigner, a0 as addFeeTransfer, aA as assertAllowedAsset, a1 as calculateFee, a2 as classifyAction, a3 as classifyLabel, a4 as classifyTransaction, a5 as extractAllUserLegs, a6 as extractTransferDetails, a7 as extractTxCommands, a8 as extractTxSender, a9 as fallbackLabel, aa as formatAssetAmount, ab as formatSui, ac as formatUsd, aB as getCoinMeta, ad as getDecimals, ae as getDecimalsForCoinType, af as getTier, aC as isAllowedAsset, aD as isInRegistry, ag as isSupported, ah as isTier1, ai as isTier2, aj as mapMoveAbortCode, ak as mapWalletError, al as mistToSui, aE as normalizeAsset, aF as normalizeCoinType, am as parseSuiRpcTx, aG as queryHistory, aH as queryTransaction, an as rawToStable, ao as rawToUsdc, ap as refineLendingLabel, aq as resolveSymbol, ar as resolveTokenType, aI as simulateTransaction, as as stableToRaw, at as suiToMist, aJ as throwIfSimulationFailed, au as truncateAddress, av as usdcToRaw, aw as validateAddress } from './types-C2Va_r0h.cjs';
4
+ import { Q as TxMetadata, o as SafeguardConfig, T as T2000Error, H as TransactionSigner, _ as ZkLoginProof, v as SupportedAsset } from './types-DOnXJXL2.cjs';
5
+ export { A as ALL_NAVI_ASSETS, B as BORROW_FEE_BPS, a as BPS_DENOMINATOR, ax 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, I as IKA_TYPE, K as KNOWN_TARGETS, h as KeypairSigner, L as LABEL_PATTERNS, i as LOFI_TYPE, M as MANIFEST_TYPE, j as MIST_PER_SUI, N as NAVX_TYPE, ay as OPERATION_ASSETS, O as OUTBOUND_OPS, az as Operation, P as ProtocolFeeInfo, S as SAVE_FEE_BPS, k as STABLE_ASSETS, l as SUI_DECIMALS, m as SUI_TYPE, n as SUPPORTED_ASSETS, p as SafeguardError, q as SafeguardErrorDetails, r as SafeguardRule, s as SimulationResult, t as StableAsset, u as SuiRpcTxBlock, w as T2000ErrorCode, x as T2000ErrorData, y as T2000_OVERLAY_FEE_WALLET, z as TOKEN_MAP, J as TxDirection, U as USDC_DECIMALS, R as USDC_TYPE, V as USDE_TYPE, W as USDSUI_TYPE, X as USDT_TYPE, Y as WAL_TYPE, Z as WBTC_TYPE, $ as ZkLoginSigner, a0 as addFeeTransfer, aA as assertAllowedAsset, a1 as calculateFee, a2 as classifyAction, a3 as classifyLabel, a4 as classifyTransaction, a5 as extractAllUserLegs, a6 as extractTransferDetails, a7 as extractTxCommands, a8 as extractTxSender, a9 as fallbackLabel, aa as formatAssetAmount, ab as formatSui, ac as formatUsd, aB as getCoinMeta, ad as getDecimals, ae as getDecimalsForCoinType, af as getTier, aC as isAllowedAsset, aD as isInRegistry, ag as isSupported, ah as isTier1, ai as isTier2, aj as mapMoveAbortCode, ak as mapWalletError, al as mistToSui, aE as normalizeAsset, aF as normalizeCoinType, am as parseSuiRpcTx, aG as queryHistory, aH as queryTransaction, an as rawToStable, ao as rawToUsdc, ap as refineLendingLabel, aq as resolveSymbol, ar as resolveTokenType, aI as simulateTransaction, as as stableToRaw, at as suiToMist, aJ as throwIfSimulationFailed, au as truncateAddress, av as usdcToRaw, aw as validateAddress } from './types-DOnXJXL2.cjs';
6
6
  import { L as LendingAdapter, a as LendingRates, P as PendingReward$1 } from './descriptors-DqIb4AnV.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-DqIb4AnV.cjs';
8
- import { n as T2000Options, P as PayOptions, d as PayResult, o as StakeVSuiResult, U as UnstakeVSuiResult, p as SwapResult, q as SwapQuoteResult, i as SendResult, B as BalanceResponse, k as TransactionRecord, D as DepositInfo, r as PaymentRequest, S as SaveResult, W as WithdrawResult, b as MaxWithdrawResult, a as BorrowResult, h as RepayResult, M as MaxBorrowResult, H as HealthFactorResult, e as PendingReward, C as ClaimRewardsResult, s as CompoundRewardsResult, g as PositionsResult, R as RatesResult, E as EarningsResult, F as FundStatusResult, c as OverlayFeeConfig, j as SwapRouteResult, t as FinancialSummary } from './types-I7U99DvG.cjs';
9
- export { A as AssetRates, G as GasReserve, u as HFAlertLevel, O as OVERLAY_FEE_RATE, f as PositionEntry, v as SerializedCetusRoute, w as SerializedCetusRoutePath, x as SerializedRouterDataV3, T as TransactionLeg, y as addSwapToTx, l as buildSwapTx, z as deserializeCetusRoute, m as findSwapRoute, I as isCetusRouteFresh, J as serializeCetusRoute, K as verifyCetusRouteCoinMatch } from './types-I7U99DvG.cjs';
8
+ import { n as T2000Options, P as PayOptions, d as PayResult, o as StakeVSuiResult, U as UnstakeVSuiResult, p as SwapResult, q as SwapQuoteResult, i as SendResult, B as BalanceResponse, k as TransactionRecord, D as DepositInfo, r as PaymentRequest, S as SaveResult, W as WithdrawResult, b as MaxWithdrawResult, a as BorrowResult, h as RepayResult, M as MaxBorrowResult, H as HealthFactorResult, e as PendingReward, C as ClaimRewardsResult, s as CompoundRewardsResult, g as PositionsResult, R as RatesResult, E as EarningsResult, F as FundStatusResult, c as OverlayFeeConfig, j as SwapRouteResult, t as FinancialSummary } from './types-Bk7NncQ_.cjs';
9
+ export { A as AssetRates, G as GasReserve, u as HFAlertLevel, O as OVERLAY_FEE_RATE, f as PositionEntry, v as SerializedCetusRoute, w as SerializedCetusRoutePath, x as SerializedRouterDataV3, T as TransactionLeg, y as addSwapToTx, l as buildSwapTx, z as deserializeCetusRoute, m as findSwapRoute, I as isCetusRouteFresh, J as serializeCetusRoute, K as verifyCetusRouteCoinMatch } from './types-Bk7NncQ_.cjs';
10
10
  import { Transaction, TransactionObjectArgument } from '@mysten/sui/transactions';
11
11
  import { SuinsClient } from '@mysten/suins';
12
12
  export { NaviAdapter, ProtocolRegistry } from './adapters/index.cjs';
@@ -136,6 +136,25 @@ declare class T2000 extends EventEmitter<T2000Events> {
136
136
  amount: number;
137
137
  asset?: string;
138
138
  }): Promise<SendResult>;
139
+ /**
140
+ * [S.279 / CLI-CONTACTS-CLEANUP — 2026-05-23] Resolve a recipient
141
+ * string into a canonical 0x address, trying each shape in priority
142
+ * order:
143
+ * 1. **hex** — `0x…` is used directly (no RPC round-trip).
144
+ * 2. **SuiNS** — `alex.sui` resolves via `suix_resolveNameServiceAddress`.
145
+ * 3. **saved contact** — `ContactManager.resolve()` falls back to the
146
+ * legacy `~/.t2000/contacts.json` alias map. Deprecated; the
147
+ * manager surfaces a one-time `console.warn` when this path fires.
148
+ *
149
+ * Returns `{ address, suinsName?, contactName? }` so `send()` can stamp
150
+ * the name source on the receipt without re-resolving.
151
+ *
152
+ * Throws `T2000Error('SUINS_NOT_REGISTERED', …)` for well-formed but
153
+ * unregistered SuiNS names (vs. propagating the engine-style
154
+ * `SuinsNotRegisteredError` — keeps the SDK's error surface
155
+ * `T2000Error`-only, consistent with every other write helper).
156
+ */
157
+ private resolveRecipient;
139
158
  balance(): Promise<BalanceResponse>;
140
159
  history(params?: {
141
160
  limit?: number;
@@ -223,6 +242,116 @@ declare class T2000 extends EventEmitter<T2000Events> {
223
242
  private emitBalanceChange;
224
243
  }
225
244
 
245
+ /**
246
+ * Canonical 0x-address shape. Loose lower bound (>= 1 hex char) so
247
+ * pre-v1.0 short addresses still validate; tools that need a full 64-hex
248
+ * address can additionally check `length === 66`. Case-insensitive on
249
+ * the `0x` prefix because some upstream callers (and historic tests)
250
+ * uppercase the prefix as part of address normalization tests; the
251
+ * normalizer always returns the lowercased canonical form regardless.
252
+ */
253
+ declare const SUI_ADDRESS_REGEX: RegExp;
254
+ /**
255
+ * Strict canonical 0x-address shape (66 chars total). Used by the
256
+ * resolver's "looks like" check to disambiguate "user pasted an
257
+ * address" vs "user typed a SuiNS name".
258
+ */
259
+ declare const SUI_ADDRESS_STRICT_REGEX: RegExp;
260
+ /**
261
+ * Mirrors the pattern in `audric/apps/web-v2/lib/suins-cache.ts` so the
262
+ * host-side send executor and the engine-side read normalizer agree on
263
+ * what counts as a SuiNS name. SuiNS allows nested labels (`team.alex.sui`)
264
+ * but every label must use only `[a-z0-9-]`.
265
+ */
266
+ declare const SUINS_NAME_REGEX: RegExp;
267
+ declare class InvalidAddressError extends Error {
268
+ readonly raw: string;
269
+ constructor(raw: string);
270
+ }
271
+ declare class SuinsNotRegisteredError extends Error {
272
+ readonly name_: string;
273
+ constructor(name_: string);
274
+ }
275
+ declare class SuinsRpcError extends Error {
276
+ readonly name_: string;
277
+ constructor(name_: string, detail: string);
278
+ }
279
+ /**
280
+ * Returns true if `value` looks like a SuiNS name (case-insensitive).
281
+ * Cheap synchronous check — use to avoid an unnecessary RPC round-trip
282
+ * for inputs that obviously aren't names (0x addresses, contact handles).
283
+ */
284
+ declare function looksLikeSuiNs(value: string): boolean;
285
+ /**
286
+ * Resolve a SuiNS name to its on-chain Sui address via the public
287
+ * `suix_resolveNameServiceAddress` JSON-RPC method. Returns `null` if
288
+ * the name resolves to no address (= not registered or expired). Throws
289
+ * `SuinsRpcError` on RPC/network failure.
290
+ *
291
+ * The host SHOULD pass a `rpcUrl` that includes any vendor key (e.g.
292
+ * audric's BlockVision-keyed URL) so the call benefits from the host's
293
+ * paid retry/cache budget. Falls back to the public mainnet endpoint.
294
+ */
295
+ declare function resolveSuinsViaRpc(rawName: string, ctx?: {
296
+ suiRpcUrl?: string;
297
+ signal?: AbortSignal;
298
+ }): Promise<string | null>;
299
+ /**
300
+ * Reverse-resolve a 0x address to its registered SuiNS names via
301
+ * `suix_resolveNameServiceNames`. Returns the names sorted by the
302
+ * registry (the first entry is conventionally the user's "primary"
303
+ * name on dApps that show one), or `[]` when the address has no
304
+ * SuiNS records. Throws `SuinsRpcError` on RPC/network failure.
305
+ *
306
+ * Why this is its own helper (not folded into `normalizeAddressInput`):
307
+ * a reverse lookup adds a second RPC round-trip per tool call. We don't
308
+ * want every read tool that takes an `address` to silently double its
309
+ * latency. The lookup primitive is opt-in via the `resolve_suins` tool;
310
+ * normalizers stay forward-only.
311
+ */
312
+ declare function resolveAddressToSuinsViaRpc(rawAddress: string, ctx?: {
313
+ suiRpcUrl?: string;
314
+ signal?: AbortSignal;
315
+ }): Promise<string[]>;
316
+ interface NormalizedAddress {
317
+ /**
318
+ * Canonical 0x-prefixed lowercase hex address. Always set on success.
319
+ * Tools should use this for any downstream query (BlockVision, NAVI,
320
+ * positionFetcher, etc.) and for cache keys.
321
+ */
322
+ address: string;
323
+ /**
324
+ * The user-facing name when the input was resolved via SuiNS, otherwise
325
+ * `null`. Tools should stamp this on result data so card titles can
326
+ * render "Balance · obehi.sui" instead of "Balance · 0x1234…abcd".
327
+ */
328
+ suinsName: string | null;
329
+ /**
330
+ * The original input (pre-normalization). Useful for error narration —
331
+ * "I tried to resolve `Obehi.Sui` and …" reads better than the
332
+ * post-trim/lowercase form.
333
+ */
334
+ raw: string;
335
+ }
336
+ /**
337
+ * Canonical normalizer. Accepts a 0x address OR a SuiNS name; returns
338
+ * a structured `NormalizedAddress`. Throws:
339
+ * - `InvalidAddressError` if the input matches neither shape.
340
+ * - `SuinsNotRegisteredError` if the SuiNS name is well-formed but
341
+ * resolves to null (= not registered).
342
+ * - `SuinsRpcError` if the RPC fails.
343
+ *
344
+ * Every read tool (engine) and write helper (SDK `T2000.send()`) that
345
+ * accepts a user-supplied recipient MUST call this helper before any
346
+ * downstream lookup. Doing the check inline (1) duplicates the regex,
347
+ * (2) silently rejects SuiNS names, (3) makes cache keys inconsistent
348
+ * across tools.
349
+ */
350
+ declare function normalizeAddressInput(value: string, ctx?: {
351
+ suiRpcUrl?: string;
352
+ signal?: AbortSignal;
353
+ }): Promise<NormalizedAddress>;
354
+
226
355
  declare function generateKeypair(): Ed25519Keypair;
227
356
  declare function keypairFromPrivateKey(privateKey: string): Ed25519Keypair;
228
357
  declare function saveKey(keypair: Ed25519Keypair, passphrase: string, keyPath?: string): Promise<string>;
@@ -1347,4 +1476,4 @@ declare function fullHandle(label: string): string;
1347
1476
  */
1348
1477
  declare function displayHandle(label: string): string;
1349
1478
 
1350
- export { AUDRIC_PARENT_NAME, AUDRIC_PARENT_NFT_ID, type AppenderContext, BalanceResponse, type BorrowInput, BorrowResult, type BuildAddLeafParams, type BuildHarvestRewardsTxOptions, type BuildRevokeLeafParams, type ClaimRewardsInput, ClaimRewardsResult, type CoinPage, type ComposeTxFeeHookContext, type ComposeTxFeeHooks, type ComposeTxOptions, type ComposeTxResult, CompoundRewardsResult, ContactManager, DepositInfo, EarningsResult, FinancialSummary, type FinancialSummaryOptions, FundStatusResult, HF_CRITICAL_THRESHOLD, HF_WARN_THRESHOLD, type HarvestPlan, type HarvestSkippedLeg, type HarvestSwapLeg, HealthFactorResult, type LabelValidationResult, LendingAdapter, LendingRates, MaxBorrowResult, MaxWithdrawResult, OverlayFeeConfig, PayOptions, PayResult, PaymentRequest, PendingReward, PositionsResult, RatesResult, type RepayDebtInput, RepayResult, SPONSORED_PYTH_DEPENDENT_PROVIDERS, SafeguardConfig, SafeguardEnforcer, type SaveDepositInput, SaveResult, type SelectAndSplitResult, SendResult, type SendTransferInput, StakeVSuiResult, type StepPreview, SupportedAsset, type SwapExecuteInput, SwapQuoteResult, SwapResult, SwapRouteResult, T2000, T2000Error, T2000Options, TransactionRecord, TransactionSigner, TxMetadata, UnstakeVSuiResult, VOLO_METADATA, VOLO_PKG, VOLO_POOL, VSUI_TYPE, type VoloStakeInput, type VoloStats, type VoloUnstakeInput, WRITE_APPENDER_REGISTRY, type WithdrawInput, WithdrawResult, type WriteStep, type WriteToolName, ZkLoginProof, addClaimRewardsToTx, addSendToTx, addStakeVSuiToTx, addUnstakeVSuiToTx, aggregateClaimableRewards, buildAddLeafTx, buildClaimRewardsTx, buildHarvestRewardsTx, buildRevokeLeafTx, buildSendTx, buildStakeVSuiTx, buildUnstakeVSuiTx, composeTx, deriveAllowedAddressesFromPtb, displayHandle, exportPrivateKey, fetchAllCoins, fullHandle, generateKeypair, getAddress, getFinancialSummary, getPendingRewards, getPendingRewardsByAddress, getRates, getSponsoredSwapProviders, getSwapQuote, getVoloStats, keypairFromPrivateKey, loadKey, saveKey, selectAndSplitCoin, selectSuiCoin, validateLabel, walletExists };
1479
+ export { AUDRIC_PARENT_NAME, AUDRIC_PARENT_NFT_ID, type AppenderContext, BalanceResponse, type BorrowInput, BorrowResult, type BuildAddLeafParams, type BuildHarvestRewardsTxOptions, type BuildRevokeLeafParams, type ClaimRewardsInput, ClaimRewardsResult, type CoinPage, type ComposeTxFeeHookContext, type ComposeTxFeeHooks, type ComposeTxOptions, type ComposeTxResult, CompoundRewardsResult, ContactManager, DepositInfo, EarningsResult, FinancialSummary, type FinancialSummaryOptions, FundStatusResult, HF_CRITICAL_THRESHOLD, HF_WARN_THRESHOLD, type HarvestPlan, type HarvestSkippedLeg, type HarvestSwapLeg, HealthFactorResult, InvalidAddressError, type LabelValidationResult, LendingAdapter, LendingRates, MaxBorrowResult, MaxWithdrawResult, type NormalizedAddress, OverlayFeeConfig, PayOptions, PayResult, PaymentRequest, PendingReward, PositionsResult, RatesResult, type RepayDebtInput, RepayResult, SPONSORED_PYTH_DEPENDENT_PROVIDERS, SUINS_NAME_REGEX, SUI_ADDRESS_REGEX, SUI_ADDRESS_STRICT_REGEX, SafeguardConfig, SafeguardEnforcer, type SaveDepositInput, SaveResult, type SelectAndSplitResult, SendResult, type SendTransferInput, StakeVSuiResult, type StepPreview, SuinsNotRegisteredError, SuinsRpcError, SupportedAsset, type SwapExecuteInput, SwapQuoteResult, SwapResult, SwapRouteResult, T2000, T2000Error, T2000Options, TransactionRecord, TransactionSigner, TxMetadata, UnstakeVSuiResult, VOLO_METADATA, VOLO_PKG, VOLO_POOL, VSUI_TYPE, type VoloStakeInput, type VoloStats, type VoloUnstakeInput, WRITE_APPENDER_REGISTRY, type WithdrawInput, WithdrawResult, type WriteStep, type WriteToolName, ZkLoginProof, addClaimRewardsToTx, addSendToTx, addStakeVSuiToTx, addUnstakeVSuiToTx, aggregateClaimableRewards, buildAddLeafTx, buildClaimRewardsTx, buildHarvestRewardsTx, buildRevokeLeafTx, buildSendTx, buildStakeVSuiTx, buildUnstakeVSuiTx, composeTx, deriveAllowedAddressesFromPtb, displayHandle, exportPrivateKey, fetchAllCoins, fullHandle, generateKeypair, getAddress, getFinancialSummary, getPendingRewards, getPendingRewardsByAddress, getRates, getSponsoredSwapProviders, getSwapQuote, getVoloStats, keypairFromPrivateKey, loadKey, looksLikeSuiNs, normalizeAddressInput, resolveAddressToSuinsViaRpc, resolveSuinsViaRpc, saveKey, selectAndSplitCoin, selectSuiCoin, validateLabel, walletExists };
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 { Q as TxMetadata, o as SafeguardConfig, T as T2000Error, H as TransactionSigner, _ as ZkLoginProof, v as SupportedAsset } from './types-BMdhu0D7.js';
5
- export { A as ALL_NAVI_ASSETS, B as BORROW_FEE_BPS, a as BPS_DENOMINATOR, ax 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, I as IKA_TYPE, K as KNOWN_TARGETS, h as KeypairSigner, L as LABEL_PATTERNS, i as LOFI_TYPE, M as MANIFEST_TYPE, j as MIST_PER_SUI, N as NAVX_TYPE, ay as OPERATION_ASSETS, O as OUTBOUND_OPS, az as Operation, P as ProtocolFeeInfo, S as SAVE_FEE_BPS, k as STABLE_ASSETS, l as SUI_DECIMALS, m as SUI_TYPE, n as SUPPORTED_ASSETS, p as SafeguardError, q as SafeguardErrorDetails, r as SafeguardRule, s as SimulationResult, t as StableAsset, u as SuiRpcTxBlock, w as T2000ErrorCode, x as T2000ErrorData, y as T2000_OVERLAY_FEE_WALLET, z as TOKEN_MAP, J as TxDirection, U as USDC_DECIMALS, R as USDC_TYPE, V as USDE_TYPE, W as USDSUI_TYPE, X as USDT_TYPE, Y as WAL_TYPE, Z as WBTC_TYPE, $ as ZkLoginSigner, a0 as addFeeTransfer, aA as assertAllowedAsset, a1 as calculateFee, a2 as classifyAction, a3 as classifyLabel, a4 as classifyTransaction, a5 as extractAllUserLegs, a6 as extractTransferDetails, a7 as extractTxCommands, a8 as extractTxSender, a9 as fallbackLabel, aa as formatAssetAmount, ab as formatSui, ac as formatUsd, aB as getCoinMeta, ad as getDecimals, ae as getDecimalsForCoinType, af as getTier, aC as isAllowedAsset, aD as isInRegistry, ag as isSupported, ah as isTier1, ai as isTier2, aj as mapMoveAbortCode, ak as mapWalletError, al as mistToSui, aE as normalizeAsset, aF as normalizeCoinType, am as parseSuiRpcTx, aG as queryHistory, aH as queryTransaction, an as rawToStable, ao as rawToUsdc, ap as refineLendingLabel, aq as resolveSymbol, ar as resolveTokenType, aI as simulateTransaction, as as stableToRaw, at as suiToMist, aJ as throwIfSimulationFailed, au as truncateAddress, av as usdcToRaw, aw as validateAddress } from './types-BMdhu0D7.js';
4
+ import { Q as TxMetadata, o as SafeguardConfig, T as T2000Error, H as TransactionSigner, _ as ZkLoginProof, v as SupportedAsset } from './types-CfBlFLmU.js';
5
+ export { A as ALL_NAVI_ASSETS, B as BORROW_FEE_BPS, a as BPS_DENOMINATOR, ax 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, I as IKA_TYPE, K as KNOWN_TARGETS, h as KeypairSigner, L as LABEL_PATTERNS, i as LOFI_TYPE, M as MANIFEST_TYPE, j as MIST_PER_SUI, N as NAVX_TYPE, ay as OPERATION_ASSETS, O as OUTBOUND_OPS, az as Operation, P as ProtocolFeeInfo, S as SAVE_FEE_BPS, k as STABLE_ASSETS, l as SUI_DECIMALS, m as SUI_TYPE, n as SUPPORTED_ASSETS, p as SafeguardError, q as SafeguardErrorDetails, r as SafeguardRule, s as SimulationResult, t as StableAsset, u as SuiRpcTxBlock, w as T2000ErrorCode, x as T2000ErrorData, y as T2000_OVERLAY_FEE_WALLET, z as TOKEN_MAP, J as TxDirection, U as USDC_DECIMALS, R as USDC_TYPE, V as USDE_TYPE, W as USDSUI_TYPE, X as USDT_TYPE, Y as WAL_TYPE, Z as WBTC_TYPE, $ as ZkLoginSigner, a0 as addFeeTransfer, aA as assertAllowedAsset, a1 as calculateFee, a2 as classifyAction, a3 as classifyLabel, a4 as classifyTransaction, a5 as extractAllUserLegs, a6 as extractTransferDetails, a7 as extractTxCommands, a8 as extractTxSender, a9 as fallbackLabel, aa as formatAssetAmount, ab as formatSui, ac as formatUsd, aB as getCoinMeta, ad as getDecimals, ae as getDecimalsForCoinType, af as getTier, aC as isAllowedAsset, aD as isInRegistry, ag as isSupported, ah as isTier1, ai as isTier2, aj as mapMoveAbortCode, ak as mapWalletError, al as mistToSui, aE as normalizeAsset, aF as normalizeCoinType, am as parseSuiRpcTx, aG as queryHistory, aH as queryTransaction, an as rawToStable, ao as rawToUsdc, ap as refineLendingLabel, aq as resolveSymbol, ar as resolveTokenType, aI as simulateTransaction, as as stableToRaw, at as suiToMist, aJ as throwIfSimulationFailed, au as truncateAddress, av as usdcToRaw, aw as validateAddress } from './types-CfBlFLmU.js';
6
6
  import { L as LendingAdapter, a as LendingRates, P as PendingReward$1 } from './descriptors-DqIb4AnV.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-DqIb4AnV.js';
8
- import { n as T2000Options, P as PayOptions, d as PayResult, o as StakeVSuiResult, U as UnstakeVSuiResult, p as SwapResult, q as SwapQuoteResult, i as SendResult, B as BalanceResponse, k as TransactionRecord, D as DepositInfo, r as PaymentRequest, S as SaveResult, W as WithdrawResult, b as MaxWithdrawResult, a as BorrowResult, h as RepayResult, M as MaxBorrowResult, H as HealthFactorResult, e as PendingReward, C as ClaimRewardsResult, s as CompoundRewardsResult, g as PositionsResult, R as RatesResult, E as EarningsResult, F as FundStatusResult, c as OverlayFeeConfig, j as SwapRouteResult, t as FinancialSummary } from './types-I7U99DvG.js';
9
- export { A as AssetRates, G as GasReserve, u as HFAlertLevel, O as OVERLAY_FEE_RATE, f as PositionEntry, v as SerializedCetusRoute, w as SerializedCetusRoutePath, x as SerializedRouterDataV3, T as TransactionLeg, y as addSwapToTx, l as buildSwapTx, z as deserializeCetusRoute, m as findSwapRoute, I as isCetusRouteFresh, J as serializeCetusRoute, K as verifyCetusRouteCoinMatch } from './types-I7U99DvG.js';
8
+ import { n as T2000Options, P as PayOptions, d as PayResult, o as StakeVSuiResult, U as UnstakeVSuiResult, p as SwapResult, q as SwapQuoteResult, i as SendResult, B as BalanceResponse, k as TransactionRecord, D as DepositInfo, r as PaymentRequest, S as SaveResult, W as WithdrawResult, b as MaxWithdrawResult, a as BorrowResult, h as RepayResult, M as MaxBorrowResult, H as HealthFactorResult, e as PendingReward, C as ClaimRewardsResult, s as CompoundRewardsResult, g as PositionsResult, R as RatesResult, E as EarningsResult, F as FundStatusResult, c as OverlayFeeConfig, j as SwapRouteResult, t as FinancialSummary } from './types-Bk7NncQ_.js';
9
+ export { A as AssetRates, G as GasReserve, u as HFAlertLevel, O as OVERLAY_FEE_RATE, f as PositionEntry, v as SerializedCetusRoute, w as SerializedCetusRoutePath, x as SerializedRouterDataV3, T as TransactionLeg, y as addSwapToTx, l as buildSwapTx, z as deserializeCetusRoute, m as findSwapRoute, I as isCetusRouteFresh, J as serializeCetusRoute, K as verifyCetusRouteCoinMatch } from './types-Bk7NncQ_.js';
10
10
  import { Transaction, TransactionObjectArgument } from '@mysten/sui/transactions';
11
11
  import { SuinsClient } from '@mysten/suins';
12
12
  export { NaviAdapter, ProtocolRegistry } from './adapters/index.js';
@@ -136,6 +136,25 @@ declare class T2000 extends EventEmitter<T2000Events> {
136
136
  amount: number;
137
137
  asset?: string;
138
138
  }): Promise<SendResult>;
139
+ /**
140
+ * [S.279 / CLI-CONTACTS-CLEANUP — 2026-05-23] Resolve a recipient
141
+ * string into a canonical 0x address, trying each shape in priority
142
+ * order:
143
+ * 1. **hex** — `0x…` is used directly (no RPC round-trip).
144
+ * 2. **SuiNS** — `alex.sui` resolves via `suix_resolveNameServiceAddress`.
145
+ * 3. **saved contact** — `ContactManager.resolve()` falls back to the
146
+ * legacy `~/.t2000/contacts.json` alias map. Deprecated; the
147
+ * manager surfaces a one-time `console.warn` when this path fires.
148
+ *
149
+ * Returns `{ address, suinsName?, contactName? }` so `send()` can stamp
150
+ * the name source on the receipt without re-resolving.
151
+ *
152
+ * Throws `T2000Error('SUINS_NOT_REGISTERED', …)` for well-formed but
153
+ * unregistered SuiNS names (vs. propagating the engine-style
154
+ * `SuinsNotRegisteredError` — keeps the SDK's error surface
155
+ * `T2000Error`-only, consistent with every other write helper).
156
+ */
157
+ private resolveRecipient;
139
158
  balance(): Promise<BalanceResponse>;
140
159
  history(params?: {
141
160
  limit?: number;
@@ -223,6 +242,116 @@ declare class T2000 extends EventEmitter<T2000Events> {
223
242
  private emitBalanceChange;
224
243
  }
225
244
 
245
+ /**
246
+ * Canonical 0x-address shape. Loose lower bound (>= 1 hex char) so
247
+ * pre-v1.0 short addresses still validate; tools that need a full 64-hex
248
+ * address can additionally check `length === 66`. Case-insensitive on
249
+ * the `0x` prefix because some upstream callers (and historic tests)
250
+ * uppercase the prefix as part of address normalization tests; the
251
+ * normalizer always returns the lowercased canonical form regardless.
252
+ */
253
+ declare const SUI_ADDRESS_REGEX: RegExp;
254
+ /**
255
+ * Strict canonical 0x-address shape (66 chars total). Used by the
256
+ * resolver's "looks like" check to disambiguate "user pasted an
257
+ * address" vs "user typed a SuiNS name".
258
+ */
259
+ declare const SUI_ADDRESS_STRICT_REGEX: RegExp;
260
+ /**
261
+ * Mirrors the pattern in `audric/apps/web-v2/lib/suins-cache.ts` so the
262
+ * host-side send executor and the engine-side read normalizer agree on
263
+ * what counts as a SuiNS name. SuiNS allows nested labels (`team.alex.sui`)
264
+ * but every label must use only `[a-z0-9-]`.
265
+ */
266
+ declare const SUINS_NAME_REGEX: RegExp;
267
+ declare class InvalidAddressError extends Error {
268
+ readonly raw: string;
269
+ constructor(raw: string);
270
+ }
271
+ declare class SuinsNotRegisteredError extends Error {
272
+ readonly name_: string;
273
+ constructor(name_: string);
274
+ }
275
+ declare class SuinsRpcError extends Error {
276
+ readonly name_: string;
277
+ constructor(name_: string, detail: string);
278
+ }
279
+ /**
280
+ * Returns true if `value` looks like a SuiNS name (case-insensitive).
281
+ * Cheap synchronous check — use to avoid an unnecessary RPC round-trip
282
+ * for inputs that obviously aren't names (0x addresses, contact handles).
283
+ */
284
+ declare function looksLikeSuiNs(value: string): boolean;
285
+ /**
286
+ * Resolve a SuiNS name to its on-chain Sui address via the public
287
+ * `suix_resolveNameServiceAddress` JSON-RPC method. Returns `null` if
288
+ * the name resolves to no address (= not registered or expired). Throws
289
+ * `SuinsRpcError` on RPC/network failure.
290
+ *
291
+ * The host SHOULD pass a `rpcUrl` that includes any vendor key (e.g.
292
+ * audric's BlockVision-keyed URL) so the call benefits from the host's
293
+ * paid retry/cache budget. Falls back to the public mainnet endpoint.
294
+ */
295
+ declare function resolveSuinsViaRpc(rawName: string, ctx?: {
296
+ suiRpcUrl?: string;
297
+ signal?: AbortSignal;
298
+ }): Promise<string | null>;
299
+ /**
300
+ * Reverse-resolve a 0x address to its registered SuiNS names via
301
+ * `suix_resolveNameServiceNames`. Returns the names sorted by the
302
+ * registry (the first entry is conventionally the user's "primary"
303
+ * name on dApps that show one), or `[]` when the address has no
304
+ * SuiNS records. Throws `SuinsRpcError` on RPC/network failure.
305
+ *
306
+ * Why this is its own helper (not folded into `normalizeAddressInput`):
307
+ * a reverse lookup adds a second RPC round-trip per tool call. We don't
308
+ * want every read tool that takes an `address` to silently double its
309
+ * latency. The lookup primitive is opt-in via the `resolve_suins` tool;
310
+ * normalizers stay forward-only.
311
+ */
312
+ declare function resolveAddressToSuinsViaRpc(rawAddress: string, ctx?: {
313
+ suiRpcUrl?: string;
314
+ signal?: AbortSignal;
315
+ }): Promise<string[]>;
316
+ interface NormalizedAddress {
317
+ /**
318
+ * Canonical 0x-prefixed lowercase hex address. Always set on success.
319
+ * Tools should use this for any downstream query (BlockVision, NAVI,
320
+ * positionFetcher, etc.) and for cache keys.
321
+ */
322
+ address: string;
323
+ /**
324
+ * The user-facing name when the input was resolved via SuiNS, otherwise
325
+ * `null`. Tools should stamp this on result data so card titles can
326
+ * render "Balance · obehi.sui" instead of "Balance · 0x1234…abcd".
327
+ */
328
+ suinsName: string | null;
329
+ /**
330
+ * The original input (pre-normalization). Useful for error narration —
331
+ * "I tried to resolve `Obehi.Sui` and …" reads better than the
332
+ * post-trim/lowercase form.
333
+ */
334
+ raw: string;
335
+ }
336
+ /**
337
+ * Canonical normalizer. Accepts a 0x address OR a SuiNS name; returns
338
+ * a structured `NormalizedAddress`. Throws:
339
+ * - `InvalidAddressError` if the input matches neither shape.
340
+ * - `SuinsNotRegisteredError` if the SuiNS name is well-formed but
341
+ * resolves to null (= not registered).
342
+ * - `SuinsRpcError` if the RPC fails.
343
+ *
344
+ * Every read tool (engine) and write helper (SDK `T2000.send()`) that
345
+ * accepts a user-supplied recipient MUST call this helper before any
346
+ * downstream lookup. Doing the check inline (1) duplicates the regex,
347
+ * (2) silently rejects SuiNS names, (3) makes cache keys inconsistent
348
+ * across tools.
349
+ */
350
+ declare function normalizeAddressInput(value: string, ctx?: {
351
+ suiRpcUrl?: string;
352
+ signal?: AbortSignal;
353
+ }): Promise<NormalizedAddress>;
354
+
226
355
  declare function generateKeypair(): Ed25519Keypair;
227
356
  declare function keypairFromPrivateKey(privateKey: string): Ed25519Keypair;
228
357
  declare function saveKey(keypair: Ed25519Keypair, passphrase: string, keyPath?: string): Promise<string>;
@@ -1347,4 +1476,4 @@ declare function fullHandle(label: string): string;
1347
1476
  */
1348
1477
  declare function displayHandle(label: string): string;
1349
1478
 
1350
- export { AUDRIC_PARENT_NAME, AUDRIC_PARENT_NFT_ID, type AppenderContext, BalanceResponse, type BorrowInput, BorrowResult, type BuildAddLeafParams, type BuildHarvestRewardsTxOptions, type BuildRevokeLeafParams, type ClaimRewardsInput, ClaimRewardsResult, type CoinPage, type ComposeTxFeeHookContext, type ComposeTxFeeHooks, type ComposeTxOptions, type ComposeTxResult, CompoundRewardsResult, ContactManager, DepositInfo, EarningsResult, FinancialSummary, type FinancialSummaryOptions, FundStatusResult, HF_CRITICAL_THRESHOLD, HF_WARN_THRESHOLD, type HarvestPlan, type HarvestSkippedLeg, type HarvestSwapLeg, HealthFactorResult, type LabelValidationResult, LendingAdapter, LendingRates, MaxBorrowResult, MaxWithdrawResult, OverlayFeeConfig, PayOptions, PayResult, PaymentRequest, PendingReward, PositionsResult, RatesResult, type RepayDebtInput, RepayResult, SPONSORED_PYTH_DEPENDENT_PROVIDERS, SafeguardConfig, SafeguardEnforcer, type SaveDepositInput, SaveResult, type SelectAndSplitResult, SendResult, type SendTransferInput, StakeVSuiResult, type StepPreview, SupportedAsset, type SwapExecuteInput, SwapQuoteResult, SwapResult, SwapRouteResult, T2000, T2000Error, T2000Options, TransactionRecord, TransactionSigner, TxMetadata, UnstakeVSuiResult, VOLO_METADATA, VOLO_PKG, VOLO_POOL, VSUI_TYPE, type VoloStakeInput, type VoloStats, type VoloUnstakeInput, WRITE_APPENDER_REGISTRY, type WithdrawInput, WithdrawResult, type WriteStep, type WriteToolName, ZkLoginProof, addClaimRewardsToTx, addSendToTx, addStakeVSuiToTx, addUnstakeVSuiToTx, aggregateClaimableRewards, buildAddLeafTx, buildClaimRewardsTx, buildHarvestRewardsTx, buildRevokeLeafTx, buildSendTx, buildStakeVSuiTx, buildUnstakeVSuiTx, composeTx, deriveAllowedAddressesFromPtb, displayHandle, exportPrivateKey, fetchAllCoins, fullHandle, generateKeypair, getAddress, getFinancialSummary, getPendingRewards, getPendingRewardsByAddress, getRates, getSponsoredSwapProviders, getSwapQuote, getVoloStats, keypairFromPrivateKey, loadKey, saveKey, selectAndSplitCoin, selectSuiCoin, validateLabel, walletExists };
1479
+ export { AUDRIC_PARENT_NAME, AUDRIC_PARENT_NFT_ID, type AppenderContext, BalanceResponse, type BorrowInput, BorrowResult, type BuildAddLeafParams, type BuildHarvestRewardsTxOptions, type BuildRevokeLeafParams, type ClaimRewardsInput, ClaimRewardsResult, type CoinPage, type ComposeTxFeeHookContext, type ComposeTxFeeHooks, type ComposeTxOptions, type ComposeTxResult, CompoundRewardsResult, ContactManager, DepositInfo, EarningsResult, FinancialSummary, type FinancialSummaryOptions, FundStatusResult, HF_CRITICAL_THRESHOLD, HF_WARN_THRESHOLD, type HarvestPlan, type HarvestSkippedLeg, type HarvestSwapLeg, HealthFactorResult, InvalidAddressError, type LabelValidationResult, LendingAdapter, LendingRates, MaxBorrowResult, MaxWithdrawResult, type NormalizedAddress, OverlayFeeConfig, PayOptions, PayResult, PaymentRequest, PendingReward, PositionsResult, RatesResult, type RepayDebtInput, RepayResult, SPONSORED_PYTH_DEPENDENT_PROVIDERS, SUINS_NAME_REGEX, SUI_ADDRESS_REGEX, SUI_ADDRESS_STRICT_REGEX, SafeguardConfig, SafeguardEnforcer, type SaveDepositInput, SaveResult, type SelectAndSplitResult, SendResult, type SendTransferInput, StakeVSuiResult, type StepPreview, SuinsNotRegisteredError, SuinsRpcError, SupportedAsset, type SwapExecuteInput, SwapQuoteResult, SwapResult, SwapRouteResult, T2000, T2000Error, T2000Options, TransactionRecord, TransactionSigner, TxMetadata, UnstakeVSuiResult, VOLO_METADATA, VOLO_PKG, VOLO_POOL, VSUI_TYPE, type VoloStakeInput, type VoloStats, type VoloUnstakeInput, WRITE_APPENDER_REGISTRY, type WithdrawInput, WithdrawResult, type WriteStep, type WriteToolName, ZkLoginProof, addClaimRewardsToTx, addSendToTx, addStakeVSuiToTx, addUnstakeVSuiToTx, aggregateClaimableRewards, buildAddLeafTx, buildClaimRewardsTx, buildHarvestRewardsTx, buildRevokeLeafTx, buildSendTx, buildStakeVSuiTx, buildUnstakeVSuiTx, composeTx, deriveAllowedAddressesFromPtb, displayHandle, exportPrivateKey, fetchAllCoins, fullHandle, generateKeypair, getAddress, getFinancialSummary, getPendingRewards, getPendingRewardsByAddress, getRates, getSponsoredSwapProviders, getSwapQuote, getVoloStats, keypairFromPrivateKey, loadKey, looksLikeSuiNs, normalizeAddressInput, resolveAddressToSuinsViaRpc, resolveSuinsViaRpc, saveKey, selectAndSplitCoin, selectSuiCoin, validateLabel, walletExists };
package/dist/index.js CHANGED
@@ -1799,6 +1799,132 @@ function extractCommands(txBlock) {
1799
1799
  // src/t2000.ts
1800
1800
  init_token_registry();
1801
1801
 
1802
+ // src/utils/suins.ts
1803
+ var SUI_MAINNET_URL = "https://fullnode.mainnet.sui.io:443";
1804
+ var SUI_ADDRESS_REGEX = /^0x[a-fA-F0-9]{1,64}$/i;
1805
+ var SUI_ADDRESS_STRICT_REGEX = /^0x[a-fA-F0-9]{64}$/i;
1806
+ var SUINS_NAME_REGEX = /^[a-z0-9-]+(\.[a-z0-9-]+)*\.sui$/;
1807
+ var InvalidAddressError = class extends Error {
1808
+ constructor(raw) {
1809
+ super(
1810
+ `"${raw}" isn't a valid Sui address or SuiNS name. Pass a 0x-prefixed hex address (e.g. 0x40cd\u20263e62) or a SuiNS name ending in .sui (e.g. alex.sui).`
1811
+ );
1812
+ this.raw = raw;
1813
+ this.name = "InvalidAddressError";
1814
+ }
1815
+ };
1816
+ var SuinsNotRegisteredError = class extends Error {
1817
+ constructor(name_) {
1818
+ super(
1819
+ `"${name_}" isn't a registered SuiNS name. Double-check the spelling, or paste the full Sui address (0x\u2026 64 hex characters).`
1820
+ );
1821
+ this.name_ = name_;
1822
+ this.name = "SuinsNotRegisteredError";
1823
+ }
1824
+ };
1825
+ var SuinsRpcError = class extends Error {
1826
+ constructor(name_, detail) {
1827
+ super(`SuiNS lookup failed for "${name_}" (${detail}). Try again, or paste the full Sui address.`);
1828
+ this.name_ = name_;
1829
+ this.name = "SuinsRpcError";
1830
+ }
1831
+ };
1832
+ function looksLikeSuiNs(value) {
1833
+ if (!value) return false;
1834
+ return SUINS_NAME_REGEX.test(value.trim().toLowerCase());
1835
+ }
1836
+ async function resolveSuinsViaRpc(rawName, ctx = {}) {
1837
+ const name = rawName.trim().toLowerCase();
1838
+ if (!SUINS_NAME_REGEX.test(name)) {
1839
+ throw new InvalidAddressError(rawName);
1840
+ }
1841
+ const url = ctx.suiRpcUrl || SUI_MAINNET_URL;
1842
+ let res;
1843
+ try {
1844
+ res = await fetch(url, {
1845
+ method: "POST",
1846
+ headers: { "Content-Type": "application/json" },
1847
+ body: JSON.stringify({
1848
+ jsonrpc: "2.0",
1849
+ id: 1,
1850
+ method: "suix_resolveNameServiceAddress",
1851
+ params: [name]
1852
+ }),
1853
+ signal: ctx.signal ?? AbortSignal.timeout(8e3)
1854
+ });
1855
+ } catch (err) {
1856
+ const msg = err instanceof Error ? err.message : String(err);
1857
+ throw new SuinsRpcError(name, msg);
1858
+ }
1859
+ if (!res.ok) {
1860
+ throw new SuinsRpcError(name, `HTTP ${res.status}`);
1861
+ }
1862
+ let body;
1863
+ try {
1864
+ body = await res.json();
1865
+ } catch (err) {
1866
+ const msg = err instanceof Error ? err.message : String(err);
1867
+ throw new SuinsRpcError(name, `JSON parse failed: ${msg}`);
1868
+ }
1869
+ if (body.error) {
1870
+ throw new SuinsRpcError(name, body.error.message);
1871
+ }
1872
+ return body.result ?? null;
1873
+ }
1874
+ async function resolveAddressToSuinsViaRpc(rawAddress, ctx = {}) {
1875
+ const address = rawAddress.trim().toLowerCase();
1876
+ if (!SUI_ADDRESS_REGEX.test(address)) {
1877
+ throw new InvalidAddressError(rawAddress);
1878
+ }
1879
+ const url = ctx.suiRpcUrl || SUI_MAINNET_URL;
1880
+ let res;
1881
+ try {
1882
+ res = await fetch(url, {
1883
+ method: "POST",
1884
+ headers: { "Content-Type": "application/json" },
1885
+ body: JSON.stringify({
1886
+ jsonrpc: "2.0",
1887
+ id: 1,
1888
+ method: "suix_resolveNameServiceNames",
1889
+ params: [address]
1890
+ }),
1891
+ signal: ctx.signal ?? AbortSignal.timeout(8e3)
1892
+ });
1893
+ } catch (err) {
1894
+ const msg = err instanceof Error ? err.message : String(err);
1895
+ throw new SuinsRpcError(address, msg);
1896
+ }
1897
+ if (!res.ok) {
1898
+ throw new SuinsRpcError(address, `HTTP ${res.status}`);
1899
+ }
1900
+ let body;
1901
+ try {
1902
+ body = await res.json();
1903
+ } catch (err) {
1904
+ const msg = err instanceof Error ? err.message : String(err);
1905
+ throw new SuinsRpcError(address, `JSON parse failed: ${msg}`);
1906
+ }
1907
+ if (body.error) {
1908
+ throw new SuinsRpcError(address, body.error.message);
1909
+ }
1910
+ return body.result?.data ?? [];
1911
+ }
1912
+ async function normalizeAddressInput(value, ctx = {}) {
1913
+ const trimmed = value.trim();
1914
+ if (SUI_ADDRESS_REGEX.test(trimmed)) {
1915
+ return { address: trimmed.toLowerCase(), suinsName: null, raw: value };
1916
+ }
1917
+ if (looksLikeSuiNs(trimmed)) {
1918
+ const name = trimmed.toLowerCase();
1919
+ const address = await resolveSuinsViaRpc(name, ctx);
1920
+ if (!address) {
1921
+ throw new SuinsNotRegisteredError(name);
1922
+ }
1923
+ return { address: address.toLowerCase(), suinsName: name, raw: value };
1924
+ }
1925
+ throw new InvalidAddressError(value);
1926
+ }
1927
+
1802
1928
  // ../../node_modules/.pnpm/@mysten+bcs@2.0.2/node_modules/@mysten/bcs/dist/uleb.mjs
1803
1929
  function ulebEncode(num) {
1804
1930
  let bigNum = BigInt(num);
@@ -6266,6 +6392,14 @@ var SafeguardEnforcer = class {
6266
6392
  };
6267
6393
  init_errors();
6268
6394
  var RESERVED_NAMES = /* @__PURE__ */ new Set(["to", "all", "address"]);
6395
+ var deprecationWarned = false;
6396
+ function warnContactsDeprecation() {
6397
+ if (deprecationWarned) return;
6398
+ deprecationWarned = true;
6399
+ console.warn(
6400
+ "[t2000] DEPRECATION: ~/.t2000/contacts.json alias resolution is deprecated and will be removed in the next major release. Use SuiNS names instead (e.g. `t2000 send alex.sui 10 USDC`). Register a SuiNS name at https://suins.io if you need a memorable handle."
6401
+ );
6402
+ }
6269
6403
  var ContactManager = class {
6270
6404
  contacts = {};
6271
6405
  filePath;
@@ -6319,12 +6453,15 @@ var ContactManager = class {
6319
6453
  }
6320
6454
  const contact = this.contacts[nameOrAddress.toLowerCase()];
6321
6455
  if (contact) {
6456
+ warnContactsDeprecation();
6322
6457
  return { address: contact.address, contactName: contact.name };
6323
6458
  }
6324
6459
  throw new T2000Error(
6325
6460
  "CONTACT_NOT_FOUND",
6326
6461
  `"${nameOrAddress}" is not a valid Sui address or saved contact.
6327
- Add it: t2000 contacts add ${nameOrAddress} 0x...`
6462
+ Use a SuiNS name (e.g. alex.sui \u2014 register at https://suins.io)
6463
+ or paste the full Sui address (0x... 64 hex characters).
6464
+ Legacy contact aliases: \`t2000 contacts add ${nameOrAddress} 0x...\` (deprecated).`
6328
6465
  );
6329
6466
  }
6330
6467
  validateName(name) {
@@ -6694,7 +6831,7 @@ var T2000 = class _T2000 extends EventEmitter {
6694
6831
  if (!(asset in SUPPORTED_ASSETS)) {
6695
6832
  throw new T2000Error("ASSET_NOT_SUPPORTED", `Asset ${asset} is not supported`);
6696
6833
  }
6697
- const resolved = this.contacts.resolve(params.to);
6834
+ const resolved = await this.resolveRecipient(params.to);
6698
6835
  const sendAmount = params.amount;
6699
6836
  const sendTo = resolved.address;
6700
6837
  const gasResult = await executeTx(
@@ -6711,11 +6848,55 @@ var T2000 = class _T2000 extends EventEmitter {
6711
6848
  amount: sendAmount,
6712
6849
  to: resolved.address,
6713
6850
  contactName: resolved.contactName,
6851
+ suinsName: resolved.suinsName,
6714
6852
  gasCost: gasResult.gasCostSui,
6715
6853
  gasCostUnit: "SUI",
6716
6854
  balance
6717
6855
  };
6718
6856
  }
6857
+ /**
6858
+ * [S.279 / CLI-CONTACTS-CLEANUP — 2026-05-23] Resolve a recipient
6859
+ * string into a canonical 0x address, trying each shape in priority
6860
+ * order:
6861
+ * 1. **hex** — `0x…` is used directly (no RPC round-trip).
6862
+ * 2. **SuiNS** — `alex.sui` resolves via `suix_resolveNameServiceAddress`.
6863
+ * 3. **saved contact** — `ContactManager.resolve()` falls back to the
6864
+ * legacy `~/.t2000/contacts.json` alias map. Deprecated; the
6865
+ * manager surfaces a one-time `console.warn` when this path fires.
6866
+ *
6867
+ * Returns `{ address, suinsName?, contactName? }` so `send()` can stamp
6868
+ * the name source on the receipt without re-resolving.
6869
+ *
6870
+ * Throws `T2000Error('SUINS_NOT_REGISTERED', …)` for well-formed but
6871
+ * unregistered SuiNS names (vs. propagating the engine-style
6872
+ * `SuinsNotRegisteredError` — keeps the SDK's error surface
6873
+ * `T2000Error`-only, consistent with every other write helper).
6874
+ */
6875
+ async resolveRecipient(input) {
6876
+ const trimmed = input.trim();
6877
+ if (SUI_ADDRESS_REGEX.test(trimmed)) {
6878
+ return { address: trimmed.toLowerCase() };
6879
+ }
6880
+ if (looksLikeSuiNs(trimmed)) {
6881
+ try {
6882
+ const name = trimmed.toLowerCase();
6883
+ const address = await resolveSuinsViaRpc(name);
6884
+ if (!address) {
6885
+ throw new SuinsNotRegisteredError(name);
6886
+ }
6887
+ return { address: address.toLowerCase(), suinsName: name };
6888
+ } catch (err) {
6889
+ if (err instanceof SuinsNotRegisteredError) {
6890
+ throw new T2000Error(
6891
+ "SUINS_NOT_REGISTERED",
6892
+ err.message
6893
+ );
6894
+ }
6895
+ throw err;
6896
+ }
6897
+ }
6898
+ return this.contacts.resolve(input);
6899
+ }
6719
6900
  async balance() {
6720
6901
  const bal = await queryBalance(this.client, this._address);
6721
6902
  let chainTotal = bal.available + bal.gasReserve.usdEquiv;
@@ -8379,6 +8560,6 @@ function displayHandle(label) {
8379
8560
  (*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
8380
8561
  */
8381
8562
 
8382
- export { ALL_NAVI_ASSETS, AUDRIC_PARENT_NAME, AUDRIC_PARENT_NFT_ID, BORROW_FEE_BPS, BPS_DENOMINATOR, CETUS_USDC_SUI_POOL, CLOCK_ID, COIN_REGISTRY, ContactManager, DEFAULT_NETWORK, DEFAULT_SAFEGUARD_CONFIG, ETH_TYPE, GAS_RESERVE_MIN, HF_CRITICAL_THRESHOLD, HF_WARN_THRESHOLD, IKA_TYPE, KNOWN_TARGETS, KeypairSigner, LABEL_PATTERNS, LOFI_TYPE, MANIFEST_TYPE, MIST_PER_SUI, NAVX_TYPE, NaviAdapter, OPERATION_ASSETS, OUTBOUND_OPS, OVERLAY_FEE_RATE, ProtocolRegistry, SAVE_FEE_BPS, SPONSORED_PYTH_DEPENDENT_PROVIDERS, STABLE_ASSETS, SUI_DECIMALS, SUI_TYPE, SUPPORTED_ASSETS, SafeguardEnforcer, SafeguardError, T2000, T2000Error, T2000_OVERLAY_FEE_WALLET, TOKEN_MAP, USDC_DECIMALS, USDC_TYPE, USDE_TYPE, USDSUI_TYPE, USDT_TYPE, VOLO_METADATA, VOLO_PKG, VOLO_POOL, VSUI_TYPE, WAL_TYPE, WBTC_TYPE, WRITE_APPENDER_REGISTRY, ZkLoginSigner, addClaimRewardsToTx, addFeeTransfer, addSendToTx, addStakeVSuiToTx, addSwapToTx, addUnstakeVSuiToTx, aggregateClaimableRewards, allDescriptors, assertAllowedAsset, buildAddLeafTx, buildClaimRewardsTx, buildHarvestRewardsTx, buildRevokeLeafTx, buildSendTx, buildStakeVSuiTx, buildSwapTx, buildUnstakeVSuiTx, calculateFee, classifyAction, classifyLabel, classifyTransaction, composeTx, deriveAllowedAddressesFromPtb, deserializeCetusRoute, displayHandle, exportPrivateKey, extractAllUserLegs, extractTransferDetails, extractTxCommands, extractTxSender, fallbackLabel, fetchAllCoins, findSwapRoute, formatAssetAmount, formatSui, formatUsd, fullHandle, generateKeypair, getAddress, getCoinMeta, getDecimals, getDecimalsForCoinType, getFinancialSummary, getPendingRewards, getPendingRewardsByAddress, getRates, getSponsoredSwapProviders, getSwapQuote, getTier, getVoloStats, isAllowedAsset, isCetusRouteFresh, isInRegistry, isSupported, isTier1, isTier2, keypairFromPrivateKey, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, naviDescriptor, normalizeAsset, normalizeCoinType, parseSuiRpcTx, queryHistory, queryTransaction, rawToStable, rawToUsdc, refineLendingLabel, resolveSymbol, resolveTokenType, saveKey, selectAndSplitCoin, selectSuiCoin, serializeCetusRoute, simulateTransaction, stableToRaw, suiToMist, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, validateLabel, verifyCetusRouteCoinMatch, walletExists };
8563
+ export { ALL_NAVI_ASSETS, AUDRIC_PARENT_NAME, AUDRIC_PARENT_NFT_ID, BORROW_FEE_BPS, BPS_DENOMINATOR, CETUS_USDC_SUI_POOL, CLOCK_ID, COIN_REGISTRY, ContactManager, DEFAULT_NETWORK, DEFAULT_SAFEGUARD_CONFIG, ETH_TYPE, GAS_RESERVE_MIN, HF_CRITICAL_THRESHOLD, HF_WARN_THRESHOLD, IKA_TYPE, InvalidAddressError, KNOWN_TARGETS, KeypairSigner, LABEL_PATTERNS, LOFI_TYPE, MANIFEST_TYPE, MIST_PER_SUI, NAVX_TYPE, NaviAdapter, OPERATION_ASSETS, OUTBOUND_OPS, OVERLAY_FEE_RATE, ProtocolRegistry, SAVE_FEE_BPS, SPONSORED_PYTH_DEPENDENT_PROVIDERS, STABLE_ASSETS, SUINS_NAME_REGEX, SUI_ADDRESS_REGEX, SUI_ADDRESS_STRICT_REGEX, SUI_DECIMALS, SUI_TYPE, SUPPORTED_ASSETS, SafeguardEnforcer, SafeguardError, SuinsNotRegisteredError, SuinsRpcError, T2000, T2000Error, T2000_OVERLAY_FEE_WALLET, TOKEN_MAP, USDC_DECIMALS, USDC_TYPE, USDE_TYPE, USDSUI_TYPE, USDT_TYPE, VOLO_METADATA, VOLO_PKG, VOLO_POOL, VSUI_TYPE, WAL_TYPE, WBTC_TYPE, WRITE_APPENDER_REGISTRY, ZkLoginSigner, addClaimRewardsToTx, addFeeTransfer, addSendToTx, addStakeVSuiToTx, addSwapToTx, addUnstakeVSuiToTx, aggregateClaimableRewards, allDescriptors, assertAllowedAsset, buildAddLeafTx, buildClaimRewardsTx, buildHarvestRewardsTx, buildRevokeLeafTx, buildSendTx, buildStakeVSuiTx, buildSwapTx, buildUnstakeVSuiTx, calculateFee, classifyAction, classifyLabel, classifyTransaction, composeTx, deriveAllowedAddressesFromPtb, deserializeCetusRoute, displayHandle, exportPrivateKey, extractAllUserLegs, extractTransferDetails, extractTxCommands, extractTxSender, fallbackLabel, fetchAllCoins, findSwapRoute, formatAssetAmount, formatSui, formatUsd, fullHandle, generateKeypair, getAddress, getCoinMeta, getDecimals, getDecimalsForCoinType, getFinancialSummary, getPendingRewards, getPendingRewardsByAddress, getRates, getSponsoredSwapProviders, getSwapQuote, getTier, getVoloStats, isAllowedAsset, isCetusRouteFresh, isInRegistry, isSupported, isTier1, isTier2, keypairFromPrivateKey, loadKey, looksLikeSuiNs, mapMoveAbortCode, mapWalletError, mistToSui, naviDescriptor, normalizeAddressInput, normalizeAsset, normalizeCoinType, parseSuiRpcTx, queryHistory, queryTransaction, rawToStable, rawToUsdc, refineLendingLabel, resolveAddressToSuinsViaRpc, resolveSuinsViaRpc, resolveSymbol, resolveTokenType, saveKey, selectAndSplitCoin, selectSuiCoin, serializeCetusRoute, simulateTransaction, stableToRaw, suiToMist, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, validateLabel, verifyCetusRouteCoinMatch, walletExists };
8383
8564
  //# sourceMappingURL=index.js.map
8384
8565
  //# sourceMappingURL=index.js.map