@t2000/cli 0.22.3 → 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
@@ -133,10 +133,14 @@ async function clearSession() {
133
133
  async function resolvePin(opts) {
134
134
  const envPin = getPinFromEnv();
135
135
  if (envPin) return envPin;
136
- const sessionPin = await readSession();
137
- if (sessionPin) return sessionPin;
136
+ if (!opts?.skipSession) {
137
+ const sessionPin = await readSession();
138
+ if (sessionPin) return sessionPin;
139
+ }
138
140
  const pin = opts?.confirm ? await askPinConfirm() : await askPin();
139
- await saveSession(pin);
141
+ if (!opts?.skipSession) {
142
+ await saveSession(pin);
143
+ }
140
144
  return pin;
141
145
  }
142
146
 
@@ -493,7 +497,27 @@ function registerDeposit(program2) {
493
497
  }
494
498
 
495
499
  // src/commands/history.ts
500
+ import pc4 from "picocolors";
496
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
+ }
497
521
  function registerHistory(program2) {
498
522
  program2.command("history").description("Show transaction history").option("--limit <n>", "Number of transactions", "20").option("--key <path>", "Key file path").action(async (opts) => {
499
523
  try {
@@ -509,11 +533,19 @@ function registerHistory(program2) {
509
533
  printInfo("No transactions yet.");
510
534
  } else {
511
535
  for (const tx of txns) {
512
- const time = tx.timestamp ? new Date(tx.timestamp).toLocaleString() : "unknown";
513
- const gas = tx.gasMethod ? ` (${tx.gasMethod})` : "";
514
- 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();
515
545
  }
516
546
  }
547
+ printDivider();
548
+ printInfo(`${txns.length} transaction${txns.length === 1 ? "" : "s"} shown`);
517
549
  printBlank();
518
550
  } catch (error) {
519
551
  handleError(error);
@@ -625,7 +657,7 @@ function registerImport(program2) {
625
657
  }
626
658
 
627
659
  // src/commands/save.ts
628
- import pc4 from "picocolors";
660
+ import pc5 from "picocolors";
629
661
  import { T2000 as T20009, formatUsd as formatUsd3 } from "@t2000/sdk";
630
662
  function registerSave(program2) {
631
663
  const action = async (amountStr, opts) => {
@@ -647,16 +679,16 @@ function registerSave(program2) {
647
679
  }
648
680
  printBlank();
649
681
  if (gasManagerUsdc > 0) {
650
- printSuccess(`Gas manager: ${pc4.yellow(formatUsd3(gasManagerUsdc))} USDC \u2192 SUI`);
682
+ printSuccess(`Gas manager: ${pc5.yellow(formatUsd3(gasManagerUsdc))} USDC \u2192 SUI`);
651
683
  }
652
684
  const protocolName = opts.protocol ?? "best rate";
653
- printSuccess(`Saved ${pc4.yellow(formatUsd3(result.amount))} USDC to ${protocolName}`);
685
+ printSuccess(`Saved ${pc5.yellow(formatUsd3(result.amount))} USDC to ${protocolName}`);
654
686
  if (result.fee > 0) {
655
687
  const feeRate = (result.fee / result.amount * 100).toFixed(1);
656
- printSuccess(`Protocol fee: ${pc4.dim(`${formatUsd3(result.fee)} USDC (${feeRate}%)`)}`);
688
+ printSuccess(`Protocol fee: ${pc5.dim(`${formatUsd3(result.fee)} USDC (${feeRate}%)`)}`);
657
689
  }
658
- printSuccess(`Current APY: ${pc4.green(`${result.apy.toFixed(2)}%`)}`);
659
- 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`);
660
692
  printKeyValue("Tx", explorerUrl(result.tx));
661
693
  printBlank();
662
694
  } catch (error) {
@@ -788,7 +820,7 @@ function registerHealth(program2) {
788
820
  }
789
821
 
790
822
  // src/commands/rates.ts
791
- import pc5 from "picocolors";
823
+ import pc6 from "picocolors";
792
824
  import { T2000 as T200014, SUPPORTED_ASSETS, INVESTMENT_ASSETS, STABLE_ASSETS } from "@t2000/sdk";
793
825
  var INVEST_ASSETS = Object.keys(INVESTMENT_ASSETS);
794
826
  function registerRates(program2) {
@@ -805,14 +837,14 @@ function registerRates(program2) {
805
837
  if (allRates.length > 0) {
806
838
  const best = allRates.reduce((a, b) => b.rates.saveApy > a.rates.saveApy ? b : a);
807
839
  const bestDisplay = SUPPORTED_ASSETS[best.asset]?.displayName ?? best.asset;
808
- 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})`));
809
841
  printBlank();
810
842
  }
811
843
  for (const asset of STABLE_ASSETS) {
812
844
  const assetRates = allRates.filter((r) => r.asset === asset);
813
845
  if (assetRates.length === 0) continue;
814
846
  const display = SUPPORTED_ASSETS[asset]?.displayName ?? asset;
815
- printLine(pc5.bold(display));
847
+ printLine(pc6.bold(display));
816
848
  printDivider();
817
849
  for (const entry of assetRates) {
818
850
  printKeyValue(entry.protocol, `Save ${entry.rates.saveApy.toFixed(2)}% Borrow ${entry.rates.borrowApy.toFixed(2)}%`);
@@ -821,7 +853,7 @@ function registerRates(program2) {
821
853
  }
822
854
  const investRates = allRates.filter((r) => INVEST_ASSETS.includes(r.asset));
823
855
  if (investRates.length > 0) {
824
- printLine(pc5.bold("Investment Assets"));
856
+ printLine(pc6.bold("Investment Assets"));
825
857
  printDivider();
826
858
  for (const asset of INVEST_ASSETS) {
827
859
  const assetRates = investRates.filter((r) => r.asset === asset);
@@ -844,7 +876,7 @@ function registerRates(program2) {
844
876
  }
845
877
 
846
878
  // src/commands/positions.ts
847
- import pc6 from "picocolors";
879
+ import pc7 from "picocolors";
848
880
  import { T2000 as T200015, formatUsd as formatUsd8, formatAssetAmount } from "@t2000/sdk";
849
881
  function registerPositions(program2) {
850
882
  program2.command("positions").description("Show savings & borrow positions across all protocols and assets").option("--key <path>", "Key file path").action(async (opts) => {
@@ -873,10 +905,10 @@ function registerPositions(program2) {
873
905
  const saves = result.positions.filter((p) => p.type === "save");
874
906
  const borrows = result.positions.filter((p) => p.type === "borrow");
875
907
  if (saves.length > 0) {
876
- printLine(pc6.bold("Savings"));
908
+ printLine(pc7.bold("Savings"));
877
909
  printDivider();
878
910
  for (const pos of saves) {
879
- const earning = rewardsByKey.has(`${pos.protocol}:${pos.asset}`) ? ` ${pc6.yellow("+rewards")}` : "";
911
+ const earning = rewardsByKey.has(`${pos.protocol}:${pos.asset}`) ? ` ${pc7.yellow("+rewards")}` : "";
880
912
  const usd = formatUsd8(pos.amountUsd ?? pos.amount);
881
913
  printKeyValue(pos.protocol, `${formatAssetAmount(pos.amount, pos.asset)} ${pos.asset} (${usd}) @ ${pos.apy.toFixed(2)}% APY${earning}`);
882
914
  }
@@ -885,12 +917,12 @@ function registerPositions(program2) {
885
917
  printKeyValue("Total", formatUsd8(totalSaved));
886
918
  }
887
919
  if (hasRewards) {
888
- 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")}`);
889
921
  }
890
922
  printBlank();
891
923
  }
892
924
  if (borrows.length > 0) {
893
- printLine(pc6.bold("Borrows"));
925
+ printLine(pc7.bold("Borrows"));
894
926
  printDivider();
895
927
  for (const pos of borrows) {
896
928
  const usd = formatUsd8(pos.amountUsd ?? pos.amount);
@@ -910,7 +942,7 @@ function registerPositions(program2) {
910
942
  }
911
943
 
912
944
  // src/commands/earnings.ts
913
- import pc7 from "picocolors";
945
+ import pc8 from "picocolors";
914
946
  import { T2000 as T200016, formatUsd as formatUsd9, formatAssetAmount as formatAssetAmount2 } from "@t2000/sdk";
915
947
  function registerEarnings(program2) {
916
948
  program2.command("earnings").description("Show yield earned to date").option("--key <path>", "Key file path").action(async (opts) => {
@@ -928,7 +960,7 @@ function registerEarnings(program2) {
928
960
  printKeyValue("Total Saved", formatUsd9(result.supplied));
929
961
  if (savePositions.length > 0) {
930
962
  for (const p of savePositions) {
931
- 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`);
932
964
  }
933
965
  }
934
966
  printKeyValue("Blended APY", `${result.currentApy.toFixed(2)}%`);
@@ -942,7 +974,7 @@ function registerEarnings(program2) {
942
974
  }
943
975
 
944
976
  // src/commands/fundStatus.ts
945
- import pc8 from "picocolors";
977
+ import pc9 from "picocolors";
946
978
  import { T2000 as T200017, formatUsd as formatUsd10, formatAssetAmount as formatAssetAmount3 } from "@t2000/sdk";
947
979
  function registerFundStatus(program2) {
948
980
  program2.command("fund-status").description("Full savings summary").option("--key <path>", "Key file path").action(async (opts) => {
@@ -966,7 +998,7 @@ function registerFundStatus(program2) {
966
998
  printKeyValue("Total Saved", formatUsd10(result.supplied));
967
999
  if (savePositions.length > 0) {
968
1000
  for (const p of savePositions) {
969
- 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`);
970
1002
  }
971
1003
  }
972
1004
  printKeyValue("Blended APY", `${result.apy.toFixed(2)}%`);
@@ -1451,7 +1483,7 @@ function isRetryable(code) {
1451
1483
  }
1452
1484
 
1453
1485
  // src/commands/pay.ts
1454
- import pc9 from "picocolors";
1486
+ import pc10 from "picocolors";
1455
1487
  import { T2000 as T200019 } from "@t2000/sdk";
1456
1488
  function registerPay(program2) {
1457
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) => {
@@ -1480,7 +1512,7 @@ function registerPay(program2) {
1480
1512
  if (result.paid && result.receipt) {
1481
1513
  printSuccess(`Paid via MPP (tx: ${result.receipt.reference.slice(0, 10)}...)`);
1482
1514
  }
1483
- printInfo(`\u2190 ${result.status} OK ${pc9.dim(`[${elapsed}ms]`)}`);
1515
+ printInfo(`\u2190 ${result.status} OK ${pc10.dim(`[${elapsed}ms]`)}`);
1484
1516
  }
1485
1517
  if (isJsonMode()) {
1486
1518
  printJson({
@@ -1540,12 +1572,34 @@ function registerLock(program2) {
1540
1572
  });
1541
1573
  program2.command("unlock").description("Unlock agent \u2014 resume operations").action(async () => {
1542
1574
  try {
1543
- const pin = await resolvePin();
1544
- if (!pin) {
1545
- throw new Error("PIN required to unlock agent");
1546
- }
1547
1575
  const { T2000: T200027 } = await import("@t2000/sdk");
1548
- await T200027.create({ pin });
1576
+ const MAX_ATTEMPTS2 = 3;
1577
+ let pin;
1578
+ for (let attempt = 1; attempt <= MAX_ATTEMPTS2; attempt++) {
1579
+ pin = await resolvePin({ skipSession: true });
1580
+ if (!pin) {
1581
+ throw new Error("PIN required to unlock agent");
1582
+ }
1583
+ try {
1584
+ await T200027.create({ pin });
1585
+ break;
1586
+ } catch (error) {
1587
+ const msg = error instanceof Error ? error.message : "";
1588
+ if (msg.includes("Invalid PIN")) {
1589
+ const remaining = MAX_ATTEMPTS2 - attempt;
1590
+ if (remaining > 0) {
1591
+ printError(`Invalid PIN. ${remaining} attempt${remaining > 1 ? "s" : ""} remaining.`);
1592
+ pin = void 0;
1593
+ continue;
1594
+ }
1595
+ printError("Invalid PIN. No attempts remaining.");
1596
+ return;
1597
+ }
1598
+ throw error;
1599
+ }
1600
+ }
1601
+ if (!pin) return;
1602
+ await saveSession(pin);
1549
1603
  const enforcer = new SafeguardEnforcer3(CONFIG_DIR4);
1550
1604
  enforcer.load();
1551
1605
  enforcer.unlock();
@@ -1571,7 +1625,7 @@ function registerLock(program2) {
1571
1625
 
1572
1626
  // src/commands/sentinel.ts
1573
1627
  import { T2000 as T200020, MIST_PER_SUI } from "@t2000/sdk";
1574
- import pc10 from "picocolors";
1628
+ import pc11 from "picocolors";
1575
1629
  function formatSui(mist) {
1576
1630
  return (Number(mist) / Number(MIST_PER_SUI)).toFixed(2);
1577
1631
  }
@@ -1601,8 +1655,8 @@ function registerSentinel(program2) {
1601
1655
  const pool = `${formatSui(s.prizePool)} SUI`.padEnd(12);
1602
1656
  const fee = `${formatSui(s.attackFee)} SUI`.padEnd(12);
1603
1657
  printLine(` ${s.name}`);
1604
- printLine(` ${pc10.dim(`Pool: ${pool}Fee: ${fee}Attacks: ${s.totalAttacks}`)}`);
1605
- printLine(` ${pc10.dim(s.objectId)}`);
1658
+ printLine(` ${pc11.dim(`Pool: ${pool}Fee: ${fee}Attacks: ${s.totalAttacks}`)}`);
1659
+ printLine(` ${pc11.dim(s.objectId)}`);
1606
1660
  printBlank();
1607
1661
  });
1608
1662
  printBlank();
@@ -1637,7 +1691,7 @@ function registerSentinel(program2) {
1637
1691
  if (s.systemPrompt) {
1638
1692
  printBlank();
1639
1693
  printKeyValue("System Prompt", "");
1640
- printLine(` ${pc10.dim(s.systemPrompt.slice(0, 500))}`);
1694
+ printLine(` ${pc11.dim(s.systemPrompt.slice(0, 500))}`);
1641
1695
  }
1642
1696
  printBlank();
1643
1697
  } catch (error) {
@@ -1663,7 +1717,7 @@ function registerSentinel(program2) {
1663
1717
  return;
1664
1718
  }
1665
1719
  printBlank();
1666
- printLine(` ${pc10.dim("\u23F3")} Requesting attack...`);
1720
+ printLine(` ${pc11.dim("\u23F3")} Requesting attack...`);
1667
1721
  const result = await agent.sentinelAttack(id, prompt, feeMist);
1668
1722
  printBlank();
1669
1723
  if (result.won) {
@@ -1690,7 +1744,7 @@ function registerSentinel(program2) {
1690
1744
 
1691
1745
  // src/commands/earn.ts
1692
1746
  import { T2000 as T200021, MIST_PER_SUI as MIST_PER_SUI2, listSentinels, formatUsd as formatUsd12 } from "@t2000/sdk";
1693
- import pc11 from "picocolors";
1747
+ import pc12 from "picocolors";
1694
1748
  function mistToSui(mist) {
1695
1749
  return Number(mist) / Number(MIST_PER_SUI2);
1696
1750
  }
@@ -1762,7 +1816,7 @@ function registerEarn(program2) {
1762
1816
  return;
1763
1817
  }
1764
1818
  printHeader("Earning Opportunities");
1765
- printLine(pc11.bold("SAVINGS") + pc11.dim(" \u2014 Passive Yield"));
1819
+ printLine(pc12.bold("SAVINGS") + pc12.dim(" \u2014 Passive Yield"));
1766
1820
  printDivider();
1767
1821
  if (savePositions.length > 0) {
1768
1822
  for (const pos of savePositions) {
@@ -1771,7 +1825,7 @@ function registerEarn(program2) {
1771
1825
  if (dailyYield > 1e-4) {
1772
1826
  const dailyStr = dailyYield < 0.01 ? `$${dailyYield.toFixed(4)}` : formatUsd12(dailyYield);
1773
1827
  const monthlyStr = dailyYield * 30 < 0.01 ? `$${(dailyYield * 30).toFixed(4)}` : formatUsd12(dailyYield * 30);
1774
- printLine(pc11.dim(` ~${dailyStr}/day \xB7 ~${monthlyStr}/month`));
1828
+ printLine(pc12.dim(` ~${dailyStr}/day \xB7 ~${monthlyStr}/month`));
1775
1829
  }
1776
1830
  }
1777
1831
  if (savePositions.length > 1) {
@@ -1786,7 +1840,7 @@ function registerEarn(program2) {
1786
1840
  const example = 100;
1787
1841
  const daily = example * bestSaveApy / 100 / 365;
1788
1842
  const monthly = daily * 30;
1789
- 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`));
1790
1844
  printBlank();
1791
1845
  printInfo("No savings yet \u2014 run `t2000 save <amount>` to start");
1792
1846
  } else if (posData) {
@@ -1796,7 +1850,7 @@ function registerEarn(program2) {
1796
1850
  }
1797
1851
  if (earningInvestments.length > 0) {
1798
1852
  printBlank();
1799
- printLine(pc11.bold("INVESTMENTS") + pc11.dim(" \u2014 Earning Yield"));
1853
+ printLine(pc12.bold("INVESTMENTS") + pc12.dim(" \u2014 Earning Yield"));
1800
1854
  printDivider();
1801
1855
  let totalInvestValue = 0;
1802
1856
  for (const pos of earningInvestments) {
@@ -1809,7 +1863,7 @@ function registerEarn(program2) {
1809
1863
  if (dailyYield > 1e-4) {
1810
1864
  const dailyStr = dailyYield < 0.01 ? `$${dailyYield.toFixed(4)}` : formatUsd12(dailyYield);
1811
1865
  const monthlyStr = dailyYield * 30 < 0.01 ? `$${(dailyYield * 30).toFixed(4)}` : formatUsd12(dailyYield * 30);
1812
- printLine(pc11.dim(` ~${dailyStr}/day \xB7 ~${monthlyStr}/month`));
1866
+ printLine(pc12.dim(` ~${dailyStr}/day \xB7 ~${monthlyStr}/month`));
1813
1867
  }
1814
1868
  totalInvestValue += pos.currentValue;
1815
1869
  }
@@ -1819,7 +1873,7 @@ function registerEarn(program2) {
1819
1873
  }
1820
1874
  }
1821
1875
  printBlank();
1822
- printLine(pc11.bold("SENTINEL BOUNTIES") + pc11.dim(" \u2014 Active Red Teaming"));
1876
+ printLine(pc12.bold("SENTINEL BOUNTIES") + pc12.dim(" \u2014 Active Red Teaming"));
1823
1877
  printDivider();
1824
1878
  if (agents && agents.length > 0) {
1825
1879
  const totalPool = agents.reduce((sum, s) => sum + mistToSui(s.prizePool), 0);
@@ -1838,12 +1892,12 @@ function registerEarn(program2) {
1838
1892
  printInfo("Sentinel data unavailable");
1839
1893
  }
1840
1894
  printBlank();
1841
- printLine(pc11.bold("Quick Actions"));
1895
+ printLine(pc12.bold("Quick Actions"));
1842
1896
  printDivider();
1843
- printLine(` ${pc11.dim("t2000 save <amount> [asset]")} Save stablecoins for yield`);
1844
- printLine(` ${pc11.dim("t2000 invest earn <asset>")} Earn yield on investments`);
1845
- printLine(` ${pc11.dim("t2000 sentinel list")} Browse sentinel bounties`);
1846
- 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`);
1847
1901
  printBlank();
1848
1902
  } catch (error) {
1849
1903
  handleError(error);
@@ -1852,7 +1906,7 @@ function registerEarn(program2) {
1852
1906
  }
1853
1907
 
1854
1908
  // src/commands/rebalance.ts
1855
- import pc12 from "picocolors";
1909
+ import pc13 from "picocolors";
1856
1910
  import { T2000 as T200022, formatUsd as formatUsd13, SUPPORTED_ASSETS as SUPPORTED_ASSETS2 } from "@t2000/sdk";
1857
1911
  function registerRebalance(program2) {
1858
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) => {
@@ -1880,24 +1934,24 @@ function registerRebalance(program2) {
1880
1934
  const diff = plan.newApy - plan.currentApy;
1881
1935
  if (diff < minYieldDiff) {
1882
1936
  printInfo(`Already optimized \u2014 ${plan.currentApy.toFixed(2)}% APY on ${plan.fromProtocol}`);
1883
- printLine(pc12.dim(` Best available: ${plan.newApy.toFixed(2)}% (${displayAsset(plan.toAsset)} on ${plan.toProtocol})`));
1884
- 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)`));
1885
1939
  } else if (plan.breakEvenDays > maxBreakEven && plan.estimatedSwapCost > 0) {
1886
1940
  printInfo(`Skipped \u2014 break-even of ${plan.breakEvenDays} days exceeds ${maxBreakEven}-day limit`);
1887
- 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)}%)`));
1888
1942
  } else {
1889
1943
  printInfo("Already at the best rate. Nothing to rebalance.");
1890
1944
  }
1891
1945
  printBlank();
1892
1946
  return;
1893
1947
  }
1894
- printLine(pc12.bold("Rebalance Plan"));
1948
+ printLine(pc13.bold("Rebalance Plan"));
1895
1949
  printDivider();
1896
1950
  printKeyValue("From", `${displayAsset(plan.fromAsset)} on ${plan.fromProtocol} (${plan.currentApy.toFixed(2)}% APY)`);
1897
1951
  printKeyValue("To", `${displayAsset(plan.toAsset)} on ${plan.toProtocol} (${plan.newApy.toFixed(2)}% APY)`);
1898
1952
  printKeyValue("Amount", formatUsd13(plan.amount));
1899
1953
  printBlank();
1900
- printLine(pc12.bold("Economics"));
1954
+ printLine(pc13.bold("Economics"));
1901
1955
  printDivider();
1902
1956
  printKeyValue("APY Gain", `+${(plan.newApy - plan.currentApy).toFixed(2)}%`);
1903
1957
  printKeyValue("Annual Gain", `${formatUsd13(plan.annualGain)}/year`);
@@ -1907,7 +1961,7 @@ function registerRebalance(program2) {
1907
1961
  }
1908
1962
  printBlank();
1909
1963
  if (plan.steps.length > 0) {
1910
- printLine(pc12.bold("Steps"));
1964
+ printLine(pc13.bold("Steps"));
1911
1965
  printDivider();
1912
1966
  for (let i = 0; i < plan.steps.length; i++) {
1913
1967
  const step = plan.steps[i];
@@ -1923,8 +1977,8 @@ function registerRebalance(program2) {
1923
1977
  printBlank();
1924
1978
  }
1925
1979
  if (opts.dryRun) {
1926
- printLine(pc12.bold(pc12.yellow("DRY RUN \u2014 Preview only, no transactions executed")));
1927
- 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."));
1928
1982
  printBlank();
1929
1983
  return;
1930
1984
  }
@@ -2037,7 +2091,7 @@ function registerMcp(program2) {
2037
2091
  mcp.command("start", { isDefault: true }).description("Start MCP server (stdio transport)").option("--key <path>", "Key file path").action(async (opts) => {
2038
2092
  let mod;
2039
2093
  try {
2040
- mod = await import("./dist-JF2T7VQK.js");
2094
+ mod = await import("./dist-NXFA54RO.js");
2041
2095
  } catch {
2042
2096
  console.error(
2043
2097
  "MCP server not installed. Run:\n npm install -g @t2000/mcp"
@@ -2189,7 +2243,7 @@ function registerContacts(program2) {
2189
2243
  }
2190
2244
 
2191
2245
  // src/commands/invest.ts
2192
- import pc13 from "picocolors";
2246
+ import pc14 from "picocolors";
2193
2247
  import { T2000 as T200024, formatUsd as formatUsd15, formatAssetAmount as formatAssetAmount4, INVESTMENT_ASSETS as INVESTMENT_ASSETS2 } from "@t2000/sdk";
2194
2248
  function registerInvest(program2) {
2195
2249
  const investCmd = program2.command("invest").description("Buy or sell investment assets");
@@ -2197,7 +2251,7 @@ function registerInvest(program2) {
2197
2251
  try {
2198
2252
  const parsed = parseFloat(amount);
2199
2253
  if (isNaN(parsed) || parsed <= 0 || !isFinite(parsed)) {
2200
- console.error(pc13.red(" \u2717 Amount must be greater than $0"));
2254
+ console.error(pc14.red(" \u2717 Amount must be greater than $0"));
2201
2255
  process.exitCode = 1;
2202
2256
  return;
2203
2257
  }
@@ -2229,7 +2283,7 @@ function registerInvest(program2) {
2229
2283
  if (!isAll) {
2230
2284
  const parsed = parseFloat(amount);
2231
2285
  if (isNaN(parsed) || parsed <= 0 || !isFinite(parsed)) {
2232
- console.error(pc13.red(" \u2717 Amount must be greater than $0"));
2286
+ console.error(pc14.red(" \u2717 Amount must be greater than $0"));
2233
2287
  process.exitCode = 1;
2234
2288
  return;
2235
2289
  }
@@ -2251,7 +2305,7 @@ function registerInvest(program2) {
2251
2305
  printSuccess(`Sold ${formatAssetAmount4(result.amount, sym)} ${sym} at ${formatUsd15(result.price)}`);
2252
2306
  printKeyValue("Proceeds", formatUsd15(result.usdValue));
2253
2307
  if (result.realizedPnL !== void 0) {
2254
- const pnlColor = result.realizedPnL >= 0 ? pc13.green : pc13.red;
2308
+ const pnlColor = result.realizedPnL >= 0 ? pc14.green : pc14.red;
2255
2309
  const pnlSign = result.realizedPnL >= 0 ? "+" : "";
2256
2310
  printKeyValue("Realized P&L", pnlColor(`${pnlSign}${formatUsd15(result.realizedPnL)}`));
2257
2311
  }
@@ -2382,9 +2436,9 @@ function registerInvest(program2) {
2382
2436
  printSeparator();
2383
2437
  for (const [key, def] of Object.entries(all)) {
2384
2438
  const allocs = Object.entries(def.allocations).map(([a, p]) => `${a} ${p}%`).join(", ");
2385
- const tag = def.custom ? pc13.dim(" (custom)") : "";
2439
+ const tag = def.custom ? pc14.dim(" (custom)") : "";
2386
2440
  printKeyValue(key, `${allocs}${tag}`);
2387
- printLine(` ${pc13.dim(def.description)}`);
2441
+ printLine(` ${pc14.dim(def.description)}`);
2388
2442
  }
2389
2443
  printSeparator();
2390
2444
  const hasPositions = Object.keys(all).some((k) => agent.portfolio.hasStrategyPositions(k));
@@ -2400,7 +2454,7 @@ function registerInvest(program2) {
2400
2454
  try {
2401
2455
  const parsed = parseFloat(amount);
2402
2456
  if (isNaN(parsed) || parsed <= 0) {
2403
- console.error(pc13.red(" \u2717 Amount must be greater than $0"));
2457
+ console.error(pc14.red(" \u2717 Amount must be greater than $0"));
2404
2458
  process.exitCode = 1;
2405
2459
  return;
2406
2460
  }
@@ -2434,7 +2488,7 @@ function registerInvest(program2) {
2434
2488
  printKeyValue("Tx", explorerUrl(txDigests[0]));
2435
2489
  } else {
2436
2490
  for (const buy of result.buys) {
2437
- printLine(` ${pc13.dim(`${buy.asset}: ${explorerUrl(buy.tx)}`)}`);
2491
+ printLine(` ${pc14.dim(`${buy.asset}: ${explorerUrl(buy.tx)}`)}`);
2438
2492
  }
2439
2493
  }
2440
2494
  }
@@ -2456,18 +2510,18 @@ function registerInvest(program2) {
2456
2510
  printSuccess(`Sold all ${name} strategy positions`);
2457
2511
  printSeparator();
2458
2512
  for (const sell of result.sells) {
2459
- const pnlColor = sell.realizedPnL >= 0 ? pc13.green : pc13.red;
2513
+ const pnlColor = sell.realizedPnL >= 0 ? pc14.green : pc14.red;
2460
2514
  const pnlSign = sell.realizedPnL >= 0 ? "+" : "";
2461
2515
  printKeyValue(sell.asset, `${formatAssetAmount4(sell.amount, sell.asset)} \u2192 ${formatUsd15(sell.usdValue)} ${pnlColor(`${pnlSign}${formatUsd15(sell.realizedPnL)}`)}`);
2462
2516
  }
2463
2517
  if (result.failed && result.failed.length > 0) {
2464
2518
  for (const f of result.failed) {
2465
- console.error(pc13.yellow(` \u26A0 ${f.asset}: ${f.reason}`));
2519
+ console.error(pc14.yellow(` \u26A0 ${f.asset}: ${f.reason}`));
2466
2520
  }
2467
2521
  }
2468
2522
  printSeparator();
2469
2523
  printKeyValue("Total proceeds", formatUsd15(result.totalProceeds));
2470
- const rpnlColor = result.realizedPnL >= 0 ? pc13.green : pc13.red;
2524
+ const rpnlColor = result.realizedPnL >= 0 ? pc14.green : pc14.red;
2471
2525
  const rpnlSign = result.realizedPnL >= 0 ? "+" : "";
2472
2526
  printKeyValue("Realized P&L", rpnlColor(`${rpnlSign}${formatUsd15(result.realizedPnL)}`));
2473
2527
  printBlank();
@@ -2494,8 +2548,8 @@ function registerInvest(program2) {
2494
2548
  const target = status.definition.allocations[pos.asset] ?? 0;
2495
2549
  const actual = status.currentWeights[pos.asset] ?? 0;
2496
2550
  const drift = actual - target;
2497
- const driftColor = Math.abs(drift) > 3 ? pc13.yellow : pc13.dim;
2498
- 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;
2499
2553
  const pnlSign = pos.unrealizedPnL >= 0 ? "+" : "";
2500
2554
  printKeyValue(
2501
2555
  pos.asset,
@@ -2526,7 +2580,7 @@ function registerInvest(program2) {
2526
2580
  printSuccess(`Rebalanced ${name} strategy`);
2527
2581
  printSeparator();
2528
2582
  for (const t of result.trades) {
2529
- const action = t.action === "buy" ? pc13.green("BUY") : pc13.red("SELL");
2583
+ const action = t.action === "buy" ? pc14.green("BUY") : pc14.red("SELL");
2530
2584
  printKeyValue(t.asset, `${action} ${formatUsd15(t.usdAmount)} (${formatAssetAmount4(t.amount, t.asset)})`);
2531
2585
  }
2532
2586
  printSeparator();
@@ -2543,7 +2597,7 @@ function registerInvest(program2) {
2543
2597
  for (const pair of opts.alloc) {
2544
2598
  const [asset, pctStr] = pair.split(":");
2545
2599
  if (!asset || !pctStr) {
2546
- 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)`));
2547
2601
  process.exitCode = 1;
2548
2602
  return;
2549
2603
  }
@@ -2570,7 +2624,7 @@ function registerInvest(program2) {
2570
2624
  const pin = await resolvePin();
2571
2625
  const agent = await T200024.create({ pin, keyPath: opts.key });
2572
2626
  if (agent.portfolio.hasStrategyPositions(name.toLowerCase())) {
2573
- 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}`));
2574
2628
  process.exitCode = 1;
2575
2629
  return;
2576
2630
  }
@@ -2591,12 +2645,12 @@ function registerInvest(program2) {
2591
2645
  try {
2592
2646
  const parsed = parseFloat(amount);
2593
2647
  if (isNaN(parsed) || parsed < 1) {
2594
- console.error(pc13.red(" \u2717 Amount must be at least $1"));
2648
+ console.error(pc14.red(" \u2717 Amount must be at least $1"));
2595
2649
  process.exitCode = 1;
2596
2650
  return;
2597
2651
  }
2598
2652
  if (!["daily", "weekly", "monthly"].includes(frequency)) {
2599
- 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"));
2600
2654
  process.exitCode = 1;
2601
2655
  return;
2602
2656
  }
@@ -2606,7 +2660,7 @@ function registerInvest(program2) {
2606
2660
  const isStrategy = target ? target.toLowerCase() in allStrategies : false;
2607
2661
  const isAsset = target ? target.toUpperCase() in INVESTMENT_ASSETS2 : false;
2608
2662
  if (target && !isStrategy && !isAsset) {
2609
- 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`));
2610
2664
  process.exitCode = 1;
2611
2665
  return;
2612
2666
  }
@@ -2653,9 +2707,9 @@ function registerInvest(program2) {
2653
2707
  printSeparator();
2654
2708
  for (const s of status.schedules) {
2655
2709
  const target = s.strategy ?? s.asset ?? "?";
2656
- const statusTag = s.enabled ? pc13.green("active") : pc13.dim("paused");
2710
+ const statusTag = s.enabled ? pc14.green("active") : pc14.dim("paused");
2657
2711
  printKeyValue(s.id, `${formatUsd15(s.amount)} ${s.frequency} \u2192 ${target} ${statusTag}`);
2658
- 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)}`)}`);
2659
2713
  }
2660
2714
  printSeparator();
2661
2715
  if (status.pendingRuns.length > 0) {
@@ -2698,7 +2752,7 @@ function registerInvest(program2) {
2698
2752
  }
2699
2753
  if (result.skipped.length > 0) {
2700
2754
  for (const skip of result.skipped) {
2701
- printLine(` ${pc13.yellow("\u26A0")} Skipped ${skip.scheduleId}: ${skip.reason}`);
2755
+ printLine(` ${pc14.yellow("\u26A0")} Skipped ${skip.scheduleId}: ${skip.reason}`);
2702
2756
  }
2703
2757
  }
2704
2758
  printBlank();
@@ -2725,22 +2779,22 @@ function registerInvest(program2) {
2725
2779
  }
2726
2780
 
2727
2781
  // src/commands/portfolio.ts
2728
- import pc14 from "picocolors";
2782
+ import pc15 from "picocolors";
2729
2783
  import { T2000 as T200025, formatUsd as formatUsd16, formatAssetAmount as formatAssetAmount5 } from "@t2000/sdk";
2730
2784
  function printPositionLine(pos, rewardKeys) {
2731
2785
  if (pos.currentPrice === 0 && pos.totalAmount > 0) {
2732
2786
  printKeyValue(
2733
2787
  pos.asset,
2734
- `${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")}`
2735
2789
  );
2736
2790
  } else {
2737
- const pnlColor = pos.unrealizedPnL >= 0 ? pc14.green : pc14.red;
2791
+ const pnlColor = pos.unrealizedPnL >= 0 ? pc15.green : pc15.red;
2738
2792
  const pnlSign = pos.unrealizedPnL >= 0 ? "+" : "";
2739
2793
  let yieldSuffix = "";
2740
2794
  if (pos.earning && pos.earningApy) {
2741
2795
  const hasRewards = rewardKeys?.has(`${pos.earningProtocol}:${pos.asset}`);
2742
- const rewardTag = hasRewards ? ` ${pc14.yellow("+rewards")}` : "";
2743
- 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}`;
2744
2798
  }
2745
2799
  printKeyValue(
2746
2800
  pos.asset,
@@ -2781,19 +2835,19 @@ function registerPortfolio(program2) {
2781
2835
  stratLabel = def.name;
2782
2836
  } catch {
2783
2837
  }
2784
- printLine(` ${pc14.bold(pc14.cyan(`\u25B8 ${stratLabel}`))}`);
2838
+ printLine(` ${pc15.bold(pc15.cyan(`\u25B8 ${stratLabel}`))}`);
2785
2839
  printSeparator();
2786
2840
  for (const pos of positions) {
2787
2841
  printPositionLine(pos, rewardKeys);
2788
2842
  }
2789
2843
  const stratValue = positions.reduce((s, p) => s + p.currentValue, 0);
2790
- printLine(` ${pc14.dim(`Subtotal: ${formatUsd16(stratValue)}`)}`);
2844
+ printLine(` ${pc15.dim(`Subtotal: ${formatUsd16(stratValue)}`)}`);
2791
2845
  printBlank();
2792
2846
  }
2793
2847
  }
2794
2848
  if (hasDirectPositions) {
2795
2849
  if (hasStrategyPositions) {
2796
- printLine(` ${pc14.bold(pc14.cyan("\u25B8 Direct"))}`);
2850
+ printLine(` ${pc15.bold(pc15.cyan("\u25B8 Direct"))}`);
2797
2851
  }
2798
2852
  printSeparator();
2799
2853
  for (const pos of portfolio.positions) {
@@ -2801,21 +2855,21 @@ function registerPortfolio(program2) {
2801
2855
  }
2802
2856
  if (hasStrategyPositions) {
2803
2857
  const directValue = portfolio.positions.reduce((s, p) => s + p.currentValue, 0);
2804
- printLine(` ${pc14.dim(`Subtotal: ${formatUsd16(directValue)}`)}`);
2858
+ printLine(` ${pc15.dim(`Subtotal: ${formatUsd16(directValue)}`)}`);
2805
2859
  }
2806
2860
  }
2807
2861
  printSeparator();
2808
2862
  const hasPriceUnavailable = portfolio.positions.some((p) => p.currentPrice === 0 && p.totalAmount > 0);
2809
2863
  if (hasPriceUnavailable) {
2810
- 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."));
2811
2865
  }
2812
2866
  printKeyValue("Total invested", formatUsd16(portfolio.totalInvested));
2813
2867
  printKeyValue("Current value", formatUsd16(portfolio.totalValue));
2814
- const upnlColor = portfolio.unrealizedPnL >= 0 ? pc14.green : pc14.red;
2868
+ const upnlColor = portfolio.unrealizedPnL >= 0 ? pc15.green : pc15.red;
2815
2869
  const upnlSign = portfolio.unrealizedPnL >= 0 ? "+" : "";
2816
2870
  printKeyValue("Unrealized P&L", upnlColor(`${upnlSign}${formatUsd16(portfolio.unrealizedPnL)} (${upnlSign}${portfolio.unrealizedPnLPct.toFixed(1)}%)`));
2817
2871
  if (portfolio.realizedPnL !== 0) {
2818
- const rpnlColor = portfolio.realizedPnL >= 0 ? pc14.green : pc14.red;
2872
+ const rpnlColor = portfolio.realizedPnL >= 0 ? pc15.green : pc15.red;
2819
2873
  const rpnlSign = portfolio.realizedPnL >= 0 ? "+" : "";
2820
2874
  printKeyValue("Realized P&L", rpnlColor(`${rpnlSign}${formatUsd16(portfolio.realizedPnL)}`));
2821
2875
  }
@@ -2827,7 +2881,7 @@ function registerPortfolio(program2) {
2827
2881
  }
2828
2882
 
2829
2883
  // src/commands/claimRewards.ts
2830
- import pc15 from "picocolors";
2884
+ import pc16 from "picocolors";
2831
2885
  import { T2000 as T200026, formatUsd as formatUsd17 } from "@t2000/sdk";
2832
2886
  function registerClaimRewards(program2) {
2833
2887
  program2.command("claim-rewards").description("Claim pending protocol rewards").option("--key <path>", "Key file path").action(async (opts) => {
@@ -2841,20 +2895,20 @@ function registerClaimRewards(program2) {
2841
2895
  }
2842
2896
  printBlank();
2843
2897
  if (result.rewards.length === 0) {
2844
- printLine(` ${pc15.dim("No rewards to claim")}`);
2898
+ printLine(` ${pc16.dim("No rewards to claim")}`);
2845
2899
  printBlank();
2846
2900
  return;
2847
2901
  }
2848
2902
  const protocols = [...new Set(result.rewards.map((r) => r.protocol))];
2849
- printLine(` ${pc15.green("\u2713")} Claimed and converted rewards to USDC`);
2903
+ printLine(` ${pc16.green("\u2713")} Claimed and converted rewards to USDC`);
2850
2904
  printSeparator();
2851
2905
  const received = result.usdcReceived;
2852
2906
  if (received >= 0.01) {
2853
- printKeyValue("Received", `${pc15.green(formatUsd17(received))} USDC`);
2907
+ printKeyValue("Received", `${pc16.green(formatUsd17(received))} USDC`);
2854
2908
  } else if (received > 0) {
2855
- printKeyValue("Received", `${pc15.green("< $0.01")} USDC`);
2909
+ printKeyValue("Received", `${pc16.green("< $0.01")} USDC`);
2856
2910
  } else {
2857
- printKeyValue("Received", `${pc15.dim("< $0.01 USDC (rewards are still accruing)")}`);
2911
+ printKeyValue("Received", `${pc16.dim("< $0.01 USDC (rewards are still accruing)")}`);
2858
2912
  }
2859
2913
  printKeyValue("Source", protocols.join(", "));
2860
2914
  if (result.tx) {