@fased/fased 0.1.62 → 0.1.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (342) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +44 -29
  3. package/config/dependency-ownership.json +1 -1
  4. package/config/signer-policies/README.md +58 -0
  5. package/config/signer-policies/agent.json.template +32 -0
  6. package/config/signer-policies/mining.json.template +69 -0
  7. package/config/signer-policies/network.json.template +5 -0
  8. package/config/signer-policies/vault.json.template +70 -0
  9. package/config/signer-protocol-v2.json +78 -0
  10. package/config/typescript-noemit-baseline.json +680 -0
  11. package/dist/agents/auth-profiles/store.js +267 -31
  12. package/dist/agents/bash-tools.exec.js +10 -4
  13. package/dist/agents/current-model-catalog.js +3 -3
  14. package/dist/agents/memory-search.js +7 -1
  15. package/dist/agents/model-catalog-access.js +1 -2
  16. package/dist/agents/model-catalog-snapshot.js +1 -1
  17. package/dist/agents/model-catalog-source.js +1 -1
  18. package/dist/agents/model-metadata.js +1 -1
  19. package/dist/agents/model-selection.js +2 -28
  20. package/dist/agents/models-config.providers.js +6 -6
  21. package/dist/agents/pi-embedded-runner/compact.js +15 -7
  22. package/dist/agents/pi-embedded-runner/model.js +1 -1
  23. package/dist/agents/pi-embedded-runner/run/attempt.js +24 -13
  24. package/dist/agents/pi-embedded-runner/run.js +2 -0
  25. package/dist/agents/pi-embedded-runner/tool-split.js +40 -2
  26. package/dist/agents/pi-tool-definition-adapter.js +16 -1
  27. package/dist/agents/pi-tools.js +2 -1
  28. package/dist/agents/sandbox/config.js +1 -1
  29. package/dist/agents/sandbox/context.js +27 -2
  30. package/dist/agents/skills/env-overrides.js +38 -28
  31. package/dist/agents/skills/trust.js +93 -0
  32. package/dist/agents/skills/workspace.js +128 -0
  33. package/dist/agents/skills-clawhub.js +36 -11
  34. package/dist/agents/skills-marketplace-scan.js +49 -0
  35. package/dist/agents/tools/marketplace-offer-draft-tool.js +1 -1
  36. package/dist/agents/tools/mining-tool.js +1 -1
  37. package/dist/agents/tools/session-status-tool.js +1 -1
  38. package/dist/agents/tools/wallet-action-tool.js +172 -36
  39. package/dist/agents/tools/wallet-skill-policy.js +65 -23
  40. package/dist/agents/tools/wallet-tool.js +7 -11
  41. package/dist/auto-reply/reply/directive-handling.fast-lane.js +2 -1
  42. package/dist/auto-reply/reply/directive-handling.impl.js +2 -1
  43. package/dist/auto-reply/reply/directive-handling.model.js +2 -1
  44. package/dist/auto-reply/reply/directive-handling.persist.js +2 -2
  45. package/dist/auto-reply/reply/get-reply-directives-apply.js +2 -0
  46. package/dist/auto-reply/reply/get-reply-inline-actions.js +25 -1
  47. package/dist/auto-reply/reply/model-selection.js +7 -4
  48. package/dist/auto-reply/reply/session-reset-model.js +4 -4
  49. package/dist/brand.js +1 -1
  50. package/dist/build-info.json +3 -3
  51. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  52. package/dist/channel-web.js +2 -2
  53. package/dist/cli/gateway-cli/run.js +8 -0
  54. package/dist/cli/program/command-registry.js +1 -1
  55. package/dist/cli/program/register.onboard.js +2 -3
  56. package/dist/cli/program/register.wallet.js +16 -123
  57. package/dist/cli/providers-cli.js +1 -1
  58. package/dist/cli/sat-cli.js +129 -2
  59. package/dist/cli/update-cli/update-command.js +260 -11
  60. package/dist/commands/auth-choice.apply.api-providers.js +3 -3
  61. package/dist/commands/doctor-config-flow.js +1 -1
  62. package/dist/commands/doctor-legacy-config.js +2 -13
  63. package/dist/commands/model-picker.js +6 -6
  64. package/dist/commands/models/auth.js +1 -1
  65. package/dist/commands/onboard-auth.config-gateways.js +1 -1
  66. package/dist/commands/onboard-auth.credentials.js +32 -8
  67. package/dist/commands/onboard-non-interactive/local/wallet-config.js +28 -27
  68. package/dist/commands/onboard-non-interactive/local.js +5 -1
  69. package/dist/commands/wallet.js +568 -1911
  70. package/dist/config/config.js +2 -2
  71. package/dist/config/io.js +64 -2
  72. package/dist/config/schema.help.js +8 -7
  73. package/dist/config/schema.labels.js +5 -4
  74. package/dist/config/zod-schema.agent-runtime.js +1 -0
  75. package/dist/config/zod-schema.js +5 -0
  76. package/dist/control-ui/assets/{app-DLil9VO1.js → app-MaQnPa5G.js} +1511 -1555
  77. package/dist/control-ui/assets/{config-CU5Zi8Dh.js → config-LeImukCW.js} +10 -10
  78. package/dist/control-ui/assets/{federation-D10Q4eP_.js → federation-DgA9e-Pn.js} +364 -422
  79. package/dist/control-ui/assets/{index-DdE_NIXo.js → index-D4YMr1fA.js} +3 -3
  80. package/dist/control-ui/assets/mining-commit-DFpB_4JN.js +2 -0
  81. package/dist/control-ui/assets/{mining-BdhMn18r.js → mining-qMYs4aD-.js} +70 -50
  82. package/dist/control-ui/assets/{open-external-url-DwSiwMPl.js → open-external-url-ulF1B-sA.js} +3 -3
  83. package/dist/control-ui/assets/{providers-QMn4w2_f.js → providers-CIx9fxc6.js} +2 -2
  84. package/dist/control-ui/assets/{wallet-C2g294QT.js → wallet-DvStR_AT.js} +259 -377
  85. package/dist/control-ui/index.html +1 -1
  86. package/dist/control-ui/version.json +1 -1
  87. package/dist/daemon/systemd-system.js +56 -50
  88. package/dist/extensions/sat-mining/src/protocol-contract.js +43 -3
  89. package/dist/extensions/sat-mining/src/rpc-read.js +291 -84
  90. package/dist/extensions/sat-mining/src/sat-bond-layout.js +5 -2
  91. package/dist/extensions/sat-mining/src/signer-codec-manifest.js +406 -0
  92. package/dist/extensions/sat-mining/src/solana-submit.js +1274 -390
  93. package/dist/extensions/sat-mining/src/submission-ledger.js +349 -0
  94. package/dist/federation/auto-connect.js +98 -8
  95. package/dist/federation/marketplace-capability-adapter.js +33 -7
  96. package/dist/federation/marketplace-delivery-outbox.js +196 -0
  97. package/dist/federation/marketplace-delivery.js +351 -215
  98. package/dist/federation/marketplace-direct-payment.js +272 -141
  99. package/dist/federation/marketplace-escrow.js +607 -249
  100. package/dist/federation/marketplace-settlement-ledger.js +352 -0
  101. package/dist/federation/offers.js +9 -7
  102. package/dist/federation/peer-auth-v2.js +529 -0
  103. package/dist/gateway/a2a-http.js +425 -96
  104. package/dist/gateway/a2a-settlement.js +259 -153
  105. package/dist/gateway/a2a-task-store.js +524 -0
  106. package/dist/gateway/auth.js +38 -2
  107. package/dist/gateway/config-reload.js +46 -33
  108. package/dist/gateway/durable-capacity.js +31 -0
  109. package/dist/gateway/federation-http.js +540 -135
  110. package/dist/gateway/federation-marketplace-run-store.js +397 -0
  111. package/dist/gateway/federation-marketplace.js +535 -230
  112. package/dist/gateway/mutating-admin-rpc-rate-limit.js +5 -0
  113. package/dist/gateway/security-path.js +1 -1
  114. package/dist/gateway/server-http.js +1084 -1205
  115. package/dist/gateway/server-methods/models.js +1 -1
  116. package/dist/gateway/server-methods/secrets.js +40 -0
  117. package/dist/gateway/server-methods.js +1 -2
  118. package/dist/gateway/server-reload-handlers.js +196 -66
  119. package/dist/gateway/server-runtime-config.js +1 -1
  120. package/dist/gateway/server-secrets-runtime.js +288 -0
  121. package/dist/gateway/server.impl.js +73 -42
  122. package/dist/gateway/sessions-patch.js +3 -5
  123. package/dist/index.js +4 -2
  124. package/dist/infra/fasedhub.js +64 -1
  125. package/dist/infra/local-source-paired-update.js +538 -0
  126. package/dist/infra/restart.js +41 -10
  127. package/dist/infra/update-runner.js +96 -0
  128. package/dist/light-update-status.js +11 -11
  129. package/dist/memory/backend-config.js +2 -1
  130. package/dist/memory/session-files.js +16 -2
  131. package/dist/plugin-sdk/{accounts-DxblobYM.js → accounts-Brn3-uWN.js} +1 -1
  132. package/dist/plugin-sdk/{actions-D4UNimWa.js → actions-DRu135h0.js} +2 -2
  133. package/dist/plugin-sdk/{active-listener-CFuy106s.js → active-listener-B_NMtgPL.js} +1 -1
  134. package/dist/plugin-sdk/{audio-preflight-Bwi2Oq03.js → audio-preflight-I4IngVlJ.js} +27 -27
  135. package/dist/plugin-sdk/{audit-Cs0K7LBp.js → audit-C5d2z5U1.js} +1 -1
  136. package/dist/plugin-sdk/{channel-access-D5aHoTY8.js → channel-access-CcFRdRPO.js} +1 -1
  137. package/dist/plugin-sdk/{channel-access-configure-Dvch9mMQ.js → channel-access-configure-DaI5wevh.js} +1 -1
  138. package/dist/plugin-sdk/channel-plugin-common.d.ts +3 -3
  139. package/dist/plugin-sdk/channel-plugin-common.js +4 -4
  140. package/dist/plugin-sdk/{chunk-B0FUGc5A.js → chunk-CyoyqpbG.js} +1 -1
  141. package/dist/plugin-sdk/{chunk-items-DzT4L4Ty.js → chunk-items-DLQ6_lLK.js} +1 -1
  142. package/dist/plugin-sdk/command-status.d.ts +2 -2
  143. package/dist/plugin-sdk/command-status.js +27 -27
  144. package/dist/plugin-sdk/{commands-registry-DmDRhRAU.js → commands-registry-BfqdEWdF.js} +2 -2
  145. package/dist/plugin-sdk/{common-CfUOowOp.js → common-HCcXU-NR.js} +1 -1
  146. package/dist/plugin-sdk/{config-mxULv0fQ.js → config-DlWVeLFB.js} +7113 -6877
  147. package/dist/plugin-sdk/{config-schema-BrkmtFxB.js → config-schema-D_8FVI1C.js} +6798 -3695
  148. package/dist/plugin-sdk/device-pair.d.ts +1 -1
  149. package/dist/plugin-sdk/discord.d.ts +6 -6
  150. package/dist/plugin-sdk/discord.js +19 -19
  151. package/dist/plugin-sdk/file-lock.js +35 -4
  152. package/dist/plugin-sdk/{filesystem-manager-ZoHU8oA7.js → filesystem-manager-DoI8IBNF.js} +1 -1
  153. package/dist/plugin-sdk/{group-mentions-BHRff6j8.d.ts → group-mentions-q3hUTCt7.d.ts} +1 -1
  154. package/dist/plugin-sdk/{handle-action-DbVCF9HZ.js → handle-action-hvwapMKg.js} +13 -13
  155. package/dist/plugin-sdk/{helpers-BXbdgs5H.js → helpers-DMBU4oTo.js} +1 -1
  156. package/dist/plugin-sdk/{image-ops-D7jPxaph.js → image-ops-DQi0n_Tt.js} +1 -1
  157. package/dist/plugin-sdk/index.d.ts +21 -39
  158. package/dist/plugin-sdk/index.js +29 -29
  159. package/dist/plugin-sdk/{login-BRxww6nv.js → login-Ca583Okc.js} +3 -3
  160. package/dist/plugin-sdk/{login-qr-DJXsk9XH.js → login-qr-CGciBSNP.js} +3 -3
  161. package/dist/plugin-sdk/{manager-Y2S_5IlI.js → manager-BegWxNYX.js} +4 -4
  162. package/dist/plugin-sdk/{markdown-tables-DHLFQqaF.js → markdown-tables-DCOXEUfZ.js} +1 -1
  163. package/dist/plugin-sdk/{media-Czo4carg.js → media-CAdQF5TG.js} +47 -47
  164. package/dist/plugin-sdk/{memory-search-DTjIMw8J.js → memory-search-CrFPOeTH.js} +4 -1
  165. package/dist/plugin-sdk/{monitor-M_ta2lMc.js → monitor-B4KF4Kpo.js} +31 -31
  166. package/dist/plugin-sdk/{monitor-wYVncM9w.js → monitor-Bb6x1KAG.js} +32 -32
  167. package/dist/plugin-sdk/{openresponses-http-B2GmeSt4.js → openresponses-http-DCTO8JkL.js} +27 -27
  168. package/dist/plugin-sdk/{optional-runtime-dependency-DdMbxS24.js → optional-runtime-dependency-0dznm3ZO.js} +1 -1
  169. package/dist/plugin-sdk/{outbound-Db8mRN6P.js → outbound-BgVDdHxx.js} +6 -6
  170. package/dist/plugin-sdk/{outbound-attachment-BqFjcypb.js → outbound-attachment-QqTnIhZL.js} +2 -2
  171. package/dist/plugin-sdk/{pairing-message-B3GC_7CD.js → pairing-message-D0CoLHRJ.js} +1 -1
  172. package/dist/plugin-sdk/{pairing-message-B3bHYGaw.d.ts → pairing-message-DHPDFZbC.d.ts} +2 -2
  173. package/dist/plugin-sdk/{pairing-store-CQikgIbw.js → pairing-store-BChahgI2.js} +2 -2
  174. package/dist/plugin-sdk/{pi-model-discovery-CY3m5zJP.js → pi-model-discovery-BX_JLcEJ.js} +1 -1
  175. package/dist/plugin-sdk/{pi-model-discovery-runtime-DSh1T2pn.js → pi-model-discovery-runtime-DxTMz_XF.js} +2 -2
  176. package/dist/plugin-sdk/provider-web-search-config-contract.d.ts +2 -2
  177. package/dist/plugin-sdk/{pw-ai-AFUqn-tQ.js → pw-ai-natjh3rm.js} +3 -3
  178. package/dist/plugin-sdk/{qmd-manager-DSyx77KY.js → qmd-manager-CgRaTxUq.js} +1 -1
  179. package/dist/plugin-sdk/{query-expansion-CAI2kKLQ.js → query-expansion-BG3FgzF7.js} +14 -3
  180. package/dist/plugin-sdk/{replies-Fzh9PhXl.js → replies-ChYo5ZQM.js} +2 -2
  181. package/dist/plugin-sdk/{resolve-outbound-target-KpF3co6T.js → resolve-outbound-target-D-KGgHJZ.js} +1 -1
  182. package/dist/plugin-sdk/{resolve-route-CDl74O19.js → resolve-route-C8tvQm8Z.js} +1 -1
  183. package/dist/plugin-sdk/{retry-policy-D4uiqUOG.js → retry-policy-C6SjKjQA.js} +1 -1
  184. package/dist/plugin-sdk/{runtime-Bb6KRnCC.js → runtime-2B9_WKoI.js} +8 -3
  185. package/dist/plugin-sdk/{runtime-dependency-DLDmB94f.js → runtime-dependency-DczkvPxn.js} +2 -2
  186. package/dist/plugin-sdk/sat-runtime.d.ts +565 -309
  187. package/dist/plugin-sdk/sat-runtime.js +29 -29
  188. package/dist/plugin-sdk/{send-C4k4JuJN.js → send-B6KkGKZD.js} +6 -6
  189. package/dist/plugin-sdk/{send-D-uDKGIq.js → send-CFzGKJXo.js} +6 -6
  190. package/dist/plugin-sdk/{send-Du8ykP1k.js → send-DCO441U7.js} +8 -8
  191. package/dist/plugin-sdk/{send-5nFktR1n.js → send-gDoGA-7e.js} +5 -5
  192. package/dist/plugin-sdk/{send-Bfzf11VY.js → send-q9HXrSwK.js} +7 -7
  193. package/dist/plugin-sdk/{session-CS-Td9EM.js → session-DHD4ZKyG.js} +2 -2
  194. package/dist/plugin-sdk/{skill-commands-CFAlXWHk.js → skill-commands-FKEPLS7T.js} +201 -26
  195. package/dist/plugin-sdk/{slack-CxE1mfzj.js → slack-BHmvqgjH.js} +39 -39
  196. package/dist/plugin-sdk/{slack-actions-BcMkNv1Z.js → slack-actions-DhbMcp8M.js} +11 -11
  197. package/dist/plugin-sdk/slack.d.ts +6 -6
  198. package/dist/plugin-sdk/slack.js +9 -9
  199. package/dist/plugin-sdk/{sticker-cache-CGzGWu00.js → sticker-cache-By5AcorL.js} +3 -3
  200. package/dist/plugin-sdk/{tables-bFXyRpkx.js → tables-B3jr0Pvq.js} +1 -1
  201. package/dist/plugin-sdk/{targets-DH7a9lKB.js → targets-CtSbTxYX.js} +1 -1
  202. package/dist/plugin-sdk/{telegram-actions-DaEcYQ8r.js → telegram-actions-DGnBz1YT.js} +30 -30
  203. package/dist/plugin-sdk/telegram.d.ts +6 -6
  204. package/dist/plugin-sdk/telegram.js +8 -8
  205. package/dist/plugin-sdk/{thread-bindings.lifecycle-CgOvvdw8.js → thread-bindings.lifecycle-QbkNl-m6.js} +3 -3
  206. package/dist/plugin-sdk/{thread-bindings.state-CQpk44Hq.js → thread-bindings.state-D9hg_M1c.js} +2 -2
  207. package/dist/plugin-sdk/tmp-fased-dir-EJGTmL1Q.d.ts +486 -0
  208. package/dist/plugin-sdk/{types-vcJrC_uv.d.ts → types-BdwdFCD6.d.ts} +2 -3
  209. package/dist/plugin-sdk/{types-DFAW-n1J.d.ts → types-BrCpYMxn.d.ts} +2 -2
  210. package/dist/plugin-sdk/{types-DyhXnYUr.d.ts → types-D0kDG8l0.d.ts} +3 -2
  211. package/dist/plugin-sdk/{types.plugin-_fbu40Re.d.ts → types.plugin-BcSBq42x.d.ts} +8 -3
  212. package/dist/plugin-sdk/{web-CInY-lCv.js → web-DUJwrTYs.js} +32 -32
  213. package/dist/plugin-sdk/{whatsapp-actions-BtSc2CBv.js → whatsapp-actions-Bj_rOncr.js} +13 -13
  214. package/dist/plugin-sdk/{whatsapp-heartbeat-Bg9TuYzl.js → whatsapp-heartbeat-B1WHkJIg.js} +2 -2
  215. package/dist/plugin-sdk/whatsapp.d.ts +13 -13
  216. package/dist/plugin-sdk/whatsapp.js +12 -12
  217. package/dist/plugin-sdk/{wsl-C4DGFkOd.js → wsl-J-HscWxS.js} +3 -3
  218. package/dist/plugin-sdk/{zod-schema.providers-core-BEbNizPe.d.ts → zod-schema.providers-core-CIzCjXH9.d.ts} +61 -61
  219. package/dist/providers/refresh.js +1 -1
  220. package/dist/providers/registry.js +1 -1
  221. package/dist/secrets/apply.js +1 -1
  222. package/dist/secrets/runtime.js +1 -1
  223. package/dist/wallet/external-submission-ledger.js +376 -0
  224. package/dist/wallet/legacy-embedded-keystore.js +40 -0
  225. package/dist/wallet/local-socket-signer-archive.js +30 -0
  226. package/dist/wallet/local-socket-signer-lifecycle.js +97 -0
  227. package/dist/wallet/local-socket-signer-policy.js +166 -0
  228. package/dist/wallet/local-socket-signer-protocol.js +578 -117
  229. package/dist/wallet/native-signer-wallet-id.js +25 -0
  230. package/dist/wallet/providers/alchemy-adapter.js +3 -0
  231. package/dist/wallet/providers/local-socket-signer-adapter.js +380 -105
  232. package/dist/wallet/providers/turnkey-adapter.js +292 -34
  233. package/dist/wallet/providers/wallet-standard-adapter.js +100 -0
  234. package/dist/wallet/signer-network-admin.js +184 -0
  235. package/dist/wallet/signer-protocol-v2.generated.js +92 -0
  236. package/dist/wallet/solana-bond-signing.js +157 -69
  237. package/dist/wallet/solana-reviewed-transaction.js +375 -0
  238. package/dist/wallet/solana-swap.js +520 -64
  239. package/dist/wallet/solana-transaction-inspection.js +106 -4
  240. package/dist/wallet/solana-trigger.js +658 -320
  241. package/dist/wallet/turnkey-reviewed-state.js +370 -0
  242. package/dist/wallet/wallet-approval-auth.js +17 -28
  243. package/dist/wallet/wallet-atomic-state.js +53 -0
  244. package/dist/wallet/wallet-canary.js +0 -1
  245. package/dist/wallet/wallet-inbound-events.js +16 -11
  246. package/dist/wallet/wallet-policy-simulation.js +1 -1
  247. package/dist/wallet/wallet-policy.js +93 -37
  248. package/dist/wallet/wallet-provider-capabilities.js +28 -4
  249. package/dist/wallet/wallet-provider-registry.js +57 -44
  250. package/dist/wallet/wallet-provider-resolver.js +62 -63
  251. package/dist/wallet/wallet-runtime-config.js +28 -41
  252. package/dist/wallet/wallet-secrets-store.js +22 -0
  253. package/dist/wallet/wallet-send-approvals.js +1891 -589
  254. package/dist/wallet/wallet-send-execution-ledger.js +292 -0
  255. package/dist/wallet/wallet-settlement-links.js +14 -13
  256. package/dist/wallet/wallet-standard-review.js +353 -0
  257. package/dist/wallet/wallet-status.js +0 -9
  258. package/dist/wallet/wallet-task-ledger.js +16 -2
  259. package/dist/web/auto-reply/heartbeat-runner.js +1 -1
  260. package/dist/web/auto-reply/monitor.js +2 -2
  261. package/dist/wizard/host-security-capability.js +14 -23
  262. package/dist/wizard/onboarding.finalize.js +63 -184
  263. package/dist/wizard/onboarding.host-security.js +117 -1367
  264. package/dist/wizard/onboarding.js +172 -217
  265. package/dist/wizard/onboarding.wallet.js +232 -785
  266. package/extensions/acpx/package.json +1 -1
  267. package/extensions/bluebubbles/package.json +1 -1
  268. package/extensions/copilot-proxy/package.json +1 -1
  269. package/extensions/diagnostics-otel/package.json +1 -1
  270. package/extensions/fased-federation/package.json +1 -1
  271. package/extensions/google-gemini-cli-auth/package.json +1 -1
  272. package/extensions/imessage/package.json +1 -1
  273. package/extensions/irc/package.json +1 -1
  274. package/extensions/line/package.json +1 -1
  275. package/extensions/llm-task/package.json +1 -1
  276. package/extensions/lobster/package.json +1 -1
  277. package/extensions/matrix/CHANGELOG.md +18 -0
  278. package/extensions/matrix/package.json +1 -1
  279. package/extensions/mattermost/package.json +1 -1
  280. package/extensions/memory-core/package.json +2 -2
  281. package/extensions/memory-lancedb/package.json +1 -1
  282. package/extensions/minimax-portal-auth/package.json +1 -1
  283. package/extensions/msteams/CHANGELOG.md +18 -0
  284. package/extensions/msteams/package.json +1 -1
  285. package/extensions/nextcloud-talk/package.json +1 -1
  286. package/extensions/nostr/CHANGELOG.md +18 -0
  287. package/extensions/nostr/package.json +1 -1
  288. package/extensions/open-prose/package.json +1 -1
  289. package/extensions/sat-mining/index.ts +587 -154
  290. package/extensions/sat-mining/package.json +1 -1
  291. package/extensions/sat-mining/signer-codec-schema.v1.json +374 -0
  292. package/extensions/sat-mining/src/audit-store.ts +91 -5
  293. package/extensions/sat-mining/src/claim-service.ts +85 -14
  294. package/extensions/sat-mining/src/client.ts +13 -0
  295. package/extensions/sat-mining/src/config.ts +9 -0
  296. package/extensions/sat-mining/src/cycle-progress.ts +16 -8
  297. package/extensions/sat-mining/src/epoch-service.ts +9 -5
  298. package/extensions/sat-mining/src/gateway-runner.ts +21 -1
  299. package/extensions/sat-mining/src/protocol-contract.ts +45 -1
  300. package/extensions/sat-mining/src/recovery-service.ts +312 -0
  301. package/extensions/sat-mining/src/round-watcher.ts +391 -81
  302. package/extensions/sat-mining/src/rpc-read.ts +431 -106
  303. package/extensions/sat-mining/src/runtime.ts +16 -0
  304. package/extensions/sat-mining/src/sat-bond-layout.ts +6 -0
  305. package/extensions/sat-mining/src/signer-codec-manifest.ts +429 -0
  306. package/extensions/sat-mining/src/solana-submit.ts +1544 -436
  307. package/extensions/sat-mining/src/submission-ledger.ts +434 -0
  308. package/extensions/signal/package.json +1 -1
  309. package/extensions/synology-chat/package.json +1 -1
  310. package/extensions/tlon/package.json +1 -1
  311. package/extensions/twitch/CHANGELOG.md +18 -0
  312. package/extensions/twitch/package.json +1 -1
  313. package/extensions/voice-call/CHANGELOG.md +18 -0
  314. package/extensions/voice-call/package.json +1 -1
  315. package/extensions/zalo/CHANGELOG.md +18 -0
  316. package/extensions/zalo/package.json +1 -1
  317. package/extensions/zalouser/CHANGELOG.md +18 -0
  318. package/extensions/zalouser/package.json +1 -1
  319. package/install.sh +4951 -0
  320. package/package.json +23 -5
  321. package/scripts/fased-host-updater.mjs +1421 -0
  322. package/scripts/fased-host-updaterctl.mjs +186 -0
  323. package/scripts/fased-managed-service.sh +36 -0
  324. package/scripts/fased-managed-updater.mjs +3065 -156
  325. package/scripts/fased-signer-enroll-hosting.sh +275 -0
  326. package/scripts/fased-signer-network-hosting.sh +143 -0
  327. package/scripts/fased-signer-owner-policy.mjs +1442 -0
  328. package/scripts/fased-signer-policy-hosting.sh +50 -0
  329. package/scripts/fased-signer-policy-local.sh +26 -0
  330. package/scripts/hosted-release-manifest.mjs +185 -0
  331. package/scripts/install-fased-signerd.sh +183 -108
  332. package/scripts/install-managed-runtime.mjs +212 -10
  333. package/scripts/managed-runtime-layout.mjs +75 -3
  334. package/scripts/migrate-hosted-signer-v2.mjs +58 -0
  335. package/scripts/start-managed.sh +173 -360
  336. package/dist/control-ui/assets/mining-commit-R-6nu87p.js +0 -2
  337. package/dist/plugin-sdk/tmp-fased-dir-CS6zsYEE.d.ts +0 -77
  338. package/dist/wallet/local-socket-signer-broker.js +0 -224
  339. package/dist/wallet/local-socket-signer-custody.js +0 -42
  340. package/dist/wallet/providers/embedded-keystore-adapter.js +0 -402
  341. package/dist/wallet/providers/privy-adapter.js +0 -80
  342. package/dist/wallet/wallet-custody.js +0 -1836
@@ -3,6 +3,7 @@ import { readWalletProviderRegistry, resolveWalletUserRole } from "../wallet/wal
3
3
  import { listLocalMarketplaceOrders, upsertMarketplaceOrderConfig } from "./offers.js";
4
4
  import { assertValidSolanaAddress } from "../wallet/solana-address.js";
5
5
  import { createOrExecuteWalletSend } from "../wallet/wallet-send-approvals.js";
6
+ import { claimMarketplaceSettlementOrder, getMarketplaceSettlementEntry, reserveMarketplaceSettlementAction, updateMarketplaceSettlementAction } from "./marketplace-settlement-ledger.js";
6
7
 
7
8
  //#region src/federation/marketplace-escrow.ts
8
9
  const DEFAULT_DEPS = {
@@ -10,12 +11,13 @@ const DEFAULT_DEPS = {
10
11
  resolveWalletRuntimeConfig,
11
12
  createOrExecuteWalletSend
12
13
  };
13
- function fail(statusCode, code, message) {
14
+ function fail(statusCode, code, message, details = {}) {
14
15
  return {
15
16
  ok: false,
16
17
  statusCode,
17
18
  code,
18
- message
19
+ message,
20
+ ...details
19
21
  };
20
22
  }
21
23
  function trimString(value) {
@@ -133,6 +135,65 @@ function sendModeAndRefs(send) {
133
135
  }
134
136
  return { mode: "manual" };
135
137
  }
138
+ function cachedEscrowActionRefs(action) {
139
+ if (action.state !== "executed" && action.state !== "complete" || !action.txHash) {
140
+ return null;
141
+ }
142
+ return {
143
+ mode: "autonomous",
144
+ requestId: action.requestId,
145
+ txHash: action.txHash
146
+ };
147
+ }
148
+ function escrowInitialPhase(order) {
149
+ const escrow = order.settlement?.escrow;
150
+ if (escrow?.status === "released" || escrow?.releaseTxRef) {
151
+ return "released";
152
+ }
153
+ if (escrow?.status === "refunded" || escrow?.refundTxRef) {
154
+ return "refunded";
155
+ }
156
+ if (escrow?.releaseRequestId) {
157
+ return "release_pending";
158
+ }
159
+ if (escrow?.refundRequestId) {
160
+ return "refund_pending";
161
+ }
162
+ if (escrow?.status === "held" || escrow?.status === "funded" || escrow?.fundingTxRef || order.settlement?.status === "held") {
163
+ return "held";
164
+ }
165
+ if (escrow?.fundingRequestId || order.settlement?.status === "submitted") {
166
+ return "fund_pending";
167
+ }
168
+ if (escrow?.status === "cancelled" || order.settlement?.status === "cancelled") {
169
+ return "cancelled";
170
+ }
171
+ return "open";
172
+ }
173
+ function isAmbiguousSendFailure(code) {
174
+ return code === "wallet_provider_ambiguous" || code === "wallet_send_in_progress";
175
+ }
176
+ function failForExistingUnknown(params) {
177
+ const action = getMarketplaceSettlementEntry({
178
+ orderId: params.orderId,
179
+ env: params.env
180
+ })?.actions[params.action];
181
+ if (action?.state !== "unknown") {
182
+ return null;
183
+ }
184
+ return fail(409, "escrow_settlement_unknown", action.reason || `escrow ${params.action} result is unknown; reconcile it before retrying`, {
185
+ state: "unknown",
186
+ requestId: action.requestId,
187
+ txHash: action.txHash
188
+ });
189
+ }
190
+ async function claimEscrowOrder(params) {
191
+ try {
192
+ return await claimMarketplaceSettlementOrder(params.orderId, params.env);
193
+ } catch (error) {
194
+ return fail(409, "escrow_settlement_in_progress", error instanceof Error ? error.message : String(error), { state: "pending" });
195
+ }
196
+ }
136
197
  async function fundMarketplaceSolanaEscrow(params) {
137
198
  const env = params.env ?? process.env;
138
199
  const deps = {
@@ -167,89 +228,179 @@ async function fundMarketplaceSolanaEscrow(params) {
167
228
  if (!walletConfig.enabled) {
168
229
  return fail(409, "wallet_disabled", "wallet runtime is disabled");
169
230
  }
170
- const invoiceId = trimString(order.settlement?.invoiceId ?? order.receipt?.invoiceId ?? order.invoiceId);
171
- const send = await deps.createOrExecuteWalletSend({
172
- payload: {
173
- chain: "solana",
174
- to: vault.address,
175
- amount: validated.amountLamports,
176
- walletId: payerWallet.id,
177
- walletName: payerWallet.name,
178
- providerId: payerWallet.providerId,
179
- memo: invoiceId || `escrow-fund:${entry.configId}`
180
- },
181
- requestedBy: params.actor?.trim() || "marketplace-escrow",
182
- sendPath: params.sendPath ?? "automation",
183
- settlementContext: {
184
- taskId: `marketplace-escrow-fund:${entry.configId}`,
185
- ...invoiceId ? { invoiceId } : {},
186
- ...trimString(order.buyerHandle) ? { senderHandle: trimString(order.buyerHandle) } : {}
187
- },
188
- config: walletConfig,
189
- runtimeConfig: params.config,
190
- providerIdOverride: payerWallet.providerId,
231
+ const claim = await claimEscrowOrder({
232
+ orderId: entry.configId,
191
233
  env
192
234
  });
193
- if (!send.ok) {
194
- return fail(409, send.code, send.message);
235
+ if (typeof claim !== "function") {
236
+ return claim;
195
237
  }
196
- const now = params.now ?? new Date().toISOString();
197
- const refs = sendModeAndRefs(send);
198
- const status = refs.txHash ? "held" : "submitted";
199
- const result = updateOrder({
200
- config: params.config,
201
- now,
202
- order: {
203
- ...order,
204
- status: refs.txHash ? "funded" : order.status,
205
- paymentIntent: {
206
- ...order.paymentIntent,
207
- status: refs.txHash ? "verified" : "submitted",
208
- txRef: refs.txHash ?? order.paymentIntent?.txRef,
209
- payerWalletId: payerWallet.id,
210
- updatedAt: now
211
- },
212
- settlement: {
213
- ...order.settlement,
214
- mode: "escrow",
215
- status,
216
- amount: order.settlement?.amount ?? order.paymentIntent?.amount,
217
- currency: "SOL",
218
- chain: "solana",
219
- assetKind: "native",
220
- payerWalletId: payerWallet.id,
221
- txRef: refs.txHash ?? order.settlement?.txRef,
222
- escrow: {
223
- ...order.settlement?.escrow,
224
- status: refs.txHash ? "held" : "required",
225
- holdPolicy: order.settlement?.escrow?.holdPolicy ?? "release_on_delivery",
226
- releaseRequired: true,
238
+ try {
239
+ const escrow = order.settlement?.escrow;
240
+ if (escrow?.fundingTxRef || escrow?.status === "funded" || escrow?.status === "held" || order.settlement?.status === "held") {
241
+ return fail(409, "escrow_already_funded", "escrow is already funded and must not be paid again", { txHash: escrow?.fundingTxRef ?? order.settlement?.txRef });
242
+ }
243
+ const currentLedger = getMarketplaceSettlementEntry({
244
+ orderId: entry.configId,
245
+ env
246
+ });
247
+ if (escrow?.fundingRequestId && !currentLedger?.actions.fund) {
248
+ return fail(409, "escrow_settlement_unknown", "an older escrow funding request exists without a durable settlement record; reconcile or reject it before retrying", {
249
+ state: "unknown",
250
+ requestId: escrow.fundingRequestId
251
+ });
252
+ }
253
+ const executionIntentId = `marketplace-order:${entry.configId}:escrow-fund`;
254
+ let workflow;
255
+ try {
256
+ workflow = reserveMarketplaceSettlementAction({
257
+ orderId: entry.configId,
258
+ action: "fund",
259
+ executionIntentId,
260
+ initialPhase: escrowInitialPhase(order),
261
+ intent: {
262
+ chain: "solana",
263
+ assetKind: "native",
264
+ amount: validated.amountLamports,
265
+ payerWalletId: payerWallet.id,
227
266
  vaultWalletId: vault.wallet.id,
228
- vaultWalletName: vault.wallet.name,
229
- vaultAddress: vault.address,
230
- ...refs.requestId ? { fundingRequestId: refs.requestId } : {},
231
- ...refs.txHash ? {
232
- fundingTxRef: refs.txHash,
233
- fundedAt: now
234
- } : {},
235
- updatedAt: now
267
+ vaultAddress: vault.address
236
268
  },
237
- notes: refs.txHash ? "Escrow funded with native SOL and held for release." : "Escrow funding approval request was created.",
238
- updatedAt: now,
239
- ...refs.txHash ? { verifiedAt: now } : {}
269
+ env
270
+ });
271
+ } catch (error) {
272
+ return fail(409, "escrow_settlement_conflict", error instanceof Error ? error.message : String(error));
273
+ }
274
+ const unknown = failForExistingUnknown({
275
+ orderId: entry.configId,
276
+ action: "fund",
277
+ env
278
+ });
279
+ if (unknown) {
280
+ return unknown;
281
+ }
282
+ const invoiceId = trimString(order.settlement?.invoiceId ?? order.receipt?.invoiceId ?? order.invoiceId);
283
+ let refs = cachedEscrowActionRefs(workflow.action);
284
+ if (!refs) {
285
+ updateMarketplaceSettlementAction({
286
+ orderId: entry.configId,
287
+ action: "fund",
288
+ expectedStates: [
289
+ "reserved",
290
+ "pending",
291
+ "failed"
292
+ ],
293
+ state: "pending",
294
+ env
295
+ });
296
+ const send = await deps.createOrExecuteWalletSend({
297
+ payload: {
298
+ chain: "solana",
299
+ to: vault.address,
300
+ amount: validated.amountLamports,
301
+ walletId: payerWallet.id,
302
+ walletName: payerWallet.name,
303
+ providerId: payerWallet.providerId
304
+ },
305
+ requestedBy: params.actor?.trim() || "marketplace-escrow",
306
+ executionIntentId,
307
+ sendPath: params.sendPath ?? "automation",
308
+ settlementContext: {
309
+ taskId: `marketplace-escrow-fund:${entry.configId}`,
310
+ ...invoiceId ? { invoiceId } : {},
311
+ ...trimString(order.buyerHandle) ? { senderHandle: trimString(order.buyerHandle) } : {}
312
+ },
313
+ config: walletConfig,
314
+ runtimeConfig: params.config,
315
+ providerIdOverride: payerWallet.providerId,
316
+ env
317
+ });
318
+ if (!send.ok) {
319
+ const ambiguous = isAmbiguousSendFailure(send.code);
320
+ updateMarketplaceSettlementAction({
321
+ orderId: entry.configId,
322
+ action: "fund",
323
+ expectedStates: ["pending"],
324
+ state: ambiguous ? "unknown" : "failed",
325
+ requestId: send.requestId,
326
+ reason: send.message,
327
+ env
328
+ });
329
+ return fail(409, send.code, send.message, {
330
+ state: ambiguous ? "unknown" : undefined,
331
+ requestId: send.requestId
332
+ });
240
333
  }
334
+ refs = sendModeAndRefs(send);
335
+ updateMarketplaceSettlementAction({
336
+ orderId: entry.configId,
337
+ action: "fund",
338
+ expectedStates: ["pending"],
339
+ state: refs.txHash ? "complete" : "pending",
340
+ requestId: refs.requestId,
341
+ txHash: refs.txHash,
342
+ env
343
+ });
241
344
  }
242
- });
243
- return {
244
- ok: true,
245
- config: result.config,
246
- order: result.order,
247
- mode: refs.mode,
248
- requestId: refs.requestId,
249
- txHash: refs.txHash,
250
- status,
251
- message: refs.txHash ? "Solana escrow funded and held." : "Solana escrow funding queued."
252
- };
345
+ const now = params.now ?? new Date().toISOString();
346
+ const status = refs.txHash ? "held" : "submitted";
347
+ const result = updateOrder({
348
+ config: params.config,
349
+ now,
350
+ order: {
351
+ ...order,
352
+ status: refs.txHash ? "funded" : order.status,
353
+ paymentIntent: {
354
+ ...order.paymentIntent,
355
+ status: refs.txHash ? "verified" : "submitted",
356
+ txRef: refs.txHash ?? order.paymentIntent?.txRef,
357
+ payerWalletId: payerWallet.id,
358
+ updatedAt: now
359
+ },
360
+ settlement: {
361
+ ...order.settlement,
362
+ mode: "escrow",
363
+ status,
364
+ amount: order.settlement?.amount ?? order.paymentIntent?.amount,
365
+ currency: "SOL",
366
+ chain: "solana",
367
+ assetKind: "native",
368
+ payerWalletId: payerWallet.id,
369
+ txRef: refs.txHash ?? order.settlement?.txRef,
370
+ escrow: {
371
+ ...escrow,
372
+ status: refs.txHash ? "held" : "required",
373
+ holdPolicy: escrow?.holdPolicy ?? "release_on_delivery",
374
+ releaseRequired: true,
375
+ vaultWalletId: vault.wallet.id,
376
+ vaultWalletName: vault.wallet.name,
377
+ vaultAddress: vault.address,
378
+ ...refs.requestId ? { fundingRequestId: refs.requestId } : {},
379
+ ...refs.txHash ? {
380
+ fundingTxRef: refs.txHash,
381
+ fundedAt: now
382
+ } : {},
383
+ updatedAt: now
384
+ },
385
+ notes: refs.txHash ? "Escrow funded with native SOL and held for release." : "Escrow funding approval request was created.",
386
+ updatedAt: now,
387
+ ...refs.txHash ? { verifiedAt: now } : {}
388
+ }
389
+ }
390
+ });
391
+ return {
392
+ ok: true,
393
+ config: result.config,
394
+ order: result.order,
395
+ mode: refs.mode,
396
+ requestId: refs.requestId,
397
+ txHash: refs.txHash,
398
+ status,
399
+ message: refs.txHash ? "Solana escrow funded and held." : "Solana escrow funding queued."
400
+ };
401
+ } finally {
402
+ await claim();
403
+ }
253
404
  }
254
405
  async function releaseMarketplaceSolanaEscrow(params) {
255
406
  const env = params.env ?? process.env;
@@ -289,73 +440,160 @@ async function releaseMarketplaceSolanaEscrow(params) {
289
440
  if (!walletConfig.enabled) {
290
441
  return fail(409, "wallet_disabled", "wallet runtime is disabled");
291
442
  }
292
- const invoiceId = trimString(order.settlement?.invoiceId ?? order.receipt?.invoiceId ?? order.invoiceId);
293
- const send = await deps.createOrExecuteWalletSend({
294
- payload: {
295
- chain: "solana",
296
- to: validated.payeeAddress,
297
- amount: validated.amountLamports,
298
- walletId: vault.wallet.id,
299
- walletName: vault.wallet.name,
300
- providerId: vault.wallet.providerId,
301
- memo: invoiceId || `escrow-release:${entry.configId}`
302
- },
303
- requestedBy: params.actor?.trim() || "marketplace-escrow",
304
- sendPath: params.sendPath ?? "reviewed",
305
- settlementContext: {
306
- taskId: `marketplace-escrow-release:${entry.configId}`,
307
- ...invoiceId ? { invoiceId } : {},
308
- ...trimString(order.buyerHandle) ? { senderHandle: trimString(order.buyerHandle) } : {}
309
- },
310
- config: walletConfig,
311
- runtimeConfig: params.config,
312
- providerIdOverride: vault.wallet.providerId,
443
+ const claim = await claimEscrowOrder({
444
+ orderId: entry.configId,
313
445
  env
314
446
  });
315
- if (!send.ok) {
316
- return fail(409, send.code, send.message);
447
+ if (typeof claim !== "function") {
448
+ return claim;
317
449
  }
318
- const now = params.now ?? new Date().toISOString();
319
- const refs = sendModeAndRefs(send);
320
- const released = Boolean(refs.txHash);
321
- const result = updateOrder({
322
- config: params.config,
323
- now,
324
- order: {
325
- ...order,
326
- status: released ? "closed" : order.status,
327
- settlement: {
328
- ...order.settlement,
329
- mode: "escrow",
330
- status: released ? "released" : "held",
331
- escrow: {
332
- ...order.settlement?.escrow,
333
- status: released ? "released" : "held",
334
- holdPolicy,
335
- releaseRequired: !released,
336
- ...refs.requestId ? { releaseRequestId: refs.requestId } : {},
337
- ...refs.txHash ? {
338
- releaseTxRef: refs.txHash,
339
- releasedAt: now
340
- } : {},
341
- updatedAt: now
450
+ try {
451
+ const escrow = order.settlement?.escrow;
452
+ const currentLedger = getMarketplaceSettlementEntry({
453
+ orderId: entry.configId,
454
+ env
455
+ });
456
+ if (escrow?.releaseRequestId && !currentLedger?.actions.release) {
457
+ return fail(409, "escrow_settlement_unknown", "an older escrow release request exists without a durable settlement record; reconcile it before retrying", {
458
+ state: "unknown",
459
+ requestId: escrow.releaseRequestId
460
+ });
461
+ }
462
+ const executionIntentId = `marketplace-order:${entry.configId}:escrow-release`;
463
+ let workflow;
464
+ try {
465
+ workflow = reserveMarketplaceSettlementAction({
466
+ orderId: entry.configId,
467
+ action: "release",
468
+ executionIntentId,
469
+ initialPhase: escrowInitialPhase(order),
470
+ intent: {
471
+ chain: "solana",
472
+ assetKind: "native",
473
+ amount: validated.amountLamports,
474
+ vaultWalletId: vault.wallet.id,
475
+ vaultAddress: vault.address,
476
+ payeeAddress: validated.payeeAddress
477
+ },
478
+ env
479
+ });
480
+ } catch (error) {
481
+ return fail(409, "escrow_settlement_conflict", error instanceof Error ? error.message : String(error));
482
+ }
483
+ const unknown = failForExistingUnknown({
484
+ orderId: entry.configId,
485
+ action: "release",
486
+ env
487
+ });
488
+ if (unknown) {
489
+ return unknown;
490
+ }
491
+ const invoiceId = trimString(order.settlement?.invoiceId ?? order.receipt?.invoiceId ?? order.invoiceId);
492
+ let refs = cachedEscrowActionRefs(workflow.action);
493
+ if (!refs) {
494
+ updateMarketplaceSettlementAction({
495
+ orderId: entry.configId,
496
+ action: "release",
497
+ expectedStates: [
498
+ "reserved",
499
+ "pending",
500
+ "failed"
501
+ ],
502
+ state: "pending",
503
+ env
504
+ });
505
+ const send = await deps.createOrExecuteWalletSend({
506
+ payload: {
507
+ chain: "solana",
508
+ to: validated.payeeAddress,
509
+ amount: validated.amountLamports,
510
+ walletId: vault.wallet.id,
511
+ walletName: vault.wallet.name,
512
+ providerId: vault.wallet.providerId
342
513
  },
343
- notes: released ? "Escrow released to seller payee address." : "Escrow release approval request was created.",
344
- updatedAt: now,
345
- ...released ? { settledAt: now } : {}
514
+ requestedBy: params.actor?.trim() || "marketplace-escrow",
515
+ executionIntentId,
516
+ sendPath: params.sendPath ?? "reviewed",
517
+ settlementContext: {
518
+ taskId: `marketplace-escrow-release:${entry.configId}`,
519
+ ...invoiceId ? { invoiceId } : {},
520
+ ...trimString(order.buyerHandle) ? { senderHandle: trimString(order.buyerHandle) } : {}
521
+ },
522
+ config: walletConfig,
523
+ runtimeConfig: params.config,
524
+ providerIdOverride: vault.wallet.providerId,
525
+ env
526
+ });
527
+ if (!send.ok) {
528
+ const ambiguous = isAmbiguousSendFailure(send.code);
529
+ updateMarketplaceSettlementAction({
530
+ orderId: entry.configId,
531
+ action: "release",
532
+ expectedStates: ["pending"],
533
+ state: ambiguous ? "unknown" : "failed",
534
+ requestId: send.requestId,
535
+ reason: send.message,
536
+ env
537
+ });
538
+ return fail(409, send.code, send.message, {
539
+ state: ambiguous ? "unknown" : undefined,
540
+ requestId: send.requestId
541
+ });
346
542
  }
543
+ refs = sendModeAndRefs(send);
544
+ updateMarketplaceSettlementAction({
545
+ orderId: entry.configId,
546
+ action: "release",
547
+ expectedStates: ["pending"],
548
+ state: refs.txHash ? "complete" : "pending",
549
+ requestId: refs.requestId,
550
+ txHash: refs.txHash,
551
+ env
552
+ });
347
553
  }
348
- });
349
- return {
350
- ok: true,
351
- config: result.config,
352
- order: result.order,
353
- mode: refs.mode,
354
- requestId: refs.requestId,
355
- txHash: refs.txHash,
356
- status: released ? "released" : "held",
357
- message: released ? "Solana escrow released." : "Solana escrow release queued."
358
- };
554
+ const now = params.now ?? new Date().toISOString();
555
+ const released = Boolean(refs.txHash);
556
+ const result = updateOrder({
557
+ config: params.config,
558
+ now,
559
+ order: {
560
+ ...order,
561
+ status: released ? "closed" : order.status,
562
+ settlement: {
563
+ ...order.settlement,
564
+ mode: "escrow",
565
+ status: released ? "released" : "held",
566
+ escrow: {
567
+ ...escrow,
568
+ status: released ? "released" : "held",
569
+ holdPolicy,
570
+ releaseRequired: !released,
571
+ ...refs.requestId ? { releaseRequestId: refs.requestId } : {},
572
+ ...refs.txHash ? {
573
+ releaseTxRef: refs.txHash,
574
+ releasedAt: now
575
+ } : {},
576
+ updatedAt: now
577
+ },
578
+ notes: released ? "Escrow released to seller payee address." : "Escrow release approval request was created.",
579
+ updatedAt: now,
580
+ ...released ? { settledAt: now } : {}
581
+ }
582
+ }
583
+ });
584
+ return {
585
+ ok: true,
586
+ config: result.config,
587
+ order: result.order,
588
+ mode: refs.mode,
589
+ requestId: refs.requestId,
590
+ txHash: refs.txHash,
591
+ status: released ? "released" : "held",
592
+ message: released ? "Solana escrow released." : "Solana escrow release queued."
593
+ };
594
+ } finally {
595
+ await claim();
596
+ }
359
597
  }
360
598
  async function refundMarketplaceSolanaEscrow(params) {
361
599
  const env = params.env ?? process.env;
@@ -402,85 +640,174 @@ async function refundMarketplaceSolanaEscrow(params) {
402
640
  if (!walletConfig.enabled) {
403
641
  return fail(409, "wallet_disabled", "wallet runtime is disabled");
404
642
  }
405
- const invoiceId = trimString(order.settlement?.invoiceId ?? order.receipt?.invoiceId ?? order.invoiceId);
406
- const send = await deps.createOrExecuteWalletSend({
407
- payload: {
408
- chain: "solana",
409
- to: payerAddress,
410
- amount: validated.amountLamports,
411
- walletId: vault.wallet.id,
412
- walletName: vault.wallet.name,
413
- providerId: vault.wallet.providerId,
414
- memo: invoiceId || `escrow-refund:${entry.configId}`
415
- },
416
- requestedBy: params.actor?.trim() || "marketplace-escrow",
417
- sendPath: params.sendPath ?? "reviewed",
418
- settlementContext: {
419
- taskId: `marketplace-escrow-refund:${entry.configId}`,
420
- ...invoiceId ? { invoiceId } : {},
421
- ...trimString(order.buyerHandle) ? { senderHandle: trimString(order.buyerHandle) } : {}
422
- },
423
- config: walletConfig,
424
- runtimeConfig: params.config,
425
- providerIdOverride: vault.wallet.providerId,
643
+ const claim = await claimEscrowOrder({
644
+ orderId: entry.configId,
426
645
  env
427
646
  });
428
- if (!send.ok) {
429
- return fail(409, send.code, send.message);
647
+ if (typeof claim !== "function") {
648
+ return claim;
430
649
  }
431
- const now = params.now ?? new Date().toISOString();
432
- const refs = sendModeAndRefs(send);
433
- const refunded = Boolean(refs.txHash);
434
- const result = updateOrder({
435
- config: params.config,
436
- now,
437
- order: {
438
- ...order,
439
- status: refunded ? "cancelled" : order.status,
440
- paymentIntent: {
441
- ...order.paymentIntent,
442
- status: refunded ? "cancelled" : order.paymentIntent?.status,
443
- payerWalletId: payerWallet.id,
444
- updatedAt: now
445
- },
446
- settlement: {
447
- ...order.settlement,
448
- mode: "escrow",
449
- status: refunded ? "cancelled" : "held",
450
- payerWalletId: payerWallet.id,
451
- escrow: {
452
- ...order.settlement?.escrow,
453
- status: refunded ? "refunded" : "held",
454
- holdPolicy: order.settlement?.escrow?.holdPolicy ?? "release_on_delivery",
455
- releaseRequired: !refunded,
650
+ try {
651
+ const escrow = order.settlement?.escrow;
652
+ const currentLedger = getMarketplaceSettlementEntry({
653
+ orderId: entry.configId,
654
+ env
655
+ });
656
+ if (escrow?.refundRequestId && !currentLedger?.actions.refund) {
657
+ return fail(409, "escrow_settlement_unknown", "an older escrow refund request exists without a durable settlement record; reconcile it before retrying", {
658
+ state: "unknown",
659
+ requestId: escrow.refundRequestId
660
+ });
661
+ }
662
+ const executionIntentId = `marketplace-order:${entry.configId}:escrow-refund`;
663
+ let workflow;
664
+ try {
665
+ workflow = reserveMarketplaceSettlementAction({
666
+ orderId: entry.configId,
667
+ action: "refund",
668
+ executionIntentId,
669
+ initialPhase: escrowInitialPhase(order),
670
+ intent: {
671
+ chain: "solana",
672
+ assetKind: "native",
673
+ amount: validated.amountLamports,
456
674
  vaultWalletId: vault.wallet.id,
457
- vaultWalletName: vault.wallet.name,
458
675
  vaultAddress: vault.address,
459
- ...refs.requestId ? { refundRequestId: refs.requestId } : {},
460
- ...refs.txHash ? {
461
- refundTxRef: refs.txHash,
462
- refundedAt: now
463
- } : {},
464
- updatedAt: now
676
+ payerWalletId: payerWallet.id,
677
+ payerAddress
465
678
  },
466
- notes: refunded ? "Escrow refunded to the Agent payer wallet." : "Escrow refund approval request was created.",
467
- updatedAt: now,
468
- ...refunded ? { settledAt: now } : {}
679
+ env
680
+ });
681
+ } catch (error) {
682
+ return fail(409, "escrow_settlement_conflict", error instanceof Error ? error.message : String(error));
683
+ }
684
+ const unknown = failForExistingUnknown({
685
+ orderId: entry.configId,
686
+ action: "refund",
687
+ env
688
+ });
689
+ if (unknown) {
690
+ return unknown;
691
+ }
692
+ const invoiceId = trimString(order.settlement?.invoiceId ?? order.receipt?.invoiceId ?? order.invoiceId);
693
+ let refs = cachedEscrowActionRefs(workflow.action);
694
+ if (!refs) {
695
+ updateMarketplaceSettlementAction({
696
+ orderId: entry.configId,
697
+ action: "refund",
698
+ expectedStates: [
699
+ "reserved",
700
+ "pending",
701
+ "failed"
702
+ ],
703
+ state: "pending",
704
+ env
705
+ });
706
+ const send = await deps.createOrExecuteWalletSend({
707
+ payload: {
708
+ chain: "solana",
709
+ to: payerAddress,
710
+ amount: validated.amountLamports,
711
+ walletId: vault.wallet.id,
712
+ walletName: vault.wallet.name,
713
+ providerId: vault.wallet.providerId
714
+ },
715
+ requestedBy: params.actor?.trim() || "marketplace-escrow",
716
+ executionIntentId,
717
+ sendPath: params.sendPath ?? "reviewed",
718
+ settlementContext: {
719
+ taskId: `marketplace-escrow-refund:${entry.configId}`,
720
+ ...invoiceId ? { invoiceId } : {},
721
+ ...trimString(order.buyerHandle) ? { senderHandle: trimString(order.buyerHandle) } : {}
722
+ },
723
+ config: walletConfig,
724
+ runtimeConfig: params.config,
725
+ providerIdOverride: vault.wallet.providerId,
726
+ env
727
+ });
728
+ if (!send.ok) {
729
+ const ambiguous = isAmbiguousSendFailure(send.code);
730
+ updateMarketplaceSettlementAction({
731
+ orderId: entry.configId,
732
+ action: "refund",
733
+ expectedStates: ["pending"],
734
+ state: ambiguous ? "unknown" : "failed",
735
+ requestId: send.requestId,
736
+ reason: send.message,
737
+ env
738
+ });
739
+ return fail(409, send.code, send.message, {
740
+ state: ambiguous ? "unknown" : undefined,
741
+ requestId: send.requestId
742
+ });
469
743
  }
744
+ refs = sendModeAndRefs(send);
745
+ updateMarketplaceSettlementAction({
746
+ orderId: entry.configId,
747
+ action: "refund",
748
+ expectedStates: ["pending"],
749
+ state: refs.txHash ? "complete" : "pending",
750
+ requestId: refs.requestId,
751
+ txHash: refs.txHash,
752
+ env
753
+ });
470
754
  }
471
- });
472
- return {
473
- ok: true,
474
- config: result.config,
475
- order: result.order,
476
- mode: refs.mode,
477
- requestId: refs.requestId,
478
- txHash: refs.txHash,
479
- status: refunded ? "refunded" : "held",
480
- message: refunded ? "Solana escrow refunded." : "Solana escrow refund queued."
481
- };
755
+ const now = params.now ?? new Date().toISOString();
756
+ const refunded = Boolean(refs.txHash);
757
+ const result = updateOrder({
758
+ config: params.config,
759
+ now,
760
+ order: {
761
+ ...order,
762
+ status: refunded ? "cancelled" : order.status,
763
+ paymentIntent: {
764
+ ...order.paymentIntent,
765
+ status: refunded ? "cancelled" : order.paymentIntent?.status,
766
+ payerWalletId: payerWallet.id,
767
+ updatedAt: now
768
+ },
769
+ settlement: {
770
+ ...order.settlement,
771
+ mode: "escrow",
772
+ status: refunded ? "cancelled" : "held",
773
+ payerWalletId: payerWallet.id,
774
+ escrow: {
775
+ ...escrow,
776
+ status: refunded ? "refunded" : "held",
777
+ holdPolicy: escrow?.holdPolicy ?? "release_on_delivery",
778
+ releaseRequired: !refunded,
779
+ vaultWalletId: vault.wallet.id,
780
+ vaultWalletName: vault.wallet.name,
781
+ vaultAddress: vault.address,
782
+ ...refs.requestId ? { refundRequestId: refs.requestId } : {},
783
+ ...refs.txHash ? {
784
+ refundTxRef: refs.txHash,
785
+ refundedAt: now
786
+ } : {},
787
+ updatedAt: now
788
+ },
789
+ notes: refunded ? "Escrow refunded to the Agent payer wallet." : "Escrow refund approval request was created.",
790
+ updatedAt: now,
791
+ ...refunded ? { settledAt: now } : {}
792
+ }
793
+ }
794
+ });
795
+ return {
796
+ ok: true,
797
+ config: result.config,
798
+ order: result.order,
799
+ mode: refs.mode,
800
+ requestId: refs.requestId,
801
+ txHash: refs.txHash,
802
+ status: refunded ? "refunded" : "held",
803
+ message: refunded ? "Solana escrow refunded." : "Solana escrow refund queued."
804
+ };
805
+ } finally {
806
+ await claim();
807
+ }
482
808
  }
483
809
  async function cancelMarketplaceSolanaEscrow(params) {
810
+ const env = params.env ?? process.env;
484
811
  const entry = findOrder(params.config, params.orderId);
485
812
  if (!entry) {
486
813
  return fail(404, "order_not_found", "marketplace order not found");
@@ -489,53 +816,84 @@ async function cancelMarketplaceSolanaEscrow(params) {
489
816
  if (order.settlement?.mode !== "escrow") {
490
817
  return fail(409, "escrow_not_enabled", "order settlement mode must be escrow");
491
818
  }
492
- const escrow = order.settlement.escrow;
493
- if (escrow?.status === "held" || escrow?.status === "funded" || escrow?.fundingTxRef || escrow?.refundRequestId || escrow?.releaseRequestId) {
494
- return fail(409, "escrow_refund_required", "funded escrow must be refunded, not cancelled");
495
- }
496
- if (escrow?.fundingRequestId) {
497
- return fail(409, "escrow_funding_pending", "escrow funding approval is pending; reject the wallet request before cancelling");
498
- }
499
- if (escrow?.status === "released" || escrow?.status === "refunded") {
500
- return fail(409, "escrow_already_closed", "closed escrow cannot be cancelled");
819
+ const claim = await claimEscrowOrder({
820
+ orderId: entry.configId,
821
+ env
822
+ });
823
+ if (typeof claim !== "function") {
824
+ return claim;
501
825
  }
502
- const now = params.now ?? new Date().toISOString();
503
- const result = updateOrder({
504
- config: params.config,
505
- now,
506
- order: {
507
- ...order,
508
- status: "cancelled",
509
- paymentIntent: {
510
- ...order.paymentIntent,
511
- status: "cancelled",
512
- updatedAt: now
513
- },
514
- settlement: {
515
- ...order.settlement,
516
- mode: "escrow",
826
+ try {
827
+ const escrow = order.settlement.escrow;
828
+ if (escrow?.status === "held" || escrow?.status === "funded" || escrow?.fundingTxRef || escrow?.refundRequestId || escrow?.releaseRequestId) {
829
+ return fail(409, "escrow_refund_required", "funded escrow must be refunded, not cancelled");
830
+ }
831
+ if (escrow?.fundingRequestId) {
832
+ return fail(409, "escrow_funding_pending", "escrow funding approval is pending; reject the wallet request before cancelling", {
833
+ state: "pending",
834
+ requestId: escrow.fundingRequestId
835
+ });
836
+ }
837
+ if (escrow?.status === "released" || escrow?.status === "refunded") {
838
+ return fail(409, "escrow_already_closed", "closed escrow cannot be cancelled");
839
+ }
840
+ try {
841
+ reserveMarketplaceSettlementAction({
842
+ orderId: entry.configId,
843
+ action: "cancel",
844
+ executionIntentId: `marketplace-order:${entry.configId}:escrow-cancel`,
845
+ initialPhase: escrowInitialPhase(order),
846
+ intent: {
847
+ orderId: entry.configId,
848
+ settlementMode: "escrow",
849
+ fundingRequestId: escrow?.fundingRequestId,
850
+ fundingTxRef: escrow?.fundingTxRef
851
+ },
852
+ env
853
+ });
854
+ } catch (error) {
855
+ return fail(409, "escrow_settlement_conflict", error instanceof Error ? error.message : String(error));
856
+ }
857
+ const now = params.now ?? new Date().toISOString();
858
+ const result = updateOrder({
859
+ config: params.config,
860
+ now,
861
+ order: {
862
+ ...order,
517
863
  status: "cancelled",
518
- escrow: {
519
- ...escrow,
864
+ paymentIntent: {
865
+ ...order.paymentIntent,
520
866
  status: "cancelled",
521
- holdPolicy: escrow?.holdPolicy ?? "release_on_delivery",
522
- releaseRequired: false,
523
- cancelledAt: now,
524
867
  updatedAt: now
525
868
  },
526
- notes: "Escrow order cancelled before funding.",
527
- updatedAt: now
869
+ settlement: {
870
+ ...order.settlement,
871
+ mode: "escrow",
872
+ status: "cancelled",
873
+ escrow: {
874
+ ...escrow,
875
+ status: "cancelled",
876
+ holdPolicy: escrow?.holdPolicy ?? "release_on_delivery",
877
+ releaseRequired: false,
878
+ cancelledAt: now,
879
+ updatedAt: now
880
+ },
881
+ notes: "Escrow order cancelled before funding.",
882
+ updatedAt: now
883
+ }
528
884
  }
529
- }
530
- });
531
- return {
532
- ok: true,
533
- config: result.config,
534
- order: result.order,
535
- mode: "manual",
536
- status: "cancelled",
537
- message: "Escrow order cancelled before funding."
538
- };
885
+ });
886
+ return {
887
+ ok: true,
888
+ config: result.config,
889
+ order: result.order,
890
+ mode: "manual",
891
+ status: "cancelled",
892
+ message: "Escrow order cancelled before funding."
893
+ };
894
+ } finally {
895
+ await claim();
896
+ }
539
897
  }
540
898
 
541
899
  //#endregion