@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
@@ -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