@t2000/cli 0.23.0 → 0.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,14 +19,23 @@ import {
19
19
  SafeguardError,
20
20
  T2000,
21
21
  T2000Error,
22
+ TOKEN_MAP,
22
23
  USDC_DECIMALS,
24
+ VOLO_METADATA,
25
+ VOLO_PKG,
26
+ VOLO_POOL,
27
+ VSUI_TYPE,
23
28
  ZkLoginSigner,
24
29
  addCollectFeeToTx,
25
30
  allDescriptors,
31
+ buildStakeVSuiTx,
32
+ buildSwapTx,
33
+ buildUnstakeVSuiTx,
26
34
  calculateFee,
27
35
  executeAutoTopUp,
28
36
  executeWithGas,
29
37
  exportPrivateKey,
38
+ findSwapRoute,
30
39
  formatAssetAmount,
31
40
  formatSui,
32
41
  formatUsd,
@@ -35,6 +44,8 @@ import {
35
44
  getDecimals,
36
45
  getGasStatus,
37
46
  getRates,
47
+ getSwapQuote,
48
+ getVoloStats,
38
49
  keypairFromPrivateKey,
39
50
  loadKey,
40
51
  mapMoveAbortCode,
@@ -43,6 +54,7 @@ import {
43
54
  naviDescriptor,
44
55
  rawToStable,
45
56
  rawToUsdc,
57
+ resolveTokenType,
46
58
  saveKey,
47
59
  shouldAutoTopUp,
48
60
  simulateTransaction,
@@ -54,9 +66,9 @@ import {
54
66
  usdcToRaw,
55
67
  validateAddress,
56
68
  walletExists
57
- } from "./chunk-4N76GQCL.js";
69
+ } from "./chunk-NVVRO5EM.js";
58
70
  import "./chunk-V7PXDEKG.js";
59
- import "./chunk-DWOZSUBE.js";
71
+ import "./chunk-Q2LY5BHK.js";
60
72
  import "./chunk-3XUF7GM3.js";
61
73
  import "./chunk-YPWSCLE3.js";
62
74
  export {
@@ -79,14 +91,23 @@ export {
79
91
  SafeguardError,
80
92
  T2000,
81
93
  T2000Error,
94
+ TOKEN_MAP,
82
95
  USDC_DECIMALS,
96
+ VOLO_METADATA,
97
+ VOLO_PKG,
98
+ VOLO_POOL,
99
+ VSUI_TYPE,
83
100
  ZkLoginSigner,
84
101
  addCollectFeeToTx,
85
102
  allDescriptors,
103
+ buildStakeVSuiTx,
104
+ buildSwapTx,
105
+ buildUnstakeVSuiTx,
86
106
  calculateFee,
87
107
  executeAutoTopUp,
88
108
  executeWithGas,
89
109
  exportPrivateKey,
110
+ findSwapRoute,
90
111
  formatAssetAmount,
91
112
  formatSui,
92
113
  formatUsd,
@@ -95,6 +116,8 @@ export {
95
116
  getDecimals,
96
117
  getGasStatus,
97
118
  getRates,
119
+ getSwapQuote,
120
+ getVoloStats,
98
121
  keypairFromPrivateKey,
99
122
  loadKey,
100
123
  mapMoveAbortCode,
@@ -103,6 +126,7 @@ export {
103
126
  naviDescriptor,
104
127
  rawToStable,
105
128
  rawToUsdc,
129
+ resolveTokenType,
106
130
  saveKey,
107
131
  shouldAutoTopUp,
108
132
  simulateTransaction,
@@ -115,4 +139,4 @@ export {
115
139
  validateAddress,
116
140
  walletExists
117
141
  };
118
- //# sourceMappingURL=dist-E7HUP73Q.js.map
142
+ //# sourceMappingURL=dist-OCRGWGZT.js.map
package/dist/index.js CHANGED
@@ -17,9 +17,9 @@ import {
17
17
  saveKey,
18
18
  truncateAddress,
19
19
  walletExists
20
- } from "./chunk-4N76GQCL.js";
20
+ } from "./chunk-NVVRO5EM.js";
21
21
  import "./chunk-V7PXDEKG.js";
22
- import "./chunk-DWOZSUBE.js";
22
+ import "./chunk-Q2LY5BHK.js";
23
23
  import "./chunk-3XUF7GM3.js";
24
24
  import {
25
25
  __commonJS,
@@ -4090,13 +4090,14 @@ function registerSave(program3) {
4090
4090
  if (amount !== "all" && (isNaN(amount) || amount <= 0)) {
4091
4091
  throw new Error('Amount must be a positive number or "all"');
4092
4092
  }
4093
+ const asset = opts.asset?.toUpperCase() ?? "USDC";
4093
4094
  const pin = await resolvePin();
4094
4095
  const agent = await T2000.create({ pin, keyPath: opts.key });
4095
4096
  let gasManagerUsdc = 0;
4096
4097
  agent.on("gasAutoTopUp", (data) => {
4097
4098
  gasManagerUsdc = data.usdcSpent;
4098
4099
  });
4099
- const result = await agent.save({ amount, protocol: opts.protocol });
4100
+ const result = await agent.save({ amount, asset, protocol: opts.protocol });
4100
4101
  if (isJsonMode()) {
4101
4102
  printJson(result);
4102
4103
  return;
@@ -4106,26 +4107,26 @@ function registerSave(program3) {
4106
4107
  printSuccess(`Gas manager: ${import_picocolors5.default.yellow(formatUsd(gasManagerUsdc))} USDC \u2192 SUI`);
4107
4108
  }
4108
4109
  const protocolName = opts.protocol ?? "best rate";
4109
- printSuccess(`Saved ${import_picocolors5.default.yellow(formatUsd(result.amount))} USDC to ${protocolName}`);
4110
+ printSuccess(`Saved ${import_picocolors5.default.yellow(formatUsd(result.amount))} ${asset} to ${protocolName}`);
4110
4111
  if (result.fee > 0) {
4111
4112
  const feeRate = (result.fee / result.amount * 100).toFixed(1);
4112
- printSuccess(`Protocol fee: ${import_picocolors5.default.dim(`${formatUsd(result.fee)} USDC (${feeRate}%)`)}`);
4113
+ printSuccess(`Protocol fee: ${import_picocolors5.default.dim(`${formatUsd(result.fee)} ${asset} (${feeRate}%)`)}`);
4113
4114
  }
4114
4115
  printSuccess(`Current APY: ${import_picocolors5.default.green(`${result.apy.toFixed(2)}%`)}`);
4115
- printSuccess(`Savings balance: ${import_picocolors5.default.yellow(formatUsd(result.savingsBalance))} USDC`);
4116
+ printSuccess(`Savings balance: ${import_picocolors5.default.yellow(formatUsd(result.savingsBalance))} ${asset}`);
4116
4117
  printKeyValue("Tx", explorerUrl(result.tx));
4117
4118
  printBlank();
4118
4119
  } catch (error) {
4119
4120
  handleError(error);
4120
4121
  }
4121
4122
  };
4122
- program3.command("save").description("Deposit USDC into savings").argument("<amount>", 'Amount to save (or "all")').option("--key <path>", "Key file path").option("--protocol <name>", "Protocol to use (e.g. navi)").action(action);
4123
- program3.command("supply").description("Deposit USDC into savings (alias for save)").argument("<amount>", 'Amount to save (or "all")').option("--key <path>", "Key file path").option("--protocol <name>", "Protocol to use (e.g. navi)").action(action);
4123
+ program3.command("save").description("Deposit into NAVI lending to earn yield (USDC, USDT, SUI, USDe, USDsui)").argument("<amount>", 'Amount to save (or "all")').option("--key <path>", "Key file path").option("--protocol <name>", "Protocol to use (e.g. navi)").option("--asset <token>", "Asset to deposit (default: USDC)").action(action);
4124
+ program3.command("supply").description("Deposit into NAVI lending (alias for save)").argument("<amount>", 'Amount to save (or "all")').option("--key <path>", "Key file path").option("--protocol <name>", "Protocol to use (e.g. navi)").option("--asset <token>", "Asset to deposit (default: USDC)").action(action);
4124
4125
  }
4125
4126
 
4126
4127
  // src/commands/withdraw.ts
4127
4128
  function registerWithdraw(program3) {
4128
- program3.command("withdraw").description("Withdraw USDC from savings").argument("<amount>", 'Amount to withdraw (or "all")').option("--key <path>", "Key file path").option("--protocol <name>", "Protocol to use (e.g. navi)").action(async (amountStr, opts) => {
4129
+ program3.command("withdraw").description("Withdraw from NAVI lending (USDC, USDT, SUI, USDe, USDsui)").argument("<amount>", 'Amount to withdraw (or "all")').option("--key <path>", "Key file path").option("--protocol <name>", "Protocol to use (e.g. navi)").option("--asset <token>", "Asset to withdraw (default: auto-detect)").action(async (amountStr, opts) => {
4129
4130
  try {
4130
4131
  const amount = amountStr === "all" ? "all" : parseFloat(amountStr);
4131
4132
  if (amount !== "all" && (isNaN(amount) || amount <= 0)) {
@@ -4133,13 +4134,14 @@ function registerWithdraw(program3) {
4133
4134
  }
4134
4135
  const pin = await resolvePin();
4135
4136
  const agent = await T2000.create({ pin, keyPath: opts.key });
4136
- const result = await agent.withdraw({ amount, protocol: opts.protocol });
4137
+ const result = await agent.withdraw({ amount, asset: opts.asset, protocol: opts.protocol });
4137
4138
  if (isJsonMode()) {
4138
4139
  printJson(result);
4139
4140
  return;
4140
4141
  }
4142
+ const assetLabel = opts.asset ?? "USDC";
4141
4143
  printBlank();
4142
- printSuccess(`Withdrew ${formatUsd(result.amount)} USDC`);
4144
+ printSuccess(`Withdrew ${formatUsd(result.amount)} ${assetLabel}`);
4143
4145
  printKeyValue("Tx", explorerUrl(result.tx));
4144
4146
  printBlank();
4145
4147
  } catch (error) {
@@ -7834,7 +7836,7 @@ function registerLock(program3) {
7834
7836
  });
7835
7837
  program3.command("unlock").description("Unlock agent \u2014 resume operations").action(async () => {
7836
7838
  try {
7837
- const { T2000: T20003 } = await import("./dist-E7HUP73Q.js");
7839
+ const { T2000: T20003 } = await import("./dist-OCRGWGZT.js");
7838
7840
  const MAX_ATTEMPTS2 = 3;
7839
7841
  let pin;
7840
7842
  for (let attempt = 1; attempt <= MAX_ATTEMPTS2; attempt++) {
@@ -8008,7 +8010,7 @@ function registerMcp(program3) {
8008
8010
  mcp.command("start", { isDefault: true }).description("Start MCP server (stdio transport)").option("--key <path>", "Key file path").action(async (opts) => {
8009
8011
  let mod;
8010
8012
  try {
8011
- mod = await import("./dist-W4Q4YXD7.js");
8013
+ mod = await import("./dist-I2SVTLMJ.js");
8012
8014
  } catch {
8013
8015
  console.error(
8014
8016
  "MCP server not installed. Run:\n npm install -g @t2000/mcp"
@@ -8260,6 +8262,132 @@ function registerGas(program3) {
8260
8262
  });
8261
8263
  }
8262
8264
 
8265
+ // src/commands/swap.ts
8266
+ var import_picocolors14 = __toESM(require_picocolors(), 1);
8267
+ function registerSwap(program3) {
8268
+ program3.command("swap").description("Swap tokens via Cetus Aggregator (20+ DEXs)").argument("<amount>", "Amount to swap").argument("<from>", "Source token (e.g. SUI, USDC, CETUS)").argument("[to_keyword]", '"for" keyword (optional)').argument("<to>", "Target token (e.g. USDC, SUI, DEEP)").option("--slippage <pct>", "Max slippage percentage (default: 1)", "1").option("--key <path>", "Key file path").action(async (amountStr, from, toKeywordOrTo, to, opts) => {
8269
+ try {
8270
+ const amount = parseFloat(amountStr);
8271
+ if (isNaN(amount) || amount <= 0) {
8272
+ throw new Error("Amount must be a positive number");
8273
+ }
8274
+ if (toKeywordOrTo?.toLowerCase() === "for" && !to) {
8275
+ throw new Error("Usage: t2000 swap <amount> <from> [for] <to>");
8276
+ }
8277
+ const actualTo = to ?? toKeywordOrTo;
8278
+ const slippage = Math.min(parseFloat(opts.slippage ?? "1") / 100, 0.05);
8279
+ const pin = await resolvePin();
8280
+ const agent = await T2000.create({ pin, keyPath: opts.key });
8281
+ const result = await agent.swap({ from, to: actualTo, amount, slippage });
8282
+ if (isJsonMode()) {
8283
+ printJson(result);
8284
+ return;
8285
+ }
8286
+ printBlank();
8287
+ printSuccess(`Swapped ${import_picocolors14.default.yellow(String(result.fromAmount))} ${result.fromToken} for ${import_picocolors14.default.green(result.toAmount.toFixed(4))} ${result.toToken}`);
8288
+ if (result.priceImpact > 5e-3) {
8289
+ printKeyValue("Price Impact", import_picocolors14.default.yellow(`${(result.priceImpact * 100).toFixed(2)}%`));
8290
+ }
8291
+ printKeyValue("Route", `${result.fromToken} \u2192 ${result.toToken} (${result.route})`);
8292
+ printKeyValue("Gas", `${result.gasCost.toFixed(4)} SUI (${result.gasMethod})`);
8293
+ printKeyValue("Tx", explorerUrl(result.tx));
8294
+ printBlank();
8295
+ } catch (error) {
8296
+ handleError(error);
8297
+ }
8298
+ });
8299
+ }
8300
+
8301
+ // src/commands/swapQuote.ts
8302
+ var import_picocolors15 = __toESM(require_picocolors(), 1);
8303
+ function registerSwapQuote(program3) {
8304
+ program3.command("swap-quote").description("Preview a swap quote without executing (shows output, price impact, route)").argument("<amount>", "Amount to swap").argument("<from>", "Source token (e.g. SUI, USDC)").argument("[to_keyword]", '"for" keyword (optional)').argument("<to>", "Target token (e.g. USDC, SUI)").option("--key <path>", "Key file path").action(async (amountStr, from, toKeywordOrTo, to, opts) => {
8305
+ try {
8306
+ const amount = parseFloat(amountStr);
8307
+ if (isNaN(amount) || amount <= 0) {
8308
+ throw new Error("Amount must be a positive number");
8309
+ }
8310
+ if (toKeywordOrTo?.toLowerCase() === "for" && !to) {
8311
+ throw new Error("Usage: t2000 swap-quote <amount> <from> [for] <to>");
8312
+ }
8313
+ const actualTo = to ?? toKeywordOrTo;
8314
+ const pin = await resolvePin();
8315
+ const agent = await T2000.create({ pin, keyPath: opts.key });
8316
+ const result = await agent.swapQuote({ from, to: actualTo, amount });
8317
+ if (isJsonMode()) {
8318
+ printJson(result);
8319
+ return;
8320
+ }
8321
+ printBlank();
8322
+ printKeyValue("Input", `${result.fromAmount} ${result.fromToken}`);
8323
+ printKeyValue("Output", import_picocolors15.default.green(`${result.toAmount.toFixed(6)} ${result.toToken}`));
8324
+ if (result.priceImpact > 1e-3) {
8325
+ printKeyValue("Price Impact", import_picocolors15.default.yellow(`${(result.priceImpact * 100).toFixed(2)}%`));
8326
+ }
8327
+ printKeyValue("Route", `${result.fromToken} \u2192 ${result.toToken} (${result.route})`);
8328
+ printBlank();
8329
+ } catch (error) {
8330
+ handleError(error);
8331
+ }
8332
+ });
8333
+ }
8334
+
8335
+ // src/commands/stake.ts
8336
+ var import_picocolors16 = __toESM(require_picocolors(), 1);
8337
+ function registerStake(program3) {
8338
+ program3.command("stake").description("Stake SUI for vSUI via VOLO liquid staking (earn ~3-5% APY)").argument("<amount>", "Amount of SUI to stake (minimum 1)").option("--key <path>", "Key file path").action(async (amountStr, opts) => {
8339
+ try {
8340
+ const amount = parseFloat(amountStr);
8341
+ if (isNaN(amount) || amount < 1) {
8342
+ throw new Error("Amount must be at least 1 SUI");
8343
+ }
8344
+ const pin = await resolvePin();
8345
+ const agent = await T2000.create({ pin, keyPath: opts.key });
8346
+ const result = await agent.stakeVSui({ amount });
8347
+ if (isJsonMode()) {
8348
+ printJson(result);
8349
+ return;
8350
+ }
8351
+ printBlank();
8352
+ printSuccess(`Staked ${import_picocolors16.default.yellow(String(result.amountSui))} SUI for ${import_picocolors16.default.green(result.vSuiReceived.toFixed(4))} vSUI`);
8353
+ printSuccess(`APY: ${import_picocolors16.default.green(`${(result.apy * 100).toFixed(2)}%`)}`);
8354
+ printKeyValue("Gas", `${result.gasCost.toFixed(4)} SUI (${result.gasMethod})`);
8355
+ printKeyValue("Tx", explorerUrl(result.tx));
8356
+ printBlank();
8357
+ } catch (error) {
8358
+ handleError(error);
8359
+ }
8360
+ });
8361
+ }
8362
+
8363
+ // src/commands/unstake.ts
8364
+ var import_picocolors17 = __toESM(require_picocolors(), 1);
8365
+ function registerUnstake(program3) {
8366
+ program3.command("unstake").description("Unstake vSUI back to SUI (returns SUI including accumulated yield)").argument("<amount>", 'Amount of vSUI to unstake (or "all")').option("--key <path>", "Key file path").action(async (amountStr, opts) => {
8367
+ try {
8368
+ const amount = amountStr === "all" ? "all" : parseFloat(amountStr);
8369
+ if (amount !== "all" && (isNaN(amount) || amount <= 0)) {
8370
+ throw new Error('Amount must be a positive number or "all"');
8371
+ }
8372
+ const pin = await resolvePin();
8373
+ const agent = await T2000.create({ pin, keyPath: opts.key });
8374
+ const result = await agent.unstakeVSui({ amount });
8375
+ if (isJsonMode()) {
8376
+ printJson(result);
8377
+ return;
8378
+ }
8379
+ printBlank();
8380
+ printSuccess(`Unstaked ${import_picocolors17.default.yellow(result.vSuiAmount.toFixed(4))} vSUI`);
8381
+ printSuccess(`Received ${import_picocolors17.default.green(result.suiReceived.toFixed(4))} SUI`);
8382
+ printKeyValue("Gas", `${result.gasCost.toFixed(4)} SUI (${result.gasMethod})`);
8383
+ printKeyValue("Tx", explorerUrl(result.tx));
8384
+ printBlank();
8385
+ } catch (error) {
8386
+ handleError(error);
8387
+ }
8388
+ });
8389
+ }
8390
+
8263
8391
  // src/program.ts
8264
8392
  var require2 = createRequire(import.meta.url);
8265
8393
  var { version: CLI_VERSION } = require2("../package.json");
@@ -8303,6 +8431,10 @@ Examples:
8303
8431
  registerContacts(program3);
8304
8432
  registerClaimRewards(program3);
8305
8433
  registerGas(program3);
8434
+ registerSwap(program3);
8435
+ registerSwapQuote(program3);
8436
+ registerStake(program3);
8437
+ registerUnstake(program3);
8306
8438
  return program3;
8307
8439
  }
8308
8440