@blockrun/clawrouter 0.12.32 → 0.12.34
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 +41 -12
- package/dist/cli.js +288 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.js +299 -12
- 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");
|
|
@@ -6358,7 +6375,9 @@ async function startProxy(options) {
|
|
|
6358
6375
|
console.log(`[ClawRouter] Image downloaded & saved \u2192 ${img.url}`);
|
|
6359
6376
|
}
|
|
6360
6377
|
} catch (downloadErr) {
|
|
6361
|
-
console.warn(
|
|
6378
|
+
console.warn(
|
|
6379
|
+
`[ClawRouter] Failed to download image, using original URL: ${downloadErr instanceof Error ? downloadErr.message : String(downloadErr)}`
|
|
6380
|
+
);
|
|
6362
6381
|
}
|
|
6363
6382
|
}
|
|
6364
6383
|
}
|
|
@@ -6375,6 +6394,103 @@ async function startProxy(options) {
|
|
|
6375
6394
|
}
|
|
6376
6395
|
return;
|
|
6377
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 rawBody = Buffer.concat(chunks);
|
|
6403
|
+
let reqBody;
|
|
6404
|
+
try {
|
|
6405
|
+
const parsed = JSON.parse(rawBody.toString());
|
|
6406
|
+
for (const field of ["image", "mask"]) {
|
|
6407
|
+
const val = parsed[field];
|
|
6408
|
+
if (typeof val !== "string" || !val) continue;
|
|
6409
|
+
if (val.startsWith("data:")) {
|
|
6410
|
+
} else if (val.startsWith("https://") || val.startsWith("http://")) {
|
|
6411
|
+
const imgResp = await fetch(val);
|
|
6412
|
+
if (!imgResp.ok) throw new Error(`Failed to download ${field} from ${val}: HTTP ${imgResp.status}`);
|
|
6413
|
+
const contentType = imgResp.headers.get("content-type") ?? "image/png";
|
|
6414
|
+
const buf = Buffer.from(await imgResp.arrayBuffer());
|
|
6415
|
+
parsed[field] = `data:${contentType};base64,${buf.toString("base64")}`;
|
|
6416
|
+
console.log(`[ClawRouter] img2img: downloaded ${field} URL \u2192 data URI (${buf.length} bytes)`);
|
|
6417
|
+
} else {
|
|
6418
|
+
parsed[field] = readImageFileAsDataUri(val);
|
|
6419
|
+
console.log(`[ClawRouter] img2img: read ${field} file \u2192 data URI`);
|
|
6420
|
+
}
|
|
6421
|
+
}
|
|
6422
|
+
if (!parsed.model) parsed.model = "openai/gpt-image-1";
|
|
6423
|
+
reqBody = JSON.stringify(parsed);
|
|
6424
|
+
} catch (parseErr) {
|
|
6425
|
+
const msg = parseErr instanceof Error ? parseErr.message : String(parseErr);
|
|
6426
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
6427
|
+
res.end(JSON.stringify({ error: "Invalid request", details: msg }));
|
|
6428
|
+
return;
|
|
6429
|
+
}
|
|
6430
|
+
try {
|
|
6431
|
+
const upstream = await payFetch(`${apiBase}/v1/images/image2image`, {
|
|
6432
|
+
method: "POST",
|
|
6433
|
+
headers: { "content-type": "application/json", "user-agent": USER_AGENT },
|
|
6434
|
+
body: reqBody
|
|
6435
|
+
});
|
|
6436
|
+
const text = await upstream.text();
|
|
6437
|
+
if (!upstream.ok) {
|
|
6438
|
+
res.writeHead(upstream.status, { "Content-Type": "application/json" });
|
|
6439
|
+
res.end(text);
|
|
6440
|
+
return;
|
|
6441
|
+
}
|
|
6442
|
+
let result;
|
|
6443
|
+
try {
|
|
6444
|
+
result = JSON.parse(text);
|
|
6445
|
+
} catch {
|
|
6446
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
6447
|
+
res.end(text);
|
|
6448
|
+
return;
|
|
6449
|
+
}
|
|
6450
|
+
if (result.data?.length) {
|
|
6451
|
+
await mkdir3(IMAGE_DIR, { recursive: true });
|
|
6452
|
+
const port2 = server.address()?.port ?? 8402;
|
|
6453
|
+
for (const img of result.data) {
|
|
6454
|
+
const dataUriMatch = img.url?.match(/^data:(image\/\w+);base64,(.+)$/);
|
|
6455
|
+
if (dataUriMatch) {
|
|
6456
|
+
const [, mimeType, b64] = dataUriMatch;
|
|
6457
|
+
const ext = mimeType === "image/jpeg" ? "jpg" : mimeType.split("/")[1] ?? "png";
|
|
6458
|
+
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
6459
|
+
await writeFile2(join5(IMAGE_DIR, filename), Buffer.from(b64, "base64"));
|
|
6460
|
+
img.url = `http://localhost:${port2}/images/${filename}`;
|
|
6461
|
+
console.log(`[ClawRouter] Image saved \u2192 ${img.url}`);
|
|
6462
|
+
} else if (img.url?.startsWith("https://") || img.url?.startsWith("http://")) {
|
|
6463
|
+
try {
|
|
6464
|
+
const imgResp = await fetch(img.url);
|
|
6465
|
+
if (imgResp.ok) {
|
|
6466
|
+
const contentType = imgResp.headers.get("content-type") ?? "image/png";
|
|
6467
|
+
const ext = contentType.includes("jpeg") || contentType.includes("jpg") ? "jpg" : contentType.includes("webp") ? "webp" : "png";
|
|
6468
|
+
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
6469
|
+
const buf = Buffer.from(await imgResp.arrayBuffer());
|
|
6470
|
+
await writeFile2(join5(IMAGE_DIR, filename), buf);
|
|
6471
|
+
img.url = `http://localhost:${port2}/images/${filename}`;
|
|
6472
|
+
console.log(`[ClawRouter] Image downloaded & saved \u2192 ${img.url}`);
|
|
6473
|
+
}
|
|
6474
|
+
} catch (downloadErr) {
|
|
6475
|
+
console.warn(
|
|
6476
|
+
`[ClawRouter] Failed to download image, using original URL: ${downloadErr instanceof Error ? downloadErr.message : String(downloadErr)}`
|
|
6477
|
+
);
|
|
6478
|
+
}
|
|
6479
|
+
}
|
|
6480
|
+
}
|
|
6481
|
+
}
|
|
6482
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
6483
|
+
res.end(JSON.stringify(result));
|
|
6484
|
+
} catch (err) {
|
|
6485
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6486
|
+
console.error(`[ClawRouter] Image editing error: ${msg}`);
|
|
6487
|
+
if (!res.headersSent) {
|
|
6488
|
+
res.writeHead(502, { "Content-Type": "application/json" });
|
|
6489
|
+
res.end(JSON.stringify({ error: "Image editing failed", details: msg }));
|
|
6490
|
+
}
|
|
6491
|
+
}
|
|
6492
|
+
return;
|
|
6493
|
+
}
|
|
6378
6494
|
if (req.url?.match(/^\/v1\/(?:x|partner)\//)) {
|
|
6379
6495
|
try {
|
|
6380
6496
|
await proxyPartnerRequest(req, res, apiBase, payFetch);
|
|
@@ -6989,6 +7105,177 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
6989
7105
|
}
|
|
6990
7106
|
return;
|
|
6991
7107
|
}
|
|
7108
|
+
if (lastContent.startsWith("/img2img")) {
|
|
7109
|
+
const imgArgs = lastContent.slice("/img2img".length).trim();
|
|
7110
|
+
let img2imgModel = "openai/gpt-image-1";
|
|
7111
|
+
let img2imgSize = "1024x1024";
|
|
7112
|
+
let imagePath = null;
|
|
7113
|
+
let maskPath = null;
|
|
7114
|
+
let img2imgPrompt = imgArgs;
|
|
7115
|
+
const imageMatch = imgArgs.match(/--image\s+(\S+)/);
|
|
7116
|
+
if (imageMatch) {
|
|
7117
|
+
imagePath = imageMatch[1];
|
|
7118
|
+
img2imgPrompt = img2imgPrompt.replace(/--image\s+\S+/, "").trim();
|
|
7119
|
+
}
|
|
7120
|
+
const maskMatch = imgArgs.match(/--mask\s+(\S+)/);
|
|
7121
|
+
if (maskMatch) {
|
|
7122
|
+
maskPath = maskMatch[1];
|
|
7123
|
+
img2imgPrompt = img2imgPrompt.replace(/--mask\s+\S+/, "").trim();
|
|
7124
|
+
}
|
|
7125
|
+
const img2imgSizeMatch = imgArgs.match(/--size\s+(\d+x\d+)/);
|
|
7126
|
+
if (img2imgSizeMatch) {
|
|
7127
|
+
img2imgSize = img2imgSizeMatch[1];
|
|
7128
|
+
img2imgPrompt = img2imgPrompt.replace(/--size\s+\d+x\d+/, "").trim();
|
|
7129
|
+
}
|
|
7130
|
+
const img2imgModelMatch = imgArgs.match(/--model\s+(\S+)/);
|
|
7131
|
+
if (img2imgModelMatch) {
|
|
7132
|
+
const raw = img2imgModelMatch[1];
|
|
7133
|
+
const IMG2IMG_ALIASES = {
|
|
7134
|
+
"gpt-image": "openai/gpt-image-1",
|
|
7135
|
+
"gpt-image-1": "openai/gpt-image-1"
|
|
7136
|
+
};
|
|
7137
|
+
img2imgModel = IMG2IMG_ALIASES[raw] ?? raw;
|
|
7138
|
+
img2imgPrompt = img2imgPrompt.replace(/--model\s+\S+/, "").trim();
|
|
7139
|
+
}
|
|
7140
|
+
const usageText = [
|
|
7141
|
+
"Usage: /img2img --image <path> <prompt>",
|
|
7142
|
+
"",
|
|
7143
|
+
"Options:",
|
|
7144
|
+
" --image <path> Source image path (required)",
|
|
7145
|
+
" --mask <path> Mask image path (optional, white = area to edit)",
|
|
7146
|
+
" --model <model> Model (default: gpt-image-1)",
|
|
7147
|
+
" --size <WxH> Output size (default: 1024x1024)",
|
|
7148
|
+
"",
|
|
7149
|
+
"Models:",
|
|
7150
|
+
" gpt-image-1 OpenAI GPT Image 1 \u2014 $0.02/image",
|
|
7151
|
+
"",
|
|
7152
|
+
"Examples:",
|
|
7153
|
+
" /img2img --image ~/photo.png change background to starry sky",
|
|
7154
|
+
" /img2img --image ./cat.jpg --mask ./mask.png remove the background",
|
|
7155
|
+
" /img2img --image /tmp/portrait.png --size 1536x1024 add a hat"
|
|
7156
|
+
].join("\n");
|
|
7157
|
+
const sendImg2ImgText = (text) => {
|
|
7158
|
+
const completionId = `chatcmpl-img2img-${Date.now()}`;
|
|
7159
|
+
const timestamp = Math.floor(Date.now() / 1e3);
|
|
7160
|
+
if (isStreaming) {
|
|
7161
|
+
res.writeHead(200, {
|
|
7162
|
+
"Content-Type": "text/event-stream",
|
|
7163
|
+
"Cache-Control": "no-cache",
|
|
7164
|
+
Connection: "keep-alive"
|
|
7165
|
+
});
|
|
7166
|
+
res.write(
|
|
7167
|
+
`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 }] })}
|
|
7168
|
+
|
|
7169
|
+
`
|
|
7170
|
+
);
|
|
7171
|
+
res.write(
|
|
7172
|
+
`data: ${JSON.stringify({ id: completionId, object: "chat.completion.chunk", created: timestamp, model: "clawrouter/img2img", choices: [{ index: 0, delta: {}, finish_reason: "stop" }] })}
|
|
7173
|
+
|
|
7174
|
+
`
|
|
7175
|
+
);
|
|
7176
|
+
res.write("data: [DONE]\n\n");
|
|
7177
|
+
res.end();
|
|
7178
|
+
} else {
|
|
7179
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
7180
|
+
res.end(
|
|
7181
|
+
JSON.stringify({
|
|
7182
|
+
id: completionId,
|
|
7183
|
+
object: "chat.completion",
|
|
7184
|
+
created: timestamp,
|
|
7185
|
+
model: "clawrouter/img2img",
|
|
7186
|
+
choices: [
|
|
7187
|
+
{
|
|
7188
|
+
index: 0,
|
|
7189
|
+
message: { role: "assistant", content: text },
|
|
7190
|
+
finish_reason: "stop"
|
|
7191
|
+
}
|
|
7192
|
+
],
|
|
7193
|
+
usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 }
|
|
7194
|
+
})
|
|
7195
|
+
);
|
|
7196
|
+
}
|
|
7197
|
+
};
|
|
7198
|
+
if (!imagePath || !img2imgPrompt) {
|
|
7199
|
+
sendImg2ImgText(usageText);
|
|
7200
|
+
return;
|
|
7201
|
+
}
|
|
7202
|
+
let imageDataUri;
|
|
7203
|
+
let maskDataUri;
|
|
7204
|
+
try {
|
|
7205
|
+
imageDataUri = readImageFileAsDataUri(imagePath);
|
|
7206
|
+
if (maskPath) maskDataUri = readImageFileAsDataUri(maskPath);
|
|
7207
|
+
} catch (fileErr) {
|
|
7208
|
+
const fileErrMsg = fileErr instanceof Error ? fileErr.message : String(fileErr);
|
|
7209
|
+
sendImg2ImgText(`Failed to read image file: ${fileErrMsg}`);
|
|
7210
|
+
return;
|
|
7211
|
+
}
|
|
7212
|
+
console.log(
|
|
7213
|
+
`[ClawRouter] /img2img \u2192 ${img2imgModel} (${img2imgSize}): ${img2imgPrompt.slice(0, 80)}`
|
|
7214
|
+
);
|
|
7215
|
+
try {
|
|
7216
|
+
const img2imgBody = JSON.stringify({
|
|
7217
|
+
model: img2imgModel,
|
|
7218
|
+
prompt: img2imgPrompt,
|
|
7219
|
+
image: imageDataUri,
|
|
7220
|
+
...maskDataUri ? { mask: maskDataUri } : {},
|
|
7221
|
+
size: img2imgSize,
|
|
7222
|
+
n: 1
|
|
7223
|
+
});
|
|
7224
|
+
const img2imgResponse = await payFetch(`${apiBase}/v1/images/image2image`, {
|
|
7225
|
+
method: "POST",
|
|
7226
|
+
headers: { "content-type": "application/json", "user-agent": USER_AGENT },
|
|
7227
|
+
body: img2imgBody
|
|
7228
|
+
});
|
|
7229
|
+
const img2imgResult = await img2imgResponse.json();
|
|
7230
|
+
let responseText;
|
|
7231
|
+
if (!img2imgResponse.ok || img2imgResult.error) {
|
|
7232
|
+
const errMsg = typeof img2imgResult.error === "string" ? img2imgResult.error : img2imgResult.error?.message ?? `HTTP ${img2imgResponse.status}`;
|
|
7233
|
+
responseText = `Image editing failed: ${errMsg}`;
|
|
7234
|
+
console.log(`[ClawRouter] /img2img error: ${errMsg}`);
|
|
7235
|
+
} else {
|
|
7236
|
+
const images = img2imgResult.data ?? [];
|
|
7237
|
+
if (images.length === 0) {
|
|
7238
|
+
responseText = "Image editing returned no results.";
|
|
7239
|
+
} else {
|
|
7240
|
+
const lines = [];
|
|
7241
|
+
for (const img of images) {
|
|
7242
|
+
if (img.url) {
|
|
7243
|
+
if (img.url.startsWith("data:")) {
|
|
7244
|
+
try {
|
|
7245
|
+
const hostedUrl = await uploadDataUriToHost(img.url);
|
|
7246
|
+
lines.push(hostedUrl);
|
|
7247
|
+
} catch (uploadErr) {
|
|
7248
|
+
console.error(
|
|
7249
|
+
`[ClawRouter] /img2img: failed to upload data URI: ${uploadErr instanceof Error ? uploadErr.message : String(uploadErr)}`
|
|
7250
|
+
);
|
|
7251
|
+
lines.push("Image edited but upload failed. Try again.");
|
|
7252
|
+
}
|
|
7253
|
+
} else {
|
|
7254
|
+
lines.push(img.url);
|
|
7255
|
+
}
|
|
7256
|
+
}
|
|
7257
|
+
if (img.revised_prompt) lines.push(`Revised prompt: ${img.revised_prompt}`);
|
|
7258
|
+
}
|
|
7259
|
+
lines.push("", `Model: ${img2imgModel} | Size: ${img2imgSize}`);
|
|
7260
|
+
responseText = lines.join("\n");
|
|
7261
|
+
}
|
|
7262
|
+
console.log(`[ClawRouter] /img2img success: ${images.length} image(s)`);
|
|
7263
|
+
}
|
|
7264
|
+
sendImg2ImgText(responseText);
|
|
7265
|
+
} catch (err) {
|
|
7266
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
7267
|
+
console.error(`[ClawRouter] /img2img error: ${errMsg}`);
|
|
7268
|
+
if (!res.headersSent) {
|
|
7269
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
7270
|
+
res.end(
|
|
7271
|
+
JSON.stringify({
|
|
7272
|
+
error: { message: `Image editing failed: ${errMsg}`, type: "img2img_error" }
|
|
7273
|
+
})
|
|
7274
|
+
);
|
|
7275
|
+
}
|
|
7276
|
+
}
|
|
7277
|
+
return;
|
|
7278
|
+
}
|
|
6992
7279
|
if (parsed.stream === true) {
|
|
6993
7280
|
parsed.stream = false;
|
|
6994
7281
|
bodyModified = true;
|
|
@@ -7778,7 +8065,7 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
7778
8065
|
// src/index.ts
|
|
7779
8066
|
import {
|
|
7780
8067
|
writeFileSync as writeFileSync2,
|
|
7781
|
-
existsSync as
|
|
8068
|
+
existsSync as existsSync3,
|
|
7782
8069
|
readdirSync,
|
|
7783
8070
|
mkdirSync as mkdirSync2,
|
|
7784
8071
|
copyFileSync,
|
|
@@ -8220,7 +8507,7 @@ function injectModelsConfig(logger) {
|
|
|
8220
8507
|
const configPath = join7(configDir, "openclaw.json");
|
|
8221
8508
|
let config = {};
|
|
8222
8509
|
let needsWrite = false;
|
|
8223
|
-
if (!
|
|
8510
|
+
if (!existsSync3(configDir)) {
|
|
8224
8511
|
try {
|
|
8225
8512
|
mkdirSync2(configDir, { recursive: true });
|
|
8226
8513
|
logger.info("Created OpenClaw config directory");
|
|
@@ -8231,7 +8518,7 @@ function injectModelsConfig(logger) {
|
|
|
8231
8518
|
return;
|
|
8232
8519
|
}
|
|
8233
8520
|
}
|
|
8234
|
-
if (
|
|
8521
|
+
if (existsSync3(configPath)) {
|
|
8235
8522
|
try {
|
|
8236
8523
|
const content = readTextFileSync(configPath).trim();
|
|
8237
8524
|
if (content) {
|
|
@@ -8379,7 +8666,7 @@ function injectModelsConfig(logger) {
|
|
|
8379
8666
|
}
|
|
8380
8667
|
function injectAuthProfile(logger) {
|
|
8381
8668
|
const agentsDir = join7(homedir6(), ".openclaw", "agents");
|
|
8382
|
-
if (!
|
|
8669
|
+
if (!existsSync3(agentsDir)) {
|
|
8383
8670
|
try {
|
|
8384
8671
|
mkdirSync2(agentsDir, { recursive: true });
|
|
8385
8672
|
} catch (err) {
|
|
@@ -8397,7 +8684,7 @@ function injectAuthProfile(logger) {
|
|
|
8397
8684
|
for (const agentId of agents) {
|
|
8398
8685
|
const authDir = join7(agentsDir, agentId, "agent");
|
|
8399
8686
|
const authPath = join7(authDir, "auth-profiles.json");
|
|
8400
|
-
if (!
|
|
8687
|
+
if (!existsSync3(authDir)) {
|
|
8401
8688
|
try {
|
|
8402
8689
|
mkdirSync2(authDir, { recursive: true });
|
|
8403
8690
|
} catch {
|
|
@@ -8408,7 +8695,7 @@ function injectAuthProfile(logger) {
|
|
|
8408
8695
|
version: 1,
|
|
8409
8696
|
profiles: {}
|
|
8410
8697
|
};
|
|
8411
|
-
if (
|
|
8698
|
+
if (existsSync3(authPath)) {
|
|
8412
8699
|
try {
|
|
8413
8700
|
const existing = JSON.parse(readTextFileSync(authPath));
|
|
8414
8701
|
if (existing.version && existing.profiles) {
|
|
@@ -8552,7 +8839,7 @@ async function createWalletCommand() {
|
|
|
8552
8839
|
let walletKey;
|
|
8553
8840
|
let address;
|
|
8554
8841
|
try {
|
|
8555
|
-
if (
|
|
8842
|
+
if (existsSync3(WALLET_FILE)) {
|
|
8556
8843
|
walletKey = readTextFileSync(WALLET_FILE).trim();
|
|
8557
8844
|
if (walletKey.startsWith("0x") && walletKey.length === 66) {
|
|
8558
8845
|
const account = privateKeyToAccount4(walletKey);
|
|
@@ -8582,7 +8869,7 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
|
|
|
8582
8869
|
];
|
|
8583
8870
|
let hasMnemonic = false;
|
|
8584
8871
|
try {
|
|
8585
|
-
if (
|
|
8872
|
+
if (existsSync3(MNEMONIC_FILE)) {
|
|
8586
8873
|
const mnemonic = readTextFileSync(MNEMONIC_FILE).trim();
|
|
8587
8874
|
if (mnemonic) {
|
|
8588
8875
|
hasMnemonic = true;
|
|
@@ -8624,7 +8911,7 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
|
|
|
8624
8911
|
if (subcommand === "solana") {
|
|
8625
8912
|
try {
|
|
8626
8913
|
let solanaAddr;
|
|
8627
|
-
if (
|
|
8914
|
+
if (existsSync3(MNEMONIC_FILE)) {
|
|
8628
8915
|
const existingMnemonic = readTextFileSync(MNEMONIC_FILE).trim();
|
|
8629
8916
|
if (existingMnemonic) {
|
|
8630
8917
|
await savePaymentChain("solana");
|
|
@@ -8669,7 +8956,7 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
|
|
|
8669
8956
|
}
|
|
8670
8957
|
if (subcommand === "migrate-solana") {
|
|
8671
8958
|
try {
|
|
8672
|
-
if (!
|
|
8959
|
+
if (!existsSync3(MNEMONIC_FILE)) {
|
|
8673
8960
|
return {
|
|
8674
8961
|
text: "No mnemonic file found. Solana wallet not set up \u2014 nothing to migrate.",
|
|
8675
8962
|
isError: true
|
|
@@ -8772,7 +9059,7 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
|
|
|
8772
9059
|
}
|
|
8773
9060
|
let solanaSection = "";
|
|
8774
9061
|
try {
|
|
8775
|
-
if (
|
|
9062
|
+
if (existsSync3(MNEMONIC_FILE)) {
|
|
8776
9063
|
const { deriveSolanaKeyBytes: deriveSolanaKeyBytes2 } = await Promise.resolve().then(() => (init_wallet(), wallet_exports));
|
|
8777
9064
|
const mnemonic = readTextFileSync(MNEMONIC_FILE).trim();
|
|
8778
9065
|
if (mnemonic) {
|