@fased/fased 0.1.62 → 0.1.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (341) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +38 -30
  3. package/config/dependency-ownership.json +1 -1
  4. package/config/signer-policies/README.md +49 -0
  5. package/config/signer-policies/agent.json.template +32 -0
  6. package/config/signer-policies/mining.json.template +69 -0
  7. package/config/signer-policies/network.json.template +5 -0
  8. package/config/signer-policies/vault.json.template +70 -0
  9. package/config/signer-protocol-v2.json +76 -0
  10. package/config/typescript-noemit-baseline.json +680 -0
  11. package/dist/agents/auth-profiles/store.js +267 -31
  12. package/dist/agents/bash-tools.exec.js +10 -4
  13. package/dist/agents/current-model-catalog.js +3 -3
  14. package/dist/agents/memory-search.js +7 -1
  15. package/dist/agents/model-catalog-access.js +1 -2
  16. package/dist/agents/model-catalog-snapshot.js +1 -1
  17. package/dist/agents/model-catalog-source.js +1 -1
  18. package/dist/agents/model-metadata.js +1 -1
  19. package/dist/agents/model-selection.js +2 -28
  20. package/dist/agents/models-config.providers.js +6 -6
  21. package/dist/agents/pi-embedded-runner/compact.js +15 -7
  22. package/dist/agents/pi-embedded-runner/model.js +1 -1
  23. package/dist/agents/pi-embedded-runner/run/attempt.js +24 -13
  24. package/dist/agents/pi-embedded-runner/run.js +2 -0
  25. package/dist/agents/pi-embedded-runner/tool-split.js +40 -2
  26. package/dist/agents/pi-tool-definition-adapter.js +16 -1
  27. package/dist/agents/pi-tools.js +2 -1
  28. package/dist/agents/sandbox/config.js +1 -1
  29. package/dist/agents/sandbox/context.js +27 -2
  30. package/dist/agents/skills/env-overrides.js +38 -28
  31. package/dist/agents/skills/trust.js +93 -0
  32. package/dist/agents/skills/workspace.js +128 -0
  33. package/dist/agents/skills-clawhub.js +36 -11
  34. package/dist/agents/skills-marketplace-scan.js +49 -0
  35. package/dist/agents/tools/marketplace-offer-draft-tool.js +1 -1
  36. package/dist/agents/tools/mining-tool.js +1 -1
  37. package/dist/agents/tools/session-status-tool.js +1 -1
  38. package/dist/agents/tools/wallet-action-tool.js +172 -36
  39. package/dist/agents/tools/wallet-skill-policy.js +65 -23
  40. package/dist/agents/tools/wallet-tool.js +7 -11
  41. package/dist/auto-reply/reply/directive-handling.fast-lane.js +2 -1
  42. package/dist/auto-reply/reply/directive-handling.impl.js +2 -1
  43. package/dist/auto-reply/reply/directive-handling.model.js +2 -1
  44. package/dist/auto-reply/reply/directive-handling.persist.js +2 -2
  45. package/dist/auto-reply/reply/get-reply-directives-apply.js +2 -0
  46. package/dist/auto-reply/reply/get-reply-inline-actions.js +25 -1
  47. package/dist/auto-reply/reply/model-selection.js +7 -4
  48. package/dist/auto-reply/reply/session-reset-model.js +4 -4
  49. package/dist/brand.js +1 -1
  50. package/dist/build-info.json +3 -3
  51. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  52. package/dist/channel-web.js +2 -2
  53. package/dist/cli/gateway-cli/run.js +8 -0
  54. package/dist/cli/program/command-registry.js +1 -1
  55. package/dist/cli/program/register.onboard.js +2 -3
  56. package/dist/cli/program/register.wallet.js +16 -123
  57. package/dist/cli/providers-cli.js +1 -1
  58. package/dist/cli/sat-cli.js +129 -2
  59. package/dist/cli/update-cli/update-command.js +260 -11
  60. package/dist/commands/auth-choice.apply.api-providers.js +3 -3
  61. package/dist/commands/doctor-config-flow.js +1 -1
  62. package/dist/commands/doctor-legacy-config.js +2 -13
  63. package/dist/commands/model-picker.js +6 -6
  64. package/dist/commands/models/auth.js +1 -1
  65. package/dist/commands/onboard-auth.config-gateways.js +1 -1
  66. package/dist/commands/onboard-auth.credentials.js +32 -8
  67. package/dist/commands/onboard-non-interactive/local/wallet-config.js +28 -27
  68. package/dist/commands/onboard-non-interactive/local.js +5 -1
  69. package/dist/commands/wallet.js +568 -1911
  70. package/dist/config/config.js +2 -2
  71. package/dist/config/io.js +64 -2
  72. package/dist/config/schema.help.js +8 -7
  73. package/dist/config/schema.labels.js +5 -4
  74. package/dist/config/zod-schema.agent-runtime.js +1 -0
  75. package/dist/config/zod-schema.js +5 -0
  76. package/dist/control-ui/assets/{app-DLil9VO1.js → app-bR-fO5ty.js} +1511 -1555
  77. package/dist/control-ui/assets/{config-CU5Zi8Dh.js → config-LeImukCW.js} +10 -10
  78. package/dist/control-ui/assets/{federation-D10Q4eP_.js → federation-DgA9e-Pn.js} +364 -422
  79. package/dist/control-ui/assets/{index-DdE_NIXo.js → index-ckCxHwjy.js} +3 -3
  80. package/dist/control-ui/assets/{mining-BdhMn18r.js → mining-BgHFh0ei.js} +134 -114
  81. package/dist/control-ui/assets/mining-commit-DFpB_4JN.js +2 -0
  82. package/dist/control-ui/assets/{open-external-url-DwSiwMPl.js → open-external-url-ulF1B-sA.js} +3 -3
  83. package/dist/control-ui/assets/{providers-QMn4w2_f.js → providers-CIx9fxc6.js} +2 -2
  84. package/dist/control-ui/assets/{wallet-C2g294QT.js → wallet-DvStR_AT.js} +259 -377
  85. package/dist/control-ui/index.html +1 -1
  86. package/dist/control-ui/version.json +1 -1
  87. package/dist/daemon/systemd-system.js +56 -50
  88. package/dist/extensions/sat-mining/src/protocol-contract.js +43 -3
  89. package/dist/extensions/sat-mining/src/rpc-read.js +235 -67
  90. package/dist/extensions/sat-mining/src/sat-bond-layout.js +5 -2
  91. package/dist/extensions/sat-mining/src/signer-codec-manifest.js +406 -0
  92. package/dist/extensions/sat-mining/src/solana-submit.js +1038 -397
  93. package/dist/extensions/sat-mining/src/submission-ledger.js +349 -0
  94. package/dist/federation/auto-connect.js +98 -8
  95. package/dist/federation/marketplace-capability-adapter.js +33 -7
  96. package/dist/federation/marketplace-delivery-outbox.js +196 -0
  97. package/dist/federation/marketplace-delivery.js +351 -215
  98. package/dist/federation/marketplace-direct-payment.js +272 -141
  99. package/dist/federation/marketplace-escrow.js +607 -249
  100. package/dist/federation/marketplace-settlement-ledger.js +352 -0
  101. package/dist/federation/offers.js +9 -7
  102. package/dist/federation/peer-auth-v2.js +529 -0
  103. package/dist/gateway/a2a-http.js +425 -96
  104. package/dist/gateway/a2a-settlement.js +259 -153
  105. package/dist/gateway/a2a-task-store.js +524 -0
  106. package/dist/gateway/auth.js +38 -2
  107. package/dist/gateway/config-reload.js +46 -33
  108. package/dist/gateway/durable-capacity.js +31 -0
  109. package/dist/gateway/federation-http.js +540 -135
  110. package/dist/gateway/federation-marketplace-run-store.js +397 -0
  111. package/dist/gateway/federation-marketplace.js +535 -230
  112. package/dist/gateway/mutating-admin-rpc-rate-limit.js +5 -0
  113. package/dist/gateway/security-path.js +1 -1
  114. package/dist/gateway/server-http.js +1084 -1205
  115. package/dist/gateway/server-methods/models.js +1 -1
  116. package/dist/gateway/server-methods/secrets.js +40 -0
  117. package/dist/gateway/server-methods.js +1 -2
  118. package/dist/gateway/server-reload-handlers.js +196 -66
  119. package/dist/gateway/server-runtime-config.js +1 -1
  120. package/dist/gateway/server-secrets-runtime.js +288 -0
  121. package/dist/gateway/server.impl.js +73 -42
  122. package/dist/gateway/sessions-patch.js +3 -5
  123. package/dist/index.js +4 -2
  124. package/dist/infra/fasedhub.js +64 -1
  125. package/dist/infra/local-source-paired-update.js +538 -0
  126. package/dist/infra/restart.js +41 -10
  127. package/dist/infra/update-runner.js +96 -0
  128. package/dist/light-update-status.js +11 -11
  129. package/dist/memory/backend-config.js +2 -1
  130. package/dist/memory/session-files.js +16 -2
  131. package/dist/plugin-sdk/{accounts-DxblobYM.js → accounts-Brn3-uWN.js} +1 -1
  132. package/dist/plugin-sdk/{actions-D4UNimWa.js → actions-DRu135h0.js} +2 -2
  133. package/dist/plugin-sdk/{active-listener-CFuy106s.js → active-listener-B_NMtgPL.js} +1 -1
  134. package/dist/plugin-sdk/{audio-preflight-Bwi2Oq03.js → audio-preflight-BYxAt775.js} +27 -27
  135. package/dist/plugin-sdk/{audit-Cs0K7LBp.js → audit-C5d2z5U1.js} +1 -1
  136. package/dist/plugin-sdk/{channel-access-D5aHoTY8.js → channel-access-CcFRdRPO.js} +1 -1
  137. package/dist/plugin-sdk/{channel-access-configure-Dvch9mMQ.js → channel-access-configure-DaI5wevh.js} +1 -1
  138. package/dist/plugin-sdk/channel-plugin-common.d.ts +3 -3
  139. package/dist/plugin-sdk/channel-plugin-common.js +4 -4
  140. package/dist/plugin-sdk/{chunk-B0FUGc5A.js → chunk-CyoyqpbG.js} +1 -1
  141. package/dist/plugin-sdk/{chunk-items-DzT4L4Ty.js → chunk-items-DIRHG2gJ.js} +1 -1
  142. package/dist/plugin-sdk/command-status.d.ts +2 -2
  143. package/dist/plugin-sdk/command-status.js +27 -27
  144. package/dist/plugin-sdk/{commands-registry-DmDRhRAU.js → commands-registry-BfqdEWdF.js} +2 -2
  145. package/dist/plugin-sdk/{common-CfUOowOp.js → common-HCcXU-NR.js} +1 -1
  146. package/dist/plugin-sdk/{config-mxULv0fQ.js → config-DlWVeLFB.js} +7113 -6877
  147. package/dist/plugin-sdk/{config-schema-BrkmtFxB.js → config-schema-BOT7kHb6.js} +6779 -3696
  148. package/dist/plugin-sdk/device-pair.d.ts +1 -1
  149. package/dist/plugin-sdk/discord.d.ts +6 -6
  150. package/dist/plugin-sdk/discord.js +19 -19
  151. package/dist/plugin-sdk/file-lock.js +35 -4
  152. package/dist/plugin-sdk/{filesystem-manager-ZoHU8oA7.js → filesystem-manager-DoI8IBNF.js} +1 -1
  153. package/dist/plugin-sdk/{group-mentions-BHRff6j8.d.ts → group-mentions-q3hUTCt7.d.ts} +1 -1
  154. package/dist/plugin-sdk/{handle-action-DbVCF9HZ.js → handle-action-hvwapMKg.js} +13 -13
  155. package/dist/plugin-sdk/{helpers-BXbdgs5H.js → helpers-DMBU4oTo.js} +1 -1
  156. package/dist/plugin-sdk/{image-ops-D7jPxaph.js → image-ops-DQi0n_Tt.js} +1 -1
  157. package/dist/plugin-sdk/index.d.ts +21 -39
  158. package/dist/plugin-sdk/index.js +29 -29
  159. package/dist/plugin-sdk/{login-BRxww6nv.js → login-Ca583Okc.js} +3 -3
  160. package/dist/plugin-sdk/{login-qr-DJXsk9XH.js → login-qr-CGciBSNP.js} +3 -3
  161. package/dist/plugin-sdk/{manager-Y2S_5IlI.js → manager-BegWxNYX.js} +4 -4
  162. package/dist/plugin-sdk/{markdown-tables-DHLFQqaF.js → markdown-tables-DCOXEUfZ.js} +1 -1
  163. package/dist/plugin-sdk/{media-Czo4carg.js → media-CAdQF5TG.js} +47 -47
  164. package/dist/plugin-sdk/{memory-search-DTjIMw8J.js → memory-search-CrFPOeTH.js} +4 -1
  165. package/dist/plugin-sdk/{monitor-M_ta2lMc.js → monitor-BCFDaqJ-.js} +31 -31
  166. package/dist/plugin-sdk/{monitor-wYVncM9w.js → monitor-BgbjRiPM.js} +32 -32
  167. package/dist/plugin-sdk/{openresponses-http-B2GmeSt4.js → openresponses-http-DFf87SMM.js} +27 -27
  168. package/dist/plugin-sdk/{optional-runtime-dependency-DdMbxS24.js → optional-runtime-dependency-0dznm3ZO.js} +1 -1
  169. package/dist/plugin-sdk/{outbound-Db8mRN6P.js → outbound-BgVDdHxx.js} +6 -6
  170. package/dist/plugin-sdk/{outbound-attachment-BqFjcypb.js → outbound-attachment-QqTnIhZL.js} +2 -2
  171. package/dist/plugin-sdk/{pairing-message-B3bHYGaw.d.ts → pairing-message-CS-9BHug.d.ts} +2 -2
  172. package/dist/plugin-sdk/{pairing-message-B3GC_7CD.js → pairing-message-D0CoLHRJ.js} +1 -1
  173. package/dist/plugin-sdk/{pairing-store-CQikgIbw.js → pairing-store-BChahgI2.js} +2 -2
  174. package/dist/plugin-sdk/{pi-model-discovery-CY3m5zJP.js → pi-model-discovery-BX_JLcEJ.js} +1 -1
  175. package/dist/plugin-sdk/{pi-model-discovery-runtime-DSh1T2pn.js → pi-model-discovery-runtime-DxTMz_XF.js} +2 -2
  176. package/dist/plugin-sdk/provider-web-search-config-contract.d.ts +2 -2
  177. package/dist/plugin-sdk/{pw-ai-AFUqn-tQ.js → pw-ai-natjh3rm.js} +3 -3
  178. package/dist/plugin-sdk/{qmd-manager-DSyx77KY.js → qmd-manager-CgRaTxUq.js} +1 -1
  179. package/dist/plugin-sdk/{query-expansion-CAI2kKLQ.js → query-expansion-BG3FgzF7.js} +14 -3
  180. package/dist/plugin-sdk/{replies-Fzh9PhXl.js → replies-ChYo5ZQM.js} +2 -2
  181. package/dist/plugin-sdk/{resolve-outbound-target-KpF3co6T.js → resolve-outbound-target-D-KGgHJZ.js} +1 -1
  182. package/dist/plugin-sdk/{resolve-route-CDl74O19.js → resolve-route-C8tvQm8Z.js} +1 -1
  183. package/dist/plugin-sdk/{retry-policy-D4uiqUOG.js → retry-policy-C6SjKjQA.js} +1 -1
  184. package/dist/plugin-sdk/{runtime-Bb6KRnCC.js → runtime-2B9_WKoI.js} +8 -3
  185. package/dist/plugin-sdk/{runtime-dependency-DLDmB94f.js → runtime-dependency-DczkvPxn.js} +2 -2
  186. package/dist/plugin-sdk/sat-runtime.d.ts +549 -309
  187. package/dist/plugin-sdk/sat-runtime.js +29 -29
  188. package/dist/plugin-sdk/{send-C4k4JuJN.js → send-B6KkGKZD.js} +6 -6
  189. package/dist/plugin-sdk/{send-D-uDKGIq.js → send-CFzGKJXo.js} +6 -6
  190. package/dist/plugin-sdk/{send-Du8ykP1k.js → send-DCO441U7.js} +8 -8
  191. package/dist/plugin-sdk/{send-5nFktR1n.js → send-gDoGA-7e.js} +5 -5
  192. package/dist/plugin-sdk/{send-Bfzf11VY.js → send-q9HXrSwK.js} +7 -7
  193. package/dist/plugin-sdk/{session-CS-Td9EM.js → session-DHD4ZKyG.js} +2 -2
  194. package/dist/plugin-sdk/{skill-commands-CFAlXWHk.js → skill-commands-FKEPLS7T.js} +201 -26
  195. package/dist/plugin-sdk/{slack-CxE1mfzj.js → slack-BUTt8cxK.js} +39 -39
  196. package/dist/plugin-sdk/{slack-actions-BcMkNv1Z.js → slack-actions-DhbMcp8M.js} +11 -11
  197. package/dist/plugin-sdk/slack.d.ts +6 -6
  198. package/dist/plugin-sdk/slack.js +9 -9
  199. package/dist/plugin-sdk/{sticker-cache-CGzGWu00.js → sticker-cache-D0wHVqjt.js} +3 -3
  200. package/dist/plugin-sdk/{tables-bFXyRpkx.js → tables-B3jr0Pvq.js} +1 -1
  201. package/dist/plugin-sdk/{targets-DH7a9lKB.js → targets-CtSbTxYX.js} +1 -1
  202. package/dist/plugin-sdk/{telegram-actions-DaEcYQ8r.js → telegram-actions-CC_qN4v0.js} +30 -30
  203. package/dist/plugin-sdk/telegram.d.ts +6 -6
  204. package/dist/plugin-sdk/telegram.js +8 -8
  205. package/dist/plugin-sdk/{thread-bindings.lifecycle-CgOvvdw8.js → thread-bindings.lifecycle-QbkNl-m6.js} +3 -3
  206. package/dist/plugin-sdk/{thread-bindings.state-CQpk44Hq.js → thread-bindings.state-D9hg_M1c.js} +2 -2
  207. package/dist/plugin-sdk/tmp-fased-dir-xOTGlzBE.d.ts +486 -0
  208. package/dist/plugin-sdk/{types-vcJrC_uv.d.ts → types-C3avNytw.d.ts} +3 -4
  209. package/dist/plugin-sdk/{types-DyhXnYUr.d.ts → types-D0kDG8l0.d.ts} +3 -2
  210. package/dist/plugin-sdk/{types-DFAW-n1J.d.ts → types-DWfbSAaM.d.ts} +2 -2
  211. package/dist/plugin-sdk/{types.plugin-_fbu40Re.d.ts → types.plugin-BcSBq42x.d.ts} +8 -3
  212. package/dist/plugin-sdk/{web-CInY-lCv.js → web-BXsJ1vqe.js} +32 -32
  213. package/dist/plugin-sdk/{whatsapp-actions-BtSc2CBv.js → whatsapp-actions-Bj_rOncr.js} +13 -13
  214. package/dist/plugin-sdk/{whatsapp-heartbeat-Bg9TuYzl.js → whatsapp-heartbeat-B1WHkJIg.js} +2 -2
  215. package/dist/plugin-sdk/whatsapp.d.ts +13 -13
  216. package/dist/plugin-sdk/whatsapp.js +12 -12
  217. package/dist/plugin-sdk/{wsl-C4DGFkOd.js → wsl-J-HscWxS.js} +3 -3
  218. package/dist/plugin-sdk/{zod-schema.providers-core-BEbNizPe.d.ts → zod-schema.providers-core-CIzCjXH9.d.ts} +61 -61
  219. package/dist/providers/refresh.js +1 -1
  220. package/dist/providers/registry.js +1 -1
  221. package/dist/secrets/apply.js +1 -1
  222. package/dist/secrets/runtime.js +1 -1
  223. package/dist/wallet/external-submission-ledger.js +376 -0
  224. package/dist/wallet/legacy-embedded-keystore.js +40 -0
  225. package/dist/wallet/local-socket-signer-archive.js +30 -0
  226. package/dist/wallet/local-socket-signer-lifecycle.js +97 -0
  227. package/dist/wallet/local-socket-signer-policy.js +166 -0
  228. package/dist/wallet/local-socket-signer-protocol.js +561 -118
  229. package/dist/wallet/native-signer-wallet-id.js +25 -0
  230. package/dist/wallet/providers/alchemy-adapter.js +3 -0
  231. package/dist/wallet/providers/local-socket-signer-adapter.js +380 -105
  232. package/dist/wallet/providers/turnkey-adapter.js +292 -34
  233. package/dist/wallet/providers/wallet-standard-adapter.js +100 -0
  234. package/dist/wallet/signer-network-admin.js +184 -0
  235. package/dist/wallet/signer-protocol-v2.generated.js +90 -0
  236. package/dist/wallet/solana-bond-signing.js +157 -69
  237. package/dist/wallet/solana-reviewed-transaction.js +375 -0
  238. package/dist/wallet/solana-swap.js +520 -64
  239. package/dist/wallet/solana-transaction-inspection.js +106 -4
  240. package/dist/wallet/solana-trigger.js +658 -320
  241. package/dist/wallet/turnkey-reviewed-state.js +370 -0
  242. package/dist/wallet/wallet-approval-auth.js +17 -28
  243. package/dist/wallet/wallet-atomic-state.js +53 -0
  244. package/dist/wallet/wallet-canary.js +0 -1
  245. package/dist/wallet/wallet-inbound-events.js +16 -11
  246. package/dist/wallet/wallet-policy-simulation.js +1 -1
  247. package/dist/wallet/wallet-policy.js +90 -36
  248. package/dist/wallet/wallet-provider-capabilities.js +28 -4
  249. package/dist/wallet/wallet-provider-registry.js +57 -44
  250. package/dist/wallet/wallet-provider-resolver.js +62 -63
  251. package/dist/wallet/wallet-runtime-config.js +28 -41
  252. package/dist/wallet/wallet-secrets-store.js +22 -0
  253. package/dist/wallet/wallet-send-approvals.js +1891 -589
  254. package/dist/wallet/wallet-send-execution-ledger.js +292 -0
  255. package/dist/wallet/wallet-settlement-links.js +14 -13
  256. package/dist/wallet/wallet-standard-review.js +353 -0
  257. package/dist/wallet/wallet-status.js +0 -9
  258. package/dist/wallet/wallet-task-ledger.js +16 -2
  259. package/dist/web/auto-reply/heartbeat-runner.js +1 -1
  260. package/dist/web/auto-reply/monitor.js +2 -2
  261. package/dist/wizard/host-security-capability.js +14 -23
  262. package/dist/wizard/onboarding.finalize.js +63 -184
  263. package/dist/wizard/onboarding.host-security.js +117 -1367
  264. package/dist/wizard/onboarding.js +172 -217
  265. package/dist/wizard/onboarding.wallet.js +232 -785
  266. package/extensions/acpx/package.json +1 -1
  267. package/extensions/bluebubbles/package.json +1 -1
  268. package/extensions/copilot-proxy/package.json +1 -1
  269. package/extensions/diagnostics-otel/package.json +1 -1
  270. package/extensions/fased-federation/package.json +1 -1
  271. package/extensions/google-gemini-cli-auth/package.json +1 -1
  272. package/extensions/imessage/package.json +1 -1
  273. package/extensions/irc/package.json +1 -1
  274. package/extensions/line/package.json +1 -1
  275. package/extensions/llm-task/package.json +1 -1
  276. package/extensions/lobster/package.json +1 -1
  277. package/extensions/matrix/CHANGELOG.md +12 -0
  278. package/extensions/matrix/package.json +1 -1
  279. package/extensions/mattermost/package.json +1 -1
  280. package/extensions/memory-core/package.json +2 -2
  281. package/extensions/memory-lancedb/package.json +1 -1
  282. package/extensions/minimax-portal-auth/package.json +1 -1
  283. package/extensions/msteams/CHANGELOG.md +12 -0
  284. package/extensions/msteams/package.json +1 -1
  285. package/extensions/nextcloud-talk/package.json +1 -1
  286. package/extensions/nostr/CHANGELOG.md +12 -0
  287. package/extensions/nostr/package.json +1 -1
  288. package/extensions/open-prose/package.json +1 -1
  289. package/extensions/sat-mining/index.ts +498 -153
  290. package/extensions/sat-mining/package.json +1 -1
  291. package/extensions/sat-mining/signer-codec-schema.v1.json +374 -0
  292. package/extensions/sat-mining/src/audit-store.ts +50 -5
  293. package/extensions/sat-mining/src/claim-service.ts +85 -14
  294. package/extensions/sat-mining/src/config.ts +9 -0
  295. package/extensions/sat-mining/src/cycle-progress.ts +16 -8
  296. package/extensions/sat-mining/src/epoch-service.ts +9 -5
  297. package/extensions/sat-mining/src/gateway-runner.ts +21 -1
  298. package/extensions/sat-mining/src/protocol-contract.ts +45 -1
  299. package/extensions/sat-mining/src/recovery-service.ts +312 -0
  300. package/extensions/sat-mining/src/round-watcher.ts +391 -81
  301. package/extensions/sat-mining/src/rpc-read.ts +330 -89
  302. package/extensions/sat-mining/src/runtime.ts +14 -0
  303. package/extensions/sat-mining/src/sat-bond-layout.ts +6 -0
  304. package/extensions/sat-mining/src/signer-codec-manifest.ts +429 -0
  305. package/extensions/sat-mining/src/solana-submit.ts +1199 -428
  306. package/extensions/sat-mining/src/submission-ledger.ts +433 -0
  307. package/extensions/signal/package.json +1 -1
  308. package/extensions/synology-chat/package.json +1 -1
  309. package/extensions/tlon/package.json +1 -1
  310. package/extensions/twitch/CHANGELOG.md +12 -0
  311. package/extensions/twitch/package.json +1 -1
  312. package/extensions/voice-call/CHANGELOG.md +12 -0
  313. package/extensions/voice-call/package.json +1 -1
  314. package/extensions/zalo/CHANGELOG.md +12 -0
  315. package/extensions/zalo/package.json +1 -1
  316. package/extensions/zalouser/CHANGELOG.md +12 -0
  317. package/extensions/zalouser/package.json +1 -1
  318. package/install.sh +4955 -0
  319. package/package.json +23 -5
  320. package/scripts/fased-host-updater.mjs +1421 -0
  321. package/scripts/fased-host-updaterctl.mjs +186 -0
  322. package/scripts/fased-managed-service.sh +36 -0
  323. package/scripts/fased-managed-updater.mjs +3065 -156
  324. package/scripts/fased-signer-enroll-hosting.sh +275 -0
  325. package/scripts/fased-signer-network-hosting.sh +143 -0
  326. package/scripts/fased-signer-owner-policy.mjs +1430 -0
  327. package/scripts/fased-signer-policy-hosting.sh +50 -0
  328. package/scripts/fased-signer-policy-local.sh +26 -0
  329. package/scripts/hosted-release-manifest.mjs +185 -0
  330. package/scripts/install-fased-signerd.sh +183 -108
  331. package/scripts/install-managed-runtime.mjs +212 -10
  332. package/scripts/managed-runtime-layout.mjs +75 -3
  333. package/scripts/migrate-hosted-signer-v2.mjs +58 -0
  334. package/scripts/start-managed.sh +169 -360
  335. package/dist/control-ui/assets/mining-commit-R-6nu87p.js +0 -2
  336. package/dist/plugin-sdk/tmp-fased-dir-CS6zsYEE.d.ts +0 -77
  337. package/dist/wallet/local-socket-signer-broker.js +0 -224
  338. package/dist/wallet/local-socket-signer-custody.js +0 -42
  339. package/dist/wallet/providers/embedded-keystore-adapter.js +0 -402
  340. package/dist/wallet/providers/privy-adapter.js +0 -80
  341. package/dist/wallet/wallet-custody.js +0 -1836
@@ -1,418 +1,756 @@
1
- import { enforceWalletDailyCap } from "./wallet-policy.js";
2
- import { inspectSerializedSolanaSwapTransaction } from "./solana-transaction-inspection.js";
3
- import { SOLANA_NATIVE_MINT, validateSolanaSwapInputBalance, validateSolanaSwapIntentPolicy } from "./solana-swap.js";
1
+ import { SOLANA_ASSET_CONSTANTS, fetchSolanaMintInfoViaRpc } from "./solana-assets.js";
2
+ import { beginExternalSubmission, claimExternalSubmissionExecution, createExternalSubmissionKey, externalSubmissionIntentDigest, getExternalSubmission, getExternalSubmissionByExplicitIntent, updateExternalSubmission } from "./external-submission-ledger.js";
3
+ import { SOLANA_NATIVE_MINT, resolveJupiterMaxFeeLamports, validateSolanaSwapInputBalance, validateSolanaSwapIntentPolicy } from "./solana-swap.js";
4
+ import { createHash } from "node:crypto";
4
5
 
5
6
  //#region src/wallet/solana-trigger.ts
6
- const JUPITER_TRIGGER_DEFAULT_BASE_URL = "https://api.jup.ag/trigger/v2";
7
7
  const JUPITER_TRIGGER_MAX_EXPIRY_MS = 30 * 24 * 60 * 60 * 1e3;
8
8
  const JUPITER_TRIGGER_DEFAULT_EXPIRY_MS = 7 * 24 * 60 * 60 * 1e3;
9
+ const SOLANA_SYSTEM_PROGRAM_ID = "11111111111111111111111111111111";
9
10
  function stringValue(value) {
10
11
  return typeof value === "string" && value.trim() ? value.trim() : undefined;
11
12
  }
12
- function positiveNumber(value) {
13
- return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : undefined;
13
+ function positiveBaseUnits(value, field) {
14
+ const normalized = stringValue(value);
15
+ if (!normalized || normalized.length > 32 || !/^[1-9][0-9]*$/.test(normalized)) {
16
+ throw new Error(`${field} must be a positive base-unit integer`);
17
+ }
18
+ const parsed = BigInt(normalized);
19
+ if (parsed > 18446744073709551615n) {
20
+ throw new Error(`${field} must fit an unsigned 64-bit integer`);
21
+ }
22
+ return parsed.toString();
14
23
  }
15
- function resolveTriggerApiBaseUrl(env = process.env) {
16
- return (env.FASED_JUPITER_TRIGGER_API_BASE_URL?.trim() || env.JUPITER_TRIGGER_API_BASE_URL?.trim() || JUPITER_TRIGGER_DEFAULT_BASE_URL).replace(/\/+$/, "");
24
+ function expandScientificDecimal(value) {
25
+ const match = /^(\d+)(?:\.(\d+))?[eE]([+-]?\d+)$/.exec(value);
26
+ if (!match) {
27
+ return value;
28
+ }
29
+ const integer = match[1] ?? "";
30
+ const fraction = match[2] ?? "";
31
+ const exponent = Number.parseInt(match[3] ?? "0", 10);
32
+ const digits = integer + fraction;
33
+ const decimalIndex = integer.length + exponent;
34
+ if (decimalIndex <= 0) {
35
+ return `0.${"0".repeat(-decimalIndex)}${digits}`;
36
+ }
37
+ if (decimalIndex >= digits.length) {
38
+ return `${digits}${"0".repeat(decimalIndex - digits.length)}`;
39
+ }
40
+ return `${digits.slice(0, decimalIndex)}.${digits.slice(decimalIndex)}`;
17
41
  }
18
- function resolveTriggerApiKey(env = process.env) {
19
- return env.FASED_JUPITER_API_KEY?.trim() || env.JUPITER_API_KEY?.trim() || "";
42
+ function canonicalJupiterTriggerPrice(value) {
43
+ const raw = typeof value === "number" && Number.isFinite(value) ? expandScientificDecimal(String(value)) : typeof value === "string" ? value.trim() : "";
44
+ if (!/^(?:0|[1-9][0-9]*)(?:\.[0-9]+)?$/.test(raw)) {
45
+ throw new Error("limit order triggerPriceUsd must be a positive plain decimal string");
46
+ }
47
+ const [integer = "", rawFraction] = raw.split(".");
48
+ const fraction = rawFraction?.replace(/0+$/, "");
49
+ const normalized = fraction ? `${integer}.${fraction}` : integer;
50
+ if (!normalized || normalized === "0") {
51
+ throw new Error("limit order triggerPriceUsd must be positive");
52
+ }
53
+ return normalized;
20
54
  }
21
- async function triggerJson(params) {
22
- const response = await fetch(`${resolveTriggerApiBaseUrl(params.env)}/${params.path.replace(/^\/+/, "")}`, {
23
- method: params.method ?? "GET",
24
- headers: {
25
- accept: "application/json",
26
- "x-api-key": params.apiKey,
27
- ...params.body ? { "content-type": "application/json" } : {},
28
- ...params.token ? { authorization: `Bearer ${params.token}` } : {}
29
- },
30
- body: params.body ? JSON.stringify(params.body) : undefined
31
- });
32
- const json = await response.json().catch(() => null);
33
- if (!response.ok || !json || typeof json !== "object") {
34
- const message = stringValue(json?.error) ?? stringValue(json?.message) ?? response.statusText;
35
- throw new Error(`jupiter trigger ${params.path} failed: ${response.status} ${message}`);
55
+ function readJupiterTriggerPositiveNumber(value) {
56
+ try {
57
+ return canonicalJupiterTriggerPrice(value);
58
+ } catch {
59
+ return undefined;
60
+ }
61
+ }
62
+ function normalizeTriggerSlippage(value) {
63
+ const slippageBps = value === undefined ? 50 : Math.floor(value);
64
+ if (!Number.isFinite(slippageBps) || slippageBps < 1 || slippageBps > 1e3) {
65
+ throw new Error("limit order slippageBps must be between 1 and 1000");
36
66
  }
37
- return json;
67
+ return slippageBps;
38
68
  }
39
69
  function normalizeTriggerExpiry(params) {
40
- const now = Date.now();
41
- const fromSeconds = typeof params.expirySeconds === "number" && Number.isFinite(params.expirySeconds) ? now + Math.max(60, Math.floor(params.expirySeconds)) * 1e3 : undefined;
42
- const expiresAt = Math.floor(params.expiresAt ?? fromSeconds ?? now + JUPITER_TRIGGER_DEFAULT_EXPIRY_MS);
43
- if (expiresAt <= now + 6e4) {
44
- throw new Error("limit order expiry must be at least 60 seconds in the future");
70
+ const now = params.now ?? Date.now();
71
+ let expiresAtMs;
72
+ let callerExpiry;
73
+ if (typeof params.expiresAt === "string") {
74
+ if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(params.expiresAt)) {
75
+ throw new Error("limit order expiresAt must use exact UTC millisecond format");
76
+ }
77
+ expiresAtMs = Date.parse(params.expiresAt);
78
+ callerExpiry = { expiresAt: params.expiresAt };
79
+ } else if (typeof params.expiresAt === "number" && Number.isFinite(params.expiresAt)) {
80
+ expiresAtMs = Math.floor(params.expiresAt);
81
+ callerExpiry = { expiresAtMs };
82
+ } else if (typeof params.expirySeconds === "number" && Number.isFinite(params.expirySeconds)) {
83
+ const expirySeconds = Math.floor(params.expirySeconds);
84
+ if (expirySeconds < 60 || expirySeconds > JUPITER_TRIGGER_MAX_EXPIRY_MS / 1e3) {
85
+ throw new Error("limit order expirySeconds must be between 60 and 2592000");
86
+ }
87
+ expiresAtMs = now + expirySeconds * 1e3;
88
+ callerExpiry = { expirySeconds };
89
+ } else {
90
+ expiresAtMs = now + JUPITER_TRIGGER_DEFAULT_EXPIRY_MS;
91
+ callerExpiry = { defaultExpiry: "7d" };
92
+ }
93
+ if (!Number.isFinite(expiresAtMs) || expiresAtMs <= now + 6e4) {
94
+ throw new Error("limit order expiry must be more than 60 seconds in the future");
45
95
  }
46
- if (expiresAt > now + JUPITER_TRIGGER_MAX_EXPIRY_MS) {
96
+ if (expiresAtMs > now + JUPITER_TRIGGER_MAX_EXPIRY_MS) {
47
97
  throw new Error("limit order expiry must be 30 days or less");
48
98
  }
49
- return expiresAt;
50
- }
51
- async function signSerializedSolanaTx(params) {
52
- if (!params.provider.signTx) {
53
- throw new Error("wallet provider cannot sign Jupiter Trigger deposit transactions");
54
- }
55
- const signed = await params.provider.signTx({
56
- chain: "solana",
57
- walletId: params.walletId,
58
- serializedTxBase64: params.serializedTxBase64,
59
- amount: params.amount ?? "0",
60
- tokenMint: params.tokenMint
61
- });
62
- if (!signed.ok || !signed.signedTxBase64) {
63
- throw new Error("wallet provider failed to sign Jupiter Trigger transaction");
99
+ const expiresAt = new Date(expiresAtMs).toISOString();
100
+ if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(expiresAt)) {
101
+ throw new Error("limit order expiry is outside the supported timestamp range");
64
102
  }
65
103
  return {
66
- signedTxBase64: signed.signedTxBase64,
67
- signer: signed.signer
104
+ expiresAt,
105
+ callerExpiry
68
106
  };
69
107
  }
70
- async function authenticateJupiterTrigger(params) {
71
- const challenge = await triggerJson({
72
- path: "/auth/challenge",
73
- method: "POST",
74
- apiKey: params.apiKey,
75
- body: {
76
- walletPubkey: params.walletAddress,
77
- type: "transaction"
78
- },
79
- env: params.env
108
+ function triggerExpiryIdentity(params) {
109
+ if (typeof params.expiresAt === "string") {
110
+ return { expiresAt: params.expiresAt.trim() };
111
+ }
112
+ if (typeof params.expiresAt === "number" && Number.isFinite(params.expiresAt)) {
113
+ return { expiresAtMs: Math.floor(params.expiresAt) };
114
+ }
115
+ if (typeof params.expirySeconds === "number" && Number.isFinite(params.expirySeconds)) {
116
+ return { expirySeconds: Math.floor(params.expirySeconds) };
117
+ }
118
+ return { defaultExpiry: "7d" };
119
+ }
120
+ async function resolveTriggerTransferProgram(params) {
121
+ if (params.mint === SOLANA_NATIVE_MINT) {
122
+ return SOLANA_SYSTEM_PROGRAM_ID;
123
+ }
124
+ if (!params.rpcUrl?.trim()) {
125
+ throw new Error("Solana RPC is required to resolve the exact Trigger token program");
126
+ }
127
+ const mint = await fetchSolanaMintInfoViaRpc({
128
+ rpcUrl: params.rpcUrl,
129
+ mint: params.mint
80
130
  });
81
- const transaction = stringValue(challenge.transaction);
82
- if (!transaction) {
83
- throw new Error("jupiter trigger did not return an auth transaction");
84
- }
85
- const inspection = await inspectSerializedSolanaSwapTransaction({
86
- serializedTxBase64: transaction,
87
- expectedSigner: params.walletAddress,
88
- rpcUrl: params.rpcUrl
131
+ if (!mint || mint.tokenProgramId !== SOLANA_ASSET_CONSTANTS.tokenProgramId && mint.tokenProgramId !== SOLANA_ASSET_CONSTANTS.token2022ProgramId) {
132
+ throw new Error(`unable to resolve a supported SPL token program for ${params.mint}`);
133
+ }
134
+ return mint.tokenProgramId;
135
+ }
136
+ function validateJupiterTriggerLimitOrderIntent(params) {
137
+ const swapPolicy = validateSolanaSwapIntentPolicy({
138
+ config: params.config,
139
+ inputMint: params.inputMint,
140
+ outputMint: params.outputMint,
141
+ amount: params.amount,
142
+ autonomous: params.autonomous
89
143
  });
90
- if (!inspection.ok) {
91
- throw new Error(inspection.message);
144
+ if (!swapPolicy.ok) {
145
+ return {
146
+ ok: false,
147
+ code: swapPolicy.code ?? "wallet_trigger_policy_rejected",
148
+ message: swapPolicy.message ?? "wallet Trigger policy rejected"
149
+ };
92
150
  }
93
- if (inspection.routeProgramIds.length > 0) {
94
- throw new Error(`jupiter trigger auth uses unexpected program ${inspection.routeProgramIds[0]}`);
151
+ if (params.triggerCondition !== "above" && params.triggerCondition !== "below") {
152
+ return {
153
+ ok: false,
154
+ code: "wallet_trigger_condition_invalid",
155
+ message: "limit order triggerCondition must be above or below"
156
+ };
95
157
  }
96
- const signed = await signSerializedSolanaTx({
97
- provider: params.provider,
158
+ try {
159
+ canonicalJupiterTriggerPrice(params.triggerPriceUsd);
160
+ normalizeTriggerSlippage(params.slippageBps);
161
+ } catch (error) {
162
+ return {
163
+ ok: false,
164
+ code: "wallet_trigger_terms_invalid",
165
+ message: String(error)
166
+ };
167
+ }
168
+ return { ok: true };
169
+ }
170
+ function triggerRequestId(params) {
171
+ const digest = createHash("sha256").update(`${params.action}\0${params.mode}\0${params.walletId}\0${params.intentId}`).digest("hex");
172
+ return `jupiter-trigger-${params.action}:${digest}`;
173
+ }
174
+ function triggerExplicitIntentId(params) {
175
+ return `${params.action}:${params.mode}:${createHash("sha256").update(params.intentId).digest("hex")}`;
176
+ }
177
+ function isStoredTriggerIntent(value, action) {
178
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
179
+ return false;
180
+ }
181
+ const intent = value;
182
+ return intent.type === `solana.jupiter.trigger.${action}` && Boolean(intent.jupiter && typeof intent.jupiter === "object") && intent.jupiter?.trigger?.operation === action;
183
+ }
184
+ async function bindTriggerIntent(params) {
185
+ if (!params.intentId.trim()) {
186
+ throw new Error("Jupiter Trigger requires a stable caller-owned intentId");
187
+ }
188
+ const explicitIntentId = triggerExplicitIntentId(params);
189
+ const callerIntentDigest = externalSubmissionIntentDigest(params.callerIntent);
190
+ const reuse = (entry) => {
191
+ if (entry.details?.callerIntentDigest !== callerIntentDigest) {
192
+ throw new Error("Jupiter Trigger intentId is already bound to different immutable terms");
193
+ }
194
+ const intent = entry.details?.semanticIntent;
195
+ if (!isStoredTriggerIntent(intent, params.action)) {
196
+ throw new Error("Jupiter Trigger durable intent record is incomplete; refusing execution");
197
+ }
198
+ return {
199
+ entry,
200
+ intent
201
+ };
202
+ };
203
+ const existing = getExternalSubmissionByExplicitIntent({
204
+ kind: params.kind,
98
205
  walletId: params.walletId,
99
- serializedTxBase64: transaction,
100
- amount: "0"
101
- });
102
- const verified = await triggerJson({
103
- path: "/auth/verify",
104
- method: "POST",
105
- apiKey: params.apiKey,
106
- body: {
107
- type: "transaction",
108
- walletPubkey: params.walletAddress,
109
- signedTransaction: signed.signedTxBase64
110
- },
206
+ explicitIntentId,
111
207
  env: params.env
112
208
  });
113
- const token = stringValue(verified.token);
114
- if (!token) {
115
- throw new Error("jupiter trigger auth did not return a token");
209
+ if (existing) {
210
+ return reuse(existing);
211
+ }
212
+ const intent = await params.buildIntent();
213
+ const identity = createExternalSubmissionKey({
214
+ kind: params.kind,
215
+ walletId: params.walletId,
216
+ explicitIntentId,
217
+ intent
218
+ });
219
+ try {
220
+ const begun = await beginExternalSubmission({
221
+ ...identity,
222
+ kind: params.kind,
223
+ walletId: params.walletId,
224
+ details: {
225
+ callerIntentDigest,
226
+ semanticIntent: intent
227
+ },
228
+ env: params.env
229
+ });
230
+ return {
231
+ entry: begun.entry,
232
+ intent
233
+ };
234
+ } catch (error) {
235
+ const raced = getExternalSubmissionByExplicitIntent({
236
+ kind: params.kind,
237
+ walletId: params.walletId,
238
+ explicitIntentId,
239
+ env: params.env
240
+ });
241
+ if (raced) {
242
+ return reuse(raced);
243
+ }
244
+ throw error;
245
+ }
246
+ }
247
+ function storedOperation(entry) {
248
+ const value = entry.result?.operation;
249
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
250
+ return null;
251
+ }
252
+ const operation = value;
253
+ if (typeof operation.requestId !== "string" || typeof operation.walletId !== "string" || typeof operation.intentDigest !== "string" || typeof operation.policyHash !== "string" || typeof operation.state !== "string") {
254
+ return null;
116
255
  }
117
- return token;
256
+ return operation;
118
257
  }
119
- async function getOrRegisterJupiterVault(params) {
258
+ function ensureTriggerReview(params) {
259
+ const { review } = params;
260
+ if (review.walletId !== params.walletId || review.requestId !== params.requestId || review.mode !== "reviewed" || review.state !== "prepared" || review.intentType !== params.intent.type || review.artifactKind !== "jupiter-trigger-state" || review.transaction !== undefined || review.messageBase64 !== undefined || externalSubmissionIntentDigest(review.semanticIntent) !== externalSubmissionIntentDigest(params.intent)) {
261
+ throw new Error("signer returned a mismatched Jupiter Trigger review");
262
+ }
263
+ return review;
264
+ }
265
+ async function prepareReviewedTrigger(params) {
266
+ if (!params.provider.prepareSignerReview || !params.provider.getSignerReview) {
267
+ throw new Error("Jupiter Trigger review requires protocol-v2 local-socket-signer review.prepare support");
268
+ }
269
+ const release = await claimExternalSubmissionExecution(params.entry.key, params.env);
120
270
  try {
121
- return await triggerJson({
122
- path: "/vault",
123
- apiKey: params.apiKey,
124
- token: params.token,
271
+ const entry = getExternalSubmission({
272
+ key: params.entry.key,
125
273
  env: params.env
126
274
  });
127
- } catch {
128
- try {
129
- return await triggerJson({
130
- path: "/vault/register",
131
- apiKey: params.apiKey,
132
- token: params.token,
133
- env: params.env
275
+ if (!entry) {
276
+ throw new Error("Jupiter Trigger durable intent record disappeared; refusing review");
277
+ }
278
+ if (entry.state === "prepared") {
279
+ return ensureTriggerReview({
280
+ review: await params.provider.getSignerReview({
281
+ walletId: params.walletId,
282
+ requestId: params.requestId
283
+ }),
284
+ walletId: params.walletId,
285
+ requestId: params.requestId,
286
+ intent: params.intent
134
287
  });
135
- } catch {
136
- return await triggerJson({
137
- path: "/vault",
138
- apiKey: params.apiKey,
139
- token: params.token,
140
- env: params.env
288
+ }
289
+ if (entry.state !== "reserved") {
290
+ throw new Error(`reviewed Jupiter Trigger intent is ${entry.state}; it cannot be prepared again`);
291
+ }
292
+ let review;
293
+ try {
294
+ review = await params.provider.prepareSignerReview({
295
+ walletId: params.walletId,
296
+ requestId: params.requestId,
297
+ mode: "reviewed",
298
+ intent: params.intent
141
299
  });
300
+ } catch (error) {
301
+ try {
302
+ review = await params.provider.getSignerReview({
303
+ walletId: params.walletId,
304
+ requestId: params.requestId
305
+ });
306
+ } catch {
307
+ throw error;
308
+ }
142
309
  }
310
+ const checked = ensureTriggerReview({
311
+ review,
312
+ walletId: params.walletId,
313
+ requestId: params.requestId,
314
+ intent: params.intent
315
+ });
316
+ await updateExternalSubmission({
317
+ key: entry.key,
318
+ expectedStates: ["reserved"],
319
+ state: "prepared",
320
+ patch: {
321
+ signerRequestId: checked.requestId,
322
+ signerIntentDigest: checked.intentDigest,
323
+ details: entry.details
324
+ },
325
+ env: params.env
326
+ });
327
+ return checked;
328
+ } finally {
329
+ await release();
143
330
  }
144
331
  }
145
- function validateJupiterTriggerLimitOrderIntent(params) {
146
- const condition = params.triggerCondition.trim();
147
- if (condition !== "above" && condition !== "below") {
148
- return {
149
- ok: false,
150
- code: "wallet_limit_trigger_condition_invalid",
151
- message: "limit order triggerCondition must be above or below"
152
- };
332
+ async function persistAutonomousOperation(params) {
333
+ const state = params.operation.state === "confirmed" ? "confirmed" : params.operation.state === "failed" ? "failed" : "unknown";
334
+ return await updateExternalSubmission({
335
+ key: params.entry.key,
336
+ expectedStates: ["submitting", "unknown"],
337
+ state,
338
+ patch: {
339
+ signerRequestId: params.operation.requestId,
340
+ signerIntentDigest: params.operation.intentDigest,
341
+ signerSignature: params.operation.signature,
342
+ transactionDigest: params.operation.transactionDigest,
343
+ reason: params.operation.error,
344
+ details: params.entry.details,
345
+ result: { operation: params.operation }
346
+ },
347
+ env: params.env
348
+ });
349
+ }
350
+ function requireConfirmedTriggerOperation(params) {
351
+ const operation = params.operation;
352
+ if (operation.requestId !== params.requestId || operation.walletId !== params.walletId || operation.intentType !== `solana.jupiter.trigger.${params.action}`) {
353
+ throw new Error("signer returned a Jupiter Trigger operation for different immutable terms");
153
354
  }
154
- if (!Number.isFinite(params.triggerPriceUsd) || params.triggerPriceUsd <= 0) {
155
- return {
156
- ok: false,
157
- code: "wallet_limit_trigger_price_invalid",
158
- message: "limit order triggerPriceUsd must be positive"
159
- };
355
+ if (operation.state !== "confirmed" || !operation.signature) {
356
+ const ambiguous = operation.state === "reserved" || operation.state === "broadcast" || operation.state === "unknown";
357
+ throw new Error(ambiguous ? `Jupiter Trigger signer operation ${operation.requestId} is ${operation.state}; reconcile it and do not submit again` : operation.error ?? `Jupiter Trigger signer operation failed in state=${operation.state}`);
358
+ }
359
+ const external = operation.externalResult;
360
+ if (external?.provider !== "jupiter-trigger-v2" || external.action !== params.action || !external.orderId || (params.action === "create" ? external.orderState !== "open" : external.orderState !== "cancelled")) {
361
+ throw new Error("confirmed Jupiter Trigger operation omitted its sanitized exact order result");
160
362
  }
161
- const slippage = params.slippageBps ?? 100;
162
- if (!Number.isFinite(slippage) || slippage < 1 || slippage > 1e3) {
363
+ return {
364
+ id: external.orderId,
365
+ txSignature: operation.signature,
366
+ state: external.orderState,
367
+ provider: external.provider
368
+ };
369
+ }
370
+ function assertTriggerOperationIdentity(params) {
371
+ if (params.operation.requestId !== params.requestId || params.operation.walletId !== params.walletId || params.operation.intentType !== `solana.jupiter.trigger.${params.action}` || params.signerIntentDigest && params.operation.intentDigest !== params.signerIntentDigest) {
372
+ throw new Error("signer returned a Jupiter Trigger operation for different immutable terms");
373
+ }
374
+ }
375
+ async function executeAutonomousTrigger(params) {
376
+ if (!params.provider.executeSignerIntent || !params.provider.reconcileSignerOperation) {
377
+ throw new Error("autonomous Jupiter Trigger requires protocol-v2 local-socket-signer execute/reconcile support");
378
+ }
379
+ const release = await claimExternalSubmissionExecution(params.entry.key, params.env);
380
+ try {
381
+ let entry = getExternalSubmission({
382
+ key: params.entry.key,
383
+ env: params.env
384
+ });
385
+ if (!entry) {
386
+ throw new Error("Jupiter Trigger durable intent record disappeared; refusing execution");
387
+ }
388
+ if (entry.state === "confirmed" || entry.state === "failed") {
389
+ const operation = storedOperation(entry);
390
+ if (!operation) {
391
+ throw new Error("Jupiter Trigger durable result is incomplete; refusing another submission");
392
+ }
393
+ return {
394
+ operation,
395
+ order: requireConfirmedTriggerOperation({
396
+ ...params,
397
+ operation
398
+ })
399
+ };
400
+ }
401
+ let operation;
402
+ if (entry.state === "submitting" || entry.state === "unknown") {
403
+ operation = await params.provider.reconcileSignerOperation({
404
+ walletId: params.walletId,
405
+ requestId: params.requestId
406
+ });
407
+ } else if (entry.state === "reserved") {
408
+ entry = await updateExternalSubmission({
409
+ key: entry.key,
410
+ expectedStates: ["reserved"],
411
+ state: "submitting",
412
+ patch: {
413
+ signerRequestId: params.requestId,
414
+ details: entry.details
415
+ },
416
+ env: params.env
417
+ });
418
+ try {
419
+ operation = await params.provider.executeSignerIntent({
420
+ walletId: params.walletId,
421
+ requestId: params.requestId,
422
+ intent: params.intent
423
+ });
424
+ } catch (error) {
425
+ await updateExternalSubmission({
426
+ key: entry.key,
427
+ expectedStates: ["submitting"],
428
+ state: "unknown",
429
+ patch: {
430
+ signerRequestId: params.requestId,
431
+ reason: "signer response was lost; reconcile the existing request without re-executing",
432
+ details: entry.details
433
+ },
434
+ env: params.env
435
+ });
436
+ throw new Error("Jupiter Trigger execution result is unknown; reconcile the signer request and do not retry it", { cause: error });
437
+ }
438
+ } else {
439
+ throw new Error(`autonomous Jupiter Trigger intent cannot execute from ${entry.state}`);
440
+ }
441
+ assertTriggerOperationIdentity({
442
+ ...params,
443
+ operation,
444
+ signerIntentDigest: entry.signerIntentDigest
445
+ });
446
+ entry = await persistAutonomousOperation({
447
+ entry,
448
+ operation,
449
+ env: params.env
450
+ });
451
+ const stored = storedOperation(entry);
452
+ if (!stored) {
453
+ throw new Error("Jupiter Trigger durable operation result was not persisted");
454
+ }
163
455
  return {
164
- ok: false,
165
- code: "wallet_limit_slippage_invalid",
166
- message: "limit order slippageBps must be between 1 and 1000"
456
+ operation: stored,
457
+ order: requireConfirmedTriggerOperation({
458
+ ...params,
459
+ operation: stored
460
+ })
167
461
  };
462
+ } finally {
463
+ await release();
168
464
  }
169
- const policy = validateSolanaSwapIntentPolicy({
170
- config: params.config,
171
- inputMint: params.inputMint,
172
- outputMint: params.outputMint,
173
- amount: params.amount,
174
- autonomous: params.autonomous
175
- });
176
- return policy.ok ? { ok: true } : {
177
- ok: false,
178
- code: policy.code ?? "wallet_limit_policy_rejected",
179
- message: policy.message ?? "limit order rejected by wallet policy"
180
- };
181
465
  }
182
466
  async function createJupiterTriggerLimitOrder(params) {
183
467
  const env = params.env ?? process.env;
184
- const apiKey = resolveTriggerApiKey(env);
185
- if (!apiKey) {
186
- throw new Error("Jupiter Trigger requires FASED_JUPITER_API_KEY or JUPITER_API_KEY");
468
+ const mode = params.autonomous ? "autonomous" : "reviewed";
469
+ const intentId = params.intentId?.trim();
470
+ if (!intentId) {
471
+ throw new Error("Jupiter Trigger create requires a stable caller-owned intentId");
187
472
  }
473
+ const inputMint = params.inputMint.trim();
474
+ const outputMint = params.outputMint.trim();
475
+ const triggerMint = params.triggerMint.trim();
476
+ const amount = positiveBaseUnits(params.amount, "limit order amount");
477
+ const triggerPriceUsd = canonicalJupiterTriggerPrice(params.triggerPriceUsd);
478
+ const slippageBps = normalizeTriggerSlippage(params.slippageBps);
479
+ const callerExpiry = triggerExpiryIdentity(params);
188
480
  const policy = validateJupiterTriggerLimitOrderIntent({
189
481
  config: params.config,
190
- inputMint: params.inputMint,
191
- outputMint: params.outputMint,
192
- amount: params.amount,
482
+ inputMint,
483
+ outputMint,
484
+ amount,
193
485
  triggerCondition: params.triggerCondition,
194
- triggerPriceUsd: params.triggerPriceUsd,
195
- slippageBps: params.slippageBps,
486
+ triggerPriceUsd,
487
+ slippageBps,
196
488
  autonomous: params.autonomous
197
489
  });
198
490
  if (!policy.ok) {
199
491
  throw new Error(policy.message);
200
492
  }
201
- const balance = await validateSolanaSwapInputBalance({
202
- rpcUrl: params.rpcUrl,
203
- ownerAddress: params.walletAddress,
204
- inputMint: params.inputMint,
205
- amount: params.amount
206
- });
207
- if (!balance.ok) {
208
- throw new Error(balance.message);
493
+ if (!triggerMint) {
494
+ throw new Error("Jupiter Trigger create requires an exact trigger mint");
209
495
  }
210
- const token = await authenticateJupiterTrigger({
211
- provider: params.provider,
496
+ const requestId = triggerRequestId({
497
+ action: "create",
498
+ mode,
212
499
  walletId: params.walletId,
213
- walletAddress: params.walletAddress,
214
- apiKey,
215
- rpcUrl: params.rpcUrl,
216
- env
217
- });
218
- const vault = await getOrRegisterJupiterVault({
219
- apiKey,
220
- token,
221
- env
222
- });
223
- const deposit = await triggerJson({
224
- path: "/deposit/craft",
225
- method: "POST",
226
- apiKey,
227
- token,
228
- body: {
229
- inputMint: params.inputMint,
230
- outputMint: params.outputMint,
231
- userAddress: params.walletAddress,
232
- amount: params.amount
233
- },
234
- env
235
- });
236
- const depositTx = stringValue(deposit.transaction);
237
- const depositRequestId = stringValue(deposit.requestId);
238
- if (!depositTx || !depositRequestId) {
239
- throw new Error("jupiter trigger did not return a deposit transaction");
240
- }
241
- const depositInspection = await inspectSerializedSolanaSwapTransaction({
242
- serializedTxBase64: depositTx,
243
- expectedSigner: params.walletAddress,
244
- rpcUrl: params.rpcUrl
500
+ intentId
245
501
  });
246
- if (!depositInspection.ok) {
247
- throw new Error(depositInspection.message);
248
- }
249
- if (depositInspection.routeProgramIds.length > 0) {
250
- throw new Error(`jupiter trigger deposit uses unexpected program ${depositInspection.routeProgramIds[0]}`);
251
- }
252
- const daily = enforceWalletDailyCap({
253
- config: params.config,
254
- chain: "solana",
255
- amount: params.amount,
256
- tokenMint: params.inputMint === SOLANA_NATIVE_MINT ? undefined : params.inputMint,
502
+ const bound = await bindTriggerIntent({
503
+ kind: "jupiter-trigger-create",
504
+ action: "create",
505
+ mode,
257
506
  walletId: params.walletId,
507
+ intentId,
508
+ callerIntent: {
509
+ owner: params.walletAddress,
510
+ inputMint,
511
+ outputMint,
512
+ inputAmount: amount,
513
+ triggerMint,
514
+ condition: params.triggerCondition,
515
+ targetPriceUsd: triggerPriceUsd,
516
+ slippageBps,
517
+ expiry: callerExpiry
518
+ },
519
+ buildIntent: async () => {
520
+ const expiry = normalizeTriggerExpiry({
521
+ expiresAt: params.expiresAt,
522
+ expirySeconds: params.expirySeconds
523
+ });
524
+ if (params.rpcUrl?.trim()) {
525
+ const balance = await validateSolanaSwapInputBalance({
526
+ rpcUrl: params.rpcUrl,
527
+ ownerAddress: params.walletAddress,
528
+ inputMint,
529
+ amount
530
+ });
531
+ if (!balance.ok) {
532
+ throw new Error(balance.message);
533
+ }
534
+ }
535
+ const program = await resolveTriggerTransferProgram({
536
+ mint: inputMint,
537
+ rpcUrl: params.rpcUrl
538
+ });
539
+ return {
540
+ type: "solana.jupiter.trigger.create",
541
+ jupiter: {
542
+ owner: params.walletAddress,
543
+ inputMint,
544
+ outputMint,
545
+ inputAmount: amount,
546
+ maxInputAmount: amount,
547
+ minimumOutputAmount: "0",
548
+ maxFeeLamports: resolveJupiterMaxFeeLamports(env),
549
+ programs: [program],
550
+ trigger: {
551
+ operation: "create",
552
+ program,
553
+ triggerMint,
554
+ condition: params.triggerCondition,
555
+ targetPriceUsd: triggerPriceUsd,
556
+ slippageBps,
557
+ expiresAt: expiry.expiresAt,
558
+ expectedOrderState: "new"
559
+ }
560
+ }
561
+ };
562
+ },
258
563
  env
259
564
  });
260
- if (!daily.ok) {
261
- throw new Error(daily.message ?? daily.code ?? "wallet daily cap exceeded");
565
+ if (mode === "reviewed") {
566
+ const review = await prepareReviewedTrigger({
567
+ provider: params.provider,
568
+ walletId: params.walletId,
569
+ requestId,
570
+ entry: bound.entry,
571
+ intent: bound.intent,
572
+ env
573
+ });
574
+ return {
575
+ ok: true,
576
+ mode,
577
+ review,
578
+ intent: bound.intent
579
+ };
262
580
  }
263
- const signedDeposit = await signSerializedSolanaTx({
581
+ const executed = await executeAutonomousTrigger({
264
582
  provider: params.provider,
265
583
  walletId: params.walletId,
266
- serializedTxBase64: depositTx,
267
- amount: params.amount,
268
- tokenMint: params.inputMint === SOLANA_NATIVE_MINT ? undefined : params.inputMint
269
- });
270
- const orderBody = {
271
- orderType: "single",
272
- depositRequestId,
273
- depositSignedTx: signedDeposit.signedTxBase64,
274
- userPubkey: params.walletAddress,
275
- inputMint: params.inputMint,
276
- inputAmount: params.amount,
277
- outputMint: params.outputMint,
278
- triggerMint: params.triggerMint || params.inputMint,
279
- triggerCondition: params.triggerCondition,
280
- triggerPriceUsd: params.triggerPriceUsd,
281
- slippageBps: params.slippageBps ?? 100,
282
- expiresAt: normalizeTriggerExpiry({
283
- expiresAt: params.expiresAt,
284
- expirySeconds: params.expirySeconds
285
- })
286
- };
287
- const raw = await triggerJson({
288
- path: "/orders/price",
289
- method: "POST",
290
- apiKey,
291
- token,
292
- body: orderBody,
584
+ requestId,
585
+ entry: bound.entry,
586
+ intent: bound.intent,
587
+ action: "create",
293
588
  env
294
589
  });
295
590
  return {
296
591
  ok: true,
297
- vault,
298
- order: {
299
- id: stringValue(raw.id),
300
- txSignature: stringValue(raw.txSignature),
301
- raw
302
- }
592
+ mode,
593
+ ...executed
303
594
  };
304
595
  }
305
596
  async function listJupiterTriggerOrders(params) {
306
- const env = params.env ?? process.env;
307
- const apiKey = resolveTriggerApiKey(env);
308
- if (!apiKey) {
309
- throw new Error("Jupiter Trigger requires FASED_JUPITER_API_KEY or JUPITER_API_KEY");
597
+ if (!params.provider.listJupiterTriggerOrders) {
598
+ throw new Error("Jupiter Trigger history requires the signer-owned sanitized history capability");
310
599
  }
311
- const token = await authenticateJupiterTrigger({
312
- provider: params.provider,
600
+ const history = await params.provider.listJupiterTriggerOrders({
313
601
  walletId: params.walletId,
314
- walletAddress: params.walletAddress,
315
- apiKey,
316
- rpcUrl: params.rpcUrl,
317
- env
318
- });
319
- const search = new URLSearchParams();
320
- if (params.state) {
321
- search.set("state", params.state);
322
- }
323
- if (params.mint?.trim()) {
324
- search.set("mint", params.mint.trim());
325
- }
326
- search.set("limit", String(Math.max(1, Math.min(100, Math.floor(params.limit ?? 20)))));
327
- search.set("offset", String(Math.max(0, Math.floor(params.offset ?? 0))));
328
- const raw = await triggerJson({
329
- path: `/orders/history?${search.toString()}`,
330
- apiKey,
331
- token,
332
- env
602
+ state: params.state
333
603
  });
604
+ const mint = params.mint?.trim();
605
+ const matching = mint ? history.orders.filter((order) => order.inputMint === mint || order.outputMint === mint || order.triggerMint === mint) : history.orders;
606
+ const offset = Math.max(0, Math.floor(params.offset ?? 0));
607
+ const limit = Math.max(1, Math.min(100, Math.floor(params.limit ?? 20)));
334
608
  return {
335
- orders: Array.isArray(raw.orders) ? raw.orders : [],
336
- pagination: raw.pagination,
337
- raw
609
+ orders: matching.slice(offset, offset + limit),
610
+ pagination: {
611
+ total: matching.length,
612
+ limit,
613
+ offset
614
+ }
338
615
  };
339
616
  }
340
617
  async function cancelJupiterTriggerOrder(params) {
341
618
  const env = params.env ?? process.env;
342
- const apiKey = resolveTriggerApiKey(env);
343
- if (!apiKey) {
344
- throw new Error("Jupiter Trigger requires FASED_JUPITER_API_KEY or JUPITER_API_KEY");
345
- }
619
+ const mode = params.autonomous ? "autonomous" : "reviewed";
346
620
  const orderId = params.orderId.trim();
347
- if (!orderId) {
348
- throw new Error("orderId is required");
621
+ const intentId = params.intentId?.trim();
622
+ if (!orderId || !intentId) {
623
+ throw new Error("Jupiter Trigger cancel requires exact orderId and stable caller-owned intentId");
349
624
  }
350
- const token = await authenticateJupiterTrigger({
351
- provider: params.provider,
625
+ const requestId = triggerRequestId({
626
+ action: "cancel",
627
+ mode,
352
628
  walletId: params.walletId,
353
- walletAddress: params.walletAddress,
354
- apiKey,
355
- rpcUrl: params.rpcUrl,
356
- env
629
+ intentId
357
630
  });
358
- const cancel = await triggerJson({
359
- path: `/orders/price/cancel/${encodeURIComponent(orderId)}`,
360
- method: "POST",
361
- apiKey,
362
- token,
631
+ const existing = getExternalSubmissionByExplicitIntent({
632
+ kind: "jupiter-trigger-cancel",
633
+ walletId: params.walletId,
634
+ explicitIntentId: triggerExplicitIntentId({
635
+ action: "cancel",
636
+ mode,
637
+ intentId
638
+ }),
363
639
  env
364
640
  });
365
- const transaction = stringValue(cancel.transaction);
366
- const cancelRequestId = stringValue(cancel.requestId);
367
- if (!transaction || !cancelRequestId) {
368
- throw new Error("jupiter trigger did not return a cancel withdrawal transaction");
369
- }
370
- const inspection = await inspectSerializedSolanaSwapTransaction({
371
- serializedTxBase64: transaction,
372
- expectedSigner: params.walletAddress,
373
- rpcUrl: params.rpcUrl
374
- });
375
- if (!inspection.ok) {
376
- throw new Error(inspection.message);
641
+ if (existing) {
642
+ const intent = existing.details?.semanticIntent;
643
+ if (!isStoredTriggerIntent(intent, "cancel") || intent.jupiter.owner !== params.walletAddress || intent.jupiter.trigger?.order !== orderId) {
644
+ throw new Error("Jupiter Trigger intentId is already bound to different immutable terms");
645
+ }
646
+ if (mode === "reviewed") {
647
+ const review = await prepareReviewedTrigger({
648
+ provider: params.provider,
649
+ walletId: params.walletId,
650
+ requestId,
651
+ entry: existing,
652
+ intent,
653
+ env
654
+ });
655
+ return {
656
+ ok: true,
657
+ mode,
658
+ review,
659
+ intent
660
+ };
661
+ }
662
+ const executed = await executeAutonomousTrigger({
663
+ provider: params.provider,
664
+ walletId: params.walletId,
665
+ requestId,
666
+ entry: existing,
667
+ intent,
668
+ action: "cancel",
669
+ env
670
+ });
671
+ return {
672
+ ok: true,
673
+ mode,
674
+ ...executed
675
+ };
377
676
  }
378
- if (inspection.routeProgramIds.length > 0) {
379
- throw new Error(`jupiter trigger cancel uses unexpected program ${inspection.routeProgramIds[0]}`);
677
+ if (!params.provider.listJupiterTriggerOrders) {
678
+ throw new Error("Jupiter Trigger cancel requires signer-owned sanitized order history and exact refund terms");
380
679
  }
381
- const signed = await signSerializedSolanaTx({
382
- provider: params.provider,
680
+ const history = await params.provider.listJupiterTriggerOrders({
383
681
  walletId: params.walletId,
384
- serializedTxBase64: transaction,
385
- amount: "0"
682
+ state: "active"
386
683
  });
387
- const raw = await triggerJson({
388
- path: `/orders/price/confirm-cancel/${encodeURIComponent(orderId)}`,
389
- method: "POST",
390
- apiKey,
391
- token,
392
- body: {
393
- signedTransaction: signed.signedTxBase64,
394
- cancelRequestId
684
+ const order = history.orders.find((candidate) => candidate.orderId === orderId);
685
+ if (!order || order.orderType !== "single" || order.orderState !== "open" || !order.cancel) {
686
+ throw new Error("Jupiter Trigger order is not an exact open cancellable single order");
687
+ }
688
+ const refundAmount = positiveBaseUnits(order.cancel.refundAmount, "Trigger refund amount");
689
+ const bound = await bindTriggerIntent({
690
+ kind: "jupiter-trigger-cancel",
691
+ action: "cancel",
692
+ mode,
693
+ walletId: params.walletId,
694
+ intentId,
695
+ callerIntent: {
696
+ owner: params.walletAddress,
697
+ orderId,
698
+ orderState: order.orderState,
699
+ refundMint: order.cancel.refundMint,
700
+ refundAmount,
701
+ destinationTokenAccount: order.cancel.destinationTokenAccount,
702
+ program: order.cancel.program
395
703
  },
704
+ buildIntent: async () => ({
705
+ type: "solana.jupiter.trigger.cancel",
706
+ jupiter: {
707
+ owner: params.walletAddress,
708
+ outputMint: order.cancel?.refundMint,
709
+ minimumOutputAmount: refundAmount,
710
+ maxFeeLamports: resolveJupiterMaxFeeLamports(env),
711
+ destinationTokenAccount: order.cancel?.destinationTokenAccount,
712
+ programs: [order.cancel?.program ?? ""],
713
+ trigger: {
714
+ operation: "cancel",
715
+ program: order.cancel?.program ?? "",
716
+ order: order.orderId,
717
+ expectedOrderState: order.cancel?.expectedOrderState ?? "open"
718
+ }
719
+ }
720
+ }),
721
+ env
722
+ });
723
+ if (mode === "reviewed") {
724
+ const review = await prepareReviewedTrigger({
725
+ provider: params.provider,
726
+ walletId: params.walletId,
727
+ requestId,
728
+ entry: bound.entry,
729
+ intent: bound.intent,
730
+ env
731
+ });
732
+ return {
733
+ ok: true,
734
+ mode,
735
+ review,
736
+ intent: bound.intent
737
+ };
738
+ }
739
+ const executed = await executeAutonomousTrigger({
740
+ provider: params.provider,
741
+ walletId: params.walletId,
742
+ requestId,
743
+ entry: bound.entry,
744
+ intent: bound.intent,
745
+ action: "cancel",
396
746
  env
397
747
  });
398
748
  return {
399
749
  ok: true,
400
- raw,
401
- tx: {
402
- ok: true,
403
- chain: "solana",
404
- txHash: stringValue(raw.txSignature) ?? "",
405
- signer: params.walletAddress,
406
- metadata: {
407
- provider: "jupiter-trigger",
408
- orderId
409
- }
410
- }
750
+ mode,
751
+ ...executed
411
752
  };
412
753
  }
413
- function readJupiterTriggerPositiveNumber(value) {
414
- return positiveNumber(value);
415
- }
416
754
 
417
755
  //#endregion
418
756
  export { cancelJupiterTriggerOrder, createJupiterTriggerLimitOrder, listJupiterTriggerOrders, readJupiterTriggerPositiveNumber, validateJupiterTriggerLimitOrderIntent };