@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
@@ -1,3 +1,4 @@
1
+ import { randomBytes } from "node:crypto";
1
2
  import type { FasedAgentPluginApi } from "fased/plugin-sdk";
2
3
  import { computeAutoPlannerDecision } from "./auto-planner.js";
3
4
  import { refreshSatChainTime } from "./chain-time.js";
@@ -9,16 +10,15 @@ import {
9
10
  hasSuccessfulClaimOrCloseRecord,
10
11
  } from "./cycle-progress.js";
11
12
  import { runSatGatewayMethod } from "./gateway-runner.js";
12
- import { SAT_PROTOCOL_CONSTANTS } from "./protocol-contract.js";
13
+ import { resolveSatGenesisProfileContract, SAT_PROTOCOL_CONSTANTS } from "./protocol-contract.js";
13
14
  import {
14
15
  inspectSatCycle,
15
- inspectSatCycleAccountExists,
16
16
  inspectSatCycleRegistryMeta,
17
+ inspectSatChainSlot,
17
18
  inspectSatGlobalState,
18
19
  inspectSatLamportBalance,
19
20
  inspectSatMinerCapital,
20
21
  inspectSatMinerCycle,
21
- inspectSatMinerCycleAccountExists,
22
22
  inspectSatRegistryReserveLamports,
23
23
  inspectSatRentExemptionLamports,
24
24
  inspectSatTreasuryVaultLamports,
@@ -39,6 +39,7 @@ import {
39
39
  scheduleWorkerNextRun,
40
40
  type SatMiningRuntimeState,
41
41
  } from "./runtime.js";
42
+ import { buildSatCycleCommitment } from "./solana-submit.js";
42
43
  import { computeMiningStrategy } from "./strategy-engine.js";
43
44
  import type { SatSkillLiveContext } from "./strategy-skill.js";
44
45
 
@@ -47,8 +48,6 @@ const SAT_CYCLE_EROSION_PPM = SAT_PROTOCOL_CONSTANTS.cycleErosionPpm;
47
48
  const SAT_MIN_ENTRY_LAMPORTS = SAT_PROTOCOL_CONSTANTS.minimumEntryLamports;
48
49
  const SAT_DEFAULT_RESERVE_LAMPORTS = 150_000_000n;
49
50
  const SAT_DEFAULT_FEE_BUFFER_LAMPORTS = 250_000n;
50
- const SAT_DEFAULT_REGISTRY_RESERVE_TARGET_LAMPORTS =
51
- SAT_PROTOCOL_CONSTANTS.registryReserveTargetLamports;
52
51
  const SAT_MAX_PENDING_CYCLE_BACKLOG = 2;
53
52
  const SAT_CAPITAL_SAFETY_BUFFER_MIN_LAMPORTS = 100_000_000n;
54
53
  const SAT_CAPITAL_SAFETY_BUFFER_MAX_LAMPORTS = 1_000_000_000n;
@@ -258,6 +257,22 @@ function cycleErosionLamports(committedLamports: bigint, cycleErosionPpm: bigint
258
257
  return (committedLamports * cycleErosionPpm) / SAT_RATIO_FP_SCALE;
259
258
  }
260
259
 
260
+ function cycleCommitCollateralLamports(committedLamports: bigint, cycleErosionPpm: bigint): bigint {
261
+ const erosion = cycleErosionLamports(committedLamports, cycleErosionPpm);
262
+ const nonRevealPenalty =
263
+ (committedLamports * BigInt(SAT_PROTOCOL_CONSTANTS.cycleNonRevealPenaltyBps)) / 10_000n;
264
+ return nonRevealPenalty > erosion ? nonRevealPenalty : erosion;
265
+ }
266
+
267
+ export function shouldParticipateInSatCycle(params: {
268
+ cycleId: number;
269
+ launchCycleId: number;
270
+ cadence: 1 | 2 | 6 | 12;
271
+ }): boolean {
272
+ if (params.cycleId < params.launchCycleId) return false;
273
+ return (params.cycleId - params.launchCycleId) % params.cadence === 0;
274
+ }
275
+
261
276
  function floorCommitToUsableFreeCapital(params: {
262
277
  desiredCommitLamports: bigint;
263
278
  freeCapitalLamports: bigint;
@@ -269,7 +284,7 @@ function floorCommitToUsableFreeCapital(params: {
269
284
  const retainedFreeLamports = params.retainedFreeLamports ?? 0n;
270
285
  while (commitLamports >= params.minimumEntryLamports) {
271
286
  const requiredLamports =
272
- commitLamports + cycleErosionLamports(commitLamports, params.cycleErosionPpm);
287
+ commitLamports + cycleCommitCollateralLamports(commitLamports, params.cycleErosionPpm);
273
288
  if (requiredLamports + retainedFreeLamports <= params.freeCapitalLamports) {
274
289
  return commitLamports;
275
290
  }
@@ -324,13 +339,13 @@ function computeCapitalContinuityReserveLamports(params: {
324
339
  ) {
325
340
  return 0n;
326
341
  }
327
- const minimumEntryWithErosion =
342
+ const minimumEntryWithCollateral =
328
343
  params.minimumEntryLamports +
329
- cycleErosionLamports(params.minimumEntryLamports, params.cycleErosionPpm);
330
- if (params.freeCapitalLamports < minimumEntryWithErosion * 2n) {
344
+ cycleCommitCollateralLamports(params.minimumEntryLamports, params.cycleErosionPpm);
345
+ if (params.freeCapitalLamports < minimumEntryWithCollateral * 2n) {
331
346
  return 0n;
332
347
  }
333
- return minimumEntryWithErosion;
348
+ return minimumEntryWithCollateral;
334
349
  }
335
350
 
336
351
  export function createSatRoundWatcherService(params: {
@@ -370,7 +385,7 @@ export function createSatRoundWatcherService(params: {
370
385
  const treasuryVaultBalance = BigInt(treasuryVault?.lamports ?? "0");
371
386
  const reserveTarget = BigInt(
372
387
  rentExemption?.registryReserveTargetLamports ??
373
- SAT_DEFAULT_REGISTRY_RESERVE_TARGET_LAMPORTS.toString(),
388
+ resolveSatGenesisProfileContract(state.activeConfig.network).registryReserveTargetLamports,
374
389
  );
375
390
  const protocolVaultLamports = BigInt(rentExemption?.protocolVaultLamports ?? "0");
376
391
  const openCycleLamports = params.needsOpenCycle
@@ -450,6 +465,7 @@ export function createSatRoundWatcherService(params: {
450
465
  api,
451
466
  method: "sat.withdrawMinerCapital",
452
467
  payload: { lamports: Number(missingLamports) },
468
+ workflowId: `round-watcher:cycle:${params.cycleId}:withdraw-operating-rent`,
453
469
  });
454
470
  walletSpendableLamports += missingLamports;
455
471
  } catch (error) {
@@ -471,6 +487,7 @@ export function createSatRoundWatcherService(params: {
471
487
  payload: {
472
488
  targetBalanceLamports: Number(targetReserveBalance),
473
489
  },
490
+ workflowId: `round-watcher:cycle:${params.cycleId}:treasury-reserve-refill`,
474
491
  });
475
492
  } catch (error) {
476
493
  if (isInsufficientLamportsError(error)) {
@@ -493,8 +510,9 @@ export function createSatRoundWatcherService(params: {
493
510
  try {
494
511
  await runSatGatewayMethod({
495
512
  api,
496
- method: "sat.bootstrapRegistryReserve",
497
- payload: {},
513
+ method: "sat.topUpRegistryReserve",
514
+ payload: { targetBalanceLamports: Number(targetReserveBalance) },
515
+ workflowId: `round-watcher:cycle:${params.cycleId}:wallet-reserve-top-up`,
498
516
  });
499
517
  } catch (error) {
500
518
  if (isInsufficientLamportsError(error)) {
@@ -572,7 +590,7 @@ export function createSatRoundWatcherService(params: {
572
590
  markWorkerTarget(state, "roundWatcher", activeCycleId, "participation");
573
591
 
574
592
  const secondsUntilClose = cycleCloseTs(activeCycleId) - nowSec;
575
- if (secondsUntilClose <= SUBMISSION_GUARD_SECONDS) {
593
+ if (secondsUntilClose <= SUBMISSION_GUARD_SECONDS && execution.commitSubmitted !== true) {
576
594
  markWorkerWaiting(
577
595
  state,
578
596
  "roundWatcher",
@@ -583,56 +601,141 @@ export function createSatRoundWatcherService(params: {
583
601
  }
584
602
 
585
603
  const authority = state.activeWalletAddress;
586
- const localWatcherConfirmed = state.workers.roundWatcher.lastSuccessAt != null;
587
- const localOpenRecorded =
588
- localWatcherConfirmed ||
589
- state.recentActions.some(
590
- (entry) =>
591
- entry.status === "success" &&
592
- typeof entry.cycleId === "number" &&
593
- entry.cycleId === activeCycleId &&
594
- (entry.action === "openCycle" || entry.action === "submitCycle"),
595
- );
596
- const localSubmitRecorded =
597
- localWatcherConfirmed ||
598
- state.recentActions.some(
599
- (entry) =>
600
- entry.status === "success" &&
601
- typeof entry.cycleId === "number" &&
602
- entry.cycleId === activeCycleId &&
603
- entry.action === "submitCycle",
604
- );
604
+ const localOpenRecorded = state.recentActions.some(
605
+ (entry) =>
606
+ entry.status === "success" &&
607
+ typeof entry.cycleId === "number" &&
608
+ entry.cycleId === activeCycleId &&
609
+ (entry.action === "openCycle" ||
610
+ entry.action === "commitCycle" ||
611
+ entry.action === "revealCycle"),
612
+ );
613
+ const localCommitRecorded = state.recentActions.some(
614
+ (entry) =>
615
+ entry.status === "success" &&
616
+ typeof entry.cycleId === "number" &&
617
+ entry.cycleId === activeCycleId &&
618
+ (entry.action === "commitCycle" || entry.action === "revealCycle"),
619
+ );
605
620
  let cycleExists = execution.openRoundSubmitted && localOpenRecorded;
621
+ let onChainCycle = null;
606
622
  if (!cycleExists) {
607
- cycleExists = await withRoundWatcherTimeout("cycle account existence", () =>
608
- inspectSatCycleAccountExists(state.activeConfig, {
623
+ onChainCycle = await withRoundWatcherTimeout("cycle account", () =>
624
+ inspectSatCycle(state.activeConfig, {
609
625
  cycleId: activeCycleId,
610
626
  }),
611
- ).catch(() => false);
627
+ ).catch(() => null);
628
+ cycleExists = onChainCycle != null;
612
629
  }
613
- let minerCycleExists = execution.participationSubmitted && localSubmitRecorded;
614
- if (authority != null && !minerCycleExists) {
615
- minerCycleExists = await withRoundWatcherTimeout("miner-cycle account existence", () =>
616
- inspectSatMinerCycleAccountExists(state.activeConfig, {
630
+ let onChainMinerCycle = null;
631
+ if (authority != null) {
632
+ onChainMinerCycle = await withRoundWatcherTimeout("miner-cycle account", () =>
633
+ inspectSatMinerCycle(state.activeConfig, {
617
634
  authority,
618
635
  cycleId: activeCycleId,
619
636
  }),
620
- ).catch(() => false);
637
+ ).catch(() => null);
621
638
  }
639
+ let minerCycleExists = onChainMinerCycle != null;
640
+ let cycleRentFundingPrepared = false;
622
641
  if (authority) {
623
642
  execution.openRoundSubmitted = execution.openRoundSubmitted || cycleExists;
624
- if (minerCycleExists) {
643
+ if (minerCycleExists || localCommitRecorded) {
625
644
  execution.openRoundSubmitted = true;
645
+ execution.commitSubmitted = true;
646
+ }
647
+ if (onChainMinerCycle?.validParticipation === true) {
626
648
  execution.participationSubmitted = true;
627
- } else if (
628
- execution.participationSubmitted &&
629
- state.workers.roundWatcher.lastSuccessAt == null
630
- ) {
649
+ markWorkerSuccess(
650
+ state,
651
+ "roundWatcher",
652
+ `cycle ${activeCycleId} reveal confirmed on-chain`,
653
+ );
654
+ } else if (execution.participationSubmitted && onChainMinerCycle == null) {
631
655
  execution.participationSubmitted = false;
632
656
  }
633
657
  }
634
658
 
635
- if (!execution.participationSubmitted) {
659
+ const cycleCadence = state.activeConfig.cycleCadence ?? 1;
660
+ if (execution.commitSubmitted !== true && cycleCadence > 1) {
661
+ const cadenceGlobalState = await withRoundWatcherTimeout("cadence launch cycle", () =>
662
+ inspectSatGlobalState(state.activeConfig),
663
+ ).catch(() => null);
664
+ const launchCycleId = parseOptionalCount(cadenceGlobalState?.launchCycleId);
665
+ if (launchCycleId == null) {
666
+ markWorkerWaiting(
667
+ state,
668
+ "roundWatcher",
669
+ `cycle ${activeCycleId} waiting: launch cycle is unavailable for the every-${cycleCadence}-cycle schedule`,
670
+ );
671
+ scheduleWorkerNextRun(state, "roundWatcher", SAT_ROUND_WATCHER_APPROACH_DELAY_MS);
672
+ return;
673
+ }
674
+ if (
675
+ !shouldParticipateInSatCycle({
676
+ cycleId: activeCycleId,
677
+ launchCycleId,
678
+ cadence: cycleCadence,
679
+ })
680
+ ) {
681
+ markWorkerWaiting(
682
+ state,
683
+ "roundWatcher",
684
+ `economy schedule skips cycle ${activeCycleId}; participating every ${cycleCadence} cycles`,
685
+ );
686
+ scheduleWorkerNextRun(state, "roundWatcher", delayUntilNextCycleMs(secondsUntilClose));
687
+ return;
688
+ }
689
+ }
690
+
691
+ if (!cycleExists) {
692
+ const cycleOpenDeadline =
693
+ activeCycleId * SAT_CYCLE_SECONDS + SAT_PROTOCOL_CONSTANTS.cycleOpenGraceSeconds;
694
+ if (nowSec >= cycleOpenDeadline) {
695
+ markWorkerWaiting(
696
+ state,
697
+ "roundWatcher",
698
+ `cycle ${activeCycleId} was not opened during its protected opening window; waiting for the next cycle`,
699
+ );
700
+ scheduleWorkerNextRun(state, "roundWatcher", delayUntilNextCycleMs(secondsUntilClose));
701
+ return;
702
+ }
703
+ const walletBalanceLamports = authority
704
+ ? await withRoundWatcherTimeout("signer wallet balance", () =>
705
+ inspectSatLamportBalance(state.activeConfig, { address: authority }),
706
+ ).catch(() => null)
707
+ : null;
708
+ const rentFunding = await ensureCycleRentFunding({
709
+ cycleId: activeCycleId,
710
+ walletBalanceLamports,
711
+ needsOpenCycle: true,
712
+ needsSubmit: authority != null && !minerCycleExists,
713
+ });
714
+ if (!rentFunding.ok) {
715
+ markWorkerWaiting(state, "roundWatcher", rentFunding.reason);
716
+ scheduleWorkerNextRun(state, "roundWatcher", SAT_RENT_WAIT_DELAY_MS);
717
+ return;
718
+ }
719
+ cycleRentFundingPrepared = true;
720
+ try {
721
+ await runSatGatewayMethod({
722
+ api,
723
+ method: "sat.openCycle",
724
+ payload: { cycleId: activeCycleId },
725
+ });
726
+ } catch (error) {
727
+ if (!isAlreadyInitializedCycleError(error)) {
728
+ throw error;
729
+ }
730
+ }
731
+ cycleExists = true;
732
+ execution.openRoundSubmitted = true;
733
+ onChainCycle = await withRoundWatcherTimeout("opened cycle", () =>
734
+ inspectSatCycle(state.activeConfig, { cycleId: activeCycleId }),
735
+ ).catch(() => null);
736
+ }
737
+
738
+ if (execution.commitSubmitted !== true) {
636
739
  const round = {
637
740
  epochId: activeCycleId,
638
741
  microRoundId: 0,
@@ -992,7 +1095,7 @@ export function createSatRoundWatcherService(params: {
992
1095
  markWorkerWaiting(
993
1096
  state,
994
1097
  "roundWatcher",
995
- `cycle ${cycleId} skipped: free miner capital cannot cover commit plus erosion while keeping ${formatLamportsAsSol(retainedFreeLamports)} uncommitted for recovery`,
1098
+ `cycle ${cycleId} skipped: free miner capital cannot cover commit plus worst-case reveal collateral while keeping ${formatLamportsAsSol(retainedFreeLamports)} uncommitted for recovery`,
996
1099
  );
997
1100
  scheduleWorkerNextRun(
998
1101
  state,
@@ -1096,12 +1199,14 @@ export function createSatRoundWatcherService(params: {
1096
1199
  inspectSatLamportBalance(state.activeConfig, { address: authority }),
1097
1200
  ).catch(() => null)
1098
1201
  : null;
1099
- const rentFunding = await ensureCycleRentFunding({
1100
- cycleId,
1101
- walletBalanceLamports: preflightWalletBalanceLamports,
1102
- needsOpenCycle: !cycleExists,
1103
- needsSubmit: authority != null && !minerCycleExists,
1104
- });
1202
+ const rentFunding = cycleRentFundingPrepared
1203
+ ? ({ ok: true } as const)
1204
+ : await ensureCycleRentFunding({
1205
+ cycleId,
1206
+ walletBalanceLamports: preflightWalletBalanceLamports,
1207
+ needsOpenCycle: !cycleExists,
1208
+ needsSubmit: authority != null && !minerCycleExists,
1209
+ });
1105
1210
  if (!rentFunding.ok) {
1106
1211
  state.workers.roundWatcher.lastError = null;
1107
1212
  markWorkerWaiting(state, "roundWatcher", rentFunding.reason);
@@ -1187,7 +1292,7 @@ export function createSatRoundWatcherService(params: {
1187
1292
  markWorkerWaiting(
1188
1293
  state,
1189
1294
  "roundWatcher",
1190
- `cycle ${cycleId} skipped: free miner capital cannot cover commit plus erosion while keeping ${formatLamportsAsSol(finalRetainedFreeLamports)} uncommitted for recovery`,
1295
+ `cycle ${cycleId} skipped: free miner capital cannot cover commit plus worst-case reveal collateral while keeping ${formatLamportsAsSol(finalRetainedFreeLamports)} uncommitted for recovery`,
1191
1296
  );
1192
1297
  scheduleWorkerNextRun(
1193
1298
  state,
@@ -1238,34 +1343,238 @@ export function createSatRoundWatcherService(params: {
1238
1343
  state.lastPlannerDecision.snapshot.capitalFreeLamports;
1239
1344
  }
1240
1345
  }
1241
- const allocationFp = strategyDecision.allocationFp;
1346
+ const plannedCommitLamports = Math.max(
1347
+ SAT_MIN_ENTRY_LAMPORTS,
1348
+ Math.floor(effectiveConfig.commitLamports ?? SAT_MIN_ENTRY_LAMPORTS),
1349
+ );
1350
+ const hasDurableCommitPlan =
1351
+ Array.isArray(execution.allocationFp) &&
1352
+ execution.allocationFp.length === SAT_PROTOCOL_CONSTANTS.allocationBuckets &&
1353
+ typeof execution.revealNonceBase64 === "string" &&
1354
+ Buffer.from(execution.revealNonceBase64, "base64").length === 32 &&
1355
+ typeof execution.commitmentHex === "string" &&
1356
+ /^[0-9a-f]{64}$/i.test(execution.commitmentHex) &&
1357
+ typeof execution.commitLamports === "number" &&
1358
+ Number.isSafeInteger(execution.commitLamports);
1359
+ if (!hasDurableCommitPlan) {
1360
+ if (!authority) {
1361
+ throw new Error("SAT mining wallet authority is unavailable before cycle commit");
1362
+ }
1363
+ const nonce = randomBytes(32);
1364
+ const allocationFp = [...strategyDecision.allocationFp];
1365
+ execution.revealNonceBase64 = nonce.toString("base64");
1366
+ execution.allocationFp = allocationFp;
1367
+ execution.commitLamports = plannedCommitLamports;
1368
+ execution.commitmentHex = buildSatCycleCommitment({
1369
+ authority,
1370
+ cycleId,
1371
+ committedLamports: plannedCommitLamports,
1372
+ nonce,
1373
+ allocationFp,
1374
+ }).toString("hex");
1375
+ await persistRuntimeState?.();
1376
+ }
1377
+ const commitLamports = execution.commitLamports ?? plannedCommitLamports;
1242
1378
  if (resolveFrozenActiveCommitLamports(state, finalMinerCapital) == null) {
1243
1379
  await runSatGatewayMethod({
1244
1380
  api,
1245
1381
  method: "sat.setActiveCommit",
1246
1382
  payload: {
1247
- lamports: Math.max(
1248
- SAT_MIN_ENTRY_LAMPORTS,
1249
- Math.floor(effectiveConfig.commitLamports ?? SAT_MIN_ENTRY_LAMPORTS),
1250
- ),
1383
+ lamports: commitLamports,
1251
1384
  persistConfig: false,
1252
1385
  },
1386
+ workflowId: `round-watcher:cycle:${cycleId}:set-active-commit`,
1253
1387
  });
1254
1388
  }
1255
1389
  await runSatGatewayMethod({
1256
1390
  api,
1257
- method: "sat.submitCycle",
1391
+ method: "sat.commitCycle",
1258
1392
  payload: {
1259
1393
  cycleId,
1260
- allocationFp,
1394
+ commitmentHex: execution.commitmentHex,
1261
1395
  },
1262
1396
  });
1263
1397
  execution.openRoundSubmitted = true;
1264
- execution.participationSubmitted = true;
1398
+ execution.commitSubmitted = true;
1265
1399
  state.cycleContext = round;
1400
+ await persistRuntimeState?.();
1401
+ markWorkerSuccess(state, "roundWatcher", `cycle ${cycleId} committed`);
1266
1402
  }
1267
1403
 
1268
- markWorkerSuccess(state, "roundWatcher", `cycle ${cycleId} submitted`);
1404
+ onChainCycle ??= await withRoundWatcherTimeout("commit/reveal cycle", () =>
1405
+ inspectSatCycle(state.activeConfig, { cycleId: activeCycleId }),
1406
+ ).catch(() => null);
1407
+ if (!onChainCycle) {
1408
+ markWorkerWaiting(state, "roundWatcher", `cycle ${cycleId} state is not readable yet`);
1409
+ scheduleWorkerNextRun(state, "roundWatcher", 1_000);
1410
+ return;
1411
+ }
1412
+ const commitDeadlineTs =
1413
+ onChainCycle.commitDeadlineTs ??
1414
+ cycleId * SAT_CYCLE_SECONDS + SAT_PROTOCOL_CONSTANTS.cycleCommitSeconds;
1415
+ const revealDeadlineTs =
1416
+ onChainCycle.revealDeadlineTs ??
1417
+ cycleCloseTs(cycleId) - SAT_PROTOCOL_CONSTANTS.cycleSettlementBufferSeconds;
1418
+ const currentSlot = await withRoundWatcherTimeout("chain slot", () =>
1419
+ inspectSatChainSlot(state.activeConfig),
1420
+ ).catch(() => null);
1421
+ const commitPhaseOpen =
1422
+ currentSlot != null && onChainCycle.commitDeadlineSlot != null
1423
+ ? currentSlot < onChainCycle.commitDeadlineSlot
1424
+ : nowSec < commitDeadlineTs;
1425
+ const revealPhaseOpen =
1426
+ currentSlot != null && onChainCycle.revealDeadlineSlot != null
1427
+ ? currentSlot < onChainCycle.revealDeadlineSlot
1428
+ : nowSec < revealDeadlineTs;
1429
+ if (commitPhaseOpen) {
1430
+ markWorkerWaiting(
1431
+ state,
1432
+ "roundWatcher",
1433
+ `cycle ${cycleId} committed; reveal material is sealed until the commit window closes`,
1434
+ );
1435
+ scheduleWorkerNextRun(
1436
+ state,
1437
+ "roundWatcher",
1438
+ Math.max(1_000, Math.min(10_000, (commitDeadlineTs - nowSec) * 1_000 + 500)),
1439
+ );
1440
+ return;
1441
+ }
1442
+ if (execution.entropyTargetPinned !== true) {
1443
+ execution.entropyTargetPinned = true;
1444
+ await persistRuntimeState?.();
1445
+ }
1446
+ if (
1447
+ onChainCycle.entropyUnavailable === true ||
1448
+ onChainCycle.cycleSeed === SAT_PROTOCOL_CONSTANTS.entropyUnavailableSeedHex
1449
+ ) {
1450
+ if (authority && onChainMinerCycle?.capitalLockReleased !== true) {
1451
+ await runSatGatewayMethod({
1452
+ api,
1453
+ method: "sat.releaseUnrevealedCommit",
1454
+ payload: { cycleId, minerAuthority: authority },
1455
+ });
1456
+ }
1457
+ execution.entropySealed = false;
1458
+ await persistRuntimeState?.();
1459
+ markWorkerSuccess(
1460
+ state,
1461
+ "roundWatcher",
1462
+ `cycle ${cycleId} cancelled because pinned entropy became unprovable; capital released without penalty`,
1463
+ );
1464
+ scheduleWorkerNextRun(state, "roundWatcher", delayUntilNextCycleMs(secondsUntilClose));
1465
+ return;
1466
+ }
1467
+ const cycleSeedIsZero = !onChainCycle.cycleSeed || /^0+$/.test(onChainCycle.cycleSeed);
1468
+ if (cycleSeedIsZero && revealPhaseOpen) {
1469
+ if (execution.participationSubmitted) {
1470
+ markWorkerSuccess(
1471
+ state,
1472
+ "roundWatcher",
1473
+ `cycle ${cycleId} revealed; waiting for the sealed-strategy window to close`,
1474
+ );
1475
+ scheduleWorkerNextRun(state, "roundWatcher", 1_000);
1476
+ return;
1477
+ }
1478
+ if (
1479
+ !authority ||
1480
+ !execution.commitmentHex ||
1481
+ !execution.revealNonceBase64 ||
1482
+ !execution.allocationFp ||
1483
+ execution.commitLamports == null
1484
+ ) {
1485
+ markWorkerFailure(
1486
+ state,
1487
+ "roundWatcher",
1488
+ new Error("committed cycle is missing its durable reveal material"),
1489
+ `cycle ${cycleId}`,
1490
+ );
1491
+ markWorkerWaiting(
1492
+ state,
1493
+ "roundWatcher",
1494
+ `cycle ${cycleId} cannot be revealed safely because its persisted nonce or allocation is missing`,
1495
+ );
1496
+ scheduleWorkerNextRun(state, "roundWatcher", SAT_ROUND_WATCHER_IDLE_DELAY_MS);
1497
+ return;
1498
+ }
1499
+ await runSatGatewayMethod({
1500
+ api,
1501
+ method: "sat.revealCycle",
1502
+ payload: {
1503
+ cycleId,
1504
+ nonceBase64: execution.revealNonceBase64,
1505
+ allocationFp: execution.allocationFp,
1506
+ },
1507
+ });
1508
+ execution.participationSubmitted = true;
1509
+ await persistRuntimeState?.();
1510
+ markWorkerSuccess(state, "roundWatcher", `cycle ${cycleId} revealed sealed allocation`);
1511
+ scheduleWorkerNextRun(state, "roundWatcher", 1_000);
1512
+ api.logger.info(
1513
+ `[sat-mining] cycle watcher revealed committed participation (riskMode=${state.activeConfig.riskMode}, cycle=${cycleId})`,
1514
+ );
1515
+ return;
1516
+ }
1517
+ if (cycleSeedIsZero) {
1518
+ if (
1519
+ currentSlot != null &&
1520
+ onChainCycle.entropyTargetSlot != null &&
1521
+ currentSlot <= onChainCycle.entropyTargetSlot
1522
+ ) {
1523
+ markWorkerWaiting(
1524
+ state,
1525
+ "roundWatcher",
1526
+ `cycle ${cycleId} reveal window closed; waiting for future entropy slots`,
1527
+ );
1528
+ scheduleWorkerNextRun(state, "roundWatcher", 1_000);
1529
+ return;
1530
+ }
1531
+ try {
1532
+ await runSatGatewayMethod({
1533
+ api,
1534
+ method: "sat.sealCycleEntropy",
1535
+ payload: { cycleId },
1536
+ });
1537
+ } catch (error) {
1538
+ markWorkerWaiting(
1539
+ state,
1540
+ "roundWatcher",
1541
+ `cycle ${cycleId} is waiting for all future entropy hashes`,
1542
+ );
1543
+ scheduleWorkerNextRun(state, "roundWatcher", 1_000);
1544
+ api.logger.debug?.(`[sat-mining] entropy not sealable yet: ${String(error)}`);
1545
+ return;
1546
+ }
1547
+ markWorkerWaiting(
1548
+ state,
1549
+ "roundWatcher",
1550
+ `cycle ${cycleId} submitted its post-reveal entropy seal`,
1551
+ );
1552
+ scheduleWorkerNextRun(state, "roundWatcher", 500);
1553
+ return;
1554
+ }
1555
+ execution.entropySealed = true;
1556
+ await persistRuntimeState?.();
1557
+ if (!execution.participationSubmitted) {
1558
+ if (!authority) {
1559
+ throw new Error("SAT mining wallet authority is unavailable for missed-reveal release");
1560
+ }
1561
+ await runSatGatewayMethod({
1562
+ api,
1563
+ method: "sat.releaseUnrevealedCommit",
1564
+ payload: { cycleId, minerAuthority: authority },
1565
+ });
1566
+ markWorkerFailure(
1567
+ state,
1568
+ "roundWatcher",
1569
+ new Error(
1570
+ `cycle reveal deadline elapsed; capital was released after the ${SAT_PROTOCOL_CONSTANTS.cycleNonRevealPenaltyBps / 100}% non-reveal penalty`,
1571
+ ),
1572
+ `cycle ${cycleId}`,
1573
+ );
1574
+ scheduleWorkerNextRun(state, "roundWatcher", delayUntilNextCycleMs(secondsUntilClose));
1575
+ return;
1576
+ }
1577
+ markWorkerSuccess(state, "roundWatcher", `cycle ${cycleId} reveal and entropy sealed`);
1269
1578
  scheduleWorkerNextRun(
1270
1579
  state,
1271
1580
  "roundWatcher",
@@ -1273,9 +1582,6 @@ export function createSatRoundWatcherService(params: {
1273
1582
  ? delayUntilNextCycleMs(cycleCloseTs(cycleId) - nextCycleDelayAnchorSec)
1274
1583
  : SAT_ROUND_WATCHER_EDGE_DELAY_MS,
1275
1584
  );
1276
- api.logger.info(
1277
- `[sat-mining] cycle watcher executed (riskMode=${state.activeConfig.riskMode}, cycle=${cycleId})`,
1278
- );
1279
1585
  } catch (error) {
1280
1586
  if (cycleId != null && isRoundWatcherTimeoutError(error)) {
1281
1587
  state.workers.roundWatcher.lastError = null;
@@ -1335,20 +1641,24 @@ export function createSatRoundWatcherService(params: {
1335
1641
  }
1336
1642
  if (cycleId != null && isAlreadyParticipatingError(error)) {
1337
1643
  const execution = getOrCreateRoundExecutionState(state, cycleId, 0);
1338
- execution.openRoundSubmitted = true;
1339
- execution.participationSubmitted = true;
1340
- markWorkerSuccess(state, "roundWatcher", `cycle ${cycleId} already submitted`);
1341
- scheduleWorkerNextRun(
1342
- state,
1343
- "roundWatcher",
1344
- state.workers.roundWatcher.lastSuccessAt != null
1345
- ? delayUntilNextCycleMs(cycleCloseTs(cycleId) - Math.floor(Date.now() / 1000))
1346
- : SAT_ROUND_WATCHER_EDGE_DELAY_MS,
1347
- );
1348
- api.logger.warn(
1349
- `[sat-mining] cycle watcher detected existing participation for cycle ${cycleId}; reconciling local state`,
1350
- );
1351
- return;
1644
+ const authority = state.activeWalletAddress;
1645
+ const minerCycle = authority
1646
+ ? await inspectSatMinerCycle(state.activeConfig, { authority, cycleId }).catch(() => null)
1647
+ : null;
1648
+ if (minerCycle) {
1649
+ execution.openRoundSubmitted = true;
1650
+ execution.commitSubmitted = true;
1651
+ execution.participationSubmitted = minerCycle.validParticipation;
1652
+ markWorkerWaiting(
1653
+ state,
1654
+ "roundWatcher",
1655
+ minerCycle.validParticipation
1656
+ ? `cycle ${cycleId} reveal already exists; local state reconciled`
1657
+ : `cycle ${cycleId} commitment already exists; continuing its reveal phases`,
1658
+ );
1659
+ scheduleWorkerNextRun(state, "roundWatcher", 1_000);
1660
+ return;
1661
+ }
1352
1662
  }
1353
1663
  if (cycleId != null && isInsufficientLamportsError(error)) {
1354
1664
  state.workers.roundWatcher.lastError = null;