@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.
Files changed (342) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +44 -29
  3. package/config/dependency-ownership.json +1 -1
  4. package/config/signer-policies/README.md +58 -0
  5. package/config/signer-policies/agent.json.template +32 -0
  6. package/config/signer-policies/mining.json.template +69 -0
  7. package/config/signer-policies/network.json.template +5 -0
  8. package/config/signer-policies/vault.json.template +70 -0
  9. package/config/signer-protocol-v2.json +78 -0
  10. package/config/typescript-noemit-baseline.json +680 -0
  11. package/dist/agents/auth-profiles/store.js +267 -31
  12. package/dist/agents/bash-tools.exec.js +10 -4
  13. package/dist/agents/current-model-catalog.js +3 -3
  14. package/dist/agents/memory-search.js +7 -1
  15. package/dist/agents/model-catalog-access.js +1 -2
  16. package/dist/agents/model-catalog-snapshot.js +1 -1
  17. package/dist/agents/model-catalog-source.js +1 -1
  18. package/dist/agents/model-metadata.js +1 -1
  19. package/dist/agents/model-selection.js +2 -28
  20. package/dist/agents/models-config.providers.js +6 -6
  21. package/dist/agents/pi-embedded-runner/compact.js +15 -7
  22. package/dist/agents/pi-embedded-runner/model.js +1 -1
  23. package/dist/agents/pi-embedded-runner/run/attempt.js +24 -13
  24. package/dist/agents/pi-embedded-runner/run.js +2 -0
  25. package/dist/agents/pi-embedded-runner/tool-split.js +40 -2
  26. package/dist/agents/pi-tool-definition-adapter.js +16 -1
  27. package/dist/agents/pi-tools.js +2 -1
  28. package/dist/agents/sandbox/config.js +1 -1
  29. package/dist/agents/sandbox/context.js +27 -2
  30. package/dist/agents/skills/env-overrides.js +38 -28
  31. package/dist/agents/skills/trust.js +93 -0
  32. package/dist/agents/skills/workspace.js +128 -0
  33. package/dist/agents/skills-clawhub.js +36 -11
  34. package/dist/agents/skills-marketplace-scan.js +49 -0
  35. package/dist/agents/tools/marketplace-offer-draft-tool.js +1 -1
  36. package/dist/agents/tools/mining-tool.js +1 -1
  37. package/dist/agents/tools/session-status-tool.js +1 -1
  38. package/dist/agents/tools/wallet-action-tool.js +172 -36
  39. package/dist/agents/tools/wallet-skill-policy.js +65 -23
  40. package/dist/agents/tools/wallet-tool.js +7 -11
  41. package/dist/auto-reply/reply/directive-handling.fast-lane.js +2 -1
  42. package/dist/auto-reply/reply/directive-handling.impl.js +2 -1
  43. package/dist/auto-reply/reply/directive-handling.model.js +2 -1
  44. package/dist/auto-reply/reply/directive-handling.persist.js +2 -2
  45. package/dist/auto-reply/reply/get-reply-directives-apply.js +2 -0
  46. package/dist/auto-reply/reply/get-reply-inline-actions.js +25 -1
  47. package/dist/auto-reply/reply/model-selection.js +7 -4
  48. package/dist/auto-reply/reply/session-reset-model.js +4 -4
  49. package/dist/brand.js +1 -1
  50. package/dist/build-info.json +3 -3
  51. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  52. package/dist/channel-web.js +2 -2
  53. package/dist/cli/gateway-cli/run.js +8 -0
  54. package/dist/cli/program/command-registry.js +1 -1
  55. package/dist/cli/program/register.onboard.js +2 -3
  56. package/dist/cli/program/register.wallet.js +16 -123
  57. package/dist/cli/providers-cli.js +1 -1
  58. package/dist/cli/sat-cli.js +129 -2
  59. package/dist/cli/update-cli/update-command.js +260 -11
  60. package/dist/commands/auth-choice.apply.api-providers.js +3 -3
  61. package/dist/commands/doctor-config-flow.js +1 -1
  62. package/dist/commands/doctor-legacy-config.js +2 -13
  63. package/dist/commands/model-picker.js +6 -6
  64. package/dist/commands/models/auth.js +1 -1
  65. package/dist/commands/onboard-auth.config-gateways.js +1 -1
  66. package/dist/commands/onboard-auth.credentials.js +32 -8
  67. package/dist/commands/onboard-non-interactive/local/wallet-config.js +28 -27
  68. package/dist/commands/onboard-non-interactive/local.js +5 -1
  69. package/dist/commands/wallet.js +568 -1911
  70. package/dist/config/config.js +2 -2
  71. package/dist/config/io.js +64 -2
  72. package/dist/config/schema.help.js +8 -7
  73. package/dist/config/schema.labels.js +5 -4
  74. package/dist/config/zod-schema.agent-runtime.js +1 -0
  75. package/dist/config/zod-schema.js +5 -0
  76. package/dist/control-ui/assets/{app-DLil9VO1.js → app-MaQnPa5G.js} +1511 -1555
  77. package/dist/control-ui/assets/{config-CU5Zi8Dh.js → config-LeImukCW.js} +10 -10
  78. package/dist/control-ui/assets/{federation-D10Q4eP_.js → federation-DgA9e-Pn.js} +364 -422
  79. package/dist/control-ui/assets/{index-DdE_NIXo.js → index-D4YMr1fA.js} +3 -3
  80. package/dist/control-ui/assets/mining-commit-DFpB_4JN.js +2 -0
  81. package/dist/control-ui/assets/{mining-BdhMn18r.js → mining-qMYs4aD-.js} +70 -50
  82. package/dist/control-ui/assets/{open-external-url-DwSiwMPl.js → open-external-url-ulF1B-sA.js} +3 -3
  83. package/dist/control-ui/assets/{providers-QMn4w2_f.js → providers-CIx9fxc6.js} +2 -2
  84. package/dist/control-ui/assets/{wallet-C2g294QT.js → wallet-DvStR_AT.js} +259 -377
  85. package/dist/control-ui/index.html +1 -1
  86. package/dist/control-ui/version.json +1 -1
  87. package/dist/daemon/systemd-system.js +56 -50
  88. package/dist/extensions/sat-mining/src/protocol-contract.js +43 -3
  89. package/dist/extensions/sat-mining/src/rpc-read.js +291 -84
  90. package/dist/extensions/sat-mining/src/sat-bond-layout.js +5 -2
  91. package/dist/extensions/sat-mining/src/signer-codec-manifest.js +406 -0
  92. package/dist/extensions/sat-mining/src/solana-submit.js +1274 -390
  93. package/dist/extensions/sat-mining/src/submission-ledger.js +349 -0
  94. package/dist/federation/auto-connect.js +98 -8
  95. package/dist/federation/marketplace-capability-adapter.js +33 -7
  96. package/dist/federation/marketplace-delivery-outbox.js +196 -0
  97. package/dist/federation/marketplace-delivery.js +351 -215
  98. package/dist/federation/marketplace-direct-payment.js +272 -141
  99. package/dist/federation/marketplace-escrow.js +607 -249
  100. package/dist/federation/marketplace-settlement-ledger.js +352 -0
  101. package/dist/federation/offers.js +9 -7
  102. package/dist/federation/peer-auth-v2.js +529 -0
  103. package/dist/gateway/a2a-http.js +425 -96
  104. package/dist/gateway/a2a-settlement.js +259 -153
  105. package/dist/gateway/a2a-task-store.js +524 -0
  106. package/dist/gateway/auth.js +38 -2
  107. package/dist/gateway/config-reload.js +46 -33
  108. package/dist/gateway/durable-capacity.js +31 -0
  109. package/dist/gateway/federation-http.js +540 -135
  110. package/dist/gateway/federation-marketplace-run-store.js +397 -0
  111. package/dist/gateway/federation-marketplace.js +535 -230
  112. package/dist/gateway/mutating-admin-rpc-rate-limit.js +5 -0
  113. package/dist/gateway/security-path.js +1 -1
  114. package/dist/gateway/server-http.js +1084 -1205
  115. package/dist/gateway/server-methods/models.js +1 -1
  116. package/dist/gateway/server-methods/secrets.js +40 -0
  117. package/dist/gateway/server-methods.js +1 -2
  118. package/dist/gateway/server-reload-handlers.js +196 -66
  119. package/dist/gateway/server-runtime-config.js +1 -1
  120. package/dist/gateway/server-secrets-runtime.js +288 -0
  121. package/dist/gateway/server.impl.js +73 -42
  122. package/dist/gateway/sessions-patch.js +3 -5
  123. package/dist/index.js +4 -2
  124. package/dist/infra/fasedhub.js +64 -1
  125. package/dist/infra/local-source-paired-update.js +538 -0
  126. package/dist/infra/restart.js +41 -10
  127. package/dist/infra/update-runner.js +96 -0
  128. package/dist/light-update-status.js +11 -11
  129. package/dist/memory/backend-config.js +2 -1
  130. package/dist/memory/session-files.js +16 -2
  131. package/dist/plugin-sdk/{accounts-DxblobYM.js → accounts-Brn3-uWN.js} +1 -1
  132. package/dist/plugin-sdk/{actions-D4UNimWa.js → actions-DRu135h0.js} +2 -2
  133. package/dist/plugin-sdk/{active-listener-CFuy106s.js → active-listener-B_NMtgPL.js} +1 -1
  134. package/dist/plugin-sdk/{audio-preflight-Bwi2Oq03.js → audio-preflight-I4IngVlJ.js} +27 -27
  135. package/dist/plugin-sdk/{audit-Cs0K7LBp.js → audit-C5d2z5U1.js} +1 -1
  136. package/dist/plugin-sdk/{channel-access-D5aHoTY8.js → channel-access-CcFRdRPO.js} +1 -1
  137. package/dist/plugin-sdk/{channel-access-configure-Dvch9mMQ.js → channel-access-configure-DaI5wevh.js} +1 -1
  138. package/dist/plugin-sdk/channel-plugin-common.d.ts +3 -3
  139. package/dist/plugin-sdk/channel-plugin-common.js +4 -4
  140. package/dist/plugin-sdk/{chunk-B0FUGc5A.js → chunk-CyoyqpbG.js} +1 -1
  141. package/dist/plugin-sdk/{chunk-items-DzT4L4Ty.js → chunk-items-DLQ6_lLK.js} +1 -1
  142. package/dist/plugin-sdk/command-status.d.ts +2 -2
  143. package/dist/plugin-sdk/command-status.js +27 -27
  144. package/dist/plugin-sdk/{commands-registry-DmDRhRAU.js → commands-registry-BfqdEWdF.js} +2 -2
  145. package/dist/plugin-sdk/{common-CfUOowOp.js → common-HCcXU-NR.js} +1 -1
  146. package/dist/plugin-sdk/{config-mxULv0fQ.js → config-DlWVeLFB.js} +7113 -6877
  147. package/dist/plugin-sdk/{config-schema-BrkmtFxB.js → config-schema-D_8FVI1C.js} +6798 -3695
  148. package/dist/plugin-sdk/device-pair.d.ts +1 -1
  149. package/dist/plugin-sdk/discord.d.ts +6 -6
  150. package/dist/plugin-sdk/discord.js +19 -19
  151. package/dist/plugin-sdk/file-lock.js +35 -4
  152. package/dist/plugin-sdk/{filesystem-manager-ZoHU8oA7.js → filesystem-manager-DoI8IBNF.js} +1 -1
  153. package/dist/plugin-sdk/{group-mentions-BHRff6j8.d.ts → group-mentions-q3hUTCt7.d.ts} +1 -1
  154. package/dist/plugin-sdk/{handle-action-DbVCF9HZ.js → handle-action-hvwapMKg.js} +13 -13
  155. package/dist/plugin-sdk/{helpers-BXbdgs5H.js → helpers-DMBU4oTo.js} +1 -1
  156. package/dist/plugin-sdk/{image-ops-D7jPxaph.js → image-ops-DQi0n_Tt.js} +1 -1
  157. package/dist/plugin-sdk/index.d.ts +21 -39
  158. package/dist/plugin-sdk/index.js +29 -29
  159. package/dist/plugin-sdk/{login-BRxww6nv.js → login-Ca583Okc.js} +3 -3
  160. package/dist/plugin-sdk/{login-qr-DJXsk9XH.js → login-qr-CGciBSNP.js} +3 -3
  161. package/dist/plugin-sdk/{manager-Y2S_5IlI.js → manager-BegWxNYX.js} +4 -4
  162. package/dist/plugin-sdk/{markdown-tables-DHLFQqaF.js → markdown-tables-DCOXEUfZ.js} +1 -1
  163. package/dist/plugin-sdk/{media-Czo4carg.js → media-CAdQF5TG.js} +47 -47
  164. package/dist/plugin-sdk/{memory-search-DTjIMw8J.js → memory-search-CrFPOeTH.js} +4 -1
  165. package/dist/plugin-sdk/{monitor-M_ta2lMc.js → monitor-B4KF4Kpo.js} +31 -31
  166. package/dist/plugin-sdk/{monitor-wYVncM9w.js → monitor-Bb6x1KAG.js} +32 -32
  167. package/dist/plugin-sdk/{openresponses-http-B2GmeSt4.js → openresponses-http-DCTO8JkL.js} +27 -27
  168. package/dist/plugin-sdk/{optional-runtime-dependency-DdMbxS24.js → optional-runtime-dependency-0dznm3ZO.js} +1 -1
  169. package/dist/plugin-sdk/{outbound-Db8mRN6P.js → outbound-BgVDdHxx.js} +6 -6
  170. package/dist/plugin-sdk/{outbound-attachment-BqFjcypb.js → outbound-attachment-QqTnIhZL.js} +2 -2
  171. package/dist/plugin-sdk/{pairing-message-B3GC_7CD.js → pairing-message-D0CoLHRJ.js} +1 -1
  172. package/dist/plugin-sdk/{pairing-message-B3bHYGaw.d.ts → pairing-message-DHPDFZbC.d.ts} +2 -2
  173. package/dist/plugin-sdk/{pairing-store-CQikgIbw.js → pairing-store-BChahgI2.js} +2 -2
  174. package/dist/plugin-sdk/{pi-model-discovery-CY3m5zJP.js → pi-model-discovery-BX_JLcEJ.js} +1 -1
  175. package/dist/plugin-sdk/{pi-model-discovery-runtime-DSh1T2pn.js → pi-model-discovery-runtime-DxTMz_XF.js} +2 -2
  176. package/dist/plugin-sdk/provider-web-search-config-contract.d.ts +2 -2
  177. package/dist/plugin-sdk/{pw-ai-AFUqn-tQ.js → pw-ai-natjh3rm.js} +3 -3
  178. package/dist/plugin-sdk/{qmd-manager-DSyx77KY.js → qmd-manager-CgRaTxUq.js} +1 -1
  179. package/dist/plugin-sdk/{query-expansion-CAI2kKLQ.js → query-expansion-BG3FgzF7.js} +14 -3
  180. package/dist/plugin-sdk/{replies-Fzh9PhXl.js → replies-ChYo5ZQM.js} +2 -2
  181. package/dist/plugin-sdk/{resolve-outbound-target-KpF3co6T.js → resolve-outbound-target-D-KGgHJZ.js} +1 -1
  182. package/dist/plugin-sdk/{resolve-route-CDl74O19.js → resolve-route-C8tvQm8Z.js} +1 -1
  183. package/dist/plugin-sdk/{retry-policy-D4uiqUOG.js → retry-policy-C6SjKjQA.js} +1 -1
  184. package/dist/plugin-sdk/{runtime-Bb6KRnCC.js → runtime-2B9_WKoI.js} +8 -3
  185. package/dist/plugin-sdk/{runtime-dependency-DLDmB94f.js → runtime-dependency-DczkvPxn.js} +2 -2
  186. package/dist/plugin-sdk/sat-runtime.d.ts +565 -309
  187. package/dist/plugin-sdk/sat-runtime.js +29 -29
  188. package/dist/plugin-sdk/{send-C4k4JuJN.js → send-B6KkGKZD.js} +6 -6
  189. package/dist/plugin-sdk/{send-D-uDKGIq.js → send-CFzGKJXo.js} +6 -6
  190. package/dist/plugin-sdk/{send-Du8ykP1k.js → send-DCO441U7.js} +8 -8
  191. package/dist/plugin-sdk/{send-5nFktR1n.js → send-gDoGA-7e.js} +5 -5
  192. package/dist/plugin-sdk/{send-Bfzf11VY.js → send-q9HXrSwK.js} +7 -7
  193. package/dist/plugin-sdk/{session-CS-Td9EM.js → session-DHD4ZKyG.js} +2 -2
  194. package/dist/plugin-sdk/{skill-commands-CFAlXWHk.js → skill-commands-FKEPLS7T.js} +201 -26
  195. package/dist/plugin-sdk/{slack-CxE1mfzj.js → slack-BHmvqgjH.js} +39 -39
  196. package/dist/plugin-sdk/{slack-actions-BcMkNv1Z.js → slack-actions-DhbMcp8M.js} +11 -11
  197. package/dist/plugin-sdk/slack.d.ts +6 -6
  198. package/dist/plugin-sdk/slack.js +9 -9
  199. package/dist/plugin-sdk/{sticker-cache-CGzGWu00.js → sticker-cache-By5AcorL.js} +3 -3
  200. package/dist/plugin-sdk/{tables-bFXyRpkx.js → tables-B3jr0Pvq.js} +1 -1
  201. package/dist/plugin-sdk/{targets-DH7a9lKB.js → targets-CtSbTxYX.js} +1 -1
  202. package/dist/plugin-sdk/{telegram-actions-DaEcYQ8r.js → telegram-actions-DGnBz1YT.js} +30 -30
  203. package/dist/plugin-sdk/telegram.d.ts +6 -6
  204. package/dist/plugin-sdk/telegram.js +8 -8
  205. package/dist/plugin-sdk/{thread-bindings.lifecycle-CgOvvdw8.js → thread-bindings.lifecycle-QbkNl-m6.js} +3 -3
  206. package/dist/plugin-sdk/{thread-bindings.state-CQpk44Hq.js → thread-bindings.state-D9hg_M1c.js} +2 -2
  207. package/dist/plugin-sdk/tmp-fased-dir-EJGTmL1Q.d.ts +486 -0
  208. package/dist/plugin-sdk/{types-vcJrC_uv.d.ts → types-BdwdFCD6.d.ts} +2 -3
  209. package/dist/plugin-sdk/{types-DFAW-n1J.d.ts → types-BrCpYMxn.d.ts} +2 -2
  210. package/dist/plugin-sdk/{types-DyhXnYUr.d.ts → types-D0kDG8l0.d.ts} +3 -2
  211. package/dist/plugin-sdk/{types.plugin-_fbu40Re.d.ts → types.plugin-BcSBq42x.d.ts} +8 -3
  212. package/dist/plugin-sdk/{web-CInY-lCv.js → web-DUJwrTYs.js} +32 -32
  213. package/dist/plugin-sdk/{whatsapp-actions-BtSc2CBv.js → whatsapp-actions-Bj_rOncr.js} +13 -13
  214. package/dist/plugin-sdk/{whatsapp-heartbeat-Bg9TuYzl.js → whatsapp-heartbeat-B1WHkJIg.js} +2 -2
  215. package/dist/plugin-sdk/whatsapp.d.ts +13 -13
  216. package/dist/plugin-sdk/whatsapp.js +12 -12
  217. package/dist/plugin-sdk/{wsl-C4DGFkOd.js → wsl-J-HscWxS.js} +3 -3
  218. package/dist/plugin-sdk/{zod-schema.providers-core-BEbNizPe.d.ts → zod-schema.providers-core-CIzCjXH9.d.ts} +61 -61
  219. package/dist/providers/refresh.js +1 -1
  220. package/dist/providers/registry.js +1 -1
  221. package/dist/secrets/apply.js +1 -1
  222. package/dist/secrets/runtime.js +1 -1
  223. package/dist/wallet/external-submission-ledger.js +376 -0
  224. package/dist/wallet/legacy-embedded-keystore.js +40 -0
  225. package/dist/wallet/local-socket-signer-archive.js +30 -0
  226. package/dist/wallet/local-socket-signer-lifecycle.js +97 -0
  227. package/dist/wallet/local-socket-signer-policy.js +166 -0
  228. package/dist/wallet/local-socket-signer-protocol.js +578 -117
  229. package/dist/wallet/native-signer-wallet-id.js +25 -0
  230. package/dist/wallet/providers/alchemy-adapter.js +3 -0
  231. package/dist/wallet/providers/local-socket-signer-adapter.js +380 -105
  232. package/dist/wallet/providers/turnkey-adapter.js +292 -34
  233. package/dist/wallet/providers/wallet-standard-adapter.js +100 -0
  234. package/dist/wallet/signer-network-admin.js +184 -0
  235. package/dist/wallet/signer-protocol-v2.generated.js +92 -0
  236. package/dist/wallet/solana-bond-signing.js +157 -69
  237. package/dist/wallet/solana-reviewed-transaction.js +375 -0
  238. package/dist/wallet/solana-swap.js +520 -64
  239. package/dist/wallet/solana-transaction-inspection.js +106 -4
  240. package/dist/wallet/solana-trigger.js +658 -320
  241. package/dist/wallet/turnkey-reviewed-state.js +370 -0
  242. package/dist/wallet/wallet-approval-auth.js +17 -28
  243. package/dist/wallet/wallet-atomic-state.js +53 -0
  244. package/dist/wallet/wallet-canary.js +0 -1
  245. package/dist/wallet/wallet-inbound-events.js +16 -11
  246. package/dist/wallet/wallet-policy-simulation.js +1 -1
  247. package/dist/wallet/wallet-policy.js +93 -37
  248. package/dist/wallet/wallet-provider-capabilities.js +28 -4
  249. package/dist/wallet/wallet-provider-registry.js +57 -44
  250. package/dist/wallet/wallet-provider-resolver.js +62 -63
  251. package/dist/wallet/wallet-runtime-config.js +28 -41
  252. package/dist/wallet/wallet-secrets-store.js +22 -0
  253. package/dist/wallet/wallet-send-approvals.js +1891 -589
  254. package/dist/wallet/wallet-send-execution-ledger.js +292 -0
  255. package/dist/wallet/wallet-settlement-links.js +14 -13
  256. package/dist/wallet/wallet-standard-review.js +353 -0
  257. package/dist/wallet/wallet-status.js +0 -9
  258. package/dist/wallet/wallet-task-ledger.js +16 -2
  259. package/dist/web/auto-reply/heartbeat-runner.js +1 -1
  260. package/dist/web/auto-reply/monitor.js +2 -2
  261. package/dist/wizard/host-security-capability.js +14 -23
  262. package/dist/wizard/onboarding.finalize.js +63 -184
  263. package/dist/wizard/onboarding.host-security.js +117 -1367
  264. package/dist/wizard/onboarding.js +172 -217
  265. package/dist/wizard/onboarding.wallet.js +232 -785
  266. package/extensions/acpx/package.json +1 -1
  267. package/extensions/bluebubbles/package.json +1 -1
  268. package/extensions/copilot-proxy/package.json +1 -1
  269. package/extensions/diagnostics-otel/package.json +1 -1
  270. package/extensions/fased-federation/package.json +1 -1
  271. package/extensions/google-gemini-cli-auth/package.json +1 -1
  272. package/extensions/imessage/package.json +1 -1
  273. package/extensions/irc/package.json +1 -1
  274. package/extensions/line/package.json +1 -1
  275. package/extensions/llm-task/package.json +1 -1
  276. package/extensions/lobster/package.json +1 -1
  277. package/extensions/matrix/CHANGELOG.md +18 -0
  278. package/extensions/matrix/package.json +1 -1
  279. package/extensions/mattermost/package.json +1 -1
  280. package/extensions/memory-core/package.json +2 -2
  281. package/extensions/memory-lancedb/package.json +1 -1
  282. package/extensions/minimax-portal-auth/package.json +1 -1
  283. package/extensions/msteams/CHANGELOG.md +18 -0
  284. package/extensions/msteams/package.json +1 -1
  285. package/extensions/nextcloud-talk/package.json +1 -1
  286. package/extensions/nostr/CHANGELOG.md +18 -0
  287. package/extensions/nostr/package.json +1 -1
  288. package/extensions/open-prose/package.json +1 -1
  289. package/extensions/sat-mining/index.ts +587 -154
  290. package/extensions/sat-mining/package.json +1 -1
  291. package/extensions/sat-mining/signer-codec-schema.v1.json +374 -0
  292. package/extensions/sat-mining/src/audit-store.ts +91 -5
  293. package/extensions/sat-mining/src/claim-service.ts +85 -14
  294. package/extensions/sat-mining/src/client.ts +13 -0
  295. package/extensions/sat-mining/src/config.ts +9 -0
  296. package/extensions/sat-mining/src/cycle-progress.ts +16 -8
  297. package/extensions/sat-mining/src/epoch-service.ts +9 -5
  298. package/extensions/sat-mining/src/gateway-runner.ts +21 -1
  299. package/extensions/sat-mining/src/protocol-contract.ts +45 -1
  300. package/extensions/sat-mining/src/recovery-service.ts +312 -0
  301. package/extensions/sat-mining/src/round-watcher.ts +391 -81
  302. package/extensions/sat-mining/src/rpc-read.ts +431 -106
  303. package/extensions/sat-mining/src/runtime.ts +16 -0
  304. package/extensions/sat-mining/src/sat-bond-layout.ts +6 -0
  305. package/extensions/sat-mining/src/signer-codec-manifest.ts +429 -0
  306. package/extensions/sat-mining/src/solana-submit.ts +1544 -436
  307. package/extensions/sat-mining/src/submission-ledger.ts +434 -0
  308. package/extensions/signal/package.json +1 -1
  309. package/extensions/synology-chat/package.json +1 -1
  310. package/extensions/tlon/package.json +1 -1
  311. package/extensions/twitch/CHANGELOG.md +18 -0
  312. package/extensions/twitch/package.json +1 -1
  313. package/extensions/voice-call/CHANGELOG.md +18 -0
  314. package/extensions/voice-call/package.json +1 -1
  315. package/extensions/zalo/CHANGELOG.md +18 -0
  316. package/extensions/zalo/package.json +1 -1
  317. package/extensions/zalouser/CHANGELOG.md +18 -0
  318. package/extensions/zalouser/package.json +1 -1
  319. package/install.sh +4951 -0
  320. package/package.json +23 -5
  321. package/scripts/fased-host-updater.mjs +1421 -0
  322. package/scripts/fased-host-updaterctl.mjs +186 -0
  323. package/scripts/fased-managed-service.sh +36 -0
  324. package/scripts/fased-managed-updater.mjs +3065 -156
  325. package/scripts/fased-signer-enroll-hosting.sh +275 -0
  326. package/scripts/fased-signer-network-hosting.sh +143 -0
  327. package/scripts/fased-signer-owner-policy.mjs +1442 -0
  328. package/scripts/fased-signer-policy-hosting.sh +50 -0
  329. package/scripts/fased-signer-policy-local.sh +26 -0
  330. package/scripts/hosted-release-manifest.mjs +185 -0
  331. package/scripts/install-fased-signerd.sh +183 -108
  332. package/scripts/install-managed-runtime.mjs +212 -10
  333. package/scripts/managed-runtime-layout.mjs +75 -3
  334. package/scripts/migrate-hosted-signer-v2.mjs +58 -0
  335. package/scripts/start-managed.sh +173 -360
  336. package/dist/control-ui/assets/mining-commit-R-6nu87p.js +0 -2
  337. package/dist/plugin-sdk/tmp-fased-dir-CS6zsYEE.d.ts +0 -77
  338. package/dist/wallet/local-socket-signer-broker.js +0 -224
  339. package/dist/wallet/local-socket-signer-custody.js +0 -42
  340. package/dist/wallet/providers/embedded-keystore-adapter.js +0 -402
  341. package/dist/wallet/providers/privy-adapter.js +0 -80
  342. 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
- OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
10
- ARCH="$(uname -m)"
11
- case "$ARCH" in
12
- x86_64|amd64) ARCH="amd64" ;;
13
- aarch64|arm64) ARCH="arm64" ;;
14
- esac
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
- mkdir -p "$INSTALL_DIR"
25
- BIN_PATH="${INSTALL_DIR}/fased-signerd"
26
- TMP="$(mktemp -d)"
27
- trap 'rm -rf "$TMP"' EXIT
28
-
29
- DEFAULT_RELEASE_DOWNLOAD_BASE="https://github.com/fased-ai/fased/releases/download"
30
- BASE_URL="${FASED_LOCAL_SIGNER_BASE_URL:-}"
31
- if [[ -z "$BASE_URL" ]]; then
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 [[ "$BASE_URL" == "$DEFAULT_RELEASE_DOWNLOAD_BASE" && ( -z "$VERSION_TAG" || "$VERSION_TAG" == "latest" ) ]]; then
41
- if command -v node >/dev/null 2>&1 && [[ -f "${ROOT}/package.json" ]]; then
42
- PACKAGE_VERSION="$(cd "$ROOT" && node -p "require('./package.json').version" 2>/dev/null || true)"
43
- if [[ "$PACKAGE_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+([+-][0-9A-Za-z.-]+)?$ ]]; then
44
- VERSION_TAG="v${PACKAGE_VERSION}"
45
- fi
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 [[ "$BASE_URL" == "$DEFAULT_RELEASE_DOWNLOAD_BASE" && ( -z "$VERSION_TAG" || "$VERSION_TAG" == "latest" ) ]]; then
50
- cat >&2 <<'EOF'
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
- ASSET="fased-signerd-${OS}-${ARCH}"
65
- if [[ "${VERSION_TAG}" == "latest" && "$BASE_URL" == */releases/download ]]; then
66
- RELEASES_ROOT="${BASE_URL%/download}"
67
- URL="${RELEASES_ROOT}/latest/download/${ASSET}"
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
- download() {
78
- if command -v curl >/dev/null 2>&1; then
79
- curl -fsSL "$URL" -o "${TMP}/fased-signerd"
80
- return
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
- if command -v wget >/dev/null 2>&1; then
83
- wget -O "${TMP}/fased-signerd" "$URL"
84
- return
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
- echo "Need curl or wget to download fased-signerd" >&2
87
- exit 1
88
- }
146
+ fi
89
147
 
90
- download_to() {
91
- local src="$1"
92
- local dst="$2"
93
- if command -v curl >/dev/null 2>&1; then
94
- curl -fsSL "$src" -o "$dst"
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
- if command -v wget >/dev/null 2>&1; then
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
- sha256_file() {
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
- echo "Installing fased-signerd (${OS}/${ARCH}) from:"
120
- echo " $URL"
121
- download
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
- ACTUAL="$(sha256_file "${TMP}/fased-signerd")"
131
- if [[ "$ACTUAL" != "$EXPECTED" ]]; then
132
- echo "Checksum mismatch for $ASSET" >&2
133
- echo "expected: $EXPECTED" >&2
134
- echo "actual: $ACTUAL" >&2
135
- exit 1
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
- echo "Checksum OK: $ACTUAL"
138
- install -m 0755 "${TMP}/fased-signerd" "$BIN_PATH"
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
- echo "Installed: $BIN_PATH"
141
- echo "Export for Fased:"
142
- echo " export FASED_WALLET_LOCAL_SIGNER_BIN=\"$BIN_PATH\""
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