@t2000/cli 5.5.0 → 5.6.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.
Files changed (27) hide show
  1. package/dist/{chunk-YKME3ZZ5.js → chunk-64M2IV26.js} +5 -5
  2. package/dist/{chunk-V6MPPVOY.js → chunk-D6WAQS6U.js} +3 -3
  3. package/dist/{chunk-HRGEZK3M.js → chunk-I2DCISQP.js} +3 -3
  4. package/dist/{chunk-ZIKS3DOX.js → chunk-ITIKLNK5.js} +3 -3
  5. package/dist/{chunk-FORXEDQJ.js → chunk-MPXYF2CX.js} +1449 -1449
  6. package/dist/chunk-MPXYF2CX.js.map +1 -0
  7. package/dist/{dist-4JZ33TE5.js → dist-ULTRYNV7.js} +1977 -1899
  8. package/dist/dist-ULTRYNV7.js.map +1 -0
  9. package/dist/{dist-OPR66FUQ.js → dist-VXJH2WYL.js} +6 -6
  10. package/dist/{esm-EIRCX523.js → esm-RF62MWQV.js} +2 -2
  11. package/dist/{grpc-IINTSDGR.js → grpc-UMZJXRGY.js} +4 -4
  12. package/dist/index.js +127 -48
  13. package/dist/index.js.map +1 -1
  14. package/dist/{transactions-JPL6KL3D.js → transactions-FSCAFG5Z.js} +4 -4
  15. package/dist/{x402-TTLPDM7N.js → x402-EMQGKUTK.js} +4 -4
  16. package/package.json +3 -3
  17. package/dist/chunk-FORXEDQJ.js.map +0 -1
  18. package/dist/dist-4JZ33TE5.js.map +0 -1
  19. /package/dist/{chunk-YKME3ZZ5.js.map → chunk-64M2IV26.js.map} +0 -0
  20. /package/dist/{chunk-V6MPPVOY.js.map → chunk-D6WAQS6U.js.map} +0 -0
  21. /package/dist/{chunk-HRGEZK3M.js.map → chunk-I2DCISQP.js.map} +0 -0
  22. /package/dist/{chunk-ZIKS3DOX.js.map → chunk-ITIKLNK5.js.map} +0 -0
  23. /package/dist/{dist-OPR66FUQ.js.map → dist-VXJH2WYL.js.map} +0 -0
  24. /package/dist/{esm-EIRCX523.js.map → esm-RF62MWQV.js.map} +0 -0
  25. /package/dist/{grpc-IINTSDGR.js.map → grpc-UMZJXRGY.js.map} +0 -0
  26. /package/dist/{transactions-JPL6KL3D.js.map → transactions-FSCAFG5Z.js.map} +0 -0
  27. /package/dist/{x402-TTLPDM7N.js.map → x402-EMQGKUTK.js.map} +0 -0
@@ -171,12 +171,12 @@ import {
171
171
  processEndpoint,
172
172
  processFlattenRoutes,
173
173
  restituteMsafeFastRouterSwapParams
174
- } from "./chunk-YKME3ZZ5.js";
175
- import "./chunk-V6MPPVOY.js";
174
+ } from "./chunk-64M2IV26.js";
175
+ import "./chunk-D6WAQS6U.js";
176
176
  import "./chunk-OCLKPYUU.js";
177
- import "./chunk-ZIKS3DOX.js";
178
- import "./chunk-FORXEDQJ.js";
179
- import "./chunk-HRGEZK3M.js";
177
+ import "./chunk-ITIKLNK5.js";
178
+ import "./chunk-MPXYF2CX.js";
179
+ import "./chunk-I2DCISQP.js";
180
180
  import "./chunk-SVEVGZKZ.js";
181
181
  export {
182
182
  AFSUI,
@@ -351,4 +351,4 @@ export {
351
351
  processFlattenRoutes,
352
352
  restituteMsafeFastRouterSwapParams
353
353
  };
354
- //# sourceMappingURL=dist-OPR66FUQ.js.map
354
+ //# sourceMappingURL=dist-VXJH2WYL.js.map
@@ -14,7 +14,7 @@ import {
14
14
  randomBytes,
15
15
  toBase64,
16
16
  toHex
17
- } from "./chunk-HRGEZK3M.js";
17
+ } from "./chunk-I2DCISQP.js";
18
18
  import {
19
19
  __commonJS,
20
20
  __toESM
@@ -1081,4 +1081,4 @@ export {
1081
1081
  jwtToAddress2 as jwtToAddress,
1082
1082
  poseidonHash
1083
1083
  };
1084
- //# sourceMappingURL=esm-EIRCX523.js.map
1084
+ //# sourceMappingURL=esm-RF62MWQV.js.map
@@ -5,9 +5,9 @@ import {
5
5
  SuiGrpcClient,
6
6
  isSuiGrpcClient,
7
7
  types_exports
8
- } from "./chunk-V6MPPVOY.js";
9
- import "./chunk-FORXEDQJ.js";
10
- import "./chunk-HRGEZK3M.js";
8
+ } from "./chunk-D6WAQS6U.js";
9
+ import "./chunk-MPXYF2CX.js";
10
+ import "./chunk-I2DCISQP.js";
11
11
  import "./chunk-SVEVGZKZ.js";
12
12
  export {
13
13
  GrpcCoreClient,
@@ -16,4 +16,4 @@ export {
16
16
  SuiGrpcClient,
17
17
  isSuiGrpcClient
18
18
  };
19
- //# sourceMappingURL=grpc-IINTSDGR.js.map
19
+ //# sourceMappingURL=grpc-UMZJXRGY.js.map
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import { createRequire as __createRequire } from 'module'; import { fileURLToPat
3
3
  import {
4
4
  AggregatorClient,
5
5
  Env
6
- } from "./chunk-YKME3ZZ5.js";
6
+ } from "./chunk-64M2IV26.js";
7
7
  import {
8
8
  BalanceChange,
9
9
  BaseClient,
@@ -16,12 +16,12 @@ import {
16
16
  parseTransactionEffectsBcs,
17
17
  transactionDataToGrpcTransaction,
18
18
  transactionToGrpcJson
19
- } from "./chunk-V6MPPVOY.js";
19
+ } from "./chunk-D6WAQS6U.js";
20
20
  import "./chunk-OCLKPYUU.js";
21
21
  import {
22
22
  Transaction,
23
23
  coinWithBalance
24
- } from "./chunk-ZIKS3DOX.js";
24
+ } from "./chunk-ITIKLNK5.js";
25
25
  import {
26
26
  ObjectError,
27
27
  SUI_TYPE_ARG,
@@ -32,7 +32,7 @@ import {
32
32
  fromBase64 as fromBase642,
33
33
  suiBcs,
34
34
  toBase64 as toBase642
35
- } from "./chunk-FORXEDQJ.js";
35
+ } from "./chunk-MPXYF2CX.js";
36
36
  import {
37
37
  SIGNATURE_FLAG_TO_SCHEME,
38
38
  SIGNATURE_SCHEME_TO_FLAG,
@@ -83,7 +83,7 @@ import {
83
83
  split,
84
84
  toBase64,
85
85
  toHex
86
- } from "./chunk-HRGEZK3M.js";
86
+ } from "./chunk-I2DCISQP.js";
87
87
  import {
88
88
  __commonJS,
89
89
  __require,
@@ -26692,6 +26692,38 @@ var init_errors = __esm({
26692
26692
  };
26693
26693
  }
26694
26694
  });
26695
+ function preflightFail(code, error) {
26696
+ return { valid: false, code, error };
26697
+ }
26698
+ function checkPositiveAmount(amount, label = "Amount", max = PREFLIGHT_MAX_AMOUNT) {
26699
+ if (typeof amount !== "number" || !Number.isFinite(amount)) {
26700
+ return preflightFail("INVALID_AMOUNT", `${label} must be a finite number`);
26701
+ }
26702
+ if (amount <= 0) {
26703
+ return preflightFail("INVALID_AMOUNT", `${label} must be greater than zero`);
26704
+ }
26705
+ if (amount > max) {
26706
+ return preflightFail("INVALID_AMOUNT", `${label} ${amount} exceeds the sane maximum (${max})`);
26707
+ }
26708
+ return PREFLIGHT_OK;
26709
+ }
26710
+ function checkSuiAddress(address, label = "recipient") {
26711
+ try {
26712
+ if (typeof address === "string" && address.trim() !== "" && isValidSuiAddress(normalizeSuiAddress(address))) {
26713
+ return PREFLIGHT_OK;
26714
+ }
26715
+ } catch {
26716
+ }
26717
+ return preflightFail("INVALID_ADDRESS", `Invalid ${label} address: ${address}`);
26718
+ }
26719
+ var PREFLIGHT_MAX_AMOUNT;
26720
+ var PREFLIGHT_OK;
26721
+ var init_preflight = __esm({
26722
+ "src/preflight.ts"() {
26723
+ PREFLIGHT_MAX_AMOUNT = 1e6;
26724
+ PREFLIGHT_OK = { valid: true };
26725
+ }
26726
+ });
26695
26727
  var token_registry_exports = {};
26696
26728
  __export(token_registry_exports, {
26697
26729
  COIN_REGISTRY: () => COIN_REGISTRY,
@@ -26965,10 +26997,28 @@ __export(cetus_swap_exports, {
26965
26997
  findSwapRoute: () => findSwapRoute,
26966
26998
  isCetusRouteFresh: () => isCetusRouteFresh,
26967
26999
  isPrecomputedRouteCompatibleWithProviders: () => isPrecomputedRouteCompatibleWithProviders,
27000
+ preflightSwap: () => preflightSwap,
26968
27001
  resolveTokenType: () => resolveTokenType,
26969
27002
  serializeCetusRoute: () => serializeCetusRoute,
26970
27003
  verifyCetusRouteCoinMatch: () => verifyCetusRouteCoinMatch
26971
27004
  });
27005
+ function preflightSwap(input) {
27006
+ if (typeof input.from !== "string" || input.from.trim() === "") {
27007
+ return preflightFail("INVALID_ASSET", "A `from` token is required to swap");
27008
+ }
27009
+ if (typeof input.to !== "string" || input.to.trim() === "") {
27010
+ return preflightFail("INVALID_ASSET", "A `to` token is required to swap");
27011
+ }
27012
+ const amountCheck = checkPositiveAmount(input.amount, "Amount", Number.POSITIVE_INFINITY);
27013
+ if (!amountCheck.valid) return amountCheck;
27014
+ const resolvedFrom = resolveTokenType(input.from);
27015
+ const resolvedTo = resolveTokenType(input.to);
27016
+ const sameToken = input.from.trim() === input.to.trim() || resolvedFrom !== null && resolvedFrom === resolvedTo;
27017
+ if (sameToken) {
27018
+ return preflightFail("INVALID_ASSET", `Cannot swap ${input.from} to itself`);
27019
+ }
27020
+ return PREFLIGHT_OK;
27021
+ }
26972
27022
  function serializeCetusRoute(route, context) {
26973
27023
  return {
26974
27024
  routerData: serializeRouterDataV3(route.routerData),
@@ -27221,6 +27271,7 @@ var clientCache;
27221
27271
  var init_cetus_swap = __esm({
27222
27272
  "src/protocols/cetus-swap.ts"() {
27223
27273
  init_token_registry();
27274
+ init_preflight();
27224
27275
  init_token_registry();
27225
27276
  OVERLAY_FEE_RATE = 1e-3;
27226
27277
  clientCache = /* @__PURE__ */ new Map();
@@ -27567,8 +27618,33 @@ async function executeTx(client, signer, buildTx, options = {}) {
27567
27618
  return { digest: txn.digest, gasCostSui, effects };
27568
27619
  }
27569
27620
  init_errors();
27621
+ init_preflight();
27622
+ function preflightPay(input) {
27623
+ if (typeof input.url !== "string" || input.url.trim() === "") {
27624
+ return preflightFail("FACILITATOR_REJECTION", "A target URL is required to pay");
27625
+ }
27626
+ let parsed;
27627
+ try {
27628
+ parsed = new URL(input.url);
27629
+ } catch {
27630
+ return preflightFail("FACILITATOR_REJECTION", `Invalid URL: ${input.url}`);
27631
+ }
27632
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
27633
+ return preflightFail(
27634
+ "FACILITATOR_REJECTION",
27635
+ `URL must be http(s): got ${parsed.protocol}//`
27636
+ );
27637
+ }
27638
+ if (input.maxPrice !== void 0) {
27639
+ const priceCheck = checkPositiveAmount(input.maxPrice, "maxPrice");
27640
+ if (!priceCheck.valid) return priceCheck;
27641
+ }
27642
+ return PREFLIGHT_OK;
27643
+ }
27570
27644
  async function payWithMpp(args) {
27571
27645
  const { signer, client, options } = args;
27646
+ const pf = preflightPay({ url: options.url, maxPrice: options.maxPrice });
27647
+ if (!pf.valid) throw new T2000Error(pf.code, pf.error);
27572
27648
  const method = (options.method ?? "GET").toUpperCase();
27573
27649
  const canHaveBody = method !== "GET" && method !== "HEAD";
27574
27650
  const reqInit = {
@@ -27600,7 +27676,7 @@ async function pickSuiExactRequirements(response, network) {
27600
27676
  }
27601
27677
  async function payViaX402(args) {
27602
27678
  const { signer, client, options, reqInit, requirements } = args;
27603
- const { buildX402SignedPayment, X402_PAYMENT_HEADER, X402_PAYMENT_RESPONSE_HEADER } = await import("./x402-TTLPDM7N.js");
27679
+ const { buildX402SignedPayment, X402_PAYMENT_HEADER, X402_PAYMENT_RESPONSE_HEADER } = await import("./x402-EMQGKUTK.js");
27604
27680
  const amountRaw = BigInt(requirements.maxAmountRequired);
27605
27681
  const migrationGasSui = await ensureAddressBalanceCovers({
27606
27682
  signer,
@@ -27660,7 +27736,7 @@ async function ensureAddressBalanceCovers(args) {
27660
27736
  const addressBalance = total - coinSum;
27661
27737
  if (addressBalance >= amountRaw) return 0;
27662
27738
  const shortfall = amountRaw - addressBalance;
27663
- const { Transaction: Transaction6 } = await import("./transactions-JPL6KL3D.js");
27739
+ const { Transaction: Transaction6 } = await import("./transactions-FSCAFG5Z.js");
27664
27740
  const { selectAndSplitCoin: selectAndSplitCoin2 } = await Promise.resolve().then(() => (init_coinSelection(), coinSelection_exports));
27665
27741
  const grpcClient = await makeGrpcBuildClient(client);
27666
27742
  const migration = await executeTx(
@@ -27695,7 +27771,7 @@ async function finalize(response, opts) {
27695
27771
  return { status: response.status, body, paid: opts.paid };
27696
27772
  }
27697
27773
  async function makeGrpcBuildClient(client) {
27698
- const { SuiGrpcClient: SuiGrpcClient2 } = await import("./grpc-IINTSDGR.js");
27774
+ const { SuiGrpcClient: SuiGrpcClient2 } = await import("./grpc-UMZJXRGY.js");
27699
27775
  const network = client.network === "testnet" ? "testnet" : "mainnet";
27700
27776
  const baseUrl = network === "testnet" ? "https://fullnode.testnet.sui.io" : "https://fullnode.mainnet.sui.io";
27701
27777
  return new SuiGrpcClient2({ baseUrl, network });
@@ -27723,7 +27799,7 @@ var ZkLoginSigner = class {
27723
27799
  return this.userAddress;
27724
27800
  }
27725
27801
  async signTransaction(txBytes) {
27726
- const { getZkLoginSignature } = await import("./esm-EIRCX523.js");
27802
+ const { getZkLoginSignature } = await import("./esm-RF62MWQV.js");
27727
27803
  const ephSig = await this.ephemeralKeypair.signTransaction(txBytes);
27728
27804
  return {
27729
27805
  signature: getZkLoginSignature({
@@ -27734,7 +27810,7 @@ var ZkLoginSigner = class {
27734
27810
  };
27735
27811
  }
27736
27812
  async signPersonalMessage(messageBytes) {
27737
- const { getZkLoginSignature } = await import("./esm-EIRCX523.js");
27813
+ const { getZkLoginSignature } = await import("./esm-RF62MWQV.js");
27738
27814
  const { signature: ephSig, bytes } = await this.ephemeralKeypair.signPersonalMessage(messageBytes);
27739
27815
  return {
27740
27816
  signature: getZkLoginSignature({
@@ -27763,6 +27839,25 @@ for (const [key, info] of Object.entries(SUPPORTED_ASSETS)) {
27763
27839
  ASSET_LOOKUP.set(info.displayName.toUpperCase(), key);
27764
27840
  }
27765
27841
  }
27842
+ init_preflight();
27843
+ function preflightSend(input) {
27844
+ try {
27845
+ assertAllowedAsset("send", input.asset);
27846
+ } catch (e) {
27847
+ return preflightFail("INVALID_ASSET", e.message);
27848
+ }
27849
+ const amountCheck = checkPositiveAmount(input.amount);
27850
+ if (!amountCheck.valid) return amountCheck;
27851
+ if ((input.asset === "USDC" || input.asset === "USDsui") && input.amount < GASLESS_MIN_STABLE_AMOUNT) {
27852
+ return preflightFail(
27853
+ "INVALID_AMOUNT",
27854
+ `Minimum gasless transfer is ${GASLESS_MIN_STABLE_AMOUNT} ${input.asset}. Got ${input.amount}.`
27855
+ );
27856
+ }
27857
+ const addressCheck = checkSuiAddress(input.to);
27858
+ if (!addressCheck.valid) return addressCheck;
27859
+ return PREFLIGHT_OK;
27860
+ }
27766
27861
  async function buildSendTx({
27767
27862
  client,
27768
27863
  address,
@@ -27770,17 +27865,11 @@ async function buildSendTx({
27770
27865
  amount,
27771
27866
  asset
27772
27867
  }) {
27773
- assertAllowedAsset("send", asset);
27868
+ const pf = preflightSend({ to, amount, asset });
27869
+ if (!pf.valid) throw new T2000Error(pf.code, pf.error);
27774
27870
  const recipient = validateAddress(to);
27775
27871
  const assetInfo = SUPPORTED_ASSETS[asset];
27776
27872
  if (!assetInfo) throw new T2000Error("ASSET_NOT_SUPPORTED", `Asset ${asset} is not supported`);
27777
- if (amount <= 0) throw new T2000Error("INVALID_AMOUNT", "Amount must be greater than zero");
27778
- if ((asset === "USDC" || asset === "USDsui") && amount < GASLESS_MIN_STABLE_AMOUNT) {
27779
- throw new T2000Error(
27780
- "INVALID_AMOUNT",
27781
- `Minimum gasless transfer is ${GASLESS_MIN_STABLE_AMOUNT} ${asset}. Got ${amount}.`
27782
- );
27783
- }
27784
27873
  const rawAmount = displayToRaw(amount, assetInfo.decimals);
27785
27874
  const tx = new Transaction();
27786
27875
  tx.setSender(address);
@@ -28067,7 +28156,7 @@ var TX_NODE_FRAGMENT = `
28067
28156
  }
28068
28157
  `;
28069
28158
  var HISTORY_QUERY = `query History($address: SuiAddress!, $last: Int!) {
28070
- transactions(last: $last, filter: { sentAddress: $address }) {
28159
+ transactions(last: $last, filter: { affectedAddress: $address }) {
28071
28160
  nodes {${TX_NODE_FRAGMENT}}
28072
28161
  }
28073
28162
  }`;
@@ -28137,7 +28226,9 @@ function buildRecord(args) {
28137
28226
  return { digest, action, label, legs, amount, asset, recipient, direction, timestamp: timestampMs, gasCost };
28138
28227
  }
28139
28228
  init_token_registry();
28140
- var SUI_MAINNET_URL = "https://fullnode.mainnet.sui.io:443";
28229
+ var RESOLVE_NAME_QUERY = `query ResolveSuins($name: String!) {
28230
+ address(name: $name) { address }
28231
+ }`;
28141
28232
  var SUI_ADDRESS_REGEX = /^0x[a-fA-F0-9]{1,64}$/i;
28142
28233
  var SUINS_NAME_REGEX = /^[a-z0-9-]+(\.[a-z0-9-]+)*\.sui$/;
28143
28234
  var InvalidAddressError = class extends Error {
@@ -28174,38 +28265,22 @@ async function resolveSuinsViaRpc(rawName, ctx = {}) {
28174
28265
  if (!SUINS_NAME_REGEX.test(name)) {
28175
28266
  throw new InvalidAddressError(rawName);
28176
28267
  }
28177
- const url = ctx.suiRpcUrl || SUI_MAINNET_URL;
28268
+ const gql = getSuiGraphQLClient();
28178
28269
  let res;
28179
28270
  try {
28180
- res = await fetch(url, {
28181
- method: "POST",
28182
- headers: { "Content-Type": "application/json" },
28183
- body: JSON.stringify({
28184
- jsonrpc: "2.0",
28185
- id: 1,
28186
- method: "suix_resolveNameServiceAddress",
28187
- params: [name]
28188
- }),
28189
- signal: ctx.signal ?? AbortSignal.timeout(8e3)
28271
+ res = await gql.query({
28272
+ query: RESOLVE_NAME_QUERY,
28273
+ variables: { name },
28274
+ signal: ctx.signal
28190
28275
  });
28191
28276
  } catch (err) {
28192
28277
  const msg = err instanceof Error ? err.message : String(err);
28193
28278
  throw new SuinsRpcError(name, msg);
28194
28279
  }
28195
- if (!res.ok) {
28196
- throw new SuinsRpcError(name, `HTTP ${res.status}`);
28197
- }
28198
- let body;
28199
- try {
28200
- body = await res.json();
28201
- } catch (err) {
28202
- const msg = err instanceof Error ? err.message : String(err);
28203
- throw new SuinsRpcError(name, `JSON parse failed: ${msg}`);
28204
- }
28205
- if (body.error) {
28206
- throw new SuinsRpcError(name, body.error.message);
28280
+ if (res.errors?.length) {
28281
+ throw new SuinsRpcError(name, res.errors.map((e) => e.message ?? "unknown error").join("; "));
28207
28282
  }
28208
- return body.result ?? null;
28283
+ return res.data?.address?.address ?? null;
28209
28284
  }
28210
28285
  init_errors();
28211
28286
  var DEFAULT_CONFIG_DIR = join2(homedir(), ".t2000");
@@ -28477,7 +28552,9 @@ var T2000 = class _T2000 extends import_index2.default {
28477
28552
  amountUsd: approxUsdValue(params.from, params.amount) ?? 0,
28478
28553
  force: params.force
28479
28554
  });
28480
- const { findSwapRoute: findSwapRoute2, buildSwapTx: buildSwapTx2, resolveTokenType: resolveTokenType2 } = await Promise.resolve().then(() => (init_cetus_swap(), cetus_swap_exports));
28555
+ const { findSwapRoute: findSwapRoute2, buildSwapTx: buildSwapTx2, resolveTokenType: resolveTokenType2, preflightSwap: preflightSwap2 } = await Promise.resolve().then(() => (init_cetus_swap(), cetus_swap_exports));
28556
+ const pf = preflightSwap2({ from: params.from, to: params.to, amount: params.amount });
28557
+ if (!pf.valid) throw new T2000Error(pf.code, pf.error);
28481
28558
  const fromType = resolveTokenType2(params.from);
28482
28559
  const toType = resolveTokenType2(params.to);
28483
28560
  if (!fromType) throw new T2000Error("ASSET_NOT_SUPPORTED", `Unknown token: ${params.from}. Provide the full coin type.`);
@@ -28811,6 +28888,7 @@ init_errors();
28811
28888
  init_swap_quote();
28812
28889
  init_cetus_swap();
28813
28890
  init_token_registry();
28891
+ init_preflight();
28814
28892
 
28815
28893
  // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@20.19.37/node_modules/@inquirer/core/dist/esm/lib/key.js
28816
28894
  var isUpKey = (key, keybindings = []) => (
@@ -31452,9 +31530,9 @@ function printTxSummary(tx) {
31452
31530
  const label = ACTION_LABELS[tx.action] ?? `\u{1F4E6} ${tx.action}`;
31453
31531
  const time = tx.timestamp ? relativeTime(tx.timestamp) : "";
31454
31532
  const amount = formatAmount(tx);
31455
- const recipient = tx.recipient ? import_picocolors4.default.dim(`\u2192 ${truncateAddress(tx.recipient)}`) : "";
31533
+ const direction = tx.direction === "in" ? import_picocolors4.default.green("\u2190 received") : tx.recipient ? import_picocolors4.default.dim(`\u2192 ${truncateAddress(tx.recipient)}`) : "";
31456
31534
  const link = import_picocolors4.default.dim(explorerUrl(tx.digest));
31457
- printLine(`${label} ${amount} ${recipient}`);
31535
+ printLine(`${label} ${amount} ${direction}`);
31458
31536
  printLine(` ${import_picocolors4.default.dim(truncateAddress(tx.digest))} ${import_picocolors4.default.dim(time)}`);
31459
31537
  printLine(` ${link}`);
31460
31538
  }
@@ -31464,6 +31542,7 @@ function printTxDetail(tx) {
31464
31542
  printKeyValue("Type", label);
31465
31543
  printKeyValue("Digest", tx.digest);
31466
31544
  if (tx.amount) printKeyValue("Amount", `${tx.amount.toFixed(tx.amount < 0.01 ? 6 : 4)} ${tx.asset ?? ""}`);
31545
+ if (tx.direction) printKeyValue("Direction", tx.direction === "in" ? "Received" : "Sent");
31467
31546
  if (tx.recipient) printKeyValue("Recipient", tx.recipient);
31468
31547
  if (tx.timestamp) {
31469
31548
  printKeyValue("Time", `${new Date(tx.timestamp).toLocaleString()} (${relativeTime(tx.timestamp)})`);
@@ -32403,7 +32482,7 @@ function registerMcpStart(parent) {
32403
32482
  parent.command("start", { isDefault: true }).description("Start MCP server (stdio transport \u2014 for AI client integration)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(async (opts) => {
32404
32483
  let mod2;
32405
32484
  try {
32406
- mod2 = await import("./dist-4JZ33TE5.js");
32485
+ mod2 = await import("./dist-ULTRYNV7.js");
32407
32486
  } catch {
32408
32487
  console.error("MCP server not installed. Run:\n npm install -g @t2000/mcp");
32409
32488
  process.exit(1);