@t2000/cli 0.22.4 → 0.22.5

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.js CHANGED
@@ -497,7 +497,27 @@ function registerDeposit(program2) {
497
497
  }
498
498
 
499
499
  // src/commands/history.ts
500
+ import pc4 from "picocolors";
500
501
  import { T2000 as T20006, truncateAddress as truncateAddress2 } from "@t2000/sdk";
502
+ var ACTION_LABELS = {
503
+ send: "\u2197 send",
504
+ lending: "\u{1F3E6} lend",
505
+ swap: "\u{1F504} swap",
506
+ "mpp payment": "\u{1F4B3} mpp",
507
+ split: "\u2702 split",
508
+ transaction: "\u{1F4E6} tx"
509
+ };
510
+ function relativeTime(ts) {
511
+ const diff = Date.now() - ts;
512
+ const mins = Math.floor(diff / 6e4);
513
+ if (mins < 1) return "just now";
514
+ if (mins < 60) return `${mins}m ago`;
515
+ const hours = Math.floor(mins / 60);
516
+ if (hours < 24) return `${hours}h ago`;
517
+ const days = Math.floor(hours / 24);
518
+ if (days < 7) return `${days}d ago`;
519
+ return new Date(ts).toLocaleDateString();
520
+ }
501
521
  function registerHistory(program2) {
502
522
  program2.command("history").description("Show transaction history").option("--limit <n>", "Number of transactions", "20").option("--key <path>", "Key file path").action(async (opts) => {
503
523
  try {
@@ -513,11 +533,19 @@ function registerHistory(program2) {
513
533
  printInfo("No transactions yet.");
514
534
  } else {
515
535
  for (const tx of txns) {
516
- const time = tx.timestamp ? new Date(tx.timestamp).toLocaleString() : "unknown";
517
- const gas = tx.gasMethod ? ` (${tx.gasMethod})` : "";
518
- printLine(`${truncateAddress2(tx.digest)} ${tx.action}${gas} ${time}`);
536
+ const label = ACTION_LABELS[tx.action] ?? `\u{1F4E6} ${tx.action}`;
537
+ const time = tx.timestamp ? relativeTime(tx.timestamp) : "";
538
+ const amount = tx.amount ? pc4.bold(`${tx.amount.toFixed(tx.amount < 0.01 ? 4 : 2)} ${tx.asset ?? ""}`) : "";
539
+ const recipient = tx.recipient ? pc4.dim(`\u2192 ${truncateAddress2(tx.recipient)}`) : "";
540
+ const link = pc4.dim(explorerUrl(tx.digest));
541
+ printLine(`${label} ${amount} ${recipient}`);
542
+ printLine(` ${pc4.dim(truncateAddress2(tx.digest))} ${pc4.dim(time)}`);
543
+ printLine(` ${link}`);
544
+ printBlank();
519
545
  }
520
546
  }
547
+ printDivider();
548
+ printInfo(`${txns.length} transaction${txns.length === 1 ? "" : "s"} shown`);
521
549
  printBlank();
522
550
  } catch (error) {
523
551
  handleError(error);
@@ -629,7 +657,7 @@ function registerImport(program2) {
629
657
  }
630
658
 
631
659
  // src/commands/save.ts
632
- import pc4 from "picocolors";
660
+ import pc5 from "picocolors";
633
661
  import { T2000 as T20009, formatUsd as formatUsd3 } from "@t2000/sdk";
634
662
  function registerSave(program2) {
635
663
  const action = async (amountStr, opts) => {
@@ -651,16 +679,16 @@ function registerSave(program2) {
651
679
  }
652
680
  printBlank();
653
681
  if (gasManagerUsdc > 0) {
654
- printSuccess(`Gas manager: ${pc4.yellow(formatUsd3(gasManagerUsdc))} USDC \u2192 SUI`);
682
+ printSuccess(`Gas manager: ${pc5.yellow(formatUsd3(gasManagerUsdc))} USDC \u2192 SUI`);
655
683
  }
656
684
  const protocolName = opts.protocol ?? "best rate";
657
- printSuccess(`Saved ${pc4.yellow(formatUsd3(result.amount))} USDC to ${protocolName}`);
685
+ printSuccess(`Saved ${pc5.yellow(formatUsd3(result.amount))} USDC to ${protocolName}`);
658
686
  if (result.fee > 0) {
659
687
  const feeRate = (result.fee / result.amount * 100).toFixed(1);
660
- printSuccess(`Protocol fee: ${pc4.dim(`${formatUsd3(result.fee)} USDC (${feeRate}%)`)}`);
688
+ printSuccess(`Protocol fee: ${pc5.dim(`${formatUsd3(result.fee)} USDC (${feeRate}%)`)}`);
661
689
  }
662
- printSuccess(`Current APY: ${pc4.green(`${result.apy.toFixed(2)}%`)}`);
663
- printSuccess(`Savings balance: ${pc4.yellow(formatUsd3(result.savingsBalance))} USDC`);
690
+ printSuccess(`Current APY: ${pc5.green(`${result.apy.toFixed(2)}%`)}`);
691
+ printSuccess(`Savings balance: ${pc5.yellow(formatUsd3(result.savingsBalance))} USDC`);
664
692
  printKeyValue("Tx", explorerUrl(result.tx));
665
693
  printBlank();
666
694
  } catch (error) {
@@ -792,7 +820,7 @@ function registerHealth(program2) {
792
820
  }
793
821
 
794
822
  // src/commands/rates.ts
795
- import pc5 from "picocolors";
823
+ import pc6 from "picocolors";
796
824
  import { T2000 as T200014, SUPPORTED_ASSETS, INVESTMENT_ASSETS, STABLE_ASSETS } from "@t2000/sdk";
797
825
  var INVEST_ASSETS = Object.keys(INVESTMENT_ASSETS);
798
826
  function registerRates(program2) {
@@ -809,14 +837,14 @@ function registerRates(program2) {
809
837
  if (allRates.length > 0) {
810
838
  const best = allRates.reduce((a, b) => b.rates.saveApy > a.rates.saveApy ? b : a);
811
839
  const bestDisplay = SUPPORTED_ASSETS[best.asset]?.displayName ?? best.asset;
812
- printLine(pc5.bold(pc5.green(`Best yield: ${best.rates.saveApy.toFixed(2)}% APY`)) + pc5.dim(` (${bestDisplay} on ${best.protocol})`));
840
+ printLine(pc6.bold(pc6.green(`Best yield: ${best.rates.saveApy.toFixed(2)}% APY`)) + pc6.dim(` (${bestDisplay} on ${best.protocol})`));
813
841
  printBlank();
814
842
  }
815
843
  for (const asset of STABLE_ASSETS) {
816
844
  const assetRates = allRates.filter((r) => r.asset === asset);
817
845
  if (assetRates.length === 0) continue;
818
846
  const display = SUPPORTED_ASSETS[asset]?.displayName ?? asset;
819
- printLine(pc5.bold(display));
847
+ printLine(pc6.bold(display));
820
848
  printDivider();
821
849
  for (const entry of assetRates) {
822
850
  printKeyValue(entry.protocol, `Save ${entry.rates.saveApy.toFixed(2)}% Borrow ${entry.rates.borrowApy.toFixed(2)}%`);
@@ -825,7 +853,7 @@ function registerRates(program2) {
825
853
  }
826
854
  const investRates = allRates.filter((r) => INVEST_ASSETS.includes(r.asset));
827
855
  if (investRates.length > 0) {
828
- printLine(pc5.bold("Investment Assets"));
856
+ printLine(pc6.bold("Investment Assets"));
829
857
  printDivider();
830
858
  for (const asset of INVEST_ASSETS) {
831
859
  const assetRates = investRates.filter((r) => r.asset === asset);
@@ -848,7 +876,7 @@ function registerRates(program2) {
848
876
  }
849
877
 
850
878
  // src/commands/positions.ts
851
- import pc6 from "picocolors";
879
+ import pc7 from "picocolors";
852
880
  import { T2000 as T200015, formatUsd as formatUsd8, formatAssetAmount } from "@t2000/sdk";
853
881
  function registerPositions(program2) {
854
882
  program2.command("positions").description("Show savings & borrow positions across all protocols and assets").option("--key <path>", "Key file path").action(async (opts) => {
@@ -877,10 +905,10 @@ function registerPositions(program2) {
877
905
  const saves = result.positions.filter((p) => p.type === "save");
878
906
  const borrows = result.positions.filter((p) => p.type === "borrow");
879
907
  if (saves.length > 0) {
880
- printLine(pc6.bold("Savings"));
908
+ printLine(pc7.bold("Savings"));
881
909
  printDivider();
882
910
  for (const pos of saves) {
883
- const earning = rewardsByKey.has(`${pos.protocol}:${pos.asset}`) ? ` ${pc6.yellow("+rewards")}` : "";
911
+ const earning = rewardsByKey.has(`${pos.protocol}:${pos.asset}`) ? ` ${pc7.yellow("+rewards")}` : "";
884
912
  const usd = formatUsd8(pos.amountUsd ?? pos.amount);
885
913
  printKeyValue(pos.protocol, `${formatAssetAmount(pos.amount, pos.asset)} ${pos.asset} (${usd}) @ ${pos.apy.toFixed(2)}% APY${earning}`);
886
914
  }
@@ -889,12 +917,12 @@ function registerPositions(program2) {
889
917
  printKeyValue("Total", formatUsd8(totalSaved));
890
918
  }
891
919
  if (hasRewards) {
892
- printLine(` ${pc6.dim("Run claim-rewards to collect and convert to USDC")}`);
920
+ printLine(` ${pc7.dim("Run claim-rewards to collect and convert to USDC")}`);
893
921
  }
894
922
  printBlank();
895
923
  }
896
924
  if (borrows.length > 0) {
897
- printLine(pc6.bold("Borrows"));
925
+ printLine(pc7.bold("Borrows"));
898
926
  printDivider();
899
927
  for (const pos of borrows) {
900
928
  const usd = formatUsd8(pos.amountUsd ?? pos.amount);
@@ -914,7 +942,7 @@ function registerPositions(program2) {
914
942
  }
915
943
 
916
944
  // src/commands/earnings.ts
917
- import pc7 from "picocolors";
945
+ import pc8 from "picocolors";
918
946
  import { T2000 as T200016, formatUsd as formatUsd9, formatAssetAmount as formatAssetAmount2 } from "@t2000/sdk";
919
947
  function registerEarnings(program2) {
920
948
  program2.command("earnings").description("Show yield earned to date").option("--key <path>", "Key file path").action(async (opts) => {
@@ -932,7 +960,7 @@ function registerEarnings(program2) {
932
960
  printKeyValue("Total Saved", formatUsd9(result.supplied));
933
961
  if (savePositions.length > 0) {
934
962
  for (const p of savePositions) {
935
- printLine(` ${pc7.dim("\u2022")} ${formatAssetAmount2(p.amount, p.asset)} ${p.asset} (${formatUsd9(p.amountUsd ?? p.amount)}) on ${p.protocol} @ ${p.apy.toFixed(2)}% APY`);
963
+ printLine(` ${pc8.dim("\u2022")} ${formatAssetAmount2(p.amount, p.asset)} ${p.asset} (${formatUsd9(p.amountUsd ?? p.amount)}) on ${p.protocol} @ ${p.apy.toFixed(2)}% APY`);
936
964
  }
937
965
  }
938
966
  printKeyValue("Blended APY", `${result.currentApy.toFixed(2)}%`);
@@ -946,7 +974,7 @@ function registerEarnings(program2) {
946
974
  }
947
975
 
948
976
  // src/commands/fundStatus.ts
949
- import pc8 from "picocolors";
977
+ import pc9 from "picocolors";
950
978
  import { T2000 as T200017, formatUsd as formatUsd10, formatAssetAmount as formatAssetAmount3 } from "@t2000/sdk";
951
979
  function registerFundStatus(program2) {
952
980
  program2.command("fund-status").description("Full savings summary").option("--key <path>", "Key file path").action(async (opts) => {
@@ -970,7 +998,7 @@ function registerFundStatus(program2) {
970
998
  printKeyValue("Total Saved", formatUsd10(result.supplied));
971
999
  if (savePositions.length > 0) {
972
1000
  for (const p of savePositions) {
973
- printLine(` ${pc8.dim("\u2022")} ${formatAssetAmount3(p.amount, p.asset)} ${p.asset} (${formatUsd10(p.amountUsd ?? p.amount)}) on ${p.protocol} @ ${p.apy.toFixed(2)}% APY`);
1001
+ printLine(` ${pc9.dim("\u2022")} ${formatAssetAmount3(p.amount, p.asset)} ${p.asset} (${formatUsd10(p.amountUsd ?? p.amount)}) on ${p.protocol} @ ${p.apy.toFixed(2)}% APY`);
974
1002
  }
975
1003
  }
976
1004
  printKeyValue("Blended APY", `${result.apy.toFixed(2)}%`);
@@ -1455,7 +1483,7 @@ function isRetryable(code) {
1455
1483
  }
1456
1484
 
1457
1485
  // src/commands/pay.ts
1458
- import pc9 from "picocolors";
1486
+ import pc10 from "picocolors";
1459
1487
  import { T2000 as T200019 } from "@t2000/sdk";
1460
1488
  function registerPay(program2) {
1461
1489
  program2.command("pay <url>").description("Pay for an MPP-protected API resource").option("--key <path>", "Key file path").option("--method <method>", "HTTP method (GET, POST, PUT)", "GET").option("--data <json>", "Request body for POST/PUT").option("--header <key=value>", "Additional HTTP header (repeatable)", collectHeaders, {}).option("--max-price <amount>", "Max USDC price to auto-approve", "1.00").action(async (url, opts) => {
@@ -1484,7 +1512,7 @@ function registerPay(program2) {
1484
1512
  if (result.paid && result.receipt) {
1485
1513
  printSuccess(`Paid via MPP (tx: ${result.receipt.reference.slice(0, 10)}...)`);
1486
1514
  }
1487
- printInfo(`\u2190 ${result.status} OK ${pc9.dim(`[${elapsed}ms]`)}`);
1515
+ printInfo(`\u2190 ${result.status} OK ${pc10.dim(`[${elapsed}ms]`)}`);
1488
1516
  }
1489
1517
  if (isJsonMode()) {
1490
1518
  printJson({
@@ -1597,7 +1625,7 @@ function registerLock(program2) {
1597
1625
 
1598
1626
  // src/commands/sentinel.ts
1599
1627
  import { T2000 as T200020, MIST_PER_SUI } from "@t2000/sdk";
1600
- import pc10 from "picocolors";
1628
+ import pc11 from "picocolors";
1601
1629
  function formatSui(mist) {
1602
1630
  return (Number(mist) / Number(MIST_PER_SUI)).toFixed(2);
1603
1631
  }
@@ -1627,8 +1655,8 @@ function registerSentinel(program2) {
1627
1655
  const pool = `${formatSui(s.prizePool)} SUI`.padEnd(12);
1628
1656
  const fee = `${formatSui(s.attackFee)} SUI`.padEnd(12);
1629
1657
  printLine(` ${s.name}`);
1630
- printLine(` ${pc10.dim(`Pool: ${pool}Fee: ${fee}Attacks: ${s.totalAttacks}`)}`);
1631
- printLine(` ${pc10.dim(s.objectId)}`);
1658
+ printLine(` ${pc11.dim(`Pool: ${pool}Fee: ${fee}Attacks: ${s.totalAttacks}`)}`);
1659
+ printLine(` ${pc11.dim(s.objectId)}`);
1632
1660
  printBlank();
1633
1661
  });
1634
1662
  printBlank();
@@ -1663,7 +1691,7 @@ function registerSentinel(program2) {
1663
1691
  if (s.systemPrompt) {
1664
1692
  printBlank();
1665
1693
  printKeyValue("System Prompt", "");
1666
- printLine(` ${pc10.dim(s.systemPrompt.slice(0, 500))}`);
1694
+ printLine(` ${pc11.dim(s.systemPrompt.slice(0, 500))}`);
1667
1695
  }
1668
1696
  printBlank();
1669
1697
  } catch (error) {
@@ -1689,7 +1717,7 @@ function registerSentinel(program2) {
1689
1717
  return;
1690
1718
  }
1691
1719
  printBlank();
1692
- printLine(` ${pc10.dim("\u23F3")} Requesting attack...`);
1720
+ printLine(` ${pc11.dim("\u23F3")} Requesting attack...`);
1693
1721
  const result = await agent.sentinelAttack(id, prompt, feeMist);
1694
1722
  printBlank();
1695
1723
  if (result.won) {
@@ -1716,7 +1744,7 @@ function registerSentinel(program2) {
1716
1744
 
1717
1745
  // src/commands/earn.ts
1718
1746
  import { T2000 as T200021, MIST_PER_SUI as MIST_PER_SUI2, listSentinels, formatUsd as formatUsd12 } from "@t2000/sdk";
1719
- import pc11 from "picocolors";
1747
+ import pc12 from "picocolors";
1720
1748
  function mistToSui(mist) {
1721
1749
  return Number(mist) / Number(MIST_PER_SUI2);
1722
1750
  }
@@ -1788,7 +1816,7 @@ function registerEarn(program2) {
1788
1816
  return;
1789
1817
  }
1790
1818
  printHeader("Earning Opportunities");
1791
- printLine(pc11.bold("SAVINGS") + pc11.dim(" \u2014 Passive Yield"));
1819
+ printLine(pc12.bold("SAVINGS") + pc12.dim(" \u2014 Passive Yield"));
1792
1820
  printDivider();
1793
1821
  if (savePositions.length > 0) {
1794
1822
  for (const pos of savePositions) {
@@ -1797,7 +1825,7 @@ function registerEarn(program2) {
1797
1825
  if (dailyYield > 1e-4) {
1798
1826
  const dailyStr = dailyYield < 0.01 ? `$${dailyYield.toFixed(4)}` : formatUsd12(dailyYield);
1799
1827
  const monthlyStr = dailyYield * 30 < 0.01 ? `$${(dailyYield * 30).toFixed(4)}` : formatUsd12(dailyYield * 30);
1800
- printLine(pc11.dim(` ~${dailyStr}/day \xB7 ~${monthlyStr}/month`));
1828
+ printLine(pc12.dim(` ~${dailyStr}/day \xB7 ~${monthlyStr}/month`));
1801
1829
  }
1802
1830
  }
1803
1831
  if (savePositions.length > 1) {
@@ -1812,7 +1840,7 @@ function registerEarn(program2) {
1812
1840
  const example = 100;
1813
1841
  const daily = example * bestSaveApy / 100 / 365;
1814
1842
  const monthly = daily * 30;
1815
- printLine(pc11.dim(` Save $${example} \u2192 ~$${daily.toFixed(2)}/day \xB7 ~$${monthly.toFixed(2)}/month`));
1843
+ printLine(pc12.dim(` Save $${example} \u2192 ~$${daily.toFixed(2)}/day \xB7 ~$${monthly.toFixed(2)}/month`));
1816
1844
  printBlank();
1817
1845
  printInfo("No savings yet \u2014 run `t2000 save <amount>` to start");
1818
1846
  } else if (posData) {
@@ -1822,7 +1850,7 @@ function registerEarn(program2) {
1822
1850
  }
1823
1851
  if (earningInvestments.length > 0) {
1824
1852
  printBlank();
1825
- printLine(pc11.bold("INVESTMENTS") + pc11.dim(" \u2014 Earning Yield"));
1853
+ printLine(pc12.bold("INVESTMENTS") + pc12.dim(" \u2014 Earning Yield"));
1826
1854
  printDivider();
1827
1855
  let totalInvestValue = 0;
1828
1856
  for (const pos of earningInvestments) {
@@ -1835,7 +1863,7 @@ function registerEarn(program2) {
1835
1863
  if (dailyYield > 1e-4) {
1836
1864
  const dailyStr = dailyYield < 0.01 ? `$${dailyYield.toFixed(4)}` : formatUsd12(dailyYield);
1837
1865
  const monthlyStr = dailyYield * 30 < 0.01 ? `$${(dailyYield * 30).toFixed(4)}` : formatUsd12(dailyYield * 30);
1838
- printLine(pc11.dim(` ~${dailyStr}/day \xB7 ~${monthlyStr}/month`));
1866
+ printLine(pc12.dim(` ~${dailyStr}/day \xB7 ~${monthlyStr}/month`));
1839
1867
  }
1840
1868
  totalInvestValue += pos.currentValue;
1841
1869
  }
@@ -1845,7 +1873,7 @@ function registerEarn(program2) {
1845
1873
  }
1846
1874
  }
1847
1875
  printBlank();
1848
- printLine(pc11.bold("SENTINEL BOUNTIES") + pc11.dim(" \u2014 Active Red Teaming"));
1876
+ printLine(pc12.bold("SENTINEL BOUNTIES") + pc12.dim(" \u2014 Active Red Teaming"));
1849
1877
  printDivider();
1850
1878
  if (agents && agents.length > 0) {
1851
1879
  const totalPool = agents.reduce((sum, s) => sum + mistToSui(s.prizePool), 0);
@@ -1864,12 +1892,12 @@ function registerEarn(program2) {
1864
1892
  printInfo("Sentinel data unavailable");
1865
1893
  }
1866
1894
  printBlank();
1867
- printLine(pc11.bold("Quick Actions"));
1895
+ printLine(pc12.bold("Quick Actions"));
1868
1896
  printDivider();
1869
- printLine(` ${pc11.dim("t2000 save <amount> [asset]")} Save stablecoins for yield`);
1870
- printLine(` ${pc11.dim("t2000 invest earn <asset>")} Earn yield on investments`);
1871
- printLine(` ${pc11.dim("t2000 sentinel list")} Browse sentinel bounties`);
1872
- printLine(` ${pc11.dim("t2000 sentinel attack <id>")} Attack a sentinel`);
1897
+ printLine(` ${pc12.dim("t2000 save <amount> [asset]")} Save stablecoins for yield`);
1898
+ printLine(` ${pc12.dim("t2000 invest earn <asset>")} Earn yield on investments`);
1899
+ printLine(` ${pc12.dim("t2000 sentinel list")} Browse sentinel bounties`);
1900
+ printLine(` ${pc12.dim("t2000 sentinel attack <id>")} Attack a sentinel`);
1873
1901
  printBlank();
1874
1902
  } catch (error) {
1875
1903
  handleError(error);
@@ -1878,7 +1906,7 @@ function registerEarn(program2) {
1878
1906
  }
1879
1907
 
1880
1908
  // src/commands/rebalance.ts
1881
- import pc12 from "picocolors";
1909
+ import pc13 from "picocolors";
1882
1910
  import { T2000 as T200022, formatUsd as formatUsd13, SUPPORTED_ASSETS as SUPPORTED_ASSETS2 } from "@t2000/sdk";
1883
1911
  function registerRebalance(program2) {
1884
1912
  program2.command("rebalance").description("Optimize yield \u2014 move savings to the best rate across protocols and stablecoins").option("--key <path>", "Key file path").option("--dry-run", "Show what would happen without executing").option("--min-diff <pct>", "Minimum APY difference to trigger (default: 0.5)", "0.5").option("--max-break-even <days>", "Max break-even days for cross-asset moves (default: 30)", "30").action(async (opts) => {
@@ -1906,24 +1934,24 @@ function registerRebalance(program2) {
1906
1934
  const diff = plan.newApy - plan.currentApy;
1907
1935
  if (diff < minYieldDiff) {
1908
1936
  printInfo(`Already optimized \u2014 ${plan.currentApy.toFixed(2)}% APY on ${plan.fromProtocol}`);
1909
- printLine(pc12.dim(` Best available: ${plan.newApy.toFixed(2)}% (${displayAsset(plan.toAsset)} on ${plan.toProtocol})`));
1910
- printLine(pc12.dim(` Difference: ${diff.toFixed(2)}% (below ${minYieldDiff}% threshold)`));
1937
+ printLine(pc13.dim(` Best available: ${plan.newApy.toFixed(2)}% (${displayAsset(plan.toAsset)} on ${plan.toProtocol})`));
1938
+ printLine(pc13.dim(` Difference: ${diff.toFixed(2)}% (below ${minYieldDiff}% threshold)`));
1911
1939
  } else if (plan.breakEvenDays > maxBreakEven && plan.estimatedSwapCost > 0) {
1912
1940
  printInfo(`Skipped \u2014 break-even of ${plan.breakEvenDays} days exceeds ${maxBreakEven}-day limit`);
1913
- printLine(pc12.dim(` ${displayAsset(plan.fromAsset)} on ${plan.fromProtocol} (${plan.currentApy.toFixed(2)}%) \u2192 ${displayAsset(plan.toAsset)} on ${plan.toProtocol} (${plan.newApy.toFixed(2)}%)`));
1941
+ printLine(pc13.dim(` ${displayAsset(plan.fromAsset)} on ${plan.fromProtocol} (${plan.currentApy.toFixed(2)}%) \u2192 ${displayAsset(plan.toAsset)} on ${plan.toProtocol} (${plan.newApy.toFixed(2)}%)`));
1914
1942
  } else {
1915
1943
  printInfo("Already at the best rate. Nothing to rebalance.");
1916
1944
  }
1917
1945
  printBlank();
1918
1946
  return;
1919
1947
  }
1920
- printLine(pc12.bold("Rebalance Plan"));
1948
+ printLine(pc13.bold("Rebalance Plan"));
1921
1949
  printDivider();
1922
1950
  printKeyValue("From", `${displayAsset(plan.fromAsset)} on ${plan.fromProtocol} (${plan.currentApy.toFixed(2)}% APY)`);
1923
1951
  printKeyValue("To", `${displayAsset(plan.toAsset)} on ${plan.toProtocol} (${plan.newApy.toFixed(2)}% APY)`);
1924
1952
  printKeyValue("Amount", formatUsd13(plan.amount));
1925
1953
  printBlank();
1926
- printLine(pc12.bold("Economics"));
1954
+ printLine(pc13.bold("Economics"));
1927
1955
  printDivider();
1928
1956
  printKeyValue("APY Gain", `+${(plan.newApy - plan.currentApy).toFixed(2)}%`);
1929
1957
  printKeyValue("Annual Gain", `${formatUsd13(plan.annualGain)}/year`);
@@ -1933,7 +1961,7 @@ function registerRebalance(program2) {
1933
1961
  }
1934
1962
  printBlank();
1935
1963
  if (plan.steps.length > 0) {
1936
- printLine(pc12.bold("Steps"));
1964
+ printLine(pc13.bold("Steps"));
1937
1965
  printDivider();
1938
1966
  for (let i = 0; i < plan.steps.length; i++) {
1939
1967
  const step = plan.steps[i];
@@ -1949,8 +1977,8 @@ function registerRebalance(program2) {
1949
1977
  printBlank();
1950
1978
  }
1951
1979
  if (opts.dryRun) {
1952
- printLine(pc12.bold(pc12.yellow("DRY RUN \u2014 Preview only, no transactions executed")));
1953
- printLine(pc12.dim(" Run `t2000 rebalance` to execute."));
1980
+ printLine(pc13.bold(pc13.yellow("DRY RUN \u2014 Preview only, no transactions executed")));
1981
+ printLine(pc13.dim(" Run `t2000 rebalance` to execute."));
1954
1982
  printBlank();
1955
1983
  return;
1956
1984
  }
@@ -2063,7 +2091,7 @@ function registerMcp(program2) {
2063
2091
  mcp.command("start", { isDefault: true }).description("Start MCP server (stdio transport)").option("--key <path>", "Key file path").action(async (opts) => {
2064
2092
  let mod;
2065
2093
  try {
2066
- mod = await import("./dist-72NNY4EV.js");
2094
+ mod = await import("./dist-NXFA54RO.js");
2067
2095
  } catch {
2068
2096
  console.error(
2069
2097
  "MCP server not installed. Run:\n npm install -g @t2000/mcp"
@@ -2215,7 +2243,7 @@ function registerContacts(program2) {
2215
2243
  }
2216
2244
 
2217
2245
  // src/commands/invest.ts
2218
- import pc13 from "picocolors";
2246
+ import pc14 from "picocolors";
2219
2247
  import { T2000 as T200024, formatUsd as formatUsd15, formatAssetAmount as formatAssetAmount4, INVESTMENT_ASSETS as INVESTMENT_ASSETS2 } from "@t2000/sdk";
2220
2248
  function registerInvest(program2) {
2221
2249
  const investCmd = program2.command("invest").description("Buy or sell investment assets");
@@ -2223,7 +2251,7 @@ function registerInvest(program2) {
2223
2251
  try {
2224
2252
  const parsed = parseFloat(amount);
2225
2253
  if (isNaN(parsed) || parsed <= 0 || !isFinite(parsed)) {
2226
- console.error(pc13.red(" \u2717 Amount must be greater than $0"));
2254
+ console.error(pc14.red(" \u2717 Amount must be greater than $0"));
2227
2255
  process.exitCode = 1;
2228
2256
  return;
2229
2257
  }
@@ -2255,7 +2283,7 @@ function registerInvest(program2) {
2255
2283
  if (!isAll) {
2256
2284
  const parsed = parseFloat(amount);
2257
2285
  if (isNaN(parsed) || parsed <= 0 || !isFinite(parsed)) {
2258
- console.error(pc13.red(" \u2717 Amount must be greater than $0"));
2286
+ console.error(pc14.red(" \u2717 Amount must be greater than $0"));
2259
2287
  process.exitCode = 1;
2260
2288
  return;
2261
2289
  }
@@ -2277,7 +2305,7 @@ function registerInvest(program2) {
2277
2305
  printSuccess(`Sold ${formatAssetAmount4(result.amount, sym)} ${sym} at ${formatUsd15(result.price)}`);
2278
2306
  printKeyValue("Proceeds", formatUsd15(result.usdValue));
2279
2307
  if (result.realizedPnL !== void 0) {
2280
- const pnlColor = result.realizedPnL >= 0 ? pc13.green : pc13.red;
2308
+ const pnlColor = result.realizedPnL >= 0 ? pc14.green : pc14.red;
2281
2309
  const pnlSign = result.realizedPnL >= 0 ? "+" : "";
2282
2310
  printKeyValue("Realized P&L", pnlColor(`${pnlSign}${formatUsd15(result.realizedPnL)}`));
2283
2311
  }
@@ -2408,9 +2436,9 @@ function registerInvest(program2) {
2408
2436
  printSeparator();
2409
2437
  for (const [key, def] of Object.entries(all)) {
2410
2438
  const allocs = Object.entries(def.allocations).map(([a, p]) => `${a} ${p}%`).join(", ");
2411
- const tag = def.custom ? pc13.dim(" (custom)") : "";
2439
+ const tag = def.custom ? pc14.dim(" (custom)") : "";
2412
2440
  printKeyValue(key, `${allocs}${tag}`);
2413
- printLine(` ${pc13.dim(def.description)}`);
2441
+ printLine(` ${pc14.dim(def.description)}`);
2414
2442
  }
2415
2443
  printSeparator();
2416
2444
  const hasPositions = Object.keys(all).some((k) => agent.portfolio.hasStrategyPositions(k));
@@ -2426,7 +2454,7 @@ function registerInvest(program2) {
2426
2454
  try {
2427
2455
  const parsed = parseFloat(amount);
2428
2456
  if (isNaN(parsed) || parsed <= 0) {
2429
- console.error(pc13.red(" \u2717 Amount must be greater than $0"));
2457
+ console.error(pc14.red(" \u2717 Amount must be greater than $0"));
2430
2458
  process.exitCode = 1;
2431
2459
  return;
2432
2460
  }
@@ -2460,7 +2488,7 @@ function registerInvest(program2) {
2460
2488
  printKeyValue("Tx", explorerUrl(txDigests[0]));
2461
2489
  } else {
2462
2490
  for (const buy of result.buys) {
2463
- printLine(` ${pc13.dim(`${buy.asset}: ${explorerUrl(buy.tx)}`)}`);
2491
+ printLine(` ${pc14.dim(`${buy.asset}: ${explorerUrl(buy.tx)}`)}`);
2464
2492
  }
2465
2493
  }
2466
2494
  }
@@ -2482,18 +2510,18 @@ function registerInvest(program2) {
2482
2510
  printSuccess(`Sold all ${name} strategy positions`);
2483
2511
  printSeparator();
2484
2512
  for (const sell of result.sells) {
2485
- const pnlColor = sell.realizedPnL >= 0 ? pc13.green : pc13.red;
2513
+ const pnlColor = sell.realizedPnL >= 0 ? pc14.green : pc14.red;
2486
2514
  const pnlSign = sell.realizedPnL >= 0 ? "+" : "";
2487
2515
  printKeyValue(sell.asset, `${formatAssetAmount4(sell.amount, sell.asset)} \u2192 ${formatUsd15(sell.usdValue)} ${pnlColor(`${pnlSign}${formatUsd15(sell.realizedPnL)}`)}`);
2488
2516
  }
2489
2517
  if (result.failed && result.failed.length > 0) {
2490
2518
  for (const f of result.failed) {
2491
- console.error(pc13.yellow(` \u26A0 ${f.asset}: ${f.reason}`));
2519
+ console.error(pc14.yellow(` \u26A0 ${f.asset}: ${f.reason}`));
2492
2520
  }
2493
2521
  }
2494
2522
  printSeparator();
2495
2523
  printKeyValue("Total proceeds", formatUsd15(result.totalProceeds));
2496
- const rpnlColor = result.realizedPnL >= 0 ? pc13.green : pc13.red;
2524
+ const rpnlColor = result.realizedPnL >= 0 ? pc14.green : pc14.red;
2497
2525
  const rpnlSign = result.realizedPnL >= 0 ? "+" : "";
2498
2526
  printKeyValue("Realized P&L", rpnlColor(`${rpnlSign}${formatUsd15(result.realizedPnL)}`));
2499
2527
  printBlank();
@@ -2520,8 +2548,8 @@ function registerInvest(program2) {
2520
2548
  const target = status.definition.allocations[pos.asset] ?? 0;
2521
2549
  const actual = status.currentWeights[pos.asset] ?? 0;
2522
2550
  const drift = actual - target;
2523
- const driftColor = Math.abs(drift) > 3 ? pc13.yellow : pc13.dim;
2524
- const pnlColor = pos.unrealizedPnL >= 0 ? pc13.green : pc13.red;
2551
+ const driftColor = Math.abs(drift) > 3 ? pc14.yellow : pc14.dim;
2552
+ const pnlColor = pos.unrealizedPnL >= 0 ? pc14.green : pc14.red;
2525
2553
  const pnlSign = pos.unrealizedPnL >= 0 ? "+" : "";
2526
2554
  printKeyValue(
2527
2555
  pos.asset,
@@ -2552,7 +2580,7 @@ function registerInvest(program2) {
2552
2580
  printSuccess(`Rebalanced ${name} strategy`);
2553
2581
  printSeparator();
2554
2582
  for (const t of result.trades) {
2555
- const action = t.action === "buy" ? pc13.green("BUY") : pc13.red("SELL");
2583
+ const action = t.action === "buy" ? pc14.green("BUY") : pc14.red("SELL");
2556
2584
  printKeyValue(t.asset, `${action} ${formatUsd15(t.usdAmount)} (${formatAssetAmount4(t.amount, t.asset)})`);
2557
2585
  }
2558
2586
  printSeparator();
@@ -2569,7 +2597,7 @@ function registerInvest(program2) {
2569
2597
  for (const pair of opts.alloc) {
2570
2598
  const [asset, pctStr] = pair.split(":");
2571
2599
  if (!asset || !pctStr) {
2572
- console.error(pc13.red(` \u2717 Invalid allocation: '${pair}'. Use ASSET:PCT format (e.g. SUI:60)`));
2600
+ console.error(pc14.red(` \u2717 Invalid allocation: '${pair}'. Use ASSET:PCT format (e.g. SUI:60)`));
2573
2601
  process.exitCode = 1;
2574
2602
  return;
2575
2603
  }
@@ -2596,7 +2624,7 @@ function registerInvest(program2) {
2596
2624
  const pin = await resolvePin();
2597
2625
  const agent = await T200024.create({ pin, keyPath: opts.key });
2598
2626
  if (agent.portfolio.hasStrategyPositions(name.toLowerCase())) {
2599
- console.error(pc13.red(` \u2717 Strategy '${name}' has open positions. Sell first: t2000 invest strategy sell ${name}`));
2627
+ console.error(pc14.red(` \u2717 Strategy '${name}' has open positions. Sell first: t2000 invest strategy sell ${name}`));
2600
2628
  process.exitCode = 1;
2601
2629
  return;
2602
2630
  }
@@ -2617,12 +2645,12 @@ function registerInvest(program2) {
2617
2645
  try {
2618
2646
  const parsed = parseFloat(amount);
2619
2647
  if (isNaN(parsed) || parsed < 1) {
2620
- console.error(pc13.red(" \u2717 Amount must be at least $1"));
2648
+ console.error(pc14.red(" \u2717 Amount must be at least $1"));
2621
2649
  process.exitCode = 1;
2622
2650
  return;
2623
2651
  }
2624
2652
  if (!["daily", "weekly", "monthly"].includes(frequency)) {
2625
- console.error(pc13.red(" \u2717 Frequency must be daily, weekly, or monthly"));
2653
+ console.error(pc14.red(" \u2717 Frequency must be daily, weekly, or monthly"));
2626
2654
  process.exitCode = 1;
2627
2655
  return;
2628
2656
  }
@@ -2632,7 +2660,7 @@ function registerInvest(program2) {
2632
2660
  const isStrategy = target ? target.toLowerCase() in allStrategies : false;
2633
2661
  const isAsset = target ? target.toUpperCase() in INVESTMENT_ASSETS2 : false;
2634
2662
  if (target && !isStrategy && !isAsset) {
2635
- console.error(pc13.red(` \u2717 '${target}' is not a valid strategy or asset`));
2663
+ console.error(pc14.red(` \u2717 '${target}' is not a valid strategy or asset`));
2636
2664
  process.exitCode = 1;
2637
2665
  return;
2638
2666
  }
@@ -2679,9 +2707,9 @@ function registerInvest(program2) {
2679
2707
  printSeparator();
2680
2708
  for (const s of status.schedules) {
2681
2709
  const target = s.strategy ?? s.asset ?? "?";
2682
- const statusTag = s.enabled ? pc13.green("active") : pc13.dim("paused");
2710
+ const statusTag = s.enabled ? pc14.green("active") : pc14.dim("paused");
2683
2711
  printKeyValue(s.id, `${formatUsd15(s.amount)} ${s.frequency} \u2192 ${target} ${statusTag}`);
2684
- printLine(` ${pc13.dim(`Next: ${new Date(s.nextRun).toLocaleDateString()} \xB7 Runs: ${s.runCount} \xB7 Total: ${formatUsd15(s.totalInvested)}`)}`);
2712
+ printLine(` ${pc14.dim(`Next: ${new Date(s.nextRun).toLocaleDateString()} \xB7 Runs: ${s.runCount} \xB7 Total: ${formatUsd15(s.totalInvested)}`)}`);
2685
2713
  }
2686
2714
  printSeparator();
2687
2715
  if (status.pendingRuns.length > 0) {
@@ -2724,7 +2752,7 @@ function registerInvest(program2) {
2724
2752
  }
2725
2753
  if (result.skipped.length > 0) {
2726
2754
  for (const skip of result.skipped) {
2727
- printLine(` ${pc13.yellow("\u26A0")} Skipped ${skip.scheduleId}: ${skip.reason}`);
2755
+ printLine(` ${pc14.yellow("\u26A0")} Skipped ${skip.scheduleId}: ${skip.reason}`);
2728
2756
  }
2729
2757
  }
2730
2758
  printBlank();
@@ -2751,22 +2779,22 @@ function registerInvest(program2) {
2751
2779
  }
2752
2780
 
2753
2781
  // src/commands/portfolio.ts
2754
- import pc14 from "picocolors";
2782
+ import pc15 from "picocolors";
2755
2783
  import { T2000 as T200025, formatUsd as formatUsd16, formatAssetAmount as formatAssetAmount5 } from "@t2000/sdk";
2756
2784
  function printPositionLine(pos, rewardKeys) {
2757
2785
  if (pos.currentPrice === 0 && pos.totalAmount > 0) {
2758
2786
  printKeyValue(
2759
2787
  pos.asset,
2760
- `${formatAssetAmount5(pos.totalAmount, pos.asset)} Avg: ${formatUsd16(pos.avgPrice)} Now: ${pc14.yellow("unavailable")}`
2788
+ `${formatAssetAmount5(pos.totalAmount, pos.asset)} Avg: ${formatUsd16(pos.avgPrice)} Now: ${pc15.yellow("unavailable")}`
2761
2789
  );
2762
2790
  } else {
2763
- const pnlColor = pos.unrealizedPnL >= 0 ? pc14.green : pc14.red;
2791
+ const pnlColor = pos.unrealizedPnL >= 0 ? pc15.green : pc15.red;
2764
2792
  const pnlSign = pos.unrealizedPnL >= 0 ? "+" : "";
2765
2793
  let yieldSuffix = "";
2766
2794
  if (pos.earning && pos.earningApy) {
2767
2795
  const hasRewards = rewardKeys?.has(`${pos.earningProtocol}:${pos.asset}`);
2768
- const rewardTag = hasRewards ? ` ${pc14.yellow("+rewards")}` : "";
2769
- yieldSuffix = ` ${pc14.cyan(`${pos.earningApy.toFixed(1)}% APY (${pos.earningProtocol})`)}${rewardTag}`;
2796
+ const rewardTag = hasRewards ? ` ${pc15.yellow("+rewards")}` : "";
2797
+ yieldSuffix = ` ${pc15.cyan(`${pos.earningApy.toFixed(1)}% APY (${pos.earningProtocol})`)}${rewardTag}`;
2770
2798
  }
2771
2799
  printKeyValue(
2772
2800
  pos.asset,
@@ -2807,19 +2835,19 @@ function registerPortfolio(program2) {
2807
2835
  stratLabel = def.name;
2808
2836
  } catch {
2809
2837
  }
2810
- printLine(` ${pc14.bold(pc14.cyan(`\u25B8 ${stratLabel}`))}`);
2838
+ printLine(` ${pc15.bold(pc15.cyan(`\u25B8 ${stratLabel}`))}`);
2811
2839
  printSeparator();
2812
2840
  for (const pos of positions) {
2813
2841
  printPositionLine(pos, rewardKeys);
2814
2842
  }
2815
2843
  const stratValue = positions.reduce((s, p) => s + p.currentValue, 0);
2816
- printLine(` ${pc14.dim(`Subtotal: ${formatUsd16(stratValue)}`)}`);
2844
+ printLine(` ${pc15.dim(`Subtotal: ${formatUsd16(stratValue)}`)}`);
2817
2845
  printBlank();
2818
2846
  }
2819
2847
  }
2820
2848
  if (hasDirectPositions) {
2821
2849
  if (hasStrategyPositions) {
2822
- printLine(` ${pc14.bold(pc14.cyan("\u25B8 Direct"))}`);
2850
+ printLine(` ${pc15.bold(pc15.cyan("\u25B8 Direct"))}`);
2823
2851
  }
2824
2852
  printSeparator();
2825
2853
  for (const pos of portfolio.positions) {
@@ -2827,21 +2855,21 @@ function registerPortfolio(program2) {
2827
2855
  }
2828
2856
  if (hasStrategyPositions) {
2829
2857
  const directValue = portfolio.positions.reduce((s, p) => s + p.currentValue, 0);
2830
- printLine(` ${pc14.dim(`Subtotal: ${formatUsd16(directValue)}`)}`);
2858
+ printLine(` ${pc15.dim(`Subtotal: ${formatUsd16(directValue)}`)}`);
2831
2859
  }
2832
2860
  }
2833
2861
  printSeparator();
2834
2862
  const hasPriceUnavailable = portfolio.positions.some((p) => p.currentPrice === 0 && p.totalAmount > 0);
2835
2863
  if (hasPriceUnavailable) {
2836
- printInfo(pc14.yellow("\u26A0 Price data unavailable for some assets. Values may be inaccurate."));
2864
+ printInfo(pc15.yellow("\u26A0 Price data unavailable for some assets. Values may be inaccurate."));
2837
2865
  }
2838
2866
  printKeyValue("Total invested", formatUsd16(portfolio.totalInvested));
2839
2867
  printKeyValue("Current value", formatUsd16(portfolio.totalValue));
2840
- const upnlColor = portfolio.unrealizedPnL >= 0 ? pc14.green : pc14.red;
2868
+ const upnlColor = portfolio.unrealizedPnL >= 0 ? pc15.green : pc15.red;
2841
2869
  const upnlSign = portfolio.unrealizedPnL >= 0 ? "+" : "";
2842
2870
  printKeyValue("Unrealized P&L", upnlColor(`${upnlSign}${formatUsd16(portfolio.unrealizedPnL)} (${upnlSign}${portfolio.unrealizedPnLPct.toFixed(1)}%)`));
2843
2871
  if (portfolio.realizedPnL !== 0) {
2844
- const rpnlColor = portfolio.realizedPnL >= 0 ? pc14.green : pc14.red;
2872
+ const rpnlColor = portfolio.realizedPnL >= 0 ? pc15.green : pc15.red;
2845
2873
  const rpnlSign = portfolio.realizedPnL >= 0 ? "+" : "";
2846
2874
  printKeyValue("Realized P&L", rpnlColor(`${rpnlSign}${formatUsd16(portfolio.realizedPnL)}`));
2847
2875
  }
@@ -2853,7 +2881,7 @@ function registerPortfolio(program2) {
2853
2881
  }
2854
2882
 
2855
2883
  // src/commands/claimRewards.ts
2856
- import pc15 from "picocolors";
2884
+ import pc16 from "picocolors";
2857
2885
  import { T2000 as T200026, formatUsd as formatUsd17 } from "@t2000/sdk";
2858
2886
  function registerClaimRewards(program2) {
2859
2887
  program2.command("claim-rewards").description("Claim pending protocol rewards").option("--key <path>", "Key file path").action(async (opts) => {
@@ -2867,20 +2895,20 @@ function registerClaimRewards(program2) {
2867
2895
  }
2868
2896
  printBlank();
2869
2897
  if (result.rewards.length === 0) {
2870
- printLine(` ${pc15.dim("No rewards to claim")}`);
2898
+ printLine(` ${pc16.dim("No rewards to claim")}`);
2871
2899
  printBlank();
2872
2900
  return;
2873
2901
  }
2874
2902
  const protocols = [...new Set(result.rewards.map((r) => r.protocol))];
2875
- printLine(` ${pc15.green("\u2713")} Claimed and converted rewards to USDC`);
2903
+ printLine(` ${pc16.green("\u2713")} Claimed and converted rewards to USDC`);
2876
2904
  printSeparator();
2877
2905
  const received = result.usdcReceived;
2878
2906
  if (received >= 0.01) {
2879
- printKeyValue("Received", `${pc15.green(formatUsd17(received))} USDC`);
2907
+ printKeyValue("Received", `${pc16.green(formatUsd17(received))} USDC`);
2880
2908
  } else if (received > 0) {
2881
- printKeyValue("Received", `${pc15.green("< $0.01")} USDC`);
2909
+ printKeyValue("Received", `${pc16.green("< $0.01")} USDC`);
2882
2910
  } else {
2883
- printKeyValue("Received", `${pc15.dim("< $0.01 USDC (rewards are still accruing)")}`);
2911
+ printKeyValue("Received", `${pc16.dim("< $0.01 USDC (rewards are still accruing)")}`);
2884
2912
  }
2885
2913
  printKeyValue("Source", protocols.join(", "));
2886
2914
  if (result.tx) {