@otonix/cli 2.1.1 → 2.1.2

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.
@@ -1,13 +1,9 @@
1
- import { confirm, input } from "@inquirer/prompts";
1
+ import { confirm } from "@inquirer/prompts";
2
2
  import ora from "ora";
3
3
  import chalk from "chalk";
4
4
  import { loadConfig, saveConfig, OTONIX_TREASURY } from "../lib/config.js";
5
- import { generateWallet, getEthBalance, getOtxBalance, formatOtx, OTX_REQUIRED, publicClient, OTX_ADDRESS, } from "../lib/chain.js";
5
+ import { generateWallet, getEthBalance, getOtxBalance, formatOtx, sendOtx, OTX_REQUIRED, publicClient, } from "../lib/chain.js";
6
6
  import { header, row, success, failure, info, br, warn, mono } from "../lib/display.js";
7
- import { parseAbi, decodeEventLog } from "viem";
8
- const transferAbi = parseAbi([
9
- "event Transfer(address indexed from, address indexed to, uint256 value)",
10
- ]);
11
7
  export function agentCommand(program) {
12
8
  program
13
9
  .command("agent:create")
@@ -56,14 +52,13 @@ export function agentCommand(program) {
56
52
  console.log(chalk.dim("Next — register this agent by sending 200 $OTX to:"));
57
53
  console.log(" " + chalk.white(OTONIX_TREASURY));
58
54
  br();
59
- console.log(chalk.dim("Then submit the tx hash to activate:"));
60
- console.log(" " + mono(`otonix agent:register --name ${name} --tx <txhash>`));
55
+ console.log(chalk.dim("Then register (auto-sends 200 $OTX):"));
56
+ console.log(" " + mono(`otonix agent:register --name ${name}`));
61
57
  });
62
58
  program
63
59
  .command("agent:register")
64
- .description("Activate an agent by submitting proof of 200 $OTX payment")
60
+ .description("Register an agent auto-sends 200 $OTX to Otonix treasury and activates it")
65
61
  .requiredOption("--name <name>", "Agent name to register")
66
- .option("--tx <hash>", "Transaction hash of your 200 $OTX transfer to Otonix treasury")
67
62
  .action(async (opts) => {
68
63
  header("Agent Registration");
69
64
  const cfg = loadConfig();
@@ -74,6 +69,8 @@ export function agentCommand(program) {
74
69
  }
75
70
  if (agent.registered) {
76
71
  success(`Agent "${opts.name}" is already registered!`);
72
+ br();
73
+ row("Status", chalk.green("✓ Registered & Active"));
77
74
  row("Tx hash", agent.registerTxHash ?? "—");
78
75
  row("Registered at", agent.registeredAt ? new Date(agent.registeredAt).toLocaleString() : "—");
79
76
  return;
@@ -82,67 +79,67 @@ export function agentCommand(program) {
82
79
  failure("No creator wallet found. Run: otonix wallet generate");
83
80
  process.exit(1);
84
81
  }
85
- let txHash = opts.tx;
86
- if (!txHash) {
87
- br();
88
- console.log(chalk.dim("Send 200 $OTX from your creator wallet to the Otonix treasury:"));
89
- console.log(" " + chalk.white(OTONIX_TREASURY));
90
- br();
91
- txHash = await input({ message: "Paste your transaction hash (0x...):" });
82
+ const balSpinner = ora("Checking creator wallet balance...").start();
83
+ let otxBal;
84
+ let ethBal;
85
+ try {
86
+ [otxBal, ethBal] = await Promise.all([
87
+ getOtxBalance(cfg.wallet.address),
88
+ getEthBalance(cfg.wallet.address),
89
+ ]);
90
+ }
91
+ catch {
92
+ balSpinner.stop();
93
+ failure("Failed to fetch balances. Check your connection.");
94
+ process.exit(1);
95
+ }
96
+ balSpinner.stop();
97
+ br();
98
+ row("Creator wallet", cfg.wallet.address);
99
+ row("$OTX balance", formatOtx(otxBal) + " OTX");
100
+ row("ETH balance", parseFloat(ethBal).toFixed(6) + " ETH (for gas)");
101
+ row("Registration fee", "200 $OTX → Otonix treasury");
102
+ row("Treasury", OTONIX_TREASURY);
103
+ br();
104
+ if (otxBal < OTX_REQUIRED) {
105
+ failure(`Insufficient $OTX. Need 200.000, have ${formatOtx(otxBal)}.`);
106
+ info("Buy $OTX at: https://dexscreener.com/base/0xF7E2a6226Ffe0693DD85406AC3A8917cbea5DC40");
107
+ process.exit(1);
108
+ }
109
+ if (parseFloat(ethBal) < 0.0001) {
110
+ failure("Insufficient ETH for gas. Send a small amount of ETH (Base) to your creator wallet.");
111
+ info("Creator wallet: " + cfg.wallet.address);
112
+ process.exit(1);
113
+ }
114
+ const confirmed = await confirm({
115
+ message: `Send 200 $OTX from your creator wallet to Otonix treasury to activate "${opts.name}"?`,
116
+ default: true,
117
+ });
118
+ if (!confirmed) {
119
+ info("Cancelled.");
120
+ return;
121
+ }
122
+ const sendSpinner = ora("Sending 200 $OTX to Otonix treasury...").start();
123
+ let txHash;
124
+ try {
125
+ txHash = await sendOtx(cfg.wallet.privateKey, OTONIX_TREASURY, OTX_REQUIRED);
92
126
  }
93
- if (!txHash.startsWith("0x") || txHash.length !== 66) {
94
- failure("Invalid tx hash. Must be 0x followed by 64 hex characters.");
127
+ catch (err) {
128
+ sendSpinner.stop();
129
+ const msg = err instanceof Error ? err.message : String(err);
130
+ failure("Failed to send $OTX: " + msg.slice(0, 120));
95
131
  process.exit(1);
96
132
  }
97
- const spinner = ora("Verifying transaction on Base...").start();
133
+ sendSpinner.text = `Waiting for confirmation... (${txHash.slice(0, 18)}...)`;
98
134
  try {
99
- const receipt = await publicClient.getTransactionReceipt({
135
+ const receipt = await publicClient.waitForTransactionReceipt({
100
136
  hash: txHash,
137
+ timeout: 60_000,
101
138
  });
139
+ sendSpinner.stop();
102
140
  if (receipt.status !== "success") {
103
- spinner.fail("Transaction failed on-chain.");
104
- failure("The tx hash you provided is a failed transaction.");
105
- process.exit(1);
106
- }
107
- let verified = false;
108
- let transferredAmount = 0n;
109
- for (const log of receipt.logs) {
110
- if (log.address.toLowerCase() !== OTX_ADDRESS.toLowerCase())
111
- continue;
112
- try {
113
- const decoded = decodeEventLog({
114
- abi: transferAbi,
115
- data: log.data,
116
- topics: log.topics,
117
- });
118
- if (decoded.eventName === "Transfer" &&
119
- decoded.args.from.toLowerCase() === cfg.wallet.address.toLowerCase() &&
120
- decoded.args.to.toLowerCase() === OTONIX_TREASURY.toLowerCase()) {
121
- transferredAmount = decoded.args.value;
122
- if (transferredAmount >= OTX_REQUIRED) {
123
- verified = true;
124
- break;
125
- }
126
- }
127
- }
128
- catch {
129
- continue;
130
- }
131
- }
132
- spinner.stop();
133
- if (!verified) {
134
- br();
135
- failure("Verification failed.");
136
- if (transferredAmount > 0n) {
137
- console.log(chalk.dim(` Found transfer of ${formatOtx(transferredAmount)} $OTX — need 200.000 $OTX minimum.`));
138
- }
139
- else {
140
- console.log(chalk.dim(" No valid $OTX transfer found in this tx."));
141
- console.log(chalk.dim(" Make sure you sent from your creator wallet:"));
142
- console.log(" " + chalk.white(cfg.wallet.address));
143
- console.log(chalk.dim(" to Otonix treasury:"));
144
- console.log(" " + chalk.white(OTONIX_TREASURY));
145
- }
141
+ failure("Transaction failed on-chain.");
142
+ info("Tx: https://basescan.org/tx/" + txHash);
146
143
  process.exit(1);
147
144
  }
148
145
  cfg.agents[opts.name].registered = true;
@@ -154,22 +151,21 @@ export function agentCommand(program) {
154
151
  br();
155
152
  row("Agent name", opts.name);
156
153
  row("Status", chalk.green("✓ Registered & Active"));
157
- row("OTX sent", formatOtx(transferredAmount) + " OTX");
154
+ row("OTX sent", "200.000 OTX");
158
155
  row("Tx hash", txHash);
159
- row("Treasury", OTONIX_TREASURY);
156
+ row("Basescan", "https://basescan.org/tx/" + txHash);
157
+ br();
158
+ console.log(chalk.dim("You can now deploy tokens. Fund the agent with ETH first:"));
159
+ console.log(" " + chalk.dim("Agent address:") + " " + chalk.white(agent.address));
160
160
  br();
161
- console.log(chalk.dim("You can now deploy tokens with this agent:"));
161
+ console.log(chalk.dim("Then deploy:"));
162
162
  console.log(" " + mono(`otonix launch token --agent ${opts.name} --name "MyToken" --ticker "MTK" --image "https://..." --description "..."`));
163
163
  }
164
164
  catch (err) {
165
- spinner.stop();
165
+ sendSpinner.stop();
166
166
  const msg = err instanceof Error ? err.message : String(err);
167
- if (msg.includes("not found") || msg.includes("cannot find")) {
168
- failure("Transaction not found on Base. Wait a moment and try again.");
169
- }
170
- else {
171
- failure("Failed to verify tx: " + msg.slice(0, 100));
172
- }
167
+ failure("Tx sent but confirmation timed out: " + msg.slice(0, 100));
168
+ info("Check manually: https://basescan.org/tx/" + txHash);
173
169
  process.exit(1);
174
170
  }
175
171
  });
@@ -207,9 +203,9 @@ export function agentCommand(program) {
207
203
  br();
208
204
  const ethNum = parseFloat(eth);
209
205
  if (!agent.registered) {
210
- console.log(warn("⊘ ") + chalk.dim("Send 200 $OTX to treasury to register:"));
211
- console.log(" " + chalk.white(OTONIX_TREASURY));
212
- console.log(" " + chalk.dim(`Then: otonix agent:register --name ${name} --tx <txhash>`));
206
+ console.log(warn("⊘ ") + chalk.dim("Not registered run this to activate:"));
207
+ console.log(" " + chalk.cyan(`otonix agent:register --name ${name}`));
208
+ console.log(" " + chalk.dim("(auto-sends 200 $OTX from your creator wallet)"));
213
209
  }
214
210
  else if (ethNum < 0.0005) {
215
211
  console.log(warn("⚠ ") + chalk.dim("Low ETH — fund this address with ≥0.001 ETH for gas:"));
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ const program = new Command();
15
15
  program
16
16
  .name("otonix")
17
17
  .description(chalk.bold.hex("#4d6fff")("OTONIX CLI") + chalk.dim(" — Web4 Autonomous Agent Infrastructure"))
18
- .version("2.1.1", "-v, --version")
18
+ .version("2.1.2", "-v, --version")
19
19
  .configureOutput({
20
20
  writeOut: str => process.stdout.write(str),
21
21
  writeErr: str => process.stderr.write(str),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@otonix/cli",
3
- "version": "2.1.1",
3
+ "version": "2.1.2",
4
4
  "description": "Otonix CLI — deploy autonomous agent tokens on Base via Clanker v4",
5
5
  "type": "module",
6
6
  "bin": {