@t2000/cli 0.22.6 → 0.22.8
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 +135 -5
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -503,7 +503,6 @@ var ACTION_LABELS = {
|
|
|
503
503
|
send: "\u2197 send",
|
|
504
504
|
lending: "\u{1F3E6} lend",
|
|
505
505
|
swap: "\u{1F504} swap",
|
|
506
|
-
"mpp payment": "\u{1F4B3} mpp",
|
|
507
506
|
transaction: "\u{1F4E6} tx"
|
|
508
507
|
};
|
|
509
508
|
function relativeTime(ts) {
|
|
@@ -1606,7 +1605,7 @@ function registerLock(program2) {
|
|
|
1606
1605
|
});
|
|
1607
1606
|
program2.command("unlock").description("Unlock agent \u2014 resume operations").action(async () => {
|
|
1608
1607
|
try {
|
|
1609
|
-
const { T2000:
|
|
1608
|
+
const { T2000: T200028 } = await import("@t2000/sdk");
|
|
1610
1609
|
const MAX_ATTEMPTS2 = 3;
|
|
1611
1610
|
let pin;
|
|
1612
1611
|
for (let attempt = 1; attempt <= MAX_ATTEMPTS2; attempt++) {
|
|
@@ -1615,7 +1614,7 @@ function registerLock(program2) {
|
|
|
1615
1614
|
throw new Error("PIN required to unlock agent");
|
|
1616
1615
|
}
|
|
1617
1616
|
try {
|
|
1618
|
-
await
|
|
1617
|
+
await T200028.create({ pin });
|
|
1619
1618
|
break;
|
|
1620
1619
|
} catch (error) {
|
|
1621
1620
|
const msg = error instanceof Error ? error.message : "";
|
|
@@ -2324,9 +2323,16 @@ function registerInvest(program2) {
|
|
|
2324
2323
|
}
|
|
2325
2324
|
const pin = await resolvePin();
|
|
2326
2325
|
const agent = await T200024.create({ pin, keyPath: opts.key });
|
|
2326
|
+
const sym = asset.toUpperCase();
|
|
2327
|
+
const strategyAmount = agent.portfolio.getStrategyAmountForAsset(sym);
|
|
2328
|
+
const directAmount = agent.portfolio.getDirectAmount(sym);
|
|
2329
|
+
if (isAll && strategyAmount > 0) {
|
|
2330
|
+
console.log(pc14.yellow(` \u26A0 This will sell ALL ${sym} including ${formatAssetAmount4(strategyAmount, sym)} from strategies`));
|
|
2331
|
+
console.log(pc14.dim(` To sell only strategy positions: t2000 invest strategy sell <strategy-name>`));
|
|
2332
|
+
}
|
|
2327
2333
|
const usdAmount = isAll ? "all" : parseFloat(amount);
|
|
2328
2334
|
const result = await agent.investSell({
|
|
2329
|
-
asset:
|
|
2335
|
+
asset: sym,
|
|
2330
2336
|
usdAmount,
|
|
2331
2337
|
maxSlippage: parseFloat(opts.slippage) / 100
|
|
2332
2338
|
});
|
|
@@ -2335,7 +2341,6 @@ function registerInvest(program2) {
|
|
|
2335
2341
|
return;
|
|
2336
2342
|
}
|
|
2337
2343
|
printBlank();
|
|
2338
|
-
const sym = asset.toUpperCase();
|
|
2339
2344
|
printSuccess(`Sold ${formatAssetAmount4(result.amount, sym)} ${sym} at ${formatUsd15(result.price)}`);
|
|
2340
2345
|
printKeyValue("Proceeds", formatUsd15(result.usdValue));
|
|
2341
2346
|
if (result.realizedPnL !== void 0) {
|
|
@@ -2352,6 +2357,67 @@ function registerInvest(program2) {
|
|
|
2352
2357
|
handleError(error);
|
|
2353
2358
|
}
|
|
2354
2359
|
});
|
|
2360
|
+
investCmd.command("sell-all").description("Sell ALL investment positions (direct + strategies)").option("--key <path>", "Key file path").option("--slippage <pct>", "Max slippage percent", "3").action(async (opts) => {
|
|
2361
|
+
try {
|
|
2362
|
+
const pin = await resolvePin();
|
|
2363
|
+
const agent = await T200024.create({ pin, keyPath: opts.key });
|
|
2364
|
+
const positions = agent.portfolio.getPositions();
|
|
2365
|
+
if (positions.length === 0) {
|
|
2366
|
+
if (isJsonMode()) {
|
|
2367
|
+
printJson({ sold: [] });
|
|
2368
|
+
return;
|
|
2369
|
+
}
|
|
2370
|
+
printBlank();
|
|
2371
|
+
printInfo("No investment positions to sell");
|
|
2372
|
+
printBlank();
|
|
2373
|
+
return;
|
|
2374
|
+
}
|
|
2375
|
+
if (isJsonMode()) {
|
|
2376
|
+
const results = [];
|
|
2377
|
+
for (const pos of positions) {
|
|
2378
|
+
const result = await agent.investSell({
|
|
2379
|
+
asset: pos.asset,
|
|
2380
|
+
usdAmount: "all",
|
|
2381
|
+
maxSlippage: parseFloat(opts.slippage) / 100
|
|
2382
|
+
});
|
|
2383
|
+
results.push(result);
|
|
2384
|
+
}
|
|
2385
|
+
printJson(results);
|
|
2386
|
+
return;
|
|
2387
|
+
}
|
|
2388
|
+
printBlank();
|
|
2389
|
+
printHeader("Selling all positions");
|
|
2390
|
+
printSeparator();
|
|
2391
|
+
let totalProceeds = 0;
|
|
2392
|
+
let totalPnL = 0;
|
|
2393
|
+
for (const pos of positions) {
|
|
2394
|
+
try {
|
|
2395
|
+
const result = await agent.investSell({
|
|
2396
|
+
asset: pos.asset,
|
|
2397
|
+
usdAmount: "all",
|
|
2398
|
+
maxSlippage: parseFloat(opts.slippage) / 100
|
|
2399
|
+
});
|
|
2400
|
+
const pnl = result.realizedPnL ?? 0;
|
|
2401
|
+
const pnlColor = pnl >= 0 ? pc14.green : pc14.red;
|
|
2402
|
+
const pnlSign = pnl >= 0 ? "+" : "";
|
|
2403
|
+
printKeyValue(pos.asset, `${formatUsd15(result.usdValue)} ${pnlColor(`${pnlSign}${formatUsd15(pnl)}`)}`);
|
|
2404
|
+
totalProceeds += result.usdValue;
|
|
2405
|
+
totalPnL += pnl;
|
|
2406
|
+
} catch (err) {
|
|
2407
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2408
|
+
console.error(pc14.yellow(` \u26A0 ${pos.asset}: ${msg}`));
|
|
2409
|
+
}
|
|
2410
|
+
}
|
|
2411
|
+
printSeparator();
|
|
2412
|
+
printKeyValue("Total proceeds", formatUsd15(totalProceeds));
|
|
2413
|
+
const rpnlColor = totalPnL >= 0 ? pc14.green : pc14.red;
|
|
2414
|
+
const rpnlSign = totalPnL >= 0 ? "+" : "";
|
|
2415
|
+
printKeyValue("Realized P&L", rpnlColor(`${rpnlSign}${formatUsd15(totalPnL)}`));
|
|
2416
|
+
printBlank();
|
|
2417
|
+
} catch (error) {
|
|
2418
|
+
handleError(error);
|
|
2419
|
+
}
|
|
2420
|
+
});
|
|
2355
2421
|
investCmd.command("earn <asset>").description("Deposit invested asset into best-rate lending protocol").option("--key <path>", "Key file path").option("--protocol <name>", "Force a specific protocol (navi, suilend)").action(async (asset, opts) => {
|
|
2356
2422
|
try {
|
|
2357
2423
|
const pin = await resolvePin();
|
|
@@ -2955,6 +3021,69 @@ function registerClaimRewards(program2) {
|
|
|
2955
3021
|
});
|
|
2956
3022
|
}
|
|
2957
3023
|
|
|
3024
|
+
// src/commands/gas.ts
|
|
3025
|
+
import pc17 from "picocolors";
|
|
3026
|
+
import { T2000 as T200027, getGasStatus } from "@t2000/sdk";
|
|
3027
|
+
function registerGas(program2) {
|
|
3028
|
+
program2.command("gas").description("Check gas station status and wallet gas balance").option("--key <path>", "Key file path").action(async (opts) => {
|
|
3029
|
+
try {
|
|
3030
|
+
const pin = await resolvePin();
|
|
3031
|
+
const agent = await T200027.create({ pin, keyPath: opts.key });
|
|
3032
|
+
const address = agent.address();
|
|
3033
|
+
const [status, bal] = await Promise.allSettled([
|
|
3034
|
+
getGasStatus(address),
|
|
3035
|
+
agent.balance()
|
|
3036
|
+
]);
|
|
3037
|
+
const gasStatus = status.status === "fulfilled" ? status.value : null;
|
|
3038
|
+
const balData = bal.status === "fulfilled" ? bal.value : null;
|
|
3039
|
+
if (isJsonMode()) {
|
|
3040
|
+
printJson({
|
|
3041
|
+
gasStation: gasStatus ?? { error: status.status === "rejected" ? String(status.reason) : "unavailable" },
|
|
3042
|
+
wallet: balData ? { sui: balData.gasReserve.sui, available: balData.available } : null
|
|
3043
|
+
});
|
|
3044
|
+
return;
|
|
3045
|
+
}
|
|
3046
|
+
printHeader("Gas Status");
|
|
3047
|
+
if (gasStatus) {
|
|
3048
|
+
const cbStatus = gasStatus.circuitBreaker ? pc17.red("TRIPPED \u2014 sponsorship paused") : pc17.green("OK");
|
|
3049
|
+
printKeyValue("Gas Station", cbStatus);
|
|
3050
|
+
printKeyValue("SUI Price (TWAP)", `$${gasStatus.suiPrice.toFixed(4)}`);
|
|
3051
|
+
if (gasStatus.bootstrapRemaining !== void 0) {
|
|
3052
|
+
printKeyValue("Bootstrap", `${gasStatus.bootstrapUsed}/10 used (${gasStatus.bootstrapRemaining} remaining)`);
|
|
3053
|
+
}
|
|
3054
|
+
} else {
|
|
3055
|
+
printKeyValue("Gas Station", pc17.red("unreachable"));
|
|
3056
|
+
const reason = status.status === "rejected" ? status.reason : "unknown";
|
|
3057
|
+
printLine(` ${pc17.dim(reason instanceof Error ? reason.message : String(reason))}`);
|
|
3058
|
+
}
|
|
3059
|
+
printDivider();
|
|
3060
|
+
if (balData) {
|
|
3061
|
+
const suiBal = balData.gasReserve.sui;
|
|
3062
|
+
const suiColor = suiBal < 0.05 ? pc17.red : pc17.green;
|
|
3063
|
+
printKeyValue("SUI (gas)", suiColor(`${suiBal.toFixed(4)} SUI`));
|
|
3064
|
+
if (suiBal < 0.05) {
|
|
3065
|
+
printLine(` ${pc17.yellow("\u26A0")} Below gas threshold (0.05 SUI) \u2014 transactions will need sponsorship`);
|
|
3066
|
+
}
|
|
3067
|
+
printKeyValue("Available", `$${balData.available.toFixed(2)}`);
|
|
3068
|
+
} else {
|
|
3069
|
+
printKeyValue("Wallet", pc17.dim("could not fetch balances"));
|
|
3070
|
+
}
|
|
3071
|
+
printBlank();
|
|
3072
|
+
if (gasStatus && !gasStatus.circuitBreaker && (balData?.gasReserve.sui ?? 0) >= 0.05) {
|
|
3073
|
+
printLine(` ${pc17.green("\u2713")} Gas is healthy \u2014 transactions should succeed`);
|
|
3074
|
+
} else if (gasStatus && !gasStatus.circuitBreaker) {
|
|
3075
|
+
printLine(` ${pc17.yellow("\u26A0")} Low SUI but gas station is online \u2014 sponsorship available`);
|
|
3076
|
+
} else {
|
|
3077
|
+
printLine(` ${pc17.red("\u2717")} Gas station issues detected \u2014 fund wallet with SUI directly`);
|
|
3078
|
+
printInfo("Send SUI to your address: t2000 address");
|
|
3079
|
+
}
|
|
3080
|
+
printBlank();
|
|
3081
|
+
} catch (error) {
|
|
3082
|
+
handleError(error);
|
|
3083
|
+
}
|
|
3084
|
+
});
|
|
3085
|
+
}
|
|
3086
|
+
|
|
2958
3087
|
// src/program.ts
|
|
2959
3088
|
var require2 = createRequire(import.meta.url);
|
|
2960
3089
|
var { version: CLI_VERSION } = require2("../package.json");
|
|
@@ -2994,6 +3123,7 @@ function createProgram() {
|
|
|
2994
3123
|
registerInvest(program2);
|
|
2995
3124
|
registerPortfolio(program2);
|
|
2996
3125
|
registerClaimRewards(program2);
|
|
3126
|
+
registerGas(program2);
|
|
2997
3127
|
return program2;
|
|
2998
3128
|
}
|
|
2999
3129
|
|