@otonix/cli 2.1.7 → 2.1.9

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.
@@ -7,7 +7,7 @@ import { header, row, success, failure, info, br, warn, mono } from "../lib/disp
7
7
  export function agentCommand(program) {
8
8
  program
9
9
  .command("agent:create")
10
- .description("Create a new autonomous agent with an isolated Base wallet")
10
+ .description("Create a new autonomous agent one wallet for everything")
11
11
  .requiredOption("--name <name>", "Agent name (alphanumeric, no spaces)")
12
12
  .action(async (opts) => {
13
13
  header("Create Agent");
@@ -17,19 +17,6 @@ export function agentCommand(program) {
17
17
  process.exit(1);
18
18
  }
19
19
  const cfg = loadConfig();
20
- if (!cfg.wallet) {
21
- const autoSpinner = ora("No creator wallet found — generating one automatically...").start();
22
- await new Promise(r => setTimeout(r, 400));
23
- const creator = generateWallet();
24
- autoSpinner.stop();
25
- cfg.wallet = { address: creator.address, privateKey: creator.privateKey };
26
- saveConfig(cfg);
27
- success("Creator wallet generated!");
28
- br();
29
- console.log(chalk.dim(" Creator wallet address: ") + chalk.bold.white(creator.address));
30
- console.log(chalk.dim(" Fund this address with ≥ 200 $OTX + ≥ 0.005 ETH (Base)"));
31
- br();
32
- }
33
20
  if (cfg.agents[name]) {
34
21
  const overwrite = await confirm({
35
22
  message: `Agent "${name}" already exists. Replace it?`,
@@ -40,7 +27,7 @@ export function agentCommand(program) {
40
27
  return;
41
28
  }
42
29
  }
43
- const spinner = ora("Generating isolated agent wallet on Base...").start();
30
+ const spinner = ora("Generating agent wallet on Base...").start();
44
31
  await new Promise(r => setTimeout(r, 600));
45
32
  const agent = generateWallet();
46
33
  spinner.stop();
@@ -54,28 +41,25 @@ export function agentCommand(program) {
54
41
  success(`Agent "${name}" created!`);
55
42
  br();
56
43
  row("Agent name", name);
57
- row("Agent address", agent.address);
44
+ row("Wallet address", agent.address);
58
45
  row("Created at", new Date().toLocaleString());
59
46
  row("Status", chalk.yellow("⊘ Not registered"));
60
47
  br();
61
48
  console.log(chalk.dim("─".repeat(44)));
62
- console.log(chalk.bold(" Next steps:"));
49
+ console.log(chalk.bold(" Fund this wallet (Base network):"));
63
50
  br();
64
- console.log(" " + chalk.bold.white("1.") + chalk.dim(" Make sure your creator wallet has:"));
65
- console.log(" " + chalk.yellow("≥ 200 $OTX") + chalk.dim(" (registration fee auto-sent by CLI)"));
66
- console.log(" " + chalk.yellow("≥ 0.005 ETH") + chalk.dim(" (gas for the $OTX transfer)"));
67
- console.log(" " + chalk.dim(" Check: ") + mono("otonix wallet balance"));
51
+ console.log(" " + chalk.yellow("≥ 200 $OTX") + chalk.dim(" registration fee (auto-sent by CLI)"));
52
+ console.log(" " + chalk.yellow("≥ 0.005 ETH") + chalk.dim(" gas for registration + deployment"));
68
53
  br();
69
- console.log(" " + chalk.bold.white("2.") + chalk.dim(" Fund the agent wallet with ETH for deploy gas:"));
70
- console.log(" " + chalk.yellow("≥ 0.003 ETH") + chalk.dim(" → ") + chalk.white(agent.address));
54
+ console.log(" Send to: " + chalk.bold.white(agent.address));
71
55
  br();
72
- console.log(" " + chalk.bold.white("3.") + chalk.dim(" Register this agent (sends 200 $OTX automatically):"));
73
- console.log(" " + mono(`otonix agent:register --name ${name}`));
56
+ console.log(chalk.dim(" After funded, register:"));
57
+ console.log(" " + mono(`otonix agent:register --name ${name}`));
74
58
  console.log(chalk.dim("─".repeat(44)));
75
59
  });
76
60
  program
77
61
  .command("agent:register")
78
- .description("Register an agent — auto-sends 200 $OTX to Otonix treasury and activates it")
62
+ .description("Register an agent — auto-sends 200 $OTX from agent wallet to Otonix treasury")
79
63
  .requiredOption("--name <name>", "Agent name to register")
80
64
  .action(async (opts) => {
81
65
  header("Agent Registration");
@@ -93,17 +77,13 @@ export function agentCommand(program) {
93
77
  row("Registered at", agent.registeredAt ? new Date(agent.registeredAt).toLocaleString() : "—");
94
78
  return;
95
79
  }
96
- if (!cfg.wallet) {
97
- failure("No creator wallet found. Run: otonix wallet generate");
98
- process.exit(1);
99
- }
100
- const balSpinner = ora("Checking creator wallet balance...").start();
80
+ const balSpinner = ora("Checking agent wallet balance...").start();
101
81
  let otxBal;
102
82
  let ethBal;
103
83
  try {
104
84
  [otxBal, ethBal] = await Promise.all([
105
- getOtxBalance(cfg.wallet.address),
106
- getEthBalance(cfg.wallet.address),
85
+ getOtxBalance(agent.address),
86
+ getEthBalance(agent.address),
107
87
  ]);
108
88
  }
109
89
  catch {
@@ -113,7 +93,7 @@ export function agentCommand(program) {
113
93
  }
114
94
  balSpinner.stop();
115
95
  br();
116
- row("Creator wallet", cfg.wallet.address);
96
+ row("Agent wallet", agent.address);
117
97
  row("$OTX balance", formatOtx(otxBal) + " OTX");
118
98
  row("ETH balance", parseFloat(ethBal).toFixed(6) + " ETH (for gas)");
119
99
  row("Registration fee", "200 $OTX → Otonix treasury");
@@ -121,16 +101,17 @@ export function agentCommand(program) {
121
101
  br();
122
102
  if (otxBal < OTX_REQUIRED) {
123
103
  failure(`Insufficient $OTX. Need 200.000, have ${formatOtx(otxBal)}.`);
124
- info("Buy $OTX at: https://dexscreener.com/base/0xF7E2a6226Ffe0693DD85406AC3A8917cbea5DC40");
104
+ info("Fund your agent wallet: " + agent.address);
105
+ info("Buy $OTX: https://dexscreener.com/base/0xF7E2a6226Ffe0693DD85406AC3A8917cbea5DC40");
125
106
  process.exit(1);
126
107
  }
127
108
  if (parseFloat(ethBal) < 0.0001) {
128
- failure("Insufficient ETH for gas. Send a small amount of ETH (Base) to your creator wallet.");
129
- info("Creator wallet: " + cfg.wallet.address);
109
+ failure("Insufficient ETH for gas. Send ETH (Base) to your agent wallet.");
110
+ info("Agent wallet: " + agent.address);
130
111
  process.exit(1);
131
112
  }
132
113
  const confirmed = await confirm({
133
- message: `Send 200 $OTX from your creator wallet to Otonix treasury to activate "${opts.name}"?`,
114
+ message: `Send 200 $OTX from agent wallet to Otonix treasury to activate "${opts.name}"?`,
134
115
  default: true,
135
116
  });
136
117
  if (!confirmed) {
@@ -140,7 +121,7 @@ export function agentCommand(program) {
140
121
  const sendSpinner = ora("Sending 200 $OTX to Otonix treasury...").start();
141
122
  let txHash;
142
123
  try {
143
- txHash = await sendOtx(cfg.wallet.privateKey, OTONIX_TREASURY, OTX_REQUIRED);
124
+ txHash = await sendOtx(agent.privateKey, OTONIX_TREASURY, OTX_REQUIRED);
144
125
  }
145
126
  catch (err) {
146
127
  sendSpinner.stop();
@@ -173,10 +154,7 @@ export function agentCommand(program) {
173
154
  row("Tx hash", txHash);
174
155
  row("Basescan", "https://basescan.org/tx/" + txHash);
175
156
  br();
176
- console.log(chalk.dim("You can now deploy tokens. Fund the agent with ETH first:"));
177
- console.log(" " + chalk.dim("Agent address:") + " " + chalk.white(agent.address));
178
- br();
179
- console.log(chalk.dim("Then deploy:"));
157
+ console.log(chalk.dim("You can now deploy tokens:"));
180
158
  console.log(" " + mono(`otonix launch token --agent ${opts.name} --name "MyToken" --ticker "MTK" --image "https://..." --description "..."`));
181
159
  }
182
160
  catch (err) {
@@ -208,7 +186,7 @@ export function agentCommand(program) {
208
186
  spinner.stop();
209
187
  br();
210
188
  row("Agent name", name);
211
- row("Address", agent.address);
189
+ row("Wallet address", agent.address);
212
190
  row("Created at", new Date(agent.createdAt).toLocaleString());
213
191
  row("Status", agent.registered
214
192
  ? chalk.green("✓ Registered & Active")
@@ -219,14 +197,22 @@ export function agentCommand(program) {
219
197
  row("ETH balance", parseFloat(eth).toFixed(6) + " ETH");
220
198
  row("$OTX balance", formatOtx(otx) + " OTX");
221
199
  br();
222
- const ethNum = parseFloat(eth);
223
200
  if (!agent.registered) {
224
- console.log(warn("⊘ ") + chalk.dim("Not registered run this to activate:"));
225
- console.log(" " + chalk.cyan(`otonix agent:register --name ${name}`));
226
- console.log(" " + chalk.dim("(auto-sends 200 $OTX from your creator wallet)"));
201
+ if (otx >= OTX_REQUIRED && parseFloat(eth) >= 0.0001) {
202
+ console.log(chalk.green("") + chalk.dim("Wallet funded ready to register:"));
203
+ console.log(" " + chalk.cyan(`otonix agent:register --name ${name}`));
204
+ }
205
+ else {
206
+ console.log(warn("⚠ ") + chalk.dim("Fund this wallet before registering:"));
207
+ if (otx < OTX_REQUIRED)
208
+ console.log(" " + chalk.yellow(`Need ≥ 200 $OTX (have ${formatOtx(otx)})`));
209
+ if (parseFloat(eth) < 0.0001)
210
+ console.log(" " + chalk.yellow("Need ≥ 0.005 ETH for gas"));
211
+ console.log(" " + chalk.dim("Address: ") + chalk.white(agent.address));
212
+ }
227
213
  }
228
- else if (ethNum < 0.0005) {
229
- console.log(warn("⚠ ") + chalk.dim("Low ETH — fund this address with ≥0.001 ETH for gas:"));
214
+ else if (parseFloat(eth) < 0.0005) {
215
+ console.log(warn("⚠ ") + chalk.dim("Low ETH — fund with ≥ 0.003 ETH for token deployment:"));
230
216
  console.log(" " + chalk.white(agent.address));
231
217
  }
232
218
  else {
@@ -257,11 +243,14 @@ export function agentCommand(program) {
257
243
  const results = await Promise.all(names.map(async (n) => {
258
244
  const a = cfg.agents[n];
259
245
  try {
260
- const eth = await getEthBalance(a.address);
261
- return { name: n, address: a.address, eth: parseFloat(eth).toFixed(5), registered: a.registered };
246
+ const [eth, otx] = await Promise.all([
247
+ getEthBalance(a.address),
248
+ getOtxBalance(a.address),
249
+ ]);
250
+ return { name: n, address: a.address, eth: parseFloat(eth).toFixed(5), otx: formatOtx(otx), registered: a.registered };
262
251
  }
263
252
  catch {
264
- return { name: n, address: a.address, eth: "—", registered: a.registered };
253
+ return { name: n, address: a.address, eth: "—", otx: "—", registered: a.registered };
265
254
  }
266
255
  }));
267
256
  spinner.stop();
@@ -270,8 +259,8 @@ export function agentCommand(program) {
270
259
  console.log(status + " " +
271
260
  chalk.bold.white(r.name.padEnd(16)) +
272
261
  chalk.dim(r.address.slice(0, 10) + "...") +
273
- " " +
274
- chalk.yellow(r.eth + " ETH"));
262
+ " " + chalk.yellow(r.eth + " ETH") +
263
+ " " + chalk.dim(r.otx + " OTX"));
275
264
  }
276
265
  br();
277
266
  info(`${names.length} agent(s) total`);
@@ -313,8 +302,7 @@ export function agentCommand(program) {
313
302
  br();
314
303
  console.log(chalk.bold.red("⚠ SECURITY WARNING"));
315
304
  console.log(chalk.dim(" Your private key gives full access to this agent wallet."));
316
- console.log(chalk.dim(" Never share it. Never paste it into websites or chats."));
317
- console.log(chalk.dim(" Store it offline or in a hardware wallet."));
305
+ console.log(chalk.dim(" Never share it. Store it offline or in a hardware wallet."));
318
306
  br();
319
307
  const ok = await confirm({
320
308
  message: `Show private key for agent "${name}" (${agent.address})?`,
@@ -326,12 +314,12 @@ export function agentCommand(program) {
326
314
  }
327
315
  br();
328
316
  row("Agent name", name);
329
- row("Agent address", agent.address);
317
+ row("Wallet address", agent.address);
330
318
  br();
331
319
  console.log(chalk.bold("Private key:"));
332
320
  console.log(chalk.bold.yellow(agent.privateKey));
333
321
  br();
334
322
  console.log(chalk.dim("Import into MetaMask: Settings → Import Account → paste key above."));
335
- console.log(chalk.dim("LP fee rewards (80% WETH) flow to your creator wallet, not this agent wallet."));
323
+ console.log(chalk.dim("80% LP fee rewards (WETH) are sent to this wallet address."));
336
324
  });
337
325
  }
@@ -21,10 +21,6 @@ export function launchCommand(program) {
21
21
  .action(async (opts) => {
22
22
  header("Launch Token");
23
23
  const cfg = loadConfig();
24
- if (!cfg.wallet) {
25
- failure("No wallet. Run: otonix wallet generate");
26
- process.exit(1);
27
- }
28
24
  const agent = cfg.agents[opts.agent];
29
25
  if (!agent) {
30
26
  failure(`Agent "${opts.agent}" not found. Run: otonix agent:list`);
@@ -80,7 +76,7 @@ export function launchCommand(program) {
80
76
  row("Paired token", "WETH");
81
77
  if (devBuyEth > 0)
82
78
  row("Dev buy", devBuyEth + " ETH");
83
- row("Reward 80%", cfg.wallet.address + " (WETH → creator wallet)");
79
+ row("Reward 80%", agent.address + " (WETH → agent wallet)");
84
80
  row("Reward 20%", OTONIX_TREASURY + " ($OTX burn)");
85
81
  row("Verified by", "✓ Otonix (@" + OTONIX_TWITTER + ")");
86
82
  br();
@@ -124,7 +120,7 @@ export function launchCommand(program) {
124
120
  const tokenConfig = {
125
121
  name: opts.name,
126
122
  symbol: opts.ticker.toUpperCase(),
127
- tokenAdmin: cfg.wallet.address,
123
+ tokenAdmin: agent.address,
128
124
  image: opts.image,
129
125
  metadata: {
130
126
  description: opts.description,
@@ -146,8 +142,8 @@ export function launchCommand(program) {
146
142
  rewards: {
147
143
  recipients: [
148
144
  {
149
- recipient: cfg.wallet.address,
150
- admin: cfg.wallet.address,
145
+ recipient: agent.address,
146
+ admin: agent.address,
151
147
  bps: 8000,
152
148
  token: "Paired",
153
149
  },
@@ -183,7 +179,7 @@ export function launchCommand(program) {
183
179
  txHash,
184
180
  agentName: opts.agent,
185
181
  agentAddress: agent.address,
186
- creatorAddress: cfg.wallet.address,
182
+ creatorAddress: agent.address,
187
183
  imgUrl: opts.image ?? null,
188
184
  description: opts.description ?? null,
189
185
  }),
@@ -1,166 +1,66 @@
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";
1
+ import { header, br } from "../lib/display.js";
6
2
  import chalk from "chalk";
7
3
  export function walletCommand(program) {
8
- const wallet = program.command("wallet").description("Manage your Otonix creator wallet");
4
+ const wallet = program.command("wallet").description("Wallet info each agent has its own wallet");
9
5
  wallet
10
6
  .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");
7
+ .description("Wallets are created per-agent. Use: otonix agent:create --name <name>")
8
+ .action(() => {
9
+ header("Wallet Generate");
36
10
  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"));
11
+ console.log(chalk.yellow("ℹ Each agent has its own wallet no separate creator wallet needed."));
39
12
  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"));
13
+ console.log(chalk.dim("Create an agent (generates wallet automatically):"));
14
+ console.log(' otonix agent:create --name "MyAgent"');
43
15
  br();
16
+ console.log(chalk.dim("View agent wallet:"));
17
+ console.log(" otonix agent:info MyAgent");
44
18
  });
45
19
  wallet
46
20
  .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.");
21
+ .description("Import a private key as an agent wallet")
22
+ .action(() => {
23
+ header("Wallet Import");
52
24
  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
- }
25
+ console.log(chalk.yellow("ℹ To import an existing private key as an agent wallet, use:"));
26
+ br();
27
+ console.log(chalk.dim("(This feature is coming soon — for now, create a new agent wallet)"));
28
+ console.log(' otonix agent:create --name "MyAgent"');
88
29
  });
89
30
  wallet
90
31
  .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
- }
32
+ .description("Export agent private key use: otonix agent:export <name>")
33
+ .action(() => {
106
34
  header("Wallet Export");
107
35
  br();
108
- row("Address", cfg.wallet.address);
109
- row("Private key", cfg.wallet.privateKey);
36
+ console.log(chalk.yellow("ℹ Private keys are stored per-agent. Export with:"));
110
37
  br();
111
- console.log(chalk.red("Never share this key. Anyone with it controls your wallet."));
38
+ console.log(" otonix agent:export <agent-name>");
112
39
  br();
40
+ console.log(chalk.dim("List your agents:"));
41
+ console.log(" otonix agent:list");
113
42
  });
114
43
  wallet
115
44
  .command("balance")
116
- .description("Show ETH and $OTX balance of your wallet")
117
- .action(async () => {
45
+ .description("Check balance use: otonix agent:info <name>")
46
+ .action(() => {
118
47
  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
- }
48
+ br();
49
+ console.log(chalk.yellow("ℹ Balances are tracked per-agent. Check with:"));
50
+ br();
51
+ console.log(" otonix agent:info <agent-name>");
52
+ br();
53
+ console.log(chalk.dim("List your agents:"));
54
+ console.log(" otonix agent:list");
151
55
  });
152
56
  wallet
153
57
  .command("address")
154
- .description("Show your connected wallet address")
58
+ .description("Show agent address use: otonix agent:info <name>")
155
59
  .action(() => {
156
- const cfg = loadConfig();
157
- if (!cfg.wallet) {
158
- failure("No wallet. Run: otonix wallet generate");
159
- process.exit(1);
160
- }
161
60
  header("Wallet Address");
162
61
  br();
163
- row("Address", cfg.wallet.address);
164
- row("Network", "Base Mainnet");
62
+ console.log(chalk.yellow("ℹ Each agent has its own wallet address. View with:"));
63
+ br();
64
+ console.log(" otonix agent:info <agent-name>");
165
65
  });
166
66
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@otonix/cli",
3
- "version": "2.1.7",
3
+ "version": "2.1.9",
4
4
  "description": "Otonix CLI — deploy autonomous agent tokens on Base via Clanker v4",
5
5
  "type": "module",
6
6
  "bin": {