@otonix/cli 1.7.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -246
- package/dist/commands/agent.d.ts +2 -0
- package/dist/commands/agent.js +287 -0
- package/dist/commands/launch.d.ts +2 -0
- package/dist/commands/launch.js +207 -0
- package/dist/commands/wallet.d.ts +2 -0
- package/dist/commands/wallet.js +166 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +44 -0
- package/dist/lib/chain.d.ts +15294 -0
- package/dist/lib/chain.js +58 -0
- package/dist/lib/config.d.ts +24 -0
- package/dist/lib/config.js +39 -0
- package/dist/lib/display.d.ts +14 -0
- package/dist/lib/display.js +50 -0
- package/package.json +25 -32
- package/dist/cli.js +0 -1531
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { confirm } from "@inquirer/prompts";
|
|
2
|
+
import ora from "ora";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { loadConfig, OTONIX_TREASURY } from "../lib/config.js";
|
|
5
|
+
import { getEthBalance, BASE_RPC, } from "../lib/chain.js";
|
|
6
|
+
import { header, row, failure, info, br, warn, } from "../lib/display.js";
|
|
7
|
+
const WETH_BASE = "0x4200000000000000000000000000000000000006";
|
|
8
|
+
const OTONIX_TWITTER = "otonix_tech";
|
|
9
|
+
export function launchCommand(program) {
|
|
10
|
+
const launch = program.command("launch").description("Launch tokens via autonomous agents");
|
|
11
|
+
launch
|
|
12
|
+
.command("token")
|
|
13
|
+
.description("Deploy a token on Base via your agent (Clanker v4 / Uniswap v4)")
|
|
14
|
+
.requiredOption("--agent <name>", "Agent name to deploy with")
|
|
15
|
+
.requiredOption("--name <name>", "Token name (e.g. CoolToken)")
|
|
16
|
+
.requiredOption("--ticker <ticker>", "Token ticker/symbol (e.g. COOL)")
|
|
17
|
+
.requiredOption("--image <url>", "Token logo URL (https:// or ipfs://)")
|
|
18
|
+
.requiredOption("--description <text>", "Token description")
|
|
19
|
+
.option("--twitter <handle>", "Your Twitter/X handle (e.g. yourname) — shown in metadata")
|
|
20
|
+
.option("--devbuy <eth>", "Initial dev buy in ETH (default: 0)", "0")
|
|
21
|
+
.action(async (opts) => {
|
|
22
|
+
header("Launch Token");
|
|
23
|
+
const cfg = loadConfig();
|
|
24
|
+
if (!cfg.wallet) {
|
|
25
|
+
failure("No wallet. Run: otonix wallet generate");
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
const agent = cfg.agents[opts.agent];
|
|
29
|
+
if (!agent) {
|
|
30
|
+
failure(`Agent "${opts.agent}" not found. Run: otonix agent:list`);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
if (!agent.registered) {
|
|
34
|
+
br();
|
|
35
|
+
failure(`Agent "${opts.agent}" is not registered.`);
|
|
36
|
+
console.log(chalk.dim(" Send 200 $OTX from your creator wallet to:"));
|
|
37
|
+
console.log(" " + chalk.white(OTONIX_TREASURY));
|
|
38
|
+
console.log(chalk.dim(" Then submit the tx hash to activate:"));
|
|
39
|
+
console.log(" " + chalk.cyan(`otonix agent:register --name ${opts.agent} --tx <txhash>`));
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
const devBuyEth = parseFloat(opts.devbuy) || 0;
|
|
43
|
+
const minEthNeeded = 0.001 + devBuyEth;
|
|
44
|
+
const twitterHandle = opts.twitter?.replace(/^@/, "") ?? "";
|
|
45
|
+
const checkSpinner = ora("Checking agent wallet...").start();
|
|
46
|
+
let agentEth;
|
|
47
|
+
try {
|
|
48
|
+
agentEth = await getEthBalance(agent.address);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
checkSpinner.stop();
|
|
52
|
+
failure("Failed to fetch agent balance. Check your connection.");
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
checkSpinner.stop();
|
|
56
|
+
let passed = true;
|
|
57
|
+
console.log(chalk.green("✓ ") + chalk.dim(`Agent registered (tx: ${agent.registerTxHash?.slice(0, 18)}...)`));
|
|
58
|
+
if (parseFloat(agentEth) < minEthNeeded) {
|
|
59
|
+
console.log(warn("⚠ ") + chalk.dim(`Agent ETH: ${agentEth} — need ≥${minEthNeeded} ETH for gas`));
|
|
60
|
+
console.log(chalk.dim(" Send ETH to: ") + chalk.white(agent.address));
|
|
61
|
+
passed = false;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
console.log(chalk.green("✓ ") + chalk.dim(`Agent ETH: ${agentEth} (sufficient)`));
|
|
65
|
+
}
|
|
66
|
+
if (!passed) {
|
|
67
|
+
br();
|
|
68
|
+
failure("Pre-flight checks failed. Fix the issues above and try again.");
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
br();
|
|
72
|
+
console.log(chalk.bold.white("Token to deploy:"));
|
|
73
|
+
row("Name", opts.name);
|
|
74
|
+
row("Ticker", "$" + opts.ticker.toUpperCase());
|
|
75
|
+
row("Description", opts.description.slice(0, 60) + (opts.description.length > 60 ? "..." : ""));
|
|
76
|
+
row("Logo URL", opts.image.slice(0, 55) + (opts.image.length > 55 ? "..." : ""));
|
|
77
|
+
if (twitterHandle)
|
|
78
|
+
row("Twitter", "@" + twitterHandle);
|
|
79
|
+
row("Agent", opts.agent + " (" + agent.address.slice(0, 10) + "...)");
|
|
80
|
+
row("Chain", "Base Mainnet");
|
|
81
|
+
row("LP protocol", "Clanker v4 (Uniswap v4)");
|
|
82
|
+
row("Paired token", "WETH");
|
|
83
|
+
if (devBuyEth > 0)
|
|
84
|
+
row("Dev buy", devBuyEth + " ETH");
|
|
85
|
+
row("Fee split", "80% → you (WETH) / 20% → $OTX burn");
|
|
86
|
+
row("Verified by", "✓ Otonix (@" + OTONIX_TWITTER + ")");
|
|
87
|
+
br();
|
|
88
|
+
const confirmed = await confirm({
|
|
89
|
+
message: "Deploy this token? (agent wallet signs & pays gas)",
|
|
90
|
+
default: true,
|
|
91
|
+
});
|
|
92
|
+
if (!confirmed) {
|
|
93
|
+
info("Cancelled.");
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const deploySpinner = ora("Deploying token on Base (Clanker v4 / Uniswap v4)...").start();
|
|
97
|
+
try {
|
|
98
|
+
const { createWalletClient, createPublicClient, http } = await import("viem");
|
|
99
|
+
const { base } = await import("viem/chains");
|
|
100
|
+
const { privateKeyToAccount } = await import("viem/accounts");
|
|
101
|
+
const { Clanker } = await import("clanker-sdk/v4");
|
|
102
|
+
const { POOL_POSITIONS, FEE_CONFIGS } = await import("clanker-sdk");
|
|
103
|
+
const agentAccount = privateKeyToAccount(agent.privateKey);
|
|
104
|
+
const publicClient = createPublicClient({
|
|
105
|
+
chain: base,
|
|
106
|
+
transport: http(BASE_RPC),
|
|
107
|
+
});
|
|
108
|
+
const walletClient = createWalletClient({
|
|
109
|
+
account: agentAccount,
|
|
110
|
+
chain: base,
|
|
111
|
+
transport: http(BASE_RPC),
|
|
112
|
+
});
|
|
113
|
+
const clanker = new Clanker({
|
|
114
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
115
|
+
wallet: walletClient,
|
|
116
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
117
|
+
publicClient: publicClient,
|
|
118
|
+
});
|
|
119
|
+
const socialUrls = [
|
|
120
|
+
{ platform: "x", url: `https://x.com/${OTONIX_TWITTER}` },
|
|
121
|
+
];
|
|
122
|
+
if (twitterHandle) {
|
|
123
|
+
socialUrls.push({ platform: "x", url: `https://x.com/${twitterHandle}` });
|
|
124
|
+
}
|
|
125
|
+
const tokenConfig = {
|
|
126
|
+
name: opts.name,
|
|
127
|
+
symbol: opts.ticker.toUpperCase(),
|
|
128
|
+
tokenAdmin: cfg.wallet.address,
|
|
129
|
+
image: opts.image,
|
|
130
|
+
metadata: {
|
|
131
|
+
description: opts.description,
|
|
132
|
+
socialMediaUrls: socialUrls,
|
|
133
|
+
auditUrls: [],
|
|
134
|
+
},
|
|
135
|
+
context: {
|
|
136
|
+
interface: "Otonix",
|
|
137
|
+
platform: "twitter",
|
|
138
|
+
messageId: OTONIX_TWITTER,
|
|
139
|
+
id: OTONIX_TWITTER,
|
|
140
|
+
},
|
|
141
|
+
pool: {
|
|
142
|
+
pairedToken: WETH_BASE,
|
|
143
|
+
positions: POOL_POSITIONS.Standard,
|
|
144
|
+
},
|
|
145
|
+
fees: FEE_CONFIGS.StaticBasic,
|
|
146
|
+
...(devBuyEth > 0 ? { devBuy: { ethAmount: devBuyEth } } : {}),
|
|
147
|
+
rewards: {
|
|
148
|
+
recipients: [
|
|
149
|
+
{
|
|
150
|
+
recipient: cfg.wallet.address,
|
|
151
|
+
admin: cfg.wallet.address,
|
|
152
|
+
bps: 8000,
|
|
153
|
+
token: "Paired",
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
recipient: OTONIX_TREASURY,
|
|
157
|
+
admin: OTONIX_TREASURY,
|
|
158
|
+
bps: 2000,
|
|
159
|
+
token: "Both",
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
const result = await clanker.deploy(tokenConfig);
|
|
165
|
+
if ("error" in result && result.error) {
|
|
166
|
+
deploySpinner.stop();
|
|
167
|
+
failure("Deploy failed: " + String(result.error.message ?? result.error));
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
const txHash = result.txHash;
|
|
171
|
+
deploySpinner.text = "Transaction sent — waiting for confirmation (~30s)...";
|
|
172
|
+
const waitResult = await result.waitForTransaction();
|
|
173
|
+
const tokenAddress = waitResult.address;
|
|
174
|
+
deploySpinner.stop();
|
|
175
|
+
br();
|
|
176
|
+
console.log(chalk.bold.hex("#4d6fff")("◈ Token deployed — Verified by Otonix ✓"));
|
|
177
|
+
console.log(chalk.dim("─".repeat(44)));
|
|
178
|
+
br();
|
|
179
|
+
row("Token name", opts.name);
|
|
180
|
+
row("Ticker", "$" + opts.ticker.toUpperCase());
|
|
181
|
+
row("Contract", tokenAddress ?? "—");
|
|
182
|
+
row("Tx hash", txHash.slice(0, 20) + "...");
|
|
183
|
+
row("Verified by", "✓ Otonix (@" + OTONIX_TWITTER + ")");
|
|
184
|
+
br();
|
|
185
|
+
row("Basescan", `https://basescan.org/token/${tokenAddress ?? ""}`);
|
|
186
|
+
row("DexScreener", `https://dexscreener.com/base/${tokenAddress ?? ""}`);
|
|
187
|
+
row("Clanker", `https://www.clanker.world/token/${tokenAddress ?? ""}`);
|
|
188
|
+
row("Otonix", `https://otonix.tech/launch`);
|
|
189
|
+
br();
|
|
190
|
+
}
|
|
191
|
+
catch (e) {
|
|
192
|
+
deploySpinner.stop();
|
|
193
|
+
if (e instanceof Error) {
|
|
194
|
+
failure("Deploy failed: " + e.message.slice(0, 300));
|
|
195
|
+
if (e.message.includes("insufficient funds")) {
|
|
196
|
+
br();
|
|
197
|
+
info("Agent ETH too low for gas. Send more ETH to:");
|
|
198
|
+
info(" " + agent.address);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
failure("Unexpected error: " + String(e));
|
|
203
|
+
}
|
|
204
|
+
process.exit(1);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { password, confirm } from "@inquirer/prompts";
|
|
2
|
+
import ora from "ora";
|
|
3
|
+
import { loadConfig, saveConfig } from "../lib/config.js";
|
|
4
|
+
import { getEthBalance, getOtxBalance, formatOtx, generateWallet, addressFromKey, OTX_REQUIRED, } from "../lib/chain.js";
|
|
5
|
+
import { header, row, success, failure, info, br, warn } from "../lib/display.js";
|
|
6
|
+
import chalk from "chalk";
|
|
7
|
+
export function walletCommand(program) {
|
|
8
|
+
const wallet = program.command("wallet").description("Manage your Otonix creator wallet");
|
|
9
|
+
wallet
|
|
10
|
+
.command("generate")
|
|
11
|
+
.description("Generate a new Base wallet (creator wallet for token launches)")
|
|
12
|
+
.action(async () => {
|
|
13
|
+
header("Generate Creator Wallet");
|
|
14
|
+
const cfg = loadConfig();
|
|
15
|
+
if (cfg.wallet) {
|
|
16
|
+
const overwrite = await confirm({
|
|
17
|
+
message: `Wallet ${chalk.dim(cfg.wallet.address)} already exists. Replace it?`,
|
|
18
|
+
default: false,
|
|
19
|
+
});
|
|
20
|
+
if (!overwrite) {
|
|
21
|
+
info("Cancelled. Existing wallet kept.");
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const spinner = ora("Generating new Base wallet...").start();
|
|
26
|
+
await new Promise(r => setTimeout(r, 500));
|
|
27
|
+
const { address, privateKey } = generateWallet();
|
|
28
|
+
spinner.stop();
|
|
29
|
+
cfg.wallet = { address, privateKey };
|
|
30
|
+
saveConfig(cfg);
|
|
31
|
+
success("Creator wallet generated!");
|
|
32
|
+
br();
|
|
33
|
+
row("Address", address);
|
|
34
|
+
row("Network", "Base Mainnet");
|
|
35
|
+
row("Stored at", "~/.otonix/config.json");
|
|
36
|
+
br();
|
|
37
|
+
console.log(chalk.dim("Private key is stored locally. Never share it."));
|
|
38
|
+
console.log(chalk.dim("To view your private key: ") + chalk.white("otonix wallet export"));
|
|
39
|
+
br();
|
|
40
|
+
console.log(chalk.dim("Fund this address with:"));
|
|
41
|
+
console.log(" " + chalk.yellow("≥200 $OTX") + chalk.dim(" — to activate agents"));
|
|
42
|
+
console.log(" " + chalk.yellow("ETH") + chalk.dim(" — for gas fees on Base"));
|
|
43
|
+
br();
|
|
44
|
+
});
|
|
45
|
+
wallet
|
|
46
|
+
.command("import")
|
|
47
|
+
.description("Import an existing wallet using a private key")
|
|
48
|
+
.action(async () => {
|
|
49
|
+
header("Import Wallet");
|
|
50
|
+
info("Your private key is stored locally at ~/.otonix/config.json");
|
|
51
|
+
info("Never share it. Otonix never transmits it.");
|
|
52
|
+
br();
|
|
53
|
+
const cfg = loadConfig();
|
|
54
|
+
if (cfg.wallet) {
|
|
55
|
+
const overwrite = await confirm({
|
|
56
|
+
message: `Wallet ${chalk.dim(cfg.wallet.address)} already connected. Replace it?`,
|
|
57
|
+
default: false,
|
|
58
|
+
});
|
|
59
|
+
if (!overwrite) {
|
|
60
|
+
info("Cancelled.");
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const pk = await password({
|
|
65
|
+
message: "Enter your private key (0x...):",
|
|
66
|
+
mask: "•",
|
|
67
|
+
});
|
|
68
|
+
if (!pk.startsWith("0x") || pk.length !== 66) {
|
|
69
|
+
failure("Invalid private key format. Must be 0x followed by 64 hex chars.");
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
const spinner = ora("Verifying key...").start();
|
|
73
|
+
try {
|
|
74
|
+
const address = addressFromKey(pk);
|
|
75
|
+
cfg.wallet = { address, privateKey: pk };
|
|
76
|
+
saveConfig(cfg);
|
|
77
|
+
spinner.stop();
|
|
78
|
+
success("Wallet imported!");
|
|
79
|
+
br();
|
|
80
|
+
row("Address", address);
|
|
81
|
+
row("Config", "~/.otonix/config.json");
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
spinner.stop();
|
|
85
|
+
failure("Invalid private key.");
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
wallet
|
|
90
|
+
.command("export")
|
|
91
|
+
.description("Show your private key (keep it safe!)")
|
|
92
|
+
.action(async () => {
|
|
93
|
+
const cfg = loadConfig();
|
|
94
|
+
if (!cfg.wallet) {
|
|
95
|
+
failure("No wallet. Run: otonix wallet generate");
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
const confirmed = await confirm({
|
|
99
|
+
message: chalk.red("⚠ This will display your private key. Continue?"),
|
|
100
|
+
default: false,
|
|
101
|
+
});
|
|
102
|
+
if (!confirmed) {
|
|
103
|
+
info("Cancelled.");
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
header("Wallet Export");
|
|
107
|
+
br();
|
|
108
|
+
row("Address", cfg.wallet.address);
|
|
109
|
+
row("Private key", cfg.wallet.privateKey);
|
|
110
|
+
br();
|
|
111
|
+
console.log(chalk.red("Never share this key. Anyone with it controls your wallet."));
|
|
112
|
+
br();
|
|
113
|
+
});
|
|
114
|
+
wallet
|
|
115
|
+
.command("balance")
|
|
116
|
+
.description("Show ETH and $OTX balance of your wallet")
|
|
117
|
+
.action(async () => {
|
|
118
|
+
header("Wallet Balance");
|
|
119
|
+
const cfg = loadConfig();
|
|
120
|
+
if (!cfg.wallet) {
|
|
121
|
+
failure("No wallet. Run: otonix wallet generate");
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
const address = cfg.wallet.address;
|
|
125
|
+
const spinner = ora("Fetching balances from Base...").start();
|
|
126
|
+
try {
|
|
127
|
+
const [eth, otx] = await Promise.all([
|
|
128
|
+
getEthBalance(address),
|
|
129
|
+
getOtxBalance(address),
|
|
130
|
+
]);
|
|
131
|
+
spinner.stop();
|
|
132
|
+
br();
|
|
133
|
+
row("Address", address);
|
|
134
|
+
row("Network", "Base Mainnet");
|
|
135
|
+
row("ETH balance", parseFloat(eth).toFixed(6) + " ETH");
|
|
136
|
+
row("$OTX balance", formatOtx(otx) + " OTX");
|
|
137
|
+
br();
|
|
138
|
+
if (otx >= OTX_REQUIRED) {
|
|
139
|
+
console.log(chalk.green("✓ ") + chalk.dim("Eligible to create agents (≥200 $OTX)"));
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
const need = formatOtx(OTX_REQUIRED - otx);
|
|
143
|
+
console.log(warn("⚠ ") + chalk.dim(`Need ${need} more $OTX to activate agents`));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
spinner.stop();
|
|
148
|
+
failure("Failed to fetch balances. Check your internet connection.");
|
|
149
|
+
process.exit(1);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
wallet
|
|
153
|
+
.command("address")
|
|
154
|
+
.description("Show your connected wallet address")
|
|
155
|
+
.action(() => {
|
|
156
|
+
const cfg = loadConfig();
|
|
157
|
+
if (!cfg.wallet) {
|
|
158
|
+
failure("No wallet. Run: otonix wallet generate");
|
|
159
|
+
process.exit(1);
|
|
160
|
+
}
|
|
161
|
+
header("Wallet Address");
|
|
162
|
+
br();
|
|
163
|
+
row("Address", cfg.wallet.address);
|
|
164
|
+
row("Network", "Base Mainnet");
|
|
165
|
+
});
|
|
166
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { printBanner } from "./lib/display.js";
|
|
5
|
+
import { walletCommand } from "./commands/wallet.js";
|
|
6
|
+
import { agentCommand } from "./commands/agent.js";
|
|
7
|
+
import { launchCommand } from "./commands/launch.js";
|
|
8
|
+
const args = process.argv.slice(2);
|
|
9
|
+
const showBanner = args.length === 0 ||
|
|
10
|
+
args.includes("--help") ||
|
|
11
|
+
args.includes("-h");
|
|
12
|
+
if (showBanner)
|
|
13
|
+
printBanner();
|
|
14
|
+
const program = new Command();
|
|
15
|
+
program
|
|
16
|
+
.name("otonix")
|
|
17
|
+
.description(chalk.bold.hex("#4d6fff")("OTONIX CLI") + chalk.dim(" — Web4 Autonomous Agent Infrastructure"))
|
|
18
|
+
.version("2.1.1", "-v, --version")
|
|
19
|
+
.configureOutput({
|
|
20
|
+
writeOut: str => process.stdout.write(str),
|
|
21
|
+
writeErr: str => process.stderr.write(str),
|
|
22
|
+
});
|
|
23
|
+
walletCommand(program);
|
|
24
|
+
agentCommand(program);
|
|
25
|
+
launchCommand(program);
|
|
26
|
+
program
|
|
27
|
+
.command("config")
|
|
28
|
+
.description("Show current config file location and settings")
|
|
29
|
+
.action(async () => {
|
|
30
|
+
const { loadConfig, configPath } = await import("./lib/config.js");
|
|
31
|
+
const cfg = loadConfig();
|
|
32
|
+
console.log("\n" + chalk.bold.hex("#4d6fff")("◈ OTONIX") + " " + chalk.dim("Config") + "\n" + chalk.dim("─".repeat(44)));
|
|
33
|
+
console.log(chalk.dim("File: ") + chalk.white(configPath()));
|
|
34
|
+
console.log(chalk.dim("Wallet: ") + chalk.white(cfg.wallet?.address ?? "(none)"));
|
|
35
|
+
console.log(chalk.dim("Agents: ") + chalk.white(Object.keys(cfg.agents).join(", ") || "(none)"));
|
|
36
|
+
console.log(chalk.dim("API base: ") + chalk.white(cfg.apiBase));
|
|
37
|
+
console.log(chalk.dim("Deployer: ") + chalk.white(cfg.deployerAddress));
|
|
38
|
+
console.log(chalk.dim("Treasury: ") + chalk.white(cfg.treasuryAddress));
|
|
39
|
+
console.log();
|
|
40
|
+
});
|
|
41
|
+
program.parse(process.argv);
|
|
42
|
+
if (!args.length) {
|
|
43
|
+
program.outputHelp();
|
|
44
|
+
}
|