@sequence0/blockclaw 2.0.0
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 +97 -0
- package/dist/agent/binary.d.ts +15 -0
- package/dist/agent/binary.d.ts.map +1 -0
- package/dist/agent/binary.js +172 -0
- package/dist/agent/binary.js.map +1 -0
- package/dist/agent/chains.d.ts +26 -0
- package/dist/agent/chains.d.ts.map +1 -0
- package/dist/agent/chains.js +123 -0
- package/dist/agent/chains.js.map +1 -0
- package/dist/agent/client.d.ts +484 -0
- package/dist/agent/client.d.ts.map +1 -0
- package/dist/agent/client.js +448 -0
- package/dist/agent/client.js.map +1 -0
- package/dist/agent/config.d.ts +75 -0
- package/dist/agent/config.d.ts.map +1 -0
- package/dist/agent/config.js +133 -0
- package/dist/agent/config.js.map +1 -0
- package/dist/agent/process.d.ts +36 -0
- package/dist/agent/process.d.ts.map +1 -0
- package/dist/agent/process.js +208 -0
- package/dist/agent/process.js.map +1 -0
- package/dist/agent/wallet.d.ts +43 -0
- package/dist/agent/wallet.d.ts.map +1 -0
- package/dist/agent/wallet.js +146 -0
- package/dist/agent/wallet.js.map +1 -0
- package/dist/ai/brain.d.ts +21 -0
- package/dist/ai/brain.d.ts.map +1 -0
- package/dist/ai/brain.js +117 -0
- package/dist/ai/brain.js.map +1 -0
- package/dist/ai/prompts.d.ts +15 -0
- package/dist/ai/prompts.d.ts.map +1 -0
- package/dist/ai/prompts.js +67 -0
- package/dist/ai/prompts.js.map +1 -0
- package/dist/ai/rules.d.ts +19 -0
- package/dist/ai/rules.d.ts.map +1 -0
- package/dist/ai/rules.js +143 -0
- package/dist/ai/rules.js.map +1 -0
- package/dist/core/detector.d.ts +16 -0
- package/dist/core/detector.d.ts.map +1 -0
- package/dist/core/detector.js +90 -0
- package/dist/core/detector.js.map +1 -0
- package/dist/core/healer.d.ts +62 -0
- package/dist/core/healer.d.ts.map +1 -0
- package/dist/core/healer.js +355 -0
- package/dist/core/healer.js.map +1 -0
- package/dist/core/heartbeat.d.ts +67 -0
- package/dist/core/heartbeat.d.ts.map +1 -0
- package/dist/core/heartbeat.js +426 -0
- package/dist/core/heartbeat.js.map +1 -0
- package/dist/core/memory.d.ts +57 -0
- package/dist/core/memory.d.ts.map +1 -0
- package/dist/core/memory.js +149 -0
- package/dist/core/memory.js.map +1 -0
- package/dist/core/updater.d.ts +16 -0
- package/dist/core/updater.d.ts.map +1 -0
- package/dist/core/updater.js +107 -0
- package/dist/core/updater.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +97 -0
- package/dist/index.js.map +1 -0
- package/dist/interface/commands/ask.d.ts +3 -0
- package/dist/interface/commands/ask.d.ts.map +1 -0
- package/dist/interface/commands/ask.js +39 -0
- package/dist/interface/commands/ask.js.map +1 -0
- package/dist/interface/commands/backup.d.ts +3 -0
- package/dist/interface/commands/backup.d.ts.map +1 -0
- package/dist/interface/commands/backup.js +576 -0
- package/dist/interface/commands/backup.js.map +1 -0
- package/dist/interface/commands/config.d.ts +3 -0
- package/dist/interface/commands/config.d.ts.map +1 -0
- package/dist/interface/commands/config.js +107 -0
- package/dist/interface/commands/config.js.map +1 -0
- package/dist/interface/commands/daemon.d.ts +3 -0
- package/dist/interface/commands/daemon.d.ts.map +1 -0
- package/dist/interface/commands/daemon.js +162 -0
- package/dist/interface/commands/daemon.js.map +1 -0
- package/dist/interface/commands/doctor.d.ts +3 -0
- package/dist/interface/commands/doctor.d.ts.map +1 -0
- package/dist/interface/commands/doctor.js +143 -0
- package/dist/interface/commands/doctor.js.map +1 -0
- package/dist/interface/commands/earnings.d.ts +3 -0
- package/dist/interface/commands/earnings.d.ts.map +1 -0
- package/dist/interface/commands/earnings.js +165 -0
- package/dist/interface/commands/earnings.js.map +1 -0
- package/dist/interface/commands/health.d.ts +3 -0
- package/dist/interface/commands/health.d.ts.map +1 -0
- package/dist/interface/commands/health.js +48 -0
- package/dist/interface/commands/health.js.map +1 -0
- package/dist/interface/commands/history.d.ts +3 -0
- package/dist/interface/commands/history.d.ts.map +1 -0
- package/dist/interface/commands/history.js +113 -0
- package/dist/interface/commands/history.js.map +1 -0
- package/dist/interface/commands/info.d.ts +3 -0
- package/dist/interface/commands/info.d.ts.map +1 -0
- package/dist/interface/commands/info.js +82 -0
- package/dist/interface/commands/info.js.map +1 -0
- package/dist/interface/commands/logs.d.ts +3 -0
- package/dist/interface/commands/logs.d.ts.map +1 -0
- package/dist/interface/commands/logs.js +98 -0
- package/dist/interface/commands/logs.js.map +1 -0
- package/dist/interface/commands/menu.d.ts +4 -0
- package/dist/interface/commands/menu.d.ts.map +1 -0
- package/dist/interface/commands/menu.js +156 -0
- package/dist/interface/commands/menu.js.map +1 -0
- package/dist/interface/commands/receive.d.ts +3 -0
- package/dist/interface/commands/receive.d.ts.map +1 -0
- package/dist/interface/commands/receive.js +81 -0
- package/dist/interface/commands/receive.js.map +1 -0
- package/dist/interface/commands/register.d.ts +3 -0
- package/dist/interface/commands/register.d.ts.map +1 -0
- package/dist/interface/commands/register.js +231 -0
- package/dist/interface/commands/register.js.map +1 -0
- package/dist/interface/commands/restart.d.ts +3 -0
- package/dist/interface/commands/restart.d.ts.map +1 -0
- package/dist/interface/commands/restart.js +154 -0
- package/dist/interface/commands/restart.js.map +1 -0
- package/dist/interface/commands/send.d.ts +3 -0
- package/dist/interface/commands/send.d.ts.map +1 -0
- package/dist/interface/commands/send.js +108 -0
- package/dist/interface/commands/send.js.map +1 -0
- package/dist/interface/commands/service.d.ts +3 -0
- package/dist/interface/commands/service.d.ts.map +1 -0
- package/dist/interface/commands/service.js +474 -0
- package/dist/interface/commands/service.js.map +1 -0
- package/dist/interface/commands/setup.d.ts +5 -0
- package/dist/interface/commands/setup.d.ts.map +1 -0
- package/dist/interface/commands/setup.js +410 -0
- package/dist/interface/commands/setup.js.map +1 -0
- package/dist/interface/commands/start.d.ts +3 -0
- package/dist/interface/commands/start.d.ts.map +1 -0
- package/dist/interface/commands/start.js +171 -0
- package/dist/interface/commands/start.js.map +1 -0
- package/dist/interface/commands/status.d.ts +3 -0
- package/dist/interface/commands/status.d.ts.map +1 -0
- package/dist/interface/commands/status.js +77 -0
- package/dist/interface/commands/status.js.map +1 -0
- package/dist/interface/commands/stop.d.ts +3 -0
- package/dist/interface/commands/stop.d.ts.map +1 -0
- package/dist/interface/commands/stop.js +62 -0
- package/dist/interface/commands/stop.js.map +1 -0
- package/dist/interface/commands/update.d.ts +3 -0
- package/dist/interface/commands/update.d.ts.map +1 -0
- package/dist/interface/commands/update.js +53 -0
- package/dist/interface/commands/update.js.map +1 -0
- package/dist/interface/commands/wallet.d.ts +3 -0
- package/dist/interface/commands/wallet.d.ts.map +1 -0
- package/dist/interface/commands/wallet.js +446 -0
- package/dist/interface/commands/wallet.js.map +1 -0
- package/dist/interface/commands/webhook.d.ts +3 -0
- package/dist/interface/commands/webhook.d.ts.map +1 -0
- package/dist/interface/commands/webhook.js +99 -0
- package/dist/interface/commands/webhook.js.map +1 -0
- package/dist/interface/commands/withdraw.d.ts +3 -0
- package/dist/interface/commands/withdraw.d.ts.map +1 -0
- package/dist/interface/commands/withdraw.js +261 -0
- package/dist/interface/commands/withdraw.js.map +1 -0
- package/dist/interface/interactive.d.ts +43 -0
- package/dist/interface/interactive.d.ts.map +1 -0
- package/dist/interface/interactive.js +276 -0
- package/dist/interface/interactive.js.map +1 -0
- package/dist/interface/logo.d.ts +2 -0
- package/dist/interface/logo.d.ts.map +1 -0
- package/dist/interface/logo.js +21 -0
- package/dist/interface/logo.js.map +1 -0
- package/dist/interface/webhooks.d.ts +19 -0
- package/dist/interface/webhooks.d.ts.map +1 -0
- package/dist/interface/webhooks.js +172 -0
- package/dist/interface/webhooks.js.map +1 -0
- package/dist/utils/format.d.ts +19 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +107 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/logger.d.ts +20 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +47 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/paths.d.ts +35 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +45 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/platform.d.ts +26 -0
- package/dist/utils/platform.d.ts.map +1 -0
- package/dist/utils/platform.js +72 -0
- package/dist/utils/platform.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import pc from "picocolors";
|
|
2
|
+
import { AgentClient } from "../../agent/client.js";
|
|
3
|
+
import { getChain, getSymbol } from "../../agent/chains.js";
|
|
4
|
+
import { readBlockclawConfig } from "../../agent/config.js";
|
|
5
|
+
import { logger } from "../../utils/logger.js";
|
|
6
|
+
import { selectWallet, selectChain, handleCancel } from "../interactive.js";
|
|
7
|
+
export function register(program) {
|
|
8
|
+
program
|
|
9
|
+
.command("receive")
|
|
10
|
+
.description("Show wallet address for receiving tokens")
|
|
11
|
+
.option("--wallet <id>", "Wallet identifier")
|
|
12
|
+
.option("--chain <chain>", "Target chain")
|
|
13
|
+
.action(async (opts) => {
|
|
14
|
+
try {
|
|
15
|
+
const config = readBlockclawConfig();
|
|
16
|
+
const client = new AgentClient(`http://localhost:${config.api_port ?? 8080}`);
|
|
17
|
+
// Step 1: Select wallet
|
|
18
|
+
const wallet = await selectWallet(client, opts.wallet);
|
|
19
|
+
if (!wallet)
|
|
20
|
+
handleCancel();
|
|
21
|
+
// Step 2: Select chain
|
|
22
|
+
const allWallets = await client.wallets();
|
|
23
|
+
const hasEdPair = allWallets.some((w) => w.wallet_id === `${wallet.walletId}-ed`);
|
|
24
|
+
const chainCurve = hasEdPair ? undefined : wallet.curve;
|
|
25
|
+
const chainId = await selectChain(chainCurve, opts.chain);
|
|
26
|
+
if (!chainId)
|
|
27
|
+
handleCancel();
|
|
28
|
+
const chain = getChain(chainId);
|
|
29
|
+
const chainName = chain?.name ?? chainId;
|
|
30
|
+
const symbol = getSymbol(chainId);
|
|
31
|
+
const address = wallet.address;
|
|
32
|
+
// Step 3: Display address
|
|
33
|
+
logger.blank();
|
|
34
|
+
logger.header("Receive Address");
|
|
35
|
+
logger.separator();
|
|
36
|
+
logger.kv("Wallet", wallet.walletId);
|
|
37
|
+
logger.kv("Chain", chainName);
|
|
38
|
+
logger.blank();
|
|
39
|
+
// Address display with ASCII art box
|
|
40
|
+
const boxWidth = Math.max(address.length + 4, 40);
|
|
41
|
+
const padded = address.padStart(Math.floor((boxWidth - 2 + address.length) / 2)).padEnd(boxWidth - 2);
|
|
42
|
+
console.log(` ${pc.dim("┌" + "─".repeat(boxWidth) + "┐")}`);
|
|
43
|
+
console.log(` ${pc.dim("│")} ${" ".repeat(boxWidth - 2)} ${pc.dim("│")}`);
|
|
44
|
+
console.log(` ${pc.dim("│")} ${pc.bold(pc.cyan(padded))} ${pc.dim("│")}`);
|
|
45
|
+
console.log(` ${pc.dim("│")} ${" ".repeat(boxWidth - 2)} ${pc.dim("│")}`);
|
|
46
|
+
console.log(` ${pc.dim("└" + "─".repeat(boxWidth) + "┘")}`);
|
|
47
|
+
logger.blank();
|
|
48
|
+
// Try to copy to clipboard
|
|
49
|
+
try {
|
|
50
|
+
const { execSync } = await import("node:child_process");
|
|
51
|
+
const platform = process.platform;
|
|
52
|
+
if (platform === "darwin") {
|
|
53
|
+
execSync("pbcopy", { input: address });
|
|
54
|
+
logger.success("Address copied to clipboard");
|
|
55
|
+
}
|
|
56
|
+
else if (platform === "linux") {
|
|
57
|
+
execSync("xclip -selection clipboard", { input: address });
|
|
58
|
+
logger.success("Address copied to clipboard");
|
|
59
|
+
}
|
|
60
|
+
else if (platform === "win32") {
|
|
61
|
+
execSync("clip", { input: address });
|
|
62
|
+
logger.success("Address copied to clipboard");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// Clipboard not available, just show the address
|
|
67
|
+
logger.info("Copy the address above to share it");
|
|
68
|
+
}
|
|
69
|
+
logger.blank();
|
|
70
|
+
logger.separator();
|
|
71
|
+
logger.warn(`Send only ${pc.bold(chainName)} (${symbol}) assets to this address.`);
|
|
72
|
+
logger.separator();
|
|
73
|
+
logger.blank();
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
logger.error(`Receive failed: ${err.message}`);
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=receive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receive.js","sourceRoot":"","sources":["../../../src/interface/commands/receive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../src/interface/commands/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmCzC,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiB/C"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import pc from "picocolors";
|
|
2
|
+
import * as p from "@clack/prompts";
|
|
3
|
+
import { AgentClient } from "../../agent/client.js";
|
|
4
|
+
import { isAgentRunning } from "../../agent/process.js";
|
|
5
|
+
import { readBlockclawConfig, readAgentConfig } from "../../agent/config.js";
|
|
6
|
+
import { logger } from "../../utils/logger.js";
|
|
7
|
+
import { formatDuration, truncate } from "../../utils/format.js";
|
|
8
|
+
// Contract addresses per network
|
|
9
|
+
const NETWORK_INFO = {
|
|
10
|
+
mainnet: {
|
|
11
|
+
agentRegistry: "0xdefa5ab7ea6a87ac51628f4cde55bb4d49e62f50",
|
|
12
|
+
chainId: 800801,
|
|
13
|
+
rpcUrl: "https://rpc.sequence0.network",
|
|
14
|
+
explorerBase: "https://explorer.sequence0.network",
|
|
15
|
+
},
|
|
16
|
+
testnet: {
|
|
17
|
+
agentRegistry: "0xb2c218e154d4374e721eab6293af3eeeaa117400",
|
|
18
|
+
chainId: 800800,
|
|
19
|
+
rpcUrl: "https://testnet-rpc.sequence0.network",
|
|
20
|
+
explorerBase: "https://testnet.explorer.sequence0.network",
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
const FAUCET_URL = "https://faucet.sequence0.network";
|
|
24
|
+
// AgentRegistry ABI — register(bytes32 peerId)
|
|
25
|
+
const REGISTER_SELECTOR = "0x4420e486"; // keccak256("register(bytes32)")[:4]
|
|
26
|
+
export function register(program) {
|
|
27
|
+
program
|
|
28
|
+
.command("register")
|
|
29
|
+
.description("Register your node on the Sequence0 network")
|
|
30
|
+
.option("--network <network>", "Network to register on (testnet or mainnet)")
|
|
31
|
+
.action(async (opts) => {
|
|
32
|
+
try {
|
|
33
|
+
await runRegister(opts);
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
if (err instanceof Error && err.message === "CANCEL") {
|
|
37
|
+
p.cancel("Registration cancelled.");
|
|
38
|
+
process.exit(0);
|
|
39
|
+
}
|
|
40
|
+
logger.error(`Registration failed: ${err.message}`);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function guard(value) {
|
|
46
|
+
if (p.isCancel(value))
|
|
47
|
+
throw new Error("CANCEL");
|
|
48
|
+
return value;
|
|
49
|
+
}
|
|
50
|
+
async function runRegister(opts) {
|
|
51
|
+
const config = readBlockclawConfig();
|
|
52
|
+
const agentConfig = readAgentConfig();
|
|
53
|
+
const apiPort = config.api_port ?? agentConfig?.api_port ?? 8080;
|
|
54
|
+
// Step 1: Check if agent is running
|
|
55
|
+
const proc = isAgentRunning();
|
|
56
|
+
if (!proc.running) {
|
|
57
|
+
logger.error("Node is not running. Start it first with: blockclaw start");
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
const client = new AgentClient(`http://localhost:${apiPort}`);
|
|
61
|
+
const healthy = await client.isHealthy();
|
|
62
|
+
if (!healthy) {
|
|
63
|
+
logger.error("Node is running but not responding. It may still be starting up.");
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
p.intro(pc.bgCyan(pc.black(" blockclaw register ")));
|
|
67
|
+
// Step 2: Get agent info
|
|
68
|
+
const spin = p.spinner();
|
|
69
|
+
spin.start("Checking node status");
|
|
70
|
+
const [health, status] = await Promise.all([
|
|
71
|
+
client.health(),
|
|
72
|
+
client.status(),
|
|
73
|
+
]);
|
|
74
|
+
spin.stop("Node is online");
|
|
75
|
+
const peerId = health.peer_id;
|
|
76
|
+
const network = opts.network ?? config.network ?? agentConfig?.network ?? "testnet";
|
|
77
|
+
const netInfo = NETWORK_INFO[network];
|
|
78
|
+
if (!netInfo) {
|
|
79
|
+
logger.error(`Unknown network: ${network}. Use 'testnet' or 'mainnet'.`);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
// Step 3: Check registration status via RPC
|
|
83
|
+
spin.start("Checking registration status on-chain");
|
|
84
|
+
let alreadyRegistered = false;
|
|
85
|
+
try {
|
|
86
|
+
// Call isRegistered(bytes32 peerId) on AgentRegistry
|
|
87
|
+
// We encode the peer ID as bytes32 for the call
|
|
88
|
+
const peerIdBytes32 = encodePeerIdAsBytes32(peerId);
|
|
89
|
+
const isRegisteredSelector = "0xc3c5a547"; // keccak256("isRegistered(bytes32)")[:4]
|
|
90
|
+
const callData = isRegisteredSelector + peerIdBytes32;
|
|
91
|
+
const result = await ethCall(netInfo.rpcUrl, netInfo.agentRegistry, callData);
|
|
92
|
+
// Result is a bool — 0x...01 = true
|
|
93
|
+
alreadyRegistered = result !== "0x" && result.endsWith("1");
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// RPC call failed — assume not registered
|
|
97
|
+
}
|
|
98
|
+
spin.stop(alreadyRegistered
|
|
99
|
+
? pc.green("Already registered!")
|
|
100
|
+
: "Not registered yet");
|
|
101
|
+
if (alreadyRegistered) {
|
|
102
|
+
p.note([
|
|
103
|
+
`Your node is ${pc.green("already registered")} on ${pc.bold(network)}.`,
|
|
104
|
+
"",
|
|
105
|
+
`${pc.dim("Node ID:")} ${truncate(peerId, 20)}`,
|
|
106
|
+
`${pc.dim("Network:")} ${network}`,
|
|
107
|
+
"",
|
|
108
|
+
`Run ${pc.cyan("blockclaw earnings")} to check your signing revenue.`,
|
|
109
|
+
].join("\n"), "Registration Status");
|
|
110
|
+
p.outro("You're all set.");
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
// Step 4: Show registration info
|
|
114
|
+
p.note([
|
|
115
|
+
`${pc.dim("Node ID:")} ${truncate(peerId, 20)}`,
|
|
116
|
+
`${pc.dim("Network:")} ${network}`,
|
|
117
|
+
`${pc.dim("Uptime:")} ${formatDuration(health.uptime_seconds)}`,
|
|
118
|
+
`${pc.dim("Peers:")} ${health.connected_peers} connected`,
|
|
119
|
+
`${pc.dim("Wallets:")} ${status.wallets.length}`,
|
|
120
|
+
"",
|
|
121
|
+
`Registration fee: ${pc.bold("0.1 ETH")} on Sequence0 chain`,
|
|
122
|
+
pc.dim("Free for the first 1,000 node runners."),
|
|
123
|
+
].join("\n"), "Node Info");
|
|
124
|
+
if (network === "testnet") {
|
|
125
|
+
p.log.info(`Get testnet ETH at ${pc.underline(pc.cyan(FAUCET_URL))}`);
|
|
126
|
+
}
|
|
127
|
+
// Step 5: Confirm
|
|
128
|
+
const confirmed = guard(await p.confirm({
|
|
129
|
+
message: `Register your node on ${pc.bold(network)}?`,
|
|
130
|
+
}));
|
|
131
|
+
if (!confirmed)
|
|
132
|
+
throw new Error("CANCEL");
|
|
133
|
+
// Step 6: Submit registration transaction via agent
|
|
134
|
+
spin.start("Submitting registration");
|
|
135
|
+
try {
|
|
136
|
+
// The agent exposes a /register endpoint that handles the on-chain transaction
|
|
137
|
+
// It signs and broadcasts the registration tx using its own wallet
|
|
138
|
+
const response = await client.registerAgent(network);
|
|
139
|
+
spin.stop(pc.green("Registration submitted!"));
|
|
140
|
+
const txHash = response.tx_hash;
|
|
141
|
+
if (txHash) {
|
|
142
|
+
p.note([
|
|
143
|
+
`${pc.green("Registration transaction submitted!")}`,
|
|
144
|
+
"",
|
|
145
|
+
`${pc.dim("Transaction:")} ${txHash}`,
|
|
146
|
+
`${pc.dim("Network:")} ${network}`,
|
|
147
|
+
`${pc.dim("Node ID:")} ${truncate(peerId, 20)}`,
|
|
148
|
+
"",
|
|
149
|
+
`${pc.dim("Explorer:")} ${netInfo.explorerBase}/tx/${txHash}`,
|
|
150
|
+
"",
|
|
151
|
+
pc.dim("Transaction may take a few seconds to confirm."),
|
|
152
|
+
`Run ${pc.cyan("blockclaw earnings")} to start tracking revenue.`,
|
|
153
|
+
].join("\n"), "Registration Complete");
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
p.note([
|
|
157
|
+
`Registration ${response.status === "already_registered" ? "already done" : "submitted"}.`,
|
|
158
|
+
"",
|
|
159
|
+
`${pc.dim("Status:")} ${response.status}`,
|
|
160
|
+
`${pc.dim("Node ID:")} ${truncate(peerId, 20)}`,
|
|
161
|
+
].join("\n"), "Registration");
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
spin.stop(pc.red("Registration failed"));
|
|
166
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
167
|
+
// Common failure: insufficient balance
|
|
168
|
+
if (msg.includes("insufficient") || msg.includes("balance")) {
|
|
169
|
+
p.log.error("Insufficient ETH balance for registration.");
|
|
170
|
+
p.log.info(`Your node needs ${pc.bold("0.1 ETH")} on the Sequence0 chain.`);
|
|
171
|
+
if (network === "testnet") {
|
|
172
|
+
p.log.info(`Get testnet ETH at ${pc.underline(pc.cyan(FAUCET_URL))}`);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
p.log.info("Bridge ETH to Sequence0 mainnet to fund your node.");
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
else if (msg.includes("endpoint") || msg.includes("404") || msg.includes("not found")) {
|
|
179
|
+
// Agent doesn't have /register endpoint yet — show manual instructions
|
|
180
|
+
p.log.warn("Your node version doesn't support automatic registration yet.");
|
|
181
|
+
p.note([
|
|
182
|
+
"To register manually:",
|
|
183
|
+
"",
|
|
184
|
+
`1. Ensure your node has ${pc.bold("0.1 ETH")} on the Sequence0 chain`,
|
|
185
|
+
`2. The node will auto-register on next restart if it has sufficient balance`,
|
|
186
|
+
network === "testnet"
|
|
187
|
+
? `${pc.dim("Faucet:")} ${FAUCET_URL}`
|
|
188
|
+
: "",
|
|
189
|
+
].filter(Boolean).join("\n"), "Manual Registration");
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
p.log.error(msg);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
p.outro("Done.");
|
|
196
|
+
}
|
|
197
|
+
// ---------------------------------------------------------------------------
|
|
198
|
+
// Helpers
|
|
199
|
+
// ---------------------------------------------------------------------------
|
|
200
|
+
/** Encode a peer ID string as bytes32 (right-padded with zeros) */
|
|
201
|
+
function encodePeerIdAsBytes32(peerId) {
|
|
202
|
+
// Convert peer ID to hex, pad to 32 bytes
|
|
203
|
+
const hex = Buffer.from(peerId).toString("hex");
|
|
204
|
+
return hex.padEnd(64, "0");
|
|
205
|
+
}
|
|
206
|
+
/** Make an eth_call to a contract */
|
|
207
|
+
async function ethCall(rpcUrl, to, data) {
|
|
208
|
+
const controller = new AbortController();
|
|
209
|
+
const timer = setTimeout(() => controller.abort(), 10_000);
|
|
210
|
+
try {
|
|
211
|
+
const res = await fetch(rpcUrl, {
|
|
212
|
+
method: "POST",
|
|
213
|
+
headers: { "Content-Type": "application/json" },
|
|
214
|
+
body: JSON.stringify({
|
|
215
|
+
jsonrpc: "2.0",
|
|
216
|
+
method: "eth_call",
|
|
217
|
+
params: [{ to, data }, "latest"],
|
|
218
|
+
id: 1,
|
|
219
|
+
}),
|
|
220
|
+
signal: controller.signal,
|
|
221
|
+
});
|
|
222
|
+
const json = await res.json();
|
|
223
|
+
if (json.error)
|
|
224
|
+
throw new Error(json.error.message);
|
|
225
|
+
return json.result ?? "0x";
|
|
226
|
+
}
|
|
227
|
+
finally {
|
|
228
|
+
clearTimeout(timer);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=register.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/interface/commands/register.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restart.d.ts","sourceRoot":"","sources":["../../../src/interface/commands/restart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAa/C"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { AgentClient } from "../../agent/client.js";
|
|
2
|
+
import { isAgentRunning, stopAgent, findAgentProcess } from "../../agent/process.js";
|
|
3
|
+
import { resolveBinary, downloadBinary, getBinaryVersion } from "../../agent/binary.js";
|
|
4
|
+
import { spawnAgent, isPortAvailable } from "../../agent/process.js";
|
|
5
|
+
import { mergeConfigs } from "../../agent/config.js";
|
|
6
|
+
import { logger } from "../../utils/logger.js";
|
|
7
|
+
import { formatDuration, createSpinner, colorStatus } from "../../utils/format.js";
|
|
8
|
+
export function register(program) {
|
|
9
|
+
program
|
|
10
|
+
.command("restart")
|
|
11
|
+
.description("Restart the Sequence0 node")
|
|
12
|
+
.option("-n, --network <network>", "Network to connect to (mainnet or testnet)")
|
|
13
|
+
.action(async (opts) => {
|
|
14
|
+
try {
|
|
15
|
+
await restartAgent(opts);
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
logger.error(err instanceof Error ? err.message : String(err));
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
async function restartAgent(opts) {
|
|
24
|
+
const config = mergeConfigs();
|
|
25
|
+
const network = opts.network ?? config.network;
|
|
26
|
+
const apiPort = config.apiPort;
|
|
27
|
+
const p2pPort = config.port;
|
|
28
|
+
logger.header(`Restarting node on ${network}`);
|
|
29
|
+
// 1. Stop the agent if it is running
|
|
30
|
+
let { running, pid } = isAgentRunning();
|
|
31
|
+
if (!running) {
|
|
32
|
+
const foundPid = await findAgentProcess();
|
|
33
|
+
if (foundPid) {
|
|
34
|
+
running = true;
|
|
35
|
+
pid = foundPid;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (running && pid) {
|
|
39
|
+
logger.step(1, 4, "Stopping node...");
|
|
40
|
+
const stopped = await stopAgent(apiPort);
|
|
41
|
+
if (stopped) {
|
|
42
|
+
logger.success("Node stopped.");
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
logger.warn("Graceful stop failed, force stopping...");
|
|
46
|
+
try {
|
|
47
|
+
process.kill(pid, "SIGKILL");
|
|
48
|
+
logger.success("Node force-stopped.");
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
logger.error("Failed to stop the node. Cannot restart.");
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
logger.step(1, 4, "Node is not running. Starting fresh.");
|
|
58
|
+
}
|
|
59
|
+
// 2. Wait 1 second for ports and resources to be released
|
|
60
|
+
await new Promise((r) => setTimeout(r, 1000));
|
|
61
|
+
// 3. Resolve the binary
|
|
62
|
+
logger.step(2, 4, "Resolving node software...");
|
|
63
|
+
let binPath;
|
|
64
|
+
try {
|
|
65
|
+
binPath = await resolveBinary();
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
logger.warn("Node software not found.");
|
|
69
|
+
logger.info("Downloading node software...");
|
|
70
|
+
binPath = await downloadBinary();
|
|
71
|
+
}
|
|
72
|
+
const version = await getBinaryVersion(binPath);
|
|
73
|
+
logger.kv("Binary", binPath);
|
|
74
|
+
if (version) {
|
|
75
|
+
logger.kv("Version", version);
|
|
76
|
+
}
|
|
77
|
+
// Check port availability before spawning
|
|
78
|
+
const p2pAvailable = await isPortAvailable(p2pPort);
|
|
79
|
+
if (!p2pAvailable) {
|
|
80
|
+
logger.error(`Network port ${p2pPort} is still in use. Wait a moment and try again.`);
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
const apiAvailable = await isPortAvailable(apiPort);
|
|
84
|
+
if (!apiAvailable) {
|
|
85
|
+
logger.error(`Control port ${apiPort} is still in use. Wait a moment and try again.`);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
// 4. Spawn the agent
|
|
89
|
+
logger.step(3, 4, "Starting node...");
|
|
90
|
+
const child = spawnAgent({
|
|
91
|
+
binPath,
|
|
92
|
+
network,
|
|
93
|
+
port: p2pPort,
|
|
94
|
+
apiPort,
|
|
95
|
+
dataDir: config.dataDir,
|
|
96
|
+
rpcUrl: config.rpcUrl,
|
|
97
|
+
registry: config.registry,
|
|
98
|
+
walletFactory: config.walletFactory,
|
|
99
|
+
feeCollector: config.feeCollector,
|
|
100
|
+
programRegistry: config.programRegistry,
|
|
101
|
+
delegationRegistry: config.delegationRegistry,
|
|
102
|
+
daemon: config.daemon,
|
|
103
|
+
bootstrap: config.bootstrap,
|
|
104
|
+
logLevel: config.logLevel,
|
|
105
|
+
externalIp: config.externalIp,
|
|
106
|
+
noRegistry: config.noRegistry,
|
|
107
|
+
});
|
|
108
|
+
// 5. Poll health endpoint until healthy (timeout 60s)
|
|
109
|
+
logger.step(4, 4, "Connecting to the network...");
|
|
110
|
+
const client = new AgentClient(`http://localhost:${apiPort}`);
|
|
111
|
+
const spinner = createSpinner("Node restarting...");
|
|
112
|
+
const startTime = Date.now();
|
|
113
|
+
const timeoutMs = 60_000;
|
|
114
|
+
let healthy = false;
|
|
115
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
116
|
+
healthy = await client.isHealthy();
|
|
117
|
+
if (healthy)
|
|
118
|
+
break;
|
|
119
|
+
await new Promise((r) => setTimeout(r, 1000));
|
|
120
|
+
}
|
|
121
|
+
if (!healthy) {
|
|
122
|
+
spinner.stop("Node failed to start within 60 seconds");
|
|
123
|
+
logger.error("Node did not come online after restart.");
|
|
124
|
+
logger.info("Check logs at ~/.sequence0/agent.log for details.");
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
spinner.stop("Node is online");
|
|
128
|
+
// Display restart summary
|
|
129
|
+
logger.blank();
|
|
130
|
+
logger.separator();
|
|
131
|
+
try {
|
|
132
|
+
const status = await client.status();
|
|
133
|
+
logger.kv("Status", colorStatus("running"));
|
|
134
|
+
logger.kv("Node ID", status.peer_id);
|
|
135
|
+
logger.kv("Network", network);
|
|
136
|
+
logger.kv("Peers", status.connected_peers);
|
|
137
|
+
logger.kv("Wallets", status.wallets.length);
|
|
138
|
+
logger.kv("Uptime", formatDuration(status.uptime_seconds));
|
|
139
|
+
logger.kv("Control", `http://localhost:${apiPort}`);
|
|
140
|
+
if (version) {
|
|
141
|
+
logger.kv("Version", version);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
logger.kv("Status", colorStatus("running"));
|
|
146
|
+
logger.kv("Network", network);
|
|
147
|
+
logger.kv("Control", `http://localhost:${apiPort}`);
|
|
148
|
+
}
|
|
149
|
+
logger.separator();
|
|
150
|
+
logger.blank();
|
|
151
|
+
logger.success("Node restarted successfully.");
|
|
152
|
+
logger.blank();
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=restart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restart.js","sourceRoot":"","sources":["../../../src/interface/commands/restart.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../../src/interface/commands/send.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiBzC,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAsH/C"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import pc from "picocolors";
|
|
2
|
+
import { AgentClient } from "../../agent/client.js";
|
|
3
|
+
import { getChain, getSymbol, getExplorerUrl } from "../../agent/chains.js";
|
|
4
|
+
import { readBlockclawConfig } from "../../agent/config.js";
|
|
5
|
+
import { logger } from "../../utils/logger.js";
|
|
6
|
+
import { formatAddress } from "../../utils/format.js";
|
|
7
|
+
import { selectWallet, selectChain, inputAddress, inputAmount, confirmAction, withSpinner, handleCancel, } from "../interactive.js";
|
|
8
|
+
export function register(program) {
|
|
9
|
+
program
|
|
10
|
+
.command("send")
|
|
11
|
+
.description("Send tokens from a wallet")
|
|
12
|
+
.option("--wallet <id>", "Wallet identifier")
|
|
13
|
+
.option("--chain <chain>", "Target chain")
|
|
14
|
+
.option("--to <address>", "Recipient address")
|
|
15
|
+
.option("--amount <amount>", "Amount to send")
|
|
16
|
+
.action(async (opts) => {
|
|
17
|
+
try {
|
|
18
|
+
const config = readBlockclawConfig();
|
|
19
|
+
const client = new AgentClient(`http://localhost:${config.api_port ?? 8080}`);
|
|
20
|
+
// Step 1: Select wallet
|
|
21
|
+
const wallet = await selectWallet(client, opts.wallet);
|
|
22
|
+
if (!wallet)
|
|
23
|
+
handleCancel();
|
|
24
|
+
// Step 2: Select chain
|
|
25
|
+
// Check if this is a universal wallet (has -ed pair) — show all chains
|
|
26
|
+
const allWallets = await client.wallets();
|
|
27
|
+
const hasEdPair = allWallets.some((w) => w.wallet_id === `${wallet.walletId}-ed`);
|
|
28
|
+
const chainCurve = hasEdPair ? undefined : wallet.curve;
|
|
29
|
+
const chainId = await selectChain(chainCurve, opts.chain);
|
|
30
|
+
if (!chainId)
|
|
31
|
+
handleCancel();
|
|
32
|
+
// Step 3: Input recipient address
|
|
33
|
+
const to = await inputAddress(opts.to);
|
|
34
|
+
if (!to)
|
|
35
|
+
handleCancel();
|
|
36
|
+
// Step 4: Input amount
|
|
37
|
+
const symbol = getSymbol(chainId);
|
|
38
|
+
const amount = await inputAmount(symbol, opts.amount);
|
|
39
|
+
if (!amount)
|
|
40
|
+
handleCancel();
|
|
41
|
+
// Step 5: Show confirmation summary
|
|
42
|
+
const chain = getChain(chainId);
|
|
43
|
+
const chainName = chain?.name ?? chainId;
|
|
44
|
+
logger.blank();
|
|
45
|
+
logger.separator();
|
|
46
|
+
logger.kv("Wallet", wallet.walletId);
|
|
47
|
+
logger.kv("Chain", chainName);
|
|
48
|
+
logger.kv("To", to);
|
|
49
|
+
logger.kv("Amount", `${amount} ${symbol}`);
|
|
50
|
+
logger.separator();
|
|
51
|
+
logger.blank();
|
|
52
|
+
// Step 6: Confirm
|
|
53
|
+
const confirmed = await confirmAction(`Send ${amount} ${symbol} to ${formatAddress(to)}?`);
|
|
54
|
+
if (!confirmed)
|
|
55
|
+
handleCancel();
|
|
56
|
+
// Step 7: Sign the transfer
|
|
57
|
+
const payload = {
|
|
58
|
+
wallet_id: wallet.walletId,
|
|
59
|
+
chain: chainId,
|
|
60
|
+
to,
|
|
61
|
+
amount,
|
|
62
|
+
type: "transfer",
|
|
63
|
+
};
|
|
64
|
+
const result = await withSpinner("Processing your transfer...", async () => {
|
|
65
|
+
const signResponse = await client.sign({
|
|
66
|
+
wallet_id: wallet.walletId,
|
|
67
|
+
message: JSON.stringify(payload),
|
|
68
|
+
});
|
|
69
|
+
// Poll for result
|
|
70
|
+
let signResult = await client.getSignResult(signResponse.request_id);
|
|
71
|
+
let attempts = 0;
|
|
72
|
+
while (signResult.status === "pending" ||
|
|
73
|
+
signResult.status === "in_progress") {
|
|
74
|
+
if (attempts++ > 30) {
|
|
75
|
+
throw new Error("Transfer is taking longer than expected. Please try again.");
|
|
76
|
+
}
|
|
77
|
+
await new Promise((r) => setTimeout(r, 1000));
|
|
78
|
+
signResult = await client.getSignResult(signResponse.request_id);
|
|
79
|
+
}
|
|
80
|
+
if (signResult.error) {
|
|
81
|
+
throw new Error(signResult.error);
|
|
82
|
+
}
|
|
83
|
+
return signResult;
|
|
84
|
+
});
|
|
85
|
+
// Step 8: Display result
|
|
86
|
+
logger.blank();
|
|
87
|
+
logger.header("Transaction Sent");
|
|
88
|
+
logger.kv("Status", pc.green("Signed"));
|
|
89
|
+
logger.kv("Amount", `${amount} ${symbol}`);
|
|
90
|
+
logger.kv("To", to);
|
|
91
|
+
logger.kv("Chain", chainName);
|
|
92
|
+
if (result.signature) {
|
|
93
|
+
logger.kv("Confirmation", pc.dim(result.signature.slice(0, 16) + "..."));
|
|
94
|
+
}
|
|
95
|
+
// Show explorer link if we have a tx hash (signature may serve as one)
|
|
96
|
+
const explorerUrl = getExplorerUrl(chainId, result.signature ?? result.request_id);
|
|
97
|
+
if (explorerUrl) {
|
|
98
|
+
logger.kv("Explorer", pc.underline(pc.cyan(explorerUrl)));
|
|
99
|
+
}
|
|
100
|
+
logger.blank();
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
logger.error(`Send failed: ${err.message}`);
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=send.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send.js","sourceRoot":"","sources":["../../../src/interface/commands/send.ts"],"names":[],"mappings":"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"}
|