@fased/fased 0.1.60 → 0.1.62
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/CHANGELOG.md +22 -0
- package/dist/acp/client.js +2 -2
- package/dist/acp/secret-file.js +2 -2
- package/dist/agents/agent-scope.js +2 -2
- package/dist/agents/apply-patch.js +8 -8
- package/dist/agents/auth-profiles/paths.js +2 -2
- package/dist/agents/auth-profiles/store.js +2 -2
- package/dist/agents/bash-tools.shared.js +2 -2
- package/dist/agents/cli-credentials.js +4 -4
- package/dist/agents/docs-path.js +3 -3
- package/dist/agents/embedded-pi-mcp.js +4 -4
- package/dist/agents/identity-avatar.js +3 -3
- package/dist/agents/identity-file.js +2 -2
- package/dist/agents/openai-codex-app-server.js +5 -5
- package/dist/agents/pi-embedded-subscribe.raw-stream.js +3 -3
- package/dist/agents/pi-extensions/compaction-safeguard.js +3 -3
- package/dist/agents/pi-model-discovery.js +6 -6
- package/dist/agents/pi-project-settings.js +3 -3
- package/dist/agents/sandbox/fs-bridge.js +2 -2
- package/dist/agents/session-dirs.js +4 -4
- package/dist/agents/session-write-lock.js +13 -13
- package/dist/agents/shell-utils.js +5 -5
- package/dist/agents/skills/bundled-dir.js +4 -4
- package/dist/agents/skills/local-loader.js +6 -6
- package/dist/agents/skills/plugin-skills.js +2 -2
- package/dist/agents/skills/workspace.js +13 -13
- package/dist/agents/skills-install-download.js +7 -7
- package/dist/agents/skills-install-plan.js +2 -2
- package/dist/agents/skills-install.js +2 -2
- package/dist/agents/skills-status.js +2 -2
- package/dist/agents/subagent-depth.js +2 -2
- package/dist/agents/system-prompt-params.js +2 -2
- package/dist/agents/workspace.js +22 -22
- package/dist/auto-reply/reply/agent-runner-execution.js +2 -2
- package/dist/auto-reply/reply/agent-runner.js +2 -2
- package/dist/auto-reply/reply/commands-export-session.js +7 -7
- package/dist/auto-reply/reply/post-compaction-audit.js +3 -3
- package/dist/auto-reply/reply/post-compaction-context.js +3 -3
- package/dist/auto-reply/reply/session.js +3 -3
- package/dist/auto-reply/skill-commands.js +3 -3
- package/dist/auto-reply/status.js +6 -6
- package/dist/brand.js +1 -1
- package/dist/browser/chrome.executables.js +3 -3
- package/dist/browser/chrome.js +3 -3
- package/dist/browser/chrome.profile-decoration.js +6 -6
- package/dist/browser/profiles-service.js +2 -2
- package/dist/browser/server-context.js +2 -2
- package/dist/browser/trash.js +4 -4
- package/dist/build-info.json +3 -3
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/canvas-host/server.js +4 -4
- package/dist/capabilities/catalog.js +3 -3
- package/dist/channels/plugins/catalog.js +3 -3
- package/dist/cli/browser-cli-extension.js +6 -6
- package/dist/cli/command-format.js +2 -2
- package/dist/cli/cron-cli/register.cron-simple.js +2 -2
- package/dist/cli/dns-cli.js +9 -9
- package/dist/cli/gateway-cli/dev.js +5 -5
- package/dist/cli/gateway-cli/run.js +2 -2
- package/dist/cli/hooks-cli.js +5 -5
- package/dist/cli/lightweight/gateway-runtime-probe.js +2 -2
- package/dist/cli/memory-cli.js +7 -7
- package/dist/cli/nodes-media-utils.js +2 -2
- package/dist/cli/plugins-cli.js +2 -2
- package/dist/cli/secrets-cli.js +3 -3
- package/dist/cli/windows-argv.js +2 -2
- package/dist/commands/dashboard-link.js +3 -3
- package/dist/commands/doctor-install.js +5 -5
- package/dist/commands/doctor-memory-search.js +2 -2
- package/dist/commands/doctor-platform-notes.js +2 -2
- package/dist/commands/doctor-sandbox.js +2 -2
- package/dist/commands/doctor-state-integrity.js +23 -23
- package/dist/commands/doctor-workspace.js +3 -3
- package/dist/commands/doctor.js +3 -3
- package/dist/commands/managed-up.js +2 -2
- package/dist/commands/onboard-auth.credentials.js +3 -3
- package/dist/commands/onboarding/plugin-install.js +2 -2
- package/dist/commands/sessions-cleanup.js +2 -2
- package/dist/commands/signal-install.js +6 -6
- package/dist/commands/status-all/channels.js +2 -2
- package/dist/commands/wallet.js +47 -47
- package/dist/config/cache-utils.js +2 -2
- package/dist/config/includes.js +5 -5
- package/dist/config/io.js +2 -2
- package/dist/config/paths.js +3 -3
- package/dist/config/sat-runtime-ids.js +3 -3
- package/dist/config/sessions/disk-budget.js +6 -6
- package/dist/config/sessions/paths.js +2 -2
- package/dist/config/sessions/store.js +17 -17
- package/dist/config/sessions/transcript.js +4 -4
- package/dist/config/talk.js +2 -2
- package/dist/control-ui/assets/{app-CqF4Tc9n.js → app-DLil9VO1.js} +3 -3
- package/dist/control-ui/assets/{index-DYggPSfy.js → index-DdE_NIXo.js} +3 -3
- package/dist/control-ui/index.html +1 -1
- package/dist/control-ui/version.json +1 -1
- package/dist/cron/service/store.js +2 -2
- package/dist/cron/store.js +6 -6
- package/dist/daemon/systemd-system.js +5 -5
- package/dist/discord/monitor/thread-bindings.state.js +2 -2
- package/dist/extensions/sat-mining/src/sat-bond-layout.js +9 -9
- package/dist/gateway/control-ui-boot-check.js +6 -6
- package/dist/gateway/control-ui-login.js +7 -7
- package/dist/gateway/control-ui.js +9 -9
- package/dist/gateway/hooks-mapping.js +4 -4
- package/dist/gateway/server-discovery.js +2 -2
- package/dist/gateway/server-http.js +4 -4
- package/dist/gateway/server-methods/chat.js +3 -3
- package/dist/gateway/server-methods/sessions.js +6 -6
- package/dist/gateway/server-methods/usage.js +2 -2
- package/dist/gateway/server.impl.js +3 -3
- package/dist/gateway/session-compaction-checkpoints.js +4 -4
- package/dist/gateway/session-utils.fs.js +24 -24
- package/dist/gateway/session-utils.js +6 -6
- package/dist/hooks/bundled-dir.js +4 -4
- package/dist/hooks/gmail-setup-utils.js +6 -6
- package/dist/hooks/import-url.js +2 -2
- package/dist/hooks/loader.js +4 -4
- package/dist/hooks/workspace.js +7 -7
- package/dist/infra/archive.js +17 -17
- package/dist/infra/boundary-file-read.js +2 -2
- package/dist/infra/boundary-path.js +15 -15
- package/dist/infra/brew.js +2 -2
- package/dist/infra/control-ui-assets.js +14 -14
- package/dist/infra/device-auth-store.js +8 -8
- package/dist/infra/device-identity.js +8 -8
- package/dist/infra/dotenv.js +2 -2
- package/dist/infra/exec-approvals.js +8 -8
- package/dist/infra/exec-command-resolution.js +4 -4
- package/dist/infra/exec-safe-bin-trust.js +2 -2
- package/dist/infra/fased-root.js +5 -5
- package/dist/infra/fs-safe.js +14 -14
- package/dist/infra/gateway-lock.js +11 -11
- package/dist/infra/git-commit.js +5 -5
- package/dist/infra/git-root.js +4 -4
- package/dist/infra/hosted-runtime-artifact.js +3 -3
- package/dist/infra/is-main.js +2 -2
- package/dist/infra/json-file.js +7 -7
- package/dist/infra/managed-runtime-bootstrap.js +6 -6
- package/dist/infra/outbound/delivery-queue.js +16 -16
- package/dist/infra/path-env.js +3 -3
- package/dist/infra/ports-lsof.js +4 -4
- package/dist/infra/provider-usage.auth.js +3 -3
- package/dist/infra/safe-open-sync.js +2 -2
- package/dist/infra/session-cost-usage.js +9 -9
- package/dist/infra/shell-env.js +2 -2
- package/dist/infra/state-migrations.fs.js +6 -6
- package/dist/infra/state-migrations.js +23 -23
- package/dist/infra/tmp-fased-dir.js +6 -6
- package/dist/infra/widearea-dns.js +3 -3
- package/dist/infra/wsl.js +2 -2
- package/dist/line/accounts.js +2 -2
- package/dist/line/download.js +2 -2
- package/dist/logging/config.js +3 -3
- package/dist/logging/logger.js +7 -7
- package/dist/managed/federation.js +3 -3
- package/dist/managed/tunnel.js +3 -3
- package/dist/media/store.js +13 -13
- package/dist/media-understanding/runner.js +3 -3
- package/dist/memory/embeddings.js +2 -2
- package/dist/memory/internal.js +10 -10
- package/dist/memory/manager-sync-ops.js +7 -7
- package/dist/memory/repair-executor.js +17 -17
- package/dist/node-host/invoke-system-run-plan.js +8 -8
- package/dist/node-host/invoke.js +2 -2
- package/dist/node-host/runner.js +3 -3
- package/dist/pairing/pairing-store.js +3 -3
- package/dist/plugin-sdk/{audio-preflight-C2QXh5Ml.js → audio-preflight-Bwi2Oq03.js} +2 -2
- package/dist/plugin-sdk/channel-plugin-common.d.ts +2 -2
- package/dist/plugin-sdk/{chunk-items-3ZyiGiff.js → chunk-items-DzT4L4Ty.js} +1 -1
- package/dist/plugin-sdk/command-status.js +2 -2
- package/dist/plugin-sdk/{config-schema-C9tx1Lyz.js → config-schema-BrkmtFxB.js} +16 -16
- package/dist/plugin-sdk/device-pair.d.ts +1 -1
- package/dist/plugin-sdk/discord.d.ts +4 -4
- package/dist/plugin-sdk/index.d.ts +20 -20
- package/dist/plugin-sdk/index.js +2 -2
- package/dist/plugin-sdk/json-store.js +6 -6
- package/dist/plugin-sdk/{monitor-Xgx6vGcg.js → monitor-M_ta2lMc.js} +4 -4
- package/dist/plugin-sdk/{monitor-XbunF2-r.js → monitor-wYVncM9w.js} +6 -6
- package/dist/plugin-sdk/{openresponses-http-BRUr0JLE.js → openresponses-http-B2GmeSt4.js} +2 -2
- package/dist/plugin-sdk/{pairing-message-C403mq4K.d.ts → pairing-message-B3bHYGaw.d.ts} +1 -1
- package/dist/plugin-sdk/provider-web-search-config-contract.d.ts +1 -1
- package/dist/plugin-sdk/{pw-ai-BzV0f18N.js → pw-ai-AFUqn-tQ.js} +1 -1
- package/dist/plugin-sdk/{runtime-dependency-Ch7J9a0d.js → runtime-dependency-DLDmB94f.js} +9 -9
- package/dist/plugin-sdk/sat-runtime.d.ts +2 -2
- package/dist/plugin-sdk/sat-runtime.js +2 -2
- package/dist/plugin-sdk/{slack-BzJfCWjq.js → slack-CxE1mfzj.js} +4 -4
- package/dist/plugin-sdk/slack.d.ts +4 -4
- package/dist/plugin-sdk/{sticker-cache-Dex-XpRj.js → sticker-cache-CGzGWu00.js} +2 -2
- package/dist/plugin-sdk/{telegram-actions-DoFTGX4z.js → telegram-actions-DaEcYQ8r.js} +3 -3
- package/dist/plugin-sdk/telegram.d.ts +4 -4
- package/dist/plugin-sdk/{tmp-fased-dir-Ouj58axY.d.ts → tmp-fased-dir-CS6zsYEE.d.ts} +1 -1
- package/dist/plugin-sdk/{types-B4hj6HgR.d.ts → types-DFAW-n1J.d.ts} +1 -1
- package/dist/plugin-sdk/{types-dWZFX1fk.d.ts → types-vcJrC_uv.d.ts} +2 -2
- package/dist/plugin-sdk/{web--wC3ZfVl.js → web-CInY-lCv.js} +2 -2
- package/dist/plugin-sdk/whatsapp.d.ts +13 -13
- package/dist/plugin-sdk/{zod-schema.providers-core-FaYR6KdD.d.ts → zod-schema.providers-core-BEbNizPe.d.ts} +78 -78
- package/dist/plugins/bundled-dir.js +3 -3
- package/dist/plugins/discovery.js +11 -11
- package/dist/plugins/loader.js +13 -13
- package/dist/plugins/manifest-registry.js +2 -2
- package/dist/plugins/manifest.js +4 -4
- package/dist/plugins/path-safety.js +3 -3
- package/dist/plugins/status-cache.js +9 -9
- package/dist/plugins/update.js +3 -3
- package/dist/plugins/web-search-install-catalog.js +3 -3
- package/dist/secrets/apply.js +16 -16
- package/dist/secrets/audit.js +11 -11
- package/dist/secrets/shared.js +9 -9
- package/dist/security/scan-paths.js +2 -2
- package/dist/shared/config-eval.js +2 -2
- package/dist/shared/pid-alive.js +2 -2
- package/dist/tasks/standing-orders.js +5 -5
- package/dist/tasks/task-flow-registry.js +5 -5
- package/dist/tasks/task-registry.js +5 -5
- package/dist/tasks/workflow-definitions.js +6 -6
- package/dist/telegram/token.js +5 -5
- package/dist/utils.js +5 -5
- package/dist/wallet/local-socket-signer-broker.js +16 -16
- package/dist/wallet/providers/embedded-keystore-adapter.js +5 -5
- package/dist/wallet/providers/local-socket-signer-adapter.js +2 -2
- package/dist/wallet/wallet-approval-auth.js +5 -5
- package/dist/wallet/wallet-audit-log.js +5 -5
- package/dist/wallet/wallet-custody.js +21 -21
- package/dist/wallet/wallet-inbound-events.js +5 -5
- package/dist/wallet/wallet-observability.js +5 -5
- package/dist/wallet/wallet-policy.js +9 -9
- package/dist/wallet/wallet-provider-registry.js +7 -7
- package/dist/wallet/wallet-runtime-config.js +3 -3
- package/dist/wallet/wallet-secrets-store.js +22 -22
- package/dist/wallet/wallet-send-approvals.js +5 -5
- package/dist/wallet/wallet-settlement-links.js +5 -5
- package/dist/web/accounts.js +3 -3
- package/dist/web/auth-store.js +18 -18
- package/dist/web/session.js +4 -4
- package/dist/wizard/host-security-capability.js +2 -2
- package/dist/wizard/onboarding.host-security.js +7 -7
- package/dist/wizard/onboarding.js +11 -28
- package/dist/wizard/onboarding.wallet.js +132 -85
- package/extensions/acpx/package.json +1 -1
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/fased-federation/package.json +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/imessage/package.json +1 -1
- package/extensions/irc/package.json +1 -1
- package/extensions/line/package.json +1 -1
- package/extensions/llm-task/package.json +1 -1
- package/extensions/lobster/package.json +1 -1
- package/extensions/matrix/CHANGELOG.md +12 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/mattermost/package.json +1 -1
- package/extensions/memory-core/package.json +2 -2
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/minimax-portal-auth/package.json +1 -1
- package/extensions/msteams/CHANGELOG.md +12 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +12 -0
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/sat-mining/package.json +1 -1
- package/extensions/signal/package.json +1 -1
- package/extensions/synology-chat/package.json +1 -1
- package/extensions/tlon/package.json +1 -1
- package/extensions/twitch/CHANGELOG.md +12 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +12 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +12 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +12 -0
- package/extensions/zalouser/package.json +1 -1
- package/package.json +2 -1
- package/scripts/install-fased-signerd.sh +142 -0
|
@@ -32,7 +32,7 @@ import { finalizeOnboardingWizard } from "./onboarding.finalize.js";
|
|
|
32
32
|
import { configureGatewayForOnboarding } from "./onboarding.gateway-config.js";
|
|
33
33
|
import { applyHostingSecurity } from "./onboarding.host-security.js";
|
|
34
34
|
import { normalizeHostedWalletPaths } from "./wallet-path-migration.js";
|
|
35
|
-
import
|
|
35
|
+
import syncFs from "node:fs";
|
|
36
36
|
import path from "node:path";
|
|
37
37
|
import { spawn, spawnSync } from "node:child_process";
|
|
38
38
|
|
|
@@ -446,16 +446,10 @@ async function runOnboardingWizard(opts, runtime = defaultRuntime, prompter) {
|
|
|
446
446
|
};
|
|
447
447
|
const readAgentWalletSummary = () => readAgentDefaultWallet().walletId ? readAgentDefaultWallet() : readRoleWallet("agent");
|
|
448
448
|
const goModernEnough = () => {
|
|
449
|
-
const probe = spawnSync("bash", ["-lc", "if [ -n \"${FASED_GO_BIN:-}\" ] && [ -x \"$FASED_GO_BIN\" ]; then GOCMD=\"$FASED_GO_BIN\"; " + "elif [ -x /usr/local/go/bin/go ]; then GOCMD=/usr/local/go/bin/go; " + "elif command -v go >/dev/null 2>&1; then GOCMD=$(command -v go); " + "else exit 1; fi; " + "v=$($GOCMD version 2>/dev/null | awk '{print $3}' | sed 's/^go//'); " + "maj=$(echo \"$v\" | cut -d. -f1); min=$(echo \"$v\" | cut -d. -f2); " + "([ \"${maj:-0}\" -gt 1 ] || ([ \"${maj:-0}\" -eq 1 ] && [ \"${min:-0}\" -ge
|
|
449
|
+
const probe = spawnSync("bash", ["-lc", "if [ -n \"${FASED_GO_BIN:-}\" ] && [ -x \"$FASED_GO_BIN\" ]; then GOCMD=\"$FASED_GO_BIN\"; " + "elif [ -x /usr/local/go/bin/go ]; then GOCMD=/usr/local/go/bin/go; " + "elif command -v go >/dev/null 2>&1; then GOCMD=$(command -v go); " + "else exit 1; fi; " + "v=$($GOCMD version 2>/dev/null | awk '{print $3}' | sed 's/^go//'); " + "maj=$(echo \"$v\" | cut -d. -f1); min=$(echo \"$v\" | cut -d. -f2); patch=$(echo \"$v\" | cut -d. -f3 | sed \"s/[^0-9].*$//\"); " + "([ \"${maj:-0}\" -gt 1 ] || ([ \"${maj:-0}\" -eq 1 ] && ([ \"${min:-0}\" -gt 25 ] || ([ \"${min:-0}\" -eq 25 ] && [ \"${patch:-0}\" -ge 7 ]))))"], { stdio: "ignore" });
|
|
450
450
|
return probe.status === 0;
|
|
451
451
|
};
|
|
452
452
|
const shellQuote = (value) => `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
453
|
-
const hasExplicitSignerAssetSource = () => {
|
|
454
|
-
const baseUrl = String(process.env.FASED_LOCAL_SIGNER_BASE_URL ?? "").trim();
|
|
455
|
-
const version = String(process.env.FASED_LOCAL_SIGNER_VERSION ?? "").trim();
|
|
456
|
-
const latestTag = String(process.env.FASED_LOCAL_SIGNER_LATEST_TAG ?? "").trim();
|
|
457
|
-
return Boolean(baseUrl && !baseUrl.includes("github.com/fased-ai/fased/releases/download") || version && version !== "latest" || latestTag && latestTag !== "latest");
|
|
458
|
-
};
|
|
459
453
|
const runShell = async (command) => {
|
|
460
454
|
await new Promise((resolve, reject) => {
|
|
461
455
|
const proc = spawn("bash", ["-lc", command], {
|
|
@@ -490,11 +484,11 @@ async function runOnboardingWizard(opts, runtime = defaultRuntime, prompter) {
|
|
|
490
484
|
if (process.platform !== "linux" || !hasCommand("curl") || !hasCommand("tar")) {
|
|
491
485
|
return "unavailable";
|
|
492
486
|
}
|
|
493
|
-
const goVersion = String(process.env.FASED_GO_VERSION ?? "1.
|
|
487
|
+
const goVersion = String(process.env.FASED_GO_VERSION ?? "1.25.7").trim() || "1.25.7";
|
|
494
488
|
const stateRoot = String(process.env.FASED_STATE_DIR ?? "").trim() || path.join(String(process.env.HOME ?? "").trim() || process.cwd(), ".fased");
|
|
495
489
|
const installRoot = path.join(stateRoot, "toolchains", `go${goVersion}`);
|
|
496
490
|
const goBin = path.join(installRoot, "bin", "go");
|
|
497
|
-
if (
|
|
491
|
+
if (syncFs.existsSync(goBin)) {
|
|
498
492
|
process.env.FASED_GO_BIN = goBin;
|
|
499
493
|
return goModernEnough() ? "installed" : "unavailable";
|
|
500
494
|
}
|
|
@@ -527,7 +521,7 @@ async function runOnboardingWizard(opts, runtime = defaultRuntime, prompter) {
|
|
|
527
521
|
if (String(process.env.FASED_FORCE_NATIVE_SIGNER_BUILD ?? "").trim() === "1") {
|
|
528
522
|
return false;
|
|
529
523
|
}
|
|
530
|
-
return
|
|
524
|
+
return syncFs.existsSync(resolveSignerdBinaryPath(process.env));
|
|
531
525
|
};
|
|
532
526
|
const maybeInstallGoForOnboarding = async () => {
|
|
533
527
|
if (goModernEnough()) {
|
|
@@ -544,7 +538,7 @@ async function runOnboardingWizard(opts, runtime = defaultRuntime, prompter) {
|
|
|
544
538
|
return false;
|
|
545
539
|
}
|
|
546
540
|
const installNow = await prompter.confirm({
|
|
547
|
-
message: "Go >=1.
|
|
541
|
+
message: "Go >=1.25.7 is required for a source-built native signer. Install/update Go now?",
|
|
548
542
|
initialValue: true
|
|
549
543
|
});
|
|
550
544
|
if (!installNow) {
|
|
@@ -552,7 +546,7 @@ async function runOnboardingWizard(opts, runtime = defaultRuntime, prompter) {
|
|
|
552
546
|
}
|
|
553
547
|
const progress = prompter.progress("Installing Go toolchain…");
|
|
554
548
|
try {
|
|
555
|
-
await runShell("arch=$(dpkg --print-architecture 2>/dev/null || uname -m); " + "case \"$arch\" in amd64|x86_64) goarch=amd64 ;; arm64|aarch64) goarch=arm64 ;; *) echo \"Unsupported arch: $arch\"; exit 1 ;; esac; " + "goversion=${FASED_GO_VERSION:-1.
|
|
549
|
+
await runShell("arch=$(dpkg --print-architecture 2>/dev/null || uname -m); " + "case \"$arch\" in amd64|x86_64) goarch=amd64 ;; arm64|aarch64) goarch=arm64 ;; *) echo \"Unsupported arch: $arch\"; exit 1 ;; esac; " + "goversion=${FASED_GO_VERSION:-1.25.7}; " + "tmp=$(mktemp); " + "curl -fsSL \"https://go.dev/dl/go${goversion}.linux-${goarch}.tar.gz\" -o \"$tmp\"; " + "sudo rm -rf /usr/local/go; " + "sudo tar -C /usr/local -xzf \"$tmp\"; " + "rm -f \"$tmp\"; " + "sudo ln -sf /usr/local/go/bin/go /usr/local/bin/go");
|
|
556
550
|
progress.stop("Go toolchain ready.");
|
|
557
551
|
} catch (error) {
|
|
558
552
|
progress.stop("Go toolchain install failed.");
|
|
@@ -560,15 +554,6 @@ async function runOnboardingWizard(opts, runtime = defaultRuntime, prompter) {
|
|
|
560
554
|
}
|
|
561
555
|
return goModernEnough();
|
|
562
556
|
};
|
|
563
|
-
const prepareLocalSignerForOnboarding = async (params) => {
|
|
564
|
-
if (fs.existsSync(params.binPath) || String(process.env.FASED_SKIP_NATIVE_SIGNER_BUILD ?? "").trim() === "1" || hasExplicitSignerAssetSource()) {
|
|
565
|
-
return;
|
|
566
|
-
}
|
|
567
|
-
if (goModernEnough()) {
|
|
568
|
-
return;
|
|
569
|
-
}
|
|
570
|
-
await installPrivateGoForOnboarding();
|
|
571
|
-
};
|
|
572
557
|
printWizardHeader(runtime);
|
|
573
558
|
await requireRiskAcknowledgement({
|
|
574
559
|
opts,
|
|
@@ -874,7 +859,7 @@ async function runOnboardingWizard(opts, runtime = defaultRuntime, prompter) {
|
|
|
874
859
|
await prompter.note("Native signer already current.", "Native signer");
|
|
875
860
|
}
|
|
876
861
|
} else if (!await maybeInstallGoForOnboarding()) {
|
|
877
|
-
const detail = "Go >=1.
|
|
862
|
+
const detail = "Go >=1.25.7 is required for a source-built native signer.";
|
|
878
863
|
if (hostingMode && !opts.allowInsecure) {
|
|
879
864
|
throw new Error(`${detail} Install Go and rerun onboarding, or unset FASED_BUILD_NATIVE_SIGNER_FROM_SOURCE.`);
|
|
880
865
|
}
|
|
@@ -895,7 +880,6 @@ async function runOnboardingWizard(opts, runtime = defaultRuntime, prompter) {
|
|
|
895
880
|
flow,
|
|
896
881
|
hostProfile,
|
|
897
882
|
nextConfig,
|
|
898
|
-
prepareLocalSigner: prepareLocalSignerForOnboarding,
|
|
899
883
|
prompter
|
|
900
884
|
});
|
|
901
885
|
nextConfig = syncLocalSignerRuntimeEnvIntoConfig(nextConfig);
|
|
@@ -1112,8 +1096,8 @@ async function runOnboardingWizard(opts, runtime = defaultRuntime, prompter) {
|
|
|
1112
1096
|
const configuredPaths = keystoreKeys.map((key) => (nextConfig.env?.vars?.[key] ?? "").trim() || String(process.env[key] ?? "").trim()).filter(Boolean);
|
|
1113
1097
|
for (const file of new Set([...configuredPaths, ...defaultKeystorePaths])) {
|
|
1114
1098
|
try {
|
|
1115
|
-
if (file &&
|
|
1116
|
-
|
|
1099
|
+
if (file && syncFs.existsSync(file)) {
|
|
1100
|
+
syncFs.rmSync(file, { force: true });
|
|
1117
1101
|
}
|
|
1118
1102
|
} catch {}
|
|
1119
1103
|
}
|
|
@@ -1157,7 +1141,6 @@ async function runOnboardingWizard(opts, runtime = defaultRuntime, prompter) {
|
|
|
1157
1141
|
forceEnable: true,
|
|
1158
1142
|
hostProfile,
|
|
1159
1143
|
nextConfig,
|
|
1160
|
-
prepareLocalSigner: prepareLocalSignerForOnboarding,
|
|
1161
1144
|
prompter
|
|
1162
1145
|
});
|
|
1163
1146
|
nextConfig = syncLocalSignerRuntimeEnvIntoConfig(nextConfig);
|
|
@@ -1235,7 +1218,7 @@ async function runOnboardingWizard(opts, runtime = defaultRuntime, prompter) {
|
|
|
1235
1218
|
process.env[rpcKey] = effectiveRpcUrl;
|
|
1236
1219
|
try {
|
|
1237
1220
|
let moveToSignerDir = false;
|
|
1238
|
-
if (isolatedTargetKeystorePath &&
|
|
1221
|
+
if (isolatedTargetKeystorePath && syncFs.existsSync(isolatedTargetKeystorePath)) {
|
|
1239
1222
|
moveToSignerDir = await prompter.confirm({
|
|
1240
1223
|
message: "Signer keystore already exists. Overwrite it?",
|
|
1241
1224
|
initialValue: false
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { VERSION } from "../version.js";
|
|
1
2
|
import { loadConfig } from "../config/io.js";
|
|
2
3
|
import "../config/config.js";
|
|
3
4
|
import { ensureWalletStateDir, resolveLocalSignerBackendSocketPath, resolveLocalSignerMaterialRootDir, resolveLocalSignerRunAsUser, resolveLocalSignerSidecarPaths, resolveLocalSignerSocketPath, resolveWalletRuntimeConfig } from "../wallet/wallet-runtime-config.js";
|
|
@@ -6,7 +7,7 @@ import { applyWalletPolicyConfig, resolveWalletRoleForId } from "../wallet/walle
|
|
|
6
7
|
import { callLocalSocketSigner } from "../wallet/providers/local-socket-signer-adapter.js";
|
|
7
8
|
import { resolveWalletProviderId } from "../wallet/wallet-provider-resolver.js";
|
|
8
9
|
import { fileURLToPath } from "node:url";
|
|
9
|
-
import
|
|
10
|
+
import syncFs from "node:fs";
|
|
10
11
|
import path from "node:path";
|
|
11
12
|
import { execSync, spawn, spawnSync } from "node:child_process";
|
|
12
13
|
import { randomBytes } from "node:crypto";
|
|
@@ -23,8 +24,8 @@ function resolveSignerdBinaryPath(env = process.env) {
|
|
|
23
24
|
function resolveAppOwnedSignerdStagingPath(env = process.env) {
|
|
24
25
|
return path.join(env.HOME ?? "/root", ".fased/bin/fased-signerd");
|
|
25
26
|
}
|
|
26
|
-
const
|
|
27
|
-
const
|
|
27
|
+
const INSTALL_SCRIPT_RELURLS = ["../../scripts/install-fased-signerd.sh", "../scripts/install-fased-signerd.sh"];
|
|
28
|
+
const BUILD_SCRIPT_RELURLS = ["../../scripts/build-fased-signerd.sh", "../scripts/build-fased-signerd.sh"];
|
|
28
29
|
const BROKER_CLI_RELPATHS = ["./index.js", "../../dist/index.js"];
|
|
29
30
|
const DEFAULT_SIGNER_RELEASE_DOWNLOAD_BASE = "https://github.com/fased-ai/fased/releases/download";
|
|
30
31
|
const SIGNER_MAINTENANCE_HELPER = "/usr/local/sbin/fased-signer-maintenance";
|
|
@@ -48,7 +49,7 @@ function runCommand(params) {
|
|
|
48
49
|
}
|
|
49
50
|
function isSignerdRunning(socketPath) {
|
|
50
51
|
try {
|
|
51
|
-
|
|
52
|
+
syncFs.statSync(socketPath);
|
|
52
53
|
return true;
|
|
53
54
|
} catch {
|
|
54
55
|
return false;
|
|
@@ -77,7 +78,7 @@ async function sleep(ms) {
|
|
|
77
78
|
}
|
|
78
79
|
function readFileTail(filePath, maxLines = 20) {
|
|
79
80
|
try {
|
|
80
|
-
const text =
|
|
81
|
+
const text = syncFs.readFileSync(filePath, "utf8").trim();
|
|
81
82
|
if (!text) {
|
|
82
83
|
return undefined;
|
|
83
84
|
}
|
|
@@ -157,19 +158,19 @@ async function readSignerdHealth(socketPath) {
|
|
|
157
158
|
}
|
|
158
159
|
}
|
|
159
160
|
function resolveInstallScript() {
|
|
160
|
-
for (const rel of
|
|
161
|
-
const
|
|
162
|
-
if (
|
|
163
|
-
return
|
|
161
|
+
for (const rel of INSTALL_SCRIPT_RELURLS) {
|
|
162
|
+
const candidate = fileURLToPath(new URL(rel, import.meta.url));
|
|
163
|
+
if (syncFs.existsSync(candidate)) {
|
|
164
|
+
return candidate;
|
|
164
165
|
}
|
|
165
166
|
}
|
|
166
167
|
return null;
|
|
167
168
|
}
|
|
168
169
|
function resolveBuildScript() {
|
|
169
|
-
for (const rel of
|
|
170
|
-
const
|
|
171
|
-
if (
|
|
172
|
-
return
|
|
170
|
+
for (const rel of BUILD_SCRIPT_RELURLS) {
|
|
171
|
+
const candidate = fileURLToPath(new URL(rel, import.meta.url));
|
|
172
|
+
if (syncFs.existsSync(candidate)) {
|
|
173
|
+
return candidate;
|
|
173
174
|
}
|
|
174
175
|
}
|
|
175
176
|
return null;
|
|
@@ -177,7 +178,7 @@ function resolveBuildScript() {
|
|
|
177
178
|
function resolveBrokerCliPath() {
|
|
178
179
|
for (const rel of BROKER_CLI_RELPATHS) {
|
|
179
180
|
const candidate = fileURLToPath(new URL(rel, import.meta.url));
|
|
180
|
-
if (
|
|
181
|
+
if (syncFs.existsSync(candidate)) {
|
|
181
182
|
return candidate;
|
|
182
183
|
}
|
|
183
184
|
}
|
|
@@ -190,17 +191,17 @@ function resolveLocalSignerdReleaseBaseUrl(installScriptPath) {
|
|
|
190
191
|
const arch = process.arch === "arm64" ? "arm64" : "amd64";
|
|
191
192
|
const assetPath = path.join(releaseDir, `fased-signerd-${platform}-${arch}`);
|
|
192
193
|
const checksumsPath = path.join(releaseDir, "fased-signerd-checksums.txt");
|
|
193
|
-
if (!
|
|
194
|
+
if (!syncFs.existsSync(assetPath) || !syncFs.existsSync(checksumsPath)) {
|
|
194
195
|
return null;
|
|
195
196
|
}
|
|
196
197
|
return `file://${releaseDir}`;
|
|
197
198
|
}
|
|
198
199
|
function resolveGoBinary(env = process.env) {
|
|
199
200
|
const explicit = String(env.FASED_GO_BIN ?? "").trim();
|
|
200
|
-
if (explicit &&
|
|
201
|
+
if (explicit && syncFs.existsSync(explicit)) {
|
|
201
202
|
return explicit;
|
|
202
203
|
}
|
|
203
|
-
if (
|
|
204
|
+
if (syncFs.existsSync("/usr/local/go/bin/go")) {
|
|
204
205
|
return "/usr/local/go/bin/go";
|
|
205
206
|
}
|
|
206
207
|
const child = spawnSync("bash", ["-lc", "command -v go || true"], {
|
|
@@ -227,13 +228,14 @@ function isGoModernEnough(goBin) {
|
|
|
227
228
|
if (child.status !== 0) {
|
|
228
229
|
return false;
|
|
229
230
|
}
|
|
230
|
-
const match = String(child.stdout ?? "").match(/\bgo(\d+)\.(\d+)(
|
|
231
|
+
const match = String(child.stdout ?? "").match(/\bgo(\d+)\.(\d+)(?:\.(\d+))?\b/);
|
|
231
232
|
if (!match) {
|
|
232
233
|
return false;
|
|
233
234
|
}
|
|
234
235
|
const major = Number(match[1]);
|
|
235
236
|
const minor = Number(match[2]);
|
|
236
|
-
|
|
237
|
+
const patch = Number(match[3] ?? 0);
|
|
238
|
+
return major > 1 || major === 1 && (minor > 25 || minor === 25 && patch >= 7);
|
|
237
239
|
}
|
|
238
240
|
function hasExplicitSignerdAssetSource(env = process.env) {
|
|
239
241
|
const baseUrl = String(env.FASED_LOCAL_SIGNER_BASE_URL ?? "").trim();
|
|
@@ -271,7 +273,7 @@ function runScriptOrThrow(params) {
|
|
|
271
273
|
function copySignerdBinaryToTarget(params) {
|
|
272
274
|
const sourcePath = path.resolve(params.sourcePath);
|
|
273
275
|
const targetPath = path.resolve(params.targetPath);
|
|
274
|
-
if (!
|
|
276
|
+
if (!syncFs.existsSync(sourcePath)) {
|
|
275
277
|
throw new Error(`fased-signerd build completed but binary was not found at ${sourcePath}.`);
|
|
276
278
|
}
|
|
277
279
|
if (params.runAsUser) {
|
|
@@ -295,9 +297,9 @@ function copySignerdBinaryToTarget(params) {
|
|
|
295
297
|
}
|
|
296
298
|
return;
|
|
297
299
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
300
|
+
syncFs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
301
|
+
syncFs.copyFileSync(sourcePath, targetPath);
|
|
302
|
+
syncFs.chmodSync(targetPath, 493);
|
|
301
303
|
}
|
|
302
304
|
function buildSignerdBinaryFromSource(binPath) {
|
|
303
305
|
if (String(process.env.FASED_SKIP_NATIVE_SIGNER_BUILD ?? "").trim() === "1") {
|
|
@@ -326,34 +328,53 @@ function buildSignerdBinaryFromSource(binPath) {
|
|
|
326
328
|
});
|
|
327
329
|
return true;
|
|
328
330
|
}
|
|
329
|
-
function
|
|
330
|
-
|
|
331
|
-
|
|
331
|
+
function resolveSignerdAssetInstallEnv(installScript) {
|
|
332
|
+
const env = { ...process.env };
|
|
333
|
+
if (hasExplicitSignerdAssetSource(env)) {
|
|
334
|
+
return env;
|
|
335
|
+
}
|
|
336
|
+
const localReleaseBaseUrl = resolveLocalSignerdReleaseBaseUrl(installScript);
|
|
337
|
+
if (localReleaseBaseUrl) {
|
|
338
|
+
env.FASED_LOCAL_SIGNER_BASE_URL = localReleaseBaseUrl;
|
|
339
|
+
env.FASED_LOCAL_SIGNER_VERSION = "";
|
|
340
|
+
env.FASED_LOCAL_SIGNER_LATEST_TAG = "";
|
|
341
|
+
return env;
|
|
342
|
+
}
|
|
343
|
+
const normalizedVersion = VERSION.trim().replace(/^v/, "");
|
|
344
|
+
if (!/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(normalizedVersion)) {
|
|
345
|
+
throw new Error(`Cannot resolve a versioned fased-signerd asset for Fased ${VERSION}.`);
|
|
346
|
+
}
|
|
347
|
+
env.FASED_LOCAL_SIGNER_BASE_URL = DEFAULT_SIGNER_RELEASE_DOWNLOAD_BASE;
|
|
348
|
+
env.FASED_LOCAL_SIGNER_VERSION = `v${normalizedVersion}`;
|
|
349
|
+
env.FASED_LOCAL_SIGNER_LATEST_TAG = "";
|
|
350
|
+
return env;
|
|
351
|
+
}
|
|
352
|
+
function installSignerdBinaryFromAsset(binPath) {
|
|
353
|
+
if (process.platform === "win32") {
|
|
354
|
+
throw new Error("The local socket signer requires Unix sockets. On Windows, install and run Fased inside WSL2.");
|
|
355
|
+
}
|
|
356
|
+
if (process.platform !== "linux" && process.platform !== "darwin") {
|
|
357
|
+
throw new Error(`No fased-signerd release asset is available for ${process.platform}.`);
|
|
332
358
|
}
|
|
333
359
|
const script = resolveInstallScript();
|
|
334
360
|
if (!script) {
|
|
335
|
-
|
|
361
|
+
return false;
|
|
336
362
|
}
|
|
337
363
|
const runAsUser = resolveLocalSignerRunAsUser(process.env);
|
|
338
364
|
const stagingPath = resolveAppOwnedSignerdStagingPath(process.env);
|
|
339
365
|
const installDir = path.dirname(runAsUser ? stagingPath : binPath);
|
|
340
|
-
const localReleaseBaseUrl = resolveLocalSignerdReleaseBaseUrl(script);
|
|
341
|
-
const installCmd = [
|
|
342
|
-
`FASED_LOCAL_SIGNER_BIN_DIR="${installDir}"`,
|
|
343
|
-
...localReleaseBaseUrl ? [`FASED_LOCAL_SIGNER_BASE_URL="${localReleaseBaseUrl}"`, "FASED_LOCAL_SIGNER_LATEST_TAG=\"\""] : [],
|
|
344
|
-
`bash "${script}"`
|
|
345
|
-
].join(" ");
|
|
346
366
|
const verboseInstall = String(process.env.FASED_INSTALL_VERBOSE ?? "").trim() === "1" || String(process.env.FASED_ONBOARD_VERBOSE ?? "").trim() === "1";
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
367
|
+
runScriptOrThrow({
|
|
368
|
+
script,
|
|
369
|
+
env: {
|
|
370
|
+
...resolveSignerdAssetInstallEnv(script),
|
|
371
|
+
FASED_LOCAL_SIGNER_BIN_DIR: installDir
|
|
372
|
+
},
|
|
373
|
+
verbose: verboseInstall,
|
|
374
|
+
fallbackError: "fased-signerd asset install failed"
|
|
375
|
+
});
|
|
355
376
|
const installedPath = runAsUser ? stagingPath : binPath;
|
|
356
|
-
if (!
|
|
377
|
+
if (!syncFs.existsSync(installedPath)) {
|
|
357
378
|
throw new Error(`fased-signerd install script ran but binary not found at ${binPath}.\n` + `Check install script output above for errors.`);
|
|
358
379
|
}
|
|
359
380
|
if (runAsUser && installedPath !== binPath) {
|
|
@@ -376,25 +397,44 @@ function installSignerdBinaryFromExplicitAsset(binPath) {
|
|
|
376
397
|
});
|
|
377
398
|
}
|
|
378
399
|
}
|
|
379
|
-
if (!
|
|
400
|
+
if (!syncFs.existsSync(binPath)) {
|
|
380
401
|
throw new Error(`fased-signerd install script completed but target binary not found at ${binPath}.\n` + `Check install script output above for errors.`);
|
|
381
402
|
}
|
|
382
403
|
return true;
|
|
383
404
|
}
|
|
384
405
|
function installSignerdBinary(binPath) {
|
|
385
|
-
|
|
386
|
-
|
|
406
|
+
const forceSourceBuild = String(process.env.FASED_BUILD_NATIVE_SIGNER_FROM_SOURCE ?? "").trim() === "1";
|
|
407
|
+
if (forceSourceBuild) {
|
|
408
|
+
if (buildSignerdBinaryFromSource(binPath)) {
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
throw new Error("FASED_BUILD_NATIVE_SIGNER_FROM_SOURCE=1 requires a source checkout and Go >= 1.25.7.");
|
|
387
412
|
}
|
|
388
|
-
|
|
389
|
-
|
|
413
|
+
let assetError;
|
|
414
|
+
try {
|
|
415
|
+
if (installSignerdBinaryFromAsset(binPath)) {
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
} catch (error) {
|
|
419
|
+
assetError = error;
|
|
390
420
|
}
|
|
421
|
+
let sourceError;
|
|
422
|
+
try {
|
|
423
|
+
if (buildSignerdBinaryFromSource(binPath)) {
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
} catch (error) {
|
|
427
|
+
sourceError = error;
|
|
428
|
+
}
|
|
429
|
+
const assetDetail = assetError instanceof Error ? assetError.message : undefined;
|
|
430
|
+
const sourceDetail = sourceError instanceof Error ? sourceError.message : undefined;
|
|
391
431
|
throw new Error([
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
"
|
|
397
|
-
].join("\n"));
|
|
432
|
+
`Automatic fased-signerd installation failed for ${process.platform}/${process.arch}.`,
|
|
433
|
+
`Fased ${VERSION} normally downloads its matching prebuilt signer and verifies its SHA-256 checksum; Go is not required.`,
|
|
434
|
+
assetDetail ? `Asset install: ${assetDetail}` : "The packaged signer installer was not found.",
|
|
435
|
+
sourceDetail ? `Source fallback: ${sourceDetail}` : undefined,
|
|
436
|
+
"Retry after checking GitHub release access, or set FASED_WALLET_LOCAL_SIGNER_BIN to a trusted existing binary."
|
|
437
|
+
].filter((line) => Boolean(line)).join("\n"));
|
|
398
438
|
}
|
|
399
439
|
function hasScopedWalletEnvValue(env, prefix) {
|
|
400
440
|
return Object.entries(env).some(([key, value]) => key.startsWith(`${prefix}__`) && typeof value === "string" && value.trim().length > 0);
|
|
@@ -434,7 +474,7 @@ function inferScopedSignerKeystoreEnv(materialDir, env) {
|
|
|
434
474
|
const solanaKey = `FASED_WALLET_SOLANA_KEYSTORE_PATH__${envSuffix}`;
|
|
435
475
|
if (!String(env[solanaKey] ?? "").trim()) {
|
|
436
476
|
const candidate = path.join(materialDir, `keystore-solana-${fileSuffix}.v1.enc`);
|
|
437
|
-
if (
|
|
477
|
+
if (syncFs.existsSync(candidate)) {
|
|
438
478
|
inferred[solanaKey] = candidate;
|
|
439
479
|
}
|
|
440
480
|
}
|
|
@@ -469,7 +509,7 @@ function resolveLocalSignerPassphraseSource(materialDir, env) {
|
|
|
469
509
|
const candidates = [configuredFile ? path.resolve(configuredFile) : "", path.join(materialDir, "passphrase")].filter(Boolean);
|
|
470
510
|
for (const candidate of candidates) {
|
|
471
511
|
try {
|
|
472
|
-
const value =
|
|
512
|
+
const value = syncFs.readFileSync(candidate, "utf8").trim();
|
|
473
513
|
if (value) {
|
|
474
514
|
return {
|
|
475
515
|
kind: "file",
|
|
@@ -636,11 +676,11 @@ function writeLocalSignerEnvFile(params) {
|
|
|
636
676
|
...cfg.env?.vars
|
|
637
677
|
};
|
|
638
678
|
const signerEnvPath = path.resolve(ensureWalletStateDir(mergedEnv).rootDir, "signer.env");
|
|
639
|
-
|
|
679
|
+
syncFs.mkdirSync(path.dirname(signerEnvPath), {
|
|
640
680
|
recursive: true,
|
|
641
681
|
mode: 448
|
|
642
682
|
});
|
|
643
|
-
|
|
683
|
+
syncFs.writeFileSync(signerEnvPath, renderLocalSignerEnvFile({
|
|
644
684
|
config: cfg,
|
|
645
685
|
env: mergedEnv
|
|
646
686
|
}), {
|
|
@@ -648,7 +688,7 @@ function writeLocalSignerEnvFile(params) {
|
|
|
648
688
|
mode: 384
|
|
649
689
|
});
|
|
650
690
|
try {
|
|
651
|
-
|
|
691
|
+
syncFs.chmodSync(signerEnvPath, 384);
|
|
652
692
|
} catch {}
|
|
653
693
|
return signerEnvPath;
|
|
654
694
|
}
|
|
@@ -690,7 +730,7 @@ function startSignerIsolationHelperBackground(runAsUser, args, logPath, env = pr
|
|
|
690
730
|
if (!helperArgs) {
|
|
691
731
|
return false;
|
|
692
732
|
}
|
|
693
|
-
const out =
|
|
733
|
+
const out = syncFs.openSync(logPath, "a", 384);
|
|
694
734
|
const child = spawn("sudo", [
|
|
695
735
|
"-n",
|
|
696
736
|
"-E",
|
|
@@ -711,10 +751,10 @@ function startSignerIsolationHelperBackground(runAsUser, args, logPath, env = pr
|
|
|
711
751
|
return true;
|
|
712
752
|
}
|
|
713
753
|
function signerMaintenanceHelperArgs(runAsUser, args) {
|
|
714
|
-
if (
|
|
754
|
+
if (syncFs.existsSync(SIGNER_MAINTENANCE_HELPER)) {
|
|
715
755
|
return [SIGNER_MAINTENANCE_HELPER, ...args];
|
|
716
756
|
}
|
|
717
|
-
if (
|
|
757
|
+
if (syncFs.existsSync(SIGNER_ISOLATION_HELPER)) {
|
|
718
758
|
return [
|
|
719
759
|
SIGNER_ISOLATION_HELPER,
|
|
720
760
|
resolveCurrentUnixUser(),
|
|
@@ -769,16 +809,16 @@ function ensureLocalSignerPassphrase() {
|
|
|
769
809
|
const generated = existing.kind === "value" ? existing.value : randomBytes(24).toString("base64url");
|
|
770
810
|
const stagingDir = ensureWalletStateDir(process.env).rootDir;
|
|
771
811
|
const stagingPath = path.join(stagingDir, `.local-signer-passphrase-${process.pid}-${Date.now()}`);
|
|
772
|
-
|
|
812
|
+
syncFs.mkdirSync(path.dirname(stagingPath), {
|
|
773
813
|
recursive: true,
|
|
774
814
|
mode: 448
|
|
775
815
|
});
|
|
776
|
-
|
|
816
|
+
syncFs.writeFileSync(stagingPath, `${generated}\n`, {
|
|
777
817
|
encoding: "utf8",
|
|
778
818
|
mode: 384
|
|
779
819
|
});
|
|
780
820
|
try {
|
|
781
|
-
|
|
821
|
+
syncFs.chmodSync(stagingPath, 384);
|
|
782
822
|
} catch {}
|
|
783
823
|
let passphrasePath = path.join(materialDir, "passphrase");
|
|
784
824
|
try {
|
|
@@ -808,7 +848,7 @@ function ensureLocalSignerPassphrase() {
|
|
|
808
848
|
process.env.FASED_WALLET_PASSPHRASE = generated;
|
|
809
849
|
} catch (err) {
|
|
810
850
|
try {
|
|
811
|
-
|
|
851
|
+
syncFs.rmSync(stagingPath, { force: true });
|
|
812
852
|
} catch {}
|
|
813
853
|
const detail = err instanceof Error ? err.message : String(err);
|
|
814
854
|
if (!detail.includes("passphrase already exists")) {
|
|
@@ -826,16 +866,16 @@ function ensureLocalSignerPassphrase() {
|
|
|
826
866
|
}
|
|
827
867
|
const generated = randomBytes(24).toString("base64url");
|
|
828
868
|
const passphraseFile = path.join(materialDir, "passphrase");
|
|
829
|
-
|
|
869
|
+
syncFs.mkdirSync(path.dirname(passphraseFile), {
|
|
830
870
|
recursive: true,
|
|
831
871
|
mode: 448
|
|
832
872
|
});
|
|
833
|
-
|
|
873
|
+
syncFs.writeFileSync(passphraseFile, `${generated}\n`, {
|
|
834
874
|
encoding: "utf8",
|
|
835
875
|
mode: 384
|
|
836
876
|
});
|
|
837
877
|
try {
|
|
838
|
-
|
|
878
|
+
syncFs.chmodSync(passphraseFile, 384);
|
|
839
879
|
} catch {}
|
|
840
880
|
process.env.FASED_WALLET_PASSPHRASE_FILE = passphraseFile;
|
|
841
881
|
delete process.env.FASED_WALLET_PASSPHRASE;
|
|
@@ -887,8 +927,8 @@ function startSignerdBackground(binPath, socketPath, materialDir, env = process.
|
|
|
887
927
|
throw new Error(`failed to launch isolated signer as ${runAsUser}: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
|
|
888
928
|
}
|
|
889
929
|
}
|
|
890
|
-
const out =
|
|
891
|
-
const err =
|
|
930
|
+
const out = syncFs.openSync(logPath, "a", 384);
|
|
931
|
+
const err = syncFs.openSync(logPath, "a", 384);
|
|
892
932
|
const child = spawn(binPath, [
|
|
893
933
|
"-socket",
|
|
894
934
|
socketPath,
|
|
@@ -964,7 +1004,7 @@ function stopProcessBySocket(socketPath, runAsUser) {
|
|
|
964
1004
|
}
|
|
965
1005
|
for (const candidatePidPath of pidPaths) {
|
|
966
1006
|
try {
|
|
967
|
-
const pid = Number.parseInt(
|
|
1007
|
+
const pid = Number.parseInt(syncFs.readFileSync(candidatePidPath, "utf8").trim(), 10);
|
|
968
1008
|
if (Number.isFinite(pid) && pid > 0) {
|
|
969
1009
|
try {
|
|
970
1010
|
const command = readProcessCommand(pid);
|
|
@@ -975,16 +1015,16 @@ function stopProcessBySocket(socketPath, runAsUser) {
|
|
|
975
1015
|
}
|
|
976
1016
|
} catch {}
|
|
977
1017
|
try {
|
|
978
|
-
|
|
1018
|
+
syncFs.unlinkSync(candidatePidPath);
|
|
979
1019
|
} catch {}
|
|
980
1020
|
}
|
|
981
1021
|
try {
|
|
982
|
-
|
|
1022
|
+
syncFs.unlinkSync(socketPath);
|
|
983
1023
|
} catch {}
|
|
984
1024
|
}
|
|
985
1025
|
function readProcessCommand(pid) {
|
|
986
1026
|
try {
|
|
987
|
-
const cmdline =
|
|
1027
|
+
const cmdline = syncFs.readFileSync(`/proc/${pid}/cmdline`, "utf8").replaceAll("\0", " ").trim();
|
|
988
1028
|
if (cmdline) {
|
|
989
1029
|
return cmdline;
|
|
990
1030
|
}
|
|
@@ -1050,8 +1090,8 @@ function startSignerBrokerBackground(appSocketPath, backendSocketPath, materialD
|
|
|
1050
1090
|
throw new Error(`failed to launch isolated signer broker as ${runAsUser}: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
|
|
1051
1091
|
}
|
|
1052
1092
|
}
|
|
1053
|
-
const out =
|
|
1054
|
-
const err =
|
|
1093
|
+
const out = syncFs.openSync(logPath, "a", 384);
|
|
1094
|
+
const err = syncFs.openSync(logPath, "a", 384);
|
|
1055
1095
|
const child = spawn(process.execPath, [
|
|
1056
1096
|
brokerCli,
|
|
1057
1097
|
"wallet",
|
|
@@ -1087,7 +1127,7 @@ async function restartLocalSocketSigner(walletDir, env = process.env) {
|
|
|
1087
1127
|
const binPath = resolveSignerdBinaryPath(env);
|
|
1088
1128
|
const materialDir = resolveLocalSignerMaterialRootDir(env);
|
|
1089
1129
|
const runAsUser = resolveLocalSignerRunAsUser(env);
|
|
1090
|
-
if (!
|
|
1130
|
+
if (!syncFs.existsSync(binPath)) {
|
|
1091
1131
|
return;
|
|
1092
1132
|
}
|
|
1093
1133
|
stopProcessBySocket(socketPath, runAsUser);
|
|
@@ -1130,7 +1170,7 @@ async function syncLocalSocketSignerFromConfig(params) {
|
|
|
1130
1170
|
env: mergedEnv
|
|
1131
1171
|
});
|
|
1132
1172
|
const binPath = resolveSignerdBinaryPath(mergedEnv);
|
|
1133
|
-
if (!
|
|
1173
|
+
if (!syncFs.existsSync(binPath)) {
|
|
1134
1174
|
installSignerdBinary(binPath);
|
|
1135
1175
|
}
|
|
1136
1176
|
if (params?.restart === false) {
|
|
@@ -1159,7 +1199,7 @@ function migrateLocalSignerKeystoreToMaterialDir(params) {
|
|
|
1159
1199
|
return targetPath;
|
|
1160
1200
|
}
|
|
1161
1201
|
ensureIsolatedSignerPaths(materialDir, resolveLocalSignerBackendSocketPath(process.env), resolveLocalSignerSocketPath(process.env), runAsUser);
|
|
1162
|
-
if (
|
|
1202
|
+
if (syncFs.existsSync(targetPath) && !params.force) {
|
|
1163
1203
|
throw new Error(`Keystore already exists: ${targetPath}`);
|
|
1164
1204
|
}
|
|
1165
1205
|
if (runSignerIsolationHelper(runAsUser, [
|
|
@@ -1257,7 +1297,7 @@ function hasConfiguredWalletMaterial(params) {
|
|
|
1257
1297
|
}
|
|
1258
1298
|
try {
|
|
1259
1299
|
const walletDir = ensureWalletStateDir(mergedEnv).rootDir;
|
|
1260
|
-
return
|
|
1300
|
+
return syncFs.readdirSync(walletDir).some((entry) => /^keystore-solana(?:-[A-Za-z0-9_-]+)?\.v1\.enc$/.test(entry) || /^keystore-evm(?:-[A-Za-z0-9_-]+)?\.v1\.enc$/.test(entry));
|
|
1261
1301
|
} catch {
|
|
1262
1302
|
return false;
|
|
1263
1303
|
}
|
|
@@ -1356,13 +1396,20 @@ async function configureWalletForOnboarding(params) {
|
|
|
1356
1396
|
const binPath = resolveSignerdBinaryPath(process.env);
|
|
1357
1397
|
const runAsUser = resolveLocalSignerRunAsUser(process.env);
|
|
1358
1398
|
ensureLocalSignerPassphrase();
|
|
1359
|
-
if (!
|
|
1399
|
+
if (!syncFs.existsSync(binPath)) {
|
|
1400
|
+
const signerInstallProgress = quietSignerNotes ? prompter.progress("Installing local wallet signer…") : undefined;
|
|
1360
1401
|
if (!quietSignerNotes) {
|
|
1361
|
-
await prompter.note([`fased-signerd not found at: ${binPath}`,
|
|
1402
|
+
await prompter.note([`fased-signerd not found at: ${binPath}`, `Downloading the checksum-verified signer for Fased ${VERSION}. Go is not required for a normal install.`].join("\n"), "Local socket signer");
|
|
1362
1403
|
}
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1404
|
+
try {
|
|
1405
|
+
await params.prepareLocalSigner?.({ binPath });
|
|
1406
|
+
if (!syncFs.existsSync(binPath)) {
|
|
1407
|
+
installSignerdBinary(binPath);
|
|
1408
|
+
}
|
|
1409
|
+
signerInstallProgress?.stop("Local wallet signer installed.");
|
|
1410
|
+
} catch (error) {
|
|
1411
|
+
signerInstallProgress?.stop("Local wallet signer installation failed.");
|
|
1412
|
+
throw error;
|
|
1366
1413
|
}
|
|
1367
1414
|
if (!quietSignerNotes) {
|
|
1368
1415
|
await prompter.note(`fased-signerd installed at: ${binPath}`, "Local socket signer");
|