@fased/fased 0.1.62 → 0.1.64

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 (341) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +38 -30
  3. package/config/dependency-ownership.json +1 -1
  4. package/config/signer-policies/README.md +49 -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 +76 -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-bR-fO5ty.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-ckCxHwjy.js} +3 -3
  80. package/dist/control-ui/assets/{mining-BdhMn18r.js → mining-BgHFh0ei.js} +134 -114
  81. package/dist/control-ui/assets/mining-commit-DFpB_4JN.js +2 -0
  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 +235 -67
  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 +1038 -397
  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-BYxAt775.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-DIRHG2gJ.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-BOT7kHb6.js} +6779 -3696
  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-BCFDaqJ-.js} +31 -31
  166. package/dist/plugin-sdk/{monitor-wYVncM9w.js → monitor-BgbjRiPM.js} +32 -32
  167. package/dist/plugin-sdk/{openresponses-http-B2GmeSt4.js → openresponses-http-DFf87SMM.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-B3bHYGaw.d.ts → pairing-message-CS-9BHug.d.ts} +2 -2
  172. package/dist/plugin-sdk/{pairing-message-B3GC_7CD.js → pairing-message-D0CoLHRJ.js} +1 -1
  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 +549 -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-BUTt8cxK.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-D0wHVqjt.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-CC_qN4v0.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-xOTGlzBE.d.ts +486 -0
  208. package/dist/plugin-sdk/{types-vcJrC_uv.d.ts → types-C3avNytw.d.ts} +3 -4
  209. package/dist/plugin-sdk/{types-DyhXnYUr.d.ts → types-D0kDG8l0.d.ts} +3 -2
  210. package/dist/plugin-sdk/{types-DFAW-n1J.d.ts → types-DWfbSAaM.d.ts} +2 -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-BXsJ1vqe.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 +561 -118
  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 +90 -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 +90 -36
  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 +12 -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 +12 -0
  284. package/extensions/msteams/package.json +1 -1
  285. package/extensions/nextcloud-talk/package.json +1 -1
  286. package/extensions/nostr/CHANGELOG.md +12 -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 +498 -153
  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 +50 -5
  293. package/extensions/sat-mining/src/claim-service.ts +85 -14
  294. package/extensions/sat-mining/src/config.ts +9 -0
  295. package/extensions/sat-mining/src/cycle-progress.ts +16 -8
  296. package/extensions/sat-mining/src/epoch-service.ts +9 -5
  297. package/extensions/sat-mining/src/gateway-runner.ts +21 -1
  298. package/extensions/sat-mining/src/protocol-contract.ts +45 -1
  299. package/extensions/sat-mining/src/recovery-service.ts +312 -0
  300. package/extensions/sat-mining/src/round-watcher.ts +391 -81
  301. package/extensions/sat-mining/src/rpc-read.ts +330 -89
  302. package/extensions/sat-mining/src/runtime.ts +14 -0
  303. package/extensions/sat-mining/src/sat-bond-layout.ts +6 -0
  304. package/extensions/sat-mining/src/signer-codec-manifest.ts +429 -0
  305. package/extensions/sat-mining/src/solana-submit.ts +1199 -428
  306. package/extensions/sat-mining/src/submission-ledger.ts +433 -0
  307. package/extensions/signal/package.json +1 -1
  308. package/extensions/synology-chat/package.json +1 -1
  309. package/extensions/tlon/package.json +1 -1
  310. package/extensions/twitch/CHANGELOG.md +12 -0
  311. package/extensions/twitch/package.json +1 -1
  312. package/extensions/voice-call/CHANGELOG.md +12 -0
  313. package/extensions/voice-call/package.json +1 -1
  314. package/extensions/zalo/CHANGELOG.md +12 -0
  315. package/extensions/zalo/package.json +1 -1
  316. package/extensions/zalouser/CHANGELOG.md +12 -0
  317. package/extensions/zalouser/package.json +1 -1
  318. package/install.sh +4955 -0
  319. package/package.json +23 -5
  320. package/scripts/fased-host-updater.mjs +1421 -0
  321. package/scripts/fased-host-updaterctl.mjs +186 -0
  322. package/scripts/fased-managed-service.sh +36 -0
  323. package/scripts/fased-managed-updater.mjs +3065 -156
  324. package/scripts/fased-signer-enroll-hosting.sh +275 -0
  325. package/scripts/fased-signer-network-hosting.sh +143 -0
  326. package/scripts/fased-signer-owner-policy.mjs +1430 -0
  327. package/scripts/fased-signer-policy-hosting.sh +50 -0
  328. package/scripts/fased-signer-policy-local.sh +26 -0
  329. package/scripts/hosted-release-manifest.mjs +185 -0
  330. package/scripts/install-fased-signerd.sh +183 -108
  331. package/scripts/install-managed-runtime.mjs +212 -10
  332. package/scripts/managed-runtime-layout.mjs +75 -3
  333. package/scripts/migrate-hosted-signer-v2.mjs +58 -0
  334. package/scripts/start-managed.sh +169 -360
  335. package/dist/control-ui/assets/mining-commit-R-6nu87p.js +0 -2
  336. package/dist/plugin-sdk/tmp-fased-dir-CS6zsYEE.d.ts +0 -77
  337. package/dist/wallet/local-socket-signer-broker.js +0 -224
  338. package/dist/wallet/local-socket-signer-custody.js +0 -42
  339. package/dist/wallet/providers/embedded-keystore-adapter.js +0 -402
  340. package/dist/wallet/providers/privy-adapter.js +0 -80
  341. package/dist/wallet/wallet-custody.js +0 -1836
@@ -1,15 +1,20 @@
1
1
  import { loadConfig } from "../../../config/io.js";
2
- import { resolveWalletRuntimeConfig } from "../../../wallet/wallet-runtime-config.js";
2
+ import { LEGACY_EMBEDDED_KEYSTORE_MIGRATION_MESSAGE } from "../../../wallet/legacy-embedded-keystore.js";
3
3
  import { readWalletProviderRegistry } from "../../../wallet/wallet-provider-registry.js";
4
4
  import { resolveSatBondProgramIdFromEnv, resolveSatMintAddressFromEnv, resolveSatMintProgramIdFromEnv, resolveSatProgramIdFromEnv } from "../../../config/sat-runtime-ids.js";
5
5
  import { callLocalSocketSigner, requireLocalSocketSignerPath } from "../../../wallet/providers/local-socket-signer-adapter.js";
6
6
  import { resolveWalletProviderId } from "../../../wallet/wallet-provider-resolver.js";
7
- import { enforceWalletCustodyForAutonomousSend } from "../../../wallet/wallet-custody.js";
7
+ import { createSignerReviewApprovalRequest } from "../../../wallet/wallet-send-approvals.js";
8
8
  import "../../../plugin-sdk/sat-runtime.js";
9
- import { inspectSatCycleRegistryMeta, inspectSatMinerCyclesByAddress } from "./rpc-read.js";
9
+ import { SAT_BOND_INSTRUCTION_DISCRIMINATORS, SAT_INSTRUCTION_DISCRIMINATORS, SAT_PROTOCOL_CONSTANTS, resolveSatGenesisProfileContract } from "./protocol-contract.js";
10
+ import { inspectSatCycle, inspectSatCycleRegistryMeta, inspectSatMinerCyclesByAddress } from "./rpc-read.js";
10
11
  import { decodeHash32 } from "./hash-spec.js";
11
- import { SAT_BOND_INSTRUCTION_DISCRIMINATORS, SAT_INSTRUCTION_DISCRIMINATORS } from "./protocol-contract.js";
12
+ import { resolveSatSignerCodec } from "./signer-codec-manifest.js";
13
+ import { buildSatSubmissionOperationKey, claimSatSubmission, digestSatSubmissionIntent, updateSatSubmission, waitForSatSubmissionLease } from "./submission-ledger.js";
12
14
  import { createRequire } from "node:module";
15
+ import { isDeepStrictEqual } from "node:util";
16
+ import { createHash } from "node:crypto";
17
+ import { AsyncLocalStorage } from "node:async_hooks";
13
18
 
14
19
  //#region extensions/sat-mining/src/solana-submit.ts
15
20
  const require = createRequire(import.meta.url);
@@ -37,13 +42,35 @@ const SAT_TREASURY_STATE_SEED = "sat_treasury_state";
37
42
  const SAT_REGISTRY_RESERVE_SEED = "sat_registry_reserve";
38
43
  const SAT_REBATE_VAULT_SEED = "sat_rebate_vault";
39
44
  const SAT_TREASURY_VAULT_SEED = "sat_treasury_vault";
45
+ const SAT_UNLOCK_INTERVAL_STATE_SEED = "sat_unlock_interval_state";
40
46
  const SAT_CYCLE_REGISTRY_PAGE_CAPACITY = 64;
41
47
  const MINING_POOL_SEED = "mining_pool";
42
48
  const MINING_STAKE_SEED = "mining_stake";
43
49
  const TOKEN_PROGRAM_ID = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
44
50
  const ASSOCIATED_TOKEN_PROGRAM_ID = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
51
+ const SLOT_HASHES_SYSVAR_ID = "SysvarS1otHashes111111111111111111111111111";
45
52
  const IX = SAT_INSTRUCTION_DISCRIMINATORS;
46
53
  const BOND_IX = SAT_BOND_INSTRUCTION_DISCRIMINATORS;
54
+ const VAULT_BOND_ACTIONS = new Set([
55
+ "updateBondTierPolicy",
56
+ "openBondPosition",
57
+ "increaseBondPosition",
58
+ "requestBondUnlock",
59
+ "cancelBondUnlock",
60
+ "finalizeBondUnlock",
61
+ "syncBondStakingRewards",
62
+ "syncBondStakingPosition",
63
+ "claimBondStakingRewards",
64
+ "claimUnallocatedStakingRewards"
65
+ ]);
66
+ const satSubmissionWorkflowStorage = new AsyncLocalStorage();
67
+ async function runWithSatSubmissionWorkflow(workflowId, task) {
68
+ const normalized = workflowId.trim();
69
+ if (!normalized || normalized.length > 240 || /[\u0000-\u001f\u007f]/u.test(normalized)) {
70
+ throw new Error("SAT submission idempotency key must contain 1-240 printable characters");
71
+ }
72
+ return await satSubmissionWorkflowStorage.run(normalized, task);
73
+ }
47
74
  function satSubmitDebug(message) {
48
75
  if (String(process.env.FASED_SAT_SUBMIT_DEBUG ?? "").trim() === "1") {
49
76
  console.error(message);
@@ -84,6 +111,10 @@ function resolveSatWalletId(cfg) {
84
111
  const value = cfg.plugins?.entries?.["sat-mining"]?.config?.walletId;
85
112
  return typeof value === "string" && value.trim() ? value.trim() : undefined;
86
113
  }
114
+ function resolveSatCluster(cfg) {
115
+ const value = cfg.plugins?.entries?.["sat-mining"]?.config?.network;
116
+ return value === "local" || value === "mainnet-beta" || value === "devnet" ? value : "devnet";
117
+ }
87
118
  function resolveSatEffectiveEnv(cfg, env) {
88
119
  return {
89
120
  ...env,
@@ -93,68 +124,46 @@ function resolveSatEffectiveEnv(cfg, env) {
93
124
  function resolveSatProviderId(cfg, env) {
94
125
  const effectiveEnv = resolveSatEffectiveEnv(cfg, env);
95
126
  const walletId = resolveSatWalletId(cfg);
127
+ const signerSocket = String(effectiveEnv.FASED_WALLET_LOCAL_SIGNER_SOCKET ?? "").trim();
96
128
  if (walletId) {
97
- const hasSelfHostedSignerMaterial = String(effectiveEnv.FASED_WALLET_LOCAL_SIGNER_SOCKET ?? "").trim() || String(effectiveEnv.FASED_WALLET_LOCAL_SIGNER_BACKEND_SOCKET ?? "").trim() || String(walletEnvValue(effectiveEnv, "FASED_WALLET_SOLANA_KEYSTORE_PATH", walletId) ?? "").trim();
98
- try {
99
- const wallet = readWalletProviderRegistry(effectiveEnv).wallets.find((entry) => entry.id === walletId);
100
- if (wallet?.providerId === "local-socket-signer") {
101
- return wallet.providerId;
102
- }
103
- if (hasSelfHostedSignerMaterial) {
104
- return "local-socket-signer";
105
- }
106
- if (wallet?.providerId) {
107
- return wallet.providerId;
108
- }
109
- } catch {}
110
- if (hasSelfHostedSignerMaterial) {
111
- return "local-socket-signer";
129
+ const wallet = readWalletProviderRegistry(effectiveEnv).wallets.find((entry) => entry.id === walletId);
130
+ if (wallet?.providerId === "embedded-keystore") {
131
+ throw new Error(LEGACY_EMBEDDED_KEYSTORE_MIGRATION_MESSAGE);
132
+ }
133
+ if (wallet?.providerId && wallet.providerId !== "local-socket-signer") {
134
+ return wallet.providerId;
135
+ }
136
+ if (wallet?.providerId === "local-socket-signer" && !signerSocket) {
137
+ throw new Error("SAT mining requires the actual protocol-v2 fased-signerd application socket; legacy keystore paths and backend sockets are not signer capability.");
138
+ }
139
+ if (wallet?.providerId === "local-socket-signer") {
140
+ return wallet.providerId;
112
141
  }
113
142
  }
114
- return resolveWalletProviderId(cfg, effectiveEnv);
115
- }
116
- async function enforceSatCustodyAutonomousSigning(cfg, env) {
117
- const effectiveEnv = resolveSatEffectiveEnv(cfg, env);
118
- const walletCfg = resolveWalletRuntimeConfig(cfg, effectiveEnv);
119
- const walletId = resolveSatWalletId(cfg);
120
- if (walletCfg.execution.mode !== "autonomous") {
121
- return;
122
- }
123
- const custodyGate = await enforceWalletCustodyForAutonomousSend({
124
- wallet: walletCfg,
125
- env: effectiveEnv,
126
- cfg,
127
- walletId,
128
- approvalHost: String(effectiveEnv.FASED_WALLET_CUSTODY_ACTIVE_HOST ?? effectiveEnv.FASED_A2A_ORIGIN ?? "127.0.0.1")
129
- });
130
- if (!custodyGate.ok) {
131
- throw new Error(custodyGate.message);
143
+ const providerId = resolveWalletProviderId(cfg, effectiveEnv);
144
+ if (providerId === "local-socket-signer" && !signerSocket) {
145
+ throw new Error("SAT mining requires the actual protocol-v2 fased-signerd application socket; configure FASED_WALLET_LOCAL_SIGNER_SOCKET.");
132
146
  }
147
+ return providerId;
133
148
  }
134
- function resolveSatRegistrySolanaAddress(cfg, env) {
149
+ async function resolveSatLocalSignerAddress(cfg, env, errorMessage, verifyCapabilities = true) {
135
150
  const effectiveEnv = resolveSatEffectiveEnv(cfg, env);
136
151
  const walletId = resolveSatWalletId(cfg);
137
152
  if (!walletId) {
138
- return "";
153
+ throw new Error("SAT mining local signer address lookup requires an attached walletId");
139
154
  }
140
- const wallet = readWalletProviderRegistry(effectiveEnv).wallets.find((entry) => entry.id === walletId);
141
- return typeof wallet?.addresses?.solana === "string" ? wallet.addresses.solana.trim() : "";
142
- }
143
- async function resolveSatLocalSignerAddress(cfg, env, errorMessage) {
144
- const effectiveEnv = resolveSatEffectiveEnv(cfg, env);
145
- const walletId = resolveSatWalletId(cfg);
146
- const result = await callLocalSocketSigner(requireLocalSocketSignerPath(effectiveEnv), {
147
- op: "getAddresses",
148
- ...walletId ? { walletId } : {}
155
+ const socketPath = requireLocalSocketSignerPath(effectiveEnv);
156
+ if (verifyCapabilities) {
157
+ await requireTypedSatSignerCapabilities(socketPath, "solana.satAction");
158
+ }
159
+ const result = await callLocalSocketSigner(socketPath, {
160
+ op: "v2.wallet.get",
161
+ walletId
149
162
  });
150
- const signer = String(result.solana ?? "").trim();
163
+ const signer = String(result.publicKey ?? "").trim();
151
164
  if (signer) {
152
165
  return signer;
153
166
  }
154
- const fallback = resolveSatRegistrySolanaAddress(cfg, env);
155
- if (fallback) {
156
- return fallback;
157
- }
158
167
  throw new Error(errorMessage);
159
168
  }
160
169
  function encodeU64(value) {
@@ -203,7 +212,6 @@ function assertDedicatedBondProgram(env) {
203
212
  async function resolveSatValidatorAuthority(_config) {
204
213
  const cfg = loadConfigForSatRuntime(_config);
205
214
  const effectiveEnv = resolveSatEffectiveEnv(cfg, process.env);
206
- await enforceSatCustodyAutonomousSigning(cfg, effectiveEnv);
207
215
  if (resolveSatProviderId(cfg, effectiveEnv) !== "local-socket-signer") {
208
216
  throw new Error("SAT mining unattended signing currently requires local-socket-signer for validator authority resolution");
209
217
  }
@@ -214,7 +222,7 @@ async function prepareLocalSignerSubmitContext(cfg, env) {
214
222
  const solana = await loadSolanaWeb3();
215
223
  const walletId = resolveSatWalletId(cfg);
216
224
  const socketPath = requireLocalSocketSignerPath(effectiveEnv);
217
- const signerAddress = await resolveSatLocalSignerAddress(cfg, effectiveEnv, "local-socket-signer returned no Solana address for SAT mining wallet");
225
+ const signerAddress = await resolveSatLocalSignerAddress(cfg, effectiveEnv, "local-socket-signer returned no Solana address for SAT mining wallet", false);
218
226
  const signer = new solana.PublicKey(signerAddress);
219
227
  return {
220
228
  effectiveEnv,
@@ -226,17 +234,407 @@ async function prepareLocalSignerSubmitContext(cfg, env) {
226
234
  };
227
235
  }
228
236
  async function buildLocalSignerInstructionRequest(params) {
229
- const keys = await params.spec.accountResolver(params.solana, params.signer);
230
- satSubmitDebug(`[sat-submit-debug] data_len=${params.spec.data.length} disc=${params.spec.data[0] ?? -1} keys=${keys.length}`);
237
+ const resolved = await params.spec.accountResolver(params.solana, params.signer);
238
+ const keys = Array.isArray(resolved) ? resolved : resolved.keys;
239
+ const context = Array.isArray(resolved) ? undefined : resolved.context;
240
+ const programId = params.spec.programId ?? resolveSatProgramIdFromEnv(params.env);
241
+ const mainProgramId = resolveSatProgramIdFromEnv(params.env);
242
+ const bondProgramId = resolveSatBondProgramIdFromEnv(params.env).trim() || undefined;
243
+ const codec = resolveSatSignerCodec({
244
+ programId,
245
+ mainProgramId,
246
+ bondProgramId,
247
+ data: params.spec.data
248
+ });
249
+ satSubmitDebug(`[sat-submit-debug] action=${codec.action} data_len=${params.spec.data.length} disc=${params.spec.data[0] ?? -1} keys=${keys.length}`);
231
250
  return {
232
- ...params.walletId ? { walletId: params.walletId } : {},
233
- programId: params.spec.programId ?? SAT_PROGRAM_ID(),
251
+ action: codec.action,
252
+ programId,
234
253
  dataBase64: params.spec.data.toString("base64"),
235
254
  keys: keys.map((key) => ({
236
255
  pubkey: key.pubkey.toBase58(),
237
256
  isSigner: key.isSigner,
238
257
  isWritable: key.isWritable
239
- }))
258
+ })),
259
+ ...context ? { context } : {}
260
+ };
261
+ }
262
+ const REQUIRED_SAT_SIGNER_FEATURES = [
263
+ "failClosedPolicies",
264
+ "policyHashes",
265
+ "durableCaps",
266
+ "atomicIdempotency",
267
+ "ambiguousBroadcastReconciliation",
268
+ "signerOwnedKeys",
269
+ "typedSolanaTransactions",
270
+ "typedSATActions"
271
+ ];
272
+ async function requireTypedSatSignerCapabilities(socketPath, intentType) {
273
+ const result = await callLocalSocketSigner(socketPath, { op: "v2.capabilities" });
274
+ const capabilities = result.capabilities;
275
+ const protocol = capabilities?.protocol;
276
+ const features = new Set(capabilities?.features ?? []);
277
+ const states = new Set(capabilities?.operationStates ?? []);
278
+ const missingFeatures = REQUIRED_SAT_SIGNER_FEATURES.filter((feature) => !features.has(feature));
279
+ const missingStates = [
280
+ "reserved",
281
+ "broadcast",
282
+ "confirmed",
283
+ "failed",
284
+ "unknown"
285
+ ].filter((state) => !states.has(state));
286
+ const missingVaultReviewFeatures = intentType === "solana.vaultBondAction" ? [
287
+ "signerOwnedReviewPrepareExecute",
288
+ "exactPreparedTransactions",
289
+ "reviewedVaultBondActions",
290
+ "signerOwnedStateRecheck",
291
+ "durableReviewAuthorization"
292
+ ].filter((feature) => !features.has(feature)) : [];
293
+ if (result.ready !== true || protocol?.current !== 2 || typeof protocol.min !== "number" || protocol.min > 2 || typeof protocol.max !== "number" || protocol.max < 2 || !capabilities?.intentTypes?.includes(intentType) || missingFeatures.length > 0 || intentType === "solana.vaultBondAction" && !features.has("typedVaultBondActions") || missingVaultReviewFeatures.length > 0 || missingStates.length > 0) {
294
+ throw new Error(`local-socket-signer does not support the required typed SAT protocol-v2 contract${missingFeatures.length > 0 ? `; missing features: ${missingFeatures.join(", ")}` : ""}${missingVaultReviewFeatures.length > 0 ? `; missing reviewed Vault features: ${missingVaultReviewFeatures.join(", ")}` : ""}${missingStates.length > 0 ? `; missing states: ${missingStates.join(", ")}` : ""}`);
295
+ }
296
+ }
297
+ async function reconcileTypedSatOperation(params) {
298
+ let operation = params.operation ?? await callLocalSocketSigner(params.socketPath, {
299
+ op: "v2.operation.get",
300
+ walletId: params.walletId,
301
+ request: { requestId: params.requestId }
302
+ });
303
+ if (operation.state === "broadcast" || operation.state === "unknown") {
304
+ try {
305
+ operation = await callLocalSocketSigner(params.socketPath, {
306
+ op: "v2.operation.reconcile",
307
+ walletId: params.walletId,
308
+ request: { requestId: params.requestId }
309
+ });
310
+ } catch {}
311
+ }
312
+ return operation;
313
+ }
314
+ function assertSatSignerOperationIdentity(operation, requestId) {
315
+ if (operation.requestId !== requestId) {
316
+ throw new Error(`SAT signer returned request ${operation.requestId || "<empty>"} while reconciling ${requestId}`);
317
+ }
318
+ return operation;
319
+ }
320
+ function signerStateForLedger(state) {
321
+ return state;
322
+ }
323
+ var SatSubmissionUnresolvedError = class extends Error {
324
+ constructor(params) {
325
+ super(`SAT signer operation ${params.requestId} remains ${params.state}${params.signature ? ` with signature ${params.signature}` : ""}; it is unresolved and must be reconciled with the same idempotency key before any new submission${params.detail ? ` (${params.detail})` : ""}`);
326
+ this.name = "SatSubmissionUnresolvedError";
327
+ this.requestId = params.requestId;
328
+ this.signature = params.signature;
329
+ }
330
+ };
331
+ async function executeTypedSatIntent(params) {
332
+ const isVaultBond = params.action !== "cleanupBatch" && VAULT_BOND_ACTIONS.has(params.action);
333
+ const intentType = isVaultBond ? "solana.vaultBondAction" : "solana.satAction";
334
+ await requireTypedSatSignerCapabilities(params.socketPath, intentType);
335
+ const intent = isVaultBond ? (() => {
336
+ if (!params.instruction || params.instructions) {
337
+ throw new Error("typed Vault bond execution requires exactly one semantic instruction");
338
+ }
339
+ return {
340
+ type: "solana.vaultBondAction",
341
+ cluster: params.cluster,
342
+ ...params.instruction
343
+ };
344
+ })() : {
345
+ type: "solana.satAction",
346
+ action: params.action,
347
+ ...params.instruction ?? {},
348
+ ...params.instructions ? { instructions: params.instructions } : {}
349
+ };
350
+ const policy = await callLocalSocketSigner(params.socketPath, {
351
+ op: "v2.policy.get",
352
+ walletId: params.walletId
353
+ });
354
+ const intentDigest = digestSatSubmissionIntent({
355
+ walletId: params.walletId,
356
+ policyHash: policy.hash,
357
+ intent
358
+ });
359
+ const operationKey = buildSatSubmissionOperationKey(intent);
360
+ const workflowId = satSubmissionWorkflowStorage.getStore() ?? `derived:${operationKey}:${intentDigest}`;
361
+ let claim = await claimSatSubmission({
362
+ walletId: params.walletId,
363
+ workflowId,
364
+ operationKey,
365
+ intentDigest,
366
+ action: params.action,
367
+ env: params.env
368
+ });
369
+ if (!claim.claimed) {
370
+ await waitForSatSubmissionLease({
371
+ walletId: params.walletId,
372
+ requestId: claim.record.requestId,
373
+ env: params.env
374
+ });
375
+ claim = await claimSatSubmission({
376
+ walletId: params.walletId,
377
+ workflowId,
378
+ operationKey,
379
+ intentDigest,
380
+ action: params.action,
381
+ env: params.env,
382
+ owner: claim.owner
383
+ });
384
+ if (!claim.claimed) {
385
+ throw new Error(`SAT submission ${claim.record.requestId} could not acquire its durable execution lease`);
386
+ }
387
+ }
388
+ const requestId = claim.record.requestId;
389
+ let resumedReviewedOperation;
390
+ if (intent.type === "solana.vaultBondAction") {
391
+ let reviewWasSigned = false;
392
+ try {
393
+ let review;
394
+ try {
395
+ review = await callLocalSocketSigner(params.socketPath, {
396
+ op: "v2.review.get",
397
+ walletId: params.walletId,
398
+ request: { requestId }
399
+ });
400
+ } catch (lookupError) {
401
+ if (!String(lookupError).includes("signer review not found")) {
402
+ throw lookupError;
403
+ }
404
+ review = await callLocalSocketSigner(params.socketPath, {
405
+ op: "v2.review.prepare",
406
+ walletId: params.walletId,
407
+ request: {
408
+ requestId,
409
+ policyHash: policy.hash,
410
+ mode: "reviewed",
411
+ intent
412
+ }
413
+ });
414
+ }
415
+ if (review.requestId !== requestId || review.policyHash !== policy.hash || review.mode !== "reviewed" || review.intentType !== intent.type || !isDeepStrictEqual(review.semanticIntent, intent)) {
416
+ throw new Error(`Vault bond review ${requestId} does not match the exact SAT intent`);
417
+ }
418
+ if (review.state === "prepared") {
419
+ const approval = createSignerReviewApprovalRequest({
420
+ review,
421
+ role: "vault",
422
+ walletId: params.walletId,
423
+ requestedBy: "sat-mining-vault",
424
+ assetSymbol: "SAT",
425
+ assetName: "SAT bond",
426
+ memo: `Reviewed Vault bond action: ${intent.action}`,
427
+ env: params.env
428
+ });
429
+ await updateSatSubmission({
430
+ walletId: params.walletId,
431
+ requestId,
432
+ intentDigest,
433
+ state: "reserved",
434
+ error: `review ${approval.id} pending`,
435
+ owner: claim.owner,
436
+ releaseLease: true,
437
+ env: params.env
438
+ });
439
+ throw new Error(`Vault bond review ${approval.id} is pending in Wallet Approvals for ${intent.action}; approve it there with the signer-owned passkey`);
440
+ }
441
+ reviewWasSigned = true;
442
+ resumedReviewedOperation = assertSatSignerOperationIdentity(await reconcileTypedSatOperation({
443
+ socketPath: params.socketPath,
444
+ walletId: params.walletId,
445
+ requestId
446
+ }), requestId);
447
+ } catch (error) {
448
+ await updateSatSubmission({
449
+ walletId: params.walletId,
450
+ requestId,
451
+ intentDigest,
452
+ state: reviewWasSigned ? "unknown" : "reserved",
453
+ error: error instanceof Error ? error.message : String(error),
454
+ owner: claim.owner,
455
+ releaseLease: true,
456
+ env: params.env
457
+ }).catch(() => undefined);
458
+ throw error;
459
+ }
460
+ }
461
+ const executeExactOrRecover = async () => {
462
+ try {
463
+ return await callLocalSocketSigner(params.socketPath, {
464
+ op: "v2.execute",
465
+ walletId: params.walletId,
466
+ request: {
467
+ requestId,
468
+ policyHash: policy.hash,
469
+ intent
470
+ }
471
+ });
472
+ } catch (executeError) {
473
+ try {
474
+ return await callLocalSocketSigner(params.socketPath, {
475
+ op: "v2.operation.get",
476
+ walletId: params.walletId,
477
+ request: { requestId }
478
+ });
479
+ } catch (lookupError) {
480
+ const detail = `${executeError instanceof Error ? executeError.message : String(executeError)}; ${lookupError instanceof Error ? lookupError.message : String(lookupError)}`;
481
+ await updateSatSubmission({
482
+ walletId: params.walletId,
483
+ requestId,
484
+ intentDigest,
485
+ state: claim.record.state === "confirmed" || claim.record.state === "failed" ? claim.record.state : "unknown",
486
+ ...claim.record.signature ? { signature: claim.record.signature } : {},
487
+ error: detail,
488
+ owner: claim.owner,
489
+ releaseLease: true,
490
+ env: params.env
491
+ });
492
+ throw new SatSubmissionUnresolvedError({
493
+ requestId,
494
+ state: "unknown",
495
+ detail
496
+ });
497
+ }
498
+ }
499
+ };
500
+ let operation;
501
+ if (resumedReviewedOperation) {
502
+ operation = resumedReviewedOperation;
503
+ } else if (!claim.created) {
504
+ const callerStateWasAmbiguous = claim.record.state === "broadcast" || claim.record.state === "unknown";
505
+ try {
506
+ operation = assertSatSignerOperationIdentity(await callLocalSocketSigner(params.socketPath, {
507
+ op: "v2.operation.get",
508
+ walletId: params.walletId,
509
+ request: { requestId }
510
+ }), requestId);
511
+ operation = assertSatSignerOperationIdentity(await reconcileTypedSatOperation({
512
+ socketPath: params.socketPath,
513
+ walletId: params.walletId,
514
+ requestId,
515
+ operation
516
+ }), requestId);
517
+ } catch (lookupError) {
518
+ if (claim.record.signature) {
519
+ await updateSatSubmission({
520
+ walletId: params.walletId,
521
+ requestId,
522
+ intentDigest,
523
+ state: claim.record.state === "confirmed" ? "confirmed" : "unknown",
524
+ signature: claim.record.signature,
525
+ error: lookupError instanceof Error ? lookupError.message : String(lookupError),
526
+ owner: claim.owner,
527
+ releaseLease: true,
528
+ env: params.env
529
+ });
530
+ throw new SatSubmissionUnresolvedError({
531
+ requestId,
532
+ state: claim.record.state === "confirmed" ? "confirmed-but-unverified" : "unknown",
533
+ signature: claim.record.signature,
534
+ detail: lookupError instanceof Error ? lookupError.message : String(lookupError)
535
+ });
536
+ }
537
+ if (claim.record.state === "failed" || claim.record.state === "confirmed") {
538
+ const detail = lookupError instanceof Error ? lookupError.message : String(lookupError);
539
+ await updateSatSubmission({
540
+ walletId: params.walletId,
541
+ requestId,
542
+ intentDigest,
543
+ state: claim.record.state,
544
+ error: detail,
545
+ owner: claim.owner,
546
+ releaseLease: true,
547
+ env: params.env
548
+ });
549
+ if (claim.record.state === "failed") {
550
+ throw new Error(claim.record.error || `SAT signer operation ${requestId} failed`);
551
+ }
552
+ throw new SatSubmissionUnresolvedError({
553
+ requestId,
554
+ state: "confirmed-without-signature",
555
+ detail
556
+ });
557
+ }
558
+ operation = await executeExactOrRecover();
559
+ }
560
+ if (operation.state === "reserved" && !operation.signature) {
561
+ if (callerStateWasAmbiguous) {
562
+ const detail = `signer regressed to reserved after caller persisted ${claim.record.state}`;
563
+ await updateSatSubmission({
564
+ walletId: params.walletId,
565
+ requestId,
566
+ intentDigest,
567
+ state: "unknown",
568
+ ...claim.record.signature ? { signature: claim.record.signature } : {},
569
+ error: detail,
570
+ owner: claim.owner,
571
+ releaseLease: true,
572
+ env: params.env
573
+ });
574
+ throw new SatSubmissionUnresolvedError({
575
+ requestId,
576
+ state: "unknown",
577
+ signature: claim.record.signature,
578
+ detail
579
+ });
580
+ }
581
+ operation = await executeExactOrRecover();
582
+ }
583
+ } else {
584
+ operation = await executeExactOrRecover();
585
+ }
586
+ try {
587
+ operation = assertSatSignerOperationIdentity(operation, requestId);
588
+ operation = assertSatSignerOperationIdentity(await reconcileTypedSatOperation({
589
+ socketPath: params.socketPath,
590
+ walletId: params.walletId,
591
+ requestId,
592
+ operation
593
+ }), requestId);
594
+ } catch (error) {
595
+ const detail = error instanceof Error ? error.message : String(error);
596
+ await updateSatSubmission({
597
+ walletId: params.walletId,
598
+ requestId,
599
+ intentDigest,
600
+ state: claim.record.state === "confirmed" || claim.record.state === "failed" ? claim.record.state : "unknown",
601
+ ...claim.record.signature ? { signature: claim.record.signature } : {},
602
+ error: detail,
603
+ owner: claim.owner,
604
+ releaseLease: true,
605
+ env: params.env
606
+ });
607
+ throw new SatSubmissionUnresolvedError({
608
+ requestId,
609
+ state: "unknown",
610
+ detail
611
+ });
612
+ }
613
+ await updateSatSubmission({
614
+ walletId: params.walletId,
615
+ requestId,
616
+ intentDigest,
617
+ state: signerStateForLedger(operation.state),
618
+ ...operation.signature ? { signature: operation.signature } : {},
619
+ ...operation.error ? { error: operation.error } : {},
620
+ owner: claim.owner,
621
+ releaseLease: true,
622
+ env: params.env
623
+ });
624
+ if (operation.state === "failed") {
625
+ throw new Error(operation.error || `SAT signer operation ${requestId} failed`);
626
+ }
627
+ if (operation.state !== "confirmed" || !operation.signature) {
628
+ throw new SatSubmissionUnresolvedError({
629
+ requestId,
630
+ state: operation.state,
631
+ signature: operation.signature,
632
+ detail: operation.error
633
+ });
634
+ }
635
+ return {
636
+ ...operation,
637
+ signature: operation.signature
240
638
  };
241
639
  }
242
640
  async function submitInstructionViaLocalSigner(params) {
@@ -244,21 +642,29 @@ async function submitInstructionViaLocalSigner(params) {
244
642
  const request = await buildLocalSignerInstructionRequest({
245
643
  solana: context.solana,
246
644
  signer: context.signer,
247
- walletId: context.walletId,
645
+ env: context.effectiveEnv,
248
646
  spec: params
249
647
  });
250
- const submitted = await callLocalSocketSigner(context.socketPath, {
251
- op: "sendSolanaInstruction",
252
- request
648
+ if (!context.walletId) {
649
+ throw new Error("typed SAT signing requires an explicit mining walletId");
650
+ }
651
+ const submitted = await executeTypedSatIntent({
652
+ socketPath: context.socketPath,
653
+ walletId: context.walletId,
654
+ action: request.action,
655
+ instruction: request,
656
+ cluster: resolveSatCluster(params.cfg),
657
+ env: context.effectiveEnv
253
658
  });
254
659
  return {
255
- txHash: submitted.txHash,
256
- signer: submitted.signer ?? context.signerAddress
660
+ txHash: submitted.signature,
661
+ signer: context.signerAddress,
662
+ signerState: submitted.state,
663
+ requestId: submitted.requestId
257
664
  };
258
665
  }
259
666
  async function submitInstruction(params) {
260
667
  const effectiveEnv = resolveSatEffectiveEnv(params.cfg, params.env);
261
- await enforceSatCustodyAutonomousSigning(params.cfg, effectiveEnv);
262
668
  if (resolveSatProviderId(params.cfg, effectiveEnv) !== "local-socket-signer") {
263
669
  throw new Error("SAT mining unattended submission currently requires local-socket-signer");
264
670
  }
@@ -278,7 +684,6 @@ async function submitInstructionBatch(params) {
278
684
  throw new Error("SAT cleanup batch exceeds signer limit");
279
685
  }
280
686
  const effectiveEnv = resolveSatEffectiveEnv(params.cfg, params.env);
281
- await enforceSatCustodyAutonomousSigning(params.cfg, effectiveEnv);
282
687
  if (resolveSatProviderId(params.cfg, effectiveEnv) !== "local-socket-signer") {
283
688
  throw new Error("SAT mining unattended batch submission currently requires local-socket-signer");
284
689
  }
@@ -288,21 +693,26 @@ async function submitInstructionBatch(params) {
288
693
  instructions.push(await buildLocalSignerInstructionRequest({
289
694
  solana: context.solana,
290
695
  signer: context.signer,
291
- walletId: context.walletId,
696
+ env: context.effectiveEnv,
292
697
  spec
293
698
  }));
294
699
  }
295
- const submitted = await callLocalSocketSigner(context.socketPath, {
296
- op: "sendSolanaInstructions",
297
- request: {
298
- ...context.walletId ? { walletId: context.walletId } : {},
299
- purpose: params.purpose,
300
- instructions
301
- }
700
+ if (!context.walletId) {
701
+ throw new Error("typed SAT cleanup signing requires an explicit mining walletId");
702
+ }
703
+ const submitted = await executeTypedSatIntent({
704
+ socketPath: context.socketPath,
705
+ walletId: context.walletId,
706
+ action: "cleanupBatch",
707
+ instructions,
708
+ cluster: resolveSatCluster(params.cfg),
709
+ env: context.effectiveEnv
302
710
  });
303
711
  return {
304
- txHash: submitted.txHash,
305
- signer: submitted.signer ?? context.signerAddress,
712
+ txHash: submitted.signature,
713
+ signer: context.signerAddress,
714
+ signerState: submitted.state,
715
+ requestId: submitted.requestId,
306
716
  instructionCount: instructions.length
307
717
  };
308
718
  }
@@ -390,12 +800,8 @@ function buildClaimData(params) {
390
800
  function buildMiningCrankData() {
391
801
  return Buffer.from([IX.miningCrank]);
392
802
  }
393
- function buildBootstrapData(params) {
394
- return Buffer.concat([
395
- Buffer.from([IX.bootstrap]),
396
- encodePubkey(params.authority),
397
- encodeU64(params.initialStake)
398
- ]);
803
+ function buildTopUpRegistryReserveData(params) {
804
+ return Buffer.concat([Buffer.from([IX.topUpRegistryReserve]), encodeU64(params.targetBalanceLamports)]);
399
805
  }
400
806
  function buildOpenCycleData(params) {
401
807
  return Buffer.concat([Buffer.from([IX.openCycle]), encodeU64(params.cycleId)]);
@@ -412,16 +818,6 @@ function buildWithdrawMinerCapitalData(params) {
412
818
  function buildSetActiveCommitData(params) {
413
819
  return Buffer.concat([Buffer.from([IX.setActiveCommit]), encodeU64(params.lamports)]);
414
820
  }
415
- function buildInitBondTierPolicyData(params) {
416
- return Buffer.concat([
417
- Buffer.from([BOND_IX.initTierPolicy]),
418
- encodePubkey(params.updateAuthority),
419
- encodeU64(params.basicMinRaw),
420
- encodeU64(params.operatorMinRaw),
421
- encodeU64(params.unlockDelaySlots),
422
- encodeU64(params.scheduledEffectiveSlot ?? 0)
423
- ]);
424
- }
425
821
  function buildUpdateBondTierPolicyData(params) {
426
822
  return Buffer.concat([
427
823
  Buffer.from([BOND_IX.updateTierPolicy]),
@@ -452,14 +848,6 @@ function buildFinalizeBondUnlockData(env = process.env) {
452
848
  assertDedicatedBondProgram(env);
453
849
  return Buffer.from([BOND_IX.finalizeBondUnlock]);
454
850
  }
455
- function buildInitBondStakingDistributorData(params, env = process.env) {
456
- assertDedicatedBondProgram(env);
457
- return Buffer.concat([
458
- Buffer.from([BOND_IX.initStakingDistributor]),
459
- encodePubkey(params.updateAuthority),
460
- encodeU64(params.minStakeRaw)
461
- ]);
462
- }
463
851
  function buildSyncBondStakingRewardsData(env = process.env) {
464
852
  assertDedicatedBondProgram(env);
465
853
  return Buffer.from([BOND_IX.syncStakingRewards]);
@@ -472,22 +860,75 @@ function buildClaimBondStakingRewardsData(env = process.env) {
472
860
  assertDedicatedBondProgram(env);
473
861
  return Buffer.from([BOND_IX.claimStakingRewards]);
474
862
  }
475
- function buildSubmitCycleData(params) {
476
- if (params.allocationFp.length !== 25) {
477
- throw new Error(`expected 25 allocation buckets, got ${params.allocationFp.length}`);
863
+ function buildClaimUnallocatedStakingRewardsData(env = process.env) {
864
+ assertDedicatedBondProgram(env);
865
+ return Buffer.from([BOND_IX.claimUnallocatedStakingRewards]);
866
+ }
867
+ function encodeAllocationFp(allocationFp) {
868
+ if (allocationFp.length !== 25) {
869
+ throw new Error(`expected 25 allocation buckets, got ${allocationFp.length}`);
870
+ }
871
+ return Buffer.concat(allocationFp.map((value) => {
872
+ if (!Number.isSafeInteger(value) || value < 0 || value > 4294967295) {
873
+ throw new Error(`invalid allocation bucket value: ${value}`);
874
+ }
875
+ const out = Buffer.alloc(4);
876
+ out.writeUInt32LE(value);
877
+ return out;
878
+ }));
879
+ }
880
+ function buildSatCycleCommitment(params) {
881
+ if (params.nonce.length !== 32) {
882
+ throw new Error(`expected 32-byte cycle nonce, got ${params.nonce.length}`);
478
883
  }
479
- const body = Buffer.concat([
480
- Buffer.from([IX.submitCycle]),
884
+ const allocation = encodeAllocationFp(params.allocationFp);
885
+ return createHash("sha256").update(Buffer.concat([
886
+ Buffer.from("sat-cycle-commit-v1"),
887
+ encodePubkey(params.programId ?? SAT_PROGRAM_ID()),
888
+ encodePubkey(params.authority),
481
889
  encodeU64(params.cycleId),
482
- Buffer.concat(params.allocationFp.map((value) => {
483
- const out = Buffer.alloc(4);
484
- out.writeUInt32LE(value);
485
- return out;
486
- })),
890
+ encodeU64(params.committedLamports),
891
+ params.nonce,
892
+ allocation
893
+ ])).digest();
894
+ }
895
+ function buildCommitCycleData(params) {
896
+ if (params.commitment.length !== 32) {
897
+ throw new Error(`expected 32-byte cycle commitment, got ${params.commitment.length}`);
898
+ }
899
+ return Buffer.concat([
900
+ Buffer.from([IX.commitCycle]),
901
+ encodeU64(params.cycleId),
902
+ params.commitment
903
+ ]);
904
+ }
905
+ function buildCloseCommitPhaseData(params) {
906
+ return Buffer.concat([Buffer.from([IX.closeCommitPhase]), encodeU64(params.cycleId)]);
907
+ }
908
+ function buildSealCycleEntropyData(params) {
909
+ return Buffer.concat([Buffer.from([IX.sealCycleEntropy]), encodeU64(params.cycleId)]);
910
+ }
911
+ function buildRevealCycleData(params) {
912
+ if (params.nonce.length !== 32) {
913
+ throw new Error(`expected 32-byte cycle nonce, got ${params.nonce.length}`);
914
+ }
915
+ return Buffer.concat([
916
+ Buffer.from([IX.revealCycle]),
917
+ encodeU64(params.cycleId),
918
+ params.nonce,
919
+ encodeAllocationFp(params.allocationFp),
487
920
  Buffer.alloc(4)
488
921
  ]);
489
- satSubmitDebug(`[sat-submit-build] allocs=${params.allocationFp.length} len=${body.length} cycle=${params.cycleId}`);
490
- return body;
922
+ }
923
+ function buildReleaseUnrevealedCommitData(params) {
924
+ return Buffer.concat([
925
+ Buffer.from([IX.releaseUnrevealedCommit]),
926
+ encodeU64(params.cycleId),
927
+ encodePubkey(params.minerAuthority)
928
+ ]);
929
+ }
930
+ function buildAbortEmptyCycleData(params) {
931
+ return Buffer.concat([Buffer.from([IX.abortEmptyCycle]), encodeU64(params.cycleId)]);
491
932
  }
492
933
  function buildClaimCycleRewardsData(params) {
493
934
  return Buffer.concat([Buffer.from([IX.claimCycleRewards]), encodeU64(params.cycleId)]);
@@ -504,13 +945,6 @@ function buildClaimCycleRewardsBatchData(params) {
504
945
  ...params.cycleIds.map((cycleId) => encodeU64(cycleId))
505
946
  ]);
506
947
  }
507
- function buildSetProtocolRecipientsData(params) {
508
- return Buffer.concat([
509
- Buffer.from([IX.setProtocolRecipients]),
510
- encodePubkey(params.treasuryRecipient),
511
- encodePubkey(params.distributorRecipient)
512
- ]);
513
- }
514
948
  function buildClaimProtocolTreasuryData() {
515
949
  return Buffer.from([IX.claimProtocolTreasury]);
516
950
  }
@@ -644,33 +1078,36 @@ async function submitSatValidatorAttestation(_config, params) {
644
1078
  encodeU64(params.microRoundId)
645
1079
  ], programId);
646
1080
  const [miningStake] = solana.PublicKey.findProgramAddressSync([Buffer.from(MINING_STAKE_SEED), targetAuthority.toBuffer()], programId);
647
- return [
648
- {
649
- pubkey: signer,
650
- isSigner: true,
651
- isWritable: true
652
- },
653
- {
654
- pubkey: satEpoch,
655
- isSigner: false,
656
- isWritable: true
657
- },
658
- {
659
- pubkey: satValidatorAttestation,
660
- isSigner: false,
661
- isWritable: true
662
- },
663
- {
664
- pubkey: miningStake,
665
- isSigner: false,
666
- isWritable: true
667
- },
668
- {
669
- pubkey: solana.SystemProgram.programId,
670
- isSigner: false,
671
- isWritable: false
672
- }
673
- ];
1081
+ return {
1082
+ keys: [
1083
+ {
1084
+ pubkey: signer,
1085
+ isSigner: true,
1086
+ isWritable: true
1087
+ },
1088
+ {
1089
+ pubkey: satEpoch,
1090
+ isSigner: false,
1091
+ isWritable: true
1092
+ },
1093
+ {
1094
+ pubkey: satValidatorAttestation,
1095
+ isSigner: false,
1096
+ isWritable: true
1097
+ },
1098
+ {
1099
+ pubkey: miningStake,
1100
+ isSigner: false,
1101
+ isWritable: true
1102
+ },
1103
+ {
1104
+ pubkey: solana.SystemProgram.programId,
1105
+ isSigner: false,
1106
+ isWritable: false
1107
+ }
1108
+ ],
1109
+ context: { targetAuthority: targetAuthority.toBase58() }
1110
+ };
674
1111
  }
675
1112
  });
676
1113
  }
@@ -692,33 +1129,36 @@ async function submitSatOpenDispute(_config, params) {
692
1129
  encodeU64(params.microRoundId)
693
1130
  ], programId);
694
1131
  const [miningStake] = solana.PublicKey.findProgramAddressSync([Buffer.from(MINING_STAKE_SEED), targetAuthority.toBuffer()], programId);
695
- return [
696
- {
697
- pubkey: signer,
698
- isSigner: true,
699
- isWritable: true
700
- },
701
- {
702
- pubkey: satEpoch,
703
- isSigner: false,
704
- isWritable: true
705
- },
706
- {
707
- pubkey: satDispute,
708
- isSigner: false,
709
- isWritable: true
710
- },
711
- {
712
- pubkey: miningStake,
713
- isSigner: false,
714
- isWritable: true
715
- },
716
- {
717
- pubkey: solana.SystemProgram.programId,
718
- isSigner: false,
719
- isWritable: false
720
- }
721
- ];
1132
+ return {
1133
+ keys: [
1134
+ {
1135
+ pubkey: signer,
1136
+ isSigner: true,
1137
+ isWritable: true
1138
+ },
1139
+ {
1140
+ pubkey: satEpoch,
1141
+ isSigner: false,
1142
+ isWritable: true
1143
+ },
1144
+ {
1145
+ pubkey: satDispute,
1146
+ isSigner: false,
1147
+ isWritable: true
1148
+ },
1149
+ {
1150
+ pubkey: miningStake,
1151
+ isSigner: false,
1152
+ isWritable: true
1153
+ },
1154
+ {
1155
+ pubkey: solana.SystemProgram.programId,
1156
+ isSigner: false,
1157
+ isWritable: false
1158
+ }
1159
+ ],
1160
+ context: { targetAuthority: targetAuthority.toBase58() }
1161
+ };
722
1162
  }
723
1163
  });
724
1164
  }
@@ -741,28 +1181,31 @@ async function submitSatResolveDispute(_config, params) {
741
1181
  encodeU64(params.epochId),
742
1182
  encodeU64(params.microRoundId)
743
1183
  ], programId);
744
- return [
745
- {
746
- pubkey: signer,
747
- isSigner: true,
748
- isWritable: true
749
- },
750
- {
751
- pubkey: miningPool,
752
- isSigner: false,
753
- isWritable: false
754
- },
755
- {
756
- pubkey: satEpoch,
757
- isSigner: false,
758
- isWritable: true
759
- },
760
- {
761
- pubkey: satDispute,
762
- isSigner: false,
763
- isWritable: true
764
- }
765
- ];
1184
+ return {
1185
+ keys: [
1186
+ {
1187
+ pubkey: signer,
1188
+ isSigner: true,
1189
+ isWritable: true
1190
+ },
1191
+ {
1192
+ pubkey: miningPool,
1193
+ isSigner: false,
1194
+ isWritable: false
1195
+ },
1196
+ {
1197
+ pubkey: satEpoch,
1198
+ isSigner: false,
1199
+ isWritable: true
1200
+ },
1201
+ {
1202
+ pubkey: satDispute,
1203
+ isSigner: false,
1204
+ isWritable: true
1205
+ }
1206
+ ],
1207
+ context: { disputeAuthority: disputeAuthority.toBase58() }
1208
+ };
766
1209
  }
767
1210
  });
768
1211
  }
@@ -796,44 +1239,29 @@ async function submitSatRepublishEpochRoots(_config, params) {
796
1239
  }
797
1240
  });
798
1241
  }
799
- async function submitSatBootstrap(_config, params = {}) {
1242
+ async function submitSatTopUpRegistryReserve(_config, params) {
800
1243
  const cfg = loadConfigForSatRuntime(_config);
1244
+ const targetBalanceLamports = Math.max(0, Math.floor(params.targetBalanceLamports));
1245
+ if (!Number.isSafeInteger(targetBalanceLamports)) {
1246
+ throw new Error("registry reserve target must be a safe integer lamport amount");
1247
+ }
1248
+ const profile = resolveSatGenesisProfileContract(_config.network);
1249
+ if (BigInt(targetBalanceLamports) > profile.registryReserveMaxLamports) {
1250
+ throw new Error(`registry reserve target exceeds ${profile.cluster} genesis maximum ${profile.registryReserveMaxLamports}`);
1251
+ }
801
1252
  return submitInstruction({
802
1253
  cfg,
803
1254
  env: process.env,
804
- data: buildBootstrapData({
805
- authority: params.authority ?? "",
806
- initialStake: Math.max(0, Math.floor(params.initialStake ?? 0))
807
- }),
1255
+ data: buildTopUpRegistryReserveData({ targetBalanceLamports }),
808
1256
  accountResolver: async (solana, signer) => {
809
1257
  const programId = new solana.PublicKey(SAT_PROGRAM_ID());
810
- const [satGlobalState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_GLOBAL_STATE_SEED)], programId);
811
- const [treasury] = solana.PublicKey.findProgramAddressSync([Buffer.from("treasury")], programId);
812
- const [satTreasuryState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_TREASURY_STATE_SEED)], programId);
813
1258
  const [satRegistryReserve] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_REGISTRY_RESERVE_SEED)], programId);
814
- const [satRebateVault] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_REBATE_VAULT_SEED)], programId);
815
- const [satTreasuryVault] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_TREASURY_VAULT_SEED)], programId);
816
1259
  return [
817
1260
  {
818
1261
  pubkey: signer,
819
1262
  isSigner: true,
820
1263
  isWritable: true
821
1264
  },
822
- {
823
- pubkey: satGlobalState,
824
- isSigner: false,
825
- isWritable: true
826
- },
827
- {
828
- pubkey: treasury,
829
- isSigner: false,
830
- isWritable: true
831
- },
832
- {
833
- pubkey: satTreasuryState,
834
- isSigner: false,
835
- isWritable: true
836
- },
837
1265
  {
838
1266
  pubkey: satRegistryReserve,
839
1267
  isSigner: false,
@@ -843,16 +1271,6 @@ async function submitSatBootstrap(_config, params = {}) {
843
1271
  pubkey: solana.SystemProgram.programId,
844
1272
  isSigner: false,
845
1273
  isWritable: false
846
- },
847
- {
848
- pubkey: satRebateVault,
849
- isSigner: false,
850
- isWritable: true
851
- },
852
- {
853
- pubkey: satTreasuryVault,
854
- isSigner: false,
855
- isWritable: true
856
1274
  }
857
1275
  ];
858
1276
  }
@@ -919,14 +1337,16 @@ async function submitSatOpenCycle(_config, params) {
919
1337
  }
920
1338
  async function submitSatInitMinerCapital(_config, params) {
921
1339
  const cfg = loadConfigForSatRuntime(_config);
1340
+ const effectiveEnv = resolveSatEffectiveEnv(cfg, process.env);
1341
+ const authority = params.authority?.trim() || await resolveSatLocalSignerAddress(cfg, effectiveEnv, "local-socket-signer returned no Solana address for SAT miner capital authority");
922
1342
  return submitInstruction({
923
1343
  cfg,
924
- env: process.env,
925
- data: buildInitMinerCapitalData({ authority: params.authority ?? "" }),
1344
+ env: effectiveEnv,
1345
+ data: buildInitMinerCapitalData({ authority }),
926
1346
  accountResolver: async (solana, signer) => {
927
1347
  const programId = new solana.PublicKey(SAT_PROGRAM_ID());
928
- const authority = params.authority?.trim() ? new solana.PublicKey(params.authority) : signer;
929
- const [satMinerCapitalState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_MINER_CAPITAL_STATE_SEED), authority.toBuffer()], programId);
1348
+ const authorityKey = new solana.PublicKey(authority);
1349
+ const [satMinerCapitalState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_MINER_CAPITAL_STATE_SEED), authorityKey.toBuffer()], programId);
930
1350
  return [
931
1351
  {
932
1352
  pubkey: signer,
@@ -1049,50 +1469,13 @@ function resolveSatBondAccounts(solana, signer, env = process.env) {
1049
1469
  dedicated: hasDedicatedBondProgram(env)
1050
1470
  };
1051
1471
  }
1052
- async function submitSatInitBondTierPolicy(_config, params) {
1053
- const cfg = loadConfigForSatRuntime(_config);
1054
- const effectiveEnv = resolveSatEffectiveEnv(cfg, process.env);
1055
- if (!hasDedicatedBondProgram(effectiveEnv)) {
1056
- throw new Error("SAT bond tier policy init requires FASED_SAT_BOND_PROGRAM_ID");
1057
- }
1058
- const defaultUpdateAuthority = resolveSatRegistrySolanaAddress(cfg, effectiveEnv) || await resolveSatLocalSignerAddress(cfg, effectiveEnv, "local-socket-signer returned no Solana address for SAT bond policy authority");
1059
- return submitInstruction({
1060
- cfg,
1061
- env: effectiveEnv,
1062
- data: buildInitBondTierPolicyData({
1063
- ...params,
1064
- updateAuthority: params.updateAuthority ?? defaultUpdateAuthority
1065
- }),
1066
- programId: resolveSatBondProgramIdFromEnv(effectiveEnv),
1067
- accountResolver: async (solana, signer) => {
1068
- const { bondTierPolicy } = resolveSatBondAccounts(solana, signer, effectiveEnv);
1069
- return [
1070
- {
1071
- pubkey: signer,
1072
- isSigner: true,
1073
- isWritable: true
1074
- },
1075
- {
1076
- pubkey: bondTierPolicy,
1077
- isSigner: false,
1078
- isWritable: true
1079
- },
1080
- {
1081
- pubkey: solana.SystemProgram.programId,
1082
- isSigner: false,
1083
- isWritable: false
1084
- }
1085
- ];
1086
- }
1087
- });
1088
- }
1089
1472
  async function submitSatUpdateBondTierPolicy(_config, params) {
1090
1473
  const cfg = loadConfigForSatRuntime(_config);
1091
1474
  const effectiveEnv = resolveSatEffectiveEnv(cfg, process.env);
1092
1475
  if (!hasDedicatedBondProgram(effectiveEnv)) {
1093
1476
  throw new Error("SAT bond tier policy update requires FASED_SAT_BOND_PROGRAM_ID");
1094
1477
  }
1095
- const defaultUpdateAuthority = resolveSatRegistrySolanaAddress(cfg, effectiveEnv) || await resolveSatLocalSignerAddress(cfg, effectiveEnv, "local-socket-signer returned no Solana address for SAT bond policy authority");
1478
+ const defaultUpdateAuthority = await resolveSatLocalSignerAddress(cfg, effectiveEnv, "local-socket-signer returned no Solana address for SAT bond policy authority");
1096
1479
  return submitInstruction({
1097
1480
  cfg,
1098
1481
  env: effectiveEnv,
@@ -1231,7 +1614,7 @@ async function submitSatRequestBondUnlock(_config) {
1231
1614
  data: buildRequestBondUnlockData(effectiveEnv),
1232
1615
  programId: resolveSatBondProgramIdFromEnv(effectiveEnv),
1233
1616
  accountResolver: async (solana, signer) => {
1234
- const { bondTierPolicy, bondPosition } = resolveSatBondAccounts(solana, signer, effectiveEnv);
1617
+ const { bondTierPolicy, bondPosition, bondStakingDistributor, bondStakingPosition } = resolveSatBondAccounts(solana, signer, effectiveEnv);
1235
1618
  const accounts = [{
1236
1619
  pubkey: signer,
1237
1620
  isSigner: true,
@@ -1245,6 +1628,14 @@ async function submitSatRequestBondUnlock(_config) {
1245
1628
  pubkey: bondPosition,
1246
1629
  isSigner: false,
1247
1630
  isWritable: true
1631
+ }, {
1632
+ pubkey: bondStakingDistributor,
1633
+ isSigner: false,
1634
+ isWritable: true
1635
+ }, {
1636
+ pubkey: bondStakingPosition,
1637
+ isSigner: false,
1638
+ isWritable: true
1248
1639
  });
1249
1640
  return accounts;
1250
1641
  }
@@ -1260,7 +1651,7 @@ async function submitSatCancelBondUnlock(_config) {
1260
1651
  data: buildCancelBondUnlockData(effectiveEnv),
1261
1652
  programId: resolveSatBondProgramIdFromEnv(effectiveEnv),
1262
1653
  accountResolver: async (solana, signer) => {
1263
- const { bondTierPolicy, bondPosition } = resolveSatBondAccounts(solana, signer, effectiveEnv);
1654
+ const { bondTierPolicy, bondPosition, bondStakingDistributor, bondStakingPosition } = resolveSatBondAccounts(solana, signer, effectiveEnv);
1264
1655
  const accounts = [{
1265
1656
  pubkey: signer,
1266
1657
  isSigner: true,
@@ -1274,6 +1665,14 @@ async function submitSatCancelBondUnlock(_config) {
1274
1665
  pubkey: bondPosition,
1275
1666
  isSigner: false,
1276
1667
  isWritable: true
1668
+ }, {
1669
+ pubkey: bondStakingDistributor,
1670
+ isSigner: false,
1671
+ isWritable: true
1672
+ }, {
1673
+ pubkey: bondStakingPosition,
1674
+ isSigner: false,
1675
+ isWritable: true
1277
1676
  });
1278
1677
  return accounts;
1279
1678
  }
@@ -1289,7 +1688,7 @@ async function submitSatFinalizeBondUnlock(_config) {
1289
1688
  data: buildFinalizeBondUnlockData(effectiveEnv),
1290
1689
  programId: resolveSatBondProgramIdFromEnv(effectiveEnv),
1291
1690
  accountResolver: async (solana, signer) => {
1292
- const { bondTierPolicy, bondPosition, signerTokenAccount, bondVault, mint } = resolveSatBondAccounts(solana, signer, effectiveEnv);
1691
+ const { bondTierPolicy, bondPosition, bondStakingDistributor, bondStakingPosition, signerTokenAccount, bondVault, mint } = resolveSatBondAccounts(solana, signer, effectiveEnv);
1293
1692
  const accounts = [{
1294
1693
  pubkey: signer,
1295
1694
  isSigner: true,
@@ -1303,6 +1702,14 @@ async function submitSatFinalizeBondUnlock(_config) {
1303
1702
  pubkey: bondPosition,
1304
1703
  isSigner: false,
1305
1704
  isWritable: true
1705
+ }, {
1706
+ pubkey: bondStakingDistributor,
1707
+ isSigner: false,
1708
+ isWritable: true
1709
+ }, {
1710
+ pubkey: bondStakingPosition,
1711
+ isSigner: false,
1712
+ isWritable: true
1306
1713
  }, {
1307
1714
  pubkey: bondVault,
1308
1715
  isSigner: false,
@@ -1324,66 +1731,11 @@ async function submitSatFinalizeBondUnlock(_config) {
1324
1731
  isSigner: false,
1325
1732
  isWritable: false
1326
1733
  }, {
1327
- pubkey: new solana.PublicKey(ASSOCIATED_TOKEN_PROGRAM_ID),
1328
- isSigner: false,
1329
- isWritable: false
1330
- });
1331
- return accounts;
1332
- }
1333
- });
1334
- }
1335
- async function submitSatInitBondStakingDistributor(_config, params) {
1336
- const cfg = loadConfigForSatRuntime(_config);
1337
- const effectiveEnv = resolveSatEffectiveEnv(cfg, process.env);
1338
- assertDedicatedBondProgram(effectiveEnv);
1339
- const defaultUpdateAuthority = await resolveSatLocalSignerAddress(cfg, effectiveEnv, "local-socket-signer returned no Solana address for SAT bond staking distributor authority");
1340
- return submitInstruction({
1341
- cfg,
1342
- env: effectiveEnv,
1343
- data: buildInitBondStakingDistributorData({
1344
- minStakeRaw: params.minStakeRaw,
1345
- updateAuthority: params.updateAuthority ?? defaultUpdateAuthority
1346
- }, effectiveEnv),
1347
- programId: resolveSatBondProgramIdFromEnv(effectiveEnv),
1348
- accountResolver: async (solana, signer) => {
1349
- const { bondStakingDistributor, bondStakingRewardVault, mint } = resolveSatBondAccounts(solana, signer, effectiveEnv);
1350
- return [
1351
- {
1352
- pubkey: signer,
1353
- isSigner: true,
1354
- isWritable: true
1355
- },
1356
- {
1357
- pubkey: bondStakingDistributor,
1358
- isSigner: false,
1359
- isWritable: true
1360
- },
1361
- {
1362
- pubkey: bondStakingRewardVault,
1363
- isSigner: false,
1364
- isWritable: true
1365
- },
1366
- {
1367
- pubkey: mint,
1368
- isSigner: false,
1369
- isWritable: true
1370
- },
1371
- {
1372
- pubkey: solana.SystemProgram.programId,
1373
- isSigner: false,
1374
- isWritable: false
1375
- },
1376
- {
1377
- pubkey: new solana.PublicKey(TOKEN_PROGRAM_ID),
1378
- isSigner: false,
1379
- isWritable: false
1380
- },
1381
- {
1382
- pubkey: new solana.PublicKey(ASSOCIATED_TOKEN_PROGRAM_ID),
1383
- isSigner: false,
1384
- isWritable: false
1385
- }
1386
- ];
1734
+ pubkey: new solana.PublicKey(ASSOCIATED_TOKEN_PROGRAM_ID),
1735
+ isSigner: false,
1736
+ isWritable: false
1737
+ });
1738
+ return accounts;
1387
1739
  }
1388
1740
  });
1389
1741
  }
@@ -1535,34 +1887,88 @@ async function submitSatClaimBondStakingRewards(_config) {
1535
1887
  }
1536
1888
  });
1537
1889
  }
1538
- async function submitSatCycle(_config, params) {
1890
+ async function submitSatClaimUnallocatedStakingRewards(_config, params) {
1891
+ const cfg = loadConfigForSatRuntime(_config);
1892
+ const effectiveEnv = resolveSatEffectiveEnv(cfg, process.env);
1893
+ assertDedicatedBondProgram(effectiveEnv);
1894
+ return submitInstruction({
1895
+ cfg,
1896
+ env: effectiveEnv,
1897
+ data: buildClaimUnallocatedStakingRewardsData(effectiveEnv),
1898
+ programId: resolveSatBondProgramIdFromEnv(effectiveEnv),
1899
+ accountResolver: async (solana, signer) => {
1900
+ const { bondStakingDistributor, bondStakingRewardVault, mint } = resolveSatBondAccounts(solana, signer, effectiveEnv);
1901
+ const recipientOwner = new solana.PublicKey(params.recipientOwner);
1902
+ const recipientTokenAccount = deriveAssociatedTokenAddress(solana, recipientOwner, mint);
1903
+ return [
1904
+ {
1905
+ pubkey: signer,
1906
+ isSigner: true,
1907
+ isWritable: true
1908
+ },
1909
+ {
1910
+ pubkey: bondStakingDistributor,
1911
+ isSigner: false,
1912
+ isWritable: true
1913
+ },
1914
+ {
1915
+ pubkey: bondStakingRewardVault,
1916
+ isSigner: false,
1917
+ isWritable: true
1918
+ },
1919
+ {
1920
+ pubkey: recipientTokenAccount,
1921
+ isSigner: false,
1922
+ isWritable: true
1923
+ },
1924
+ {
1925
+ pubkey: recipientOwner,
1926
+ isSigner: false,
1927
+ isWritable: false
1928
+ },
1929
+ {
1930
+ pubkey: mint,
1931
+ isSigner: false,
1932
+ isWritable: true
1933
+ },
1934
+ {
1935
+ pubkey: solana.SystemProgram.programId,
1936
+ isSigner: false,
1937
+ isWritable: false
1938
+ },
1939
+ {
1940
+ pubkey: new solana.PublicKey(TOKEN_PROGRAM_ID),
1941
+ isSigner: false,
1942
+ isWritable: false
1943
+ },
1944
+ {
1945
+ pubkey: new solana.PublicKey(ASSOCIATED_TOKEN_PROGRAM_ID),
1946
+ isSigner: false,
1947
+ isWritable: false
1948
+ }
1949
+ ];
1950
+ }
1951
+ });
1952
+ }
1953
+ async function submitSatCommitCycle(_config, params) {
1539
1954
  const cfg = loadConfigForSatRuntime(_config);
1955
+ const commitment = Buffer.from(params.commitmentHex, "hex");
1540
1956
  return submitInstruction({
1541
1957
  cfg,
1542
1958
  env: process.env,
1543
- data: buildSubmitCycleData(params),
1959
+ data: buildCommitCycleData({
1960
+ cycleId: params.cycleId,
1961
+ commitment
1962
+ }),
1544
1963
  accountResolver: async (solana, signer) => {
1545
1964
  const programId = new solana.PublicKey(SAT_PROGRAM_ID());
1546
- const pageIndex = await resolveSatCycleRegistryPageIndex(_config, params.cycleId);
1547
- const [satGlobalState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_GLOBAL_STATE_SEED)], programId);
1548
1965
  const [satCycleState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_CYCLE_STATE_SEED), encodeU64(params.cycleId)], programId);
1549
- const [satCycleRegistryMeta] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_CYCLE_REGISTRY_META_SEED), encodeU64(params.cycleId)], programId);
1550
- const [satCycleRegistryPage] = solana.PublicKey.findProgramAddressSync([
1551
- Buffer.from(SAT_CYCLE_REGISTRY_PAGE_SEED),
1552
- encodeU64(params.cycleId),
1553
- encodeU64(pageIndex)
1554
- ], programId);
1555
- const [satCycleSettlementProgress] = solana.PublicKey.findProgramAddressSync([Buffer.from("sat_cycle_settlement_progress_v2"), encodeU64(params.cycleId)], programId);
1556
1966
  const [satMinerCycleState] = solana.PublicKey.findProgramAddressSync([
1557
1967
  Buffer.from(SAT_MINER_CYCLE_STATE_SEED),
1558
1968
  signer.toBuffer(),
1559
1969
  encodeU64(params.cycleId)
1560
1970
  ], programId);
1561
1971
  const [satMinerCapitalState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_MINER_CAPITAL_STATE_SEED), signer.toBuffer()], programId);
1562
- const [satRegistryReserve] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_REGISTRY_RESERVE_SEED)], programId);
1563
- const [satTreasuryState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_TREASURY_STATE_SEED)], programId);
1564
- const [satRebateVault] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_REBATE_VAULT_SEED)], programId);
1565
- const [satTreasuryVault] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_TREASURY_VAULT_SEED)], programId);
1566
1972
  return [
1567
1973
  {
1568
1974
  pubkey: signer,
@@ -1570,27 +1976,112 @@ async function submitSatCycle(_config, params) {
1570
1976
  isWritable: true
1571
1977
  },
1572
1978
  {
1573
- pubkey: satGlobalState,
1979
+ pubkey: satCycleState,
1574
1980
  isSigner: false,
1575
1981
  isWritable: true
1576
1982
  },
1577
1983
  {
1578
- pubkey: satCycleState,
1984
+ pubkey: satMinerCycleState,
1579
1985
  isSigner: false,
1580
1986
  isWritable: true
1581
1987
  },
1582
1988
  {
1583
- pubkey: satCycleRegistryMeta,
1989
+ pubkey: satMinerCapitalState,
1584
1990
  isSigner: false,
1585
1991
  isWritable: true
1586
1992
  },
1587
1993
  {
1588
- pubkey: satCycleRegistryPage,
1994
+ pubkey: solana.SystemProgram.programId,
1995
+ isSigner: false,
1996
+ isWritable: false
1997
+ }
1998
+ ];
1999
+ }
2000
+ });
2001
+ }
2002
+ async function submitSatCyclePhaseInstruction(_config, params) {
2003
+ const cfg = loadConfigForSatRuntime(_config);
2004
+ return submitInstruction({
2005
+ cfg,
2006
+ env: process.env,
2007
+ data: params.phase === "close" ? buildCloseCommitPhaseData(params) : buildSealCycleEntropyData(params),
2008
+ accountResolver: async (solana, signer) => {
2009
+ const programId = new solana.PublicKey(SAT_PROGRAM_ID());
2010
+ const [satCycleState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_CYCLE_STATE_SEED), encodeU64(params.cycleId)], programId);
2011
+ const accounts = [{
2012
+ pubkey: signer,
2013
+ isSigner: true,
2014
+ isWritable: false
2015
+ }, {
2016
+ pubkey: satCycleState,
2017
+ isSigner: false,
2018
+ isWritable: true
2019
+ }];
2020
+ let intervalStartCycleIdForSigner;
2021
+ if (params.phase === "seal") {
2022
+ const cycle = params.intervalStartCycleId == null ? await inspectSatCycle(_config, { cycleId: params.cycleId }) : null;
2023
+ const intervalStartCycleId = params.intervalStartCycleId ?? cycle?.unlockIntervalStartCycleId;
2024
+ if (intervalStartCycleId == null || !Number.isSafeInteger(intervalStartCycleId)) {
2025
+ throw new Error(`SAT cycle ${params.cycleId} does not expose its unlock interval start`);
2026
+ }
2027
+ intervalStartCycleIdForSigner = intervalStartCycleId;
2028
+ const [satUnlockIntervalState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_UNLOCK_INTERVAL_STATE_SEED), encodeU64(intervalStartCycleId)], programId);
2029
+ accounts.push({
2030
+ pubkey: satUnlockIntervalState,
1589
2031
  isSigner: false,
1590
2032
  isWritable: true
2033
+ });
2034
+ accounts.push({
2035
+ pubkey: new solana.PublicKey(SLOT_HASHES_SYSVAR_ID),
2036
+ isSigner: false,
2037
+ isWritable: false
2038
+ });
2039
+ }
2040
+ return {
2041
+ keys: accounts,
2042
+ ...intervalStartCycleIdForSigner == null ? {} : { context: { intervalStartCycleId: String(intervalStartCycleIdForSigner) } }
2043
+ };
2044
+ }
2045
+ });
2046
+ }
2047
+ async function submitSatCloseCommitPhase(_config, params) {
2048
+ return submitSatCyclePhaseInstruction(_config, {
2049
+ ...params,
2050
+ phase: "close"
2051
+ });
2052
+ }
2053
+ async function submitSatSealCycleEntropy(_config, params) {
2054
+ return submitSatCyclePhaseInstruction(_config, {
2055
+ ...params,
2056
+ phase: "seal"
2057
+ });
2058
+ }
2059
+ async function submitSatReleaseUnrevealedCommit(_config, params) {
2060
+ const cfg = loadConfigForSatRuntime(_config);
2061
+ return submitInstruction({
2062
+ cfg,
2063
+ env: process.env,
2064
+ data: buildReleaseUnrevealedCommitData(params),
2065
+ accountResolver: async (solana, signer) => {
2066
+ const programId = new solana.PublicKey(SAT_PROGRAM_ID());
2067
+ const minerAuthority = new solana.PublicKey(params.minerAuthority);
2068
+ const [satCycleState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_CYCLE_STATE_SEED), encodeU64(params.cycleId)], programId);
2069
+ const [satMinerCycleState] = solana.PublicKey.findProgramAddressSync([
2070
+ Buffer.from(SAT_MINER_CYCLE_STATE_SEED),
2071
+ minerAuthority.toBuffer(),
2072
+ encodeU64(params.cycleId)
2073
+ ], programId);
2074
+ const [satMinerCapitalState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_MINER_CAPITAL_STATE_SEED), minerAuthority.toBuffer()], programId);
2075
+ const [satTreasuryState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_TREASURY_STATE_SEED)], programId);
2076
+ const [satTreasuryVault] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_TREASURY_VAULT_SEED)], programId);
2077
+ return [
2078
+ {
2079
+ pubkey: signer,
2080
+ isSigner: true,
2081
+ isWritable: false
1591
2082
  },
1592
2083
  {
1593
- pubkey: satCycleSettlementProgress,
2084
+ pubkey: satCycleState,
1594
2085
  isSigner: false,
1595
2086
  isWritable: true
1596
2087
  },
@@ -1605,27 +2096,42 @@ async function submitSatCycle(_config, params) {
1605
2096
  isWritable: true
1606
2097
  },
1607
2098
  {
1608
- pubkey: satRegistryReserve,
2099
+ pubkey: satTreasuryState,
1609
2100
  isSigner: false,
1610
2101
  isWritable: true
1611
2102
  },
1612
2103
  {
1613
- pubkey: satTreasuryState,
2104
+ pubkey: satTreasuryVault,
1614
2105
  isSigner: false,
1615
2106
  isWritable: true
1616
- },
2107
+ }
2108
+ ];
2109
+ }
2110
+ });
2111
+ }
2112
+ async function submitSatAbortEmptyCycle(_config, params) {
2113
+ const cfg = loadConfigForSatRuntime(_config);
2114
+ return submitInstruction({
2115
+ cfg,
2116
+ env: process.env,
2117
+ data: buildAbortEmptyCycleData(params),
2118
+ accountResolver: async (solana, signer) => {
2119
+ const programId = new solana.PublicKey(SAT_PROGRAM_ID());
2120
+ const [satCycleState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_CYCLE_STATE_SEED), encodeU64(params.cycleId)], programId);
2121
+ const [satCycleRegistryMeta] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_CYCLE_REGISTRY_META_SEED), encodeU64(params.cycleId)], programId);
2122
+ return [
1617
2123
  {
1618
- pubkey: solana.SystemProgram.programId,
1619
- isSigner: false,
2124
+ pubkey: signer,
2125
+ isSigner: true,
1620
2126
  isWritable: false
1621
2127
  },
1622
2128
  {
1623
- pubkey: satRebateVault,
2129
+ pubkey: satCycleState,
1624
2130
  isSigner: false,
1625
2131
  isWritable: true
1626
2132
  },
1627
2133
  {
1628
- pubkey: satTreasuryVault,
2134
+ pubkey: satCycleRegistryMeta,
1629
2135
  isSigner: false,
1630
2136
  isWritable: true
1631
2137
  }
@@ -1633,6 +2139,101 @@ async function submitSatCycle(_config, params) {
1633
2139
  }
1634
2140
  });
1635
2141
  }
2142
+ async function submitSatRevealCycle(_config, params) {
2143
+ const cfg = loadConfigForSatRuntime(_config);
2144
+ const nonce = Buffer.from(params.nonceBase64, "base64");
2145
+ return submitInstruction({
2146
+ cfg,
2147
+ env: process.env,
2148
+ data: buildRevealCycleData({
2149
+ ...params,
2150
+ nonce
2151
+ }),
2152
+ accountResolver: async (solana, signer) => {
2153
+ const programId = new solana.PublicKey(SAT_PROGRAM_ID());
2154
+ const pageIndex = await resolveSatCycleRegistryPageIndex(_config, params.cycleId);
2155
+ const cycle = params.intervalStartCycleId == null ? await inspectSatCycle(_config, { cycleId: params.cycleId }) : null;
2156
+ const intervalStartCycleId = params.intervalStartCycleId ?? cycle?.unlockIntervalStartCycleId;
2157
+ if (intervalStartCycleId == null || !Number.isSafeInteger(intervalStartCycleId)) {
2158
+ throw new Error(`SAT cycle ${params.cycleId} does not expose its unlock interval start`);
2159
+ }
2160
+ const [satCycleState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_CYCLE_STATE_SEED), encodeU64(params.cycleId)], programId);
2161
+ const [satCycleRegistryMeta] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_CYCLE_REGISTRY_META_SEED), encodeU64(params.cycleId)], programId);
2162
+ const [satCycleRegistryPage] = solana.PublicKey.findProgramAddressSync([
2163
+ Buffer.from(SAT_CYCLE_REGISTRY_PAGE_SEED),
2164
+ encodeU64(params.cycleId),
2165
+ encodeU64(pageIndex)
2166
+ ], programId);
2167
+ const [satCycleSettlementProgress] = solana.PublicKey.findProgramAddressSync([Buffer.from("sat_cycle_settlement_progress_v2"), encodeU64(params.cycleId)], programId);
2168
+ const [satMinerCycleState] = solana.PublicKey.findProgramAddressSync([
2169
+ Buffer.from(SAT_MINER_CYCLE_STATE_SEED),
2170
+ signer.toBuffer(),
2171
+ encodeU64(params.cycleId)
2172
+ ], programId);
2173
+ const [satMinerCapitalState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_MINER_CAPITAL_STATE_SEED), signer.toBuffer()], programId);
2174
+ const [satUnlockIntervalState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_UNLOCK_INTERVAL_STATE_SEED), encodeU64(intervalStartCycleId)], programId);
2175
+ const [satRegistryReserve] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_REGISTRY_RESERVE_SEED)], programId);
2176
+ return {
2177
+ keys: [
2178
+ {
2179
+ pubkey: signer,
2180
+ isSigner: true,
2181
+ isWritable: true
2182
+ },
2183
+ {
2184
+ pubkey: satCycleState,
2185
+ isSigner: false,
2186
+ isWritable: true
2187
+ },
2188
+ {
2189
+ pubkey: satCycleRegistryMeta,
2190
+ isSigner: false,
2191
+ isWritable: true
2192
+ },
2193
+ {
2194
+ pubkey: satCycleRegistryPage,
2195
+ isSigner: false,
2196
+ isWritable: true
2197
+ },
2198
+ {
2199
+ pubkey: satCycleSettlementProgress,
2200
+ isSigner: false,
2201
+ isWritable: true
2202
+ },
2203
+ {
2204
+ pubkey: satMinerCycleState,
2205
+ isSigner: false,
2206
+ isWritable: true
2207
+ },
2208
+ {
2209
+ pubkey: satMinerCapitalState,
2210
+ isSigner: false,
2211
+ isWritable: true
2212
+ },
2213
+ {
2214
+ pubkey: satUnlockIntervalState,
2215
+ isSigner: false,
2216
+ isWritable: true
2217
+ },
2218
+ {
2219
+ pubkey: satRegistryReserve,
2220
+ isSigner: false,
2221
+ isWritable: true
2222
+ },
2223
+ {
2224
+ pubkey: solana.SystemProgram.programId,
2225
+ isSigner: false,
2226
+ isWritable: false
2227
+ }
2228
+ ],
2229
+ context: {
2230
+ intervalStartCycleId: String(intervalStartCycleId),
2231
+ registryPageIndex: String(pageIndex)
2232
+ }
2233
+ };
2234
+ }
2235
+ });
2236
+ }
1636
2237
  async function submitSatSettleCyclePage(_config, params) {
1637
2238
  const cfg = loadConfigForSatRuntime(_config);
1638
2239
  return submitInstruction({
@@ -1728,7 +2329,22 @@ async function submitSatSettleCyclePage(_config, params) {
1728
2329
  isWritable: true
1729
2330
  });
1730
2331
  }
1731
- return accounts;
2332
+ const minerCycleAddresses = params.minerCycleAccounts ?? [];
2333
+ const minerCycles = minerCycleAddresses.length > 0 ? await inspectSatMinerCyclesByAddress(_config, { addresses: minerCycleAddresses }) : [];
2334
+ const minerAuthorities = minerCycles.map((entry, index) => {
2335
+ const authority = String(entry?.authority ?? "").trim();
2336
+ if (!authority) {
2337
+ throw new Error(`SAT settleCyclePage could not resolve miner authority for ${minerCycleAddresses[index]}`);
2338
+ }
2339
+ return authority;
2340
+ });
2341
+ if (minerAuthorities.length !== minerCycleAddresses.length) {
2342
+ throw new Error("SAT settleCyclePage miner authority count mismatch");
2343
+ }
2344
+ return {
2345
+ keys: accounts,
2346
+ ...minerAuthorities.length > 0 ? { context: { minerAuthorities } } : {}
2347
+ };
1732
2348
  }
1733
2349
  });
1734
2350
  }
@@ -1893,7 +2509,22 @@ async function submitSatScoreCyclePage(_config, params) {
1893
2509
  isWritable: true
1894
2510
  });
1895
2511
  }
1896
- return accounts;
2512
+ const minerCycleAddresses = params.minerCycleAccounts ?? [];
2513
+ const minerCycles = minerCycleAddresses.length > 0 ? await inspectSatMinerCyclesByAddress(_config, { addresses: minerCycleAddresses }) : [];
2514
+ const minerAuthorities = minerCycles.map((entry, index) => {
2515
+ const authority = String(entry?.authority ?? "").trim();
2516
+ if (!authority) {
2517
+ throw new Error(`SAT scoreCyclePage could not resolve miner authority for ${minerCycleAddresses[index]}`);
2518
+ }
2519
+ return authority;
2520
+ });
2521
+ if (minerAuthorities.length !== minerCycleAddresses.length) {
2522
+ throw new Error("SAT scoreCyclePage miner authority count mismatch");
2523
+ }
2524
+ return {
2525
+ keys: accounts,
2526
+ ...minerAuthorities.length > 0 ? { context: { minerAuthorities } } : {}
2527
+ };
1897
2528
  }
1898
2529
  });
1899
2530
  }
@@ -1921,6 +2552,7 @@ async function submitSatDistributeCyclePage(_config, params) {
1921
2552
  ], programId);
1922
2553
  const [satSignerMinerCapitalState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_MINER_CAPITAL_STATE_SEED), signer.toBuffer()], programId);
1923
2554
  const [satRebateVault] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_REBATE_VAULT_SEED)], programId);
2555
+ const [satTreasuryVault] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_TREASURY_VAULT_SEED)], programId);
1924
2556
  const accounts = [
1925
2557
  {
1926
2558
  pubkey: signer,
@@ -1945,7 +2577,7 @@ async function submitSatDistributeCyclePage(_config, params) {
1945
2577
  {
1946
2578
  pubkey: satGlobalState,
1947
2579
  isSigner: false,
1948
- isWritable: true
2580
+ isWritable: false
1949
2581
  },
1950
2582
  {
1951
2583
  pubkey: satTreasuryState,
@@ -1966,10 +2598,16 @@ async function submitSatDistributeCyclePage(_config, params) {
1966
2598
  pubkey: satRebateVault,
1967
2599
  isSigner: false,
1968
2600
  isWritable: true
2601
+ },
2602
+ {
2603
+ pubkey: satTreasuryVault,
2604
+ isSigner: false,
2605
+ isWritable: true
1969
2606
  }
1970
2607
  ];
1971
2608
  const minerCycleAccounts = params.minerCycleAccounts ?? [];
1972
2609
  const minerCycles = minerCycleAccounts.length > 0 ? await inspectSatMinerCyclesByAddress(_config, { addresses: minerCycleAccounts }).catch(() => []) : [];
2610
+ const minerAuthorities = [];
1973
2611
  for (const [index, minerCycleAccount] of minerCycleAccounts.entries()) {
1974
2612
  const satMinerCycleState = new solana.PublicKey(minerCycleAccount);
1975
2613
  const minerCycle = minerCycles[index] ?? null;
@@ -1977,6 +2615,7 @@ async function submitSatDistributeCyclePage(_config, params) {
1977
2615
  if (!authorityKey) {
1978
2616
  throw new Error(`SAT distributeCyclePage could not resolve miner authority for ${minerCycleAccount}`);
1979
2617
  }
2618
+ minerAuthorities.push(authorityKey.toBase58());
1980
2619
  const [satMinerCapitalState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_MINER_CAPITAL_STATE_SEED), authorityKey.toBuffer()], programId);
1981
2620
  accounts.push({
1982
2621
  pubkey: satMinerCycleState,
@@ -1989,7 +2628,10 @@ async function submitSatDistributeCyclePage(_config, params) {
1989
2628
  isWritable: true
1990
2629
  });
1991
2630
  }
1992
- return accounts;
2631
+ return {
2632
+ keys: accounts,
2633
+ ...minerAuthorities.length > 0 ? { context: { minerAuthorities } } : {}
2634
+ };
1993
2635
  }
1994
2636
  });
1995
2637
  }
@@ -2199,27 +2841,6 @@ async function submitSatClaimCycleRewardsBatch(_config, params) {
2199
2841
  }
2200
2842
  });
2201
2843
  }
2202
- async function submitSatSetProtocolRecipients(_config, params) {
2203
- const cfg = loadConfigForSatRuntime(_config);
2204
- return submitInstruction({
2205
- cfg,
2206
- env: process.env,
2207
- data: buildSetProtocolRecipientsData(params),
2208
- accountResolver: async (solana, signer) => {
2209
- const programId = new solana.PublicKey(SAT_PROGRAM_ID());
2210
- const [satGlobalState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_GLOBAL_STATE_SEED)], programId);
2211
- return [{
2212
- pubkey: signer,
2213
- isSigner: true,
2214
- isWritable: true
2215
- }, {
2216
- pubkey: satGlobalState,
2217
- isSigner: false,
2218
- isWritable: true
2219
- }];
2220
- }
2221
- });
2222
- }
2223
2844
  async function submitSatClaimProtocolTreasury(_config, params) {
2224
2845
  const cfg = loadConfigForSatRuntime(_config);
2225
2846
  return submitInstruction({
@@ -2355,18 +2976,20 @@ async function submitSatRefillRegistryReserveFromTreasury(_config, params) {
2355
2976
  }
2356
2977
  async function submitSatClaimProtocolDistributorSat(_config, params) {
2357
2978
  const cfg = loadConfigForSatRuntime(_config);
2979
+ const effectiveEnv = resolveSatEffectiveEnv(cfg, process.env);
2980
+ assertDedicatedBondProgram(effectiveEnv);
2358
2981
  return submitInstruction({
2359
2982
  cfg,
2360
- env: process.env,
2983
+ env: effectiveEnv,
2361
2984
  data: buildClaimProtocolDistributorSatData(),
2362
2985
  accountResolver: async (solana, signer) => {
2363
- const programId = new solana.PublicKey(SAT_PROGRAM_ID());
2986
+ const programId = new solana.PublicKey(resolveSatProgramIdFromEnv(effectiveEnv));
2364
2987
  const recipientOwner = new solana.PublicKey(params.recipientOwner);
2365
2988
  const [satGlobalState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_GLOBAL_STATE_SEED)], programId);
2366
2989
  const [treasury] = solana.PublicKey.findProgramAddressSync([Buffer.from("treasury")], programId);
2367
2990
  const [satTreasuryState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_TREASURY_STATE_SEED)], programId);
2368
- const [mintAuthority] = solana.PublicKey.findProgramAddressSync([Buffer.from("authority")], new solana.PublicKey(SAT_MINT_PROGRAM_ID()));
2369
- const recipientAta = deriveAssociatedTokenAddress(solana, recipientOwner, new solana.PublicKey(SAT_MINT_ADDRESS()));
2991
+ const [mintAuthority] = solana.PublicKey.findProgramAddressSync([Buffer.from("authority")], new solana.PublicKey(resolveSatMintProgramIdFromEnv(effectiveEnv)));
2992
+ const recipientAta = deriveAssociatedTokenAddress(solana, recipientOwner, new solana.PublicKey(resolveSatMintAddressFromEnv(effectiveEnv)));
2370
2993
  return [
2371
2994
  {
2372
2995
  pubkey: signer,
@@ -2399,7 +3022,7 @@ async function submitSatClaimProtocolDistributorSat(_config, params) {
2399
3022
  isWritable: true
2400
3023
  },
2401
3024
  {
2402
- pubkey: new solana.PublicKey(SAT_MINT_ADDRESS()),
3025
+ pubkey: new solana.PublicKey(resolveSatMintAddressFromEnv(effectiveEnv)),
2403
3026
  isSigner: false,
2404
3027
  isWritable: true
2405
3028
  },
@@ -2424,7 +3047,12 @@ async function submitSatClaimProtocolDistributorSat(_config, params) {
2424
3047
  isWritable: false
2425
3048
  },
2426
3049
  {
2427
- pubkey: new solana.PublicKey(SAT_MINT_PROGRAM_ID()),
3050
+ pubkey: new solana.PublicKey(resolveSatMintProgramIdFromEnv(effectiveEnv)),
3051
+ isSigner: false,
3052
+ isWritable: false
3053
+ },
3054
+ {
3055
+ pubkey: new solana.PublicKey(resolveSatBondProgramIdFromEnv(effectiveEnv)),
2428
3056
  isSigner: false,
2429
3057
  isWritable: false
2430
3058
  }
@@ -2442,6 +3070,8 @@ async function submitSatRetargetUnlock(_config, params) {
2442
3070
  const programId = new solana.PublicKey(SAT_PROGRAM_ID());
2443
3071
  const [satGlobalState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_GLOBAL_STATE_SEED)], programId);
2444
3072
  const [satCycleState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_CYCLE_STATE_SEED), encodeU64(params.cycleId)], programId);
3073
+ const intervalStartCycleId = Math.max(0, params.cycleId + 1 - SAT_PROTOCOL_CONSTANTS.cycleUnlockRetargetIntervalCycles);
3074
+ const [satUnlockIntervalState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_UNLOCK_INTERVAL_STATE_SEED), encodeU64(intervalStartCycleId)], programId);
2445
3075
  return [
2446
3076
  {
2447
3077
  pubkey: signer,
@@ -2457,6 +3087,11 @@ async function submitSatRetargetUnlock(_config, params) {
2457
3087
  pubkey: satCycleState,
2458
3088
  isSigner: false,
2459
3089
  isWritable: false
3090
+ },
3091
+ {
3092
+ pubkey: satUnlockIntervalState,
3093
+ isSigner: false,
3094
+ isWritable: true
2460
3095
  }
2461
3096
  ];
2462
3097
  }
@@ -2677,10 +3312,16 @@ async function submitSatCompactPendingCycleRange(_config, params) {
2677
3312
  isWritable: false
2678
3313
  });
2679
3314
  }
2680
- return accounts;
3315
+ return {
3316
+ keys: accounts,
3317
+ context: {
3318
+ frontCycleIds: params.frontCycleIds.map(String),
3319
+ backCycleIds: params.backCycleIds.map(String)
3320
+ }
3321
+ };
2681
3322
  }
2682
3323
  });
2683
3324
  }
2684
3325
 
2685
3326
  //#endregion
2686
- export { submitSatCancelBondUnlock, submitSatClaimBondStakingRewards, submitSatFinalizeBondUnlock, submitSatIncreaseBondPosition, submitSatInitBondStakingDistributor, submitSatOpenBondPosition, submitSatRequestBondUnlock, submitSatSyncBondStakingPosition, submitSatSyncBondStakingRewards };
3327
+ export { runWithSatSubmissionWorkflow, submitSatCancelBondUnlock, submitSatClaimBondStakingRewards, submitSatFinalizeBondUnlock, submitSatIncreaseBondPosition, submitSatOpenBondPosition, submitSatRequestBondUnlock, submitSatSyncBondStakingPosition, submitSatSyncBondStakingRewards };