@blockrun/clawrouter 0.12.31 → 0.12.33
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 +33 -12
- package/dist/cli.js +279 -4
- package/dist/cli.js.map +1 -1
- package/dist/index.js +289 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/imagegen/SKILL.md +7 -7
- package/skills/x-api/SKILL.md +5 -5
package/dist/index.js
CHANGED
|
@@ -1640,6 +1640,7 @@ import { finished } from "stream";
|
|
|
1640
1640
|
import { homedir as homedir4 } from "os";
|
|
1641
1641
|
import { join as join5 } from "path";
|
|
1642
1642
|
import { mkdir as mkdir3, writeFile as writeFile2, readFile, stat as fsStat } from "fs/promises";
|
|
1643
|
+
import { readFileSync, existsSync } from "fs";
|
|
1643
1644
|
import { createPublicClient as createPublicClient2, http as http2 } from "viem";
|
|
1644
1645
|
import { base as base2 } from "viem/chains";
|
|
1645
1646
|
import { privateKeyToAccount as privateKeyToAccount3 } from "viem/accounts";
|
|
@@ -6064,6 +6065,22 @@ async function proxyPartnerRequest(req, res, apiBase, payFetch) {
|
|
|
6064
6065
|
}).catch(() => {
|
|
6065
6066
|
});
|
|
6066
6067
|
}
|
|
6068
|
+
function readImageFileAsDataUri(filePath) {
|
|
6069
|
+
const resolved = filePath.startsWith("~/") ? join5(homedir4(), filePath.slice(2)) : filePath;
|
|
6070
|
+
if (!existsSync(resolved)) {
|
|
6071
|
+
throw new Error(`Image file not found: ${resolved}`);
|
|
6072
|
+
}
|
|
6073
|
+
const ext = resolved.split(".").pop()?.toLowerCase() ?? "png";
|
|
6074
|
+
const mimeMap = {
|
|
6075
|
+
png: "image/png",
|
|
6076
|
+
jpg: "image/jpeg",
|
|
6077
|
+
jpeg: "image/jpeg",
|
|
6078
|
+
webp: "image/webp"
|
|
6079
|
+
};
|
|
6080
|
+
const mime = mimeMap[ext] ?? "image/png";
|
|
6081
|
+
const data = readFileSync(resolved);
|
|
6082
|
+
return `data:${mime};base64,${data.toString("base64")}`;
|
|
6083
|
+
}
|
|
6067
6084
|
async function uploadDataUriToHost(dataUri) {
|
|
6068
6085
|
const match = dataUri.match(/^data:(image\/\w+);base64,(.+)$/);
|
|
6069
6086
|
if (!match) throw new Error("Invalid data URI format");
|
|
@@ -6337,14 +6354,31 @@ async function startProxy(options) {
|
|
|
6337
6354
|
await mkdir3(IMAGE_DIR, { recursive: true });
|
|
6338
6355
|
const port2 = server.address()?.port ?? 8402;
|
|
6339
6356
|
for (const img of result.data) {
|
|
6340
|
-
const
|
|
6341
|
-
if (
|
|
6342
|
-
const [, mimeType, b64] =
|
|
6357
|
+
const dataUriMatch = img.url?.match(/^data:(image\/\w+);base64,(.+)$/);
|
|
6358
|
+
if (dataUriMatch) {
|
|
6359
|
+
const [, mimeType, b64] = dataUriMatch;
|
|
6343
6360
|
const ext = mimeType === "image/jpeg" ? "jpg" : mimeType.split("/")[1] ?? "png";
|
|
6344
6361
|
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
6345
6362
|
await writeFile2(join5(IMAGE_DIR, filename), Buffer.from(b64, "base64"));
|
|
6346
6363
|
img.url = `http://localhost:${port2}/images/${filename}`;
|
|
6347
6364
|
console.log(`[ClawRouter] Image saved \u2192 ${img.url}`);
|
|
6365
|
+
} else if (img.url?.startsWith("https://") || img.url?.startsWith("http://")) {
|
|
6366
|
+
try {
|
|
6367
|
+
const imgResp = await fetch(img.url);
|
|
6368
|
+
if (imgResp.ok) {
|
|
6369
|
+
const contentType = imgResp.headers.get("content-type") ?? "image/png";
|
|
6370
|
+
const ext = contentType.includes("jpeg") || contentType.includes("jpg") ? "jpg" : contentType.includes("webp") ? "webp" : "png";
|
|
6371
|
+
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
6372
|
+
const buf = Buffer.from(await imgResp.arrayBuffer());
|
|
6373
|
+
await writeFile2(join5(IMAGE_DIR, filename), buf);
|
|
6374
|
+
img.url = `http://localhost:${port2}/images/${filename}`;
|
|
6375
|
+
console.log(`[ClawRouter] Image downloaded & saved \u2192 ${img.url}`);
|
|
6376
|
+
}
|
|
6377
|
+
} catch (downloadErr) {
|
|
6378
|
+
console.warn(
|
|
6379
|
+
`[ClawRouter] Failed to download image, using original URL: ${downloadErr instanceof Error ? downloadErr.message : String(downloadErr)}`
|
|
6380
|
+
);
|
|
6381
|
+
}
|
|
6348
6382
|
}
|
|
6349
6383
|
}
|
|
6350
6384
|
}
|
|
@@ -6360,6 +6394,76 @@ async function startProxy(options) {
|
|
|
6360
6394
|
}
|
|
6361
6395
|
return;
|
|
6362
6396
|
}
|
|
6397
|
+
if (req.url === "/v1/images/image2image" && req.method === "POST") {
|
|
6398
|
+
const chunks = [];
|
|
6399
|
+
for await (const chunk of req) {
|
|
6400
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
6401
|
+
}
|
|
6402
|
+
const reqBody = Buffer.concat(chunks);
|
|
6403
|
+
try {
|
|
6404
|
+
const upstream = await payFetch(`${apiBase}/v1/images/image2image`, {
|
|
6405
|
+
method: "POST",
|
|
6406
|
+
headers: { "content-type": "application/json", "user-agent": USER_AGENT },
|
|
6407
|
+
body: reqBody
|
|
6408
|
+
});
|
|
6409
|
+
const text = await upstream.text();
|
|
6410
|
+
if (!upstream.ok) {
|
|
6411
|
+
res.writeHead(upstream.status, { "Content-Type": "application/json" });
|
|
6412
|
+
res.end(text);
|
|
6413
|
+
return;
|
|
6414
|
+
}
|
|
6415
|
+
let result;
|
|
6416
|
+
try {
|
|
6417
|
+
result = JSON.parse(text);
|
|
6418
|
+
} catch {
|
|
6419
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
6420
|
+
res.end(text);
|
|
6421
|
+
return;
|
|
6422
|
+
}
|
|
6423
|
+
if (result.data?.length) {
|
|
6424
|
+
await mkdir3(IMAGE_DIR, { recursive: true });
|
|
6425
|
+
const port2 = server.address()?.port ?? 8402;
|
|
6426
|
+
for (const img of result.data) {
|
|
6427
|
+
const dataUriMatch = img.url?.match(/^data:(image\/\w+);base64,(.+)$/);
|
|
6428
|
+
if (dataUriMatch) {
|
|
6429
|
+
const [, mimeType, b64] = dataUriMatch;
|
|
6430
|
+
const ext = mimeType === "image/jpeg" ? "jpg" : mimeType.split("/")[1] ?? "png";
|
|
6431
|
+
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
6432
|
+
await writeFile2(join5(IMAGE_DIR, filename), Buffer.from(b64, "base64"));
|
|
6433
|
+
img.url = `http://localhost:${port2}/images/${filename}`;
|
|
6434
|
+
console.log(`[ClawRouter] Image saved \u2192 ${img.url}`);
|
|
6435
|
+
} else if (img.url?.startsWith("https://") || img.url?.startsWith("http://")) {
|
|
6436
|
+
try {
|
|
6437
|
+
const imgResp = await fetch(img.url);
|
|
6438
|
+
if (imgResp.ok) {
|
|
6439
|
+
const contentType = imgResp.headers.get("content-type") ?? "image/png";
|
|
6440
|
+
const ext = contentType.includes("jpeg") || contentType.includes("jpg") ? "jpg" : contentType.includes("webp") ? "webp" : "png";
|
|
6441
|
+
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
6442
|
+
const buf = Buffer.from(await imgResp.arrayBuffer());
|
|
6443
|
+
await writeFile2(join5(IMAGE_DIR, filename), buf);
|
|
6444
|
+
img.url = `http://localhost:${port2}/images/${filename}`;
|
|
6445
|
+
console.log(`[ClawRouter] Image downloaded & saved \u2192 ${img.url}`);
|
|
6446
|
+
}
|
|
6447
|
+
} catch (downloadErr) {
|
|
6448
|
+
console.warn(
|
|
6449
|
+
`[ClawRouter] Failed to download image, using original URL: ${downloadErr instanceof Error ? downloadErr.message : String(downloadErr)}`
|
|
6450
|
+
);
|
|
6451
|
+
}
|
|
6452
|
+
}
|
|
6453
|
+
}
|
|
6454
|
+
}
|
|
6455
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
6456
|
+
res.end(JSON.stringify(result));
|
|
6457
|
+
} catch (err) {
|
|
6458
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6459
|
+
console.error(`[ClawRouter] Image editing error: ${msg}`);
|
|
6460
|
+
if (!res.headersSent) {
|
|
6461
|
+
res.writeHead(502, { "Content-Type": "application/json" });
|
|
6462
|
+
res.end(JSON.stringify({ error: "Image editing failed", details: msg }));
|
|
6463
|
+
}
|
|
6464
|
+
}
|
|
6465
|
+
return;
|
|
6466
|
+
}
|
|
6363
6467
|
if (req.url?.match(/^\/v1\/(?:x|partner)\//)) {
|
|
6364
6468
|
try {
|
|
6365
6469
|
await proxyPartnerRequest(req, res, apiBase, payFetch);
|
|
@@ -6974,6 +7078,177 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
6974
7078
|
}
|
|
6975
7079
|
return;
|
|
6976
7080
|
}
|
|
7081
|
+
if (lastContent.startsWith("/img2img")) {
|
|
7082
|
+
const imgArgs = lastContent.slice("/img2img".length).trim();
|
|
7083
|
+
let img2imgModel = "openai/gpt-image-1";
|
|
7084
|
+
let img2imgSize = "1024x1024";
|
|
7085
|
+
let imagePath = null;
|
|
7086
|
+
let maskPath = null;
|
|
7087
|
+
let img2imgPrompt = imgArgs;
|
|
7088
|
+
const imageMatch = imgArgs.match(/--image\s+(\S+)/);
|
|
7089
|
+
if (imageMatch) {
|
|
7090
|
+
imagePath = imageMatch[1];
|
|
7091
|
+
img2imgPrompt = img2imgPrompt.replace(/--image\s+\S+/, "").trim();
|
|
7092
|
+
}
|
|
7093
|
+
const maskMatch = imgArgs.match(/--mask\s+(\S+)/);
|
|
7094
|
+
if (maskMatch) {
|
|
7095
|
+
maskPath = maskMatch[1];
|
|
7096
|
+
img2imgPrompt = img2imgPrompt.replace(/--mask\s+\S+/, "").trim();
|
|
7097
|
+
}
|
|
7098
|
+
const img2imgSizeMatch = imgArgs.match(/--size\s+(\d+x\d+)/);
|
|
7099
|
+
if (img2imgSizeMatch) {
|
|
7100
|
+
img2imgSize = img2imgSizeMatch[1];
|
|
7101
|
+
img2imgPrompt = img2imgPrompt.replace(/--size\s+\d+x\d+/, "").trim();
|
|
7102
|
+
}
|
|
7103
|
+
const img2imgModelMatch = imgArgs.match(/--model\s+(\S+)/);
|
|
7104
|
+
if (img2imgModelMatch) {
|
|
7105
|
+
const raw = img2imgModelMatch[1];
|
|
7106
|
+
const IMG2IMG_ALIASES = {
|
|
7107
|
+
"gpt-image": "openai/gpt-image-1",
|
|
7108
|
+
"gpt-image-1": "openai/gpt-image-1"
|
|
7109
|
+
};
|
|
7110
|
+
img2imgModel = IMG2IMG_ALIASES[raw] ?? raw;
|
|
7111
|
+
img2imgPrompt = img2imgPrompt.replace(/--model\s+\S+/, "").trim();
|
|
7112
|
+
}
|
|
7113
|
+
const usageText = [
|
|
7114
|
+
"Usage: /img2img --image <path> <prompt>",
|
|
7115
|
+
"",
|
|
7116
|
+
"Options:",
|
|
7117
|
+
" --image <path> Source image path (required)",
|
|
7118
|
+
" --mask <path> Mask image path (optional, white = area to edit)",
|
|
7119
|
+
" --model <model> Model (default: gpt-image-1)",
|
|
7120
|
+
" --size <WxH> Output size (default: 1024x1024)",
|
|
7121
|
+
"",
|
|
7122
|
+
"Models:",
|
|
7123
|
+
" gpt-image-1 OpenAI GPT Image 1 \u2014 $0.02/image",
|
|
7124
|
+
"",
|
|
7125
|
+
"Examples:",
|
|
7126
|
+
" /img2img --image ~/photo.png change background to starry sky",
|
|
7127
|
+
" /img2img --image ./cat.jpg --mask ./mask.png remove the background",
|
|
7128
|
+
" /img2img --image /tmp/portrait.png --size 1536x1024 add a hat"
|
|
7129
|
+
].join("\n");
|
|
7130
|
+
const sendImg2ImgText = (text) => {
|
|
7131
|
+
const completionId = `chatcmpl-img2img-${Date.now()}`;
|
|
7132
|
+
const timestamp = Math.floor(Date.now() / 1e3);
|
|
7133
|
+
if (isStreaming) {
|
|
7134
|
+
res.writeHead(200, {
|
|
7135
|
+
"Content-Type": "text/event-stream",
|
|
7136
|
+
"Cache-Control": "no-cache",
|
|
7137
|
+
Connection: "keep-alive"
|
|
7138
|
+
});
|
|
7139
|
+
res.write(
|
|
7140
|
+
`data: ${JSON.stringify({ id: completionId, object: "chat.completion.chunk", created: timestamp, model: "clawrouter/img2img", choices: [{ index: 0, delta: { role: "assistant", content: text }, finish_reason: null }] })}
|
|
7141
|
+
|
|
7142
|
+
`
|
|
7143
|
+
);
|
|
7144
|
+
res.write(
|
|
7145
|
+
`data: ${JSON.stringify({ id: completionId, object: "chat.completion.chunk", created: timestamp, model: "clawrouter/img2img", choices: [{ index: 0, delta: {}, finish_reason: "stop" }] })}
|
|
7146
|
+
|
|
7147
|
+
`
|
|
7148
|
+
);
|
|
7149
|
+
res.write("data: [DONE]\n\n");
|
|
7150
|
+
res.end();
|
|
7151
|
+
} else {
|
|
7152
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
7153
|
+
res.end(
|
|
7154
|
+
JSON.stringify({
|
|
7155
|
+
id: completionId,
|
|
7156
|
+
object: "chat.completion",
|
|
7157
|
+
created: timestamp,
|
|
7158
|
+
model: "clawrouter/img2img",
|
|
7159
|
+
choices: [
|
|
7160
|
+
{
|
|
7161
|
+
index: 0,
|
|
7162
|
+
message: { role: "assistant", content: text },
|
|
7163
|
+
finish_reason: "stop"
|
|
7164
|
+
}
|
|
7165
|
+
],
|
|
7166
|
+
usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 }
|
|
7167
|
+
})
|
|
7168
|
+
);
|
|
7169
|
+
}
|
|
7170
|
+
};
|
|
7171
|
+
if (!imagePath || !img2imgPrompt) {
|
|
7172
|
+
sendImg2ImgText(usageText);
|
|
7173
|
+
return;
|
|
7174
|
+
}
|
|
7175
|
+
let imageDataUri;
|
|
7176
|
+
let maskDataUri;
|
|
7177
|
+
try {
|
|
7178
|
+
imageDataUri = readImageFileAsDataUri(imagePath);
|
|
7179
|
+
if (maskPath) maskDataUri = readImageFileAsDataUri(maskPath);
|
|
7180
|
+
} catch (fileErr) {
|
|
7181
|
+
const fileErrMsg = fileErr instanceof Error ? fileErr.message : String(fileErr);
|
|
7182
|
+
sendImg2ImgText(`Failed to read image file: ${fileErrMsg}`);
|
|
7183
|
+
return;
|
|
7184
|
+
}
|
|
7185
|
+
console.log(
|
|
7186
|
+
`[ClawRouter] /img2img \u2192 ${img2imgModel} (${img2imgSize}): ${img2imgPrompt.slice(0, 80)}`
|
|
7187
|
+
);
|
|
7188
|
+
try {
|
|
7189
|
+
const img2imgBody = JSON.stringify({
|
|
7190
|
+
model: img2imgModel,
|
|
7191
|
+
prompt: img2imgPrompt,
|
|
7192
|
+
image: imageDataUri,
|
|
7193
|
+
...maskDataUri ? { mask: maskDataUri } : {},
|
|
7194
|
+
size: img2imgSize,
|
|
7195
|
+
n: 1
|
|
7196
|
+
});
|
|
7197
|
+
const img2imgResponse = await payFetch(`${apiBase}/v1/images/image2image`, {
|
|
7198
|
+
method: "POST",
|
|
7199
|
+
headers: { "content-type": "application/json", "user-agent": USER_AGENT },
|
|
7200
|
+
body: img2imgBody
|
|
7201
|
+
});
|
|
7202
|
+
const img2imgResult = await img2imgResponse.json();
|
|
7203
|
+
let responseText;
|
|
7204
|
+
if (!img2imgResponse.ok || img2imgResult.error) {
|
|
7205
|
+
const errMsg = typeof img2imgResult.error === "string" ? img2imgResult.error : img2imgResult.error?.message ?? `HTTP ${img2imgResponse.status}`;
|
|
7206
|
+
responseText = `Image editing failed: ${errMsg}`;
|
|
7207
|
+
console.log(`[ClawRouter] /img2img error: ${errMsg}`);
|
|
7208
|
+
} else {
|
|
7209
|
+
const images = img2imgResult.data ?? [];
|
|
7210
|
+
if (images.length === 0) {
|
|
7211
|
+
responseText = "Image editing returned no results.";
|
|
7212
|
+
} else {
|
|
7213
|
+
const lines = [];
|
|
7214
|
+
for (const img of images) {
|
|
7215
|
+
if (img.url) {
|
|
7216
|
+
if (img.url.startsWith("data:")) {
|
|
7217
|
+
try {
|
|
7218
|
+
const hostedUrl = await uploadDataUriToHost(img.url);
|
|
7219
|
+
lines.push(hostedUrl);
|
|
7220
|
+
} catch (uploadErr) {
|
|
7221
|
+
console.error(
|
|
7222
|
+
`[ClawRouter] /img2img: failed to upload data URI: ${uploadErr instanceof Error ? uploadErr.message : String(uploadErr)}`
|
|
7223
|
+
);
|
|
7224
|
+
lines.push("Image edited but upload failed. Try again.");
|
|
7225
|
+
}
|
|
7226
|
+
} else {
|
|
7227
|
+
lines.push(img.url);
|
|
7228
|
+
}
|
|
7229
|
+
}
|
|
7230
|
+
if (img.revised_prompt) lines.push(`Revised prompt: ${img.revised_prompt}`);
|
|
7231
|
+
}
|
|
7232
|
+
lines.push("", `Model: ${img2imgModel} | Size: ${img2imgSize}`);
|
|
7233
|
+
responseText = lines.join("\n");
|
|
7234
|
+
}
|
|
7235
|
+
console.log(`[ClawRouter] /img2img success: ${images.length} image(s)`);
|
|
7236
|
+
}
|
|
7237
|
+
sendImg2ImgText(responseText);
|
|
7238
|
+
} catch (err) {
|
|
7239
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
7240
|
+
console.error(`[ClawRouter] /img2img error: ${errMsg}`);
|
|
7241
|
+
if (!res.headersSent) {
|
|
7242
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
7243
|
+
res.end(
|
|
7244
|
+
JSON.stringify({
|
|
7245
|
+
error: { message: `Image editing failed: ${errMsg}`, type: "img2img_error" }
|
|
7246
|
+
})
|
|
7247
|
+
);
|
|
7248
|
+
}
|
|
7249
|
+
}
|
|
7250
|
+
return;
|
|
7251
|
+
}
|
|
6977
7252
|
if (parsed.stream === true) {
|
|
6978
7253
|
parsed.stream = false;
|
|
6979
7254
|
bodyModified = true;
|
|
@@ -7763,7 +8038,7 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
7763
8038
|
// src/index.ts
|
|
7764
8039
|
import {
|
|
7765
8040
|
writeFileSync as writeFileSync2,
|
|
7766
|
-
existsSync as
|
|
8041
|
+
existsSync as existsSync3,
|
|
7767
8042
|
readdirSync,
|
|
7768
8043
|
mkdirSync as mkdirSync2,
|
|
7769
8044
|
copyFileSync,
|
|
@@ -8205,7 +8480,7 @@ function injectModelsConfig(logger) {
|
|
|
8205
8480
|
const configPath = join7(configDir, "openclaw.json");
|
|
8206
8481
|
let config = {};
|
|
8207
8482
|
let needsWrite = false;
|
|
8208
|
-
if (!
|
|
8483
|
+
if (!existsSync3(configDir)) {
|
|
8209
8484
|
try {
|
|
8210
8485
|
mkdirSync2(configDir, { recursive: true });
|
|
8211
8486
|
logger.info("Created OpenClaw config directory");
|
|
@@ -8216,7 +8491,7 @@ function injectModelsConfig(logger) {
|
|
|
8216
8491
|
return;
|
|
8217
8492
|
}
|
|
8218
8493
|
}
|
|
8219
|
-
if (
|
|
8494
|
+
if (existsSync3(configPath)) {
|
|
8220
8495
|
try {
|
|
8221
8496
|
const content = readTextFileSync(configPath).trim();
|
|
8222
8497
|
if (content) {
|
|
@@ -8364,7 +8639,7 @@ function injectModelsConfig(logger) {
|
|
|
8364
8639
|
}
|
|
8365
8640
|
function injectAuthProfile(logger) {
|
|
8366
8641
|
const agentsDir = join7(homedir6(), ".openclaw", "agents");
|
|
8367
|
-
if (!
|
|
8642
|
+
if (!existsSync3(agentsDir)) {
|
|
8368
8643
|
try {
|
|
8369
8644
|
mkdirSync2(agentsDir, { recursive: true });
|
|
8370
8645
|
} catch (err) {
|
|
@@ -8382,7 +8657,7 @@ function injectAuthProfile(logger) {
|
|
|
8382
8657
|
for (const agentId of agents) {
|
|
8383
8658
|
const authDir = join7(agentsDir, agentId, "agent");
|
|
8384
8659
|
const authPath = join7(authDir, "auth-profiles.json");
|
|
8385
|
-
if (!
|
|
8660
|
+
if (!existsSync3(authDir)) {
|
|
8386
8661
|
try {
|
|
8387
8662
|
mkdirSync2(authDir, { recursive: true });
|
|
8388
8663
|
} catch {
|
|
@@ -8393,7 +8668,7 @@ function injectAuthProfile(logger) {
|
|
|
8393
8668
|
version: 1,
|
|
8394
8669
|
profiles: {}
|
|
8395
8670
|
};
|
|
8396
|
-
if (
|
|
8671
|
+
if (existsSync3(authPath)) {
|
|
8397
8672
|
try {
|
|
8398
8673
|
const existing = JSON.parse(readTextFileSync(authPath));
|
|
8399
8674
|
if (existing.version && existing.profiles) {
|
|
@@ -8537,7 +8812,7 @@ async function createWalletCommand() {
|
|
|
8537
8812
|
let walletKey;
|
|
8538
8813
|
let address;
|
|
8539
8814
|
try {
|
|
8540
|
-
if (
|
|
8815
|
+
if (existsSync3(WALLET_FILE)) {
|
|
8541
8816
|
walletKey = readTextFileSync(WALLET_FILE).trim();
|
|
8542
8817
|
if (walletKey.startsWith("0x") && walletKey.length === 66) {
|
|
8543
8818
|
const account = privateKeyToAccount4(walletKey);
|
|
@@ -8567,7 +8842,7 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
|
|
|
8567
8842
|
];
|
|
8568
8843
|
let hasMnemonic = false;
|
|
8569
8844
|
try {
|
|
8570
|
-
if (
|
|
8845
|
+
if (existsSync3(MNEMONIC_FILE)) {
|
|
8571
8846
|
const mnemonic = readTextFileSync(MNEMONIC_FILE).trim();
|
|
8572
8847
|
if (mnemonic) {
|
|
8573
8848
|
hasMnemonic = true;
|
|
@@ -8609,7 +8884,7 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
|
|
|
8609
8884
|
if (subcommand === "solana") {
|
|
8610
8885
|
try {
|
|
8611
8886
|
let solanaAddr;
|
|
8612
|
-
if (
|
|
8887
|
+
if (existsSync3(MNEMONIC_FILE)) {
|
|
8613
8888
|
const existingMnemonic = readTextFileSync(MNEMONIC_FILE).trim();
|
|
8614
8889
|
if (existingMnemonic) {
|
|
8615
8890
|
await savePaymentChain("solana");
|
|
@@ -8654,7 +8929,7 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
|
|
|
8654
8929
|
}
|
|
8655
8930
|
if (subcommand === "migrate-solana") {
|
|
8656
8931
|
try {
|
|
8657
|
-
if (!
|
|
8932
|
+
if (!existsSync3(MNEMONIC_FILE)) {
|
|
8658
8933
|
return {
|
|
8659
8934
|
text: "No mnemonic file found. Solana wallet not set up \u2014 nothing to migrate.",
|
|
8660
8935
|
isError: true
|
|
@@ -8757,7 +9032,7 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
|
|
|
8757
9032
|
}
|
|
8758
9033
|
let solanaSection = "";
|
|
8759
9034
|
try {
|
|
8760
|
-
if (
|
|
9035
|
+
if (existsSync3(MNEMONIC_FILE)) {
|
|
8761
9036
|
const { deriveSolanaKeyBytes: deriveSolanaKeyBytes2 } = await Promise.resolve().then(() => (init_wallet(), wallet_exports));
|
|
8762
9037
|
const mnemonic = readTextFileSync(MNEMONIC_FILE).trim();
|
|
8763
9038
|
if (mnemonic) {
|