@wiimdy/openfunderse 1.1.2 → 1.1.3
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/bin/openfunderse.mjs +28 -77
- package/package.json +4 -1
package/bin/openfunderse.mjs
CHANGED
|
@@ -7,6 +7,7 @@ import os from "node:os";
|
|
|
7
7
|
import path from "node:path";
|
|
8
8
|
import { createInterface } from "node:readline/promises";
|
|
9
9
|
import { fileURLToPath } from "node:url";
|
|
10
|
+
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
|
|
10
11
|
|
|
11
12
|
const THIS_FILE = fileURLToPath(import.meta.url);
|
|
12
13
|
const PACKAGE_ROOT = path.resolve(path.dirname(THIS_FILE), "..");
|
|
@@ -418,43 +419,6 @@ function shellQuote(input) {
|
|
|
418
419
|
return `'${input.replace(/'/g, `'\\''`)}'`;
|
|
419
420
|
}
|
|
420
421
|
|
|
421
|
-
async function runCommandCapture(cmd, args, cwd = process.cwd()) {
|
|
422
|
-
return await new Promise((resolve, reject) => {
|
|
423
|
-
const child = spawn(cmd, args, {
|
|
424
|
-
cwd,
|
|
425
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
426
|
-
});
|
|
427
|
-
|
|
428
|
-
const stdout = [];
|
|
429
|
-
const stderr = [];
|
|
430
|
-
|
|
431
|
-
child.stdout.on("data", (chunk) => {
|
|
432
|
-
stdout.push(chunk);
|
|
433
|
-
});
|
|
434
|
-
child.stderr.on("data", (chunk) => {
|
|
435
|
-
stderr.push(chunk);
|
|
436
|
-
});
|
|
437
|
-
child.on("error", (error) => {
|
|
438
|
-
reject(error);
|
|
439
|
-
});
|
|
440
|
-
child.on("exit", (code) => {
|
|
441
|
-
if (code === 0) {
|
|
442
|
-
resolve({
|
|
443
|
-
stdout: Buffer.concat(stdout).toString("utf8"),
|
|
444
|
-
stderr: Buffer.concat(stderr).toString("utf8")
|
|
445
|
-
});
|
|
446
|
-
return;
|
|
447
|
-
}
|
|
448
|
-
const stderrText = Buffer.concat(stderr).toString("utf8").trim();
|
|
449
|
-
reject(
|
|
450
|
-
new Error(
|
|
451
|
-
`command failed: ${cmd} ${args.join(" ")} (exit ${code})${stderrText ? ` - ${stderrText}` : ""}`
|
|
452
|
-
)
|
|
453
|
-
);
|
|
454
|
-
});
|
|
455
|
-
});
|
|
456
|
-
}
|
|
457
|
-
|
|
458
422
|
async function confirmBotInit({ role, envFile, privateKeyKey, isRotation, assumeYes }) {
|
|
459
423
|
const mode = isRotation ? "wallet rotation" : "new wallet bootstrap";
|
|
460
424
|
console.log("WARNING: bot-init will generate a new wallet and update your env private key.");
|
|
@@ -486,39 +450,11 @@ async function confirmBotInit({ role, envFile, privateKeyKey, isRotation, assume
|
|
|
486
450
|
}
|
|
487
451
|
}
|
|
488
452
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
output = await runCommandCapture("cast", ["wallet", "new", "--json"]);
|
|
493
|
-
} catch (error) {
|
|
494
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
495
|
-
if (message.includes("ENOENT")) {
|
|
496
|
-
throw new Error(
|
|
497
|
-
"cast is not installed. Install Foundry first (https://book.getfoundry.sh/getting-started/installation)."
|
|
498
|
-
);
|
|
499
|
-
}
|
|
500
|
-
throw error;
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
let parsed;
|
|
504
|
-
try {
|
|
505
|
-
parsed = JSON.parse(output.stdout);
|
|
506
|
-
} catch {
|
|
507
|
-
throw new Error(`failed to parse cast output as JSON: ${output.stdout}`);
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
const first = Array.isArray(parsed) ? parsed[0] : parsed;
|
|
511
|
-
const address = String(first?.address ?? "");
|
|
512
|
-
const privateKey = String(first?.private_key ?? first?.privateKey ?? "");
|
|
513
|
-
if (!/^0x[0-9a-fA-F]{40}$/.test(address)) {
|
|
514
|
-
throw new Error(`invalid wallet address from cast: ${address}`);
|
|
515
|
-
}
|
|
516
|
-
if (!/^0x[0-9a-fA-F]{64}$/.test(privateKey)) {
|
|
517
|
-
throw new Error("invalid private key from cast output");
|
|
518
|
-
}
|
|
519
|
-
|
|
453
|
+
function generateMonadWalletWithViem() {
|
|
454
|
+
const privateKey = generatePrivateKey();
|
|
455
|
+
const account = privateKeyToAccount(privateKey);
|
|
520
456
|
return {
|
|
521
|
-
address,
|
|
457
|
+
address: account.address,
|
|
522
458
|
privateKey
|
|
523
459
|
};
|
|
524
460
|
}
|
|
@@ -551,10 +487,13 @@ async function persistWallet(role, wallet, options) {
|
|
|
551
487
|
if (rawName.includes("/") || rawName.includes("\\")) {
|
|
552
488
|
throw new Error("--wallet-name must be a file name, not a path");
|
|
553
489
|
}
|
|
554
|
-
const
|
|
555
|
-
const walletPath = path.join(walletDir,
|
|
556
|
-
|
|
557
|
-
|
|
490
|
+
const baseName = rawName.endsWith(".json") ? rawName.slice(0, -".json".length) : rawName;
|
|
491
|
+
const walletPath = path.join(walletDir, `${baseName}.json`);
|
|
492
|
+
const privateKeyPath = path.join(walletDir, `${baseName}.private-key`);
|
|
493
|
+
if ((existsSync(walletPath) || existsSync(privateKeyPath)) && !options.force) {
|
|
494
|
+
throw new Error(
|
|
495
|
+
`wallet file already exists: ${walletPath} or ${privateKeyPath} (use --force to overwrite)`
|
|
496
|
+
);
|
|
558
497
|
}
|
|
559
498
|
|
|
560
499
|
const payload = {
|
|
@@ -565,11 +504,22 @@ async function persistWallet(role, wallet, options) {
|
|
|
565
504
|
privateKey: wallet.privateKey
|
|
566
505
|
};
|
|
567
506
|
await mkdir(walletDir, { recursive: true, mode: 0o700 });
|
|
507
|
+
if (options.force) {
|
|
508
|
+
await rm(walletPath, { force: true });
|
|
509
|
+
await rm(privateKeyPath, { force: true });
|
|
510
|
+
}
|
|
568
511
|
await writeFile(walletPath, `${JSON.stringify(payload, null, 2)}\n`, {
|
|
569
512
|
mode: 0o600
|
|
570
513
|
});
|
|
514
|
+
await writeFile(privateKeyPath, `${wallet.privateKey}\n`, {
|
|
515
|
+
mode: 0o600
|
|
516
|
+
});
|
|
571
517
|
await chmod(walletPath, 0o600);
|
|
572
|
-
|
|
518
|
+
await chmod(privateKeyPath, 0o600);
|
|
519
|
+
return {
|
|
520
|
+
walletPath,
|
|
521
|
+
privateKeyPath
|
|
522
|
+
};
|
|
573
523
|
}
|
|
574
524
|
|
|
575
525
|
function assertPrivateKeyRotationAllowed(envContent, role, force) {
|
|
@@ -609,8 +559,8 @@ async function runBotInit(options) {
|
|
|
609
559
|
assumeYes: options.yes
|
|
610
560
|
});
|
|
611
561
|
|
|
612
|
-
const wallet =
|
|
613
|
-
const
|
|
562
|
+
const wallet = generateMonadWalletWithViem();
|
|
563
|
+
const walletFiles = await persistWallet(role, wallet, options);
|
|
614
564
|
const updates = roleEnvUpdates(role, wallet);
|
|
615
565
|
const nextEnvContent = upsertEnvValues(envContent, updates);
|
|
616
566
|
|
|
@@ -622,7 +572,8 @@ async function runBotInit(options) {
|
|
|
622
572
|
console.log(`Initialized ${role} bot wallet for Monad testnet (${DEFAULT_MONAD_CHAIN_ID}).`);
|
|
623
573
|
console.log(`Address: ${wallet.address}`);
|
|
624
574
|
console.log(`Env file updated: ${envFile}`);
|
|
625
|
-
console.log(`Wallet backup (keep secret): ${walletPath}`);
|
|
575
|
+
console.log(`Wallet backup (keep secret): ${walletFiles.walletPath}`);
|
|
576
|
+
console.log(`Private key backup (keep secret): ${walletFiles.privateKeyPath}`);
|
|
626
577
|
console.log(`Load env now: ${sourceCommand}`);
|
|
627
578
|
}
|
|
628
579
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wiimdy/openfunderse",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "Install OpenFunderse skill packs into Codex",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
"packs",
|
|
12
12
|
"README.md"
|
|
13
13
|
],
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"viem": "^2.38.2"
|
|
16
|
+
},
|
|
14
17
|
"engines": {
|
|
15
18
|
"node": ">=20"
|
|
16
19
|
},
|