@t2000/cli 0.10.4 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -2
- package/dist/chunk-D4HDZEJT.js +37 -0
- package/dist/chunk-D4HDZEJT.js.map +1 -0
- package/dist/dist-QVEFT4TY.js +21540 -0
- package/dist/dist-QVEFT4TY.js.map +1 -0
- package/dist/index.js +115 -17
- package/dist/index.js.map +1 -1
- package/package.json +6 -3
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import "./chunk-D4HDZEJT.js";
|
|
2
3
|
|
|
3
4
|
// src/program.ts
|
|
4
5
|
import { Command } from "commander";
|
|
@@ -790,8 +791,10 @@ function registerFundStatus(program2) {
|
|
|
790
791
|
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
|
|
791
792
|
import { join } from "path";
|
|
792
793
|
import { homedir as homedir3 } from "os";
|
|
794
|
+
import { SafeguardEnforcer } from "@t2000/sdk";
|
|
793
795
|
var CONFIG_DIR = join(homedir3(), ".t2000");
|
|
794
796
|
var CONFIG_PATH = join(CONFIG_DIR, "config.json");
|
|
797
|
+
var SAFEGUARD_KEYS = /* @__PURE__ */ new Set(["locked", "maxPerTx", "maxDailySend", "dailyUsed", "dailyResetDate", "alertThreshold"]);
|
|
795
798
|
function loadConfig() {
|
|
796
799
|
try {
|
|
797
800
|
return JSON.parse(readFileSync(CONFIG_PATH, "utf-8"));
|
|
@@ -805,8 +808,35 @@ function saveConfig(config) {
|
|
|
805
808
|
}
|
|
806
809
|
writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + "\n");
|
|
807
810
|
}
|
|
811
|
+
function formatUsd11(amount) {
|
|
812
|
+
return `$${amount.toFixed(2)}`;
|
|
813
|
+
}
|
|
808
814
|
function registerConfig(program2) {
|
|
809
815
|
const configCmd = program2.command("config").description("Show or set configuration");
|
|
816
|
+
configCmd.command("show").description("Show safeguard settings").action(() => {
|
|
817
|
+
try {
|
|
818
|
+
const enforcer = new SafeguardEnforcer(CONFIG_DIR);
|
|
819
|
+
enforcer.load();
|
|
820
|
+
const config = enforcer.getConfig();
|
|
821
|
+
if (isJsonMode()) {
|
|
822
|
+
printJson({
|
|
823
|
+
locked: config.locked,
|
|
824
|
+
maxPerTx: config.maxPerTx,
|
|
825
|
+
maxDailySend: config.maxDailySend,
|
|
826
|
+
dailyUsed: config.dailyUsed
|
|
827
|
+
});
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
printHeader("Agent Safeguards");
|
|
831
|
+
printDivider();
|
|
832
|
+
printKeyValue("Locked", config.locked ? "Yes" : "No");
|
|
833
|
+
printKeyValue("Per-transaction", config.maxPerTx > 0 ? formatUsd11(config.maxPerTx) : "Unlimited");
|
|
834
|
+
printKeyValue("Daily send limit", config.maxDailySend > 0 ? `${formatUsd11(config.maxDailySend)} (${formatUsd11(config.dailyUsed)} used today)` : "Unlimited");
|
|
835
|
+
printBlank();
|
|
836
|
+
} catch (error) {
|
|
837
|
+
handleError(error);
|
|
838
|
+
}
|
|
839
|
+
});
|
|
810
840
|
configCmd.command("get").argument("[key]", "Config key to get (omit for all)").action((key) => {
|
|
811
841
|
try {
|
|
812
842
|
const config = loadConfig();
|
|
@@ -833,6 +863,23 @@ function registerConfig(program2) {
|
|
|
833
863
|
});
|
|
834
864
|
configCmd.command("set").argument("<key>", "Config key").argument("<value>", "Config value").action((key, value) => {
|
|
835
865
|
try {
|
|
866
|
+
if (SAFEGUARD_KEYS.has(key)) {
|
|
867
|
+
const enforcer = new SafeguardEnforcer(CONFIG_DIR);
|
|
868
|
+
enforcer.load();
|
|
869
|
+
let parsed2 = value;
|
|
870
|
+
if (value === "true") parsed2 = true;
|
|
871
|
+
else if (value === "false") parsed2 = false;
|
|
872
|
+
else if (!isNaN(Number(value)) && value.trim() !== "") parsed2 = Number(value);
|
|
873
|
+
enforcer.set(key, parsed2);
|
|
874
|
+
if (isJsonMode()) {
|
|
875
|
+
printJson({ [key]: parsed2 });
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
printBlank();
|
|
879
|
+
printSuccess(`Set ${key} = ${String(parsed2)}`);
|
|
880
|
+
printBlank();
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
836
883
|
const config = loadConfig();
|
|
837
884
|
let parsed = value;
|
|
838
885
|
if (value === "true") parsed = true;
|
|
@@ -1189,6 +1236,7 @@ function registerPay(program2) {
|
|
|
1189
1236
|
try {
|
|
1190
1237
|
const pin = await resolvePin();
|
|
1191
1238
|
const agent = await T200019.create({ pin, keyPath: opts.key });
|
|
1239
|
+
agent.enforcer.check({ operation: "pay", amount: parseFloat(opts.maxPrice) });
|
|
1192
1240
|
const wallet = createX402Wallet(agent);
|
|
1193
1241
|
const client = new x402Client(wallet);
|
|
1194
1242
|
const startTime = Date.now();
|
|
@@ -1246,12 +1294,53 @@ function collectHeaders(value, previous) {
|
|
|
1246
1294
|
}
|
|
1247
1295
|
|
|
1248
1296
|
// src/commands/lock.ts
|
|
1297
|
+
import { join as join3 } from "path";
|
|
1298
|
+
import { homedir as homedir5 } from "os";
|
|
1299
|
+
import { SafeguardEnforcer as SafeguardEnforcer2 } from "@t2000/sdk";
|
|
1300
|
+
var CONFIG_DIR3 = join3(homedir5(), ".t2000");
|
|
1249
1301
|
function registerLock(program2) {
|
|
1250
|
-
program2.command("lock").description("
|
|
1302
|
+
program2.command("lock").description("Lock agent \u2014 freeze all operations").action(async () => {
|
|
1251
1303
|
try {
|
|
1304
|
+
const enforcer = new SafeguardEnforcer2(CONFIG_DIR3);
|
|
1305
|
+
enforcer.load();
|
|
1306
|
+
enforcer.lock();
|
|
1252
1307
|
await clearSession();
|
|
1308
|
+
if (isJsonMode()) {
|
|
1309
|
+
printJson({ locked: true });
|
|
1310
|
+
return;
|
|
1311
|
+
}
|
|
1312
|
+
printBlank();
|
|
1313
|
+
printSuccess("Agent locked. All operations frozen.");
|
|
1314
|
+
printInfo("Run: t2000 unlock (requires PIN)");
|
|
1315
|
+
printBlank();
|
|
1316
|
+
} catch (error) {
|
|
1317
|
+
handleError(error);
|
|
1318
|
+
}
|
|
1319
|
+
});
|
|
1320
|
+
program2.command("unlock").description("Unlock agent \u2014 resume operations").action(async () => {
|
|
1321
|
+
try {
|
|
1322
|
+
const pin = await resolvePin();
|
|
1323
|
+
if (!pin) {
|
|
1324
|
+
throw new Error("PIN required to unlock agent");
|
|
1325
|
+
}
|
|
1326
|
+
const { T2000: T200024 } = await import("@t2000/sdk");
|
|
1327
|
+
await T200024.create({ pin });
|
|
1328
|
+
const enforcer = new SafeguardEnforcer2(CONFIG_DIR3);
|
|
1329
|
+
enforcer.load();
|
|
1330
|
+
enforcer.unlock();
|
|
1331
|
+
if (isJsonMode()) {
|
|
1332
|
+
printJson({ locked: false });
|
|
1333
|
+
return;
|
|
1334
|
+
}
|
|
1335
|
+
const config = enforcer.getConfig();
|
|
1253
1336
|
printBlank();
|
|
1254
|
-
printSuccess("
|
|
1337
|
+
printSuccess("Agent unlocked. Operations resumed.");
|
|
1338
|
+
if (config.maxPerTx > 0 || config.maxDailySend > 0) {
|
|
1339
|
+
const limits = [];
|
|
1340
|
+
if (config.maxPerTx > 0) limits.push(`maxPerTx=$${config.maxPerTx}`);
|
|
1341
|
+
if (config.maxDailySend > 0) limits.push(`maxDailySend=$${config.maxDailySend}`);
|
|
1342
|
+
printInfo(`Active safeguards: ${limits.join(", ")}`);
|
|
1343
|
+
}
|
|
1255
1344
|
printBlank();
|
|
1256
1345
|
} catch (error) {
|
|
1257
1346
|
handleError(error);
|
|
@@ -1379,7 +1468,7 @@ function registerSentinel(program2) {
|
|
|
1379
1468
|
}
|
|
1380
1469
|
|
|
1381
1470
|
// src/commands/earn.ts
|
|
1382
|
-
import { T2000 as T200021, MIST_PER_SUI as MIST_PER_SUI2, listSentinels, formatUsd as
|
|
1471
|
+
import { T2000 as T200021, MIST_PER_SUI as MIST_PER_SUI2, listSentinels, formatUsd as formatUsd12 } from "@t2000/sdk";
|
|
1383
1472
|
import pc11 from "picocolors";
|
|
1384
1473
|
function mistToSui(mist) {
|
|
1385
1474
|
return Number(mist) / Number(MIST_PER_SUI2);
|
|
@@ -1439,16 +1528,16 @@ function registerEarn(program2) {
|
|
|
1439
1528
|
if (savePositions.length > 0) {
|
|
1440
1529
|
for (const pos of savePositions) {
|
|
1441
1530
|
const dailyYield = pos.amount * pos.apy / 100 / 365;
|
|
1442
|
-
printKeyValue(pos.protocol, `${
|
|
1531
|
+
printKeyValue(pos.protocol, `${formatUsd12(pos.amount)} ${pos.asset} @ ${pos.apy.toFixed(2)}% APY`);
|
|
1443
1532
|
if (dailyYield > 1e-4) {
|
|
1444
|
-
const dailyStr = dailyYield < 0.01 ? `$${dailyYield.toFixed(4)}` :
|
|
1445
|
-
const monthlyStr = dailyYield * 30 < 0.01 ? `$${(dailyYield * 30).toFixed(4)}` :
|
|
1533
|
+
const dailyStr = dailyYield < 0.01 ? `$${dailyYield.toFixed(4)}` : formatUsd12(dailyYield);
|
|
1534
|
+
const monthlyStr = dailyYield * 30 < 0.01 ? `$${(dailyYield * 30).toFixed(4)}` : formatUsd12(dailyYield * 30);
|
|
1446
1535
|
printLine(pc11.dim(` ~${dailyStr}/day \xB7 ~${monthlyStr}/month`));
|
|
1447
1536
|
}
|
|
1448
1537
|
}
|
|
1449
1538
|
if (savePositions.length > 1) {
|
|
1450
1539
|
printBlank();
|
|
1451
|
-
printKeyValue("Total Saved",
|
|
1540
|
+
printKeyValue("Total Saved", formatUsd12(totalSaved));
|
|
1452
1541
|
}
|
|
1453
1542
|
} else if (posData) {
|
|
1454
1543
|
printInfo("No savings yet \u2014 run `t2000 save <amount>` to start earning yield");
|
|
@@ -1489,7 +1578,7 @@ function registerEarn(program2) {
|
|
|
1489
1578
|
|
|
1490
1579
|
// src/commands/rebalance.ts
|
|
1491
1580
|
import pc12 from "picocolors";
|
|
1492
|
-
import { T2000 as T200022, formatUsd as
|
|
1581
|
+
import { T2000 as T200022, formatUsd as formatUsd13, SUPPORTED_ASSETS as SUPPORTED_ASSETS2 } from "@t2000/sdk";
|
|
1493
1582
|
function registerRebalance(program2) {
|
|
1494
1583
|
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) => {
|
|
1495
1584
|
try {
|
|
@@ -1531,14 +1620,14 @@ function registerRebalance(program2) {
|
|
|
1531
1620
|
printDivider();
|
|
1532
1621
|
printKeyValue("From", `${displayAsset(plan.fromAsset)} on ${plan.fromProtocol} (${plan.currentApy.toFixed(2)}% APY)`);
|
|
1533
1622
|
printKeyValue("To", `${displayAsset(plan.toAsset)} on ${plan.toProtocol} (${plan.newApy.toFixed(2)}% APY)`);
|
|
1534
|
-
printKeyValue("Amount",
|
|
1623
|
+
printKeyValue("Amount", formatUsd13(plan.amount));
|
|
1535
1624
|
printBlank();
|
|
1536
1625
|
printLine(pc12.bold("Economics"));
|
|
1537
1626
|
printDivider();
|
|
1538
1627
|
printKeyValue("APY Gain", `+${(plan.newApy - plan.currentApy).toFixed(2)}%`);
|
|
1539
|
-
printKeyValue("Annual Gain", `${
|
|
1628
|
+
printKeyValue("Annual Gain", `${formatUsd13(plan.annualGain)}/year`);
|
|
1540
1629
|
if (plan.estimatedSwapCost > 0) {
|
|
1541
|
-
printKeyValue("Swap Cost", `~${
|
|
1630
|
+
printKeyValue("Swap Cost", `~${formatUsd13(plan.estimatedSwapCost)}`);
|
|
1542
1631
|
printKeyValue("Break-even", `${plan.breakEvenDays} days`);
|
|
1543
1632
|
}
|
|
1544
1633
|
printBlank();
|
|
@@ -1549,11 +1638,11 @@ function registerRebalance(program2) {
|
|
|
1549
1638
|
const step = plan.steps[i];
|
|
1550
1639
|
const num = `${i + 1}.`;
|
|
1551
1640
|
if (step.action === "withdraw") {
|
|
1552
|
-
printLine(` ${num} Withdraw ${
|
|
1641
|
+
printLine(` ${num} Withdraw ${formatUsd13(step.amount)} ${displayAsset(step.fromAsset ?? "")} from ${step.protocol}`);
|
|
1553
1642
|
} else if (step.action === "swap") {
|
|
1554
|
-
printLine(` ${num} Swap ${displayAsset(step.fromAsset ?? "")} \u2192 ${displayAsset(step.toAsset ?? "")} (~${
|
|
1643
|
+
printLine(` ${num} Swap ${displayAsset(step.fromAsset ?? "")} \u2192 ${displayAsset(step.toAsset ?? "")} (~${formatUsd13(step.estimatedOutput ?? 0)})`);
|
|
1555
1644
|
} else if (step.action === "deposit") {
|
|
1556
|
-
printLine(` ${num} Deposit ${
|
|
1645
|
+
printLine(` ${num} Deposit ${formatUsd13(step.amount)} ${displayAsset(step.toAsset ?? "")} into ${step.protocol}`);
|
|
1557
1646
|
}
|
|
1558
1647
|
}
|
|
1559
1648
|
printBlank();
|
|
@@ -1566,7 +1655,7 @@ function registerRebalance(program2) {
|
|
|
1566
1655
|
}
|
|
1567
1656
|
const result = await agent.rebalance({ dryRun: false, minYieldDiff, maxBreakEven });
|
|
1568
1657
|
if (result.executed) {
|
|
1569
|
-
printSuccess(`Rebalanced ${
|
|
1658
|
+
printSuccess(`Rebalanced ${formatUsd13(result.amount)} \u2192 ${result.newApy.toFixed(2)}% APY`);
|
|
1570
1659
|
for (const digest of result.txDigests) {
|
|
1571
1660
|
printKeyValue("Tx", explorerUrl(digest));
|
|
1572
1661
|
}
|
|
@@ -1583,7 +1672,7 @@ function displayAsset(asset) {
|
|
|
1583
1672
|
}
|
|
1584
1673
|
|
|
1585
1674
|
// src/commands/exchange.ts
|
|
1586
|
-
import { T2000 as T200023, formatUsd as
|
|
1675
|
+
import { T2000 as T200023, formatUsd as formatUsd14, SUPPORTED_ASSETS as SUPPORTED_ASSETS3 } from "@t2000/sdk";
|
|
1587
1676
|
function registerExchange(program2) {
|
|
1588
1677
|
program2.command("exchange <amount> <from> <to>").description("Exchange between tokens (e.g. USDC \u21CC SUI) via Cetus DEX").option("--key <path>", "Key file path").option("--slippage <pct>", "Max slippage percentage (default: 3)", "3").action(async (amount, from, to, opts) => {
|
|
1589
1678
|
try {
|
|
@@ -1609,7 +1698,7 @@ function registerExchange(program2) {
|
|
|
1609
1698
|
const toDisplay = SUPPORTED_ASSETS3[toAsset]?.displayName ?? toAsset;
|
|
1610
1699
|
const toDecimals = toAsset === "SUI" ? 4 : 2;
|
|
1611
1700
|
printBlank();
|
|
1612
|
-
const fromStr = ["USDC", "USDT", "USDE"].includes(fromAsset) ?
|
|
1701
|
+
const fromStr = ["USDC", "USDT", "USDE"].includes(fromAsset) ? formatUsd14(parsedAmount) : parsedAmount.toFixed(4);
|
|
1613
1702
|
printSuccess(`Exchanged ${fromStr} ${fromDisplay} \u2192 ${result.toAmount.toFixed(toDecimals)} ${toDisplay}`);
|
|
1614
1703
|
printKeyValue("Tx", explorerUrl(result.tx));
|
|
1615
1704
|
printKeyValue("Gas", `${result.gasCost.toFixed(4)} SUI (${result.gasMethod})`);
|
|
@@ -1620,6 +1709,14 @@ function registerExchange(program2) {
|
|
|
1620
1709
|
});
|
|
1621
1710
|
}
|
|
1622
1711
|
|
|
1712
|
+
// src/commands/mcp.ts
|
|
1713
|
+
function registerMcp(program2) {
|
|
1714
|
+
program2.command("mcp").description("Start MCP server (stdio transport)").option("--key <path>", "Key file path").action(async (opts) => {
|
|
1715
|
+
const { startMcpServer } = await import("./dist-QVEFT4TY.js");
|
|
1716
|
+
await startMcpServer({ keyPath: opts.key });
|
|
1717
|
+
});
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1623
1720
|
// src/program.ts
|
|
1624
1721
|
var require2 = createRequire(import.meta.url);
|
|
1625
1722
|
var { version: CLI_VERSION } = require2("../package.json");
|
|
@@ -1654,6 +1751,7 @@ function createProgram() {
|
|
|
1654
1751
|
registerEarn(program2);
|
|
1655
1752
|
registerRebalance(program2);
|
|
1656
1753
|
registerExchange(program2);
|
|
1754
|
+
registerMcp(program2);
|
|
1657
1755
|
return program2;
|
|
1658
1756
|
}
|
|
1659
1757
|
|