@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.
- package/dist/commands/agent.js +73 -77
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/commands/agent.js
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import { confirm
|
|
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,
|
|
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
|
|
60
|
-
console.log(" " + mono(`otonix agent:register --name ${name}
|
|
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("
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
|
|
94
|
-
|
|
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
|
-
|
|
133
|
+
sendSpinner.text = `Waiting for confirmation... (${txHash.slice(0, 18)}...)`;
|
|
98
134
|
try {
|
|
99
|
-
const receipt = await publicClient.
|
|
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
|
-
|
|
104
|
-
|
|
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",
|
|
154
|
+
row("OTX sent", "200.000 OTX");
|
|
158
155
|
row("Tx hash", txHash);
|
|
159
|
-
row("
|
|
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("
|
|
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
|
-
|
|
165
|
+
sendSpinner.stop();
|
|
166
166
|
const msg = err instanceof Error ? err.message : String(err);
|
|
167
|
-
|
|
168
|
-
|
|
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("
|
|
211
|
-
console.log(" " + chalk.
|
|
212
|
-
console.log(" " + chalk.dim(
|
|
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.
|
|
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),
|