@fased/fased 0.1.62 → 0.1.65
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 +48 -0
- package/README.md +44 -29
- package/config/dependency-ownership.json +1 -1
- package/config/signer-policies/README.md +58 -0
- package/config/signer-policies/agent.json.template +32 -0
- package/config/signer-policies/mining.json.template +69 -0
- package/config/signer-policies/network.json.template +5 -0
- package/config/signer-policies/vault.json.template +70 -0
- package/config/signer-protocol-v2.json +78 -0
- package/config/typescript-noemit-baseline.json +680 -0
- package/dist/agents/auth-profiles/store.js +267 -31
- package/dist/agents/bash-tools.exec.js +10 -4
- package/dist/agents/current-model-catalog.js +3 -3
- package/dist/agents/memory-search.js +7 -1
- package/dist/agents/model-catalog-access.js +1 -2
- package/dist/agents/model-catalog-snapshot.js +1 -1
- package/dist/agents/model-catalog-source.js +1 -1
- package/dist/agents/model-metadata.js +1 -1
- package/dist/agents/model-selection.js +2 -28
- package/dist/agents/models-config.providers.js +6 -6
- package/dist/agents/pi-embedded-runner/compact.js +15 -7
- package/dist/agents/pi-embedded-runner/model.js +1 -1
- package/dist/agents/pi-embedded-runner/run/attempt.js +24 -13
- package/dist/agents/pi-embedded-runner/run.js +2 -0
- package/dist/agents/pi-embedded-runner/tool-split.js +40 -2
- package/dist/agents/pi-tool-definition-adapter.js +16 -1
- package/dist/agents/pi-tools.js +2 -1
- package/dist/agents/sandbox/config.js +1 -1
- package/dist/agents/sandbox/context.js +27 -2
- package/dist/agents/skills/env-overrides.js +38 -28
- package/dist/agents/skills/trust.js +93 -0
- package/dist/agents/skills/workspace.js +128 -0
- package/dist/agents/skills-clawhub.js +36 -11
- package/dist/agents/skills-marketplace-scan.js +49 -0
- package/dist/agents/tools/marketplace-offer-draft-tool.js +1 -1
- package/dist/agents/tools/mining-tool.js +1 -1
- package/dist/agents/tools/session-status-tool.js +1 -1
- package/dist/agents/tools/wallet-action-tool.js +172 -36
- package/dist/agents/tools/wallet-skill-policy.js +65 -23
- package/dist/agents/tools/wallet-tool.js +7 -11
- package/dist/auto-reply/reply/directive-handling.fast-lane.js +2 -1
- package/dist/auto-reply/reply/directive-handling.impl.js +2 -1
- package/dist/auto-reply/reply/directive-handling.model.js +2 -1
- package/dist/auto-reply/reply/directive-handling.persist.js +2 -2
- package/dist/auto-reply/reply/get-reply-directives-apply.js +2 -0
- package/dist/auto-reply/reply/get-reply-inline-actions.js +25 -1
- package/dist/auto-reply/reply/model-selection.js +7 -4
- package/dist/auto-reply/reply/session-reset-model.js +4 -4
- package/dist/brand.js +1 -1
- package/dist/build-info.json +3 -3
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/channel-web.js +2 -2
- package/dist/cli/gateway-cli/run.js +8 -0
- package/dist/cli/program/command-registry.js +1 -1
- package/dist/cli/program/register.onboard.js +2 -3
- package/dist/cli/program/register.wallet.js +16 -123
- package/dist/cli/providers-cli.js +1 -1
- package/dist/cli/sat-cli.js +129 -2
- package/dist/cli/update-cli/update-command.js +260 -11
- package/dist/commands/auth-choice.apply.api-providers.js +3 -3
- package/dist/commands/doctor-config-flow.js +1 -1
- package/dist/commands/doctor-legacy-config.js +2 -13
- package/dist/commands/model-picker.js +6 -6
- package/dist/commands/models/auth.js +1 -1
- package/dist/commands/onboard-auth.config-gateways.js +1 -1
- package/dist/commands/onboard-auth.credentials.js +32 -8
- package/dist/commands/onboard-non-interactive/local/wallet-config.js +28 -27
- package/dist/commands/onboard-non-interactive/local.js +5 -1
- package/dist/commands/wallet.js +568 -1911
- package/dist/config/config.js +2 -2
- package/dist/config/io.js +64 -2
- package/dist/config/schema.help.js +8 -7
- package/dist/config/schema.labels.js +5 -4
- package/dist/config/zod-schema.agent-runtime.js +1 -0
- package/dist/config/zod-schema.js +5 -0
- package/dist/control-ui/assets/{app-DLil9VO1.js → app-MaQnPa5G.js} +1511 -1555
- package/dist/control-ui/assets/{config-CU5Zi8Dh.js → config-LeImukCW.js} +10 -10
- package/dist/control-ui/assets/{federation-D10Q4eP_.js → federation-DgA9e-Pn.js} +364 -422
- package/dist/control-ui/assets/{index-DdE_NIXo.js → index-D4YMr1fA.js} +3 -3
- package/dist/control-ui/assets/mining-commit-DFpB_4JN.js +2 -0
- package/dist/control-ui/assets/{mining-BdhMn18r.js → mining-qMYs4aD-.js} +70 -50
- package/dist/control-ui/assets/{open-external-url-DwSiwMPl.js → open-external-url-ulF1B-sA.js} +3 -3
- package/dist/control-ui/assets/{providers-QMn4w2_f.js → providers-CIx9fxc6.js} +2 -2
- package/dist/control-ui/assets/{wallet-C2g294QT.js → wallet-DvStR_AT.js} +259 -377
- package/dist/control-ui/index.html +1 -1
- package/dist/control-ui/version.json +1 -1
- package/dist/daemon/systemd-system.js +56 -50
- package/dist/extensions/sat-mining/src/protocol-contract.js +43 -3
- package/dist/extensions/sat-mining/src/rpc-read.js +291 -84
- package/dist/extensions/sat-mining/src/sat-bond-layout.js +5 -2
- package/dist/extensions/sat-mining/src/signer-codec-manifest.js +406 -0
- package/dist/extensions/sat-mining/src/solana-submit.js +1274 -390
- package/dist/extensions/sat-mining/src/submission-ledger.js +349 -0
- package/dist/federation/auto-connect.js +98 -8
- package/dist/federation/marketplace-capability-adapter.js +33 -7
- package/dist/federation/marketplace-delivery-outbox.js +196 -0
- package/dist/federation/marketplace-delivery.js +351 -215
- package/dist/federation/marketplace-direct-payment.js +272 -141
- package/dist/federation/marketplace-escrow.js +607 -249
- package/dist/federation/marketplace-settlement-ledger.js +352 -0
- package/dist/federation/offers.js +9 -7
- package/dist/federation/peer-auth-v2.js +529 -0
- package/dist/gateway/a2a-http.js +425 -96
- package/dist/gateway/a2a-settlement.js +259 -153
- package/dist/gateway/a2a-task-store.js +524 -0
- package/dist/gateway/auth.js +38 -2
- package/dist/gateway/config-reload.js +46 -33
- package/dist/gateway/durable-capacity.js +31 -0
- package/dist/gateway/federation-http.js +540 -135
- package/dist/gateway/federation-marketplace-run-store.js +397 -0
- package/dist/gateway/federation-marketplace.js +535 -230
- package/dist/gateway/mutating-admin-rpc-rate-limit.js +5 -0
- package/dist/gateway/security-path.js +1 -1
- package/dist/gateway/server-http.js +1084 -1205
- package/dist/gateway/server-methods/models.js +1 -1
- package/dist/gateway/server-methods/secrets.js +40 -0
- package/dist/gateway/server-methods.js +1 -2
- package/dist/gateway/server-reload-handlers.js +196 -66
- package/dist/gateway/server-runtime-config.js +1 -1
- package/dist/gateway/server-secrets-runtime.js +288 -0
- package/dist/gateway/server.impl.js +73 -42
- package/dist/gateway/sessions-patch.js +3 -5
- package/dist/index.js +4 -2
- package/dist/infra/fasedhub.js +64 -1
- package/dist/infra/local-source-paired-update.js +538 -0
- package/dist/infra/restart.js +41 -10
- package/dist/infra/update-runner.js +96 -0
- package/dist/light-update-status.js +11 -11
- package/dist/memory/backend-config.js +2 -1
- package/dist/memory/session-files.js +16 -2
- package/dist/plugin-sdk/{accounts-DxblobYM.js → accounts-Brn3-uWN.js} +1 -1
- package/dist/plugin-sdk/{actions-D4UNimWa.js → actions-DRu135h0.js} +2 -2
- package/dist/plugin-sdk/{active-listener-CFuy106s.js → active-listener-B_NMtgPL.js} +1 -1
- package/dist/plugin-sdk/{audio-preflight-Bwi2Oq03.js → audio-preflight-I4IngVlJ.js} +27 -27
- package/dist/plugin-sdk/{audit-Cs0K7LBp.js → audit-C5d2z5U1.js} +1 -1
- package/dist/plugin-sdk/{channel-access-D5aHoTY8.js → channel-access-CcFRdRPO.js} +1 -1
- package/dist/plugin-sdk/{channel-access-configure-Dvch9mMQ.js → channel-access-configure-DaI5wevh.js} +1 -1
- package/dist/plugin-sdk/channel-plugin-common.d.ts +3 -3
- package/dist/plugin-sdk/channel-plugin-common.js +4 -4
- package/dist/plugin-sdk/{chunk-B0FUGc5A.js → chunk-CyoyqpbG.js} +1 -1
- package/dist/plugin-sdk/{chunk-items-DzT4L4Ty.js → chunk-items-DLQ6_lLK.js} +1 -1
- package/dist/plugin-sdk/command-status.d.ts +2 -2
- package/dist/plugin-sdk/command-status.js +27 -27
- package/dist/plugin-sdk/{commands-registry-DmDRhRAU.js → commands-registry-BfqdEWdF.js} +2 -2
- package/dist/plugin-sdk/{common-CfUOowOp.js → common-HCcXU-NR.js} +1 -1
- package/dist/plugin-sdk/{config-mxULv0fQ.js → config-DlWVeLFB.js} +7113 -6877
- package/dist/plugin-sdk/{config-schema-BrkmtFxB.js → config-schema-D_8FVI1C.js} +6798 -3695
- package/dist/plugin-sdk/device-pair.d.ts +1 -1
- package/dist/plugin-sdk/discord.d.ts +6 -6
- package/dist/plugin-sdk/discord.js +19 -19
- package/dist/plugin-sdk/file-lock.js +35 -4
- package/dist/plugin-sdk/{filesystem-manager-ZoHU8oA7.js → filesystem-manager-DoI8IBNF.js} +1 -1
- package/dist/plugin-sdk/{group-mentions-BHRff6j8.d.ts → group-mentions-q3hUTCt7.d.ts} +1 -1
- package/dist/plugin-sdk/{handle-action-DbVCF9HZ.js → handle-action-hvwapMKg.js} +13 -13
- package/dist/plugin-sdk/{helpers-BXbdgs5H.js → helpers-DMBU4oTo.js} +1 -1
- package/dist/plugin-sdk/{image-ops-D7jPxaph.js → image-ops-DQi0n_Tt.js} +1 -1
- package/dist/plugin-sdk/index.d.ts +21 -39
- package/dist/plugin-sdk/index.js +29 -29
- package/dist/plugin-sdk/{login-BRxww6nv.js → login-Ca583Okc.js} +3 -3
- package/dist/plugin-sdk/{login-qr-DJXsk9XH.js → login-qr-CGciBSNP.js} +3 -3
- package/dist/plugin-sdk/{manager-Y2S_5IlI.js → manager-BegWxNYX.js} +4 -4
- package/dist/plugin-sdk/{markdown-tables-DHLFQqaF.js → markdown-tables-DCOXEUfZ.js} +1 -1
- package/dist/plugin-sdk/{media-Czo4carg.js → media-CAdQF5TG.js} +47 -47
- package/dist/plugin-sdk/{memory-search-DTjIMw8J.js → memory-search-CrFPOeTH.js} +4 -1
- package/dist/plugin-sdk/{monitor-M_ta2lMc.js → monitor-B4KF4Kpo.js} +31 -31
- package/dist/plugin-sdk/{monitor-wYVncM9w.js → monitor-Bb6x1KAG.js} +32 -32
- package/dist/plugin-sdk/{openresponses-http-B2GmeSt4.js → openresponses-http-DCTO8JkL.js} +27 -27
- package/dist/plugin-sdk/{optional-runtime-dependency-DdMbxS24.js → optional-runtime-dependency-0dznm3ZO.js} +1 -1
- package/dist/plugin-sdk/{outbound-Db8mRN6P.js → outbound-BgVDdHxx.js} +6 -6
- package/dist/plugin-sdk/{outbound-attachment-BqFjcypb.js → outbound-attachment-QqTnIhZL.js} +2 -2
- package/dist/plugin-sdk/{pairing-message-B3GC_7CD.js → pairing-message-D0CoLHRJ.js} +1 -1
- package/dist/plugin-sdk/{pairing-message-B3bHYGaw.d.ts → pairing-message-DHPDFZbC.d.ts} +2 -2
- package/dist/plugin-sdk/{pairing-store-CQikgIbw.js → pairing-store-BChahgI2.js} +2 -2
- package/dist/plugin-sdk/{pi-model-discovery-CY3m5zJP.js → pi-model-discovery-BX_JLcEJ.js} +1 -1
- package/dist/plugin-sdk/{pi-model-discovery-runtime-DSh1T2pn.js → pi-model-discovery-runtime-DxTMz_XF.js} +2 -2
- package/dist/plugin-sdk/provider-web-search-config-contract.d.ts +2 -2
- package/dist/plugin-sdk/{pw-ai-AFUqn-tQ.js → pw-ai-natjh3rm.js} +3 -3
- package/dist/plugin-sdk/{qmd-manager-DSyx77KY.js → qmd-manager-CgRaTxUq.js} +1 -1
- package/dist/plugin-sdk/{query-expansion-CAI2kKLQ.js → query-expansion-BG3FgzF7.js} +14 -3
- package/dist/plugin-sdk/{replies-Fzh9PhXl.js → replies-ChYo5ZQM.js} +2 -2
- package/dist/plugin-sdk/{resolve-outbound-target-KpF3co6T.js → resolve-outbound-target-D-KGgHJZ.js} +1 -1
- package/dist/plugin-sdk/{resolve-route-CDl74O19.js → resolve-route-C8tvQm8Z.js} +1 -1
- package/dist/plugin-sdk/{retry-policy-D4uiqUOG.js → retry-policy-C6SjKjQA.js} +1 -1
- package/dist/plugin-sdk/{runtime-Bb6KRnCC.js → runtime-2B9_WKoI.js} +8 -3
- package/dist/plugin-sdk/{runtime-dependency-DLDmB94f.js → runtime-dependency-DczkvPxn.js} +2 -2
- package/dist/plugin-sdk/sat-runtime.d.ts +565 -309
- package/dist/plugin-sdk/sat-runtime.js +29 -29
- package/dist/plugin-sdk/{send-C4k4JuJN.js → send-B6KkGKZD.js} +6 -6
- package/dist/plugin-sdk/{send-D-uDKGIq.js → send-CFzGKJXo.js} +6 -6
- package/dist/plugin-sdk/{send-Du8ykP1k.js → send-DCO441U7.js} +8 -8
- package/dist/plugin-sdk/{send-5nFktR1n.js → send-gDoGA-7e.js} +5 -5
- package/dist/plugin-sdk/{send-Bfzf11VY.js → send-q9HXrSwK.js} +7 -7
- package/dist/plugin-sdk/{session-CS-Td9EM.js → session-DHD4ZKyG.js} +2 -2
- package/dist/plugin-sdk/{skill-commands-CFAlXWHk.js → skill-commands-FKEPLS7T.js} +201 -26
- package/dist/plugin-sdk/{slack-CxE1mfzj.js → slack-BHmvqgjH.js} +39 -39
- package/dist/plugin-sdk/{slack-actions-BcMkNv1Z.js → slack-actions-DhbMcp8M.js} +11 -11
- package/dist/plugin-sdk/slack.d.ts +6 -6
- package/dist/plugin-sdk/slack.js +9 -9
- package/dist/plugin-sdk/{sticker-cache-CGzGWu00.js → sticker-cache-By5AcorL.js} +3 -3
- package/dist/plugin-sdk/{tables-bFXyRpkx.js → tables-B3jr0Pvq.js} +1 -1
- package/dist/plugin-sdk/{targets-DH7a9lKB.js → targets-CtSbTxYX.js} +1 -1
- package/dist/plugin-sdk/{telegram-actions-DaEcYQ8r.js → telegram-actions-DGnBz1YT.js} +30 -30
- package/dist/plugin-sdk/telegram.d.ts +6 -6
- package/dist/plugin-sdk/telegram.js +8 -8
- package/dist/plugin-sdk/{thread-bindings.lifecycle-CgOvvdw8.js → thread-bindings.lifecycle-QbkNl-m6.js} +3 -3
- package/dist/plugin-sdk/{thread-bindings.state-CQpk44Hq.js → thread-bindings.state-D9hg_M1c.js} +2 -2
- package/dist/plugin-sdk/tmp-fased-dir-EJGTmL1Q.d.ts +486 -0
- package/dist/plugin-sdk/{types-vcJrC_uv.d.ts → types-BdwdFCD6.d.ts} +2 -3
- package/dist/plugin-sdk/{types-DFAW-n1J.d.ts → types-BrCpYMxn.d.ts} +2 -2
- package/dist/plugin-sdk/{types-DyhXnYUr.d.ts → types-D0kDG8l0.d.ts} +3 -2
- package/dist/plugin-sdk/{types.plugin-_fbu40Re.d.ts → types.plugin-BcSBq42x.d.ts} +8 -3
- package/dist/plugin-sdk/{web-CInY-lCv.js → web-DUJwrTYs.js} +32 -32
- package/dist/plugin-sdk/{whatsapp-actions-BtSc2CBv.js → whatsapp-actions-Bj_rOncr.js} +13 -13
- package/dist/plugin-sdk/{whatsapp-heartbeat-Bg9TuYzl.js → whatsapp-heartbeat-B1WHkJIg.js} +2 -2
- package/dist/plugin-sdk/whatsapp.d.ts +13 -13
- package/dist/plugin-sdk/whatsapp.js +12 -12
- package/dist/plugin-sdk/{wsl-C4DGFkOd.js → wsl-J-HscWxS.js} +3 -3
- package/dist/plugin-sdk/{zod-schema.providers-core-BEbNizPe.d.ts → zod-schema.providers-core-CIzCjXH9.d.ts} +61 -61
- package/dist/providers/refresh.js +1 -1
- package/dist/providers/registry.js +1 -1
- package/dist/secrets/apply.js +1 -1
- package/dist/secrets/runtime.js +1 -1
- package/dist/wallet/external-submission-ledger.js +376 -0
- package/dist/wallet/legacy-embedded-keystore.js +40 -0
- package/dist/wallet/local-socket-signer-archive.js +30 -0
- package/dist/wallet/local-socket-signer-lifecycle.js +97 -0
- package/dist/wallet/local-socket-signer-policy.js +166 -0
- package/dist/wallet/local-socket-signer-protocol.js +578 -117
- package/dist/wallet/native-signer-wallet-id.js +25 -0
- package/dist/wallet/providers/alchemy-adapter.js +3 -0
- package/dist/wallet/providers/local-socket-signer-adapter.js +380 -105
- package/dist/wallet/providers/turnkey-adapter.js +292 -34
- package/dist/wallet/providers/wallet-standard-adapter.js +100 -0
- package/dist/wallet/signer-network-admin.js +184 -0
- package/dist/wallet/signer-protocol-v2.generated.js +92 -0
- package/dist/wallet/solana-bond-signing.js +157 -69
- package/dist/wallet/solana-reviewed-transaction.js +375 -0
- package/dist/wallet/solana-swap.js +520 -64
- package/dist/wallet/solana-transaction-inspection.js +106 -4
- package/dist/wallet/solana-trigger.js +658 -320
- package/dist/wallet/turnkey-reviewed-state.js +370 -0
- package/dist/wallet/wallet-approval-auth.js +17 -28
- package/dist/wallet/wallet-atomic-state.js +53 -0
- package/dist/wallet/wallet-canary.js +0 -1
- package/dist/wallet/wallet-inbound-events.js +16 -11
- package/dist/wallet/wallet-policy-simulation.js +1 -1
- package/dist/wallet/wallet-policy.js +93 -37
- package/dist/wallet/wallet-provider-capabilities.js +28 -4
- package/dist/wallet/wallet-provider-registry.js +57 -44
- package/dist/wallet/wallet-provider-resolver.js +62 -63
- package/dist/wallet/wallet-runtime-config.js +28 -41
- package/dist/wallet/wallet-secrets-store.js +22 -0
- package/dist/wallet/wallet-send-approvals.js +1891 -589
- package/dist/wallet/wallet-send-execution-ledger.js +292 -0
- package/dist/wallet/wallet-settlement-links.js +14 -13
- package/dist/wallet/wallet-standard-review.js +353 -0
- package/dist/wallet/wallet-status.js +0 -9
- package/dist/wallet/wallet-task-ledger.js +16 -2
- package/dist/web/auto-reply/heartbeat-runner.js +1 -1
- package/dist/web/auto-reply/monitor.js +2 -2
- package/dist/wizard/host-security-capability.js +14 -23
- package/dist/wizard/onboarding.finalize.js +63 -184
- package/dist/wizard/onboarding.host-security.js +117 -1367
- package/dist/wizard/onboarding.js +172 -217
- package/dist/wizard/onboarding.wallet.js +232 -785
- 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 +18 -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 +18 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +18 -0
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/sat-mining/index.ts +587 -154
- package/extensions/sat-mining/package.json +1 -1
- package/extensions/sat-mining/signer-codec-schema.v1.json +374 -0
- package/extensions/sat-mining/src/audit-store.ts +91 -5
- package/extensions/sat-mining/src/claim-service.ts +85 -14
- package/extensions/sat-mining/src/client.ts +13 -0
- package/extensions/sat-mining/src/config.ts +9 -0
- package/extensions/sat-mining/src/cycle-progress.ts +16 -8
- package/extensions/sat-mining/src/epoch-service.ts +9 -5
- package/extensions/sat-mining/src/gateway-runner.ts +21 -1
- package/extensions/sat-mining/src/protocol-contract.ts +45 -1
- package/extensions/sat-mining/src/recovery-service.ts +312 -0
- package/extensions/sat-mining/src/round-watcher.ts +391 -81
- package/extensions/sat-mining/src/rpc-read.ts +431 -106
- package/extensions/sat-mining/src/runtime.ts +16 -0
- package/extensions/sat-mining/src/sat-bond-layout.ts +6 -0
- package/extensions/sat-mining/src/signer-codec-manifest.ts +429 -0
- package/extensions/sat-mining/src/solana-submit.ts +1544 -436
- package/extensions/sat-mining/src/submission-ledger.ts +434 -0
- 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 +18 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +18 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +18 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +18 -0
- package/extensions/zalouser/package.json +1 -1
- package/install.sh +4951 -0
- package/package.json +23 -5
- package/scripts/fased-host-updater.mjs +1421 -0
- package/scripts/fased-host-updaterctl.mjs +186 -0
- package/scripts/fased-managed-service.sh +36 -0
- package/scripts/fased-managed-updater.mjs +3065 -156
- package/scripts/fased-signer-enroll-hosting.sh +275 -0
- package/scripts/fased-signer-network-hosting.sh +143 -0
- package/scripts/fased-signer-owner-policy.mjs +1442 -0
- package/scripts/fased-signer-policy-hosting.sh +50 -0
- package/scripts/fased-signer-policy-local.sh +26 -0
- package/scripts/hosted-release-manifest.mjs +185 -0
- package/scripts/install-fased-signerd.sh +183 -108
- package/scripts/install-managed-runtime.mjs +212 -10
- package/scripts/managed-runtime-layout.mjs +75 -3
- package/scripts/migrate-hosted-signer-v2.mjs +58 -0
- package/scripts/start-managed.sh +173 -360
- package/dist/control-ui/assets/mining-commit-R-6nu87p.js +0 -2
- package/dist/plugin-sdk/tmp-fased-dir-CS6zsYEE.d.ts +0 -77
- package/dist/wallet/local-socket-signer-broker.js +0 -224
- package/dist/wallet/local-socket-signer-custody.js +0 -42
- package/dist/wallet/providers/embedded-keystore-adapter.js +0 -402
- package/dist/wallet/providers/privy-adapter.js +0 -80
- package/dist/wallet/wallet-custody.js +0 -1836
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
umask 077
|
|
5
|
+
|
|
6
|
+
if [[ "${EUID}" != "0" ]]; then
|
|
7
|
+
echo "Hosted signer policy setup must run as root from a root SSH or provider-console session." >&2
|
|
8
|
+
exit 1
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
|
12
|
+
export PATH
|
|
13
|
+
NODE_BIN="$(command -v node || true)"
|
|
14
|
+
HELPER="/usr/local/libexec/fased-signer-owner-policy.mjs"
|
|
15
|
+
STAT_BIN="/usr/bin/stat"
|
|
16
|
+
|
|
17
|
+
case "$NODE_BIN" in
|
|
18
|
+
/usr/bin/node|/usr/local/bin/node|/bin/node) ;;
|
|
19
|
+
*)
|
|
20
|
+
echo "A supported system Node.js executable is unavailable." >&2
|
|
21
|
+
exit 1
|
|
22
|
+
;;
|
|
23
|
+
esac
|
|
24
|
+
|
|
25
|
+
for executable in "$NODE_BIN" "$STAT_BIN"; do
|
|
26
|
+
[[ -f "$executable" && -x "$executable" ]] || {
|
|
27
|
+
echo "Required root-controlled executable is missing: $executable" >&2
|
|
28
|
+
exit 1
|
|
29
|
+
}
|
|
30
|
+
read -r owner mode <<<"$($STAT_BIN -Lc '%u %a' "$executable")"
|
|
31
|
+
[[ "$owner" == "0" && $((8#$mode & 8#22)) -eq 0 ]] || {
|
|
32
|
+
echo "Required executable is not root-owned and non-writable: $executable" >&2
|
|
33
|
+
exit 1
|
|
34
|
+
}
|
|
35
|
+
done
|
|
36
|
+
|
|
37
|
+
[[ -f "$HELPER" && ! -L "$HELPER" ]] || {
|
|
38
|
+
echo "Installed Hosted signer policy helper is missing or unsafe: $HELPER" >&2
|
|
39
|
+
exit 1
|
|
40
|
+
}
|
|
41
|
+
read -r helper_owner helper_mode helper_links <<<"$($STAT_BIN -c '%u %a %h' "$HELPER")"
|
|
42
|
+
[[ "$helper_owner" == "0" && "$helper_links" -eq 1 && $((8#$helper_mode & 8#22)) -eq 0 ]] || {
|
|
43
|
+
echo "Hosted signer policy helper must be a single-link root-owned non-writable file." >&2
|
|
44
|
+
exit 1
|
|
45
|
+
}
|
|
46
|
+
if [[ $# -eq 1 && "$1" == "--help" ]]; then
|
|
47
|
+
exec "$NODE_BIN" "$HELPER" --help
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
exec "$NODE_BIN" "$HELPER" --profile hosting "$@"
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
umask 077
|
|
5
|
+
|
|
6
|
+
if [[ "${EUID}" == "0" ]]; then
|
|
7
|
+
echo "Local signer policy setup must run as the non-root user that owns the signer." >&2
|
|
8
|
+
exit 1
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
INSTALL_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
|
|
12
|
+
HELPER="${INSTALL_DIR}/fased-signer-owner-policy.mjs"
|
|
13
|
+
|
|
14
|
+
if [[ ! -f "$HELPER" || -L "$HELPER" ]]; then
|
|
15
|
+
echo "Installed Local signer policy helper is missing or unsafe: $HELPER" >&2
|
|
16
|
+
exit 1
|
|
17
|
+
fi
|
|
18
|
+
if ! command -v node >/dev/null 2>&1; then
|
|
19
|
+
echo "Node.js is required to run the Local signer policy helper." >&2
|
|
20
|
+
exit 1
|
|
21
|
+
fi
|
|
22
|
+
if [[ $# -eq 1 && "$1" == "--help" ]]; then
|
|
23
|
+
exec node "$HELPER" --help
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
exec node "$HELPER" --profile local "$@"
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import fsp from "node:fs/promises";
|
|
3
|
+
|
|
4
|
+
const VERSION_PATTERN = /^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z]+(?:[.-][0-9A-Za-z]+)*)?$/u;
|
|
5
|
+
const COMMIT_PATTERN = /^[a-f0-9]{40}$/u;
|
|
6
|
+
const SHA256_PATTERN = /^[a-f0-9]{64}$/u;
|
|
7
|
+
const PREFIXED_SHA256_PATTERN = /^sha256:[a-f0-9]{64}$/u;
|
|
8
|
+
|
|
9
|
+
function exactKeys(value, expected, label) {
|
|
10
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
11
|
+
throw new Error(`${label} must be an object`);
|
|
12
|
+
}
|
|
13
|
+
if (
|
|
14
|
+
Object.keys(value).toSorted().join(",") !==
|
|
15
|
+
[...expected].toSorted((left, right) => left.localeCompare(right)).join(",")
|
|
16
|
+
) {
|
|
17
|
+
throw new Error(`${label} contains unsupported or missing fields`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function canonicalJSON(value) {
|
|
22
|
+
if (Array.isArray(value)) {
|
|
23
|
+
return `[${value.map((entry) => canonicalJSON(entry)).join(",")}]`;
|
|
24
|
+
}
|
|
25
|
+
if (value && typeof value === "object") {
|
|
26
|
+
return `{${Object.keys(value)
|
|
27
|
+
.toSorted()
|
|
28
|
+
.map((key) => `${JSON.stringify(key)}:${canonicalJSON(value[key])}`)
|
|
29
|
+
.join(",")}}`;
|
|
30
|
+
}
|
|
31
|
+
return JSON.stringify(value);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function sha256Bytes(value) {
|
|
35
|
+
return createHash("sha256").update(value).digest("hex");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function capabilitiesDigest(value) {
|
|
39
|
+
return `sha256:${sha256Bytes(canonicalJSON(value))}`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function parseArtifact(value, label) {
|
|
43
|
+
exactKeys(value, ["asset", "sha256"], label);
|
|
44
|
+
if (
|
|
45
|
+
typeof value.asset !== "string" ||
|
|
46
|
+
!/^[A-Za-z0-9][A-Za-z0-9._-]+$/u.test(value.asset) ||
|
|
47
|
+
!SHA256_PATTERN.test(value.sha256 || "")
|
|
48
|
+
) {
|
|
49
|
+
throw new Error(`${label} is invalid`);
|
|
50
|
+
}
|
|
51
|
+
return Object.freeze({ asset: value.asset, sha256: value.sha256 });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function parseCapabilities(value, claimedDigest) {
|
|
55
|
+
exactKeys(
|
|
56
|
+
value,
|
|
57
|
+
["protocol", "nativeFeeReservationLamports", "intentTypes", "operationStates", "features"],
|
|
58
|
+
"signer capabilities",
|
|
59
|
+
);
|
|
60
|
+
exactKeys(value.protocol, ["current", "min", "max"], "signer protocol range");
|
|
61
|
+
if (
|
|
62
|
+
value.protocol.current !== 2 ||
|
|
63
|
+
value.protocol.min !== 2 ||
|
|
64
|
+
value.protocol.max !== 2 ||
|
|
65
|
+
value.nativeFeeReservationLamports !== 5_000_000 ||
|
|
66
|
+
!Array.isArray(value.intentTypes) ||
|
|
67
|
+
!Array.isArray(value.operationStates) ||
|
|
68
|
+
!Array.isArray(value.features) ||
|
|
69
|
+
[...value.intentTypes, ...value.operationStates, ...value.features].some(
|
|
70
|
+
(entry) => typeof entry !== "string" || !entry,
|
|
71
|
+
) ||
|
|
72
|
+
new Set(value.intentTypes).size !== value.intentTypes.length ||
|
|
73
|
+
new Set(value.operationStates).size !== value.operationStates.length ||
|
|
74
|
+
new Set(value.features).size !== value.features.length
|
|
75
|
+
) {
|
|
76
|
+
throw new Error("signer capabilities are malformed or not protocol v2");
|
|
77
|
+
}
|
|
78
|
+
const actualDigest = capabilitiesDigest(value);
|
|
79
|
+
if (!PREFIXED_SHA256_PATTERN.test(claimedDigest || "") || actualDigest !== claimedDigest) {
|
|
80
|
+
throw new Error("signer capability digest does not match its canonical capability contract");
|
|
81
|
+
}
|
|
82
|
+
return Object.freeze({ ...value, protocol: Object.freeze({ ...value.protocol }) });
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function parseHostedReleaseManifestV2(value, expected = {}) {
|
|
86
|
+
exactKeys(
|
|
87
|
+
value,
|
|
88
|
+
["schemaVersion", "release", "application", "signer"],
|
|
89
|
+
"hosted release manifest",
|
|
90
|
+
);
|
|
91
|
+
if (value.schemaVersion !== 2) {
|
|
92
|
+
throw new Error("hosted release manifest schema must be v2");
|
|
93
|
+
}
|
|
94
|
+
exactKeys(value.release, ["version", "tag", "commit"], "hosted release identity");
|
|
95
|
+
const version = String(value.release.version || "");
|
|
96
|
+
const commit = String(value.release.commit || "");
|
|
97
|
+
if (
|
|
98
|
+
!VERSION_PATTERN.test(version) ||
|
|
99
|
+
value.release.tag !== `v${version}` ||
|
|
100
|
+
!COMMIT_PATTERN.test(commit) ||
|
|
101
|
+
(expected.version && version !== expected.version) ||
|
|
102
|
+
(expected.commit && commit !== expected.commit)
|
|
103
|
+
) {
|
|
104
|
+
throw new Error("hosted release version, tag, or commit is malformed or mismatched");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
exactKeys(value.application, ["linux"], "hosted application platforms");
|
|
108
|
+
exactKeys(value.application.linux, ["x64", "arm64"], "hosted Linux architectures");
|
|
109
|
+
const application = { linux: {} };
|
|
110
|
+
for (const architecture of ["x64", "arm64"]) {
|
|
111
|
+
const entry = value.application.linux[architecture];
|
|
112
|
+
exactKeys(entry, ["artifact", "dependencies"], `hosted Linux ${architecture} entry`);
|
|
113
|
+
exactKeys(
|
|
114
|
+
entry.dependencies,
|
|
115
|
+
["asset", "sha256", "dependencyHash"],
|
|
116
|
+
`hosted Linux ${architecture} dependencies`,
|
|
117
|
+
);
|
|
118
|
+
if (!SHA256_PATTERN.test(entry.dependencies.dependencyHash || "")) {
|
|
119
|
+
throw new Error(`hosted Linux ${architecture} dependency hash is invalid`);
|
|
120
|
+
}
|
|
121
|
+
application.linux[architecture] = Object.freeze({
|
|
122
|
+
artifact: parseArtifact(entry.artifact, `hosted Linux ${architecture} app artifact`),
|
|
123
|
+
dependencies: Object.freeze({
|
|
124
|
+
...parseArtifact(
|
|
125
|
+
{ asset: entry.dependencies.asset, sha256: entry.dependencies.sha256 },
|
|
126
|
+
`hosted Linux ${architecture} dependency artifact`,
|
|
127
|
+
),
|
|
128
|
+
dependencyHash: entry.dependencies.dependencyHash,
|
|
129
|
+
}),
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
exactKeys(
|
|
134
|
+
value.signer,
|
|
135
|
+
["release", "capabilities", "capabilitiesDigest", "platforms"],
|
|
136
|
+
"hosted signer release",
|
|
137
|
+
);
|
|
138
|
+
exactKeys(
|
|
139
|
+
value.signer.release,
|
|
140
|
+
["version", "commit", "buildInputDigest", "development"],
|
|
141
|
+
"hosted signer build identity",
|
|
142
|
+
);
|
|
143
|
+
if (
|
|
144
|
+
value.signer.release.version !== version ||
|
|
145
|
+
value.signer.release.commit !== commit ||
|
|
146
|
+
!PREFIXED_SHA256_PATTERN.test(value.signer.release.buildInputDigest || "") ||
|
|
147
|
+
value.signer.release.development !== false
|
|
148
|
+
) {
|
|
149
|
+
throw new Error("hosted app and signer release identities do not match");
|
|
150
|
+
}
|
|
151
|
+
exactKeys(
|
|
152
|
+
value.signer.platforms,
|
|
153
|
+
["linux-amd64", "linux-arm64", "darwin-amd64", "darwin-arm64"],
|
|
154
|
+
"hosted signer platforms",
|
|
155
|
+
);
|
|
156
|
+
const platforms = {};
|
|
157
|
+
for (const platform of ["linux-amd64", "linux-arm64", "darwin-amd64", "darwin-arm64"]) {
|
|
158
|
+
platforms[platform] = parseArtifact(value.signer.platforms[platform], `signer ${platform}`);
|
|
159
|
+
}
|
|
160
|
+
return Object.freeze({
|
|
161
|
+
schemaVersion: 2,
|
|
162
|
+
release: Object.freeze({ version, tag: `v${version}`, commit }),
|
|
163
|
+
application: Object.freeze({ linux: Object.freeze(application.linux) }),
|
|
164
|
+
signer: Object.freeze({
|
|
165
|
+
release: Object.freeze({ ...value.signer.release }),
|
|
166
|
+
capabilities: parseCapabilities(value.signer.capabilities, value.signer.capabilitiesDigest),
|
|
167
|
+
capabilitiesDigest: value.signer.capabilitiesDigest,
|
|
168
|
+
platforms: Object.freeze(platforms),
|
|
169
|
+
}),
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export async function readHostedReleaseManifestV2(filePath, expected = {}) {
|
|
174
|
+
const bytes = await fsp.readFile(filePath);
|
|
175
|
+
const manifest = parseHostedReleaseManifestV2(JSON.parse(bytes.toString("utf8")), expected);
|
|
176
|
+
return { manifest, digest: `sha256:${sha256Bytes(bytes)}` };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export async function verifyManifestArtifact(filePath, artifact, label = artifact?.asset) {
|
|
180
|
+
const actual = sha256Bytes(await fsp.readFile(filePath));
|
|
181
|
+
if (actual !== artifact?.sha256) {
|
|
182
|
+
throw new Error(`${label || "release artifact"} does not match the attested release manifest`);
|
|
183
|
+
}
|
|
184
|
+
return actual;
|
|
185
|
+
}
|
|
@@ -5,138 +5,213 @@ ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
|
5
5
|
INSTALL_DIR_DEFAULT="${HOME}/.fased/bin"
|
|
6
6
|
INSTALL_DIR="${FASED_LOCAL_SIGNER_BIN_DIR:-$INSTALL_DIR_DEFAULT}"
|
|
7
7
|
VERSION="${FASED_LOCAL_SIGNER_VERSION:-}"
|
|
8
|
+
POLICY_TEMPLATE_DIR="${FASED_LOCAL_SIGNER_POLICY_TEMPLATE_DIR:-$(dirname "$INSTALL_DIR")/share/signer-policies}"
|
|
9
|
+
UPDATER="$ROOT/scripts/fased-managed-updater.mjs"
|
|
10
|
+
ACTION="install"
|
|
11
|
+
DEFER_COMMIT=0
|
|
12
|
+
CONFIRM_DOWNGRADE=""
|
|
13
|
+
EXPECTED_COMMIT="${FASED_LOCAL_SIGNER_EXPECTED_COMMIT:-}"
|
|
8
14
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
usage() {
|
|
16
|
+
cat <<'EOF'
|
|
17
|
+
Usage: install-fased-signerd.sh [options]
|
|
18
|
+
|
|
19
|
+
Installs the exact version-matched native signer for Local Linux, WSL2, or
|
|
20
|
+
native macOS using an offline snapshot and crash-recoverable transaction.
|
|
21
|
+
|
|
22
|
+
Options:
|
|
23
|
+
--version vX.Y.Z Exact signer release (defaults to package version)
|
|
24
|
+
--expected-commit SHA Require the signer release to match this app commit
|
|
25
|
+
--defer-commit Leave the verified candidate open for paired app health
|
|
26
|
+
--confirm-downgrade X.Y.Z Explicitly confirm one exact reviewed downgrade target
|
|
27
|
+
--verify Verify the exact running binary, release, and protocol-v2 health
|
|
28
|
+
--commit Commit a deferred verified transaction
|
|
29
|
+
--rollback Restore the exact verified pre-update snapshot
|
|
30
|
+
--recover Recover an interrupted transaction deterministically
|
|
31
|
+
--status Print the current signer transaction journal
|
|
32
|
+
-h, --help Show this help
|
|
33
|
+
|
|
34
|
+
Native Windows is unsupported. Run this installer inside Ubuntu on WSL2.
|
|
35
|
+
Official installs require gh with `gh attestation verify`; Go is not required.
|
|
36
|
+
EOF
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
while [[ $# -gt 0 ]]; do
|
|
40
|
+
case "$1" in
|
|
41
|
+
--version)
|
|
42
|
+
VERSION="${2:-}"
|
|
43
|
+
shift 2
|
|
44
|
+
;;
|
|
45
|
+
--expected-commit)
|
|
46
|
+
EXPECTED_COMMIT="${2:-}"
|
|
47
|
+
shift 2
|
|
48
|
+
;;
|
|
49
|
+
--defer-commit)
|
|
50
|
+
DEFER_COMMIT=1
|
|
51
|
+
shift
|
|
52
|
+
;;
|
|
53
|
+
--confirm-downgrade)
|
|
54
|
+
CONFIRM_DOWNGRADE="${2:-}"
|
|
55
|
+
shift 2
|
|
56
|
+
;;
|
|
57
|
+
--commit)
|
|
58
|
+
ACTION="commit"
|
|
59
|
+
shift
|
|
60
|
+
;;
|
|
61
|
+
--verify)
|
|
62
|
+
ACTION="verify"
|
|
63
|
+
shift
|
|
64
|
+
;;
|
|
65
|
+
--rollback)
|
|
66
|
+
ACTION="rollback"
|
|
67
|
+
shift
|
|
68
|
+
;;
|
|
69
|
+
--recover)
|
|
70
|
+
ACTION="recover"
|
|
71
|
+
shift
|
|
72
|
+
;;
|
|
73
|
+
--status)
|
|
74
|
+
ACTION="status"
|
|
75
|
+
shift
|
|
76
|
+
;;
|
|
77
|
+
-h|--help)
|
|
78
|
+
usage
|
|
79
|
+
exit 0
|
|
80
|
+
;;
|
|
81
|
+
*)
|
|
82
|
+
echo "Unknown signer installer option: $1" >&2
|
|
83
|
+
usage >&2
|
|
84
|
+
exit 2
|
|
85
|
+
;;
|
|
86
|
+
esac
|
|
87
|
+
done
|
|
15
88
|
|
|
89
|
+
OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
|
|
16
90
|
case "$OS" in
|
|
17
91
|
linux|darwin) ;;
|
|
92
|
+
mingw*|msys*|cygwin*)
|
|
93
|
+
echo "Native Windows is unsupported. Install and run Fased inside Ubuntu on WSL2." >&2
|
|
94
|
+
exit 1
|
|
95
|
+
;;
|
|
18
96
|
*)
|
|
19
|
-
echo "Unsupported OS: $OS" >&2
|
|
97
|
+
echo "Unsupported OS for fased-signerd: $OS" >&2
|
|
20
98
|
exit 1
|
|
21
99
|
;;
|
|
22
100
|
esac
|
|
23
101
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
BASE_URL="$DEFAULT_RELEASE_DOWNLOAD_BASE"
|
|
33
|
-
fi
|
|
34
|
-
if [[ -z "$VERSION" || "$VERSION" == "latest" ]]; then
|
|
35
|
-
VERSION_TAG="${FASED_LOCAL_SIGNER_LATEST_TAG:-}"
|
|
36
|
-
else
|
|
37
|
-
VERSION_TAG="$VERSION"
|
|
38
|
-
fi
|
|
102
|
+
command -v node >/dev/null 2>&1 || {
|
|
103
|
+
echo "Node.js is required to run the transactional signer installer." >&2
|
|
104
|
+
exit 1
|
|
105
|
+
}
|
|
106
|
+
[[ -f "$UPDATER" && ! -L "$UPDATER" ]] || {
|
|
107
|
+
echo "Packaged transactional signer updater is missing: $UPDATER" >&2
|
|
108
|
+
exit 1
|
|
109
|
+
}
|
|
39
110
|
|
|
40
|
-
if [[ "$
|
|
41
|
-
if
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
111
|
+
if [[ "$ACTION" == "install" || "$ACTION" == "verify" ]]; then
|
|
112
|
+
if [[ -z "$VERSION" || "$VERSION" == "latest" ]]; then
|
|
113
|
+
VERSION="$(node -p "require(process.argv[1]).version" "$ROOT/package.json" 2>/dev/null || true)"
|
|
114
|
+
fi
|
|
115
|
+
VERSION="${VERSION#v}"
|
|
116
|
+
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z]+([.-][0-9A-Za-z]+)*)?$ ]]; then
|
|
117
|
+
echo "An exact signer release version X.Y.Z is required; latest is not accepted." >&2
|
|
118
|
+
exit 1
|
|
46
119
|
fi
|
|
47
120
|
fi
|
|
48
121
|
|
|
49
|
-
if [[
|
|
50
|
-
|
|
51
|
-
Could not determine the version-matched fased-signerd release asset.
|
|
52
|
-
|
|
53
|
-
Normal Fased install, dashboard, Gateway, and Fased Network startup do not need fased-signerd.
|
|
54
|
-
The wallet setup wizard normally supplies the installed Fased version automatically.
|
|
55
|
-
|
|
56
|
-
For a manual install, set one of:
|
|
57
|
-
FASED_LOCAL_SIGNER_VERSION=vX.Y.Z
|
|
58
|
-
FASED_LOCAL_SIGNER_BASE_URL=file:///path/to/release FASED_LOCAL_SIGNER_LATEST_TAG=
|
|
59
|
-
FASED_LOCAL_SIGNER_BASE_URL=https://example.invalid/releases/download FASED_LOCAL_SIGNER_VERSION=vX.Y.Z
|
|
60
|
-
EOF
|
|
122
|
+
if [[ -n "$EXPECTED_COMMIT" && ! "$EXPECTED_COMMIT" =~ ^[a-f0-9]{40}$ ]]; then
|
|
123
|
+
echo "--expected-commit must be one exact 40-character Git commit." >&2
|
|
61
124
|
exit 1
|
|
62
125
|
fi
|
|
63
126
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
SUMS_URL="${RELEASES_ROOT}/latest/download/fased-signerd-checksums.txt"
|
|
69
|
-
elif [[ -n "${VERSION_TAG}" ]]; then
|
|
70
|
-
URL="${BASE_URL}/${VERSION_TAG}/${ASSET}"
|
|
71
|
-
SUMS_URL="${BASE_URL}/${VERSION_TAG}/fased-signerd-checksums.txt"
|
|
72
|
-
else
|
|
73
|
-
URL="${BASE_URL}/${ASSET}"
|
|
74
|
-
SUMS_URL="${BASE_URL}/fased-signerd-checksums.txt"
|
|
75
|
-
fi
|
|
127
|
+
mkdir -p "$INSTALL_DIR"
|
|
128
|
+
chmod 700 "$INSTALL_DIR" 2>/dev/null || true
|
|
129
|
+
export FASED_LOCAL_SIGNER_BIN_DIR="$INSTALL_DIR"
|
|
130
|
+
export FASED_WALLET_LOCAL_SIGNER_BIN="$INSTALL_DIR/fased-signerd"
|
|
76
131
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
132
|
+
args=(local-signer "$ACTION")
|
|
133
|
+
if [[ "$ACTION" == "install" || "$ACTION" == "verify" ]]; then
|
|
134
|
+
args+=(--version "$VERSION")
|
|
135
|
+
if [[ -n "$EXPECTED_COMMIT" ]]; then
|
|
136
|
+
args+=(--expected-commit "$EXPECTED_COMMIT")
|
|
81
137
|
fi
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
138
|
+
fi
|
|
139
|
+
if [[ "$ACTION" == "install" ]]; then
|
|
140
|
+
# Keep the candidate read-only and the rollback journal open until all
|
|
141
|
+
# packaged policy helpers/templates are installed successfully.
|
|
142
|
+
args+=(--defer-commit)
|
|
143
|
+
if [[ -n "$CONFIRM_DOWNGRADE" ]]; then
|
|
144
|
+
args+=(--confirm-downgrade "${CONFIRM_DOWNGRADE#v}")
|
|
85
145
|
fi
|
|
86
|
-
|
|
87
|
-
exit 1
|
|
88
|
-
}
|
|
146
|
+
fi
|
|
89
147
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
local
|
|
93
|
-
if
|
|
94
|
-
|
|
95
|
-
return
|
|
148
|
+
TRANSACTION_OPEN=0
|
|
149
|
+
rollback_failed_install() {
|
|
150
|
+
local status=$?
|
|
151
|
+
if [[ "$status" -ne 0 && "$TRANSACTION_OPEN" -eq 1 ]]; then
|
|
152
|
+
node "$UPDATER" local-signer rollback >/dev/null 2>&1 || true
|
|
96
153
|
fi
|
|
97
|
-
|
|
98
|
-
wget -O "$dst" "$src"
|
|
99
|
-
return
|
|
100
|
-
fi
|
|
101
|
-
echo "Need curl or wget to download fased-signerd" >&2
|
|
102
|
-
exit 1
|
|
154
|
+
return "$status"
|
|
103
155
|
}
|
|
156
|
+
trap rollback_failed_install EXIT
|
|
104
157
|
|
|
105
|
-
|
|
106
|
-
local file="$1"
|
|
107
|
-
if command -v sha256sum >/dev/null 2>&1; then
|
|
108
|
-
sha256sum "$file" | awk '{print $1}'
|
|
109
|
-
return
|
|
110
|
-
fi
|
|
111
|
-
if command -v shasum >/dev/null 2>&1; then
|
|
112
|
-
shasum -a 256 "$file" | awk '{print $1}'
|
|
113
|
-
return
|
|
114
|
-
fi
|
|
115
|
-
echo "Need sha256sum or shasum for checksum verification" >&2
|
|
116
|
-
exit 1
|
|
117
|
-
}
|
|
158
|
+
node "$UPDATER" "${args[@]}"
|
|
118
159
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
echo "Verifying checksum from:"
|
|
123
|
-
echo " $SUMS_URL"
|
|
124
|
-
download_to "$SUMS_URL" "${TMP}/checksums.txt"
|
|
125
|
-
EXPECTED="$(awk -v asset="$ASSET" '$2==asset {print $1}' "${TMP}/checksums.txt" | head -n1)"
|
|
126
|
-
if [[ -z "$EXPECTED" ]]; then
|
|
127
|
-
echo "Checksum entry not found for $ASSET in checksums file" >&2
|
|
128
|
-
exit 1
|
|
160
|
+
if [[ "$ACTION" != "install" ]]; then
|
|
161
|
+
trap - EXIT
|
|
162
|
+
exit 0
|
|
129
163
|
fi
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
164
|
+
TRANSACTION_OPEN=1
|
|
165
|
+
|
|
166
|
+
POLICY_HELPER_PATH="${INSTALL_DIR}/fased-signer-owner-policy.mjs"
|
|
167
|
+
POLICY_LAUNCHER_PATH="${INSTALL_DIR}/fased-signer-policy"
|
|
168
|
+
POLICY_HELPER_SOURCE="${ROOT}/scripts/fased-signer-owner-policy.mjs"
|
|
169
|
+
POLICY_LAUNCHER_SOURCE="${ROOT}/scripts/fased-signer-policy-local.sh"
|
|
170
|
+
POLICY_TEMPLATE_SOURCE="${ROOT}/config/signer-policies"
|
|
171
|
+
|
|
172
|
+
required_assets=(
|
|
173
|
+
"$POLICY_HELPER_SOURCE"
|
|
174
|
+
"$POLICY_LAUNCHER_SOURCE"
|
|
175
|
+
"$POLICY_TEMPLATE_SOURCE/README.md"
|
|
176
|
+
"$POLICY_TEMPLATE_SOURCE/agent.json.template"
|
|
177
|
+
"$POLICY_TEMPLATE_SOURCE/mining.json.template"
|
|
178
|
+
"$POLICY_TEMPLATE_SOURCE/vault.json.template"
|
|
179
|
+
)
|
|
180
|
+
if [[ -f "$POLICY_TEMPLATE_SOURCE/network.json.template" ]]; then
|
|
181
|
+
required_assets+=("$POLICY_TEMPLATE_SOURCE/network.json.template")
|
|
136
182
|
fi
|
|
137
|
-
|
|
138
|
-
|
|
183
|
+
for required_path in "${required_assets[@]}"; do
|
|
184
|
+
[[ -f "$required_path" && ! -L "$required_path" ]] || {
|
|
185
|
+
echo "Packaged signer policy asset is missing or unsafe: $required_path" >&2
|
|
186
|
+
exit 1
|
|
187
|
+
}
|
|
188
|
+
done
|
|
139
189
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
190
|
+
install -d -m 0700 "$INSTALL_DIR" "$POLICY_TEMPLATE_DIR"
|
|
191
|
+
install -m 0700 "$POLICY_HELPER_SOURCE" "$POLICY_HELPER_PATH"
|
|
192
|
+
install -m 0700 "$POLICY_LAUNCHER_SOURCE" "$POLICY_LAUNCHER_PATH"
|
|
193
|
+
for template in README.md agent.json.template mining.json.template vault.json.template network.json.template; do
|
|
194
|
+
[[ -f "$POLICY_TEMPLATE_SOURCE/$template" ]] || continue
|
|
195
|
+
install -m 0600 "$POLICY_TEMPLATE_SOURCE/$template" "$POLICY_TEMPLATE_DIR/$template"
|
|
196
|
+
done
|
|
197
|
+
|
|
198
|
+
if [[ "$DEFER_COMMIT" -eq 0 ]]; then
|
|
199
|
+
node "$UPDATER" local-signer commit
|
|
200
|
+
TRANSACTION_OPEN=0
|
|
201
|
+
fi
|
|
202
|
+
trap - EXIT
|
|
203
|
+
|
|
204
|
+
echo "Installed exact transactional signer: $INSTALL_DIR/fased-signerd"
|
|
205
|
+
echo "Installed signer enrollment launcher: $INSTALL_DIR/fased-signer-enroll"
|
|
206
|
+
echo "Installed signer policy launcher: $POLICY_LAUNCHER_PATH"
|
|
207
|
+
echo "Installed fail-closed policy templates: $POLICY_TEMPLATE_DIR"
|
|
208
|
+
cat <<EOF
|
|
209
|
+
Fresh signer-owned wallets remain deny-all. After wallet setup creates a wallet,
|
|
210
|
+
enroll the owner authenticator and apply an explicit reviewed policy as this user:
|
|
211
|
+
1. $INSTALL_DIR/fased-signer-enroll [authenticator-label]
|
|
212
|
+
2. Copy the matching owner-only template from $POLICY_TEMPLATE_DIR and replace
|
|
213
|
+
every REPLACE_WITH_ value.
|
|
214
|
+
3. $POLICY_LAUNCHER_PATH --initial-install --policy-file /absolute/path/to/policy.json
|
|
215
|
+
|
|
216
|
+
Enrollment never enables signing, and copying a template never applies it.
|
|
217
|
+
EOF
|