@fased/fased 0.1.61 → 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 (514) hide show
  1. package/CHANGELOG.md +43 -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/acp/client.js +2 -2
  12. package/dist/acp/secret-file.js +2 -2
  13. package/dist/agents/agent-scope.js +2 -2
  14. package/dist/agents/apply-patch.js +8 -8
  15. package/dist/agents/auth-profiles/paths.js +2 -2
  16. package/dist/agents/auth-profiles/store.js +269 -33
  17. package/dist/agents/bash-tools.exec.js +10 -4
  18. package/dist/agents/bash-tools.shared.js +2 -2
  19. package/dist/agents/cli-credentials.js +4 -4
  20. package/dist/agents/current-model-catalog.js +3 -3
  21. package/dist/agents/docs-path.js +3 -3
  22. package/dist/agents/embedded-pi-mcp.js +4 -4
  23. package/dist/agents/identity-avatar.js +3 -3
  24. package/dist/agents/identity-file.js +2 -2
  25. package/dist/agents/memory-search.js +7 -1
  26. package/dist/agents/model-catalog-access.js +1 -2
  27. package/dist/agents/model-catalog-snapshot.js +1 -1
  28. package/dist/agents/model-catalog-source.js +1 -1
  29. package/dist/agents/model-metadata.js +1 -1
  30. package/dist/agents/model-selection.js +2 -28
  31. package/dist/agents/models-config.providers.js +6 -6
  32. package/dist/agents/openai-codex-app-server.js +5 -5
  33. package/dist/agents/pi-embedded-runner/compact.js +15 -7
  34. package/dist/agents/pi-embedded-runner/model.js +1 -1
  35. package/dist/agents/pi-embedded-runner/run/attempt.js +24 -13
  36. package/dist/agents/pi-embedded-runner/run.js +2 -0
  37. package/dist/agents/pi-embedded-runner/tool-split.js +40 -2
  38. package/dist/agents/pi-embedded-subscribe.raw-stream.js +3 -3
  39. package/dist/agents/pi-extensions/compaction-safeguard.js +3 -3
  40. package/dist/agents/pi-model-discovery.js +6 -6
  41. package/dist/agents/pi-project-settings.js +3 -3
  42. package/dist/agents/pi-tool-definition-adapter.js +16 -1
  43. package/dist/agents/pi-tools.js +2 -1
  44. package/dist/agents/sandbox/config.js +1 -1
  45. package/dist/agents/sandbox/context.js +27 -2
  46. package/dist/agents/sandbox/fs-bridge.js +2 -2
  47. package/dist/agents/session-dirs.js +4 -4
  48. package/dist/agents/session-write-lock.js +13 -13
  49. package/dist/agents/shell-utils.js +5 -5
  50. package/dist/agents/skills/bundled-dir.js +4 -4
  51. package/dist/agents/skills/env-overrides.js +38 -28
  52. package/dist/agents/skills/local-loader.js +6 -6
  53. package/dist/agents/skills/plugin-skills.js +2 -2
  54. package/dist/agents/skills/trust.js +93 -0
  55. package/dist/agents/skills/workspace.js +141 -13
  56. package/dist/agents/skills-clawhub.js +36 -11
  57. package/dist/agents/skills-install-download.js +7 -7
  58. package/dist/agents/skills-install-plan.js +2 -2
  59. package/dist/agents/skills-install.js +2 -2
  60. package/dist/agents/skills-marketplace-scan.js +49 -0
  61. package/dist/agents/skills-status.js +2 -2
  62. package/dist/agents/subagent-depth.js +2 -2
  63. package/dist/agents/system-prompt-params.js +2 -2
  64. package/dist/agents/tools/marketplace-offer-draft-tool.js +1 -1
  65. package/dist/agents/tools/mining-tool.js +1 -1
  66. package/dist/agents/tools/session-status-tool.js +1 -1
  67. package/dist/agents/tools/wallet-action-tool.js +172 -36
  68. package/dist/agents/tools/wallet-skill-policy.js +65 -23
  69. package/dist/agents/tools/wallet-tool.js +7 -11
  70. package/dist/agents/workspace.js +22 -22
  71. package/dist/auto-reply/reply/agent-runner-execution.js +2 -2
  72. package/dist/auto-reply/reply/agent-runner.js +2 -2
  73. package/dist/auto-reply/reply/commands-export-session.js +7 -7
  74. package/dist/auto-reply/reply/directive-handling.fast-lane.js +2 -1
  75. package/dist/auto-reply/reply/directive-handling.impl.js +2 -1
  76. package/dist/auto-reply/reply/directive-handling.model.js +2 -1
  77. package/dist/auto-reply/reply/directive-handling.persist.js +2 -2
  78. package/dist/auto-reply/reply/get-reply-directives-apply.js +2 -0
  79. package/dist/auto-reply/reply/get-reply-inline-actions.js +25 -1
  80. package/dist/auto-reply/reply/model-selection.js +7 -4
  81. package/dist/auto-reply/reply/post-compaction-audit.js +3 -3
  82. package/dist/auto-reply/reply/post-compaction-context.js +3 -3
  83. package/dist/auto-reply/reply/session-reset-model.js +4 -4
  84. package/dist/auto-reply/reply/session.js +3 -3
  85. package/dist/auto-reply/skill-commands.js +3 -3
  86. package/dist/auto-reply/status.js +6 -6
  87. package/dist/brand.js +1 -1
  88. package/dist/browser/chrome.executables.js +3 -3
  89. package/dist/browser/chrome.js +3 -3
  90. package/dist/browser/chrome.profile-decoration.js +6 -6
  91. package/dist/browser/profiles-service.js +2 -2
  92. package/dist/browser/server-context.js +2 -2
  93. package/dist/browser/trash.js +4 -4
  94. package/dist/build-info.json +3 -3
  95. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  96. package/dist/canvas-host/server.js +4 -4
  97. package/dist/capabilities/catalog.js +3 -3
  98. package/dist/channel-web.js +2 -2
  99. package/dist/channels/plugins/catalog.js +3 -3
  100. package/dist/cli/browser-cli-extension.js +6 -6
  101. package/dist/cli/command-format.js +2 -2
  102. package/dist/cli/cron-cli/register.cron-simple.js +2 -2
  103. package/dist/cli/dns-cli.js +9 -9
  104. package/dist/cli/gateway-cli/dev.js +5 -5
  105. package/dist/cli/gateway-cli/run.js +10 -2
  106. package/dist/cli/hooks-cli.js +5 -5
  107. package/dist/cli/lightweight/gateway-runtime-probe.js +2 -2
  108. package/dist/cli/memory-cli.js +7 -7
  109. package/dist/cli/nodes-media-utils.js +2 -2
  110. package/dist/cli/plugins-cli.js +2 -2
  111. package/dist/cli/program/command-registry.js +1 -1
  112. package/dist/cli/program/register.onboard.js +2 -3
  113. package/dist/cli/program/register.wallet.js +16 -123
  114. package/dist/cli/providers-cli.js +1 -1
  115. package/dist/cli/sat-cli.js +129 -2
  116. package/dist/cli/secrets-cli.js +3 -3
  117. package/dist/cli/update-cli/update-command.js +260 -11
  118. package/dist/cli/windows-argv.js +2 -2
  119. package/dist/commands/auth-choice.apply.api-providers.js +3 -3
  120. package/dist/commands/dashboard-link.js +3 -3
  121. package/dist/commands/doctor-config-flow.js +1 -1
  122. package/dist/commands/doctor-install.js +5 -5
  123. package/dist/commands/doctor-legacy-config.js +2 -13
  124. package/dist/commands/doctor-memory-search.js +2 -2
  125. package/dist/commands/doctor-platform-notes.js +2 -2
  126. package/dist/commands/doctor-sandbox.js +2 -2
  127. package/dist/commands/doctor-state-integrity.js +23 -23
  128. package/dist/commands/doctor-workspace.js +3 -3
  129. package/dist/commands/doctor.js +3 -3
  130. package/dist/commands/managed-up.js +2 -2
  131. package/dist/commands/model-picker.js +6 -6
  132. package/dist/commands/models/auth.js +1 -1
  133. package/dist/commands/onboard-auth.config-gateways.js +1 -1
  134. package/dist/commands/onboard-auth.credentials.js +35 -11
  135. package/dist/commands/onboard-non-interactive/local/wallet-config.js +28 -27
  136. package/dist/commands/onboard-non-interactive/local.js +5 -1
  137. package/dist/commands/onboarding/plugin-install.js +2 -2
  138. package/dist/commands/sessions-cleanup.js +2 -2
  139. package/dist/commands/signal-install.js +6 -6
  140. package/dist/commands/status-all/channels.js +2 -2
  141. package/dist/commands/wallet.js +570 -1913
  142. package/dist/config/cache-utils.js +2 -2
  143. package/dist/config/config.js +2 -2
  144. package/dist/config/includes.js +5 -5
  145. package/dist/config/io.js +66 -4
  146. package/dist/config/paths.js +3 -3
  147. package/dist/config/sat-runtime-ids.js +3 -3
  148. package/dist/config/schema.help.js +8 -7
  149. package/dist/config/schema.labels.js +5 -4
  150. package/dist/config/sessions/disk-budget.js +6 -6
  151. package/dist/config/sessions/paths.js +2 -2
  152. package/dist/config/sessions/store.js +17 -17
  153. package/dist/config/sessions/transcript.js +4 -4
  154. package/dist/config/talk.js +2 -2
  155. package/dist/config/zod-schema.agent-runtime.js +1 -0
  156. package/dist/config/zod-schema.js +5 -0
  157. package/dist/control-ui/assets/{app-BXA4gPvN.js → app-bR-fO5ty.js} +1511 -1555
  158. package/dist/control-ui/assets/{config-CU5Zi8Dh.js → config-LeImukCW.js} +10 -10
  159. package/dist/control-ui/assets/{federation-D10Q4eP_.js → federation-DgA9e-Pn.js} +364 -422
  160. package/dist/control-ui/assets/{index-D2QbJhVg.js → index-ckCxHwjy.js} +3 -3
  161. package/dist/control-ui/assets/{mining-BdhMn18r.js → mining-BgHFh0ei.js} +134 -114
  162. package/dist/control-ui/assets/mining-commit-DFpB_4JN.js +2 -0
  163. package/dist/control-ui/assets/{open-external-url-DwSiwMPl.js → open-external-url-ulF1B-sA.js} +3 -3
  164. package/dist/control-ui/assets/{providers-QMn4w2_f.js → providers-CIx9fxc6.js} +2 -2
  165. package/dist/control-ui/assets/{wallet-C2g294QT.js → wallet-DvStR_AT.js} +259 -377
  166. package/dist/control-ui/index.html +1 -1
  167. package/dist/control-ui/version.json +1 -1
  168. package/dist/cron/service/store.js +2 -2
  169. package/dist/cron/store.js +6 -6
  170. package/dist/daemon/systemd-system.js +60 -54
  171. package/dist/discord/monitor/thread-bindings.state.js +2 -2
  172. package/dist/extensions/sat-mining/src/protocol-contract.js +43 -3
  173. package/dist/extensions/sat-mining/src/rpc-read.js +235 -67
  174. package/dist/extensions/sat-mining/src/sat-bond-layout.js +14 -11
  175. package/dist/extensions/sat-mining/src/signer-codec-manifest.js +406 -0
  176. package/dist/extensions/sat-mining/src/solana-submit.js +1038 -397
  177. package/dist/extensions/sat-mining/src/submission-ledger.js +349 -0
  178. package/dist/federation/auto-connect.js +98 -8
  179. package/dist/federation/marketplace-capability-adapter.js +33 -7
  180. package/dist/federation/marketplace-delivery-outbox.js +196 -0
  181. package/dist/federation/marketplace-delivery.js +351 -215
  182. package/dist/federation/marketplace-direct-payment.js +272 -141
  183. package/dist/federation/marketplace-escrow.js +607 -249
  184. package/dist/federation/marketplace-settlement-ledger.js +352 -0
  185. package/dist/federation/offers.js +9 -7
  186. package/dist/federation/peer-auth-v2.js +529 -0
  187. package/dist/gateway/a2a-http.js +425 -96
  188. package/dist/gateway/a2a-settlement.js +259 -153
  189. package/dist/gateway/a2a-task-store.js +524 -0
  190. package/dist/gateway/auth.js +38 -2
  191. package/dist/gateway/config-reload.js +46 -33
  192. package/dist/gateway/control-ui-boot-check.js +6 -6
  193. package/dist/gateway/control-ui-login.js +7 -7
  194. package/dist/gateway/control-ui.js +9 -9
  195. package/dist/gateway/durable-capacity.js +31 -0
  196. package/dist/gateway/federation-http.js +540 -135
  197. package/dist/gateway/federation-marketplace-run-store.js +397 -0
  198. package/dist/gateway/federation-marketplace.js +535 -230
  199. package/dist/gateway/hooks-mapping.js +4 -4
  200. package/dist/gateway/mutating-admin-rpc-rate-limit.js +5 -0
  201. package/dist/gateway/security-path.js +1 -1
  202. package/dist/gateway/server-discovery.js +2 -2
  203. package/dist/gateway/server-http.js +1088 -1209
  204. package/dist/gateway/server-methods/chat.js +3 -3
  205. package/dist/gateway/server-methods/models.js +1 -1
  206. package/dist/gateway/server-methods/secrets.js +40 -0
  207. package/dist/gateway/server-methods/sessions.js +6 -6
  208. package/dist/gateway/server-methods/usage.js +2 -2
  209. package/dist/gateway/server-methods.js +1 -2
  210. package/dist/gateway/server-reload-handlers.js +196 -66
  211. package/dist/gateway/server-runtime-config.js +1 -1
  212. package/dist/gateway/server-secrets-runtime.js +288 -0
  213. package/dist/gateway/server.impl.js +73 -42
  214. package/dist/gateway/session-compaction-checkpoints.js +4 -4
  215. package/dist/gateway/session-utils.fs.js +24 -24
  216. package/dist/gateway/session-utils.js +6 -6
  217. package/dist/gateway/sessions-patch.js +3 -5
  218. package/dist/hooks/bundled-dir.js +4 -4
  219. package/dist/hooks/gmail-setup-utils.js +6 -6
  220. package/dist/hooks/import-url.js +2 -2
  221. package/dist/hooks/loader.js +4 -4
  222. package/dist/hooks/workspace.js +7 -7
  223. package/dist/index.js +4 -2
  224. package/dist/infra/archive.js +17 -17
  225. package/dist/infra/boundary-file-read.js +2 -2
  226. package/dist/infra/boundary-path.js +15 -15
  227. package/dist/infra/brew.js +2 -2
  228. package/dist/infra/control-ui-assets.js +14 -14
  229. package/dist/infra/device-auth-store.js +8 -8
  230. package/dist/infra/device-identity.js +8 -8
  231. package/dist/infra/dotenv.js +2 -2
  232. package/dist/infra/exec-approvals.js +8 -8
  233. package/dist/infra/exec-command-resolution.js +4 -4
  234. package/dist/infra/exec-safe-bin-trust.js +2 -2
  235. package/dist/infra/fased-root.js +5 -5
  236. package/dist/infra/fasedhub.js +64 -1
  237. package/dist/infra/fs-safe.js +14 -14
  238. package/dist/infra/gateway-lock.js +11 -11
  239. package/dist/infra/git-commit.js +5 -5
  240. package/dist/infra/git-root.js +4 -4
  241. package/dist/infra/hosted-runtime-artifact.js +3 -3
  242. package/dist/infra/is-main.js +2 -2
  243. package/dist/infra/json-file.js +7 -7
  244. package/dist/infra/local-source-paired-update.js +538 -0
  245. package/dist/infra/managed-runtime-bootstrap.js +6 -6
  246. package/dist/infra/outbound/delivery-queue.js +16 -16
  247. package/dist/infra/path-env.js +3 -3
  248. package/dist/infra/ports-lsof.js +4 -4
  249. package/dist/infra/provider-usage.auth.js +3 -3
  250. package/dist/infra/restart.js +41 -10
  251. package/dist/infra/safe-open-sync.js +2 -2
  252. package/dist/infra/session-cost-usage.js +9 -9
  253. package/dist/infra/shell-env.js +2 -2
  254. package/dist/infra/state-migrations.fs.js +6 -6
  255. package/dist/infra/state-migrations.js +23 -23
  256. package/dist/infra/tmp-fased-dir.js +6 -6
  257. package/dist/infra/update-runner.js +96 -0
  258. package/dist/infra/widearea-dns.js +3 -3
  259. package/dist/infra/wsl.js +2 -2
  260. package/dist/light-update-status.js +11 -11
  261. package/dist/line/accounts.js +2 -2
  262. package/dist/line/download.js +2 -2
  263. package/dist/logging/config.js +3 -3
  264. package/dist/logging/logger.js +7 -7
  265. package/dist/managed/federation.js +3 -3
  266. package/dist/managed/tunnel.js +3 -3
  267. package/dist/media/store.js +13 -13
  268. package/dist/media-understanding/runner.js +3 -3
  269. package/dist/memory/backend-config.js +2 -1
  270. package/dist/memory/embeddings.js +2 -2
  271. package/dist/memory/internal.js +10 -10
  272. package/dist/memory/manager-sync-ops.js +7 -7
  273. package/dist/memory/repair-executor.js +17 -17
  274. package/dist/memory/session-files.js +16 -2
  275. package/dist/node-host/invoke-system-run-plan.js +8 -8
  276. package/dist/node-host/invoke.js +2 -2
  277. package/dist/node-host/runner.js +3 -3
  278. package/dist/pairing/pairing-store.js +3 -3
  279. package/dist/plugin-sdk/{accounts-DxblobYM.js → accounts-Brn3-uWN.js} +1 -1
  280. package/dist/plugin-sdk/{actions-D4UNimWa.js → actions-DRu135h0.js} +2 -2
  281. package/dist/plugin-sdk/{active-listener-CFuy106s.js → active-listener-B_NMtgPL.js} +1 -1
  282. package/dist/plugin-sdk/{audio-preflight-Bv0hUOWL.js → audio-preflight-BYxAt775.js} +27 -27
  283. package/dist/plugin-sdk/{audit-Cs0K7LBp.js → audit-C5d2z5U1.js} +1 -1
  284. package/dist/plugin-sdk/{channel-access-D5aHoTY8.js → channel-access-CcFRdRPO.js} +1 -1
  285. package/dist/plugin-sdk/{channel-access-configure-Dvch9mMQ.js → channel-access-configure-DaI5wevh.js} +1 -1
  286. package/dist/plugin-sdk/channel-plugin-common.d.ts +3 -3
  287. package/dist/plugin-sdk/channel-plugin-common.js +4 -4
  288. package/dist/plugin-sdk/{chunk-B0FUGc5A.js → chunk-CyoyqpbG.js} +1 -1
  289. package/dist/plugin-sdk/{chunk-items-Bk--NU3E.js → chunk-items-DIRHG2gJ.js} +1 -1
  290. package/dist/plugin-sdk/command-status.d.ts +2 -2
  291. package/dist/plugin-sdk/command-status.js +27 -27
  292. package/dist/plugin-sdk/{commands-registry-DmDRhRAU.js → commands-registry-BfqdEWdF.js} +2 -2
  293. package/dist/plugin-sdk/{common-CfUOowOp.js → common-HCcXU-NR.js} +1 -1
  294. package/dist/plugin-sdk/{config-mxULv0fQ.js → config-DlWVeLFB.js} +7113 -6877
  295. package/dist/plugin-sdk/{config-schema-CGW6J3Pv.js → config-schema-BOT7kHb6.js} +6779 -3696
  296. package/dist/plugin-sdk/device-pair.d.ts +1 -1
  297. package/dist/plugin-sdk/discord.d.ts +5 -5
  298. package/dist/plugin-sdk/discord.js +19 -19
  299. package/dist/plugin-sdk/file-lock.js +35 -4
  300. package/dist/plugin-sdk/{filesystem-manager-ZoHU8oA7.js → filesystem-manager-DoI8IBNF.js} +1 -1
  301. package/dist/plugin-sdk/{group-mentions-BHRff6j8.d.ts → group-mentions-q3hUTCt7.d.ts} +1 -1
  302. package/dist/plugin-sdk/{handle-action-DbVCF9HZ.js → handle-action-hvwapMKg.js} +13 -13
  303. package/dist/plugin-sdk/{helpers-BXbdgs5H.js → helpers-DMBU4oTo.js} +1 -1
  304. package/dist/plugin-sdk/{image-ops-D7jPxaph.js → image-ops-DQi0n_Tt.js} +1 -1
  305. package/dist/plugin-sdk/index.d.ts +9 -27
  306. package/dist/plugin-sdk/index.js +29 -29
  307. package/dist/plugin-sdk/json-store.js +6 -6
  308. package/dist/plugin-sdk/{login-BRxww6nv.js → login-Ca583Okc.js} +3 -3
  309. package/dist/plugin-sdk/{login-qr-DJXsk9XH.js → login-qr-CGciBSNP.js} +3 -3
  310. package/dist/plugin-sdk/{manager-Y2S_5IlI.js → manager-BegWxNYX.js} +4 -4
  311. package/dist/plugin-sdk/{markdown-tables-DHLFQqaF.js → markdown-tables-DCOXEUfZ.js} +1 -1
  312. package/dist/plugin-sdk/{media-Czo4carg.js → media-CAdQF5TG.js} +47 -47
  313. package/dist/plugin-sdk/{memory-search-DTjIMw8J.js → memory-search-CrFPOeTH.js} +4 -1
  314. package/dist/plugin-sdk/{monitor-B9Cmt_Je.js → monitor-BCFDaqJ-.js} +31 -31
  315. package/dist/plugin-sdk/{monitor-B71iwAgC.js → monitor-BgbjRiPM.js} +32 -32
  316. package/dist/plugin-sdk/{openresponses-http-Du4GMmwo.js → openresponses-http-DFf87SMM.js} +27 -27
  317. package/dist/plugin-sdk/{optional-runtime-dependency-DdMbxS24.js → optional-runtime-dependency-0dznm3ZO.js} +1 -1
  318. package/dist/plugin-sdk/{outbound-Db8mRN6P.js → outbound-BgVDdHxx.js} +6 -6
  319. package/dist/plugin-sdk/{outbound-attachment-BqFjcypb.js → outbound-attachment-QqTnIhZL.js} +2 -2
  320. package/dist/plugin-sdk/{pairing-message-BMkkS038.d.ts → pairing-message-CS-9BHug.d.ts} +2 -2
  321. package/dist/plugin-sdk/{pairing-message-B3GC_7CD.js → pairing-message-D0CoLHRJ.js} +1 -1
  322. package/dist/plugin-sdk/{pairing-store-CQikgIbw.js → pairing-store-BChahgI2.js} +2 -2
  323. package/dist/plugin-sdk/{pi-model-discovery-CY3m5zJP.js → pi-model-discovery-BX_JLcEJ.js} +1 -1
  324. package/dist/plugin-sdk/{pi-model-discovery-runtime-DSh1T2pn.js → pi-model-discovery-runtime-DxTMz_XF.js} +2 -2
  325. package/dist/plugin-sdk/provider-web-search-config-contract.d.ts +2 -2
  326. package/dist/plugin-sdk/{pw-ai-AFUqn-tQ.js → pw-ai-natjh3rm.js} +3 -3
  327. package/dist/plugin-sdk/{qmd-manager-DSyx77KY.js → qmd-manager-CgRaTxUq.js} +1 -1
  328. package/dist/plugin-sdk/{query-expansion-CAI2kKLQ.js → query-expansion-BG3FgzF7.js} +14 -3
  329. package/dist/plugin-sdk/{replies-Fzh9PhXl.js → replies-ChYo5ZQM.js} +2 -2
  330. package/dist/plugin-sdk/{resolve-outbound-target-KpF3co6T.js → resolve-outbound-target-D-KGgHJZ.js} +1 -1
  331. package/dist/plugin-sdk/{resolve-route-CDl74O19.js → resolve-route-C8tvQm8Z.js} +1 -1
  332. package/dist/plugin-sdk/{retry-policy-D4uiqUOG.js → retry-policy-C6SjKjQA.js} +1 -1
  333. package/dist/plugin-sdk/{runtime-Bb6KRnCC.js → runtime-2B9_WKoI.js} +8 -3
  334. package/dist/plugin-sdk/{runtime-dependency-DLDmB94f.js → runtime-dependency-DczkvPxn.js} +2 -2
  335. package/dist/plugin-sdk/sat-runtime.d.ts +549 -309
  336. package/dist/plugin-sdk/sat-runtime.js +29 -29
  337. package/dist/plugin-sdk/{send-C4k4JuJN.js → send-B6KkGKZD.js} +6 -6
  338. package/dist/plugin-sdk/{send-D-uDKGIq.js → send-CFzGKJXo.js} +6 -6
  339. package/dist/plugin-sdk/{send-Du8ykP1k.js → send-DCO441U7.js} +8 -8
  340. package/dist/plugin-sdk/{send-5nFktR1n.js → send-gDoGA-7e.js} +5 -5
  341. package/dist/plugin-sdk/{send-Bfzf11VY.js → send-q9HXrSwK.js} +7 -7
  342. package/dist/plugin-sdk/{session-CS-Td9EM.js → session-DHD4ZKyG.js} +2 -2
  343. package/dist/plugin-sdk/{skill-commands-CFAlXWHk.js → skill-commands-FKEPLS7T.js} +201 -26
  344. package/dist/plugin-sdk/{slack-D_bbE6Yd.js → slack-BUTt8cxK.js} +39 -39
  345. package/dist/plugin-sdk/{slack-actions-BcMkNv1Z.js → slack-actions-DhbMcp8M.js} +11 -11
  346. package/dist/plugin-sdk/slack.d.ts +5 -5
  347. package/dist/plugin-sdk/slack.js +9 -9
  348. package/dist/plugin-sdk/{sticker-cache-Dqo9nRhi.js → sticker-cache-D0wHVqjt.js} +3 -3
  349. package/dist/plugin-sdk/{tables-bFXyRpkx.js → tables-B3jr0Pvq.js} +1 -1
  350. package/dist/plugin-sdk/{targets-DH7a9lKB.js → targets-CtSbTxYX.js} +1 -1
  351. package/dist/plugin-sdk/{telegram-actions-Cnag7JTH.js → telegram-actions-CC_qN4v0.js} +30 -30
  352. package/dist/plugin-sdk/telegram.d.ts +5 -5
  353. package/dist/plugin-sdk/telegram.js +8 -8
  354. package/dist/plugin-sdk/{thread-bindings.lifecycle-CgOvvdw8.js → thread-bindings.lifecycle-QbkNl-m6.js} +3 -3
  355. package/dist/plugin-sdk/{thread-bindings.state-CQpk44Hq.js → thread-bindings.state-D9hg_M1c.js} +2 -2
  356. package/dist/plugin-sdk/tmp-fased-dir-xOTGlzBE.d.ts +486 -0
  357. package/dist/plugin-sdk/{types-CLIvQaVg.d.ts → types-C3avNytw.d.ts} +3 -4
  358. package/dist/plugin-sdk/{types-DyhXnYUr.d.ts → types-D0kDG8l0.d.ts} +3 -2
  359. package/dist/plugin-sdk/{types-BYDL6dQj.d.ts → types-DWfbSAaM.d.ts} +2 -2
  360. package/dist/plugin-sdk/{types.plugin-_fbu40Re.d.ts → types.plugin-BcSBq42x.d.ts} +8 -3
  361. package/dist/plugin-sdk/{web-BInKQkc4.js → web-BXsJ1vqe.js} +32 -32
  362. package/dist/plugin-sdk/{whatsapp-actions-BtSc2CBv.js → whatsapp-actions-Bj_rOncr.js} +13 -13
  363. package/dist/plugin-sdk/{whatsapp-heartbeat-Bg9TuYzl.js → whatsapp-heartbeat-B1WHkJIg.js} +2 -2
  364. package/dist/plugin-sdk/whatsapp.d.ts +5 -5
  365. package/dist/plugin-sdk/whatsapp.js +12 -12
  366. package/dist/plugin-sdk/{wsl-C4DGFkOd.js → wsl-J-HscWxS.js} +3 -3
  367. package/dist/plugins/bundled-dir.js +3 -3
  368. package/dist/plugins/discovery.js +11 -11
  369. package/dist/plugins/loader.js +13 -13
  370. package/dist/plugins/manifest-registry.js +2 -2
  371. package/dist/plugins/manifest.js +4 -4
  372. package/dist/plugins/path-safety.js +3 -3
  373. package/dist/plugins/status-cache.js +9 -9
  374. package/dist/plugins/update.js +3 -3
  375. package/dist/plugins/web-search-install-catalog.js +3 -3
  376. package/dist/providers/refresh.js +1 -1
  377. package/dist/providers/registry.js +1 -1
  378. package/dist/secrets/apply.js +17 -17
  379. package/dist/secrets/audit.js +11 -11
  380. package/dist/secrets/runtime.js +1 -1
  381. package/dist/secrets/shared.js +9 -9
  382. package/dist/security/scan-paths.js +2 -2
  383. package/dist/shared/config-eval.js +2 -2
  384. package/dist/shared/pid-alive.js +2 -2
  385. package/dist/tasks/standing-orders.js +5 -5
  386. package/dist/tasks/task-flow-registry.js +5 -5
  387. package/dist/tasks/task-registry.js +5 -5
  388. package/dist/tasks/workflow-definitions.js +6 -6
  389. package/dist/telegram/token.js +5 -5
  390. package/dist/utils.js +5 -5
  391. package/dist/wallet/external-submission-ledger.js +376 -0
  392. package/dist/wallet/legacy-embedded-keystore.js +40 -0
  393. package/dist/wallet/local-socket-signer-archive.js +30 -0
  394. package/dist/wallet/local-socket-signer-lifecycle.js +97 -0
  395. package/dist/wallet/local-socket-signer-policy.js +166 -0
  396. package/dist/wallet/local-socket-signer-protocol.js +561 -118
  397. package/dist/wallet/native-signer-wallet-id.js +25 -0
  398. package/dist/wallet/providers/alchemy-adapter.js +3 -0
  399. package/dist/wallet/providers/local-socket-signer-adapter.js +382 -107
  400. package/dist/wallet/providers/turnkey-adapter.js +292 -34
  401. package/dist/wallet/providers/wallet-standard-adapter.js +100 -0
  402. package/dist/wallet/signer-network-admin.js +184 -0
  403. package/dist/wallet/signer-protocol-v2.generated.js +90 -0
  404. package/dist/wallet/solana-bond-signing.js +157 -69
  405. package/dist/wallet/solana-reviewed-transaction.js +375 -0
  406. package/dist/wallet/solana-swap.js +520 -64
  407. package/dist/wallet/solana-transaction-inspection.js +106 -4
  408. package/dist/wallet/solana-trigger.js +658 -320
  409. package/dist/wallet/turnkey-reviewed-state.js +370 -0
  410. package/dist/wallet/wallet-approval-auth.js +20 -31
  411. package/dist/wallet/wallet-atomic-state.js +53 -0
  412. package/dist/wallet/wallet-audit-log.js +5 -5
  413. package/dist/wallet/wallet-canary.js +0 -1
  414. package/dist/wallet/wallet-inbound-events.js +19 -14
  415. package/dist/wallet/wallet-observability.js +5 -5
  416. package/dist/wallet/wallet-policy-simulation.js +1 -1
  417. package/dist/wallet/wallet-policy.js +95 -41
  418. package/dist/wallet/wallet-provider-capabilities.js +28 -4
  419. package/dist/wallet/wallet-provider-registry.js +64 -51
  420. package/dist/wallet/wallet-provider-resolver.js +62 -63
  421. package/dist/wallet/wallet-runtime-config.js +31 -44
  422. package/dist/wallet/wallet-secrets-store.js +44 -22
  423. package/dist/wallet/wallet-send-approvals.js +1894 -592
  424. package/dist/wallet/wallet-send-execution-ledger.js +292 -0
  425. package/dist/wallet/wallet-settlement-links.js +17 -16
  426. package/dist/wallet/wallet-standard-review.js +353 -0
  427. package/dist/wallet/wallet-status.js +0 -9
  428. package/dist/wallet/wallet-task-ledger.js +16 -2
  429. package/dist/web/accounts.js +3 -3
  430. package/dist/web/auth-store.js +18 -18
  431. package/dist/web/auto-reply/heartbeat-runner.js +1 -1
  432. package/dist/web/auto-reply/monitor.js +2 -2
  433. package/dist/web/session.js +4 -4
  434. package/dist/wizard/host-security-capability.js +15 -24
  435. package/dist/wizard/onboarding.finalize.js +63 -184
  436. package/dist/wizard/onboarding.host-security.js +118 -1368
  437. package/dist/wizard/onboarding.js +180 -242
  438. package/dist/wizard/onboarding.wallet.js +323 -829
  439. package/extensions/acpx/package.json +1 -1
  440. package/extensions/bluebubbles/package.json +1 -1
  441. package/extensions/copilot-proxy/package.json +1 -1
  442. package/extensions/diagnostics-otel/package.json +1 -1
  443. package/extensions/fased-federation/package.json +1 -1
  444. package/extensions/google-gemini-cli-auth/package.json +1 -1
  445. package/extensions/imessage/package.json +1 -1
  446. package/extensions/irc/package.json +1 -1
  447. package/extensions/line/package.json +1 -1
  448. package/extensions/llm-task/package.json +1 -1
  449. package/extensions/lobster/package.json +1 -1
  450. package/extensions/matrix/CHANGELOG.md +18 -0
  451. package/extensions/matrix/package.json +1 -1
  452. package/extensions/mattermost/package.json +1 -1
  453. package/extensions/memory-core/package.json +2 -2
  454. package/extensions/memory-lancedb/package.json +1 -1
  455. package/extensions/minimax-portal-auth/package.json +1 -1
  456. package/extensions/msteams/CHANGELOG.md +18 -0
  457. package/extensions/msteams/package.json +1 -1
  458. package/extensions/nextcloud-talk/package.json +1 -1
  459. package/extensions/nostr/CHANGELOG.md +18 -0
  460. package/extensions/nostr/package.json +1 -1
  461. package/extensions/open-prose/package.json +1 -1
  462. package/extensions/sat-mining/index.ts +498 -153
  463. package/extensions/sat-mining/package.json +1 -1
  464. package/extensions/sat-mining/signer-codec-schema.v1.json +374 -0
  465. package/extensions/sat-mining/src/audit-store.ts +50 -5
  466. package/extensions/sat-mining/src/claim-service.ts +85 -14
  467. package/extensions/sat-mining/src/config.ts +9 -0
  468. package/extensions/sat-mining/src/cycle-progress.ts +16 -8
  469. package/extensions/sat-mining/src/epoch-service.ts +9 -5
  470. package/extensions/sat-mining/src/gateway-runner.ts +21 -1
  471. package/extensions/sat-mining/src/protocol-contract.ts +45 -1
  472. package/extensions/sat-mining/src/recovery-service.ts +312 -0
  473. package/extensions/sat-mining/src/round-watcher.ts +391 -81
  474. package/extensions/sat-mining/src/rpc-read.ts +330 -89
  475. package/extensions/sat-mining/src/runtime.ts +14 -0
  476. package/extensions/sat-mining/src/sat-bond-layout.ts +6 -0
  477. package/extensions/sat-mining/src/signer-codec-manifest.ts +429 -0
  478. package/extensions/sat-mining/src/solana-submit.ts +1199 -428
  479. package/extensions/sat-mining/src/submission-ledger.ts +433 -0
  480. package/extensions/signal/package.json +1 -1
  481. package/extensions/synology-chat/package.json +1 -1
  482. package/extensions/tlon/package.json +1 -1
  483. package/extensions/twitch/CHANGELOG.md +18 -0
  484. package/extensions/twitch/package.json +1 -1
  485. package/extensions/voice-call/CHANGELOG.md +18 -0
  486. package/extensions/voice-call/package.json +1 -1
  487. package/extensions/zalo/CHANGELOG.md +18 -0
  488. package/extensions/zalo/package.json +1 -1
  489. package/extensions/zalouser/CHANGELOG.md +18 -0
  490. package/extensions/zalouser/package.json +1 -1
  491. package/install.sh +4955 -0
  492. package/package.json +24 -5
  493. package/scripts/fased-host-updater.mjs +1421 -0
  494. package/scripts/fased-host-updaterctl.mjs +186 -0
  495. package/scripts/fased-managed-service.sh +36 -0
  496. package/scripts/fased-managed-updater.mjs +3065 -156
  497. package/scripts/fased-signer-enroll-hosting.sh +275 -0
  498. package/scripts/fased-signer-network-hosting.sh +143 -0
  499. package/scripts/fased-signer-owner-policy.mjs +1430 -0
  500. package/scripts/fased-signer-policy-hosting.sh +50 -0
  501. package/scripts/fased-signer-policy-local.sh +26 -0
  502. package/scripts/hosted-release-manifest.mjs +185 -0
  503. package/scripts/install-fased-signerd.sh +217 -0
  504. package/scripts/install-managed-runtime.mjs +212 -10
  505. package/scripts/managed-runtime-layout.mjs +75 -3
  506. package/scripts/migrate-hosted-signer-v2.mjs +58 -0
  507. package/scripts/start-managed.sh +169 -360
  508. package/dist/control-ui/assets/mining-commit-R-6nu87p.js +0 -2
  509. package/dist/plugin-sdk/tmp-fased-dir-BdFQvrvw.d.ts +0 -77
  510. package/dist/wallet/local-socket-signer-broker.js +0 -224
  511. package/dist/wallet/local-socket-signer-custody.js +0 -42
  512. package/dist/wallet/providers/embedded-keystore-adapter.js +0 -402
  513. package/dist/wallet/providers/privy-adapter.js +0 -80
  514. package/dist/wallet/wallet-custody.js +0 -1836
@@ -2,7 +2,7 @@ import { createHash } from "node:crypto";
2
2
  import http from "node:http";
3
3
  import https from "node:https";
4
4
  import { createRequire } from "node:module";
5
- import { redactSensitiveUrlLikeString } from "fased/plugin-sdk";
5
+ import { fetchWithSsrFGuard, redactSensitiveUrlLikeString } from "fased/plugin-sdk";
6
6
  import {
7
7
  loadConfig,
8
8
  loadWalletProviderSecret,
@@ -14,6 +14,7 @@ import {
14
14
  type FasedAgentConfig,
15
15
  } from "fased/plugin-sdk/sat-runtime";
16
16
  import type { SatMiningConfig } from "./config.js";
17
+ import { resolveSatGenesisProfileContract, SAT_PROTOCOL_CONSTANTS } from "./protocol-contract.js";
17
18
  import {
18
19
  loadSatBondLayout,
19
20
  loadSatBondPolicyLayout,
@@ -225,6 +226,21 @@ export type SatCycleView = {
225
226
  openTs: number;
226
227
  closeTs: number;
227
228
  status: number;
229
+ cycleSeed?: string;
230
+ entropyUnavailable?: boolean;
231
+ commitDeadlineTs?: number;
232
+ revealDeadlineTs?: number;
233
+ entropyTargetSlot?: number;
234
+ openSlot?: number;
235
+ commitDeadlineSlot?: number;
236
+ revealDeadlineSlot?: number;
237
+ entropyHashCount?: number;
238
+ unlockIntervalStartCycleId?: number;
239
+ committedMinerCount?: string;
240
+ revealedMinerCount?: string;
241
+ resolvedCommitCount?: string;
242
+ releasedCommitCount?: string;
243
+ entropySealedSlot?: number;
228
244
  unlockTargetLamports: string;
229
245
  totalCommittedLamports: string;
230
246
  validMinerCount: string;
@@ -258,6 +274,10 @@ export type SatMinerCycleView = {
258
274
  claimedPerfRebateLamports: string;
259
275
  validParticipation: boolean;
260
276
  capitalLockReleased?: boolean;
277
+ commitment?: string;
278
+ commitSlot?: number;
279
+ revealSlot?: number;
280
+ lockedCollateralLamports?: string;
261
281
  };
262
282
 
263
283
  export type SatMinerCapitalView = {
@@ -320,6 +340,8 @@ export type SatBondStakingDistributorView = {
320
340
  totalActiveStakeRaw: string;
321
341
  rewardIndexFp: string;
322
342
  observedRewardVaultRaw: string;
343
+ unallocatedRewardRaw: string;
344
+ fractionalRemainderFp: string;
323
345
  rewardVaultBalanceRaw?: string;
324
346
  lastSyncedSlot: number;
325
347
  mintMatchesRuntime: boolean;
@@ -338,6 +360,7 @@ export type SatBondStakingPositionView = {
338
360
  activeStakeRaw: string;
339
361
  claimableRewardRaw: string;
340
362
  rewardDebtFp: string;
363
+ fractionalRemainderFp: string;
341
364
  lastSyncedSlot: number;
342
365
  };
343
366
 
@@ -800,17 +823,21 @@ export function decodeSatGlobalState(data: Buffer, address: string): SatGlobalSt
800
823
  };
801
824
  }
802
825
 
803
- function decodeSatCycle(data: Buffer, address: string): SatCycleView {
826
+ export function decodeSatCycle(data: Buffer, address: string): SatCycleView {
804
827
  const body = expectAccountData(data, ACCOUNT_DISCRIMINATOR.satCycleState, "SAT cycle state");
828
+ const validMinerCount = readU64String(body, 192);
829
+ const cycleSeed = readHash32(body, 40);
805
830
  return {
806
831
  address,
807
832
  cycleId: readU64Number(body, 0),
808
833
  openTs: readI64Number(body, 8),
809
834
  closeTs: readI64Number(body, 16),
810
835
  status: body.readUInt8(24),
836
+ cycleSeed,
837
+ entropyUnavailable: cycleSeed === SAT_PROTOCOL_CONSTANTS.entropyUnavailableSeedHex,
811
838
  unlockTargetLamports: readU64String(body, 176),
812
839
  totalCommittedLamports: readU64String(body, 184),
813
- validMinerCount: readU64String(body, 192),
840
+ validMinerCount,
814
841
  unlockRatioFp: readU64String(body, 200),
815
842
  issuedCycleMinerSatRaw: readU64String(body, 208),
816
843
  unissuedCycleMinerSatRaw: readU64String(body, 216),
@@ -820,6 +847,23 @@ function decodeSatCycle(data: Buffer, address: string): SatCycleView {
820
847
  treasurySolLamports: readU64String(body, 248),
821
848
  submittedSolErosionPoolLamports: readU64String(body, 256),
822
849
  keeperBountyPaidLamports: readU64String(body, 264),
850
+ commitDeadlineTs: readI64Number(body, 272),
851
+ revealDeadlineTs: readI64Number(body, 280),
852
+ entropyTargetSlot: readU64Number(body, 288),
853
+ committedMinerCount: readU64String(body, 296),
854
+ revealedMinerCount: validMinerCount,
855
+ resolvedCommitCount: readU64String(body, 304),
856
+ entropySealedSlot: readU64Number(body, 312),
857
+ ...(body.length >= 368
858
+ ? {
859
+ openSlot: readU64Number(body, 320),
860
+ commitDeadlineSlot: readU64Number(body, 328),
861
+ revealDeadlineSlot: readU64Number(body, 336),
862
+ entropyHashCount: readU64Number(body, 344),
863
+ unlockIntervalStartCycleId: readU64Number(body, 352),
864
+ releasedCommitCount: readU64String(body, 360),
865
+ }
866
+ : {}),
823
867
  };
824
868
  }
825
869
 
@@ -848,6 +892,18 @@ export function decodeSatMinerCycle(data: Buffer, address: string): SatMinerCycl
848
892
  claimedPerfRebateLamports: readU64String(body, 168),
849
893
  validParticipation: body.readUInt8(176) === 1,
850
894
  capitalLockReleased: body.readUInt8(177) === 1,
895
+ ...(body.length >= 336
896
+ ? {
897
+ commitment: readHash32(body, 184),
898
+ commitSlot: readU64Number(body, 216),
899
+ revealSlot: readU64Number(body, 224),
900
+ }
901
+ : {}),
902
+ ...(body.length >= 344
903
+ ? {
904
+ lockedCollateralLamports: readU64String(body, 232),
905
+ }
906
+ : {}),
851
907
  };
852
908
  }
853
909
 
@@ -969,7 +1025,7 @@ function decodeSatBondTierPolicy(data: Buffer, address: string): SatBondTierPoli
969
1025
  };
970
1026
  }
971
1027
 
972
- function decodeSatBondStakingDistributor(
1028
+ export function decodeSatBondStakingDistributor(
973
1029
  data: Buffer,
974
1030
  address: string,
975
1031
  ): SatBondStakingDistributorView {
@@ -999,6 +1055,8 @@ function decodeSatBondStakingDistributor(
999
1055
  totalActiveStakeRaw: readU64String(body, layout.offsets.totalActiveStakeRaw),
1000
1056
  rewardIndexFp: readU128String(body, layout.offsets.rewardIndexFp),
1001
1057
  observedRewardVaultRaw: readU64String(body, layout.offsets.observedRewardVaultRaw),
1058
+ unallocatedRewardRaw: readU64String(body, layout.offsets.unallocatedRewardRaw),
1059
+ fractionalRemainderFp: readU64String(body, layout.offsets.fractionalRemainderFp),
1002
1060
  lastSyncedSlot: readU64Number(body, layout.offsets.lastSyncedSlot),
1003
1061
  mintMatchesRuntime: rewardMint === SAT_MINT_ADDRESS(),
1004
1062
  vaultMatchesExpected: rewardVault === expectedRewardVault,
@@ -1021,6 +1079,7 @@ function decodeSatBondStakingPosition(data: Buffer, address: string): SatBondSta
1021
1079
  activeStakeRaw: readU64String(body, layout.offsets.activeStakeRaw),
1022
1080
  claimableRewardRaw: readU64String(body, layout.offsets.claimableRewardRaw),
1023
1081
  rewardDebtFp: readU128String(body, layout.offsets.rewardDebtFp),
1082
+ fractionalRemainderFp: readU64String(body, layout.offsets.fractionalRemainderFp),
1024
1083
  lastSyncedSlot: readU64Number(body, layout.offsets.lastSyncedSlot),
1025
1084
  };
1026
1085
  }
@@ -1336,6 +1395,15 @@ type SatReadRpcRuntimeState = {
1336
1395
  quotaLikely: boolean;
1337
1396
  };
1338
1397
 
1398
+ type SatReadRpcEndpointState = {
1399
+ consecutiveFailures: number;
1400
+ backoffUntilMs: number;
1401
+ quotaLikely: boolean;
1402
+ lastError: string | null;
1403
+ lastFailureAt: string | null;
1404
+ lastSuccessAt: string | null;
1405
+ };
1406
+
1339
1407
  type SatRpcMethodBucket = {
1340
1408
  requests: number;
1341
1409
  successes: number;
@@ -1372,6 +1440,7 @@ const satReadRpcRuntimeState: SatReadRpcRuntimeState = {
1372
1440
  lastRpcUrl: null,
1373
1441
  quotaLikely: false,
1374
1442
  };
1443
+ const satReadRpcEndpointStates = new Map<string, SatReadRpcEndpointState>();
1375
1444
 
1376
1445
  type SatReadConnectionLike = {
1377
1446
  rpcEndpoint: string;
@@ -1416,6 +1485,14 @@ const SAT_RPC_RENT_EXEMPTION_CACHE_TTL_MS = 5 * 60_000;
1416
1485
  const SAT_RPC_METHOD_METRIC_BUCKET_MS = 60 * 60_000;
1417
1486
  const SAT_RPC_METHOD_METRIC_RETENTION_MS = 24 * 60 * 60_000;
1418
1487
  const SAT_RPC_QUOTA_BACKOFF_MS = 30_000;
1488
+ const SAT_RPC_FAILURE_BACKOFF_THRESHOLD = 2;
1489
+ const SAT_RPC_FAILURE_BACKOFF_BASE_MS = 5_000;
1490
+ const SAT_RPC_FAILURE_BACKOFF_MAX_MS = 30_000;
1491
+ const SAT_RPC_MAX_RESPONSE_BYTES = 16 * 1024 * 1024;
1492
+
1493
+ function satRpcRequestTimeoutMs(): number {
1494
+ return readPositiveIntEnv("FASED_SAT_RPC_REQUEST_TIMEOUT_MS", 10_000);
1495
+ }
1419
1496
 
1420
1497
  const satRpcReadCache = new Map<string, { expiresAt: number; value: unknown }>();
1421
1498
  const satRpcReadInFlight = new Map<string, Promise<unknown>>();
@@ -1604,41 +1681,86 @@ function looksLikeRpcQuotaFailure(value: unknown): boolean {
1604
1681
  );
1605
1682
  }
1606
1683
 
1607
- function currentReadRpcQuotaBackoffMs(nowMs = Date.now()): number {
1608
- if (!satReadRpcRuntimeState.quotaLikely || !satReadRpcRuntimeState.lastFailureAt) {
1609
- return 0;
1684
+ function getOrCreateReadRpcEndpointState(rpcUrl: string): SatReadRpcEndpointState {
1685
+ const key = normalizeRpcUrlForComparison(rpcUrl);
1686
+ const existing = satReadRpcEndpointStates.get(key);
1687
+ if (existing) {
1688
+ return existing;
1610
1689
  }
1611
- const failedAtMs = Date.parse(satReadRpcRuntimeState.lastFailureAt);
1612
- if (!Number.isFinite(failedAtMs)) {
1690
+ const created: SatReadRpcEndpointState = {
1691
+ consecutiveFailures: 0,
1692
+ backoffUntilMs: 0,
1693
+ quotaLikely: false,
1694
+ lastError: null,
1695
+ lastFailureAt: null,
1696
+ lastSuccessAt: null,
1697
+ };
1698
+ satReadRpcEndpointStates.set(key, created);
1699
+ return created;
1700
+ }
1701
+
1702
+ function currentReadRpcBackoffMs(rpcUrl: string, nowMs = Date.now()): number {
1703
+ const state = satReadRpcEndpointStates.get(normalizeRpcUrlForComparison(rpcUrl));
1704
+ if (!state) {
1613
1705
  return 0;
1614
1706
  }
1615
- const remainingMs = SAT_RPC_QUOTA_BACKOFF_MS - (nowMs - failedAtMs);
1616
- return remainingMs > 0 ? remainingMs : 0;
1707
+ return Math.max(0, state.backoffUntilMs - nowMs);
1617
1708
  }
1618
1709
 
1619
- function makeReadRpcQuotaBackoffError(method: string, remainingMs: number): Error {
1710
+ function makeReadRpcBackoffError(method: string, remainingMs: number): Error {
1620
1711
  return new Error(
1621
- `rpc ${method} skipped during provider quota backoff; retry in ${Math.ceil(remainingMs / 1000)}s`,
1712
+ `rpc ${method} skipped during endpoint circuit backoff; retry in ${Math.ceil(remainingMs / 1000)}s`,
1622
1713
  );
1623
1714
  }
1624
1715
 
1716
+ function markReadRpcEndpointSuccess(rpcUrl: string) {
1717
+ const state = getOrCreateReadRpcEndpointState(rpcUrl);
1718
+ state.consecutiveFailures = 0;
1719
+ state.backoffUntilMs = 0;
1720
+ state.quotaLikely = false;
1721
+ state.lastError = null;
1722
+ state.lastSuccessAt = new Date().toISOString();
1723
+ }
1724
+
1725
+ function markReadRpcEndpointFailure(rpcUrl: string, error: unknown) {
1726
+ const state = getOrCreateReadRpcEndpointState(rpcUrl);
1727
+ const message = error instanceof Error ? error.message : String(error);
1728
+ const quotaLikely = looksLikeRpcQuotaFailure(message);
1729
+ state.consecutiveFailures += 1;
1730
+ state.quotaLikely = quotaLikely;
1731
+ state.lastError = message;
1732
+ state.lastFailureAt = new Date().toISOString();
1733
+ if (quotaLikely) {
1734
+ state.backoffUntilMs = Date.now() + SAT_RPC_QUOTA_BACKOFF_MS;
1735
+ } else if (state.consecutiveFailures >= SAT_RPC_FAILURE_BACKOFF_THRESHOLD) {
1736
+ const exponent = state.consecutiveFailures - SAT_RPC_FAILURE_BACKOFF_THRESHOLD;
1737
+ state.backoffUntilMs =
1738
+ Date.now() +
1739
+ Math.min(SAT_RPC_FAILURE_BACKOFF_MAX_MS, SAT_RPC_FAILURE_BACKOFF_BASE_MS * 2 ** exponent);
1740
+ }
1741
+ }
1742
+
1625
1743
  function markReadRpcSuccess(mode: "primary" | "fallback", rpcUrl: string) {
1744
+ markReadRpcEndpointSuccess(rpcUrl);
1626
1745
  satReadRpcRuntimeState.lastMode = mode;
1627
1746
  satReadRpcRuntimeState.lastRpcUrl = rpcUrl;
1628
- satReadRpcRuntimeState.lastError = null;
1629
1747
  satReadRpcRuntimeState.lastSuccessAt = new Date().toISOString();
1630
- satReadRpcRuntimeState.quotaLikely = false;
1631
- if (mode === "fallback") {
1748
+ if (mode === "primary") {
1749
+ satReadRpcRuntimeState.lastError = null;
1750
+ satReadRpcRuntimeState.quotaLikely = false;
1751
+ } else {
1632
1752
  satReadRpcRuntimeState.fallbackCount += 1;
1633
1753
  }
1634
1754
  }
1635
1755
 
1636
- function markReadRpcFailure(error: unknown) {
1756
+ function markReadRpcFailure(error: unknown, rpcUrl: string) {
1637
1757
  const message = error instanceof Error ? error.message : String(error);
1758
+ markReadRpcEndpointFailure(rpcUrl, error);
1638
1759
  satReadRpcRuntimeState.lastMode = "unavailable";
1639
1760
  satReadRpcRuntimeState.lastError = message;
1640
1761
  satReadRpcRuntimeState.lastFailureAt = new Date().toISOString();
1641
- satReadRpcRuntimeState.quotaLikely = looksLikeRpcQuotaFailure(message);
1762
+ satReadRpcRuntimeState.quotaLikely =
1763
+ satReadRpcRuntimeState.quotaLikely || looksLikeRpcQuotaFailure(message);
1642
1764
  }
1643
1765
 
1644
1766
  function firstNonEmpty(...values: Array<string | null | undefined>): string {
@@ -1808,17 +1930,11 @@ function resolveReadRpcConfig(cfg: FasedAgentConfig, env: NodeJS.ProcessEnv): Sa
1808
1930
  ? readWalletProviderRegistry(env).wallets.find((wallet) => wallet.id === walletId)?.providerId
1809
1931
  : undefined;
1810
1932
  const providerId = registryProviderId || resolveWalletProviderId(cfg, env);
1811
- const walletReadRpcUrl =
1812
- walletEnvValue(env, "FASED_WALLET_SOLANA_READ_RPC_URL", walletId) ||
1813
- walletEnvValue(env, "FASED_WALLET_EMBEDDED_KEYSTORE_READ_RPC_URL", walletId);
1814
- const walletRpcUrl =
1815
- walletEnvValue(env, "FASED_WALLET_SOLANA_RPC_URL", walletId) ||
1816
- walletEnvValue(env, "FASED_WALLET_EMBEDDED_KEYSTORE_RPC_URL", walletId);
1933
+ const walletReadRpcUrl = walletEnvValue(env, "FASED_WALLET_SOLANA_READ_RPC_URL", walletId);
1934
+ const walletRpcUrl = walletEnvValue(env, "FASED_WALLET_SOLANA_RPC_URL", walletId);
1817
1935
  const walletReadRpcFallbackUrl =
1818
1936
  walletEnvValue(env, "FASED_WALLET_SOLANA_READ_RPC_FALLBACK_URL", walletId) ||
1819
- walletEnvValue(env, "FASED_WALLET_SOLANA_RPC_FALLBACK_URL", walletId) ||
1820
- walletEnvValue(env, "FASED_WALLET_EMBEDDED_KEYSTORE_READ_RPC_FALLBACK_URL", walletId) ||
1821
- walletEnvValue(env, "FASED_WALLET_EMBEDDED_KEYSTORE_RPC_FALLBACK_URL", walletId);
1937
+ walletEnvValue(env, "FASED_WALLET_SOLANA_RPC_FALLBACK_URL", walletId);
1822
1938
  if (providerId === "local-socket-signer") {
1823
1939
  const primaryUrl = firstNonEmpty(walletReadRpcUrl, walletRpcUrl);
1824
1940
  if (!primaryUrl) {
@@ -1893,68 +2009,142 @@ export function resolveEffectiveReadRpcConfig(): SatReadRpcConfig {
1893
2009
  return resolveReadRpcConfig(cfg, mergedEnv);
1894
2010
  }
1895
2011
 
2012
+ function createAbortableReadRpcFetch(): typeof globalThis.fetch {
2013
+ return (async (input, init) => {
2014
+ const timeoutMs = satRpcRequestTimeoutMs();
2015
+ const requestUrl =
2016
+ typeof input === "string" || input instanceof URL ? input.toString() : input.url;
2017
+ let guardedFetch: Awaited<ReturnType<typeof fetchWithSsrFGuard>>;
2018
+ try {
2019
+ guardedFetch = await fetchWithSsrFGuard({
2020
+ url: requestUrl,
2021
+ init,
2022
+ timeoutMs,
2023
+ signal: init?.signal ?? (input instanceof Request ? input.signal : undefined),
2024
+ policy: { allowPrivateNetwork: true },
2025
+ auditContext: "sat-mining-read-rpc",
2026
+ });
2027
+ } catch (error) {
2028
+ const reason = redactSensitiveUrlLikeString(
2029
+ error instanceof Error ? `${error.name}: ${error.message}` : String(error),
2030
+ );
2031
+ throw new Error(
2032
+ `rpc fetch failed after at most ${timeoutMs}ms (${redactSensitiveUrlLikeString(requestUrl)}): ${reason}`,
2033
+ );
2034
+ }
2035
+ const { response, release } = guardedFetch;
2036
+ try {
2037
+ const body = await response.arrayBuffer();
2038
+ return new Response(body, {
2039
+ headers: response.headers,
2040
+ status: response.status,
2041
+ statusText: response.statusText,
2042
+ });
2043
+ } finally {
2044
+ await release();
2045
+ }
2046
+ }) as typeof globalThis.fetch;
2047
+ }
2048
+
2049
+ async function withReadRpcTimeout<T>(task: Promise<T>, method: string, rpcUrl: string): Promise<T> {
2050
+ const timeoutMs = satRpcRequestTimeoutMs();
2051
+ let timer: NodeJS.Timeout | undefined;
2052
+ try {
2053
+ return await Promise.race([
2054
+ task,
2055
+ new Promise<never>((_resolve, reject) => {
2056
+ timer = setTimeout(
2057
+ () =>
2058
+ reject(
2059
+ new Error(
2060
+ `rpc ${method} timed out after ${timeoutMs}ms (${redactSensitiveUrlLikeString(rpcUrl)})`,
2061
+ ),
2062
+ ),
2063
+ timeoutMs,
2064
+ );
2065
+ timer.unref?.();
2066
+ }),
2067
+ ]);
2068
+ } finally {
2069
+ if (timer) {
2070
+ clearTimeout(timer);
2071
+ }
2072
+ }
2073
+ }
2074
+
1896
2075
  export function createReadConnection(
1897
2076
  solana: SolanaModuleLike,
1898
2077
  rpc: SatReadRpcConfig,
1899
2078
  ): SatReadConnectionLike {
1900
- const primary = new solana.Connection(rpc.primaryUrl);
1901
- const secondary = rpc.secondaryUrl ? new solana.Connection(rpc.secondaryUrl) : null;
2079
+ const primary = new solana.Connection(rpc.primaryUrl, {
2080
+ disableRetryOnRateLimit: true,
2081
+ fetch: createAbortableReadRpcFetch(),
2082
+ });
2083
+ const secondary = rpc.secondaryUrl
2084
+ ? new solana.Connection(rpc.secondaryUrl, {
2085
+ disableRetryOnRateLimit: true,
2086
+ fetch: createAbortableReadRpcFetch(),
2087
+ })
2088
+ : null;
1902
2089
 
1903
2090
  const withFallback = <TMethod extends SatReadMethodName>(
1904
2091
  method: TMethod,
1905
2092
  ): SatReadConnectionLike[TMethod] => {
1906
2093
  return (async (...args: unknown[]): Promise<unknown> => {
1907
- const quotaBackoffMs = currentReadRpcQuotaBackoffMs();
1908
- if (quotaBackoffMs > 0) {
1909
- if (!secondary) {
1910
- throw makeReadRpcQuotaBackoffError(method, quotaBackoffMs);
1911
- }
2094
+ const primaryBackoffMs = currentReadRpcBackoffMs(rpc.primaryUrl);
2095
+ const secondaryBackoffMs = rpc.secondaryUrl ? currentReadRpcBackoffMs(rpc.secondaryUrl) : 0;
2096
+ const callEndpoint = async (
2097
+ connection: InstanceType<SolanaModuleLike["Connection"]>,
2098
+ mode: "primary" | "fallback",
2099
+ rpcUrl: string,
2100
+ ) => {
2101
+ updateSatRpcMethodMetric(method, "request");
1912
2102
  try {
1913
- updateSatRpcMethodMetric(method, "request");
1914
- const result = (await (
1915
- secondary[method] as unknown as (...inner: unknown[]) => Promise<unknown>
1916
- )(...args)) as unknown;
2103
+ const task = (connection[method] as unknown as (...inner: unknown[]) => Promise<unknown>)(
2104
+ ...args,
2105
+ );
2106
+ const result = await withReadRpcTimeout(task, method, rpcUrl);
1917
2107
  updateSatRpcMethodMetric(method, "success");
1918
- markReadRpcSuccess("fallback", rpc.secondaryUrl ?? rpc.primaryUrl);
2108
+ markReadRpcSuccess(mode, rpcUrl);
1919
2109
  return result;
1920
- } catch (secondaryError) {
2110
+ } catch (error) {
1921
2111
  updateSatRpcMethodMetric(method, "failure");
1922
- markReadRpcFailure(secondaryError);
1923
- throw secondaryError;
2112
+ markReadRpcFailure(error, rpcUrl);
2113
+ throw error;
2114
+ }
2115
+ };
2116
+ if (primaryBackoffMs > 0) {
2117
+ if (!secondary || !rpc.secondaryUrl || secondaryBackoffMs > 0) {
2118
+ throw makeReadRpcBackoffError(
2119
+ method,
2120
+ Math.min(
2121
+ primaryBackoffMs,
2122
+ secondaryBackoffMs > 0 ? secondaryBackoffMs : primaryBackoffMs,
2123
+ ),
2124
+ );
1924
2125
  }
2126
+ return await callEndpoint(secondary, "fallback", rpc.secondaryUrl);
1925
2127
  }
1926
2128
  try {
1927
- updateSatRpcMethodMetric(method, "request");
1928
- const result = (await (
1929
- primary[method] as unknown as (...inner: unknown[]) => Promise<unknown>
1930
- )(...args)) as unknown;
1931
- updateSatRpcMethodMetric(method, "success");
1932
- markReadRpcSuccess("primary", rpc.primaryUrl);
1933
- return result;
2129
+ return await callEndpoint(primary, "primary", rpc.primaryUrl);
1934
2130
  } catch (primaryError) {
1935
- updateSatRpcMethodMetric(method, "failure");
1936
- if (!secondary) {
1937
- markReadRpcFailure(primaryError);
2131
+ if (!secondary || !rpc.secondaryUrl) {
1938
2132
  throw primaryError;
1939
2133
  }
2134
+ const fallbackBackoffMs = currentReadRpcBackoffMs(rpc.secondaryUrl);
2135
+ if (fallbackBackoffMs > 0) {
2136
+ throw makeReadRpcBackoffError(method, fallbackBackoffMs);
2137
+ }
1940
2138
  try {
1941
- updateSatRpcMethodMetric(method, "request");
1942
- const result = (await (
1943
- secondary[method] as unknown as (...inner: unknown[]) => Promise<unknown>
1944
- )(...args)) as unknown;
1945
- updateSatRpcMethodMetric(method, "success");
1946
- markReadRpcSuccess("fallback", rpc.secondaryUrl ?? rpc.primaryUrl);
1947
- return result;
2139
+ return await callEndpoint(secondary, "fallback", rpc.secondaryUrl);
1948
2140
  } catch (secondaryError) {
1949
- updateSatRpcMethodMetric(method, "failure");
1950
- markReadRpcFailure(
1951
- new Error(
1952
- `${String(primaryError instanceof Error ? primaryError.message : primaryError)}; ${String(
1953
- secondaryError instanceof Error ? secondaryError.message : secondaryError,
1954
- )}`,
1955
- ),
2141
+ throw new Error(
2142
+ `rpc ${method} failed on primary (${String(
2143
+ primaryError instanceof Error ? primaryError.message : primaryError,
2144
+ )}) and fallback (${String(
2145
+ secondaryError instanceof Error ? secondaryError.message : secondaryError,
2146
+ )})`,
1956
2147
  );
1957
- throw secondaryError;
1958
2148
  }
1959
2149
  }
1960
2150
  }) as unknown as SatReadConnectionLike[TMethod];
@@ -2002,7 +2192,6 @@ async function resolveBondProgramContext(env: NodeJS.ProcessEnv) {
2002
2192
  };
2003
2193
  }
2004
2194
 
2005
- const SAT_REGISTRY_RESERVE_TARGET_LAMPORTS = 200_000_000;
2006
2195
  const SAT_PROTOCOL_VAULT_ACCOUNT_SPACE = 0;
2007
2196
  const SAT_CYCLE_STATE_ACCOUNT_SPACE = 336;
2008
2197
  const SAT_CYCLE_REGISTRY_META_ACCOUNT_SPACE = 88;
@@ -2021,6 +2210,14 @@ async function rpcRequestOnce<T>(rpcUrl: string, method: string, params: unknown
2021
2210
  const target = new URL(rpcUrl);
2022
2211
  const transport = target.protocol === "https:" ? https : http;
2023
2212
  const payload = await new Promise<string>((resolve, reject) => {
2213
+ let settled = false;
2214
+ const finishReject = (error: Error) => {
2215
+ if (settled) {
2216
+ return;
2217
+ }
2218
+ settled = true;
2219
+ reject(error);
2220
+ };
2024
2221
  const req = transport.request(
2025
2222
  target,
2026
2223
  {
@@ -2032,20 +2229,36 @@ async function rpcRequestOnce<T>(rpcUrl: string, method: string, params: unknown
2032
2229
  },
2033
2230
  (res) => {
2034
2231
  const chunks: Buffer[] = [];
2035
- res.on("data", (chunk) =>
2036
- chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)),
2037
- );
2232
+ let responseBytes = 0;
2233
+ res.on("data", (chunk) => {
2234
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
2235
+ responseBytes += buffer.length;
2236
+ if (responseBytes > SAT_RPC_MAX_RESPONSE_BYTES) {
2237
+ req.destroy(new Error(`rpc ${method} response exceeded size limit`));
2238
+ return;
2239
+ }
2240
+ chunks.push(buffer);
2241
+ });
2038
2242
  res.on("end", () => {
2243
+ if (settled) {
2244
+ return;
2245
+ }
2039
2246
  const text = Buffer.concat(chunks).toString("utf8");
2040
2247
  if ((res.statusCode ?? 500) >= 400) {
2041
- reject(new Error(text || `rpc ${method} failed`));
2248
+ finishReject(new Error(text || `rpc ${method} failed`));
2042
2249
  return;
2043
2250
  }
2251
+ settled = true;
2044
2252
  resolve(text);
2045
2253
  });
2046
2254
  },
2047
2255
  );
2048
- req.on("error", reject);
2256
+ req.setTimeout(satRpcRequestTimeoutMs(), () => {
2257
+ req.destroy(
2258
+ new Error(`rpc ${method} timed out after ${satRpcRequestTimeoutMs()}ms (${rpcUrl})`),
2259
+ );
2260
+ });
2261
+ req.on("error", (error) => finishReject(error));
2049
2262
  req.write(body);
2050
2263
  req.end();
2051
2264
  });
@@ -2067,41 +2280,51 @@ async function rpcRequest<T>(
2067
2280
  params: unknown[],
2068
2281
  ): Promise<T> {
2069
2282
  const normalized = normalizeReadRpcConfig(rpc);
2070
- const quotaBackoffMs = currentReadRpcQuotaBackoffMs();
2071
- if (quotaBackoffMs > 0 && !normalized.secondaryUrl) {
2072
- throw makeReadRpcQuotaBackoffError(method, quotaBackoffMs);
2283
+ const primaryBackoffMs = currentReadRpcBackoffMs(normalized.primaryUrl);
2284
+ const secondaryBackoffMs = normalized.secondaryUrl
2285
+ ? currentReadRpcBackoffMs(normalized.secondaryUrl)
2286
+ : 0;
2287
+ if (primaryBackoffMs > 0 && (!normalized.secondaryUrl || secondaryBackoffMs > 0)) {
2288
+ throw makeReadRpcBackoffError(
2289
+ method,
2290
+ Math.min(primaryBackoffMs, secondaryBackoffMs > 0 ? secondaryBackoffMs : primaryBackoffMs),
2291
+ );
2073
2292
  }
2074
- const useFallbackDueToQuota = quotaBackoffMs > 0 && Boolean(normalized.secondaryUrl);
2293
+ const useFallbackDueToBackoff = primaryBackoffMs > 0 && Boolean(normalized.secondaryUrl);
2075
2294
  try {
2076
2295
  const rpcUrl =
2077
- useFallbackDueToQuota && normalized.secondaryUrl
2296
+ useFallbackDueToBackoff && normalized.secondaryUrl
2078
2297
  ? normalized.secondaryUrl
2079
2298
  : normalized.primaryUrl;
2080
2299
  const result = await rpcRequestOnce<T>(rpcUrl, method, params);
2081
2300
  markReadRpcSuccess(
2082
- useFallbackDueToQuota && normalized.secondaryUrl ? "fallback" : "primary",
2301
+ useFallbackDueToBackoff && normalized.secondaryUrl ? "fallback" : "primary",
2083
2302
  rpcUrl,
2084
2303
  );
2085
2304
  return result;
2086
2305
  } catch (primaryError) {
2087
- if (!normalized.secondaryUrl || useFallbackDueToQuota) {
2088
- markReadRpcFailure(primaryError);
2306
+ const failedRpcUrl =
2307
+ useFallbackDueToBackoff && normalized.secondaryUrl
2308
+ ? normalized.secondaryUrl
2309
+ : normalized.primaryUrl;
2310
+ markReadRpcFailure(primaryError, failedRpcUrl);
2311
+ if (!normalized.secondaryUrl || useFallbackDueToBackoff) {
2089
2312
  throw primaryError;
2090
2313
  }
2314
+ const fallbackBackoffMs = currentReadRpcBackoffMs(normalized.secondaryUrl);
2315
+ if (fallbackBackoffMs > 0) {
2316
+ throw makeReadRpcBackoffError(method, fallbackBackoffMs);
2317
+ }
2091
2318
  try {
2092
2319
  const result = await rpcRequestOnce<T>(normalized.secondaryUrl, method, params);
2093
2320
  markReadRpcSuccess("fallback", normalized.secondaryUrl);
2094
2321
  return result;
2095
2322
  } catch (secondaryError) {
2323
+ markReadRpcFailure(secondaryError, normalized.secondaryUrl);
2096
2324
  const primaryMessage =
2097
2325
  primaryError instanceof Error ? primaryError.message : String(primaryError);
2098
2326
  const secondaryMessage =
2099
2327
  secondaryError instanceof Error ? secondaryError.message : String(secondaryError);
2100
- markReadRpcFailure(
2101
- new Error(
2102
- `rpc ${method} failed on primary (${primaryMessage}) and fallback (${secondaryMessage})`,
2103
- ),
2104
- );
2105
2328
  throw new Error(
2106
2329
  `rpc ${method} failed on primary (${primaryMessage}) and fallback (${secondaryMessage})`,
2107
2330
  );
@@ -3343,7 +3566,7 @@ export async function inspectSatTreasuryVaultLamports(
3343
3566
  };
3344
3567
  }
3345
3568
 
3346
- export async function inspectSatRentExemptionLamports(_config: SatMiningConfig): Promise<{
3569
+ export async function inspectSatRentExemptionLamports(config: SatMiningConfig): Promise<{
3347
3570
  registryReserveTargetLamports: string;
3348
3571
  protocolVaultLamports: string;
3349
3572
  cycleStateLamports: string;
@@ -3357,8 +3580,11 @@ export async function inspectSatRentExemptionLamports(_config: SatMiningConfig):
3357
3580
  }> {
3358
3581
  const { connection } = await resolveConnection(process.env);
3359
3582
  const rpc = resolveEffectiveReadRpcConfig();
3583
+ const registryReserveTargetLamports = resolveSatGenesisProfileContract(
3584
+ config.network,
3585
+ ).registryReserveTargetLamports;
3360
3586
  return await getOrLoadRpcCacheValue(
3361
- `view:rent-exemption:${rpcCacheScope(rpc)}`,
3587
+ `view:rent-exemption:${rpcCacheScope(rpc)}:${registryReserveTargetLamports}`,
3362
3588
  SAT_RPC_RENT_EXEMPTION_CACHE_TTL_MS,
3363
3589
  async () => {
3364
3590
  const [
@@ -3381,7 +3607,7 @@ export async function inspectSatRentExemptionLamports(_config: SatMiningConfig):
3381
3607
  const openCycleLamports = cycleStateLamports + cycleRegistryMetaLamports;
3382
3608
  const submitCycleSharedLamports = cycleSettlementProgressLamports + cycleRegistryPageLamports;
3383
3609
  return {
3384
- registryReserveTargetLamports: String(SAT_REGISTRY_RESERVE_TARGET_LAMPORTS),
3610
+ registryReserveTargetLamports: String(registryReserveTargetLamports),
3385
3611
  protocolVaultLamports: String(protocolVaultLamports),
3386
3612
  cycleStateLamports: String(cycleStateLamports),
3387
3613
  cycleRegistryMetaLamports: String(cycleRegistryMetaLamports),
@@ -3592,6 +3818,20 @@ export async function inspectSatRoundState(
3592
3818
 
3593
3819
  export function inspectSatConnectionDetails() {
3594
3820
  const rpc = resolveEffectiveReadRpcConfig();
3821
+ const endpointStates = [rpc.primaryUrl, rpc.secondaryUrl]
3822
+ .filter((rpcUrl): rpcUrl is string => Boolean(rpcUrl))
3823
+ .map((rpcUrl) => {
3824
+ const state = satReadRpcEndpointStates.get(normalizeRpcUrlForComparison(rpcUrl));
3825
+ return {
3826
+ rpcUrl: redactSensitiveUrlLikeString(rpcUrl),
3827
+ consecutiveFailures: state?.consecutiveFailures ?? 0,
3828
+ backoffRemainingMs: currentReadRpcBackoffMs(rpcUrl),
3829
+ quotaLikely: state?.quotaLikely ?? false,
3830
+ lastError: state?.lastError ? redactSensitiveUrlLikeString(state.lastError) : null,
3831
+ lastFailureAt: state?.lastFailureAt ?? null,
3832
+ lastSuccessAt: state?.lastSuccessAt ?? null,
3833
+ };
3834
+ });
3595
3835
  return {
3596
3836
  programId: SAT_PROGRAM_ID(),
3597
3837
  bondProgramId: SAT_BOND_PROGRAM_ID(),
@@ -3608,6 +3848,7 @@ export function inspectSatConnectionDetails() {
3608
3848
  quotaLikely:
3609
3849
  satReadRpcRuntimeState.quotaLikely ||
3610
3850
  looksLikeRpcQuotaFailure(satReadRpcRuntimeState.lastError),
3851
+ endpoints: endpointStates,
3611
3852
  },
3612
3853
  rpcMetrics: summarizeSatRpcMethodMetrics(),
3613
3854
  };