@mysten-incubation/devstack 0.0.1 → 0.1.1

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 (838) hide show
  1. package/README.md +8 -4
  2. package/dashboard-ui/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  3. package/dashboard-ui/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  4. package/dashboard-ui/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  5. package/dashboard-ui/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  6. package/dashboard-ui/assets/geist-mono-cyrillic-ext-wght-normal-I4S5GZfc.woff2 +0 -0
  7. package/dashboard-ui/assets/geist-mono-cyrillic-wght-normal-BmXc_FBt.woff2 +0 -0
  8. package/dashboard-ui/assets/geist-mono-latin-ext-wght-normal-DrnZ1wKl.woff2 +0 -0
  9. package/dashboard-ui/assets/geist-mono-latin-wght-normal-B_7UjwxQ.woff2 +0 -0
  10. package/dashboard-ui/assets/geist-mono-symbols2-wght-normal-GZpp1pK2.woff2 +0 -0
  11. package/dashboard-ui/assets/geist-mono-vietnamese-wght-normal-D8KDMBhC.woff2 +0 -0
  12. package/dashboard-ui/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  13. package/dashboard-ui/assets/index-Bmi1UtAg.js +1356 -0
  14. package/dashboard-ui/assets/index-D5EShVt4.js +3 -0
  15. package/dashboard-ui/assets/index-Deml9drg.css +1 -0
  16. package/dashboard-ui/index.html +13 -0
  17. package/dist/api/define-capabilities.d.mts +14 -3
  18. package/dist/api/define-capabilities.mjs +18 -1
  19. package/dist/api/define-capabilities.mjs.map +1 -1
  20. package/dist/api/define-devstack.d.mts +1 -1
  21. package/dist/api/define-devstack.mjs +6 -26
  22. package/dist/api/define-devstack.mjs.map +1 -1
  23. package/dist/api/define-plugin.d.mts +1 -0
  24. package/dist/api/define-plugin.mjs +2 -0
  25. package/dist/api/inference-network.d.mts +132 -0
  26. package/dist/api/inference-network.mjs +105 -16
  27. package/dist/api/inference-network.mjs.map +1 -1
  28. package/dist/api/plugin-errors.d.mts +7 -0
  29. package/dist/api/run-stack.d.mts +20 -9
  30. package/dist/api/run-stack.mjs +56 -29
  31. package/dist/api/run-stack.mjs.map +1 -1
  32. package/dist/build-integrations/playwright/config.d.mts +6 -4
  33. package/dist/build-integrations/playwright/config.mjs +5 -3
  34. package/dist/build-integrations/playwright/config.mjs.map +1 -1
  35. package/dist/build-integrations/playwright/errors.d.mts +1 -1
  36. package/dist/build-integrations/playwright/global-setup.d.mts +43 -17
  37. package/dist/build-integrations/playwright/global-setup.mjs +250 -13
  38. package/dist/build-integrations/playwright/global-setup.mjs.map +1 -1
  39. package/dist/build-integrations/playwright/index.d.mts +5 -3
  40. package/dist/build-integrations/playwright/index.mjs +4 -2
  41. package/dist/build-integrations/playwright/stack-context.d.mts +0 -1
  42. package/dist/build-integrations/playwright/stack-context.mjs +24 -63
  43. package/dist/build-integrations/playwright/stack-context.mjs.map +1 -1
  44. package/dist/build-integrations/playwright/wallet-context.d.mts +7 -10
  45. package/dist/build-integrations/playwright/wallet-context.mjs +8 -13
  46. package/dist/build-integrations/playwright/wallet-context.mjs.map +1 -1
  47. package/dist/build-integrations/runtime/cold-start-url.d.mts +5 -0
  48. package/dist/build-integrations/runtime/cold-start-url.mjs +4 -3
  49. package/dist/build-integrations/runtime/cold-start-url.mjs.map +1 -1
  50. package/dist/build-integrations/runtime/conventional-routes.d.mts +51 -0
  51. package/dist/build-integrations/runtime/conventional-routes.mjs +92 -0
  52. package/dist/build-integrations/runtime/conventional-routes.mjs.map +1 -0
  53. package/dist/build-integrations/runtime/discover.d.mts +38 -30
  54. package/dist/build-integrations/runtime/discover.mjs +73 -70
  55. package/dist/build-integrations/runtime/discover.mjs.map +1 -1
  56. package/dist/build-integrations/runtime/endpoint-registry.d.mts +3 -1
  57. package/dist/build-integrations/runtime/endpoint-registry.mjs +3 -1
  58. package/dist/build-integrations/runtime/endpoint-registry.mjs.map +1 -1
  59. package/dist/build-integrations/runtime/index.d.mts +7 -2
  60. package/dist/build-integrations/runtime/index.mjs +9 -2
  61. package/dist/build-integrations/runtime/manifest-types.d.mts +2 -0
  62. package/dist/build-integrations/runtime/manifest-types.mjs +3 -0
  63. package/dist/build-integrations/runtime/playwright-stack-context-slot.d.mts +29 -0
  64. package/dist/build-integrations/runtime/playwright-stack-context-slot.mjs +10 -0
  65. package/dist/build-integrations/runtime/playwright-stack-context-slot.mjs.map +1 -0
  66. package/dist/build-integrations/runtime/read-stack-context.d.mts +1 -1
  67. package/dist/build-integrations/runtime/read-stack-context.mjs +10 -4
  68. package/dist/build-integrations/runtime/read-stack-context.mjs.map +1 -1
  69. package/dist/build-integrations/runtime/resolve-discovery-env.d.mts +48 -0
  70. package/dist/build-integrations/runtime/resolve-discovery-env.mjs +42 -0
  71. package/dist/build-integrations/runtime/resolve-discovery-env.mjs.map +1 -0
  72. package/dist/build-integrations/runtime/stack-context.d.mts +1 -1
  73. package/dist/build-integrations/runtime/wallet-paths.mjs +2 -0
  74. package/dist/build-integrations/vite/index.d.mts +51 -0
  75. package/dist/build-integrations/vite/index.mjs +73 -0
  76. package/dist/build-integrations/vite/index.mjs.map +1 -0
  77. package/dist/build-integrations/vitest/env.d.mts +4 -3
  78. package/dist/build-integrations/vitest/env.mjs +6 -4
  79. package/dist/build-integrations/vitest/env.mjs.map +1 -1
  80. package/dist/build-integrations/vitest/errors.d.mts +25 -4
  81. package/dist/build-integrations/vitest/errors.mjs +15 -2
  82. package/dist/build-integrations/vitest/errors.mjs.map +1 -1
  83. package/dist/build-integrations/vitest/index.d.mts +2 -2
  84. package/dist/build-integrations/vitest/index.mjs +3 -3
  85. package/dist/build-integrations/vitest/setup.d.mts +4 -2
  86. package/dist/build-integrations/vitest/setup.mjs +2 -2
  87. package/dist/build-integrations/vitest/setup.mjs.map +1 -1
  88. package/dist/build-integrations/vitest/stack-context.d.mts +0 -1
  89. package/dist/build-integrations/vitest/stack-context.mjs +33 -13
  90. package/dist/build-integrations/vitest/stack-context.mjs.map +1 -1
  91. package/dist/cli/bail.mjs +23 -0
  92. package/dist/cli/bail.mjs.map +1 -0
  93. package/dist/{surfaces/cli/commands → cli}/doctor-probes.mjs +26 -16
  94. package/dist/cli/doctor-probes.mjs.map +1 -0
  95. package/dist/cli/main.d.mts +15 -1
  96. package/dist/cli/main.mjs +166 -482
  97. package/dist/cli/main.mjs.map +1 -1
  98. package/dist/cli/prune-direct.mjs +31 -201
  99. package/dist/cli/prune-direct.mjs.map +1 -1
  100. package/dist/cli/snapshot-reader.mjs +14 -11
  101. package/dist/cli/snapshot-reader.mjs.map +1 -1
  102. package/dist/cli/up-lifecycle.mjs +4 -1
  103. package/dist/cli/up-lifecycle.mjs.map +1 -1
  104. package/dist/cli/wirings/apply.mjs +95 -0
  105. package/dist/cli/wirings/apply.mjs.map +1 -0
  106. package/dist/cli/wirings/build-verb-layers.mjs +42 -0
  107. package/dist/cli/wirings/build-verb-layers.mjs.map +1 -0
  108. package/dist/cli/wirings/config-loader.mjs +69 -0
  109. package/dist/cli/wirings/config-loader.mjs.map +1 -0
  110. package/dist/cli/wirings/engine-command.mjs +30 -0
  111. package/dist/cli/wirings/engine-command.mjs.map +1 -0
  112. package/dist/cli/wirings/identity.mjs +72 -0
  113. package/dist/cli/wirings/identity.mjs.map +1 -0
  114. package/dist/cli/wirings/provide-file-system.mjs +7 -0
  115. package/dist/cli/wirings/provide-file-system.mjs.map +1 -0
  116. package/dist/cli/wirings/snapshot.mjs +177 -0
  117. package/dist/cli/wirings/snapshot.mjs.map +1 -0
  118. package/dist/cli/wirings/up.mjs +287 -0
  119. package/dist/cli/wirings/up.mjs.map +1 -0
  120. package/dist/cli/wirings/wipe.mjs +40 -0
  121. package/dist/cli/wirings/wipe.mjs.map +1 -0
  122. package/dist/contracts/capability-decl.d.mts +0 -2
  123. package/dist/contracts/codegenable.d.mts +43 -0
  124. package/dist/contracts/container-runtime.d.mts +26 -1
  125. package/dist/contracts/faucet-strategy.d.mts +25 -0
  126. package/dist/contracts/funding-strategy.d.mts +42 -0
  127. package/dist/contracts/plugin-expander.mjs +60 -0
  128. package/dist/contracts/plugin-expander.mjs.map +1 -0
  129. package/dist/contracts/projection.d.mts +5 -3
  130. package/dist/contracts/renderer.d.mts +23 -0
  131. package/dist/contracts/routable.d.mts +14 -1
  132. package/dist/contracts/snapshotable.d.mts +25 -3
  133. package/dist/contracts/wallet-protocol.d.mts +52 -0
  134. package/dist/contracts/wallet-protocol.mjs +52 -0
  135. package/dist/contracts/wallet-protocol.mjs.map +1 -0
  136. package/dist/index.d.mts +26 -25
  137. package/dist/index.mjs +20 -13
  138. package/dist/{runtime → orchestrators}/built-in-plugin-layers.mjs +10 -5
  139. package/dist/orchestrators/built-in-plugin-layers.mjs.map +1 -0
  140. package/dist/orchestrators/codegen/bindings.d.mts +1 -2
  141. package/dist/orchestrators/codegen/bindings.mjs +52 -186
  142. package/dist/orchestrators/codegen/bindings.mjs.map +1 -1
  143. package/dist/orchestrators/codegen/emit.mjs +19 -1
  144. package/dist/orchestrators/codegen/emit.mjs.map +1 -1
  145. package/dist/orchestrators/codegen/errors.mjs +8 -3
  146. package/dist/orchestrators/codegen/errors.mjs.map +1 -1
  147. package/dist/orchestrators/codegen/format.mjs +47 -39
  148. package/dist/orchestrators/codegen/format.mjs.map +1 -1
  149. package/dist/orchestrators/codegen/gitignore.mjs +3 -1
  150. package/dist/orchestrators/codegen/gitignore.mjs.map +1 -1
  151. package/dist/orchestrators/codegen/output-location.mjs +41 -0
  152. package/dist/orchestrators/codegen/output-location.mjs.map +1 -0
  153. package/dist/orchestrators/codegen/paths.d.mts +1 -1
  154. package/dist/orchestrators/codegen/paths.mjs +40 -14
  155. package/dist/orchestrators/codegen/paths.mjs.map +1 -1
  156. package/dist/orchestrators/codegen/permissions.mjs +3 -1
  157. package/dist/orchestrators/codegen/permissions.mjs.map +1 -1
  158. package/dist/orchestrators/codegen/service.mjs +157 -105
  159. package/dist/orchestrators/codegen/service.mjs.map +1 -1
  160. package/dist/orchestrators/lifecycle-prune/errors.mjs +31 -0
  161. package/dist/orchestrators/lifecycle-prune/errors.mjs.map +1 -0
  162. package/dist/orchestrators/lifecycle-prune/index.mjs +350 -0
  163. package/dist/orchestrators/lifecycle-prune/index.mjs.map +1 -0
  164. package/dist/orchestrators/router/cleanup.mjs +26 -27
  165. package/dist/orchestrators/router/cleanup.mjs.map +1 -1
  166. package/dist/orchestrators/router/entrypoints.mjs +2 -2
  167. package/dist/orchestrators/router/entrypoints.mjs.map +1 -1
  168. package/dist/orchestrators/router/file-provider.mjs +14 -5
  169. package/dist/orchestrators/router/file-provider.mjs.map +1 -1
  170. package/dist/orchestrators/router/hostname.mjs +19 -55
  171. package/dist/orchestrators/router/hostname.mjs.map +1 -1
  172. package/dist/orchestrators/router/index.mjs +11 -0
  173. package/dist/orchestrators/router/profile.mjs +2 -2
  174. package/dist/orchestrators/router/sentinels.mjs +26 -0
  175. package/dist/orchestrators/router/sentinels.mjs.map +1 -0
  176. package/dist/orchestrators/router/service.mjs +40 -37
  177. package/dist/orchestrators/router/service.mjs.map +1 -1
  178. package/dist/orchestrators/router/traefik-container.mjs +27 -16
  179. package/dist/orchestrators/router/traefik-container.mjs.map +1 -1
  180. package/dist/{substrate/runtime → orchestrators}/run.mjs +26 -21
  181. package/dist/orchestrators/run.mjs.map +1 -0
  182. package/dist/orchestrators/runtime-composition.d.mts +1 -1
  183. package/dist/orchestrators/runtime-composition.mjs +123 -39
  184. package/dist/orchestrators/runtime-composition.mjs.map +1 -1
  185. package/dist/orchestrators/snapshot/capture-command.d.mts +1 -0
  186. package/dist/orchestrators/snapshot/capture-command.mjs +25 -0
  187. package/dist/orchestrators/snapshot/capture-command.mjs.map +1 -0
  188. package/dist/orchestrators/snapshot/capture.mjs +42 -28
  189. package/dist/orchestrators/snapshot/capture.mjs.map +1 -1
  190. package/dist/orchestrators/snapshot/descriptor.mjs +35 -10
  191. package/dist/orchestrators/snapshot/descriptor.mjs.map +1 -1
  192. package/dist/orchestrators/snapshot/identity-guard.mjs +1 -1
  193. package/dist/orchestrators/snapshot/index.mjs +13 -0
  194. package/dist/orchestrators/snapshot/integrity.d.mts +1 -1
  195. package/dist/orchestrators/snapshot/integrity.mjs +73 -17
  196. package/dist/orchestrators/snapshot/integrity.mjs.map +1 -1
  197. package/dist/orchestrators/snapshot/pending-marker.d.mts +1 -0
  198. package/dist/orchestrators/snapshot/pending-marker.mjs +99 -0
  199. package/dist/orchestrators/snapshot/pending-marker.mjs.map +1 -0
  200. package/dist/orchestrators/snapshot/phase-error.mjs +23 -0
  201. package/dist/orchestrators/snapshot/phase-error.mjs.map +1 -0
  202. package/dist/orchestrators/snapshot/prune.mjs +20 -55
  203. package/dist/orchestrators/snapshot/prune.mjs.map +1 -1
  204. package/dist/orchestrators/snapshot/recover-pending.d.mts +1 -0
  205. package/dist/orchestrators/snapshot/recover-pending.mjs +223 -0
  206. package/dist/orchestrators/snapshot/recover-pending.mjs.map +1 -0
  207. package/dist/orchestrators/snapshot/restore.mjs +118 -84
  208. package/dist/orchestrators/snapshot/restore.mjs.map +1 -1
  209. package/dist/orchestrators/snapshot/service.mjs +53 -56
  210. package/dist/orchestrators/snapshot/service.mjs.map +1 -1
  211. package/dist/orchestrators/snapshot/state-document.d.mts +1 -0
  212. package/dist/orchestrators/snapshot/state-document.mjs +47 -7
  213. package/dist/orchestrators/snapshot/state-document.mjs.map +1 -1
  214. package/dist/orchestrators/snapshot/wipe.mjs +67 -10
  215. package/dist/orchestrators/snapshot/wipe.mjs.map +1 -1
  216. package/dist/plugins/account/codegen.mjs +9 -8
  217. package/dist/plugins/account/codegen.mjs.map +1 -1
  218. package/dist/plugins/account/errors.d.mts +33 -6
  219. package/dist/plugins/account/errors.mjs.map +1 -1
  220. package/dist/plugins/account/funding.d.mts +29 -19
  221. package/dist/plugins/account/funding.mjs +84 -66
  222. package/dist/plugins/account/funding.mjs.map +1 -1
  223. package/dist/plugins/account/index.d.mts +2 -4
  224. package/dist/plugins/account/index.mjs +64 -31
  225. package/dist/plugins/account/index.mjs.map +1 -1
  226. package/dist/plugins/account/keypair.mjs +6 -9
  227. package/dist/plugins/account/keypair.mjs.map +1 -1
  228. package/dist/plugins/account/lease.mjs +1 -0
  229. package/dist/plugins/account/lease.mjs.map +1 -1
  230. package/dist/plugins/account/registry.d.mts +14 -1
  231. package/dist/plugins/account/registry.mjs +18 -18
  232. package/dist/plugins/account/registry.mjs.map +1 -1
  233. package/dist/plugins/account/service.d.mts +23 -4
  234. package/dist/plugins/account/service.mjs +83 -45
  235. package/dist/plugins/account/service.mjs.map +1 -1
  236. package/dist/plugins/account/snapshot.mjs +2 -5
  237. package/dist/plugins/account/snapshot.mjs.map +1 -1
  238. package/dist/plugins/account/spans.mjs +16 -0
  239. package/dist/plugins/account/spans.mjs.map +1 -0
  240. package/dist/plugins/account/variants/keystore.mjs +6 -8
  241. package/dist/plugins/account/variants/keystore.mjs.map +1 -1
  242. package/dist/plugins/action/build-context.d.mts +3 -2
  243. package/dist/plugins/action/errors.d.mts +16 -12
  244. package/dist/plugins/action/errors.mjs.map +1 -1
  245. package/dist/plugins/action/execute.mjs +65 -103
  246. package/dist/plugins/action/execute.mjs.map +1 -1
  247. package/dist/plugins/action/index.d.mts +0 -2
  248. package/dist/plugins/action/index.mjs +17 -13
  249. package/dist/plugins/action/index.mjs.map +1 -1
  250. package/dist/plugins/action/service.mjs +38 -35
  251. package/dist/plugins/action/service.mjs.map +1 -1
  252. package/dist/plugins/action/spans.mjs +11 -0
  253. package/dist/plugins/action/spans.mjs.map +1 -0
  254. package/dist/plugins/coin/codegen.mjs +9 -8
  255. package/dist/plugins/coin/codegen.mjs.map +1 -1
  256. package/dist/plugins/coin/discovery.mjs +8 -4
  257. package/dist/plugins/coin/discovery.mjs.map +1 -1
  258. package/dist/plugins/coin/index.d.mts +11 -29
  259. package/dist/plugins/coin/index.mjs +56 -27
  260. package/dist/plugins/coin/index.mjs.map +1 -1
  261. package/dist/plugins/coin/metadata.mjs +8 -15
  262. package/dist/plugins/coin/metadata.mjs.map +1 -1
  263. package/dist/plugins/coin/mint.d.mts +30 -11
  264. package/dist/plugins/coin/mint.mjs +78 -74
  265. package/dist/plugins/coin/mint.mjs.map +1 -1
  266. package/dist/plugins/coin/registry.mjs +4 -7
  267. package/dist/plugins/coin/registry.mjs.map +1 -1
  268. package/dist/plugins/coin/service.d.mts +39 -1
  269. package/dist/plugins/coin/service.mjs +11 -4
  270. package/dist/plugins/coin/service.mjs.map +1 -1
  271. package/dist/plugins/coin/spans.mjs +20 -0
  272. package/dist/plugins/coin/spans.mjs.map +1 -0
  273. package/dist/plugins/dashboard/domain.mjs +402 -0
  274. package/dist/plugins/dashboard/domain.mjs.map +1 -0
  275. package/dist/plugins/dashboard/index.d.mts +29 -0
  276. package/dist/plugins/dashboard/index.mjs +91 -0
  277. package/dist/plugins/dashboard/index.mjs.map +1 -0
  278. package/dist/plugins/dashboard/origin-policy.mjs +36 -0
  279. package/dist/plugins/dashboard/origin-policy.mjs.map +1 -0
  280. package/dist/plugins/dashboard/routable.mjs +27 -0
  281. package/dist/plugins/dashboard/routable.mjs.map +1 -0
  282. package/dist/plugins/dashboard/schema/builder.mjs +21 -0
  283. package/dist/plugins/dashboard/schema/builder.mjs.map +1 -0
  284. package/dist/plugins/dashboard/schema/enums.mjs +72 -0
  285. package/dist/plugins/dashboard/schema/enums.mjs.map +1 -0
  286. package/dist/plugins/dashboard/schema/root.mjs +351 -0
  287. package/dist/plugins/dashboard/schema/root.mjs.map +1 -0
  288. package/dist/plugins/dashboard/schema/types.mjs +508 -0
  289. package/dist/plugins/dashboard/schema/types.mjs.map +1 -0
  290. package/dist/plugins/dashboard/schema.mjs +11 -0
  291. package/dist/plugins/dashboard/schema.mjs.map +1 -0
  292. package/dist/plugins/dashboard/server.mjs +166 -0
  293. package/dist/plugins/dashboard/server.mjs.map +1 -0
  294. package/dist/plugins/deepbook/deploy.mjs +53 -115
  295. package/dist/plugins/deepbook/deploy.mjs.map +1 -1
  296. package/dist/plugins/deepbook/errors.mjs +1 -0
  297. package/dist/plugins/deepbook/errors.mjs.map +1 -1
  298. package/dist/plugins/deepbook/faucet-strategy.mjs +47 -34
  299. package/dist/plugins/deepbook/faucet-strategy.mjs.map +1 -1
  300. package/dist/plugins/deepbook/hash.mjs +9 -0
  301. package/dist/plugins/deepbook/hash.mjs.map +1 -0
  302. package/dist/plugins/deepbook/index.d.mts +1 -10
  303. package/dist/plugins/deepbook/index.mjs +25 -22
  304. package/dist/plugins/deepbook/index.mjs.map +1 -1
  305. package/dist/plugins/deepbook/pyth/index.mjs +26 -55
  306. package/dist/plugins/deepbook/pyth/index.mjs.map +1 -1
  307. package/dist/plugins/deepbook/snapshot.mjs +17 -29
  308. package/dist/plugins/deepbook/snapshot.mjs.map +1 -1
  309. package/dist/plugins/deepbook/spans.mjs +18 -0
  310. package/dist/plugins/deepbook/spans.mjs.map +1 -0
  311. package/dist/plugins/deepbook/type-strings.mjs +65 -0
  312. package/dist/plugins/deepbook/type-strings.mjs.map +1 -0
  313. package/dist/plugins/deepbook/types.d.mts +2 -3
  314. package/dist/plugins/deepbook/types.mjs.map +1 -1
  315. package/dist/plugins/faucet/dispatcher.d.mts +21 -2
  316. package/dist/plugins/faucet/dispatcher.mjs +1 -2
  317. package/dist/plugins/faucet/dispatcher.mjs.map +1 -1
  318. package/dist/plugins/faucet/errors.d.mts +11 -24
  319. package/dist/plugins/faucet/errors.mjs.map +1 -1
  320. package/dist/plugins/faucet/http.mjs +33 -14
  321. package/dist/plugins/faucet/http.mjs.map +1 -1
  322. package/dist/plugins/faucet/index.d.mts +15 -5
  323. package/dist/plugins/faucet/index.mjs +3 -0
  324. package/dist/plugins/faucet/index.mjs.map +1 -1
  325. package/dist/plugins/faucet/spans.mjs +12 -0
  326. package/dist/plugins/faucet/spans.mjs.map +1 -0
  327. package/dist/plugins/host-service/errors.d.mts +1 -1
  328. package/dist/plugins/host-service/index.mjs +34 -8
  329. package/dist/plugins/host-service/index.mjs.map +1 -1
  330. package/dist/plugins/host-service/routable.mjs +2 -1
  331. package/dist/plugins/host-service/routable.mjs.map +1 -1
  332. package/dist/plugins/host-service/service.d.mts +21 -0
  333. package/dist/plugins/host-service/service.mjs +136 -81
  334. package/dist/plugins/host-service/service.mjs.map +1 -1
  335. package/dist/plugins/internal/acquire-on-chain-artifact.mjs +23 -0
  336. package/dist/plugins/internal/acquire-on-chain-artifact.mjs.map +1 -0
  337. package/dist/plugins/internal/codegen-helpers.mjs +18 -0
  338. package/dist/plugins/internal/codegen-helpers.mjs.map +1 -0
  339. package/dist/plugins/internal/funding-failure-error.mjs +32 -0
  340. package/dist/plugins/internal/funding-failure-error.mjs.map +1 -0
  341. package/dist/plugins/package/build.mjs +1 -1
  342. package/dist/plugins/package/build.mjs.map +1 -1
  343. package/dist/plugins/package/codegen.mjs +26 -0
  344. package/dist/plugins/package/codegen.mjs.map +1 -1
  345. package/dist/plugins/package/errors.d.mts +16 -6
  346. package/dist/plugins/package/errors.mjs.map +1 -1
  347. package/dist/plugins/package/index.d.mts +0 -4
  348. package/dist/plugins/package/index.mjs +27 -21
  349. package/dist/plugins/package/index.mjs.map +1 -1
  350. package/dist/plugins/package/mode-known.mjs +26 -12
  351. package/dist/plugins/package/mode-known.mjs.map +1 -1
  352. package/dist/plugins/package/mode-local.mjs +47 -41
  353. package/dist/plugins/package/mode-local.mjs.map +1 -1
  354. package/dist/plugins/package/publish-executor.mjs +55 -114
  355. package/dist/plugins/package/publish-executor.mjs.map +1 -1
  356. package/dist/plugins/package/registry.mjs +2 -1
  357. package/dist/plugins/package/registry.mjs.map +1 -1
  358. package/dist/plugins/package/service.mjs.map +1 -1
  359. package/dist/plugins/package/spans.mjs +14 -0
  360. package/dist/plugins/package/spans.mjs.map +1 -0
  361. package/dist/plugins/postgres/db-ensure.mjs +19 -12
  362. package/dist/plugins/postgres/db-ensure.mjs.map +1 -1
  363. package/dist/plugins/postgres/errors.d.mts +5 -0
  364. package/dist/plugins/postgres/errors.mjs.map +1 -1
  365. package/dist/plugins/postgres/index.mjs +10 -17
  366. package/dist/plugins/postgres/index.mjs.map +1 -1
  367. package/dist/plugins/postgres/service.mjs +58 -24
  368. package/dist/plugins/postgres/service.mjs.map +1 -1
  369. package/dist/plugins/postgres/snapshot.mjs.map +1 -1
  370. package/dist/plugins/postgres/spans.mjs +11 -0
  371. package/dist/plugins/postgres/spans.mjs.map +1 -0
  372. package/dist/plugins/router-entrypoints.mjs +4 -4
  373. package/dist/plugins/router-entrypoints.mjs.map +1 -1
  374. package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs +15 -13
  375. package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs.map +1 -1
  376. package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs +15 -19
  377. package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs.map +1 -1
  378. package/dist/plugins/seal/codegen.d.mts +2 -3
  379. package/dist/plugins/seal/codegen.mjs.map +1 -1
  380. package/dist/plugins/seal/config-render.mjs +35 -8
  381. package/dist/plugins/seal/config-render.mjs.map +1 -1
  382. package/dist/plugins/seal/deploy.mjs +31 -39
  383. package/dist/plugins/seal/deploy.mjs.map +1 -1
  384. package/dist/plugins/seal/errors.d.mts +1 -3
  385. package/dist/plugins/seal/errors.mjs +7 -1
  386. package/dist/plugins/seal/errors.mjs.map +1 -1
  387. package/dist/plugins/seal/index.d.mts +1 -6
  388. package/dist/plugins/seal/index.mjs +40 -14
  389. package/dist/plugins/seal/index.mjs.map +1 -1
  390. package/dist/plugins/seal/key-manager.d.mts +1 -9
  391. package/dist/plugins/seal/key-manager.mjs +2 -18
  392. package/dist/plugins/seal/key-manager.mjs.map +1 -1
  393. package/dist/plugins/seal/key-server.mjs +37 -36
  394. package/dist/plugins/seal/key-server.mjs.map +1 -1
  395. package/dist/plugins/seal/keygen.mjs +16 -17
  396. package/dist/plugins/seal/keygen.mjs.map +1 -1
  397. package/dist/plugins/seal/mode/fork-known.mjs +36 -14
  398. package/dist/plugins/seal/mode/fork-known.mjs.map +1 -1
  399. package/dist/plugins/seal/mode/live.d.mts +6 -4
  400. package/dist/plugins/seal/mode/live.mjs +14 -21
  401. package/dist/plugins/seal/mode/live.mjs.map +1 -1
  402. package/dist/plugins/seal/mode/local-keygen.mjs +57 -21
  403. package/dist/plugins/seal/mode/local-keygen.mjs.map +1 -1
  404. package/dist/plugins/seal/registry-publish.mjs +1 -0
  405. package/dist/plugins/seal/registry-publish.mjs.map +1 -1
  406. package/dist/plugins/seal/routable.mjs.map +1 -1
  407. package/dist/plugins/seal/service.mjs.map +1 -1
  408. package/dist/plugins/seal/spans.mjs +18 -0
  409. package/dist/plugins/seal/spans.mjs.map +1 -0
  410. package/dist/plugins/sui/auto-tick.mjs +17 -23
  411. package/dist/plugins/sui/auto-tick.mjs.map +1 -1
  412. package/dist/plugins/sui/chain-build-container.mjs +18 -0
  413. package/dist/plugins/sui/chain-build-container.mjs.map +1 -0
  414. package/dist/plugins/sui/chain-probe.d.mts +5 -5
  415. package/dist/plugins/sui/chain-probe.mjs +28 -58
  416. package/dist/plugins/sui/chain-probe.mjs.map +1 -1
  417. package/dist/plugins/sui/codegen.mjs +26 -0
  418. package/dist/plugins/sui/codegen.mjs.map +1 -1
  419. package/dist/plugins/sui/errors.d.mts +2 -29
  420. package/dist/plugins/sui/errors.mjs +1 -3
  421. package/dist/plugins/sui/errors.mjs.map +1 -1
  422. package/dist/plugins/sui/fork-faucet-strategy.d.mts +1 -0
  423. package/dist/plugins/sui/fork-faucet-strategy.mjs +55 -0
  424. package/dist/plugins/sui/fork-faucet-strategy.mjs.map +1 -0
  425. package/dist/plugins/sui/fork-orchestration.d.mts +1 -0
  426. package/dist/plugins/sui/fork-orchestration.mjs +170 -2
  427. package/dist/plugins/sui/fork-orchestration.mjs.map +1 -1
  428. package/dist/plugins/sui/fork-transaction.d.mts +2 -0
  429. package/dist/plugins/sui/fork-transaction.mjs +92 -28
  430. package/dist/plugins/sui/fork-transaction.mjs.map +1 -1
  431. package/dist/plugins/sui/index.d.mts +33 -70
  432. package/dist/plugins/sui/index.mjs +58 -35
  433. package/dist/plugins/sui/index.mjs.map +1 -1
  434. package/dist/plugins/{faucet/strategies/sui-local.mjs → sui/local-faucet-strategy.mjs} +10 -7
  435. package/dist/plugins/sui/local-faucet-strategy.mjs.map +1 -0
  436. package/dist/plugins/sui/mode/external.mjs +7 -13
  437. package/dist/plugins/sui/mode/external.mjs.map +1 -1
  438. package/dist/plugins/sui/mode/fork.mjs +136 -59
  439. package/dist/plugins/sui/mode/fork.mjs.map +1 -1
  440. package/dist/plugins/sui/mode/live.mjs +10 -16
  441. package/dist/plugins/sui/mode/live.mjs.map +1 -1
  442. package/dist/plugins/sui/mode/local.mjs +37 -36
  443. package/dist/plugins/sui/mode/local.mjs.map +1 -1
  444. package/dist/plugins/sui/mode/shared-boot.mjs +38 -115
  445. package/dist/plugins/sui/mode/shared-boot.mjs.map +1 -1
  446. package/dist/plugins/sui/mode/shared.d.mts +1 -5
  447. package/dist/plugins/sui/mode/shared.mjs.map +1 -1
  448. package/dist/plugins/sui/mode/spec.d.mts +18 -0
  449. package/dist/plugins/sui/move-summary-runner.mjs +207 -0
  450. package/dist/plugins/sui/move-summary-runner.mjs.map +1 -0
  451. package/dist/plugins/sui/network-resolver.d.mts +4 -3
  452. package/dist/plugins/sui/service.mjs.map +1 -1
  453. package/dist/plugins/sui/snapshot.mjs +3 -0
  454. package/dist/plugins/sui/snapshot.mjs.map +1 -1
  455. package/dist/plugins/sui/spans.mjs +17 -0
  456. package/dist/plugins/sui/spans.mjs.map +1 -0
  457. package/dist/plugins/wallet/codegen.d.mts +0 -1
  458. package/dist/plugins/wallet/codegen.mjs +8 -9
  459. package/dist/plugins/wallet/codegen.mjs.map +1 -1
  460. package/dist/plugins/wallet/index.d.mts +6 -8
  461. package/dist/plugins/wallet/index.mjs +46 -35
  462. package/dist/plugins/wallet/index.mjs.map +1 -1
  463. package/dist/plugins/wallet/origin-policy.mjs +12 -28
  464. package/dist/plugins/wallet/origin-policy.mjs.map +1 -1
  465. package/dist/plugins/wallet/pairing.mjs +6 -4
  466. package/dist/plugins/wallet/pairing.mjs.map +1 -1
  467. package/dist/plugins/wallet/protocol.d.mts +1 -0
  468. package/dist/plugins/wallet/protocol.mjs +5 -44
  469. package/dist/plugins/wallet/protocol.mjs.map +1 -1
  470. package/dist/plugins/wallet/routable.mjs +2 -8
  471. package/dist/plugins/wallet/routable.mjs.map +1 -1
  472. package/dist/plugins/wallet/server.mjs +36 -44
  473. package/dist/plugins/wallet/server.mjs.map +1 -1
  474. package/dist/plugins/wallet/service.d.mts +1 -5
  475. package/dist/plugins/wallet/service.mjs +22 -18
  476. package/dist/plugins/wallet/service.mjs.map +1 -1
  477. package/dist/plugins/wallet/spans.mjs +22 -0
  478. package/dist/plugins/wallet/spans.mjs.map +1 -0
  479. package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs +33 -8
  480. package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs.map +1 -1
  481. package/dist/plugins/walrus/codegen.d.mts +3 -3
  482. package/dist/plugins/walrus/codegen.mjs.map +1 -1
  483. package/dist/plugins/walrus/deploy-paths.mjs +21 -5
  484. package/dist/plugins/walrus/deploy-paths.mjs.map +1 -1
  485. package/dist/plugins/walrus/deploy.mjs +67 -69
  486. package/dist/plugins/walrus/deploy.mjs.map +1 -1
  487. package/dist/plugins/walrus/errors.mjs +1 -0
  488. package/dist/plugins/walrus/errors.mjs.map +1 -1
  489. package/dist/plugins/walrus/faucet-strategy.mjs +12 -7
  490. package/dist/plugins/walrus/faucet-strategy.mjs.map +1 -1
  491. package/dist/plugins/walrus/index.d.mts +2 -13
  492. package/dist/plugins/walrus/index.mjs +18 -23
  493. package/dist/plugins/walrus/index.mjs.map +1 -1
  494. package/dist/plugins/walrus/mode/known-deploy.mjs +7 -5
  495. package/dist/plugins/walrus/mode/known-deploy.mjs.map +1 -1
  496. package/dist/plugins/walrus/mode/local-cluster.mjs +26 -7
  497. package/dist/plugins/walrus/mode/local-cluster.mjs.map +1 -1
  498. package/dist/plugins/walrus/registry-publish.mjs.map +1 -1
  499. package/dist/plugins/walrus/routable.mjs +7 -23
  500. package/dist/plugins/walrus/routable.mjs.map +1 -1
  501. package/dist/plugins/walrus/service.mjs.map +1 -1
  502. package/dist/plugins/walrus/spans.mjs +18 -0
  503. package/dist/plugins/walrus/spans.mjs.map +1 -0
  504. package/dist/plugins/walrus/storage-nodes.d.mts +6 -2
  505. package/dist/plugins/walrus/storage-nodes.mjs +15 -8
  506. package/dist/plugins/walrus/storage-nodes.mjs.map +1 -1
  507. package/dist/plugins/walrus/wal-swap.mjs +58 -15
  508. package/dist/plugins/walrus/wal-swap.mjs.map +1 -1
  509. package/dist/primitives/artifact-publisher.d.mts +1 -1
  510. package/dist/primitives/artifact-publisher.mjs +15 -0
  511. package/dist/primitives/artifact-publisher.mjs.map +1 -0
  512. package/dist/runtime/docker/client.mjs +17 -4
  513. package/dist/runtime/docker/client.mjs.map +1 -1
  514. package/dist/runtime/docker/container.mjs +219 -132
  515. package/dist/runtime/docker/container.mjs.map +1 -1
  516. package/dist/runtime/docker/errors.mjs +0 -6
  517. package/dist/runtime/docker/errors.mjs.map +1 -1
  518. package/dist/runtime/docker/exec.mjs +21 -18
  519. package/dist/runtime/docker/exec.mjs.map +1 -1
  520. package/dist/runtime/docker/image.mjs +36 -13
  521. package/dist/runtime/docker/image.mjs.map +1 -1
  522. package/dist/runtime/docker/index.mjs +14 -0
  523. package/dist/runtime/docker/inspect-and-decode.mjs +51 -0
  524. package/dist/runtime/docker/inspect-and-decode.mjs.map +1 -0
  525. package/dist/runtime/docker/inventory.mjs +14 -11
  526. package/dist/runtime/docker/inventory.mjs.map +1 -1
  527. package/dist/runtime/docker/labels.mjs +38 -5
  528. package/dist/runtime/docker/labels.mjs.map +1 -1
  529. package/dist/runtime/docker/logs.d.mts +1 -1
  530. package/dist/runtime/docker/logs.mjs.map +1 -1
  531. package/dist/runtime/docker/network.mjs +83 -47
  532. package/dist/runtime/docker/network.mjs.map +1 -1
  533. package/dist/runtime/docker/render-run-args.mjs +82 -0
  534. package/dist/runtime/docker/render-run-args.mjs.map +1 -0
  535. package/dist/runtime/docker/service.d.mts +1 -1
  536. package/dist/runtime/docker/service.mjs +12 -7
  537. package/dist/runtime/docker/service.mjs.map +1 -1
  538. package/dist/runtime/docker/sweep.mjs +118 -43
  539. package/dist/runtime/docker/sweep.mjs.map +1 -1
  540. package/dist/runtime/docker/volume.mjs +2 -0
  541. package/dist/runtime/docker/volume.mjs.map +1 -1
  542. package/dist/runtime/docker/wrap.mjs +30 -1
  543. package/dist/runtime/docker/wrap.mjs.map +1 -1
  544. package/dist/substrate/cross-process.mjs +14 -8
  545. package/dist/substrate/cross-process.mjs.map +1 -1
  546. package/dist/substrate/event-time.mjs +33 -0
  547. package/dist/substrate/event-time.mjs.map +1 -0
  548. package/dist/substrate/events.d.mts +28 -8
  549. package/dist/substrate/identity.d.mts +2 -1
  550. package/dist/substrate/manifest.d.mts +68 -5
  551. package/dist/substrate/manifest.mjs +34 -5
  552. package/dist/substrate/manifest.mjs.map +1 -1
  553. package/dist/substrate/network.d.mts +3 -5
  554. package/dist/substrate/options.d.mts +0 -2
  555. package/dist/substrate/plugin.d.mts +13 -0
  556. package/dist/substrate/plugin.mjs +4 -2
  557. package/dist/substrate/plugin.mjs.map +1 -1
  558. package/dist/substrate/projection.d.mts +35 -3
  559. package/dist/substrate/runtime/artifact-publisher/index.mjs +19 -9
  560. package/dist/substrate/runtime/artifact-publisher/index.mjs.map +1 -1
  561. package/dist/substrate/runtime/atomic-write.mjs +97 -32
  562. package/dist/substrate/runtime/atomic-write.mjs.map +1 -1
  563. package/dist/substrate/runtime/cache/index.mjs +3 -0
  564. package/dist/substrate/runtime/cache/schema.mjs +2 -2
  565. package/dist/substrate/runtime/cache/schema.mjs.map +1 -1
  566. package/dist/substrate/runtime/cache/service.mjs +9 -7
  567. package/dist/substrate/runtime/cache/service.mjs.map +1 -1
  568. package/dist/substrate/runtime/capability-sinks/index.d.mts +1 -1
  569. package/dist/substrate/runtime/capability-sinks/index.mjs +3 -0
  570. package/dist/substrate/runtime/capability-sinks/layer.mjs +1 -1
  571. package/dist/substrate/runtime/capability-sinks/service.d.mts +61 -2
  572. package/dist/substrate/runtime/capability-sinks/service.mjs +21 -26
  573. package/dist/substrate/runtime/capability-sinks/service.mjs.map +1 -1
  574. package/dist/substrate/runtime/config-validation.d.mts +1 -13
  575. package/dist/substrate/runtime/config-validation.mjs +2 -91
  576. package/dist/substrate/runtime/config-validation.mjs.map +1 -1
  577. package/dist/substrate/runtime/container-runtime.d.mts +1 -0
  578. package/dist/substrate/runtime/container-runtime.mjs +2 -0
  579. package/dist/substrate/runtime/control-plane/domain.mjs +101 -0
  580. package/dist/substrate/runtime/control-plane/domain.mjs.map +1 -0
  581. package/dist/substrate/runtime/control-plane/service.mjs +7 -0
  582. package/dist/substrate/runtime/control-plane/service.mjs.map +1 -0
  583. package/dist/substrate/runtime/cross-process/command-channel/channel.mjs +46 -19
  584. package/dist/substrate/runtime/cross-process/command-channel/channel.mjs.map +1 -1
  585. package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs +30 -12
  586. package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs.map +1 -1
  587. package/dist/substrate/runtime/cross-process/command-channel/index.mjs +5 -0
  588. package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs +11 -2
  589. package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs.map +1 -1
  590. package/dist/substrate/runtime/cross-process/command-channel/runtime-control-lock.mjs +1 -1
  591. package/dist/substrate/runtime/cross-process/index.mjs +11 -0
  592. package/dist/substrate/runtime/cross-process/live-clock.mjs +34 -0
  593. package/dist/substrate/runtime/cross-process/live-clock.mjs.map +1 -0
  594. package/dist/substrate/runtime/cross-process/liveness.mjs +52 -10
  595. package/dist/substrate/runtime/cross-process/liveness.mjs.map +1 -1
  596. package/dist/substrate/runtime/cross-process/lock.d.mts +1 -0
  597. package/dist/substrate/runtime/cross-process/lock.mjs +23 -0
  598. package/dist/substrate/runtime/cross-process/lock.mjs.map +1 -0
  599. package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs +64 -0
  600. package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs.map +1 -0
  601. package/dist/substrate/runtime/cross-process/roster.mjs +97 -83
  602. package/dist/substrate/runtime/cross-process/roster.mjs.map +1 -1
  603. package/dist/substrate/runtime/cross-process/self-pid.mjs +8 -0
  604. package/dist/substrate/runtime/cross-process/self-pid.mjs.map +1 -0
  605. package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs +24 -28
  606. package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs.map +1 -1
  607. package/dist/substrate/runtime/cross-process/stack-lock.mjs +41 -20
  608. package/dist/substrate/runtime/cross-process/stack-lock.mjs.map +1 -1
  609. package/dist/substrate/runtime/current-plugin.mjs +2 -2
  610. package/dist/substrate/runtime/current-plugin.mjs.map +1 -1
  611. package/dist/substrate/runtime/errors.mjs +12 -6
  612. package/dist/substrate/runtime/errors.mjs.map +1 -1
  613. package/dist/substrate/runtime/format-unknown-error.mjs +30 -0
  614. package/dist/substrate/runtime/format-unknown-error.mjs.map +1 -0
  615. package/dist/substrate/runtime/host-bind-mount-owner.mjs +10 -0
  616. package/dist/substrate/runtime/host-bind-mount-owner.mjs.map +1 -0
  617. package/dist/substrate/runtime/host-gateway.mjs +20 -0
  618. package/dist/substrate/runtime/host-gateway.mjs.map +1 -0
  619. package/dist/substrate/runtime/host-tree-tar/index.mjs +61 -50
  620. package/dist/substrate/runtime/host-tree-tar/index.mjs.map +1 -1
  621. package/dist/substrate/runtime/http-probe.d.mts +1 -1
  622. package/dist/substrate/runtime/index.mjs +14 -0
  623. package/dist/substrate/runtime/lease-broker/index.d.mts +1 -1
  624. package/dist/substrate/runtime/lease-broker/index.mjs +2 -0
  625. package/dist/substrate/runtime/lease-broker/service.d.mts +1 -64
  626. package/dist/substrate/runtime/lease-broker/service.mjs +1 -1
  627. package/dist/substrate/runtime/lease-broker/service.mjs.map +1 -1
  628. package/dist/substrate/runtime/lifecycle/dep-graph.mjs +22 -3
  629. package/dist/substrate/runtime/lifecycle/dep-graph.mjs.map +1 -1
  630. package/dist/substrate/runtime/lifecycle/index.mjs +9 -0
  631. package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs.map +1 -1
  632. package/dist/substrate/runtime/lifecycle/plugin-registry.mjs +20 -3
  633. package/dist/substrate/runtime/lifecycle/plugin-registry.mjs.map +1 -1
  634. package/dist/substrate/runtime/lifecycle/selective-restart.mjs +1 -1
  635. package/dist/substrate/runtime/lifecycle/signals.mjs +5 -5
  636. package/dist/substrate/runtime/lifecycle/signals.mjs.map +1 -1
  637. package/dist/substrate/runtime/lifecycle/state-machine.mjs +1 -1
  638. package/dist/substrate/runtime/managed-container.d.mts +19 -1
  639. package/dist/substrate/runtime/managed-container.mjs +20 -1
  640. package/dist/substrate/runtime/managed-container.mjs.map +1 -1
  641. package/dist/substrate/runtime/manifest/index.mjs +3 -0
  642. package/dist/substrate/runtime/manifest/manifest.mjs +15 -11
  643. package/dist/substrate/runtime/manifest/manifest.mjs.map +1 -1
  644. package/dist/substrate/runtime/mode-errors.mjs +20 -0
  645. package/dist/substrate/runtime/mode-errors.mjs.map +1 -0
  646. package/dist/substrate/runtime/observability/cascade-formatter.mjs +9 -13
  647. package/dist/substrate/runtime/observability/cascade-formatter.mjs.map +1 -1
  648. package/dist/substrate/runtime/observability/formatter-registry.mjs +19 -36
  649. package/dist/substrate/runtime/observability/formatter-registry.mjs.map +1 -1
  650. package/dist/substrate/runtime/observability/ignore-with-log.d.mts +1 -0
  651. package/dist/substrate/runtime/observability/ignore-with-log.mjs +17 -0
  652. package/dist/substrate/runtime/observability/ignore-with-log.mjs.map +1 -0
  653. package/dist/substrate/runtime/observability/index.d.mts +1 -1
  654. package/dist/substrate/runtime/observability/index.mjs +13 -0
  655. package/dist/substrate/runtime/observability/log-store.d.mts +1 -0
  656. package/dist/substrate/runtime/observability/log-store.mjs +175 -0
  657. package/dist/substrate/runtime/observability/log-store.mjs.map +1 -0
  658. package/dist/substrate/runtime/observability/logger.d.mts +2 -1
  659. package/dist/substrate/runtime/observability/logger.mjs +5 -9
  660. package/dist/substrate/runtime/observability/logger.mjs.map +1 -1
  661. package/dist/substrate/runtime/observability/output-truncate.mjs +35 -0
  662. package/dist/substrate/runtime/observability/output-truncate.mjs.map +1 -0
  663. package/dist/substrate/runtime/observability/pretty-error.mjs +9 -12
  664. package/dist/substrate/runtime/observability/pretty-error.mjs.map +1 -1
  665. package/dist/substrate/runtime/observability/redaction.d.mts +2 -13
  666. package/dist/substrate/runtime/observability/redaction.mjs +8 -14
  667. package/dist/substrate/runtime/observability/redaction.mjs.map +1 -1
  668. package/dist/substrate/runtime/observability/span-store.d.mts +1 -0
  669. package/dist/substrate/runtime/observability/span-store.mjs +110 -0
  670. package/dist/substrate/runtime/observability/span-store.mjs.map +1 -0
  671. package/dist/substrate/runtime/observability/spans.mjs +14 -14
  672. package/dist/substrate/runtime/observability/spans.mjs.map +1 -1
  673. package/dist/substrate/runtime/observability/subprocess-capture.mjs +1 -1
  674. package/dist/substrate/runtime/passthrough-or-wrap.mjs +33 -0
  675. package/dist/substrate/runtime/passthrough-or-wrap.mjs.map +1 -0
  676. package/dist/substrate/runtime/paths.d.mts +1 -1
  677. package/dist/substrate/runtime/paths.mjs +4 -3
  678. package/dist/substrate/runtime/paths.mjs.map +1 -1
  679. package/dist/substrate/runtime/phase-preserving-produce.mjs +40 -0
  680. package/dist/substrate/runtime/phase-preserving-produce.mjs.map +1 -0
  681. package/dist/substrate/runtime/port-broker/index.mjs +3 -0
  682. package/dist/substrate/runtime/port-broker/service.mjs +170 -126
  683. package/dist/substrate/runtime/port-broker/service.mjs.map +1 -1
  684. package/dist/substrate/runtime/post-acquire-tasks.mjs +1 -1
  685. package/dist/substrate/runtime/post-acquire-tasks.mjs.map +1 -1
  686. package/dist/substrate/runtime/probes.d.mts +7 -5
  687. package/dist/substrate/runtime/probes.mjs +3 -1
  688. package/dist/substrate/runtime/probes.mjs.map +1 -1
  689. package/dist/substrate/runtime/projection/index.mjs +4 -0
  690. package/dist/substrate/runtime/projection/operational-endpoints.mjs +1 -2
  691. package/dist/substrate/runtime/projection/operational-endpoints.mjs.map +1 -1
  692. package/dist/substrate/runtime/projection/persisted.mjs +33 -15
  693. package/dist/substrate/runtime/projection/persisted.mjs.map +1 -1
  694. package/dist/substrate/runtime/projection/state-ref.mjs +26 -2
  695. package/dist/substrate/runtime/projection/state-ref.mjs.map +1 -1
  696. package/dist/substrate/runtime/projection/update.mjs +88 -24
  697. package/dist/substrate/runtime/projection/update.mjs.map +1 -1
  698. package/dist/substrate/runtime/random-suffix.mjs +11 -0
  699. package/dist/substrate/runtime/random-suffix.mjs.map +1 -0
  700. package/dist/substrate/runtime/retry-policy.d.mts +59 -1
  701. package/dist/substrate/runtime/retry-policy.mjs +66 -1
  702. package/dist/substrate/runtime/retry-policy.mjs.map +1 -1
  703. package/dist/substrate/runtime/routed-url.d.mts +1 -0
  704. package/dist/substrate/runtime/routed-url.mjs +79 -0
  705. package/dist/substrate/runtime/routed-url.mjs.map +1 -0
  706. package/dist/substrate/runtime/runtime-decode.d.mts +1 -1
  707. package/dist/substrate/runtime/runtime-decode.mjs.map +1 -1
  708. package/dist/substrate/runtime/scoped-http-server.mjs +2 -3
  709. package/dist/substrate/runtime/scoped-http-server.mjs.map +1 -1
  710. package/dist/substrate/runtime/scoped-multimap/index.mjs +2 -0
  711. package/dist/substrate/runtime/scoped-multimap/service.mjs +52 -0
  712. package/dist/substrate/runtime/scoped-multimap/service.mjs.map +1 -0
  713. package/dist/substrate/runtime/scoped-ref-map/index.mjs +2 -0
  714. package/dist/substrate/runtime/scoped-ref-map/service.mjs +2 -2
  715. package/dist/substrate/runtime/scoped-ref-map/service.mjs.map +1 -1
  716. package/dist/substrate/runtime/stage-and-swap/index.mjs +72 -4
  717. package/dist/substrate/runtime/stage-and-swap/index.mjs.map +1 -1
  718. package/dist/substrate/runtime/state-store/index.d.mts +1 -0
  719. package/dist/substrate/runtime/state-store/index.mjs +3 -0
  720. package/dist/substrate/runtime/state-store/schema.d.mts +1 -0
  721. package/dist/substrate/runtime/state-store/schema.mjs +19 -14
  722. package/dist/substrate/runtime/state-store/schema.mjs.map +1 -1
  723. package/dist/substrate/runtime/state-store/service.d.mts +1 -0
  724. package/dist/substrate/runtime/state-store/service.mjs +145 -0
  725. package/dist/substrate/runtime/state-store/service.mjs.map +1 -0
  726. package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.d.mts +1 -0
  727. package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.mjs +33 -0
  728. package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.mjs.map +1 -0
  729. package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs +1 -1
  730. package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs.map +1 -1
  731. package/dist/substrate/runtime/strategy-registry/index.mjs +4 -0
  732. package/dist/substrate/runtime/strategy-registry/service.mjs +19 -33
  733. package/dist/substrate/runtime/strategy-registry/service.mjs.map +1 -1
  734. package/dist/substrate/runtime/subnet-broker.mjs +60 -0
  735. package/dist/substrate/runtime/subnet-broker.mjs.map +1 -0
  736. package/dist/substrate/runtime/sui-execute/index.d.mts +21 -1
  737. package/dist/substrate/runtime/sui-execute/index.mjs +84 -20
  738. package/dist/substrate/runtime/sui-execute/index.mjs.map +1 -1
  739. package/dist/substrate/runtime/sui-execute/sign-and-dispatch.d.mts +1 -0
  740. package/dist/substrate/runtime/sui-execute/sign-and-dispatch.mjs +32 -0
  741. package/dist/substrate/runtime/sui-execute/sign-and-dispatch.mjs.map +1 -0
  742. package/dist/substrate/runtime/sui-ledger/object-ref.mjs +32 -0
  743. package/dist/substrate/runtime/sui-ledger/object-ref.mjs.map +1 -0
  744. package/dist/substrate/runtime/sui-move-build/index.mjs +93 -19
  745. package/dist/substrate/runtime/sui-move-build/index.mjs.map +1 -1
  746. package/dist/substrate/runtime/supervisor/acquire-node.mjs +181 -0
  747. package/dist/substrate/runtime/supervisor/acquire-node.mjs.map +1 -0
  748. package/dist/substrate/runtime/supervisor/background-tasks.mjs +144 -0
  749. package/dist/substrate/runtime/supervisor/background-tasks.mjs.map +1 -0
  750. package/dist/substrate/runtime/supervisor/command-loop.mjs +68 -0
  751. package/dist/substrate/runtime/supervisor/command-loop.mjs.map +1 -0
  752. package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs +151 -0
  753. package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs.map +1 -0
  754. package/dist/substrate/runtime/supervisor/errors.d.mts +1 -0
  755. package/dist/substrate/runtime/supervisor/errors.mjs +9 -0
  756. package/dist/substrate/runtime/supervisor/errors.mjs.map +1 -0
  757. package/dist/substrate/runtime/supervisor/index.d.mts +1 -0
  758. package/dist/substrate/runtime/supervisor/index.mjs +3 -0
  759. package/dist/substrate/runtime/supervisor/shutdown.mjs +51 -0
  760. package/dist/substrate/runtime/supervisor/shutdown.mjs.map +1 -0
  761. package/dist/substrate/runtime/supervisor/start-supervisor.d.mts +1 -0
  762. package/dist/substrate/runtime/supervisor/start-supervisor.mjs +250 -0
  763. package/dist/substrate/runtime/supervisor/start-supervisor.mjs.map +1 -0
  764. package/dist/substrate/runtime/supervisor/state.d.mts +1 -0
  765. package/dist/substrate/runtime/supervisor/state.mjs +22 -0
  766. package/dist/substrate/runtime/supervisor/state.mjs.map +1 -0
  767. package/dist/substrate/runtime/supervisor/teardown.mjs +57 -0
  768. package/dist/substrate/runtime/supervisor/teardown.mjs.map +1 -0
  769. package/dist/substrate/runtime/supervisor/types.d.mts +1 -0
  770. package/dist/substrate/runtime/supervisor/wiring.mjs +133 -0
  771. package/dist/substrate/runtime/supervisor/wiring.mjs.map +1 -0
  772. package/dist/substrate/runtime/typed-env.mjs +8 -0
  773. package/dist/substrate/runtime/typed-env.mjs.map +1 -0
  774. package/dist/substrate/state-store.d.mts +1 -0
  775. package/dist/substrate/versioned-doc-schema.mjs +17 -0
  776. package/dist/substrate/versioned-doc-schema.mjs.map +1 -0
  777. package/dist/substrate/versioned-doc-sync.mjs +94 -0
  778. package/dist/substrate/versioned-doc-sync.mjs.map +1 -0
  779. package/dist/surfaces/cli/command-tree.mjs.map +1 -1
  780. package/dist/surfaces/cli/commands/index.mjs +9 -0
  781. package/dist/surfaces/cli/commands/prune-picker-entry.mjs +13 -0
  782. package/dist/surfaces/cli/commands/prune-picker-entry.mjs.map +1 -0
  783. package/dist/surfaces/cli/commands/prune-picker.mjs +3 -2
  784. package/dist/surfaces/cli/commands/prune-picker.mjs.map +1 -1
  785. package/dist/surfaces/cli/commands/prune.mjs +34 -17
  786. package/dist/surfaces/cli/commands/prune.mjs.map +1 -1
  787. package/dist/surfaces/cli/commands/status.mjs +2 -2
  788. package/dist/surfaces/cli/commands/status.mjs.map +1 -1
  789. package/dist/surfaces/cli/commands/supervisor-presence.mjs +5 -3
  790. package/dist/surfaces/cli/commands/supervisor-presence.mjs.map +1 -1
  791. package/dist/surfaces/cli/commands/wipe.mjs +38 -4
  792. package/dist/surfaces/cli/commands/wipe.mjs.map +1 -1
  793. package/dist/surfaces/cli/errors.mjs +1 -1
  794. package/dist/surfaces/cli/errors.mjs.map +1 -1
  795. package/dist/surfaces/cli/flags.mjs +0 -1
  796. package/dist/surfaces/cli/flags.mjs.map +1 -1
  797. package/dist/surfaces/cli/index.mjs +98 -18
  798. package/dist/surfaces/cli/index.mjs.map +1 -1
  799. package/dist/surfaces/cli/output.mjs +1 -0
  800. package/dist/surfaces/cli/output.mjs.map +1 -1
  801. package/dist/surfaces/cli/sysexits.mjs +2 -1
  802. package/dist/surfaces/cli/sysexits.mjs.map +1 -1
  803. package/dist/surfaces/tui/app.mjs +25 -3
  804. package/dist/surfaces/tui/app.mjs.map +1 -1
  805. package/dist/surfaces/tui/display-derivation.mjs +23 -74
  806. package/dist/surfaces/tui/display-derivation.mjs.map +1 -1
  807. package/dist/surfaces/tui/event-log.mjs +35 -23
  808. package/dist/surfaces/tui/event-log.mjs.map +1 -1
  809. package/dist/surfaces/tui/input.mjs +5 -1
  810. package/dist/surfaces/tui/input.mjs.map +1 -1
  811. package/dist/surfaces/tui/plain-renderer.mjs +70 -34
  812. package/dist/surfaces/tui/plain-renderer.mjs.map +1 -1
  813. package/package.json +24 -4
  814. package/dist/contracts/liveness-classifier.d.mts +0 -19
  815. package/dist/contracts/network-resolver.d.mts +0 -15
  816. package/dist/contracts/network-resolver.mjs +0 -7
  817. package/dist/contracts/network-resolver.mjs.map +0 -1
  818. package/dist/orchestrators/codegen/extras.mjs +0 -16
  819. package/dist/orchestrators/codegen/extras.mjs.map +0 -1
  820. package/dist/plugins/deepbook/routable.mjs +0 -21
  821. package/dist/plugins/deepbook/routable.mjs.map +0 -1
  822. package/dist/plugins/faucet/service.d.mts +0 -20
  823. package/dist/plugins/faucet/strategies/sui-local.d.mts +0 -23
  824. package/dist/plugins/faucet/strategies/sui-local.mjs.map +0 -1
  825. package/dist/plugins/sui/seed-objects.d.mts +0 -18
  826. package/dist/plugins/sui/seed-objects.mjs +0 -25
  827. package/dist/plugins/sui/seed-objects.mjs.map +0 -1
  828. package/dist/runtime/built-in-plugin-layers.mjs.map +0 -1
  829. package/dist/substrate/runtime/context-helpers.mjs +0 -32
  830. package/dist/substrate/runtime/context-helpers.mjs.map +0 -1
  831. package/dist/substrate/runtime/run.mjs.map +0 -1
  832. package/dist/substrate/runtime/strategy-registry/faucet-capability-for.mjs +0 -30
  833. package/dist/substrate/runtime/strategy-registry/faucet-capability-for.mjs.map +0 -1
  834. package/dist/substrate/runtime/supervisor.d.mts +0 -1
  835. package/dist/substrate/runtime/supervisor.mjs +0 -831
  836. package/dist/substrate/runtime/supervisor.mjs.map +0 -1
  837. package/dist/surfaces/cli/commands/doctor-probes.mjs.map +0 -1
  838. /package/dist/{substrate/runtime/strategy-registry/faucet-capability-for.d.mts → plugins/faucet/http.d.mts} +0 -0
@@ -1,10 +1,14 @@
1
+ import { SpanAttr } from "../../../substrate/runtime/observability/spans.mjs";
2
+ import { versionedDocSchema } from "../../../substrate/versioned-doc-schema.mjs";
1
3
  import { atomicWriteFile } from "../../../substrate/runtime/atomic-write.mjs";
4
+ import { decodeJsonText } from "../../../substrate/runtime/runtime-decode.mjs";
2
5
  import { sealError } from "../errors.mjs";
6
+ import { SealSpans } from "../spans.mjs";
3
7
  import { MASTER_KEY_ENVFILE_BASENAME, runSealKeygen } from "../keygen.mjs";
4
8
  import { buildKeyServerSpec, startKeyServer } from "../key-server.mjs";
5
9
  import { parseMasterKeyEnvFile, renderSealKeyServerConfig, stageSealConfig } from "../config-render.mjs";
6
10
  import { publishSealPackage, registerKeyServer } from "../deploy.mjs";
7
- import { makeKeyManager, stubRotate } from "../key-manager.mjs";
11
+ import { makeKeyManager } from "../key-manager.mjs";
8
12
  import { resolveDefaultSealSource } from "../bootstrap-assets/source-fetch.mjs";
9
13
  import { resolveDefaultSealCargoImage } from "../bootstrap-assets/cargo-image.mjs";
10
14
  import { Effect, FileSystem, Schema } from "effect";
@@ -24,20 +28,17 @@ const resolveLocalKeygenOptions = (opts, defaultVersion) => ({
24
28
  });
25
29
  const LOCAL_KEYGEN_STATE_VERSION = 1;
26
30
  const LOCAL_KEYGEN_STATE_BASENAME = "local-keygen-state.v1.json";
27
- const PersistedLocalKeygenMetadataSchema = Schema.Struct({
28
- version: Schema.Literal(LOCAL_KEYGEN_STATE_VERSION),
29
- publicKey: Schema.String
30
- });
31
+ const PersistedLocalKeygenMetadataSchema = versionedDocSchema(LOCAL_KEYGEN_STATE_VERSION, { publicKey: Schema.String });
31
32
  const localKeygenMetadataPath = (servicePath) => `${servicePath}/${LOCAL_KEYGEN_STATE_BASENAME}`;
32
33
  const readPersistedLocalKeygenMetadata = (servicePath) => Effect.gen(function* () {
33
- const raw = yield* (yield* FileSystem.FileSystem).readFileString(localKeygenMetadataPath(servicePath)).pipe(Effect.catch(() => Effect.succeed(null)));
34
+ const fs = yield* FileSystem.FileSystem;
35
+ const path = localKeygenMetadataPath(servicePath);
36
+ const raw = yield* fs.readFileString(path).pipe(Effect.catch(() => Effect.succeed(null)));
34
37
  if (raw === null) return null;
35
- const parsed = yield* Effect.try({
36
- try: () => JSON.parse(raw),
37
- catch: () => null
38
+ return yield* decodeJsonText(PersistedLocalKeygenMetadataSchema, raw, {
39
+ source: path,
40
+ mkError: (issue) => issue
38
41
  }).pipe(Effect.catch(() => Effect.succeed(null)));
39
- if (parsed === null) return null;
40
- return yield* Schema.decodeUnknownEffect(PersistedLocalKeygenMetadataSchema)(parsed).pipe(Effect.catch(() => Effect.succeed(null)));
41
42
  });
42
43
  const stagePersistedLocalKeygenMetadata = (servicePath, name, metadata) => atomicWriteFile(localKeygenMetadataPath(servicePath), new TextEncoder().encode(`${JSON.stringify(metadata, null, 2)}\n`), {
43
44
  mode: 420,
@@ -62,6 +63,39 @@ const readPersistedLocalKeygenState = (servicePath) => Effect.gen(function* () {
62
63
  masterKeyEnvFile
63
64
  };
64
65
  });
66
+ /** BLS12-381 master key — 32 bytes, persisted as 64 hex chars. */
67
+ const BLS_MASTER_KEY_HEX_LEN = 64;
68
+ /** BLS12-381 G2 uncompressed public key — 96 bytes, persisted as 192 hex chars. */
69
+ const BLS_PUBLIC_KEY_HEX_LEN = 192;
70
+ const HEX_ONLY_RE = /^[0-9a-fA-F]+$/;
71
+ /** Stricter decode than the JSON-shape Schema alone — verifies the
72
+ * persisted master key + public key are well-formed BLS12-381 hex of
73
+ * the expected widths. The Schema validation alone accepts any
74
+ * string, so a corrupt-on-disk JSON whose `publicKey` was overwritten
75
+ * to a shorter / wrong-width value would otherwise be silently
76
+ * reused on boot — leading to a master-key / KeyServer mismatch
77
+ * (the master-key.env carries one key, the registered KeyServer's
78
+ * on-chain `publicKey` carries a different one). Distilled-doc
79
+ * invariant #6 (keypair B8 verify cascade) covers the on-chain
80
+ * side; this is the on-disk side.
81
+ *
82
+ * We cannot in-process re-derive the G2 public key from the master
83
+ * scalar without bundling a BLS12-381 implementation (the keygen
84
+ * binary owns this in cargo-land). The width invariant is the
85
+ * cheapest defense that catches the realistic corruption modes:
86
+ * truncated writes, hand-edited JSON, stale persistence from an
87
+ * older devstack version. */
88
+ const validatePersistedKeyMaterialShape = (material, name) => {
89
+ if (material.masterKey.length !== BLS_MASTER_KEY_HEX_LEN || !HEX_ONLY_RE.test(material.masterKey)) return Effect.fail(sealError("config-render", {
90
+ name,
91
+ message: `seal.local-keygen: persisted master key in ${MASTER_KEY_ENVFILE_BASENAME} is not ${BLS_MASTER_KEY_HEX_LEN}-char hex (got ${material.masterKey.length} chars). The on-disk state is corrupt; delete the seal service directory and re-boot to regenerate, or restore from a known-good snapshot.`
92
+ }));
93
+ if (material.publicKey.length !== BLS_PUBLIC_KEY_HEX_LEN || !HEX_ONLY_RE.test(material.publicKey)) return Effect.fail(sealError("config-render", {
94
+ name,
95
+ message: `seal.local-keygen: persisted publicKey in ${LOCAL_KEYGEN_STATE_BASENAME} is not ${BLS_PUBLIC_KEY_HEX_LEN}-char hex (got ${material.publicKey.length} chars). The on-disk state is corrupt; reusing it would publish a KeyServer whose on-chain publicKey diverges from the local master key. Delete the seal service directory and re-boot to regenerate.`
96
+ }));
97
+ return Effect.void;
98
+ };
65
99
  const sealConfigFingerprint = (parts) => [
66
100
  `package=${parts.packageId}`,
67
101
  `keyServer=${parts.keyServerObjectId}`,
@@ -136,11 +170,7 @@ const startLocalKeygenContainer = (deps, opts, cargoImage, state) => Effect.gen(
136
170
  objectId: state.keyServerObjectId,
137
171
  weight: 1
138
172
  }];
139
- const keyManager = makeKeyManager({
140
- name: opts.name,
141
- masterKeyEnvFile: state.masterKeyEnvFile,
142
- rotateImpl: stubRotate(opts.name)
143
- });
173
+ const keyManager = makeKeyManager({ masterKeyEnvFile: state.masterKeyEnvFile });
144
174
  return {
145
175
  keyServer: {
146
176
  serverConfigs,
@@ -160,9 +190,15 @@ const startLocalKeygenContainer = (deps, opts, cargoImage, state) => Effect.gen(
160
190
  * circuits before downstream phases (cheap on warm restart because
161
191
  * the ArtifactPublisher cache + verify covers steps 3-4). */
162
192
  const bootLocalKeygen = (deps, opts) => Effect.gen(function* () {
163
- const cargoImage = yield* resolveDefaultSealCargoImage(deps.runtime);
193
+ const cargoImage = yield* resolveDefaultSealCargoImage(deps.runtime, {
194
+ app: deps.labels.app,
195
+ stack: deps.labels.stack
196
+ });
164
197
  const persisted = yield* readPersistedLocalKeygenState(deps.servicePath);
165
- if (persisted !== null) return yield* startLocalKeygenContainer(deps, opts, cargoImage, yield* stageResolvedLocalKeygenState(deps, opts, yield* ensureLocalKeygenArtifacts(deps, opts, persisted.publicKey), persisted));
198
+ if (persisted !== null) {
199
+ yield* validatePersistedKeyMaterialShape(persisted, opts.name);
200
+ return yield* startLocalKeygenContainer(deps, opts, cargoImage, yield* stageResolvedLocalKeygenState(deps, opts, yield* ensureLocalKeygenArtifacts(deps, opts, persisted.publicKey), persisted));
201
+ }
166
202
  const keypair = yield* runSealKeygen(deps.runtime, opts.name, cargoImage);
167
203
  return yield* startLocalKeygenContainer(deps, opts, cargoImage, yield* stageResolvedLocalKeygenState(deps, opts, yield* ensureLocalKeygenArtifacts(deps, opts, keypair.publicKey), keypair));
168
204
  }).pipe(Effect.catchTag("ArtifactPublishError", (err) => Effect.fail(sealError("seal", {
@@ -170,9 +206,9 @@ const bootLocalKeygen = (deps, opts) => Effect.gen(function* () {
170
206
  message: `seal.local-keygen: on-chain artifact failure (${err.reason}): ${err.detail}`,
171
207
  cause: err
172
208
  }))), Effect.withSpan("devstack.plugin.seal.localKeygen.boot", { attributes: {
173
- "devstack.plugin": "seal",
174
- "seal.name": opts.name,
175
- "seal.version": opts.version
209
+ [SpanAttr.plugin]: "seal",
210
+ [SealSpans.name]: opts.name,
211
+ [SealSpans.version]: opts.version
176
212
  } }));
177
213
  //#endregion
178
214
  export { bootLocalKeygen, resolveLocalKeygenOptions };
@@ -1 +1 @@
1
- {"version":3,"file":"local-keygen.mjs","names":[],"sources":["../../../../src/plugins/seal/mode/local-keygen.ts"],"sourcesContent":["// Seal local-keygen mode — the full localnet path.\n//\n// Distilled-doc reference (07-seal.md §\"Lifecycle / Startup —\n// `sealLocalKeygen`\"). Eight ordered phases:\n//\n// 0. Yield deps (Sui, Identity, ContainerRuntime, artifact publisher publisher).\n// 1. Image build (bootstrap asset — parallel with sui's boot).\n// 1a. Move source resolve (bootstrap asset, conditional).\n// 2. BLS keygen one-shot (real `runtime.runOneShot` against cargo\n// image; output parsed via regex).\n// 3. Publish seal Move package (via artifact publisher primitive).\n// 4. Register on-chain KeyServer (via artifact publisher primitive).\n// 5. Render config yaml + stage master-key env-file (atomic\n// FileSystem\n// writes).\n// 6. Start long-running key-server container (real\n// `runtime.ensureContainer`\n// + exec-based ready\n// probe).\n// 7. Project the plugin's aggregate value.\n//\n// Distilled-doc invariants pinned by this file:\n//\n// #1 KeyServer.url == routed hostname — single mint point\n// (`routedUrl` passed\n// identically into\n// `registerKeyServer`\n// and `buildKeyServerSpec`).\n// #2 Boot order keygen → publish → register → config → container.\n// #4 env-file for secret loading (not -e MASTER_KEY=…).\n// #5 No host-port publish.\n// #6 Keypair B8 verify cascade (deploy.ts:buildKeypairVerify).\n// #7 Signal-forwarding entrypoint shell (image-side).\n// #8 Fork incompatibility throw — handled at the barrel\n// (`index.ts`), NOT here.\n// #9 Peer-dep structural assignability (compile-time check\n// lives in registry-publish.ts).\n//\n// This is the substrate-name-LEAK boundary. Inside this file we can\n// say \"seal\"; outside `src/plugins/seal/`, the substrate doesn't\n// know seal exists.\n\nimport { Effect, FileSystem, Path, Schema, type Scope } from 'effect';\n\nimport type { ChainId } from '../../../substrate/brand.ts';\nimport type { ChainProbe } from '../../../contracts/chain-probe.ts';\nimport type { ContainerLabelTuple } from '../../../contracts/snapshotable.ts';\nimport type { ContainerRuntime, ImageRef } from '../../../contracts/container-runtime.ts';\nimport type {\n\tArtifactPublishError,\n\tArtifactPublisher,\n} from '../../../primitives/artifact-publisher.ts';\nimport type { AccountValue } from '../../account/service.ts';\nimport {\n\tparseMasterKeyEnvFile,\n\trenderSealKeyServerConfig,\n\tstageSealConfig,\n} from '../config-render.ts';\nimport {\n\tpublishSealPackage,\n\tregisterKeyServer,\n\ttype SealObjectProbeKey,\n\ttype SealSuiSdk,\n} from '../deploy.ts';\nimport { sealError, type SealError } from '../errors.ts';\nimport { MASTER_KEY_ENVFILE_BASENAME, runSealKeygen, type PersistedBlsKeypair } from '../keygen.ts';\nimport { makeKeyManager, stubRotate } from '../key-manager.ts';\nimport { buildKeyServerSpec, startKeyServer, type KeyServerContainerSpec } from '../key-server.ts';\nimport type { SealKeyServerEntry, SealLocalKeygenResolved } from '../registry-publish.ts';\nimport { resolveDefaultSealCargoImage } from '../bootstrap-assets/cargo-image.ts';\nimport { resolveDefaultSealSource } from '../bootstrap-assets/source-fetch.ts';\nimport { atomicWriteFile } from '../../../substrate/runtime/atomic-write.ts';\n\n// ---------------------------------------------------------------------------\n// Options (factory-time)\n// ---------------------------------------------------------------------------\n\n/** Options the local-keygen mode accepts. Mirrors v3\n * `SealLocalKeygenOptions` (07-seal.md §\"Configuration\"). The\n * barrel (`index.ts`) folds the typed `SealLocalKeygenOptions`\n * surface into this internal shape after default resolution. */\nexport interface LocalKeygenOptions {\n\treadonly name?: string;\n\treadonly version?: string;\n\treadonly movePackagePath?: string;\n\treadonly readyTimeoutMs?: number;\n\treadonly keyServerName?: string;\n}\n\n/** Resolved options after defaults are applied. */\nexport interface ResolvedLocalKeygenOptions {\n\treadonly name: string;\n\treadonly version: string;\n\treadonly readyTimeoutMs: number;\n\treadonly keyServerName: string;\n\treadonly movePackagePath?: string;\n}\n\nconst DEFAULT_READY_TIMEOUT_MS = 60_000;\nconst DEFAULT_KEY_SERVER_NAME = 'devstack-local';\n\n/** Synchronous factory-time defaults application. Pure — no\n * validation throws because the localnet signer requirement is\n * enforced one layer up in the barrel (the type-narrowed\n * `sealFor(local).localKeygen({signer})` makes signer required). */\nexport const resolveLocalKeygenOptions = (\n\topts: LocalKeygenOptions,\n\tdefaultVersion: string,\n): ResolvedLocalKeygenOptions => ({\n\tname: opts.name ?? 'seal',\n\tversion: opts.version ?? defaultVersion,\n\treadyTimeoutMs: opts.readyTimeoutMs ?? DEFAULT_READY_TIMEOUT_MS,\n\tkeyServerName: opts.keyServerName ?? DEFAULT_KEY_SERVER_NAME,\n\tmovePackagePath: opts.movePackagePath,\n});\n\n// ---------------------------------------------------------------------------\n// Inputs to the boot pipeline (acquire-time)\n// ---------------------------------------------------------------------------\n\n/** Acquire-time deps the boot pipeline consumes. Sourced by the\n * barrel (`index.ts`) from a mix of:\n *\n * - substrate-resolved values (`IdentityContext`,\n * `ContainerRuntimeService`, `ArtifactPublisher`);\n * - substrate-derived identifiers (chainId, servicePath,\n * subnet, etc.);\n * - router-resolved URL (single mint — distilled-doc invariant #1).\n *\n * The barrel composes these from substrate services\n * (ContainerRuntime, IdentityContext, ArtifactPublisher,\n * StackPathsService) at acquire-time. */\nexport interface LocalKeygenDeps {\n\treadonly runtime: ContainerRuntime;\n\treadonly publisher: ArtifactPublisher;\n\treadonly signer: AccountValue;\n\treadonly sdk: SealSuiSdk;\n\treadonly buildImage?: ImageRef;\n\treadonly chainProbe: ChainProbe<SealObjectProbeKey>;\n\treadonly chain: ChainId;\n\t/** Per-stack on-disk dir under `runtime/seal/`. Host path for the\n\t * config yaml + master-key env-file. */\n\treadonly servicePath: string;\n\t/** Container name composed by the substrate (app + stack + name +\n\t * role). */\n\treadonly containerName: string;\n\t/** Label tuple driving snapshot/inspect by labels. */\n\treadonly labels: ContainerLabelTuple;\n\t/** Seal's per-stack docker network — the key-server daemon attaches\n\t * to this network. */\n\treadonly suiNetworkName: string;\n\t/** In-network sui RPC URL — the daemon's CONFIG_PATH yaml carries\n\t * this. */\n\treadonly suiRpcUrlInNetwork: string;\n\t/** Router-resolved single mint (distilled-doc invariant #1). */\n\treadonly routedHostname: string;\n\treadonly routedUrl: string;\n}\n\ninterface PersistedLocalKeygenKeyMaterial {\n\treadonly masterKey: string;\n\treadonly publicKey: string;\n\treadonly masterKeyEnvFile: string;\n}\n\ninterface PersistedLocalKeygenState extends PersistedLocalKeygenKeyMaterial {\n\treadonly packageId: string;\n\treadonly keyServerObjectId: string;\n}\n\nconst LOCAL_KEYGEN_STATE_VERSION = 1;\nconst LOCAL_KEYGEN_STATE_BASENAME = 'local-keygen-state.v1.json';\n\nconst PersistedLocalKeygenMetadataSchema = Schema.Struct({\n\tversion: Schema.Literal(LOCAL_KEYGEN_STATE_VERSION),\n\tpublicKey: Schema.String,\n});\n\ntype PersistedLocalKeygenMetadata = Schema.Schema.Type<typeof PersistedLocalKeygenMetadataSchema>;\n\nconst localKeygenMetadataPath = (servicePath: string): string =>\n\t`${servicePath}/${LOCAL_KEYGEN_STATE_BASENAME}`;\n\nconst readPersistedLocalKeygenMetadata = (\n\tservicePath: string,\n): Effect.Effect<PersistedLocalKeygenMetadata | null, never, FileSystem.FileSystem> =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem.FileSystem;\n\t\tconst raw = yield* fs\n\t\t\t.readFileString(localKeygenMetadataPath(servicePath))\n\t\t\t.pipe(Effect.catch(() => Effect.succeed(null)));\n\t\tif (raw === null) return null;\n\t\tconst parsed = yield* Effect.try({\n\t\t\ttry: () => JSON.parse(raw) as unknown,\n\t\t\tcatch: () => null,\n\t\t}).pipe(Effect.catch(() => Effect.succeed(null)));\n\t\tif (parsed === null) return null;\n\t\treturn yield* Schema.decodeUnknownEffect(PersistedLocalKeygenMetadataSchema)(parsed).pipe(\n\t\t\tEffect.catch(() => Effect.succeed(null)),\n\t\t);\n\t});\n\nconst stagePersistedLocalKeygenMetadata = (\n\tservicePath: string,\n\tname: string,\n\tmetadata: PersistedLocalKeygenMetadata,\n): Effect.Effect<void, SealError, FileSystem.FileSystem> =>\n\tatomicWriteFile(\n\t\tlocalKeygenMetadataPath(servicePath),\n\t\tnew TextEncoder().encode(`${JSON.stringify(metadata, null, 2)}\\n`),\n\t\t{\n\t\t\tmode: 0o644,\n\t\t\tparentMode: 0o700,\n\t\t},\n\t).pipe(\n\t\tEffect.catch((cause) =>\n\t\t\tEffect.fail(\n\t\t\t\tsealError('config-render', {\n\t\t\t\t\tname,\n\t\t\t\t\tmessage: `seal.config-render: failed to write ${LOCAL_KEYGEN_STATE_BASENAME} (${cause.stage})`,\n\t\t\t\t\tcause,\n\t\t\t\t}),\n\t\t\t),\n\t\t),\n\t);\n\nconst readPersistedLocalKeygenState = (\n\tservicePath: string,\n): Effect.Effect<PersistedLocalKeygenKeyMaterial | null, never, FileSystem.FileSystem> =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem.FileSystem;\n\t\tconst masterKeyEnvFile = `${servicePath}/${MASTER_KEY_ENVFILE_BASENAME}`;\n\t\tconst masterKeyBody = yield* fs\n\t\t\t.readFileString(masterKeyEnvFile)\n\t\t\t.pipe(Effect.catch(() => Effect.succeed(null)));\n\t\tif (masterKeyBody === null) return null;\n\t\tconst masterKey = parseMasterKeyEnvFile(masterKeyBody);\n\t\tif (masterKey === null) return null;\n\t\tconst metadata = yield* readPersistedLocalKeygenMetadata(servicePath);\n\t\tif (metadata === null) return null;\n\n\t\treturn {\n\t\t\tmasterKey,\n\t\t\tpublicKey: metadata.publicKey,\n\t\t\tmasterKeyEnvFile,\n\t\t};\n\t});\n\nconst sealConfigFingerprint = (parts: {\n\treadonly packageId: string;\n\treadonly keyServerObjectId: string;\n\treadonly nodeUrl: string;\n}): string =>\n\t[\n\t\t`package=${parts.packageId}`,\n\t\t`keyServer=${parts.keyServerObjectId}`,\n\t\t`nodeUrl=${parts.nodeUrl}`,\n\t].join('|');\n\nconst resolveMovePackagePath = (\n\tdeps: LocalKeygenDeps,\n\topts: ResolvedLocalKeygenOptions,\n): Effect.Effect<string, SealError, Scope.Scope | FileSystem.FileSystem | Path.Path> =>\n\topts.movePackagePath\n\t\t? Effect.succeed(opts.movePackagePath)\n\t\t: resolveDefaultSealSource(deps.runtime).pipe(Effect.map((s) => s.path));\n\nconst ensureLocalKeygenArtifacts = (\n\tdeps: LocalKeygenDeps,\n\topts: ResolvedLocalKeygenOptions,\n\tpublicKey: string,\n): Effect.Effect<\n\t{\n\t\treadonly packageId: string;\n\t\treadonly keyServerObjectId: string;\n\t},\n\tSealError | ArtifactPublishError,\n\tScope.Scope | FileSystem.FileSystem | Path.Path\n> =>\n\tEffect.gen(function* () {\n\t\tconst movePackagePath = yield* resolveMovePackagePath(deps, opts);\n\t\tconst { packageId } = yield* publishSealPackage(deps.publisher, {\n\t\t\tname: opts.name,\n\t\t\tchain: deps.chain,\n\t\t\tmovePackagePath,\n\t\t\tsigner: deps.signer,\n\t\t\tsdk: deps.sdk,\n\t\t\truntime: deps.runtime,\n\t\t\tchainProbe: deps.chainProbe,\n\t\t\t...(deps.buildImage !== undefined ? { buildImage: deps.buildImage } : {}),\n\t\t});\n\t\tconst { objectId: keyServerObjectId } = yield* registerKeyServer(deps.publisher, {\n\t\t\tname: opts.name,\n\t\t\tchain: deps.chain,\n\t\t\tkeyServerUrl: deps.routedUrl,\n\t\t\tsealPackageId: packageId,\n\t\t\tpublicKeyHex: publicKey,\n\t\t\tkeyServerName: opts.keyServerName,\n\t\t\tsigner: deps.signer,\n\t\t\tsdk: deps.sdk,\n\t\t\tchainProbe: deps.chainProbe,\n\t\t});\n\t\treturn { packageId, keyServerObjectId };\n\t});\n\nconst stageResolvedLocalKeygenState = (\n\tdeps: LocalKeygenDeps,\n\topts: ResolvedLocalKeygenOptions,\n\tartifacts: {\n\t\treadonly packageId: string;\n\t\treadonly keyServerObjectId: string;\n\t},\n\tkeypair: Pick<PersistedBlsKeypair, 'masterKey' | 'publicKey'>,\n): Effect.Effect<PersistedLocalKeygenState, SealError, FileSystem.FileSystem> =>\n\tEffect.gen(function* () {\n\t\tconst yaml = renderSealKeyServerConfig({\n\t\t\tsealPackageId: artifacts.packageId,\n\t\t\tnodeUrl: deps.suiRpcUrlInNetwork,\n\t\t\tkeyServerObjectId: artifacts.keyServerObjectId,\n\t\t});\n\t\tconst { masterKeyEnvFile } = yield* stageSealConfig(\n\t\t\tyaml,\n\t\t\tkeypair.masterKey,\n\t\t\tdeps.servicePath,\n\t\t\topts.name,\n\t\t);\n\t\tyield* stagePersistedLocalKeygenMetadata(deps.servicePath, opts.name, {\n\t\t\tversion: LOCAL_KEYGEN_STATE_VERSION,\n\t\t\tpublicKey: keypair.publicKey,\n\t\t});\n\t\treturn {\n\t\t\tpackageId: artifacts.packageId,\n\t\t\tkeyServerObjectId: artifacts.keyServerObjectId,\n\t\t\tmasterKey: keypair.masterKey,\n\t\t\tpublicKey: keypair.publicKey,\n\t\t\tmasterKeyEnvFile,\n\t\t};\n\t});\n\nconst startLocalKeygenContainer = (\n\tdeps: LocalKeygenDeps,\n\topts: ResolvedLocalKeygenOptions,\n\tcargoImage: ImageRef,\n\tstate: PersistedLocalKeygenState,\n): Effect.Effect<SealLocalKeygenResolved, SealError, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst spec: KeyServerContainerSpec = buildKeyServerSpec({\n\t\t\tname: opts.name,\n\t\t\timage: cargoImage,\n\t\t\tcontainerName: deps.containerName,\n\t\t\tlabels: deps.labels,\n\t\t\tsuiNetwork: deps.suiNetworkName,\n\t\t\tservicePath: deps.servicePath,\n\t\t\tconfigFingerprint: sealConfigFingerprint({\n\t\t\t\tpackageId: state.packageId,\n\t\t\t\tkeyServerObjectId: state.keyServerObjectId,\n\t\t\t\tnodeUrl: deps.suiRpcUrlInNetwork,\n\t\t\t}),\n\t\t\troutedHostname: deps.routedHostname,\n\t\t\troutedUrl: deps.routedUrl,\n\t\t\treadyTimeoutMs: opts.readyTimeoutMs,\n\t\t});\n\t\tconst { containerName } = yield* startKeyServer(deps.runtime, spec, opts.name);\n\t\tvoid containerName;\n\n\t\tconst serverConfigs: ReadonlyArray<SealKeyServerEntry> = [\n\t\t\t{ objectId: state.keyServerObjectId, weight: 1 },\n\t\t];\n\t\tconst keyManager = makeKeyManager({\n\t\t\tname: opts.name,\n\t\t\tmasterKeyEnvFile: state.masterKeyEnvFile,\n\t\t\trotateImpl: stubRotate(opts.name),\n\t\t});\n\t\treturn {\n\t\t\tkeyServer: {\n\t\t\t\tserverConfigs,\n\t\t\t\tkeyServerUrl: deps.routedUrl,\n\t\t\t\tobjectId: state.keyServerObjectId,\n\t\t\t},\n\t\t\tkeyManager,\n\t\t\tpackageId: state.packageId,\n\t\t} satisfies SealLocalKeygenResolved;\n\t});\n\n// ---------------------------------------------------------------------------\n// Boot pipeline\n// ---------------------------------------------------------------------------\n\n/** The plugin's aggregate acquire body. Calls each phase in\n * order; failures surface as typed `SealError` /\n * `ArtifactPublishError` through the Effect's error channel.\n *\n * Distilled-doc invariant #2 — phase order is keygen → publish →\n * register → config-render → container. Any phase failure short-\n * circuits before downstream phases (cheap on warm restart because\n * the ArtifactPublisher cache + verify covers steps 3-4). */\nexport const bootLocalKeygen = (\n\tdeps: LocalKeygenDeps,\n\topts: ResolvedLocalKeygenOptions,\n): Effect.Effect<\n\tSealLocalKeygenResolved,\n\tSealError | ArtifactPublishError,\n\tScope.Scope | FileSystem.FileSystem | Path.Path\n> =>\n\tEffect.gen(function* () {\n\t\t// ---- cargo image (bootstrap asset) -----------------------\n\t\t// The cargo image's resolver honors `SEAL_CARGO_IMAGE_OVERRIDE`\n\t\t// for the pre-baked path; falls back to a documented seam error\n\t\t// pointing at the override hatch.\n\t\tconst cargoImage: ImageRef = yield* resolveDefaultSealCargoImage(deps.runtime);\n\n\t\tconst persisted = yield* readPersistedLocalKeygenState(deps.servicePath);\n\t\tif (persisted !== null) {\n\t\t\tconst artifacts = yield* ensureLocalKeygenArtifacts(deps, opts, persisted.publicKey);\n\t\t\tconst refreshed = yield* stageResolvedLocalKeygenState(deps, opts, artifacts, persisted);\n\t\t\treturn yield* startLocalKeygenContainer(deps, opts, cargoImage, refreshed);\n\t\t}\n\n\t\t// ---- keygen (BLS12-381 master + public) -----------------\n\t\t// The keypair flows into publish + register inputs. The\n\t\t// artifact publisher still owns the on-chain artifacts; this\n\t\t// local state only persists key material.\n\t\tconst keypair: PersistedBlsKeypair = yield* runSealKeygen(deps.runtime, opts.name, cargoImage);\n\n\t\t// ---- render config + stage master-key -------------------\n\t\t// Distilled-doc invariant #19 — `network: !Devnet` is hardcoded\n\t\t// by `renderSealKeyServerConfig`. Invariant #4 — `master-key.env`\n\t\t// MUST NOT be unlinked on scope close. `stageSealConfig` does\n\t\t// NOT register a finalizer.\n\t\tconst artifacts = yield* ensureLocalKeygenArtifacts(deps, opts, keypair.publicKey);\n\t\tconst state = yield* stageResolvedLocalKeygenState(deps, opts, artifacts, keypair);\n\t\treturn yield* startLocalKeygenContainer(deps, opts, cargoImage, state);\n\t}).pipe(\n\t\tEffect.catchTag('ArtifactPublishError', (err) =>\n\t\t\tEffect.fail(\n\t\t\t\tsealError('seal', {\n\t\t\t\t\tname: opts.name,\n\t\t\t\t\tmessage: `seal.local-keygen: on-chain artifact failure (${err.reason}): ${err.detail}`,\n\t\t\t\t\tcause: err,\n\t\t\t\t}),\n\t\t\t),\n\t\t),\n\t\tEffect.withSpan('devstack.plugin.seal.localKeygen.boot', {\n\t\t\tattributes: {\n\t\t\t\t'devstack.plugin': 'seal',\n\t\t\t\t'seal.name': opts.name,\n\t\t\t\t'seal.version': opts.version,\n\t\t\t},\n\t\t}),\n\t);\n"],"mappings":"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"}
1
+ {"version":3,"file":"local-keygen.mjs","names":[],"sources":["../../../../src/plugins/seal/mode/local-keygen.ts"],"sourcesContent":["// Seal local-keygen mode — the full localnet path.\n//\n// Distilled-doc reference (07-seal.md §\"Lifecycle / Startup —\n// `sealLocalKeygen`\"). Eight ordered phases:\n//\n// 0. Yield deps (Sui, Identity, ContainerRuntime, artifact publisher publisher).\n// 1. Image build (bootstrap asset — parallel with sui's boot).\n// 1a. Move source resolve (bootstrap asset, conditional).\n// 2. BLS keygen one-shot (real `runtime.runOneShot` against cargo\n// image; output parsed via regex).\n// 3. Publish seal Move package (via artifact publisher primitive).\n// 4. Register on-chain KeyServer (via artifact publisher primitive).\n// 5. Render config yaml + stage master-key env-file (atomic\n// FileSystem\n// writes).\n// 6. Start long-running key-server container (real\n// `runtime.ensureContainer`\n// + exec-based ready\n// probe).\n// 7. Project the plugin's aggregate value.\n//\n// Distilled-doc invariants pinned by this file:\n//\n// #1 KeyServer.url == routed hostname — single mint point\n// (`routedUrl` passed\n// identically into\n// `registerKeyServer`\n// and `buildKeyServerSpec`).\n// #2 Boot order keygen → publish → register → config → container.\n// #4 env-file for secret loading (not -e MASTER_KEY=…).\n// #5 No host-port publish.\n// #6 Keypair B8 verify cascade (deploy.ts:buildKeypairVerify).\n// #7 Signal-forwarding entrypoint shell (image-side).\n// #8 Fork incompatibility throw — handled at the barrel\n// (`index.ts`), NOT here.\n// #9 Peer-dep structural assignability (compile-time check\n// lives in registry-publish.ts).\n//\n// This is the substrate-name-LEAK boundary. Inside this file we can\n// say \"seal\"; outside `src/plugins/seal/`, the substrate doesn't\n// know seal exists.\n\nimport { Effect, FileSystem, Path, Schema, type Scope } from 'effect';\n\nimport { decodeJsonText } from '../../../substrate/runtime/runtime-decode.ts';\n\nimport type { ChainId } from '../../../substrate/brand.ts';\nimport type { ChainProbe } from '../../../contracts/chain-probe.ts';\nimport type { ContainerLabelTuple } from '../../../contracts/snapshotable.ts';\nimport type { ContainerRuntime, ImageRef } from '../../../contracts/container-runtime.ts';\nimport type {\n\tArtifactPublishError,\n\tArtifactPublisher,\n} from '../../../primitives/artifact-publisher.ts';\nimport type { AccountValue } from '../../account/index.ts';\nimport {\n\tparseMasterKeyEnvFile,\n\trenderSealKeyServerConfig,\n\tstageSealConfig,\n} from '../config-render.ts';\nimport {\n\tpublishSealPackage,\n\tregisterKeyServer,\n\ttype SealObjectProbeKey,\n\ttype SealSuiSdk,\n} from '../deploy.ts';\nimport { sealError, type SealError } from '../errors.ts';\nimport { SealSpans } from '../spans.ts';\nimport { SpanAttr } from '../../../substrate/runtime/observability/spans.ts';\nimport { MASTER_KEY_ENVFILE_BASENAME, runSealKeygen, type PersistedBlsKeypair } from '../keygen.ts';\nimport { makeKeyManager } from '../key-manager.ts';\nimport { buildKeyServerSpec, startKeyServer, type KeyServerContainerSpec } from '../key-server.ts';\nimport type { SealKeyServerEntry, SealLocalKeygenResolved } from '../registry-publish.ts';\nimport { resolveDefaultSealCargoImage } from '../bootstrap-assets/cargo-image.ts';\nimport { resolveDefaultSealSource } from '../bootstrap-assets/source-fetch.ts';\nimport { atomicWriteFile } from '../../../substrate/runtime/atomic-write.ts';\nimport { versionedDocSchema } from '../../../substrate/versioned-doc-schema.ts';\n\n// ---------------------------------------------------------------------------\n// Options (factory-time)\n// ---------------------------------------------------------------------------\n\n/** Options the local-keygen mode accepts. Mirrors v3\n * `SealLocalKeygenOptions` (07-seal.md §\"Configuration\"). The\n * barrel (`index.ts`) folds the typed `SealLocalKeygenOptions`\n * surface into this internal shape after default resolution. */\nexport interface LocalKeygenOptions {\n\treadonly name?: string;\n\treadonly version?: string;\n\treadonly movePackagePath?: string;\n\treadonly readyTimeoutMs?: number;\n\treadonly keyServerName?: string;\n}\n\n/** Resolved options after defaults are applied. */\nexport interface ResolvedLocalKeygenOptions {\n\treadonly name: string;\n\treadonly version: string;\n\treadonly readyTimeoutMs: number;\n\treadonly keyServerName: string;\n\treadonly movePackagePath?: string;\n}\n\nconst DEFAULT_READY_TIMEOUT_MS = 60_000;\nconst DEFAULT_KEY_SERVER_NAME = 'devstack-local';\n\n/** Synchronous factory-time defaults application. Pure — no\n * validation throws because the localnet signer requirement is\n * enforced one layer up in the barrel (the type-narrowed\n * `sealFor(local).localKeygen({signer})` makes signer required). */\nexport const resolveLocalKeygenOptions = (\n\topts: LocalKeygenOptions,\n\tdefaultVersion: string,\n): ResolvedLocalKeygenOptions => ({\n\tname: opts.name ?? 'seal',\n\tversion: opts.version ?? defaultVersion,\n\treadyTimeoutMs: opts.readyTimeoutMs ?? DEFAULT_READY_TIMEOUT_MS,\n\tkeyServerName: opts.keyServerName ?? DEFAULT_KEY_SERVER_NAME,\n\tmovePackagePath: opts.movePackagePath,\n});\n\n// ---------------------------------------------------------------------------\n// Inputs to the boot pipeline (acquire-time)\n// ---------------------------------------------------------------------------\n\n/** Acquire-time deps the boot pipeline consumes. Sourced by the\n * barrel (`index.ts`) from a mix of:\n *\n * - substrate-resolved values (`IdentityContext`,\n * `ContainerRuntimeService`, `ArtifactPublisher`);\n * - substrate-derived identifiers (chainId, servicePath,\n * subnet, etc.);\n * - router-resolved URL (single mint — distilled-doc invariant #1).\n *\n * The barrel composes these from substrate services\n * (ContainerRuntime, IdentityContext, ArtifactPublisher,\n * StackPathsService) at acquire-time. */\nexport interface LocalKeygenDeps {\n\treadonly runtime: ContainerRuntime;\n\treadonly publisher: ArtifactPublisher;\n\treadonly signer: AccountValue;\n\treadonly sdk: SealSuiSdk;\n\treadonly buildImage?: ImageRef;\n\treadonly chainProbe: ChainProbe<SealObjectProbeKey>;\n\treadonly chain: ChainId;\n\t/** Per-stack on-disk dir under `runtime/seal/`. Host path for the\n\t * config yaml + master-key env-file. */\n\treadonly servicePath: string;\n\t/** Container name composed by the substrate (app + stack + name +\n\t * role). */\n\treadonly containerName: string;\n\t/** Label tuple driving snapshot/inspect by labels. */\n\treadonly labels: ContainerLabelTuple;\n\t/** Seal's per-stack docker network — the key-server daemon attaches\n\t * to this network. */\n\treadonly suiNetworkName: string;\n\t/** In-network sui RPC URL — the daemon's CONFIG_PATH yaml carries\n\t * this. */\n\treadonly suiRpcUrlInNetwork: string;\n\t/** Router-resolved single mint (distilled-doc invariant #1). */\n\treadonly routedHostname: string;\n\treadonly routedUrl: string;\n}\n\ninterface PersistedLocalKeygenKeyMaterial {\n\treadonly masterKey: string;\n\treadonly publicKey: string;\n\treadonly masterKeyEnvFile: string;\n}\n\ninterface PersistedLocalKeygenState extends PersistedLocalKeygenKeyMaterial {\n\treadonly packageId: string;\n\treadonly keyServerObjectId: string;\n}\n\nconst LOCAL_KEYGEN_STATE_VERSION = 1;\nconst LOCAL_KEYGEN_STATE_BASENAME = 'local-keygen-state.v1.json';\n\nconst PersistedLocalKeygenMetadataSchema = versionedDocSchema(LOCAL_KEYGEN_STATE_VERSION, {\n\tpublicKey: Schema.String,\n});\n\ntype PersistedLocalKeygenMetadata = Schema.Schema.Type<typeof PersistedLocalKeygenMetadataSchema>;\n\nconst localKeygenMetadataPath = (servicePath: string): string =>\n\t`${servicePath}/${LOCAL_KEYGEN_STATE_BASENAME}`;\n\nconst readPersistedLocalKeygenMetadata = (\n\tservicePath: string,\n): Effect.Effect<PersistedLocalKeygenMetadata | null, never, FileSystem.FileSystem> =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem.FileSystem;\n\t\tconst path = localKeygenMetadataPath(servicePath);\n\t\tconst raw = yield* fs.readFileString(path).pipe(Effect.catch(() => Effect.succeed(null)));\n\t\tif (raw === null) return null;\n\t\t// Parse + decode failures here mean \"no usable persisted metadata\"\n\t\t// and the caller treats this as a miss; the typed\n\t\t// `RuntimeDecodeIssue` carries the parse/decode diagnostic for\n\t\t// debugging but is collapsed to `null` so the boot loop falls\n\t\t// through to a fresh keygen.\n\t\treturn yield* decodeJsonText(PersistedLocalKeygenMetadataSchema, raw, {\n\t\t\tsource: path,\n\t\t\tmkError: (issue) => issue,\n\t\t}).pipe(Effect.catch(() => Effect.succeed(null)));\n\t});\n\nconst stagePersistedLocalKeygenMetadata = (\n\tservicePath: string,\n\tname: string,\n\tmetadata: PersistedLocalKeygenMetadata,\n): Effect.Effect<void, SealError, FileSystem.FileSystem> =>\n\tatomicWriteFile(\n\t\tlocalKeygenMetadataPath(servicePath),\n\t\tnew TextEncoder().encode(`${JSON.stringify(metadata, null, 2)}\\n`),\n\t\t{\n\t\t\tmode: 0o644,\n\t\t\tparentMode: 0o700,\n\t\t},\n\t).pipe(\n\t\tEffect.catch((cause) =>\n\t\t\tEffect.fail(\n\t\t\t\tsealError('config-render', {\n\t\t\t\t\tname,\n\t\t\t\t\tmessage: `seal.config-render: failed to write ${LOCAL_KEYGEN_STATE_BASENAME} (${cause.stage})`,\n\t\t\t\t\tcause,\n\t\t\t\t}),\n\t\t\t),\n\t\t),\n\t);\n\nconst readPersistedLocalKeygenState = (\n\tservicePath: string,\n): Effect.Effect<PersistedLocalKeygenKeyMaterial | null, never, FileSystem.FileSystem> =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem.FileSystem;\n\t\tconst masterKeyEnvFile = `${servicePath}/${MASTER_KEY_ENVFILE_BASENAME}`;\n\t\tconst masterKeyBody = yield* fs\n\t\t\t.readFileString(masterKeyEnvFile)\n\t\t\t.pipe(Effect.catch(() => Effect.succeed(null)));\n\t\tif (masterKeyBody === null) return null;\n\t\tconst masterKey = parseMasterKeyEnvFile(masterKeyBody);\n\t\tif (masterKey === null) return null;\n\t\tconst metadata = yield* readPersistedLocalKeygenMetadata(servicePath);\n\t\tif (metadata === null) return null;\n\n\t\treturn {\n\t\t\tmasterKey,\n\t\t\tpublicKey: metadata.publicKey,\n\t\t\tmasterKeyEnvFile,\n\t\t};\n\t});\n\n/** BLS12-381 master key — 32 bytes, persisted as 64 hex chars. */\nconst BLS_MASTER_KEY_HEX_LEN = 64;\n/** BLS12-381 G2 uncompressed public key — 96 bytes, persisted as 192 hex chars. */\nconst BLS_PUBLIC_KEY_HEX_LEN = 192;\nconst HEX_ONLY_RE = /^[0-9a-fA-F]+$/;\n\n/** Stricter decode than the JSON-shape Schema alone — verifies the\n * persisted master key + public key are well-formed BLS12-381 hex of\n * the expected widths. The Schema validation alone accepts any\n * string, so a corrupt-on-disk JSON whose `publicKey` was overwritten\n * to a shorter / wrong-width value would otherwise be silently\n * reused on boot — leading to a master-key / KeyServer mismatch\n * (the master-key.env carries one key, the registered KeyServer's\n * on-chain `publicKey` carries a different one). Distilled-doc\n * invariant #6 (keypair B8 verify cascade) covers the on-chain\n * side; this is the on-disk side.\n *\n * We cannot in-process re-derive the G2 public key from the master\n * scalar without bundling a BLS12-381 implementation (the keygen\n * binary owns this in cargo-land). The width invariant is the\n * cheapest defense that catches the realistic corruption modes:\n * truncated writes, hand-edited JSON, stale persistence from an\n * older devstack version. */\nconst validatePersistedKeyMaterialShape = (\n\tmaterial: PersistedLocalKeygenKeyMaterial,\n\tname: string,\n): Effect.Effect<void, SealError> => {\n\tif (material.masterKey.length !== BLS_MASTER_KEY_HEX_LEN || !HEX_ONLY_RE.test(material.masterKey)) {\n\t\treturn Effect.fail(\n\t\t\tsealError('config-render', {\n\t\t\t\tname,\n\t\t\t\tmessage:\n\t\t\t\t\t`seal.local-keygen: persisted master key in ${MASTER_KEY_ENVFILE_BASENAME} ` +\n\t\t\t\t\t`is not ${BLS_MASTER_KEY_HEX_LEN}-char hex (got ${material.masterKey.length} chars). ` +\n\t\t\t\t\t'The on-disk state is corrupt; delete the seal service directory and ' +\n\t\t\t\t\t're-boot to regenerate, or restore from a known-good snapshot.',\n\t\t\t}),\n\t\t);\n\t}\n\tif (\n\t\tmaterial.publicKey.length !== BLS_PUBLIC_KEY_HEX_LEN ||\n\t\t!HEX_ONLY_RE.test(material.publicKey)\n\t) {\n\t\treturn Effect.fail(\n\t\t\tsealError('config-render', {\n\t\t\t\tname,\n\t\t\t\tmessage:\n\t\t\t\t\t`seal.local-keygen: persisted publicKey in ${LOCAL_KEYGEN_STATE_BASENAME} ` +\n\t\t\t\t\t`is not ${BLS_PUBLIC_KEY_HEX_LEN}-char hex (got ${material.publicKey.length} chars). ` +\n\t\t\t\t\t'The on-disk state is corrupt; reusing it would publish a KeyServer ' +\n\t\t\t\t\t'whose on-chain publicKey diverges from the local master key. ' +\n\t\t\t\t\t'Delete the seal service directory and re-boot to regenerate.',\n\t\t\t}),\n\t\t);\n\t}\n\treturn Effect.void;\n};\n\nconst sealConfigFingerprint = (parts: {\n\treadonly packageId: string;\n\treadonly keyServerObjectId: string;\n\treadonly nodeUrl: string;\n}): string =>\n\t[\n\t\t`package=${parts.packageId}`,\n\t\t`keyServer=${parts.keyServerObjectId}`,\n\t\t`nodeUrl=${parts.nodeUrl}`,\n\t].join('|');\n\nconst resolveMovePackagePath = (\n\tdeps: LocalKeygenDeps,\n\topts: ResolvedLocalKeygenOptions,\n): Effect.Effect<string, SealError, Scope.Scope | FileSystem.FileSystem | Path.Path> =>\n\topts.movePackagePath\n\t\t? Effect.succeed(opts.movePackagePath)\n\t\t: resolveDefaultSealSource(deps.runtime).pipe(Effect.map((s) => s.path));\n\nconst ensureLocalKeygenArtifacts = (\n\tdeps: LocalKeygenDeps,\n\topts: ResolvedLocalKeygenOptions,\n\tpublicKey: string,\n): Effect.Effect<\n\t{\n\t\treadonly packageId: string;\n\t\treadonly keyServerObjectId: string;\n\t},\n\tSealError | ArtifactPublishError,\n\tScope.Scope | FileSystem.FileSystem | Path.Path\n> =>\n\tEffect.gen(function* () {\n\t\tconst movePackagePath = yield* resolveMovePackagePath(deps, opts);\n\t\tconst { packageId } = yield* publishSealPackage(deps.publisher, {\n\t\t\tname: opts.name,\n\t\t\tchain: deps.chain,\n\t\t\tmovePackagePath,\n\t\t\tsigner: deps.signer,\n\t\t\tsdk: deps.sdk,\n\t\t\truntime: deps.runtime,\n\t\t\tchainProbe: deps.chainProbe,\n\t\t\t...(deps.buildImage !== undefined ? { buildImage: deps.buildImage } : {}),\n\t\t});\n\t\tconst { objectId: keyServerObjectId } = yield* registerKeyServer(deps.publisher, {\n\t\t\tname: opts.name,\n\t\t\tchain: deps.chain,\n\t\t\tkeyServerUrl: deps.routedUrl,\n\t\t\tsealPackageId: packageId,\n\t\t\tpublicKeyHex: publicKey,\n\t\t\tkeyServerName: opts.keyServerName,\n\t\t\tsigner: deps.signer,\n\t\t\tsdk: deps.sdk,\n\t\t\tchainProbe: deps.chainProbe,\n\t\t});\n\t\treturn { packageId, keyServerObjectId };\n\t});\n\nconst stageResolvedLocalKeygenState = (\n\tdeps: LocalKeygenDeps,\n\topts: ResolvedLocalKeygenOptions,\n\tartifacts: {\n\t\treadonly packageId: string;\n\t\treadonly keyServerObjectId: string;\n\t},\n\tkeypair: Pick<PersistedBlsKeypair, 'masterKey' | 'publicKey'>,\n): Effect.Effect<PersistedLocalKeygenState, SealError, FileSystem.FileSystem> =>\n\tEffect.gen(function* () {\n\t\tconst yaml = renderSealKeyServerConfig({\n\t\t\tsealPackageId: artifacts.packageId,\n\t\t\tnodeUrl: deps.suiRpcUrlInNetwork,\n\t\t\tkeyServerObjectId: artifacts.keyServerObjectId,\n\t\t});\n\t\tconst { masterKeyEnvFile } = yield* stageSealConfig(\n\t\t\tyaml,\n\t\t\tkeypair.masterKey,\n\t\t\tdeps.servicePath,\n\t\t\topts.name,\n\t\t);\n\t\tyield* stagePersistedLocalKeygenMetadata(deps.servicePath, opts.name, {\n\t\t\tversion: LOCAL_KEYGEN_STATE_VERSION,\n\t\t\tpublicKey: keypair.publicKey,\n\t\t});\n\t\treturn {\n\t\t\tpackageId: artifacts.packageId,\n\t\t\tkeyServerObjectId: artifacts.keyServerObjectId,\n\t\t\tmasterKey: keypair.masterKey,\n\t\t\tpublicKey: keypair.publicKey,\n\t\t\tmasterKeyEnvFile,\n\t\t};\n\t});\n\nconst startLocalKeygenContainer = (\n\tdeps: LocalKeygenDeps,\n\topts: ResolvedLocalKeygenOptions,\n\tcargoImage: ImageRef,\n\tstate: PersistedLocalKeygenState,\n): Effect.Effect<SealLocalKeygenResolved, SealError, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst spec: KeyServerContainerSpec = buildKeyServerSpec({\n\t\t\tname: opts.name,\n\t\t\timage: cargoImage,\n\t\t\tcontainerName: deps.containerName,\n\t\t\tlabels: deps.labels,\n\t\t\tsuiNetwork: deps.suiNetworkName,\n\t\t\tservicePath: deps.servicePath,\n\t\t\tconfigFingerprint: sealConfigFingerprint({\n\t\t\t\tpackageId: state.packageId,\n\t\t\t\tkeyServerObjectId: state.keyServerObjectId,\n\t\t\t\tnodeUrl: deps.suiRpcUrlInNetwork,\n\t\t\t}),\n\t\t\troutedHostname: deps.routedHostname,\n\t\t\troutedUrl: deps.routedUrl,\n\t\t\treadyTimeoutMs: opts.readyTimeoutMs,\n\t\t});\n\t\tconst { containerName } = yield* startKeyServer(deps.runtime, spec, opts.name);\n\t\tvoid containerName;\n\n\t\tconst serverConfigs: ReadonlyArray<SealKeyServerEntry> = [\n\t\t\t{ objectId: state.keyServerObjectId, weight: 1 },\n\t\t];\n\t\tconst keyManager = makeKeyManager({\n\t\t\tmasterKeyEnvFile: state.masterKeyEnvFile,\n\t\t});\n\t\treturn {\n\t\t\tkeyServer: {\n\t\t\t\tserverConfigs,\n\t\t\t\tkeyServerUrl: deps.routedUrl,\n\t\t\t\tobjectId: state.keyServerObjectId,\n\t\t\t},\n\t\t\tkeyManager,\n\t\t\tpackageId: state.packageId,\n\t\t} satisfies SealLocalKeygenResolved;\n\t});\n\n// ---------------------------------------------------------------------------\n// Boot pipeline\n// ---------------------------------------------------------------------------\n\n/** The plugin's aggregate acquire body. Calls each phase in\n * order; failures surface as typed `SealError` /\n * `ArtifactPublishError` through the Effect's error channel.\n *\n * Distilled-doc invariant #2 — phase order is keygen → publish →\n * register → config-render → container. Any phase failure short-\n * circuits before downstream phases (cheap on warm restart because\n * the ArtifactPublisher cache + verify covers steps 3-4). */\nexport const bootLocalKeygen = (\n\tdeps: LocalKeygenDeps,\n\topts: ResolvedLocalKeygenOptions,\n): Effect.Effect<\n\tSealLocalKeygenResolved,\n\tSealError | ArtifactPublishError,\n\tScope.Scope | FileSystem.FileSystem | Path.Path\n> =>\n\tEffect.gen(function* () {\n\t\t// ---- cargo image (bootstrap asset) -----------------------\n\t\t// The cargo image's resolver honors `SEAL_CARGO_IMAGE_OVERRIDE`\n\t\t// for the pre-baked path; falls back to a documented seam error\n\t\t// pointing at the override hatch.\n\t\tconst cargoImage: ImageRef = yield* resolveDefaultSealCargoImage(deps.runtime, {\n\t\t\tapp: deps.labels.app,\n\t\t\tstack: deps.labels.stack,\n\t\t});\n\n\t\tconst persisted = yield* readPersistedLocalKeygenState(deps.servicePath);\n\t\tif (persisted !== null) {\n\t\t\t// Defensive invariant — if the on-disk publicKey or master key\n\t\t\t// has the wrong shape, the ArtifactPublisher cache might\n\t\t\t// happily reuse a stale on-chain KeyServer whose registered\n\t\t\t// publicKey no longer matches the master key the daemon\n\t\t\t// loads at boot. Refuse to proceed so the operator gets a\n\t\t\t// clear typed error instead of a silently-broken stack.\n\t\t\tyield* validatePersistedKeyMaterialShape(persisted, opts.name);\n\t\t\tconst artifacts = yield* ensureLocalKeygenArtifacts(deps, opts, persisted.publicKey);\n\t\t\tconst refreshed = yield* stageResolvedLocalKeygenState(deps, opts, artifacts, persisted);\n\t\t\treturn yield* startLocalKeygenContainer(deps, opts, cargoImage, refreshed);\n\t\t}\n\n\t\t// ---- keygen (BLS12-381 master + public) -----------------\n\t\t// The keypair flows into publish + register inputs. The\n\t\t// artifact publisher still owns the on-chain artifacts; this\n\t\t// local state only persists key material.\n\t\tconst keypair: PersistedBlsKeypair = yield* runSealKeygen(deps.runtime, opts.name, cargoImage);\n\n\t\t// ---- render config + stage master-key -------------------\n\t\t// Distilled-doc invariant #19 — `network: !Devnet` is hardcoded\n\t\t// by `renderSealKeyServerConfig`. Invariant #4 — `master-key.env`\n\t\t// MUST NOT be unlinked on scope close. `stageSealConfig` does\n\t\t// NOT register a finalizer.\n\t\tconst artifacts = yield* ensureLocalKeygenArtifacts(deps, opts, keypair.publicKey);\n\t\tconst state = yield* stageResolvedLocalKeygenState(deps, opts, artifacts, keypair);\n\t\treturn yield* startLocalKeygenContainer(deps, opts, cargoImage, state);\n\t}).pipe(\n\t\tEffect.catchTag('ArtifactPublishError', (err) =>\n\t\t\tEffect.fail(\n\t\t\t\tsealError('seal', {\n\t\t\t\t\tname: opts.name,\n\t\t\t\t\tmessage: `seal.local-keygen: on-chain artifact failure (${err.reason}): ${err.detail}`,\n\t\t\t\t\tcause: err,\n\t\t\t\t}),\n\t\t\t),\n\t\t),\n\t\tEffect.withSpan('devstack.plugin.seal.localKeygen.boot', {\n\t\t\tattributes: {\n\t\t\t\t[SpanAttr.plugin]: 'seal',\n\t\t\t\t[SealSpans.name]: opts.name,\n\t\t\t\t[SealSpans.version]: opts.version,\n\t\t\t},\n\t\t}),\n\t);\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { resource } from "../../substrate/plugin.mjs";
2
+ import "../../api/define-plugin.mjs";
2
3
  //#region src/plugins/seal/registry-publish.ts
3
4
  const sealResourceId = (name) => `seal:${name}`;
4
5
  /** Construct the read-side resource. */
@@ -1 +1 @@
1
- {"version":3,"file":"registry-publish.mjs","names":[],"sources":["../../../src/plugins/seal/registry-publish.ts"],"sourcesContent":["// Seal plugin — public resolved value.\n//\n// Resource ids:\n//\n// - `seal:<name>` — read-side key-server fields plus the local-only\n// manager handle when the stack owns the master key.\n//\n// The `<name>` suffix lets multiple seal instances coexist in a stack\n// without colliding on the resource registry (distilled doc §Pain Points\n// #7 — multi-instance currently untested but structurally supported).\n\nimport { resource } from '../../api/define-plugin.ts';\nimport type { SealKeyManager } from './key-manager.ts';\n\n// ---------------------------------------------------------------------------\n// Read-side: SealKeyServer\n// ---------------------------------------------------------------------------\n\n/** Structural mirror of `@mysten/seal`'s `KeyServerConfig`.\n *\n * Distilled-doc invariant #9 + #18: peer-dep structural\n * assignability. `@mysten/seal` is a peer dep — we duplicate the\n * shape locally to keep the runtime import off the bundle. A\n * compile-time `_SealKeyServerEntryCheck`\n * guards against drift. */\nexport interface SealKeyServerEntry {\n\treadonly objectId: string;\n\treadonly weight: number;\n\treadonly aggregatorUrl?: string;\n}\n\n/** Read-side resolved value. SDK-ready: pass `serverConfigs` to\n * `new SealClient({serverConfigs, ...})` directly. */\nexport interface SealKeyServer {\n\treadonly serverConfigs: ReadonlyArray<SealKeyServerEntry>;\n\treadonly keyServerUrl: string;\n\treadonly objectId: string;\n}\n\n/** Public Seal resolved value. The key-server fields stay top-level\n * so the direct member ref is immediately SDK-ready; local-keygen\n * additionally exposes `manager`, while known deployments set it to\n * `null` because this stack does not own the master key. */\nexport interface SealResolved extends SealKeyServer {\n\treadonly mode: 'local-keygen' | 'live' | 'fork-known';\n\treadonly manager: SealKeyManager | null;\n}\n\n/** Resource id constructor for the read-side handle. */\nexport type SealResourceId<Name extends string> = `seal:${Name}`;\nexport const sealResourceId = <Name extends string>(name: Name): SealResourceId<Name> =>\n\t`seal:${name}`;\n\n/** Construct the read-side resource. */\nexport const makeSealResource = <Name extends string>(name: Name) =>\n\tresource<SealResourceId<Name>, SealResolved>(sealResourceId(name));\n\n// ---------------------------------------------------------------------------\n// Projection helpers — narrow the plugin's resolved value\n// ---------------------------------------------------------------------------\n\n/** Aggregate resolved value the plugin's acquire body returns.\n * Distilled-doc §\"SealLocalKeygenInternalShape\" — `{keyServer,\n * keyManager, packageId}`. Modes that don't own a manager omit it. */\nexport interface SealLocalKeygenResolved {\n\treadonly keyServer: SealKeyServer;\n\treadonly keyManager: SealKeyManager;\n\treadonly packageId: string;\n}\n\nexport interface SealKnownResolved {\n\treadonly keyServer: SealKeyServer;\n}\n"],"mappings":";;AAkDA,MAAa,kBAAuC,SACnD,QAAQ;;AAGT,MAAa,oBAAyC,SACrD,SAA6C,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"registry-publish.mjs","names":[],"sources":["../../../src/plugins/seal/registry-publish.ts"],"sourcesContent":["// Seal plugin — public resolved value.\n//\n// Resource ids:\n//\n// - `seal:<name>` — read-side key-server fields plus the local-only\n// manager handle when the stack owns the master key.\n//\n// The `<name>` suffix lets multiple seal instances coexist in a stack\n// without colliding on the resource registry (distilled doc §Pain Points\n// #7 — multi-instance currently untested but structurally supported).\n\nimport { resource } from '../../api/define-plugin.ts';\nimport type { SealKeyManager } from './key-manager.ts';\n\n// ---------------------------------------------------------------------------\n// Read-side: SealKeyServer\n// ---------------------------------------------------------------------------\n\n/** Structural mirror of `@mysten/seal`'s `KeyServerConfig`.\n *\n * Distilled-doc invariant #9 + #18: peer-dep structural\n * assignability. `@mysten/seal` is a peer dep — we duplicate the\n * shape locally to keep the runtime import off the bundle. A\n * compile-time `_SealKeyServerEntryCheck`\n * guards against drift. */\nexport interface SealKeyServerEntry {\n\treadonly objectId: string;\n\treadonly weight: number;\n\treadonly aggregatorUrl?: string;\n}\n\n/** Read-side resolved value. SDK-ready: pass `serverConfigs` to\n * `new SealClient({serverConfigs, ...})` directly. */\nexport interface SealKeyServer {\n\treadonly serverConfigs: ReadonlyArray<SealKeyServerEntry>;\n\treadonly keyServerUrl: string;\n\treadonly objectId: string;\n}\n\n/** Public Seal resolved value. The key-server fields stay top-level\n * so the direct member ref is immediately SDK-ready; local-keygen\n * additionally exposes `manager`, while known deployments set it to\n * `null` because this stack does not own the master key. */\nexport interface SealResolved extends SealKeyServer {\n\treadonly mode: 'local-keygen' | 'live' | 'fork-known';\n\treadonly manager: SealKeyManager | null;\n}\n\n/** Resource id constructor for the read-side handle. */\nexport type SealResourceId<Name extends string> = `seal:${Name}`;\nexport const sealResourceId = <Name extends string>(name: Name): SealResourceId<Name> =>\n\t`seal:${name}`;\n\n/** Construct the read-side resource. */\nexport const makeSealResource = <Name extends string>(name: Name) =>\n\tresource<SealResourceId<Name>, SealResolved>(sealResourceId(name));\n\n// ---------------------------------------------------------------------------\n// Projection helpers — narrow the plugin's resolved value\n// ---------------------------------------------------------------------------\n\n/** Aggregate resolved value the plugin's acquire body returns.\n * Distilled-doc §\"SealLocalKeygenInternalShape\" — `{keyServer,\n * keyManager, packageId}`. Modes that don't own a manager omit it. */\nexport interface SealLocalKeygenResolved {\n\treadonly keyServer: SealKeyServer;\n\treadonly keyManager: SealKeyManager;\n\treadonly packageId: string;\n}\n\nexport interface SealKnownResolved {\n\treadonly keyServer: SealKeyServer;\n}\n"],"mappings":";;;AAkDA,MAAa,kBAAuC,SACnD,QAAQ;;AAGT,MAAa,oBAAyC,SACrD,SAA6C,eAAe,KAAK,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"routable.mjs","names":[],"sources":["../../../src/plugins/seal/routable.ts"],"sourcesContent":["// Seal plugin — Routable contribution.\n//\n// Distilled-doc invariant #5: the seal port (2024) is INTENTIONALLY\n// shared across stacks. Traefik dispatches by Host: header from the\n// well-known `seal-key-server` entrypoint. No host-port publish —\n// two stacks of the same app coexist on the same well-known port.\n//\n// The substrate's router (architecture §4) mints the hostname from\n// `(app, stack, dispatch-id)`. We provide:\n//\n// - `endpointName` — the well-known string `'seal-key-server'`.\n// - `dispatchId` — `{serviceKey: 'seal:<name>', role: 'key-server'}`.\n// The service key folds the seal instance\n// name so multi-instance stacks (distilled-doc\n// Open Question #7) don't collide.\n// - `upstream` — container kind; the substrate resolves the\n// container name from the lifecycle row.\n// - `cors: true` — the @mysten/seal SDK's fetch calls require\n// CORS allowance (distilled doc: localnet\n// SDK browser flow).\n//\n// Distilled-doc invariant #1: the URL the router publishes for this\n// routable decl MUST equal the URL we register on chain. The\n// plugin's acquire body reads the router's published URL ONCE\n// and threads the same value into the Move register call.\n\nimport type { DispatchId, EntrypointDecl, RoutableDecl } from '../../contracts/routable.ts';\n\n/** Well-known endpoint name for the seal key-server. Conventional\n * router entrypoint `'seal-key-server'` on port 2024. */\nexport const SEAL_KEY_SERVER_ENDPOINT_NAME = 'seal-key-server' as const;\nexport const SEAL_KEY_SERVER_ROUTE_ROLE = 'key-server' as const;\nexport const DEFAULT_KEY_SERVER_PORT = 2024 as const;\n\nexport const SEAL_ENTRYPOINTS: ReadonlyArray<EntrypointDecl> = [\n\t{ name: SEAL_KEY_SERVER_ENDPOINT_NAME, port: DEFAULT_KEY_SERVER_PORT, protocol: 'http' },\n];\n\nconst DEFAULT_STACK = 'main';\n\nconst normalizeRouteSegment = (raw: string): string => raw.toLowerCase().replace(/\\./g, '-');\n\n/** Build the DispatchId for a seal instance. The service key\n * encodes the instance name so multi-instance seal in the same\n * stack mints distinct dispatch files.\n *\n * Note: distilled-doc Open Question #7 — multi-instance seal is\n * structurally supported but untested. The two routable decls\n * would both claim the `'seal-key-server'` entrypoint and the\n * same `key-server.<stack>.<app>.localhost` hostname. Until v2\n * plans canonicalize multi-instance routing, treat one-seal-per-stack\n * as the safe default. */\nexport const buildSealDispatchId = (name: string): DispatchId => ({\n\tserviceKey: `seal:${name}`,\n\trole: SEAL_KEY_SERVER_ROUTE_ROLE,\n});\n\nexport const buildSealKeyServerPublicRoute = (inputs: {\n\treadonly app: string;\n\treadonly stack: string;\n\treadonly port: number;\n}): { readonly hostname: string; readonly url: string } => {\n\tconst role = normalizeRouteSegment(SEAL_KEY_SERVER_ROUTE_ROLE);\n\tconst app = normalizeRouteSegment(inputs.app);\n\tconst stack = normalizeRouteSegment(inputs.stack);\n\tconst hostname =\n\t\tstack === DEFAULT_STACK ? `${role}.${app}.localhost` : `${role}.${stack}.${app}.localhost`;\n\treturn {\n\t\thostname,\n\t\turl: `http://${hostname}:${inputs.port}`,\n\t};\n};\n\n/** Build the Routable contribution. The substrate's router\n * orchestrator consumes this; the actual hostname / URL minting\n * happens there (architecture: routes-by-key, no hardcoded\n * service hostnames in router code). */\nexport const makeSealRoutable = (inputs: {\n\treadonly name: string;\n\treadonly containerName: string;\n}): RoutableDecl => ({\n\tkind: 'routable',\n\tendpointName: SEAL_KEY_SERVER_ENDPOINT_NAME,\n\tdispatchId: buildSealDispatchId(inputs.name),\n\tupstream: {\n\t\ttype: 'container',\n\t\tcontainerName: inputs.containerName,\n\t\tcontainerPort: DEFAULT_KEY_SERVER_PORT,\n\t},\n\tcors: true,\n\twireProtocol: 'http',\n});\n\n/** Known-deployment modes do NOT route through the local router —\n * the URL points at a remote endpoint (Mysten's testnet key\n * server). We expose a sentinel routable that the orchestrator\n * skips (substrate-blind: the orchestrator filters by upstream\n * type, not by service name). For now, known modes return `null`\n * from this builder. */\nexport const KNOWN_MODE_ROUTABLE: null = null;\n"],"mappings":";;;AA8BA,MAAa,gCAAgC;AAC7C,MAAa,6BAA6B;AAC1C,MAAa,0BAA0B;AAEvC,MAAa,mBAAkD,CAC9D;CAAE,MAAM;CAA+B,MAAM;CAAyB,UAAU;CAAQ,CACxF;AAED,MAAM,gBAAgB;AAEtB,MAAM,yBAAyB,QAAwB,IAAI,aAAa,CAAC,QAAQ,OAAO,IAAI;;;;;;;;;;;AAY5F,MAAa,uBAAuB,UAA8B;CACjE,YAAY,QAAQ;CACpB,MAAM;CACN;AAED,MAAa,iCAAiC,WAIa;CAC1D,MAAM,OAAO,sBAAsB,2BAA2B;CAC9D,MAAM,MAAM,sBAAsB,OAAO,IAAI;CAC7C,MAAM,QAAQ,sBAAsB,OAAO,MAAM;CACjD,MAAM,WACL,UAAU,gBAAgB,GAAG,KAAK,GAAG,IAAI,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,IAAI;AAChF,QAAO;EACN;EACA,KAAK,UAAU,SAAS,GAAG,OAAO;EAClC;;;;;;AAOF,MAAa,oBAAoB,YAGZ;CACpB,MAAM;CACN,cAAc;CACd,YAAY,oBAAoB,OAAO,KAAK;CAC5C,UAAU;EACT,MAAM;EACN,eAAe,OAAO;EACtB,eAAe;EACf;CACD,MAAM;CACN,cAAc;CACd"}
1
+ {"version":3,"file":"routable.mjs","names":[],"sources":["../../../src/plugins/seal/routable.ts"],"sourcesContent":["// Seal plugin — Routable contribution.\n//\n// Distilled-doc invariant #5: the seal port (2024) is INTENTIONALLY\n// shared across stacks. Traefik dispatches by Host: header from the\n// well-known `seal-key-server` entrypoint. No host-port publish —\n// two stacks of the same app coexist on the same well-known port.\n//\n// The substrate's router (architecture §4) mints the hostname from\n// `(app, stack, dispatch-id)`. We provide:\n//\n// - `endpointName` — the well-known string `'seal-key-server'`.\n// - `dispatchId` — `{serviceKey: 'seal:<name>', role: 'key-server'}`.\n// The service key folds the seal instance\n// name so multi-instance stacks (distilled-doc\n// Open Question #7) don't collide.\n// - `upstream` — container kind; the substrate resolves the\n// container name from the lifecycle row.\n// - `cors: true` — the @mysten/seal SDK's fetch calls require\n// CORS allowance (distilled doc: localnet\n// SDK browser flow).\n//\n// Distilled-doc invariant #1: the URL the router publishes for this\n// routable decl MUST equal the URL we register on chain. The\n// plugin's acquire body reads the router's published URL ONCE\n// and threads the same value into the Move register call.\n\nimport type { DispatchId, EntrypointDecl, RoutableDecl } from '../../contracts/routable.ts';\n\n/** Well-known endpoint name for the seal key-server. Conventional\n * router entrypoint `'seal-key-server'` on port 2024. */\nexport const SEAL_KEY_SERVER_ENDPOINT_NAME = 'seal-key-server' as const;\nexport const SEAL_KEY_SERVER_ROUTE_ROLE = 'key-server' as const;\nexport const DEFAULT_KEY_SERVER_PORT = 2024 as const;\n\nexport const SEAL_ENTRYPOINTS: ReadonlyArray<EntrypointDecl> = [\n\t{ name: SEAL_KEY_SERVER_ENDPOINT_NAME, port: DEFAULT_KEY_SERVER_PORT, protocol: 'http' },\n];\n\nconst DEFAULT_STACK = 'main';\n\nconst normalizeRouteSegment = (raw: string): string => raw.toLowerCase().replace(/\\./g, '-');\n\n/** Build the DispatchId for a seal instance. The service key\n * encodes the instance name so multi-instance seal in the same\n * stack mints distinct dispatch files.\n *\n * Note: distilled-doc Open Question #7 — multi-instance seal is\n * structurally supported but untested. The two routable decls\n * would both claim the `'seal-key-server'` entrypoint and the\n * same `key-server.<stack>.<app>.localhost` hostname. Until v2\n * plans canonicalize multi-instance routing, treat one-seal-per-stack\n * as the safe default. */\nexport const buildSealDispatchId = (name: string): DispatchId => ({\n\tserviceKey: `seal:${name}`,\n\trole: SEAL_KEY_SERVER_ROUTE_ROLE,\n});\n\nexport const buildSealKeyServerPublicRoute = (inputs: {\n\treadonly app: string;\n\treadonly stack: string;\n\treadonly port: number;\n}): { readonly hostname: string; readonly url: string } => {\n\tconst role = normalizeRouteSegment(SEAL_KEY_SERVER_ROUTE_ROLE);\n\tconst app = normalizeRouteSegment(inputs.app);\n\tconst stack = normalizeRouteSegment(inputs.stack);\n\tconst hostname =\n\t\tstack === DEFAULT_STACK ? `${role}.${app}.localhost` : `${role}.${stack}.${app}.localhost`;\n\treturn {\n\t\thostname,\n\t\turl: `http://${hostname}:${inputs.port}`,\n\t};\n};\n\n/** Build the Routable contribution. The substrate's router\n * orchestrator consumes this; the actual hostname / URL minting\n * happens there (architecture: routes-by-key, no hardcoded\n * service hostnames in router code). */\nexport const makeSealRoutable = (inputs: {\n\treadonly name: string;\n\treadonly containerName: string;\n}): RoutableDecl => ({\n\tkind: 'routable',\n\tendpointName: SEAL_KEY_SERVER_ENDPOINT_NAME,\n\tdispatchId: buildSealDispatchId(inputs.name),\n\tupstream: {\n\t\ttype: 'container',\n\t\tcontainerName: inputs.containerName,\n\t\tcontainerPort: DEFAULT_KEY_SERVER_PORT,\n\t},\n\tcors: true,\n\twireProtocol: 'http',\n});\n"],"mappings":";;;AA8BA,MAAa,gCAAgC;AAC7C,MAAa,6BAA6B;AAC1C,MAAa,0BAA0B;AAEvC,MAAa,mBAAkD,CAC9D;CAAE,MAAM;CAA+B,MAAM;CAAyB,UAAU;CAAQ,CACxF;AAED,MAAM,gBAAgB;AAEtB,MAAM,yBAAyB,QAAwB,IAAI,aAAa,CAAC,QAAQ,OAAO,IAAI;;;;;;;;;;;AAY5F,MAAa,uBAAuB,UAA8B;CACjE,YAAY,QAAQ;CACpB,MAAM;CACN;AAED,MAAa,iCAAiC,WAIa;CAC1D,MAAM,OAAO,sBAAsB,2BAA2B;CAC9D,MAAM,MAAM,sBAAsB,OAAO,IAAI;CAC7C,MAAM,QAAQ,sBAAsB,OAAO,MAAM;CACjD,MAAM,WACL,UAAU,gBAAgB,GAAG,KAAK,GAAG,IAAI,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,IAAI;AAChF,QAAO;EACN;EACA,KAAK,UAAU,SAAS,GAAG,OAAO;EAClC;;;;;;AAOF,MAAa,oBAAoB,YAGZ;CACpB,MAAM;CACN,cAAc;CACd,YAAY,oBAAoB,OAAO,KAAK;CAC5C,UAAU;EACT,MAAM;EACN,eAAe,OAAO;EACtB,eAAe;EACf;CACD,MAAM;CACN,cAAc;CACd"}
@@ -1 +1 @@
1
- {"version":3,"file":"service.mjs","names":[],"sources":["../../../src/plugins/seal/service.ts"],"sourcesContent":["// Seal plugin — known-mode dispatch (live + fork-known).\n//\n// Local-keygen mode is dispatched directly from the plugin barrel\n// (`index.ts`) via `bootLocalKeygen` because it needs a\n// `LocalKeygenDeps` bundle (ContainerRuntime, paths, identity, …)\n// composed from substrate services. This file only routes the two\n// pure-value-producing modes that need no substrate plumbing.\n\nimport { Effect, type Scope } from 'effect';\n\nimport type {\n\tArtifactPublishError,\n\tArtifactPublisher,\n} from '../../primitives/artifact-publisher.ts';\nimport type { SealAnyError } from './errors.ts';\nimport { acquireForkKnown, type ForkKnownInputs } from './mode/fork-known.ts';\nimport { acquireLive, type LiveModeInputs } from './mode/live.ts';\nimport type { SealKnownResolved } from './registry-publish.ts';\n\n/** Known-mode discriminator — live + fork-known only. */\nexport type SealMode =\n\t| ({ readonly mode: 'live' } & LiveModeInputs)\n\t| ({ readonly mode: 'fork-known' } & ForkKnownInputs);\n\nexport type SealKnownBootResult = SealKnownResolved;\n\n/** Dispatch on the known-mode discriminator. The publisher argument\n * is unused by the known paths (no on-chain artifact produce); it's\n * accepted for shape uniformity with the local-keygen entry point. */\nexport const bootSealService = (\n\t_publisher: ArtifactPublisher,\n\topts: SealMode,\n): Effect.Effect<SealKnownBootResult, SealAnyError | ArtifactPublishError, Scope.Scope> => {\n\tswitch (opts.mode) {\n\t\tcase 'live':\n\t\t\treturn acquireLive(opts);\n\t\tcase 'fork-known':\n\t\t\treturn acquireForkKnown(opts);\n\t}\n};\n"],"mappings":";;;;;;;AA6BA,MAAa,mBACZ,YACA,SAC0F;AAC1F,SAAQ,KAAK,MAAb;EACC,KAAK,OACJ,QAAO,YAAY,KAAK;EACzB,KAAK,aACJ,QAAO,iBAAiB,KAAK"}
1
+ {"version":3,"file":"service.mjs","names":[],"sources":["../../../src/plugins/seal/service.ts"],"sourcesContent":["// Seal plugin — known-mode dispatch (live + fork-known).\n//\n// Local-keygen mode is dispatched directly from the plugin barrel\n// (`index.ts`) via `bootLocalKeygen` because it needs a\n// `LocalKeygenDeps` bundle (ContainerRuntime, paths, identity, …)\n// composed from substrate services. This file only routes the two\n// pure-value-producing modes that need no substrate plumbing.\n\nimport { Effect, type Scope } from 'effect';\n\nimport type {\n\tArtifactPublishError,\n\tArtifactPublisher,\n} from '../../primitives/artifact-publisher.ts';\nimport type { SealAnyError } from './errors.ts';\nimport { acquireForkKnown, type ForkKnownInputs } from './mode/fork-known.ts';\nimport { acquireLive } from './mode/live.ts';\nimport type { SealKnownResolved } from './registry-publish.ts';\n\n/** Known-mode discriminator — live + fork-known only. */\nexport type SealMode =\n\t| {\n\t\t\treadonly mode: 'live';\n\t\t\treadonly name: string;\n\t\t\treadonly resolved: { readonly objectId: string; readonly keyServerUrl: string };\n\t }\n\t| ({ readonly mode: 'fork-known' } & ForkKnownInputs);\n\nexport type SealKnownBootResult = SealKnownResolved;\n\n/** Dispatch on the known-mode discriminator. The publisher argument\n * is unused by the known paths (no on-chain artifact produce); it's\n * accepted for shape uniformity with the local-keygen entry point. */\nexport const bootSealService = (\n\t_publisher: ArtifactPublisher,\n\topts: SealMode,\n): Effect.Effect<SealKnownBootResult, SealAnyError | ArtifactPublishError, Scope.Scope> => {\n\tswitch (opts.mode) {\n\t\tcase 'live':\n\t\t\treturn acquireLive(opts);\n\t\tcase 'fork-known':\n\t\t\treturn acquireForkKnown(opts);\n\t}\n};\n"],"mappings":";;;;;;;AAiCA,MAAa,mBACZ,YACA,SAC0F;AAC1F,SAAQ,KAAK,MAAb;EACC,KAAK,OACJ,QAAO,YAAY,KAAK;EACzB,KAAK,aACJ,QAAO,iBAAiB,KAAK"}
@@ -0,0 +1,18 @@
1
+ //#region src/plugins/seal/spans.ts
2
+ const SealSpans = {
3
+ chain: "seal.chain",
4
+ containerName: "seal.containerName",
5
+ name: "seal.name",
6
+ ref: "seal.ref",
7
+ repo: "seal.repo",
8
+ routedUrl: "seal.routedUrl",
9
+ servicePath: "seal.servicePath",
10
+ signer: "seal.signer",
11
+ subdir: "seal.subdir",
12
+ url: "seal.url",
13
+ version: "seal.version"
14
+ };
15
+ //#endregion
16
+ export { SealSpans };
17
+
18
+ //# sourceMappingURL=spans.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spans.mjs","names":[],"sources":["../../../src/plugins/seal/spans.ts"],"sourcesContent":["// Seal plugin span-attribute vocabulary. Plugin-local — substrate's\n// `SpanAttr` carries only engine-dimensional + http/process generic\n// keys; plugin-domain keys live next to the plugin that owns them.\n//\n// Callsite pattern: `Effect.annotateCurrentSpan({ [SealSpans.name]:\n// value })`. Free-form string literals are a STYLE_GUIDE §16 violation.\n\nexport const SealSpans = {\n\tchain: 'seal.chain',\n\tcontainerName: 'seal.containerName',\n\tname: 'seal.name',\n\tref: 'seal.ref',\n\trepo: 'seal.repo',\n\troutedUrl: 'seal.routedUrl',\n\tservicePath: 'seal.servicePath',\n\tsigner: 'seal.signer',\n\tsubdir: 'seal.subdir',\n\turl: 'seal.url',\n\tversion: 'seal.version',\n} as const;\n"],"mappings":";AAOA,MAAa,YAAY;CACxB,OAAO;CACP,eAAe;CACf,MAAM;CACN,KAAK;CACL,MAAM;CACN,WAAW;CACX,aAAa;CACb,QAAQ;CACR,QAAQ;CACR,KAAK;CACL,SAAS;CACT"}
@@ -1,45 +1,39 @@
1
1
  import { SpanAttr } from "../../substrate/runtime/observability/spans.mjs";
2
- import { expectPositiveFiniteNumber } from "../../substrate/runtime/config-validation.mjs";
3
2
  import { suiConfigError } from "./errors.mjs";
3
+ import { SuiSpans } from "./spans.mjs";
4
4
  import { Effect, Schedule } from "effect";
5
5
  //#region src/plugins/sui/auto-tick.ts
6
6
  /** Default cadence when caller passes `autoTick: true`. */
7
7
  const DEFAULT_AUTO_TICK_INTERVAL_MS = 1e3;
8
- /** Resolve the public option to a numeric interval. Returns
9
- * `undefined` when auto-tick is OFF. Throws on a misconfigured
10
- * option (0 / negative / non-finite) the substrate's
11
- * acquire-time validation catches this before any I/O. */
8
+ /** Resolve the public option to a numeric interval. Succeeds with
9
+ * `undefined` when auto-tick is OFF. A misconfigured option (0 /
10
+ * negative / non-finite) fails the effect with a typed
11
+ * `SuiConfigError` so the boot path can `catchTag` it — a synchronous
12
+ * `throw` inside the acquire `Effect.gen` would surface as a defect
13
+ * (STYLE_GUIDE §2: plugin errors must be catchTag-able). */
12
14
  const resolveAutoTickIntervalMs = (option) => {
13
- if (option === void 0 || option === false) return void 0;
14
- if (option === true) return DEFAULT_AUTO_TICK_INTERVAL_MS;
15
- return expectPositiveFiniteNumber(option.intervalMs, {
15
+ if (option === void 0 || option === false) return Effect.succeed(void 0);
16
+ if (option === true) return Effect.succeed(DEFAULT_AUTO_TICK_INTERVAL_MS);
17
+ const { intervalMs } = option;
18
+ if (typeof intervalMs === "number" && Number.isFinite(intervalMs) && intervalMs > 0) return Effect.succeed(intervalMs);
19
+ return Effect.fail(suiConfigError({
16
20
  field: "autoTick.intervalMs",
17
- message: `sui: autoTick.intervalMs must be a positive finite number (got ${String(option.intervalMs)})`,
18
- mkError: suiConfigError
19
- });
21
+ message: `sui: autoTick.intervalMs must be a positive finite number (got ${String(intervalMs)})`
22
+ }));
20
23
  };
21
24
  /**
22
25
  * Fork a scope-bound fiber that calls `advanceClock(intervalMs)` on
23
26
  * a `Schedule.spaced(intervalMs)` cadence. The fiber dies on the
24
27
  * surrounding scope's close (wipe / restart / Ctrl-C).
25
- *
26
- * Returns the fiber handle. Today's code discards the handle — the
27
- * distilled doc flags a designed-for-but-not-landed re-config path
28
- * (`engine/sui-fork/control.ts` opportunity). We keep the handle
29
- * returned so a future cadence-change surface has a join point.
30
28
  */
31
29
  const runAutoTickClock = (advancer, intervalMs) => Effect.gen(function* () {
32
- return yield* advancer.advanceClock(intervalMs).pipe(Effect.catch((err) => Effect.logWarning("sui auto-tick advance failed; next tick will retry").pipe(Effect.annotateLogs({
33
- [SpanAttr.suiAutoTickIntervalMs]: intervalMs,
30
+ yield* advancer.advanceClock(intervalMs).pipe(Effect.catch((err) => Effect.logWarning("sui auto-tick advance failed; next tick will retry").pipe(Effect.annotateLogs({
31
+ [SuiSpans.autoTickIntervalMs]: intervalMs,
34
32
  [SpanAttr.phase]: err.phase,
35
33
  [SpanAttr.errorMessage]: err.message
36
34
  })))).pipe(Effect.repeat(Schedule.spaced(`${intervalMs} millis`)), Effect.forkScoped);
37
35
  });
38
- /** Build a no-op advancer for local mode. Localnet's validator
39
- * drives consensus on its own; the auto-tick fiber surface exists
40
- * for symmetry but doesn't have anything to advance. */
41
- const noopClockAdvancer = { advanceClock: () => Effect.void };
42
36
  //#endregion
43
- export { noopClockAdvancer, resolveAutoTickIntervalMs, runAutoTickClock };
37
+ export { resolveAutoTickIntervalMs, runAutoTickClock };
44
38
 
45
39
  //# sourceMappingURL=auto-tick.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"auto-tick.mjs","names":[],"sources":["../../../src/plugins/sui/auto-tick.ts"],"sourcesContent":["// Auto-tick clock — local-mode-only.\n//\n// Architecture invariant: \"Auto-tick is local-mode-only\" — the\n// public option is exposed only on fork (where it advances the\n// fork binary's clock + checkpoint) AND local (where it nudges\n// localnet's consensus to commit pending txs in tests that don't\n// produce traffic).\n//\n// The fiber is `forkScoped` against the plugin's acquire scope:\n// teardown happens automatically on wipe/restart/Ctrl-C. Failure\n// policy is **log-warn-and-continue** — a single advance-clock\n// RPC failure must not break the supervisor.\n\nimport { Effect, Schedule, type Fiber, type Scope } from 'effect';\n\nimport { expectPositiveFiniteNumber } from '../../substrate/runtime/config-validation.ts';\nimport { SpanAttr } from '../../substrate/runtime/observability/spans.ts';\nimport { suiConfigError } from './errors.ts';\nimport type { SuiPluginError } from './errors.ts';\n\n/** Public knob shape mirroring the user-facing API. */\nexport type AutoTickOption = boolean | { readonly intervalMs: number };\n\n/** Default cadence when caller passes `autoTick: true`. */\nexport const DEFAULT_AUTO_TICK_INTERVAL_MS = 1000;\n\n/** Resolve the public option to a numeric interval. Returns\n * `undefined` when auto-tick is OFF. Throws on a misconfigured\n * option (0 / negative / non-finite) the substrate's\n * acquire-time validation catches this before any I/O. */\nexport const resolveAutoTickIntervalMs = (option?: AutoTickOption): number | undefined => {\n\tif (option === undefined || option === false) return undefined;\n\tif (option === true) return DEFAULT_AUTO_TICK_INTERVAL_MS;\n\treturn expectPositiveFiniteNumber(option.intervalMs, {\n\t\tfield: 'autoTick.intervalMs',\n\t\tmessage: `sui: autoTick.intervalMs must be a positive finite number (got ${String(\n\t\t\toption.intervalMs,\n\t\t)})`,\n\t\tmkError: suiConfigError,\n\t});\n};\n\n/** Plugin-internal shim — the minimal admin surface the auto-tick\n * fiber needs. Local-mode wires this to a no-op (localnet's\n * validator advances its own clock); fork-mode wires it to the\n * `ForkingService.advanceClock` gRPC method. Stub: the concrete\n * gRPC binding lands when the Mysten Sui SDK is introduced. */\nexport interface ClockAdvancer {\n\treadonly advanceClock: (intervalMs: number) => Effect.Effect<void, SuiPluginError>;\n}\n\n/**\n * Fork a scope-bound fiber that calls `advanceClock(intervalMs)` on\n * a `Schedule.spaced(intervalMs)` cadence. The fiber dies on the\n * surrounding scope's close (wipe / restart / Ctrl-C).\n *\n * Returns the fiber handle. Today's code discards the handle — the\n * distilled doc flags a designed-for-but-not-landed re-config path\n * (`engine/sui-fork/control.ts` opportunity). We keep the handle\n * returned so a future cadence-change surface has a join point.\n */\nexport const runAutoTickClock = (\n\tadvancer: ClockAdvancer,\n\tintervalMs: number,\n): Effect.Effect<Fiber.Fiber<void>, never, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst tick = advancer.advanceClock(intervalMs).pipe(\n\t\t\tEffect.catch((err) =>\n\t\t\t\tEffect.logWarning('sui auto-tick advance failed; next tick will retry').pipe(\n\t\t\t\t\tEffect.annotateLogs({\n\t\t\t\t\t\t[SpanAttr.suiAutoTickIntervalMs]: intervalMs,\n\t\t\t\t\t\t[SpanAttr.phase]: err.phase,\n\t\t\t\t\t\t[SpanAttr.errorMessage]: err.message,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\t\tconst fiber = yield* tick.pipe(\n\t\t\tEffect.repeat(Schedule.spaced(`${intervalMs} millis`)),\n\t\t\tEffect.forkScoped,\n\t\t);\n\t\treturn fiber as Fiber.Fiber<void>;\n\t});\n\n/** Build a no-op advancer for local mode. Localnet's validator\n * drives consensus on its own; the auto-tick fiber surface exists\n * for symmetry but doesn't have anything to advance. */\nexport const noopClockAdvancer: ClockAdvancer = {\n\tadvanceClock: () => Effect.void as Effect.Effect<void, SuiPluginError>,\n};\n"],"mappings":";;;;;;AAwBA,MAAa,gCAAgC;;;;;AAM7C,MAAa,6BAA6B,WAAgD;AACzF,KAAI,WAAW,KAAA,KAAa,WAAW,MAAO,QAAO,KAAA;AACrD,KAAI,WAAW,KAAM,QAAO;AAC5B,QAAO,2BAA2B,OAAO,YAAY;EACpD,OAAO;EACP,SAAS,kEAAkE,OAC1E,OAAO,WACP,CAAC;EACF,SAAS;EACT,CAAC;;;;;;;;;;;;AAsBH,MAAa,oBACZ,UACA,eAEA,OAAO,IAAI,aAAa;AAgBvB,QAAO,OAfM,SAAS,aAAa,WAAW,CAAC,KAC9C,OAAO,OAAO,QACb,OAAO,WAAW,qDAAqD,CAAC,KACvE,OAAO,aAAa;GAClB,SAAS,wBAAwB;GACjC,SAAS,QAAQ,IAAI;GACrB,SAAS,eAAe,IAAI;EAC7B,CAAC,CACF,CACD,CAEuB,CAAC,KACzB,OAAO,OAAO,SAAS,OAAO,GAAG,WAAW,SAAS,CAAC,EACtD,OAAO,WACP;EAEA;;;;AAKH,MAAa,oBAAmC,EAC/C,oBAAoB,OAAO,MAC3B"}
1
+ {"version":3,"file":"auto-tick.mjs","names":[],"sources":["../../../src/plugins/sui/auto-tick.ts"],"sourcesContent":["// Auto-tick clock — fork-mode-only.\n//\n// Architecture invariant: \"Auto-tick is fork-mode-only\" — the\n// `autoTick` option lives on `SuiForkOptions` alone, and only the\n// fork boot wires `runAutoTickClock` (against the fork binary's\n// `ForkingService.advanceClock`). Localnet's validator advances its\n// own clock and commits pending txs without prompting, so no\n// equivalent knob exists there.\n//\n// The fiber is `forkScoped` against the plugin's acquire scope:\n// teardown happens automatically on wipe/restart/Ctrl-C. Failure\n// policy is **log-warn-and-continue** — a single advance-clock\n// RPC failure must not break the supervisor.\n\nimport { Effect, Schedule, type Scope } from 'effect';\n\nimport { SpanAttr } from '../../substrate/runtime/observability/spans.ts';\nimport { suiConfigError } from './errors.ts';\nimport type { SuiConfigError, SuiPluginError } from './errors.ts';\nimport { SuiSpans } from './spans.ts';\n\n/** Public knob shape mirroring the user-facing API. */\nexport type AutoTickOption = boolean | { readonly intervalMs: number };\n\n/** Default cadence when caller passes `autoTick: true`. */\nexport const DEFAULT_AUTO_TICK_INTERVAL_MS = 1000;\n\n/** Resolve the public option to a numeric interval. Succeeds with\n * `undefined` when auto-tick is OFF. A misconfigured option (0 /\n * negative / non-finite) fails the effect with a typed\n * `SuiConfigError` so the boot path can `catchTag` it — a synchronous\n * `throw` inside the acquire `Effect.gen` would surface as a defect\n * (STYLE_GUIDE §2: plugin errors must be catchTag-able). */\nexport const resolveAutoTickIntervalMs = (\n\toption?: AutoTickOption,\n): Effect.Effect<number | undefined, SuiConfigError> => {\n\tif (option === undefined || option === false) return Effect.succeed(undefined);\n\tif (option === true) return Effect.succeed(DEFAULT_AUTO_TICK_INTERVAL_MS);\n\tconst { intervalMs } = option;\n\tif (typeof intervalMs === 'number' && Number.isFinite(intervalMs) && intervalMs > 0) {\n\t\treturn Effect.succeed(intervalMs);\n\t}\n\treturn Effect.fail(\n\t\tsuiConfigError({\n\t\t\tfield: 'autoTick.intervalMs',\n\t\t\tmessage: `sui: autoTick.intervalMs must be a positive finite number (got ${String(intervalMs)})`,\n\t\t}),\n\t);\n};\n\n/** Plugin-internal shim — the minimal admin surface the auto-tick\n * fiber needs. Fork-mode wires this to the fork admin surface, whose\n * `advanceClock` calls the binary's `ForkingService.advanceClock`\n * gRPC method (see `makeForkAdminSurface` in `mode/fork.ts`). The\n * `ForkAdminSurface` is structurally a `ClockAdvancer`, so the boot\n * hands it through directly. */\nexport interface ClockAdvancer {\n\treadonly advanceClock: (intervalMs: number) => Effect.Effect<void, SuiPluginError>;\n}\n\n/**\n * Fork a scope-bound fiber that calls `advanceClock(intervalMs)` on\n * a `Schedule.spaced(intervalMs)` cadence. The fiber dies on the\n * surrounding scope's close (wipe / restart / Ctrl-C).\n */\nexport const runAutoTickClock = (\n\tadvancer: ClockAdvancer,\n\tintervalMs: number,\n): Effect.Effect<void, never, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst tick = advancer.advanceClock(intervalMs).pipe(\n\t\t\tEffect.catch((err) =>\n\t\t\t\tEffect.logWarning('sui auto-tick advance failed; next tick will retry').pipe(\n\t\t\t\t\tEffect.annotateLogs({\n\t\t\t\t\t\t[SuiSpans.autoTickIntervalMs]: intervalMs,\n\t\t\t\t\t\t[SpanAttr.phase]: err.phase,\n\t\t\t\t\t\t[SpanAttr.errorMessage]: err.message,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\t\tyield* tick.pipe(Effect.repeat(Schedule.spaced(`${intervalMs} millis`)), Effect.forkScoped);\n\t});\n"],"mappings":";;;;;;AAyBA,MAAa,gCAAgC;;;;;;;AAQ7C,MAAa,6BACZ,WACuD;AACvD,KAAI,WAAW,KAAA,KAAa,WAAW,MAAO,QAAO,OAAO,QAAQ,KAAA,EAAU;AAC9E,KAAI,WAAW,KAAM,QAAO,OAAO,QAAQ,8BAA8B;CACzE,MAAM,EAAE,eAAe;AACvB,KAAI,OAAO,eAAe,YAAY,OAAO,SAAS,WAAW,IAAI,aAAa,EACjF,QAAO,OAAO,QAAQ,WAAW;AAElC,QAAO,OAAO,KACb,eAAe;EACd,OAAO;EACP,SAAS,kEAAkE,OAAO,WAAW,CAAC;EAC9F,CAAC,CACF;;;;;;;AAkBF,MAAa,oBACZ,UACA,eAEA,OAAO,IAAI,aAAa;AAYvB,QAXa,SAAS,aAAa,WAAW,CAAC,KAC9C,OAAO,OAAO,QACb,OAAO,WAAW,qDAAqD,CAAC,KACvE,OAAO,aAAa;GAClB,SAAS,qBAAqB;GAC9B,SAAS,QAAQ,IAAI;GACrB,SAAS,eAAe,IAAI;EAC7B,CAAC,CACF,CACD,CAES,CAAC,KAAK,OAAO,OAAO,SAAS,OAAO,GAAG,WAAW,SAAS,CAAC,EAAE,OAAO,WAAW;EAC1F"}
@@ -0,0 +1,18 @@
1
+ import "../../substrate/runtime/cross-process/stack-lock.mjs";
2
+ import "../../substrate/runtime/sui-move-build/index.mjs";
3
+ import "../../substrate/runtime/managed-container.mjs";
4
+ import "./errors.mjs";
5
+ import "effect";
6
+ import "node:crypto";
7
+ import "node:path";
8
+ import "node:os";
9
+ [
10
+ "child=;",
11
+ "trap '[ -z \"$child\" ] || kill \"$child\" 2>/dev/null || true; exit 0' INT TERM;",
12
+ "sleep infinity & child=$!;",
13
+ "wait \"$child\""
14
+ ].join(" ");
15
+ //#endregion
16
+ export {};
17
+
18
+ //# sourceMappingURL=chain-build-container.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain-build-container.mjs","names":[],"sources":["../../../src/plugins/sui/chain-build-container.ts"],"sourcesContent":["// Per-app long-lived Move build container.\n//\n// Architecture Decision §5: the build container is PER-APP, NOT\n// per-stack. Two parallel stacks of the same app share the same\n// sleeper container — their concurrent Move builds serialise on\n// docker exec queueing. This is intentional: dep-cache reuse\n// across stacks outweighs the serialisation cost.\n//\n// Adopt-or-create state machine is delegated to the substrate's\n// `ContainerRuntime.ensureContainer` with `recreate: 'never'` —\n// daemon outages must fail loudly, not silently churn (distilled\n// doc S6: \"MUST reject the helper's auto-recreate-on-resume-failed\n// path\").\n//\n// Cross-process safety: the host-wide advisory lock is owned by\n// THIS module. The lock is held inside the build call (NOT at the\n// docker-exec layer), because three distinct execution paths (host\n// CLI, fresh `docker run --rm`, container exec) all need\n// protection. Lock path: `~/.devstack/locks/sui-move-build-<repoHash>.lock`.\n\nimport { createHash } from 'node:crypto';\nimport { homedir } from 'node:os';\nimport { dirname, join, resolve } from 'node:path';\nimport { Effect, type Scope } from 'effect';\n\nimport type {\n\tContainerHandle,\n\tContainerRuntime,\n\tContainerRuntimeError,\n\tEnsureContainerSpec,\n\tImageRef,\n} from '../../contracts/container-runtime.ts';\nimport { acquireStackLock } from '../../substrate/runtime/cross-process/stack-lock.ts';\nimport {\n\tensureManagedContainer,\n\tPER_APP_SHARED_STACK,\n} from '../../substrate/runtime/managed-container.ts';\nimport { containerInnerScript } from '../../substrate/runtime/sui-move-build/index.ts';\nimport { suiCliError, suiPluginError, type SuiCliError, type SuiPluginError } from './errors.ts';\n\n/** Default move-build lock timeout — five minutes, matching the\n * distilled-doc invariant. The lock is held during the build\n * body only; long-running stages never share it. */\nexport const MOVE_BUILD_LOCK_TIMEOUT_MS = 5 * 60_000;\n\nconst BUILD_CONTAINER_STOP_GRACE_SECONDS = 2;\nconst BUILD_CONTAINER_KEEPALIVE_COMMAND = [\n\t'child=;',\n\t'trap \\'[ -z \"$child\" ] || kill \"$child\" 2>/dev/null || true; exit 0\\' INT TERM;',\n\t'sleep infinity & child=$!;',\n\t'wait \"$child\"',\n].join(' ');\n\n/** Per-app container name. The substrate's `pluginKey('sui-build')`\n * + the app discriminator combine to a stable name; the container\n * intentionally omits the stack/network suffix so two stacks of\n * the same app share. */\nexport const containerNameForApp = (app: string): string => `devstack-${app}-build`;\n\nconst expandHome = (path: string): string =>\n\tpath === '~' ? homedir() : path.startsWith('~/') ? join(homedir(), path.slice(2)) : path;\n\nconst repoHashForLock = (appDir: string): string =>\n\tcreateHash('sha256').update(resolve(appDir)).digest('hex').slice(0, 16);\n\nexport const moveBuildLockPathFor = (appDir: string, moveHome: string): string => {\n\tconst moveHomeRoot = dirname(resolve(expandHome(moveHome)));\n\treturn join(moveHomeRoot, '.devstack', 'locks', `sui-move-build-${repoHashForLock(appDir)}.lock`);\n};\n\n/** Build-container handle returned to plugin internals (the\n * cli-driver dispatches into this). */\nexport interface ChainBuildContainer {\n\treadonly handle: ContainerHandle;\n\t/** Translate a host-absolute path into a container-bind path.\n\t * Returns null when the host path escapes the bind-mounted app\n\t * dir — callers MUST fall back to `docker run --rm` in that\n\t * case (distilled-doc: \"Build container path translation MUST\n\t * refuse paths outside the bind-mounted app dir\"). */\n\treadonly toContainerPath: (hostPath: string) => string | null;\n\t/** Run a sui-cli capture inside the container. Acquires the\n\t * host-wide move-build lock before invoking docker-exec. */\n\treadonly runBuild: (\n\t\thostPackagePath: string,\n\t) => Effect.Effect<\n\t\t{ readonly exitCode: number; readonly stdout: string; readonly stderr: string },\n\t\tSuiCliError,\n\t\tScope.Scope\n\t>;\n\t/** Run a codegen-style \"summary\" build inside the container.\n\t * Same wire shape as runBuild; the codegen plugin consumes\n\t * this via the cross-service seam. */\n\treadonly runSummary: (\n\t\thostPackagePath: string,\n\t) => Effect.Effect<\n\t\t{ readonly exitCode: number; readonly stdout: string; readonly stderr: string },\n\t\tSuiCliError,\n\t\tScope.Scope\n\t>;\n}\n\n/** Spec passed to `ContainerRuntime.ensureContainer` for the\n * per-app sleeper. Image is content-hashed; labels carry the\n * app discriminator so `inspectByLabels` finds it across stacks. */\nexport interface ChainBuildContainerSpec {\n\treadonly app: string;\n\treadonly stack: string;\n\treadonly appDir: string;\n\treadonly moveHome: string;\n\treadonly image: ImageRef;\n}\n\n/**\n * Acquire (or adopt) the per-app build container. Returns a\n * `ChainBuildContainer` handle scoped to the caller's Scope.\n *\n * The build call holds the host-wide move-build lock for the docker\n * exec body. The lock uses the substrate's PID + start-time stale\n * holder reclaim path, so a crashed peer cannot wedge future builds.\n */\nexport const acquireChainBuildContainer = (\n\truntime: ContainerRuntime,\n\tspec: ChainBuildContainerSpec,\n): Effect.Effect<ChainBuildContainer, ContainerRuntimeError | SuiPluginError, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\t// The sleeper shell traps Docker's stop signal so scope-close\n\t\t// does not wait for Docker's default SIGKILL escalation path.\n\t\t// This also overrides the sui image's default `start\n\t\t// --with-faucet=...` entrypoint so the validator binary doesn't\n\t\t// run genesis inside a build container.\n\t\t// The appDir is bind-mounted at `/workspace`, with the user's\n\t\t// `~/.move` bind-mounted at `/root/.move` so the content-addressed\n\t\t// dep cache (`~/.move/git/<repo>@<sha>/…`) persists across builds.\n\t\tconst ensureSpec: EnsureContainerSpec = {\n\t\t\tname: containerNameForApp(spec.app),\n\t\t\timage: spec.image,\n\t\t\tlabels: {\n\t\t\t\tapp: spec.app,\n\t\t\t\t// Intentionally pin stack to a sentinel — see comment\n\t\t\t\t// above; this is per-app, not per-stack.\n\t\t\t\tstack: PER_APP_SHARED_STACK,\n\t\t\t\tplugin: 'sui',\n\t\t\t\trole: 'build',\n\t\t\t},\n\t\t\trecreate: 'never',\n\t\t\tentrypoint: 'sh',\n\t\t\tcommand: ['-c', BUILD_CONTAINER_KEEPALIVE_COMMAND],\n\t\t\tstopGraceSeconds: BUILD_CONTAINER_STOP_GRACE_SECONDS,\n\t\t\tmounts: [\n\t\t\t\t{ source: spec.appDir, target: '/workspace' },\n\t\t\t\t{ source: spec.moveHome, target: '/root/.move' },\n\t\t\t],\n\t\t};\n\t\tconst { labels, ...containerSpec } = ensureSpec;\n\t\tconst handle = yield* ensureManagedContainer({\n\t\t\truntime,\n\t\t\tlabels,\n\t\t\tspec: containerSpec,\n\t\t\tmapError: (cause) => cause,\n\t\t});\n\n\t\tconst toContainerPath = (hostPath: string): string | null => {\n\t\t\t// The runtime adapter bind-mounts `spec.appDir` at\n\t\t\t// `/workspace`. A host path outside that bind is not\n\t\t\t// accessible to the container.\n\t\t\tif (!hostPath.startsWith(spec.appDir)) return null;\n\t\t\tconst rel = hostPath.slice(spec.appDir.length).replace(/^\\/+/, '');\n\t\t\treturn rel === '' ? '/workspace' : `/workspace/${rel}`;\n\t\t};\n\t\tconst moveBuildLockPath = moveBuildLockPathFor(spec.appDir, spec.moveHome);\n\n\t\tconst runInContainer = (\n\t\t\top: 'build' | 'summary',\n\t\t\thostPackagePath: string,\n\t\t): Effect.Effect<\n\t\t\t{ readonly exitCode: number; readonly stdout: string; readonly stderr: string },\n\t\t\tSuiCliError,\n\t\t\tScope.Scope\n\t\t> =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst containerPath = toContainerPath(hostPackagePath);\n\t\t\t\tif (containerPath === null) {\n\t\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\t\tsuiCliError(op, {\n\t\t\t\t\t\t\tcause: new Error(\n\t\t\t\t\t\t\t\t`chain-build-container: host path ${hostPackagePath} escapes appDir bind (${spec.appDir}); ` +\n\t\t\t\t\t\t\t\t\t`caller MUST fall back to docker run --rm`,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// The package's container path = `/workspace/<basename>`.\n\t\t\t\t// containerInnerScript copies that subdir into an in-container\n\t\t\t\t// scratch dir and scrubs + builds THERE, so the bind-mounted\n\t\t\t\t// appDir source (`spec.appDir` at `/workspace`) is never\n\t\t\t\t// rewritten by the build.\n\t\t\t\tconst pkgName = containerPath.replace(/^\\/workspace\\//, '').replace(/^\\/+|\\/+$/g, '');\n\t\t\t\tconst inner = containerInnerScript(pkgName);\n\t\t\t\tconst result = yield* Effect.scoped(\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tyield* acquireStackLock(moveBuildLockPath, MOVE_BUILD_LOCK_TIMEOUT_MS).pipe(\n\t\t\t\t\t\t\tEffect.mapError(\n\t\t\t\t\t\t\t\t(cause): SuiCliError =>\n\t\t\t\t\t\t\t\t\tsuiCliError(op, {\n\t\t\t\t\t\t\t\t\t\tcause: new Error(`move-build lock acquire failed: ${cause._tag}`, { cause }),\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn yield* runtime.exec(handle, ['sh', '-c', inner]).pipe(\n\t\t\t\t\t\t\tEffect.mapError(\n\t\t\t\t\t\t\t\t(cause): SuiCliError =>\n\t\t\t\t\t\t\t\t\tsuiCliError(op, {\n\t\t\t\t\t\t\t\t\t\tcause: new Error(`runtime.exec failed: ${cause.reason}: ${cause.detail}`),\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn result;\n\t\t\t});\n\n\t\tconst runBuild = (hostPackagePath: string) => runInContainer('build', hostPackagePath);\n\t\tconst runSummary = (hostPackagePath: string) => runInContainer('summary', hostPackagePath);\n\n\t\treturn { handle, toContainerPath, runBuild, runSummary };\n\t}).pipe(\n\t\tEffect.mapError((cause) =>\n\t\t\tisContainerRuntimeError(cause)\n\t\t\t\t? cause\n\t\t\t\t: suiPluginError('image-build', 'chain-build-container.acquire failed', cause),\n\t\t),\n\t);\n\nconst isContainerRuntimeError = (e: unknown): e is ContainerRuntimeError =>\n\ttypeof e === 'object' && e !== null && (e as { _tag?: string })._tag === 'ContainerRuntimeError';\n"],"mappings":";;;;;;;;AA8C0C;CACzC;CACA;CACA;CACA;CACA,CAAC,KAAK,IAAI"}
@@ -1,4 +1,4 @@
1
- import { Schema } from "effect";
1
+ import { ClientWithCoreApi } from "@mysten/sui/client";
2
2
 
3
3
  //#region src/plugins/sui/chain-probe.d.ts
4
4
  /**
@@ -75,10 +75,10 @@ interface SuiSdkShim {
75
75
  readonly timeout?: number;
76
76
  }) => Promise<unknown>;
77
77
  };
78
- /** Opaque client reference for `Transaction.build({ client })`.
79
- * The Sui barrel wires the resolved `SuiGrpcClient` through; the
80
- * shim layer doesn't type-narrow it (mirrors `MintSdkShim.client`). */
81
- readonly client: unknown;
78
+ /** Client reference for `Transaction.build({ client })` and every
79
+ * `client.core.*` call. The Sui barrel wires the resolved
80
+ * `SuiGrpcClient` through; consumers cast no further. */
81
+ readonly client: ClientWithCoreApi;
82
82
  }
83
83
  //#endregion
84
84
  export { SuiProbeKey, SuiSdkShim };