@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,19 +1,31 @@
1
+ import { atomicWriteFileSync } from "../../substrate/runtime/atomic-write.mjs";
2
+ import { labelledExcerpt } from "../../substrate/runtime/observability/output-truncate.mjs";
3
+ import "../../substrate/runtime/observability/index.mjs";
4
+ import { probeManyLenient } from "../../substrate/runtime/probes.mjs";
5
+ import { DEPLOY_BIND_SOURCE_RETRY_PROFILE, makeSpacedRetrySchedule } from "../../substrate/runtime/retry-policy.mjs";
6
+ import { HOST_GATEWAY_EXTRA_HOSTS } from "../../substrate/runtime/host-gateway.mjs";
1
7
  import { walrusDeployMountPaths } from "./deploy-paths.mjs";
2
8
  import { walrusPluginError } from "./errors.mjs";
9
+ import { WalrusSpans } from "./spans.mjs";
10
+ import { formatUnknownError } from "../../substrate/runtime/format-unknown-error.mjs";
11
+ import { artifactPublishError } from "../../primitives/artifact-publisher.mjs";
12
+ import { hostBindMountOwner } from "../../substrate/runtime/host-bind-mount-owner.mjs";
3
13
  import { Duration, Effect, Schema } from "effect";
4
14
  import { join } from "node:path";
5
- import { access, mkdir, writeFile } from "node:fs/promises";
6
- //#region src/plugins/walrus/deploy.ts
7
- /** Verify-schema: the publisher decodes the cached id's on-chain
8
- * object through this. Minimal — the substrate's `ChainProbe`
9
- * decodes against this; any decode failure surfaces structured.
10
- * Distilled-doc invariant 8: the probe MUST consume a stable
11
- * identifier (the object id), NOT a derived hash. */
12
- const WalrusDeployVerifyShape = Schema.Struct({
15
+ import { access, mkdir } from "node:fs/promises";
16
+ Schema.Struct({
13
17
  systemObjectId: Schema.String,
14
18
  stakingObjectId: Schema.String
15
19
  });
16
20
  const SuiObjectExistsShape = Schema.Struct({ objectId: Schema.String });
21
+ /** A freshly RESTORED validator can take a few seconds to start serving the
22
+ * committed deploy objects (sui/system/staking); retry the deploy-verify
23
+ * probes across this window so a readiness race doesn't read them as
24
+ * not-found and trigger a spurious redeploy — which would churn the walrus
25
+ * deploy ids and orphan every pre-snapshot blob. A warm restart finds them on
26
+ * the first probe; a genuinely-wiped chain still redeploys once retries lapse. */
27
+ const WALRUS_DEPLOY_VERIFY_READINESS_RETRIES = 5;
28
+ const WALRUS_DEPLOY_VERIFY_READINESS_DELAY = "3 seconds";
17
29
  const requiredDeployOutputFiles = (inputs) => [join(inputs.outputDirHostPath, "deploy"), ...Array.from({ length: inputs.committeeSize }, (_, nodeIndex) => [
18
30
  join(inputs.outputDirHostPath, `dryrun-node-${nodeIndex}.yaml`),
19
31
  join(inputs.outputDirHostPath, `dryrun-node-${nodeIndex}-sui.yaml`),
@@ -31,40 +43,18 @@ const deployOutputFilesComplete = (inputs) => Effect.tryPromise({
31
43
  * observed wall-clock is 30-60s. 5-minute ceiling absorbs cold-cache
32
44
  * + slow CI runners. */
33
45
  const DEPLOY_TIMEOUT_MS = 5 * 6e4;
34
- const DEPLOY_BIND_SOURCE_RETRY_ATTEMPTS = 10;
35
- const DEPLOY_BIND_SOURCE_RETRY_DELAY_MS = 500;
36
46
  const ensureDeployOutputDir = (inputs) => Effect.tryPromise({
37
47
  try: async () => {
38
48
  await mkdir(inputs.outputDirHostPath, { recursive: true });
39
- await writeFile(join(inputs.outputDirHostPath, ".devstack-bind-source"), "devstack walrus bind source\n", "utf8");
49
+ atomicWriteFileSync(join(inputs.outputDirHostPath, ".devstack-bind-source"), "devstack walrus bind source\n", { mode: 420 });
40
50
  },
41
51
  catch: (cause) => walrusPluginError("deploy", `walrus deploy failed to prepare output directory ${inputs.outputDirHostPath}`, { cause })
42
52
  });
43
- const hostBindMountOwner = () => {
44
- const process = globalThis.process;
45
- if (typeof process?.getuid !== "function" || typeof process.getgid !== "function") return;
46
- return `${process.getuid()}:${process.getgid()}`;
47
- };
48
- const excerpt = (label, value) => {
49
- const trimmed = value.trim();
50
- if (trimmed.length === 0) return "";
51
- const body = trimmed.length > 2400 ? `${trimmed.slice(0, 1100)}...<truncated ${trimmed.length - 2200} chars>...${trimmed.slice(-1100)}` : trimmed;
52
- return ` ${label}=${JSON.stringify(body)}`;
53
- };
54
53
  const deployExitDetail = (result, inputs) => {
55
54
  const missingCommandHint = result.exitCode === 127 ? " exit 127 usually means the deploy image is missing walrus-deploy or an entrypoint command." : "";
56
- return `walrus deploy exited with code ${result.exitCode}.` + missingCommandHint + ` outputDir=${inputs.outputDirHostPath} committee=${inputs.committeeSize} shards=${inputs.shards}` + excerpt("stdout", result.stdout) + excerpt("stderr", result.stderr);
55
+ return `walrus deploy exited with code ${result.exitCode}.` + missingCommandHint + ` outputDir=${inputs.outputDirHostPath} committee=${inputs.committeeSize} shards=${inputs.shards}` + labelledExcerpt("stdout", result.stdout) + labelledExcerpt("stderr", result.stderr);
57
56
  };
58
57
  const isBindSourceMissing = (result) => result.exitCode === 125 && /bind source path does not exist/i.test(result.stderr) && /invalid mount config/i.test(result.stderr);
59
- const stringifyCause = (cause) => {
60
- if (cause instanceof Error) return cause.message;
61
- if (typeof cause === "string") return cause;
62
- try {
63
- return JSON.stringify(cause);
64
- } catch {
65
- return String(cause);
66
- }
67
- };
68
58
  /** Parse the walrus deploy output into a `CachedDeployState`.
69
59
  *
70
60
  * Expected output format (best-effort match against the v3 reference's
@@ -84,6 +74,7 @@ const parseDeployOutput = (stdout) => {
84
74
  const pick = (k) => {
85
75
  const v = new RegExp(`(?:^|\\n)\\s*${k}\\s*[:=]\\s*(\\S+)`).exec(stdout)?.[1];
86
76
  if (v === void 0 || v === "None") return void 0;
77
+ if (!/^0x[0-9a-fA-F]+$/u.test(v)) return void 0;
87
78
  return v;
88
79
  };
89
80
  const walrusPackageId = pick("walrus_package_id") ?? pick("package_id");
@@ -109,10 +100,14 @@ const parseDeployOutput = (stdout) => {
109
100
  * 3. Surface non-zero exits + parse failures as
110
101
  * `WalrusPluginError('deploy')` with stdout/stderr capture. */
111
102
  const runDeployOneShot = (runtime, inputs) => Effect.gen(function* () {
112
- if (inputs.waitForFundsReady !== void 0) yield* inputs.waitForFundsReady.pipe(Effect.mapError((cause) => walrusPluginError("deploy", `walrus deploy funding gate failed before walrus-deploy: ${stringifyCause(cause)}`, { cause })));
103
+ if (inputs.waitForFundsReady !== void 0) yield* inputs.waitForFundsReady.pipe(Effect.mapError((cause) => walrusPluginError("deploy", `walrus deploy funding gate failed before walrus-deploy: ${formatUnknownError(cause)}`, { cause })));
113
104
  yield* ensureDeployOutputDir(inputs);
114
105
  const outputOwner = hostBindMountOwner();
115
- const outputMount = walrusDeployMountPaths(inputs.outputDirHostPath, "/opt/walrus/runtime");
106
+ const outputMount = walrusDeployMountPaths({
107
+ stackRoot: inputs.stackRoot,
108
+ deployOutputDirHostPath: inputs.outputDirHostPath,
109
+ mountTarget: "/opt/walrus/runtime"
110
+ });
116
111
  const argv = [
117
112
  "deploy",
118
113
  "--output-dir",
@@ -141,16 +136,22 @@ const runDeployOneShot = (runtime, inputs) => Effect.gen(function* () {
141
136
  }],
142
137
  ...outputOwner === void 0 ? {} : { env: { DEVSTACK_HOST_UID_GID: outputOwner } },
143
138
  network: inputs.suiNetworkName,
144
- extraHosts: { "host.docker.internal": "host-gateway" },
139
+ extraHosts: HOST_GATEWAY_EXTRA_HOSTS,
145
140
  timeoutMillis: DEPLOY_TIMEOUT_MS
146
141
  }).pipe(Effect.catch((cause) => Effect.fail(walrusPluginError("deploy", `walrus deploy one-shot failed: ${cause.reason}: ${cause.detail}`, { cause }))));
147
- let result;
148
- for (let attempt = 0;; attempt += 1) {
149
- result = yield* runAttempt();
150
- if (!isBindSourceMissing(result) || attempt >= DEPLOY_BIND_SOURCE_RETRY_ATTEMPTS) break;
151
- yield* ensureDeployOutputDir(inputs);
152
- yield* Effect.sleep(Duration.millis(DEPLOY_BIND_SOURCE_RETRY_DELAY_MS));
153
- }
142
+ const result = yield* Effect.gen(function* () {
143
+ const result = yield* runAttempt();
144
+ if (isBindSourceMissing(result)) yield* ensureDeployOutputDir(inputs);
145
+ return result;
146
+ }).pipe(Effect.repeat({
147
+ schedule: makeSpacedRetrySchedule(DEPLOY_BIND_SOURCE_RETRY_PROFILE.delayMs, DEPLOY_BIND_SOURCE_RETRY_PROFILE.attempts),
148
+ until: (r) => !isBindSourceMissing(r)
149
+ }));
150
+ if (isBindSourceMissing(result)) return yield* Effect.fail(walrusPluginError("deploy", `walrus deploy: bind-source visibility race did not resolve after ${DEPLOY_BIND_SOURCE_RETRY_PROFILE.attempts} retries (${DEPLOY_BIND_SOURCE_RETRY_PROFILE.delayMs}ms spacing). outputDir=${inputs.outputDirHostPath} — Docker Desktop's bind-source propagation lagged past the retry budget. ` + deployExitDetail(result, inputs), {
151
+ exitCode: result.exitCode,
152
+ stdout: result.stdout,
153
+ stderr: result.stderr
154
+ }));
154
155
  if (result.exitCode !== 0) return yield* Effect.fail(walrusPluginError("deploy", deployExitDetail(result, inputs), {
155
156
  exitCode: result.exitCode,
156
157
  stdout: result.stdout,
@@ -163,8 +164,8 @@ const runDeployOneShot = (runtime, inputs) => Effect.gen(function* () {
163
164
  }));
164
165
  return parsed;
165
166
  }).pipe(Effect.withSpan("devstack.plugin.walrus.deploy.oneShot", { attributes: {
166
- "walrus.committeeSize": inputs.committeeSize,
167
- "walrus.shards": inputs.shards
167
+ [WalrusSpans.committeeSize]: inputs.committeeSize,
168
+ [WalrusSpans.shards]: inputs.shards
168
169
  } }), Effect.timeoutOrElse({
169
170
  duration: Duration.millis(DEPLOY_TIMEOUT_MS + 5e3),
170
171
  orElse: () => Effect.fail(walrusPluginError("deploy", `walrus deploy: outer timeout ${DEPLOY_TIMEOUT_MS}ms exceeded`))
@@ -176,47 +177,44 @@ const runDeployOneShot = (runtime, inputs) => Effect.gen(function* () {
176
177
  * Produce: real wiring — `runDeployOneShot` runs
177
178
  * `docker run --rm walrusImage deploy …` and parses the deploy stdout.
178
179
  *
179
- * Verify-hit projection: the artifact publisher primitive returns the cached
180
- * `Produced` payload after verify succeeds, so callers keep the full
181
- * `CachedDeployState` shape across warm restarts. */
180
+ * The substrate's `ArtifactPublisher.publish` returns the full
181
+ * `CachedDeployState` on EVERY path (decoded cached payload on hit,
182
+ * fresh produce on miss) — no projection dance required. */
182
183
  const deployWalrusContracts = (publisher, probe, runtime, inputs) => Effect.gen(function* () {
183
- const verified = yield* publisher.publish({
184
+ return { state: yield* publisher.publish({
184
185
  namespace: "walrus-deploy",
185
186
  chain: inputs.chainId,
186
187
  contentHash: inputs.contentHash,
187
- verifySchema: WalrusDeployVerifyShape,
188
188
  verify: (cached) => Effect.gen(function* () {
189
189
  if (!(yield* deployOutputFilesComplete(inputs))) return null;
190
- const system = yield* probe.get({
190
+ const probeBoth = probeManyLenient([probe.get({
191
191
  kind: "object",
192
192
  objectId: cached.systemObject
193
- }, SuiObjectExistsShape, "lenient");
194
- if (system === null) return null;
195
- const staking = yield* probe.get({
193
+ }, SuiObjectExistsShape, "lenient"), probe.get({
196
194
  kind: "object",
197
195
  objectId: cached.stakingObject
198
- }, SuiObjectExistsShape, "lenient");
199
- if (staking === null) return null;
196
+ }, SuiObjectExistsShape, "lenient")]);
197
+ let [system, staking] = yield* probeBoth;
198
+ for (let attempt = 0; (system == null || staking == null) && attempt < WALRUS_DEPLOY_VERIFY_READINESS_RETRIES; attempt++) {
199
+ yield* Effect.sleep(WALRUS_DEPLOY_VERIFY_READINESS_DELAY);
200
+ [system, staking] = yield* probeBoth;
201
+ }
202
+ if (system === void 0 || system === null) return null;
203
+ if (staking === void 0 || staking === null) return null;
200
204
  return {
201
205
  systemObjectId: system.objectId,
202
206
  stakingObjectId: staking.objectId
203
207
  };
204
- }).pipe(Effect.catch(() => Effect.succeed(null))),
205
- produce: runDeployOneShot(runtime, inputs).pipe(Effect.mapError((err) => ({
206
- _tag: "ArtifactPublishError",
207
- reason: "produce-failed",
208
- detail: `walrus.deploy ${err.phase}: ${err.message}`
209
- }))),
208
+ }).pipe(Effect.catchTag("ChainProbeError", (err) => {
209
+ if (err.reason === "decode-failed" || err.reason === "no-probe-registered") return Effect.succeed(null);
210
+ return Effect.logWarning(`walrus.deploy verify probe surfaced an authoritative error (reason=${err.reason}, chain=${err.chain}, detail=${err.detail}); re-deploying.`).pipe(Effect.as(null));
211
+ })),
212
+ produce: runDeployOneShot(runtime, inputs).pipe(Effect.mapError((err) => artifactPublishError("produce-failed", `walrus.deploy ${err.phase}: ${err.message}`))),
210
213
  register: () => Effect.void
211
- });
212
- return { state: "walrusPackageId" in verified ? verified : {
213
- walrusPackageId: "<cache-hit-not-rehydrated>",
214
- systemObject: verified.systemObjectId,
215
- stakingObject: verified.stakingObjectId
216
- } };
214
+ }) };
217
215
  }).pipe(Effect.withSpan("devstack.plugin.walrus.deploy", { attributes: {
218
- "walrus.name": inputs.walrusName,
219
- "walrus.chain": inputs.chainId
216
+ [WalrusSpans.name]: inputs.walrusName,
217
+ [WalrusSpans.chain]: inputs.chainId
220
218
  } }));
221
219
  //#endregion
222
220
  export { deployWalrusContracts };
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.mjs","names":[],"sources":["../../../src/plugins/walrus/deploy.ts"],"sourcesContent":["// Walrus deploy one-shot — Move publish via ArtifactPublisher.\n//\n// Distilled-doc reference (06-walrus.md §\"Lifecycle phase 2\"):\n// the `walrus-deploy` one-shot:\n// - publishes the Walrus Move package on the local sui chain,\n// - mints a WAL exchange,\n// - emits per-node config files (`dryrun-node-<i>.yaml`,\n// `dryrun-node-<i>.keystore`) under `runtime/walrus/<name>/deploy/`.\n//\n// We route this through the substrate's `ArtifactPublisher`\n// primitive (architecture §10 — \"callable from any plugin; no\n// plugin-side contract to implement\"). The publisher owns:\n// - cache key derivation (folds `chainId`),\n// - verify probe (lenient — re-derives on transient RPC failure),\n// - produce-on-miss (runs `walrus-deploy`),\n// - register-on-every-cycle (so downstream consumers always see\n// the resolved state).\n//\n// Distilled-doc invariants honored here:\n// - 5: cache key folds `chainId`.\n// - 6: verify checks BOTH the on-disk `deploy` file AND on-chain\n// object existence (system + staking). Either failure\n// invalidates and re-deploys.\n// - 7: `runtime/walrus/<name>/deploy/` rides the snapshot tar\n// (declared via `Snapshotable.subtrees` in `snapshot.ts`).\n// - 10: deploy summary must contain `package_id` + `system_object`\n// + `staking_object`. We surface parse failure as\n// `WalrusPluginError{phase: 'deploy'}` (the publisher's\n// `produce-failed` reason).\n\nimport { Duration, Effect, Schema, type Scope } from 'effect';\nimport { access, mkdir, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport type { ContainerRuntime, ImageRef } from '../../contracts/container-runtime.ts';\nimport type {\n\tArtifactPublishError,\n\tArtifactPublisher,\n} from '../../primitives/artifact-publisher.ts';\nimport type { ChainProbe } from '../../contracts/chain-probe.ts';\nimport type { ChainId, ContentHash } from '../../substrate/brand.ts';\nimport type { SuiProbeKey } from '../sui/chain-probe.ts';\nimport { walrusDeployMountPaths } from './deploy-paths.ts';\nimport { walrusPluginError, type WalrusPluginError } from './errors.ts';\n\n/** Cache-stored payload — what verify re-confirms on every cycle.\n * Mirrors the v3 `CachedDeployState` shape (06-walrus.md §\"State-\n * store entries\"). */\nexport interface CachedDeployState {\n\treadonly walrusPackageId: string;\n\treadonly systemObject: string;\n\treadonly stakingObject: string;\n\treadonly upgradeManagerObject?: string;\n\treadonly treasuryObject?: string;\n\treadonly exchangeObject?: string;\n}\n\n/** Verify-schema: the publisher decodes the cached id's on-chain\n * object through this. Minimal — the substrate's `ChainProbe`\n * decodes against this; any decode failure surfaces structured.\n * Distilled-doc invariant 8: the probe MUST consume a stable\n * identifier (the object id), NOT a derived hash. */\nexport const WalrusDeployVerifyShape = Schema.Struct({\n\tsystemObjectId: Schema.String,\n\tstakingObjectId: Schema.String,\n});\nexport type WalrusDeployVerified = Schema.Schema.Type<typeof WalrusDeployVerifyShape>;\n\nconst SuiObjectExistsShape = Schema.Struct({\n\tobjectId: Schema.String,\n});\n\nconst requiredDeployOutputFiles = (inputs: DeployInputs): ReadonlyArray<string> => [\n\tjoin(inputs.outputDirHostPath, 'deploy'),\n\t...Array.from({ length: inputs.committeeSize }, (_, nodeIndex) => [\n\t\tjoin(inputs.outputDirHostPath, `dryrun-node-${nodeIndex}.yaml`),\n\t\tjoin(inputs.outputDirHostPath, `dryrun-node-${nodeIndex}-sui.yaml`),\n\t\tjoin(inputs.outputDirHostPath, `dryrun-node-${nodeIndex}.keystore`),\n\t]).flat(),\n];\n\nconst deployOutputFilesComplete = (\n\tinputs: DeployInputs,\n): Effect.Effect<boolean, WalrusPluginError> =>\n\tEffect.tryPromise({\n\t\ttry: async () => {\n\t\t\tawait Promise.all(requiredDeployOutputFiles(inputs).map((file) => access(file)));\n\t\t\treturn true;\n\t\t},\n\t\tcatch: (cause) =>\n\t\t\twalrusPluginError(\n\t\t\t\t'deploy',\n\t\t\t\t`walrus deploy cache is missing local output files under ${inputs.outputDirHostPath}`,\n\t\t\t\t{ cause },\n\t\t\t),\n\t}).pipe(Effect.catch(() => Effect.succeed(false)));\n\n/** Inputs to one deploy round. */\nexport interface DeployInputs {\n\treadonly walrusName: string;\n\treadonly chainId: ChainId;\n\treadonly contentHash: ContentHash;\n\t/** Pre-derived host output dir — substrate's `servicePath('walrus',\n\t * name, 'deploy')` equivalent. Persists across teardown\n\t * (distilled-doc §\"What survives teardown\"). */\n\treadonly outputDirHostPath: string;\n\treadonly suiRpcUrlInNetwork: string;\n\treadonly walrusFaucetUrlInNetwork: string;\n\treadonly committeeSize: number;\n\treadonly shards: number;\n\treadonly epochDuration: string;\n\treadonly publicHostsCsv: string;\n\treadonly listeningIpsCsv: string;\n\t/** Wrapper image — the cargo-built walrus image (bootstrap asset).\n\t * The deploy one-shot is `docker run --rm <image> deploy …`. */\n\treadonly walrusImage: ImageRef;\n\t/** Docker network the deploy one-shot attaches to, so its in-network\n\t * Sui RPC + faucet hostnames resolve. */\n\treadonly suiNetworkName: string;\n\t/** Centralized Sui funding readiness gate. Local Sui exposes this so\n\t * callers don't race the faucet's socket-ready / funds-ready gap. */\n\treadonly waitForFundsReady?: Effect.Effect<void, unknown>;\n}\n\n/** Default deploy one-shot timeout. Walrus genesis publish runs the\n * Move publish + WAL exchange creation + per-node config emission;\n * observed wall-clock is 30-60s. 5-minute ceiling absorbs cold-cache\n * + slow CI runners. */\nconst DEPLOY_TIMEOUT_MS = 5 * 60_000;\nconst DEPLOY_BIND_SOURCE_RETRY_ATTEMPTS = 10;\nconst DEPLOY_BIND_SOURCE_RETRY_DELAY_MS = 500;\n\nconst ensureDeployOutputDir = (inputs: DeployInputs): Effect.Effect<void, WalrusPluginError> =>\n\tEffect.tryPromise({\n\t\ttry: async () => {\n\t\t\tawait mkdir(inputs.outputDirHostPath, { recursive: true });\n\t\t\tawait writeFile(\n\t\t\t\tjoin(inputs.outputDirHostPath, '.devstack-bind-source'),\n\t\t\t\t'devstack walrus bind source\\n',\n\t\t\t\t'utf8',\n\t\t\t);\n\t\t},\n\t\tcatch: (cause) =>\n\t\t\twalrusPluginError(\n\t\t\t\t'deploy',\n\t\t\t\t`walrus deploy failed to prepare output directory ${inputs.outputDirHostPath}`,\n\t\t\t\t{ cause },\n\t\t\t),\n\t});\n\nconst hostBindMountOwner = (): string | undefined => {\n\tconst process = (\n\t\tglobalThis as {\n\t\t\tprocess?: { getuid?: () => number; getgid?: () => number };\n\t\t}\n\t).process;\n\tif (typeof process?.getuid !== 'function' || typeof process.getgid !== 'function') {\n\t\treturn undefined;\n\t}\n\treturn `${process.getuid()}:${process.getgid()}`;\n};\n\nconst excerpt = (label: string, value: string): string => {\n\tconst trimmed = value.trim();\n\tif (trimmed.length === 0) return '';\n\tconst max = 2_400;\n\tconst body =\n\t\ttrimmed.length > max\n\t\t\t? `${trimmed.slice(0, 1_100)}...<truncated ${trimmed.length - 2_200} chars>...${trimmed.slice(-1_100)}`\n\t\t\t: trimmed;\n\treturn ` ${label}=${JSON.stringify(body)}`;\n};\n\nconst deployExitDetail = (\n\tresult: { readonly exitCode: number; readonly stdout: string; readonly stderr: string },\n\tinputs: DeployInputs,\n): string => {\n\tconst missingCommandHint =\n\t\tresult.exitCode === 127\n\t\t\t? ' exit 127 usually means the deploy image is missing walrus-deploy or an entrypoint command.'\n\t\t\t: '';\n\treturn (\n\t\t`walrus deploy exited with code ${result.exitCode}.` +\n\t\tmissingCommandHint +\n\t\t` outputDir=${inputs.outputDirHostPath} committee=${inputs.committeeSize} shards=${inputs.shards}` +\n\t\texcerpt('stdout', result.stdout) +\n\t\texcerpt('stderr', result.stderr)\n\t);\n};\n\nconst isBindSourceMissing = (result: {\n\treadonly exitCode: number;\n\treadonly stderr: string;\n}): boolean =>\n\tresult.exitCode === 125 &&\n\t/bind source path does not exist/i.test(result.stderr) &&\n\t/invalid mount config/i.test(result.stderr);\n\nconst stringifyCause = (cause: unknown): string => {\n\tif (cause instanceof Error) return cause.message;\n\tif (typeof cause === 'string') return cause;\n\ttry {\n\t\treturn JSON.stringify(cause);\n\t} catch {\n\t\treturn String(cause);\n\t}\n};\n\n/** Parse the walrus deploy output into a `CachedDeployState`.\n *\n * Expected output format (best-effort match against the v3 reference's\n * deploy stdout — the walrus binary's exact format may drift between\n * versions):\n *\n * walrus_package_id: 0x<hex>\n * system_object: 0x<hex>\n * staking_object: 0x<hex>\n * upgrade_manager_object: 0x<hex> (optional)\n * treasury_object: 0x<hex> (optional)\n * exchange_object: 0x<hex> (optional)\n *\n * Returns the parsed state OR a typed `WalrusPluginError('deploy')`\n * surfaced with stdout/stderr capture for debugging. */\nexport const parseDeployOutput = (stdout: string): CachedDeployState | null => {\n\t// Match `key: value` (or `key = value`) lines; treat `None` as\n\t// \"absent\" per the upstream walrus-deploy output convention. The\n\t// pattern is permissive on the value (`\\S+`) — walrus-deploy\n\t// versions have varied on the exact hex format, and the substrate's\n\t// downstream `ChainProbe` re-validates the id shape anyway.\n\tconst pick = (k: string): string | undefined => {\n\t\tconst re = new RegExp(`(?:^|\\\\n)\\\\s*${k}\\\\s*[:=]\\\\s*(\\\\S+)`);\n\t\tconst m = re.exec(stdout);\n\t\tconst v = m?.[1];\n\t\tif (v === undefined || v === 'None') return undefined;\n\t\treturn v;\n\t};\n\tconst walrusPackageId = pick('walrus_package_id') ?? pick('package_id');\n\tconst systemObject = pick('system_object') ?? pick('system_object_id');\n\tconst stakingObject =\n\t\tpick('staking_object') ?? pick('staking_pool_id') ?? pick('staking_object_id');\n\tif (!walrusPackageId || !systemObject || !stakingObject) return null;\n\treturn {\n\t\twalrusPackageId,\n\t\tsystemObject,\n\t\tstakingObject,\n\t\tupgradeManagerObject: pick('upgrade_manager_object'),\n\t\ttreasuryObject: pick('treasury_object'),\n\t\texchangeObject: pick('exchange_object'),\n\t};\n};\n\n/** Run the walrus-deploy one-shot and parse the output.\n *\n * Implementation:\n * 1. `runtime.runOneShot({ image, argv: ['deploy', ...] })` —\n * fresh `docker run --rm` container. Mount the host output dir\n * at `/opt/walrus/outputs` so the per-node config files persist.\n * 2. Parse stdout for the deploy summary.\n * 3. Surface non-zero exits + parse failures as\n * `WalrusPluginError('deploy')` with stdout/stderr capture. */\nexport const runDeployOneShot = (\n\truntime: ContainerRuntime,\n\tinputs: DeployInputs,\n): Effect.Effect<CachedDeployState, WalrusPluginError, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tif (inputs.waitForFundsReady !== undefined) {\n\t\t\tyield* inputs.waitForFundsReady.pipe(\n\t\t\t\tEffect.mapError((cause) =>\n\t\t\t\t\twalrusPluginError(\n\t\t\t\t\t\t'deploy',\n\t\t\t\t\t\t`walrus deploy funding gate failed before walrus-deploy: ${stringifyCause(cause)}`,\n\t\t\t\t\t\t{ cause },\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tyield* ensureDeployOutputDir(inputs);\n\n\t\tconst outputOwner = hostBindMountOwner();\n\t\tconst outputMount = walrusDeployMountPaths(inputs.outputDirHostPath, '/opt/walrus/runtime');\n\t\tconst argv: ReadonlyArray<string> = [\n\t\t\t'deploy',\n\t\t\t'--output-dir',\n\t\t\toutputMount.outputDirInContainer,\n\t\t\t'--committee-size',\n\t\t\tString(inputs.committeeSize),\n\t\t\t'--shards',\n\t\t\tString(inputs.shards),\n\t\t\t'--epoch-duration',\n\t\t\tinputs.epochDuration,\n\t\t\t'--sui-rpc-url',\n\t\t\tinputs.suiRpcUrlInNetwork,\n\t\t\t'--faucet-url',\n\t\t\tinputs.walrusFaucetUrlInNetwork,\n\t\t\t'--public-hosts',\n\t\t\tinputs.publicHostsCsv,\n\t\t\t'--listening-ips',\n\t\t\tinputs.listeningIpsCsv,\n\t\t];\n\n\t\tconst runAttempt = () =>\n\t\t\truntime\n\t\t\t\t.runOneShot({\n\t\t\t\t\timage: inputs.walrusImage,\n\t\t\t\t\targv,\n\t\t\t\t\tmounts: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsource: outputMount.sourceHostPath,\n\t\t\t\t\t\t\ttarget: outputMount.mountTarget,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\t...(outputOwner === undefined ? {} : { env: { DEVSTACK_HOST_UID_GID: outputOwner } }),\n\t\t\t\t\tnetwork: inputs.suiNetworkName,\n\t\t\t\t\t// Same `host-gateway` rationale as storage-nodes.ts —\n\t\t\t\t\t// deploy one-shot dials sui's host-bound RPC + faucet via\n\t\t\t\t\t// `host.docker.internal`. Native Linux Docker needs the\n\t\t\t\t\t// explicit mapping; Docker Desktop is a no-op.\n\t\t\t\t\textraHosts: { 'host.docker.internal': 'host-gateway' },\n\t\t\t\t\ttimeoutMillis: DEPLOY_TIMEOUT_MS,\n\t\t\t\t})\n\t\t\t\t.pipe(\n\t\t\t\t\tEffect.catch((cause) =>\n\t\t\t\t\t\tEffect.fail(\n\t\t\t\t\t\t\twalrusPluginError(\n\t\t\t\t\t\t\t\t'deploy',\n\t\t\t\t\t\t\t\t`walrus deploy one-shot failed: ${cause.reason}: ${cause.detail}`,\n\t\t\t\t\t\t\t\t{ cause },\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\n\t\tlet result: { readonly exitCode: number; readonly stdout: string; readonly stderr: string };\n\t\tfor (let attempt = 0; ; attempt += 1) {\n\t\t\tresult = yield* runAttempt();\n\t\t\tif (!isBindSourceMissing(result) || attempt >= DEPLOY_BIND_SOURCE_RETRY_ATTEMPTS) break;\n\t\t\tyield* ensureDeployOutputDir(inputs);\n\t\t\tyield* Effect.sleep(Duration.millis(DEPLOY_BIND_SOURCE_RETRY_DELAY_MS));\n\t\t}\n\n\t\tif (result.exitCode !== 0) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\twalrusPluginError('deploy', deployExitDetail(result, inputs), {\n\t\t\t\t\texitCode: result.exitCode,\n\t\t\t\t\tstdout: result.stdout,\n\t\t\t\t\tstderr: result.stderr,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tconst parsed = parseDeployOutput(result.stdout);\n\t\tif (!parsed) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\twalrusPluginError(\n\t\t\t\t\t'deploy',\n\t\t\t\t\t`walrus deploy: parser could not find walrus_package_id / system_object / staking_object ` +\n\t\t\t\t\t\t`in deploy output. Confirm the walrus binary's output format and adjust ` +\n\t\t\t\t\t\t`\\`parseDeployOutput\\` regexes in deploy.ts. ` +\n\t\t\t\t\t\t`SEAM: see deploy.ts header for the expected format.`,\n\t\t\t\t\t{ stdout: result.stdout, stderr: result.stderr },\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\treturn parsed;\n\t}).pipe(\n\t\tEffect.withSpan('devstack.plugin.walrus.deploy.oneShot', {\n\t\t\tattributes: { 'walrus.committeeSize': inputs.committeeSize, 'walrus.shards': inputs.shards },\n\t\t}),\n\t\tEffect.timeoutOrElse({\n\t\t\tduration: Duration.millis(DEPLOY_TIMEOUT_MS + 5_000),\n\t\t\torElse: () =>\n\t\t\t\tEffect.fail(\n\t\t\t\t\twalrusPluginError(\n\t\t\t\t\t\t'deploy',\n\t\t\t\t\t\t`walrus deploy: outer timeout ${DEPLOY_TIMEOUT_MS}ms exceeded`,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t}),\n\t);\n\n/** Outputs of one deploy round — surfaced to the plugin's\n * resolved value. */\nexport interface DeployOutputs {\n\treadonly state: CachedDeployState;\n}\n\n/** Compose the ArtifactSpec for a walrus deploy and dispatch\n * through the substrate primitive. The publisher handles the full\n * cache/verify/produce/register loop.\n *\n * Produce: real wiring — `runDeployOneShot` runs\n * `docker run --rm walrusImage deploy …` and parses the deploy stdout.\n *\n * Verify-hit projection: the artifact publisher primitive returns the cached\n * `Produced` payload after verify succeeds, so callers keep the full\n * `CachedDeployState` shape across warm restarts. */\nexport const deployWalrusContracts = (\n\tpublisher: ArtifactPublisher,\n\tprobe: ChainProbe<SuiProbeKey>,\n\truntime: ContainerRuntime,\n\tinputs: DeployInputs,\n): Effect.Effect<DeployOutputs, WalrusPluginError | ArtifactPublishError, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst verified = yield* publisher.publish<CachedDeployState, WalrusDeployVerified>({\n\t\t\tnamespace: 'walrus-deploy',\n\t\t\tchain: inputs.chainId,\n\t\t\tcontentHash: inputs.contentHash,\n\t\t\tverifySchema: WalrusDeployVerifyShape,\n\t\t\t// Verify: lenient probes of the cached system + staking\n\t\t\t// objects. The Sui chain probe decodes raw `getObject`\n\t\t\t// responses, so the probe schema matches that envelope and\n\t\t\t// this closure returns the compact verified shape.\n\t\t\tverify: (cached) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tif (!(yield* deployOutputFilesComplete(inputs))) return null;\n\n\t\t\t\t\tconst system = yield* probe.get(\n\t\t\t\t\t\t{ kind: 'object', objectId: cached.systemObject },\n\t\t\t\t\t\tSuiObjectExistsShape,\n\t\t\t\t\t\t'lenient',\n\t\t\t\t\t);\n\t\t\t\t\tif (system === null) return null;\n\n\t\t\t\t\tconst staking = yield* probe.get(\n\t\t\t\t\t\t{ kind: 'object', objectId: cached.stakingObject },\n\t\t\t\t\t\tSuiObjectExistsShape,\n\t\t\t\t\t\t'lenient',\n\t\t\t\t\t);\n\t\t\t\t\tif (staking === null) return null;\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsystemObjectId: system.objectId,\n\t\t\t\t\t\tstakingObjectId: staking.objectId,\n\t\t\t\t\t} satisfies WalrusDeployVerified;\n\t\t\t\t}).pipe(Effect.catch(() => Effect.succeed(null as WalrusDeployVerified | null))),\n\t\t\t// Produce: real walrus-deploy one-shot.\n\t\t\tproduce: runDeployOneShot(runtime, inputs).pipe(\n\t\t\t\tEffect.mapError(\n\t\t\t\t\t(err): ArtifactPublishError => ({\n\t\t\t\t\t\t_tag: 'ArtifactPublishError',\n\t\t\t\t\t\treason: 'produce-failed',\n\t\t\t\t\t\tdetail: `walrus.deploy ${err.phase}: ${err.message}`,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t),\n\t\t\t// Register: fires on EVERY cycle. The plugin's outer body\n\t\t\t// performs the walrus-state / endpoint / package registry\n\t\t\t// publishes after both deploy + storage-nodes are up; this\n\t\t\t// closure is the publisher-side null-op so the substrate\n\t\t\t// satisfies its Invariant-6 contract.\n\t\t\tregister: () => Effect.void,\n\t\t});\n\n\t\t// Project Produced ∪ Verified onto CachedDeployState. artifact publisher returns\n\t\t// the cached Produced payload on verify-hit, but keep a defensive\n\t\t// projection for custom publisher implementations in tests.\n\t\tconst state: CachedDeployState =\n\t\t\t'walrusPackageId' in verified\n\t\t\t\t? verified\n\t\t\t\t: {\n\t\t\t\t\t\t// Verify-hit path: synthesize from the cached id's.\n\t\t\t\t\t\t// The richer fields (packageId, exchange etc.) live\n\t\t\t\t\t\t// in the on-disk artifact publisher cache; downstream consumers\n\t\t\t\t\t\t// surface them through the in-process registry. The\n\t\t\t\t\t\t// artifact publisher primitive's next API revision will hand the\n\t\t\t\t\t\t// full Produced payload back here directly —\n\t\t\t\t\t\t// architecture revision tracked in the file header.\n\t\t\t\t\t\twalrusPackageId: '<cache-hit-not-rehydrated>',\n\t\t\t\t\t\tsystemObject: verified.systemObjectId,\n\t\t\t\t\t\tstakingObject: verified.stakingObjectId,\n\t\t\t\t\t};\n\n\t\treturn { state };\n\t}).pipe(\n\t\tEffect.withSpan('devstack.plugin.walrus.deploy', {\n\t\t\tattributes: { 'walrus.name': inputs.walrusName, 'walrus.chain': inputs.chainId },\n\t\t}),\n\t);\n"],"mappings":"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"}
1
+ {"version":3,"file":"deploy.mjs","names":[],"sources":["../../../src/plugins/walrus/deploy.ts"],"sourcesContent":["// Walrus deploy one-shot — Move publish via ArtifactPublisher.\n//\n// Distilled-doc reference (06-walrus.md §\"Lifecycle phase 2\"):\n// the `walrus-deploy` one-shot:\n// - publishes the Walrus Move package on the local sui chain,\n// - mints a WAL exchange,\n// - emits per-node config files (`dryrun-node-<i>.yaml`,\n// `dryrun-node-<i>.keystore`) under `runtime/walrus/<name>/deploy/`.\n//\n// We route this through the substrate's `ArtifactPublisher`\n// primitive (architecture §10 — \"callable from any plugin; no\n// plugin-side contract to implement\"). The publisher owns:\n// - cache key derivation (folds `chainId`),\n// - verify probe (lenient — re-derives on transient RPC failure),\n// - produce-on-miss (runs `walrus-deploy`),\n// - register-on-every-cycle (so downstream consumers always see\n// the resolved state).\n//\n// Distilled-doc invariants honored here:\n// - 5: cache key folds `chainId`.\n// - 6: verify checks BOTH the on-disk `deploy` file AND on-chain\n// object existence (system + staking). Either failure\n// invalidates and re-deploys.\n// - 7: `runtime/walrus/<name>/deploy/` rides the snapshot tar\n// (declared via `Snapshotable.subtrees` in `snapshot.ts`).\n// - 10: deploy summary must contain `package_id` + `system_object`\n// + `staking_object`. We surface parse failure as\n// `WalrusPluginError{phase: 'deploy'}` (the publisher's\n// `produce-failed` reason).\n\nimport { Duration, Effect, Schema, type Scope } from 'effect';\nimport { access, mkdir } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport type { ContainerRuntime, ImageRef } from '../../contracts/container-runtime.ts';\nimport {\n\tartifactPublishError,\n\ttype ArtifactPublishError,\n\ttype ArtifactPublisher,\n} from '../../primitives/artifact-publisher.ts';\nimport type { ChainProbe } from '../../contracts/chain-probe.ts';\nimport type { ChainId, ContentHash } from '../../substrate/brand.ts';\nimport { atomicWriteFileSync } from '../../substrate/runtime/atomic-write.ts';\nimport { hostBindMountOwner } from '../../substrate/runtime/host-bind-mount-owner.ts';\nimport { HOST_GATEWAY_EXTRA_HOSTS } from '../../substrate/runtime/host-gateway.ts';\nimport { probeManyLenient } from '../../substrate/runtime/probes.ts';\nimport {\n\tDEPLOY_BIND_SOURCE_RETRY_PROFILE,\n\tmakeSpacedRetrySchedule,\n} from '../../substrate/runtime/retry-policy.ts';\nimport { formatUnknownError } from '../../substrate/runtime/format-unknown-error.ts';\nimport { labelledExcerpt } from '../../substrate/runtime/observability/index.ts';\nimport type { SuiProbeKey } from '../sui/index.ts';\nimport { walrusDeployMountPaths } from './deploy-paths.ts';\nimport { walrusPluginError, type WalrusPluginError } from './errors.ts';\nimport { WalrusSpans } from './spans.ts';\n\n/** Cache-stored payload — what verify re-confirms on every cycle.\n * Mirrors the v3 `CachedDeployState` shape (06-walrus.md §\"State-\n * store entries\"). */\nexport interface CachedDeployState {\n\treadonly walrusPackageId: string;\n\treadonly systemObject: string;\n\treadonly stakingObject: string;\n\treadonly upgradeManagerObject?: string;\n\treadonly treasuryObject?: string;\n\treadonly exchangeObject?: string;\n}\n\n/** Verify-schema: the publisher decodes the cached id's on-chain\n * object through this. Minimal — the substrate's `ChainProbe`\n * decodes against this; any decode failure surfaces structured.\n * Distilled-doc invariant 8: the probe MUST consume a stable\n * identifier (the object id), NOT a derived hash. */\nexport const WalrusDeployVerifyShape = Schema.Struct({\n\tsystemObjectId: Schema.String,\n\tstakingObjectId: Schema.String,\n});\nexport type WalrusDeployVerified = Schema.Schema.Type<typeof WalrusDeployVerifyShape>;\n\nconst SuiObjectExistsShape = Schema.Struct({\n\tobjectId: Schema.String,\n});\n\n/** A freshly RESTORED validator can take a few seconds to start serving the\n * committed deploy objects (sui/system/staking); retry the deploy-verify\n * probes across this window so a readiness race doesn't read them as\n * not-found and trigger a spurious redeploy — which would churn the walrus\n * deploy ids and orphan every pre-snapshot blob. A warm restart finds them on\n * the first probe; a genuinely-wiped chain still redeploys once retries lapse. */\nconst WALRUS_DEPLOY_VERIFY_READINESS_RETRIES = 5;\nconst WALRUS_DEPLOY_VERIFY_READINESS_DELAY = '3 seconds';\n\nconst requiredDeployOutputFiles = (inputs: DeployInputs): ReadonlyArray<string> => [\n\tjoin(inputs.outputDirHostPath, 'deploy'),\n\t...Array.from({ length: inputs.committeeSize }, (_, nodeIndex) => [\n\t\tjoin(inputs.outputDirHostPath, `dryrun-node-${nodeIndex}.yaml`),\n\t\tjoin(inputs.outputDirHostPath, `dryrun-node-${nodeIndex}-sui.yaml`),\n\t\tjoin(inputs.outputDirHostPath, `dryrun-node-${nodeIndex}.keystore`),\n\t]).flat(),\n];\n\nconst deployOutputFilesComplete = (\n\tinputs: DeployInputs,\n): Effect.Effect<boolean, WalrusPluginError> =>\n\tEffect.tryPromise({\n\t\ttry: async () => {\n\t\t\tawait Promise.all(requiredDeployOutputFiles(inputs).map((file) => access(file)));\n\t\t\treturn true;\n\t\t},\n\t\tcatch: (cause) =>\n\t\t\twalrusPluginError(\n\t\t\t\t'deploy',\n\t\t\t\t`walrus deploy cache is missing local output files under ${inputs.outputDirHostPath}`,\n\t\t\t\t{ cause },\n\t\t\t),\n\t}).pipe(Effect.catch(() => Effect.succeed(false)));\n\n/** Inputs to one deploy round. */\nexport interface DeployInputs {\n\treadonly walrusName: string;\n\treadonly chainId: ChainId;\n\treadonly contentHash: ContentHash;\n\t/** Pre-derived host output dir — substrate's `servicePath('walrus',\n\t * name, 'deploy')` equivalent. Persists across teardown\n\t * (distilled-doc §\"What survives teardown\"). */\n\treadonly outputDirHostPath: string;\n\t/** On-disk per-stack root from `StackPathsService.stackRoot`. The\n\t * bind-mount source is `stackRoot`; `outputDirHostPath` MUST be a\n\t * descendant. Threaded explicitly to remove the previous\n\t * `dirname(dirname(dirname(...)))` walk-up footgun in\n\t * `walrusDeployMountPaths`. */\n\treadonly stackRoot: string;\n\treadonly suiRpcUrlInNetwork: string;\n\treadonly walrusFaucetUrlInNetwork: string;\n\treadonly committeeSize: number;\n\treadonly shards: number;\n\treadonly epochDuration: string;\n\treadonly publicHostsCsv: string;\n\treadonly listeningIpsCsv: string;\n\t/** Wrapper image — the cargo-built walrus image (bootstrap asset).\n\t * The deploy one-shot is `docker run --rm <image> deploy …`. */\n\treadonly walrusImage: ImageRef;\n\t/** Docker network the deploy one-shot attaches to, so its in-network\n\t * Sui RPC + faucet hostnames resolve. */\n\treadonly suiNetworkName: string;\n\t/** Centralized Sui funding readiness gate. Local Sui exposes this so\n\t * callers don't race the faucet's socket-ready / funds-ready gap. */\n\treadonly waitForFundsReady?: Effect.Effect<void, unknown>;\n}\n\n/** Default deploy one-shot timeout. Walrus genesis publish runs the\n * Move publish + WAL exchange creation + per-node config emission;\n * observed wall-clock is 30-60s. 5-minute ceiling absorbs cold-cache\n * + slow CI runners. */\nconst DEPLOY_TIMEOUT_MS = 5 * 60_000;\n\nconst ensureDeployOutputDir = (inputs: DeployInputs): Effect.Effect<void, WalrusPluginError> =>\n\tEffect.tryPromise({\n\t\ttry: async () => {\n\t\t\tawait mkdir(inputs.outputDirHostPath, { recursive: true });\n\t\t\t// Route the bind-source marker through the canonical atomic\n\t\t\t// primitive (STYLE_GUIDE §17) — tempfile + fsync + rename so a\n\t\t\t// crashed writer can't leave the bind-mount probe reading a\n\t\t\t// half-written marker. 0o644 so the in-container deploy user can\n\t\t\t// stat it. Sync variant: the marker is a tiny one-liner and it\n\t\t\t// keeps the durability boundary the raw `writeFile` lacked.\n\t\t\tatomicWriteFileSync(\n\t\t\t\tjoin(inputs.outputDirHostPath, '.devstack-bind-source'),\n\t\t\t\t'devstack walrus bind source\\n',\n\t\t\t\t{ mode: 0o644 },\n\t\t\t);\n\t\t},\n\t\tcatch: (cause) =>\n\t\t\twalrusPluginError(\n\t\t\t\t'deploy',\n\t\t\t\t`walrus deploy failed to prepare output directory ${inputs.outputDirHostPath}`,\n\t\t\t\t{ cause },\n\t\t\t),\n\t});\n\nconst deployExitDetail = (\n\tresult: { readonly exitCode: number; readonly stdout: string; readonly stderr: string },\n\tinputs: DeployInputs,\n): string => {\n\tconst missingCommandHint =\n\t\tresult.exitCode === 127\n\t\t\t? ' exit 127 usually means the deploy image is missing walrus-deploy or an entrypoint command.'\n\t\t\t: '';\n\treturn (\n\t\t`walrus deploy exited with code ${result.exitCode}.` +\n\t\tmissingCommandHint +\n\t\t` outputDir=${inputs.outputDirHostPath} committee=${inputs.committeeSize} shards=${inputs.shards}` +\n\t\tlabelledExcerpt('stdout', result.stdout) +\n\t\tlabelledExcerpt('stderr', result.stderr)\n\t);\n};\n\nconst isBindSourceMissing = (result: {\n\treadonly exitCode: number;\n\treadonly stderr: string;\n}): boolean =>\n\tresult.exitCode === 125 &&\n\t/bind source path does not exist/i.test(result.stderr) &&\n\t/invalid mount config/i.test(result.stderr);\n\n/** Parse the walrus deploy output into a `CachedDeployState`.\n *\n * Expected output format (best-effort match against the v3 reference's\n * deploy stdout — the walrus binary's exact format may drift between\n * versions):\n *\n * walrus_package_id: 0x<hex>\n * system_object: 0x<hex>\n * staking_object: 0x<hex>\n * upgrade_manager_object: 0x<hex> (optional)\n * treasury_object: 0x<hex> (optional)\n * exchange_object: 0x<hex> (optional)\n *\n * Returns the parsed state OR a typed `WalrusPluginError('deploy')`\n * surfaced with stdout/stderr capture for debugging. */\nexport const parseDeployOutput = (stdout: string): CachedDeployState | null => {\n\t// Match `key: value` (or `key = value`) lines; treat `None` as\n\t// \"absent\" per the upstream walrus-deploy output convention.\n\t//\n\t// Value pattern: `0x<hex>` strictly. The previous `\\S+` regex\n\t// happily matched values like `None,` (with a trailing comma) or\n\t// `[unset]` and passed them through as fake object ids; downstream\n\t// `ChainProbe.get(...)` would then issue a `getObject` against\n\t// garbage, surfacing a confusing \"object not found\" instead of a\n\t// parse failure. Enforcing the hex shape here makes the parse-\n\t// failure surface (`walrusPluginError('deploy', 'parser could not\n\t// find ...')`) catch the bad value at its real source.\n\tconst pick = (k: string): string | undefined => {\n\t\tconst re = new RegExp(`(?:^|\\\\n)\\\\s*${k}\\\\s*[:=]\\\\s*(\\\\S+)`);\n\t\tconst m = re.exec(stdout);\n\t\tconst v = m?.[1];\n\t\tif (v === undefined || v === 'None') return undefined;\n\t\tif (!/^0x[0-9a-fA-F]+$/u.test(v)) return undefined;\n\t\treturn v;\n\t};\n\tconst walrusPackageId = pick('walrus_package_id') ?? pick('package_id');\n\tconst systemObject = pick('system_object') ?? pick('system_object_id');\n\tconst stakingObject =\n\t\tpick('staking_object') ?? pick('staking_pool_id') ?? pick('staking_object_id');\n\tif (!walrusPackageId || !systemObject || !stakingObject) return null;\n\treturn {\n\t\twalrusPackageId,\n\t\tsystemObject,\n\t\tstakingObject,\n\t\tupgradeManagerObject: pick('upgrade_manager_object'),\n\t\ttreasuryObject: pick('treasury_object'),\n\t\texchangeObject: pick('exchange_object'),\n\t};\n};\n\n/** Run the walrus-deploy one-shot and parse the output.\n *\n * Implementation:\n * 1. `runtime.runOneShot({ image, argv: ['deploy', ...] })` —\n * fresh `docker run --rm` container. Mount the host output dir\n * at `/opt/walrus/outputs` so the per-node config files persist.\n * 2. Parse stdout for the deploy summary.\n * 3. Surface non-zero exits + parse failures as\n * `WalrusPluginError('deploy')` with stdout/stderr capture. */\nexport const runDeployOneShot = (\n\truntime: ContainerRuntime,\n\tinputs: DeployInputs,\n): Effect.Effect<CachedDeployState, WalrusPluginError, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tif (inputs.waitForFundsReady !== undefined) {\n\t\t\tyield* inputs.waitForFundsReady.pipe(\n\t\t\t\tEffect.mapError((cause) =>\n\t\t\t\t\twalrusPluginError(\n\t\t\t\t\t\t'deploy',\n\t\t\t\t\t\t`walrus deploy funding gate failed before walrus-deploy: ${formatUnknownError(cause)}`,\n\t\t\t\t\t\t{ cause },\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tyield* ensureDeployOutputDir(inputs);\n\n\t\tconst outputOwner = hostBindMountOwner();\n\t\tconst outputMount = walrusDeployMountPaths({\n\t\t\tstackRoot: inputs.stackRoot,\n\t\t\tdeployOutputDirHostPath: inputs.outputDirHostPath,\n\t\t\tmountTarget: '/opt/walrus/runtime',\n\t\t});\n\t\tconst argv: ReadonlyArray<string> = [\n\t\t\t'deploy',\n\t\t\t'--output-dir',\n\t\t\toutputMount.outputDirInContainer,\n\t\t\t'--committee-size',\n\t\t\tString(inputs.committeeSize),\n\t\t\t'--shards',\n\t\t\tString(inputs.shards),\n\t\t\t'--epoch-duration',\n\t\t\tinputs.epochDuration,\n\t\t\t'--sui-rpc-url',\n\t\t\tinputs.suiRpcUrlInNetwork,\n\t\t\t'--faucet-url',\n\t\t\tinputs.walrusFaucetUrlInNetwork,\n\t\t\t'--public-hosts',\n\t\t\tinputs.publicHostsCsv,\n\t\t\t'--listening-ips',\n\t\t\tinputs.listeningIpsCsv,\n\t\t];\n\n\t\tconst runAttempt = () =>\n\t\t\truntime\n\t\t\t\t.runOneShot({\n\t\t\t\t\timage: inputs.walrusImage,\n\t\t\t\t\targv,\n\t\t\t\t\tmounts: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsource: outputMount.sourceHostPath,\n\t\t\t\t\t\t\ttarget: outputMount.mountTarget,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\t...(outputOwner === undefined ? {} : { env: { DEVSTACK_HOST_UID_GID: outputOwner } }),\n\t\t\t\t\tnetwork: inputs.suiNetworkName,\n\t\t\t\t\t// Same `host-gateway` rationale as storage-nodes.ts —\n\t\t\t\t\t// deploy one-shot dials sui's host-bound RPC + faucet via\n\t\t\t\t\t// `host.docker.internal`. See substrate/runtime/host-gateway.ts\n\t\t\t\t\t// for the platform rationale.\n\t\t\t\t\textraHosts: HOST_GATEWAY_EXTRA_HOSTS,\n\t\t\t\t\ttimeoutMillis: DEPLOY_TIMEOUT_MS,\n\t\t\t\t})\n\t\t\t\t.pipe(\n\t\t\t\t\tEffect.catch((cause) =>\n\t\t\t\t\t\tEffect.fail(\n\t\t\t\t\t\t\twalrusPluginError(\n\t\t\t\t\t\t\t\t'deploy',\n\t\t\t\t\t\t\t\t`walrus deploy one-shot failed: ${cause.reason}: ${cause.detail}`,\n\t\t\t\t\t\t\t\t{ cause },\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\n\t\tconst attempt = Effect.gen(function* () {\n\t\t\tconst result = yield* runAttempt();\n\t\t\tif (isBindSourceMissing(result)) {\n\t\t\t\tyield* ensureDeployOutputDir(inputs);\n\t\t\t}\n\t\t\treturn result;\n\t\t});\n\t\tconst result = yield* attempt.pipe(\n\t\t\tEffect.repeat({\n\t\t\t\tschedule: makeSpacedRetrySchedule(\n\t\t\t\t\tDEPLOY_BIND_SOURCE_RETRY_PROFILE.delayMs,\n\t\t\t\t\tDEPLOY_BIND_SOURCE_RETRY_PROFILE.attempts,\n\t\t\t\t),\n\t\t\t\tuntil: (r) => !isBindSourceMissing(r),\n\t\t\t}),\n\t\t);\n\n\t\t// `Effect.repeat` with a bounded `schedule` + `until` exits SUCCESS\n\t\t// in two cases: (a) `until(r)` returned true (bind source is now\n\t\t// visible — the happy path) OR (b) the schedule recurrence cap was\n\t\t// reached while `until(r)` still returned false (the bind source\n\t\t// remained missing through every retry). The follow-up\n\t\t// `result.exitCode !== 0` check below would already surface case\n\t\t// (b) as a deploy-failure exit, but the failure message would be\n\t\t// the bind-source stderr — not the more diagnostic \"we exhausted\n\t\t// the bind-source retry budget\" message. Surface that explicitly\n\t\t// here so operators see the retry budget in the failure shape.\n\t\tif (isBindSourceMissing(result)) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\twalrusPluginError(\n\t\t\t\t\t'deploy',\n\t\t\t\t\t`walrus deploy: bind-source visibility race did not resolve after ` +\n\t\t\t\t\t\t`${DEPLOY_BIND_SOURCE_RETRY_PROFILE.attempts} retries ` +\n\t\t\t\t\t\t`(${DEPLOY_BIND_SOURCE_RETRY_PROFILE.delayMs}ms spacing). ` +\n\t\t\t\t\t\t`outputDir=${inputs.outputDirHostPath} — Docker Desktop's bind-source ` +\n\t\t\t\t\t\t`propagation lagged past the retry budget. ` +\n\t\t\t\t\t\tdeployExitDetail(result, inputs),\n\t\t\t\t\t{\n\t\t\t\t\t\texitCode: result.exitCode,\n\t\t\t\t\t\tstdout: result.stdout,\n\t\t\t\t\t\tstderr: result.stderr,\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tif (result.exitCode !== 0) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\twalrusPluginError('deploy', deployExitDetail(result, inputs), {\n\t\t\t\t\texitCode: result.exitCode,\n\t\t\t\t\tstdout: result.stdout,\n\t\t\t\t\tstderr: result.stderr,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tconst parsed = parseDeployOutput(result.stdout);\n\t\tif (!parsed) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\twalrusPluginError(\n\t\t\t\t\t'deploy',\n\t\t\t\t\t`walrus deploy: parser could not find walrus_package_id / system_object / staking_object ` +\n\t\t\t\t\t\t`in deploy output. Confirm the walrus binary's output format and adjust ` +\n\t\t\t\t\t\t`\\`parseDeployOutput\\` regexes in deploy.ts. ` +\n\t\t\t\t\t\t`SEAM: see deploy.ts header for the expected format.`,\n\t\t\t\t\t{ stdout: result.stdout, stderr: result.stderr },\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\treturn parsed;\n\t}).pipe(\n\t\tEffect.withSpan('devstack.plugin.walrus.deploy.oneShot', {\n\t\t\tattributes: {\n\t\t\t\t[WalrusSpans.committeeSize]: inputs.committeeSize,\n\t\t\t\t[WalrusSpans.shards]: inputs.shards,\n\t\t\t},\n\t\t}),\n\t\tEffect.timeoutOrElse({\n\t\t\tduration: Duration.millis(DEPLOY_TIMEOUT_MS + 5_000),\n\t\t\torElse: () =>\n\t\t\t\tEffect.fail(\n\t\t\t\t\twalrusPluginError(\n\t\t\t\t\t\t'deploy',\n\t\t\t\t\t\t`walrus deploy: outer timeout ${DEPLOY_TIMEOUT_MS}ms exceeded`,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t}),\n\t);\n\n/** Outputs of one deploy round — surfaced to the plugin's\n * resolved value. */\nexport interface DeployOutputs {\n\treadonly state: CachedDeployState;\n}\n\n/** Compose the ArtifactSpec for a walrus deploy and dispatch\n * through the substrate primitive. The publisher handles the full\n * cache/verify/produce/register loop.\n *\n * Produce: real wiring — `runDeployOneShot` runs\n * `docker run --rm walrusImage deploy …` and parses the deploy stdout.\n *\n * The substrate's `ArtifactPublisher.publish` returns the full\n * `CachedDeployState` on EVERY path (decoded cached payload on hit,\n * fresh produce on miss) — no projection dance required. */\nexport const deployWalrusContracts = (\n\tpublisher: ArtifactPublisher,\n\tprobe: ChainProbe<SuiProbeKey>,\n\truntime: ContainerRuntime,\n\tinputs: DeployInputs,\n): Effect.Effect<DeployOutputs, WalrusPluginError | ArtifactPublishError, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst state = yield* publisher.publish<CachedDeployState, WalrusDeployVerified>({\n\t\t\tnamespace: 'walrus-deploy',\n\t\t\tchain: inputs.chainId,\n\t\t\tcontentHash: inputs.contentHash,\n\t\t\t// Verify: lenient probes of the cached system + staking\n\t\t\t// objects. The Sui chain probe decodes raw `getObject`\n\t\t\t// responses, so the probe schema matches that envelope and\n\t\t\t// this closure returns the compact verified shape.\n\t\t\tverify: (cached) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tif (!(yield* deployOutputFilesComplete(inputs))) return null;\n\n\t\t\t\t\t// Both cached on-chain objects are independent lenient\n\t\t\t\t\t// probes — fan them out via `probeManyLenient` so the\n\t\t\t\t\t// substrate owns the iteration shape. Any null means\n\t\t\t\t\t// \"re-deploy\"; both non-null gives us the composite\n\t\t\t\t\t// verified payload. Retry across the post-restore\n\t\t\t\t\t// validator-readiness window (see the retry constants above)\n\t\t\t\t\t// so a transient not-found doesn't force a spurious redeploy.\n\t\t\t\t\tconst probeBoth = probeManyLenient([\n\t\t\t\t\t\tprobe.get(\n\t\t\t\t\t\t\t{ kind: 'object', objectId: cached.systemObject },\n\t\t\t\t\t\t\tSuiObjectExistsShape,\n\t\t\t\t\t\t\t'lenient',\n\t\t\t\t\t\t),\n\t\t\t\t\t\tprobe.get(\n\t\t\t\t\t\t\t{ kind: 'object', objectId: cached.stakingObject },\n\t\t\t\t\t\t\tSuiObjectExistsShape,\n\t\t\t\t\t\t\t'lenient',\n\t\t\t\t\t\t),\n\t\t\t\t\t]);\n\t\t\t\t\tlet [system, staking] = yield* probeBoth;\n\t\t\t\t\tfor (\n\t\t\t\t\t\tlet attempt = 0;\n\t\t\t\t\t\t(system == null || staking == null) && attempt < WALRUS_DEPLOY_VERIFY_READINESS_RETRIES;\n\t\t\t\t\t\tattempt++\n\t\t\t\t\t) {\n\t\t\t\t\t\tyield* Effect.sleep(WALRUS_DEPLOY_VERIFY_READINESS_DELAY);\n\t\t\t\t\t\t[system, staking] = yield* probeBoth;\n\t\t\t\t\t}\n\t\t\t\t\tif (system === undefined || system === null) return null;\n\t\t\t\t\tif (staking === undefined || staking === null) return null;\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsystemObjectId: system.objectId,\n\t\t\t\t\t\tstakingObjectId: staking.objectId,\n\t\t\t\t\t} satisfies WalrusDeployVerified;\n\t\t\t\t}).pipe(\n\t\t\t\t\t// `verify` must satisfy `Effect<… | null, never>` per\n\t\t\t\t\t// the publisher contract. Narrow the cache-miss\n\t\t\t\t\t// collapse to genuine cache-corruption signals\n\t\t\t\t\t// (`decode-failed`) and missing-registration\n\t\t\t\t\t// (`no-probe-registered`). The lenient probe already\n\t\t\t\t\t// maps `not-found`/`transient` to `null`, so the\n\t\t\t\t\t// remaining ChainProbeError values that reach here\n\t\t\t\t\t// are authoritative — `decode-failed` is stale shape\n\t\t\t\t\t// (re-produce) and `no-probe-registered` means the\n\t\t\t\t\t// plugin booted before the chain probe was\n\t\t\t\t\t// contributed (treat as miss). Anything else is a\n\t\t\t\t\t// real RPC failure we want visible in the logs\n\t\t\t\t\t// rather than silently collapsed to \"re-deploy\".\n\t\t\t\t\tEffect.catchTag('ChainProbeError', (err) => {\n\t\t\t\t\t\tif (err.reason === 'decode-failed' || err.reason === 'no-probe-registered') {\n\t\t\t\t\t\t\treturn Effect.succeed(null as WalrusDeployVerified | null);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn Effect.logWarning(\n\t\t\t\t\t\t\t`walrus.deploy verify probe surfaced an authoritative error (` +\n\t\t\t\t\t\t\t\t`reason=${err.reason}, chain=${err.chain}, detail=${err.detail}); ` +\n\t\t\t\t\t\t\t\t`re-deploying.`,\n\t\t\t\t\t\t).pipe(Effect.as(null as WalrusDeployVerified | null));\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t// Produce: real walrus-deploy one-shot.\n\t\t\tproduce: runDeployOneShot(runtime, inputs).pipe(\n\t\t\t\tEffect.mapError(\n\t\t\t\t\t(err): ArtifactPublishError =>\n\t\t\t\t\t\tartifactPublishError('produce-failed', `walrus.deploy ${err.phase}: ${err.message}`),\n\t\t\t\t),\n\t\t\t),\n\t\t\t// Register: fires on EVERY cycle. The plugin's outer body\n\t\t\t// performs the walrus-state / endpoint / package registry\n\t\t\t// publishes after both deploy + storage-nodes are up; this\n\t\t\t// closure is the publisher-side null-op so the substrate\n\t\t\t// satisfies its Invariant-6 contract.\n\t\t\tregister: () => Effect.void,\n\t\t});\n\n\t\treturn { state };\n\t}).pipe(\n\t\tEffect.withSpan('devstack.plugin.walrus.deploy', {\n\t\t\tattributes: { [WalrusSpans.name]: inputs.walrusName, [WalrusSpans.chain]: inputs.chainId },\n\t\t}),\n\t);\n"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import "../../substrate/runtime/mode-errors.mjs";
1
2
  import { defineConfigError } from "../../substrate/runtime/config-validation.mjs";
2
3
  //#region src/plugins/walrus/errors.ts
3
4
  const walrusPluginError = (phase, message, parts = {}) => ({
@@ -1 +1 @@
1
- {"version":3,"file":"errors.mjs","names":[],"sources":["../../../src/plugins/walrus/errors.ts"],"sourcesContent":["// Walrus plugin — typed errors.\n//\n// Errors raised and consumed inside the Walrus plugin live here.\n// Cross-service errors that Walrus *consumes* but the substrate\n// raises (e.g. `ArtifactPublishError`) come from the substrate's\n// primitive — we don't redeclare those.\n//\n// `ForkIncompatibleError` is a cross-cutting mode-refusal shape\n// owned by `substrate/runtime/mode-errors.ts`; walrus contributes\n// the `walrusLocalCluster` variant via the factory below.\n//\n// Effect v4: plain interfaces with `_tag` discriminator (per\n// surrounding subsystem style). `Effect.catchTag` matches on `_tag`.\n\nimport { ForkIncompatibleError } from '../../substrate/runtime/mode-errors.ts';\nimport { defineConfigError, type ConfigIssue } from '../../substrate/runtime/config-validation.ts';\n\nexport { ForkIncompatibleError };\n\n/** Phases for `WalrusError`. Closed sum — keeps the cause-walker's\n * display table small. Matches the closed `WalrusPhases` from the\n * distilled doc §\"Cross-component references\" except `'network'`\n * is dropped (the substrate's `ContainerRuntime` owns docker network\n * creation now, so its errors surface as `ContainerRuntimeError`\n * upstream — we narrate the *phase* as `'cluster-network'` but the\n * fault tags through the substrate). */\nexport type WalrusPhase =\n\t| 'image-build'\n\t| 'cluster-network'\n\t| 'deploy'\n\t| 'exchange'\n\t| 'storage-node'\n\t| 'proxy'\n\t| 'fund-wal'\n\t| 'register-known';\n\n/** Generic Walrus plugin error. Raised by the plugin's acquire\n * body, WAL funding strategy, and the per-mode builders. */\nexport interface WalrusPluginError {\n\treadonly _tag: 'WalrusPluginError';\n\treadonly phase: WalrusPhase;\n\treadonly message: string;\n\treadonly cause?: unknown;\n\t/** Optional sub-process capture envelope — populated for deploy\n\t * one-shot + per-node container failures. */\n\treadonly stderr?: string;\n\treadonly stdout?: string;\n\treadonly exitCode?: number;\n}\n\nexport const walrusPluginError = (\n\tphase: WalrusPhase,\n\tmessage: string,\n\tparts: Omit<WalrusPluginError, '_tag' | 'phase' | 'message'> = {},\n): WalrusPluginError => ({ _tag: 'WalrusPluginError', phase, message, ...parts });\n\n/**\n * Synchronous factory-time refusal when the user explicitly composes\n * the local-cluster mode against a fork network.\n *\n * sui-fork doesn't expose JSON-RPC; the local cluster's storage\n * nodes need JSON-RPC against the chain. Letting the supervisor\n * partway through the image build before the nodes fail to dial\n * would be confusing — we refuse synchronously at factory time\n * with an actionable hint pointing at `walrusFor(network).known({...})`.\n *\n * Primary refusal is TYPE-LEVEL via the `walrusFor(network).<mode>`\n * mode-narrowed namespace — fork networks expose only `.known`, so\n * calling `.local` is a compile error. This runtime shape is\n * defense-in-depth for callers that sneak through dynamic dispatch.\n */\nexport const forkIncompatibleError = (network: string): ForkIncompatibleError =>\n\tnew ForkIncompatibleError({\n\t\tvariant: 'walrusLocalCluster',\n\t\tnetwork,\n\t\tmessage: `walrus local-cluster does not support fork networks.`,\n\t\thint:\n\t\t\t`walrus local-cluster requires JSON-RPC, which sui-fork does not expose. ` +\n\t\t\t`Use walrusFor(network).known({...}) instead.`,\n\t});\n\n/** Configuration error — synchronous factory-time guards\n * (`nodeCount >= 1`, `shards >= nodeCount`, missing required\n * fields on `.known(...)`). Surfaces as a thrown `Error` shaped\n * like this in the factory, mirroring the distilled-doc behavior\n * of synchronous configuration faults. */\nexport interface WalrusConfigError extends ConfigIssue {\n\treadonly _tag: 'WalrusConfigError';\n}\n\nconst makeWalrusConfigError = defineConfigError('WalrusConfigError');\n\nexport const walrusConfigError = (\n\tfield: string,\n\tmessage: string,\n\thint?: string,\n\tcause?: unknown,\n): WalrusConfigError => makeWalrusConfigError({ field, message, hint, cause });\n\n/** Union of every error a Walrus-plugin caller may encounter. */\nexport type WalrusError = WalrusPluginError | ForkIncompatibleError | WalrusConfigError;\n\n/** Error tags this plugin contributes — surfaced to the cause\n * walker via `PluginErrorContribution`. */\nexport const WALRUS_ERROR_TAGS: ReadonlyArray<WalrusError['_tag']> = [\n\t'WalrusPluginError',\n\t'ForkIncompatibleError',\n\t'WalrusConfigError',\n] as const;\n"],"mappings":";;AAkDA,MAAa,qBACZ,OACA,SACA,QAA+D,EAAE,MACzC;CAAE,MAAM;CAAqB;CAAO;CAAS,GAAG;CAAO;AAoChF,MAAM,wBAAwB,kBAAkB,oBAAoB;AAEpE,MAAa,qBACZ,OACA,SACA,MACA,UACuB,sBAAsB;CAAE;CAAO;CAAS;CAAM;CAAO,CAAC;;;AAO9E,MAAa,oBAAwD;CACpE;CACA;CACA;CACA"}
1
+ {"version":3,"file":"errors.mjs","names":[],"sources":["../../../src/plugins/walrus/errors.ts"],"sourcesContent":["// Walrus plugin — typed errors.\n//\n// Errors raised and consumed inside the Walrus plugin live here.\n// Cross-service errors that Walrus *consumes* but the substrate\n// raises (e.g. `ArtifactPublishError`) come from the substrate's\n// primitive — we don't redeclare those.\n//\n// `ForkIncompatibleError` is a cross-cutting mode-refusal shape\n// owned by `substrate/runtime/mode-errors.ts`; walrus contributes\n// the `walrusLocalCluster` variant via the factory below.\n//\n// Effect v4: plain interfaces with `_tag` discriminator (per\n// surrounding subsystem style). `Effect.catchTag` matches on `_tag`.\n\nimport { ForkIncompatibleError } from '../../substrate/runtime/mode-errors.ts';\nimport { defineConfigError, type ConfigIssue } from '../../substrate/runtime/config-validation.ts';\n\nexport { ForkIncompatibleError };\n\n/** Phases for `WalrusError`. Closed sum — keeps the cause-walker's\n * display table small. Matches the closed `WalrusPhases` from the\n * distilled doc §\"Cross-component references\" except `'network'`\n * is dropped (the substrate's `ContainerRuntime` owns docker network\n * creation now, so its errors surface as `ContainerRuntimeError`\n * upstream — we narrate the *phase* as `'cluster-network'` but the\n * fault tags through the substrate). */\nexport type WalrusPhase =\n\t| 'image-build'\n\t| 'cluster-network'\n\t| 'deploy'\n\t| 'exchange'\n\t| 'storage-node'\n\t| 'proxy'\n\t| 'fund-wal'\n\t| 'register-known';\n\n/** Generic Walrus plugin error. Raised by the plugin's acquire\n * body, WAL funding strategy, and the per-mode builders. */\nexport interface WalrusPluginError {\n\treadonly _tag: 'WalrusPluginError';\n\treadonly phase: WalrusPhase;\n\treadonly message: string;\n\treadonly cause?: unknown;\n\t/** Optional sub-process capture envelope — populated for deploy\n\t * one-shot + per-node container failures. */\n\treadonly stderr?: string;\n\treadonly stdout?: string;\n\treadonly exitCode?: number;\n}\n\nexport const walrusPluginError = (\n\tphase: WalrusPhase,\n\tmessage: string,\n\tparts: Omit<WalrusPluginError, '_tag' | 'phase' | 'message'> = {},\n): WalrusPluginError => ({ _tag: 'WalrusPluginError', phase, message, ...parts });\n\n/** Configuration error — synchronous factory-time guards\n * (`nodeCount >= 1`, `shards >= nodeCount`, missing required\n * fields on `.known(...)`). Surfaces as a thrown `Error` shaped\n * like this in the factory, mirroring the distilled-doc behavior\n * of synchronous configuration faults. */\nexport interface WalrusConfigError extends ConfigIssue {\n\treadonly _tag: 'WalrusConfigError';\n}\n\nconst makeWalrusConfigError = defineConfigError('WalrusConfigError');\n\nexport const walrusConfigError = (\n\tfield: string,\n\tmessage: string,\n\thint?: string,\n\tcause?: unknown,\n): WalrusConfigError => makeWalrusConfigError({ field, message, hint, cause });\n\n/** Union of every error a Walrus-plugin caller may encounter. */\nexport type WalrusError = WalrusPluginError | ForkIncompatibleError | WalrusConfigError;\n\n/** Error tags this plugin contributes — surfaced to the cause\n * walker via `PluginErrorContribution`. */\nexport const WALRUS_ERROR_TAGS: ReadonlyArray<WalrusError['_tag']> = [\n\t'WalrusPluginError',\n\t'ForkIncompatibleError',\n\t'WalrusConfigError',\n] as const;\n"],"mappings":";;;AAkDA,MAAa,qBACZ,OACA,SACA,QAA+D,EAAE,MACzC;CAAE,MAAM;CAAqB;CAAO;CAAS,GAAG;CAAO;AAWhF,MAAM,wBAAwB,kBAAkB,oBAAoB;AAEpE,MAAa,qBACZ,OACA,SACA,MACA,UACuB,sBAAsB;CAAE;CAAO;CAAS;CAAM;CAAO,CAAC;;;AAO9E,MAAa,oBAAwD;CACpE;CACA;CACA;CACA"}
@@ -48,13 +48,18 @@ const walFaucetStrategyKey = (fullCoinType) => `coinType:${fullCoinType}`;
48
48
  * strategy is invoked; the guard here keeps direct calls no-op. */
49
49
  const makeWalFaucetStrategy = (opts) => ({
50
50
  usesAccountSigner: true,
51
- request: (req) => req.amount <= 0n ? Effect.void : swapAccountSuiForWal({
52
- account: req.account,
53
- sdk: opts.sdk,
54
- exchange: opts.exchange,
55
- recipientAddress: req.address,
56
- paymentMist: req.amount
57
- }).pipe(Effect.asVoid)
51
+ requiresRecipientAccount: true,
52
+ request: (req) => {
53
+ if (req.amount <= 0n) return Effect.void;
54
+ if (req.account === void 0) return Effect.fail(walrusPluginError("fund-wal", "walrus WAL funding spends the recipient account’s own SUI, so it requires a resolved account signer."));
55
+ return swapAccountSuiForWal({
56
+ account: req.account,
57
+ sdk: opts.sdk,
58
+ exchange: opts.exchange,
59
+ recipientAddress: req.address,
60
+ paymentMist: req.amount
61
+ }).pipe(Effect.asVoid);
62
+ }
58
63
  });
59
64
  //#endregion
60
65
  export { makeWalFaucetStrategy, resolveWalCoinType, walCoinType, walFaucetStrategyKey, walPackageIdFromCoinType };
@@ -1 +1 @@
1
- {"version":3,"file":"faucet-strategy.mjs","names":[],"sources":["../../../src/plugins/walrus/faucet-strategy.ts"],"sourcesContent":["// Walrus WAL faucet strategy.\n//\n// Distilled-doc reference (06-walrus.md §\"Lifecycle phase 7a\"):\n// when the local cluster has a non-empty `exchange`, walrus registers\n// a WAL exchange strategy on the global strategy registry so any\n// `account('alice', { funding: [{ coin: wal, amount }] })` request\n// gets satisfied via SUI → WAL swap on chain.\n//\n// Architecture (StrategyContributor §7): the faucet registry is\n// `capabilityKey: 'coinType:<fullCoinType>'` (distilled-doc\n// convention shared with the faucet plugin's domain:discriminator\n// pattern). The dispatch site doesn't import this strategy — it\n// looks it up by key.\n//\nimport { Effect, Schema } from 'effect';\n\nimport type { ChainProbe } from '../../contracts/chain-probe.ts';\nimport type { StrategyContributorDecl } from '../../contracts/strategy-contributor.ts';\nimport type { AccountFundingRequest, AccountFundingStrategy } from '../account/index.ts';\nimport { walrusPluginError, type WalrusPluginError } from './errors.ts';\nimport type { WalExchangeProbeKey } from './wal-swap.ts';\nimport { swapAccountSuiForWal, type WalExchangeHandle, type WalSwapSdk } from './wal-swap.ts';\n\n/** Full local WAL coin type derived from the deployed Walrus package. */\nexport const walCoinType = <PackageId extends string>(\n\tpackageId: PackageId,\n): `${PackageId}::wal::WAL` => `${packageId}::wal::WAL` as const;\n\n/** Resolve the package id that defines `wal::WAL`.\n *\n * The Walrus deploy summary's `package_id` can be the latest upgraded\n * Walrus package, while Sui coin types use the original package id\n * that defines `wal::WAL`. The protected treasury object is the\n * reliable on-chain anchor for that original id. */\nexport const parseWalCoinTypeFromTreasuryType = (\n\ttreasuryType: string,\n): `${string}::wal::WAL` | null => {\n\tconst protectedTreasury = /^(0x[0-9a-fA-F]+)::wal::ProtectedTreasury$/.exec(treasuryType);\n\tif (protectedTreasury?.[1] !== undefined) {\n\t\treturn walCoinType(protectedTreasury[1]);\n\t}\n\n\tconst treasuryCap = /^0x(?:0+)?2::coin::TreasuryCap<((0x[0-9a-fA-F]+)::wal::WAL)>$/.exec(\n\t\ttreasuryType,\n\t);\n\tif (treasuryCap?.[1] !== undefined) {\n\t\treturn treasuryCap[1] as `${string}::wal::WAL`;\n\t}\n\n\treturn null;\n};\n\nexport const walPackageIdFromCoinType = (fullCoinType: `${string}::wal::WAL`): string =>\n\tfullCoinType.split('::')[0]!;\n\nconst WalTreasuryObjectShape = Schema.Struct({\n\tobjectId: Schema.String,\n\ttype: Schema.String,\n});\n\nexport const resolveWalCoinType = (args: {\n\treadonly probe: ChainProbe<WalExchangeProbeKey>;\n\treadonly treasuryObjectId: string | undefined;\n\treadonly deployPackageId: string;\n\treadonly requireTreasuryObject: boolean;\n}): Effect.Effect<`${string}::wal::WAL`, WalrusPluginError> =>\n\tEffect.gen(function* () {\n\t\tif (args.treasuryObjectId === undefined) {\n\t\t\tif (!args.requireTreasuryObject) return walCoinType(args.deployPackageId);\n\t\t\treturn yield* Effect.fail(\n\t\t\t\twalrusPluginError(\n\t\t\t\t\t'exchange',\n\t\t\t\t\t'walrus.exchange: WAL exchange funding requires treasury_object in walrus deploy output so the original WAL coin type can be resolved.',\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tconst found = yield* args.probe\n\t\t\t.get({ kind: 'object', objectId: args.treasuryObjectId }, WalTreasuryObjectShape, 'lenient')\n\t\t\t.pipe(\n\t\t\t\tEffect.mapError((cause) =>\n\t\t\t\t\twalrusPluginError(\n\t\t\t\t\t\t'exchange',\n\t\t\t\t\t\t`walrus.exchange: failed to resolve WAL treasury object ${args.treasuryObjectId}: ${cause.reason}: ${cause.detail}`,\n\t\t\t\t\t\t{ cause },\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\n\t\tif (found === null) {\n\t\t\tif (!args.requireTreasuryObject) return walCoinType(args.deployPackageId);\n\t\t\treturn yield* Effect.fail(\n\t\t\t\twalrusPluginError(\n\t\t\t\t\t'exchange',\n\t\t\t\t\t`walrus.exchange: WAL treasury object ${args.treasuryObjectId} was not found; cannot derive the WAL coin type for account funding.`,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tconst parsed = parseWalCoinTypeFromTreasuryType(found.type);\n\t\tif (parsed !== null) return parsed;\n\n\t\treturn yield* Effect.fail(\n\t\t\twalrusPluginError(\n\t\t\t\t'exchange',\n\t\t\t\t`walrus.exchange: unexpected WAL treasury object type \"${found.type}\" — expected \"<pkg>::wal::ProtectedTreasury\" or \"0x2::coin::TreasuryCap<<pkg>::wal::WAL>\".`,\n\t\t\t),\n\t\t);\n\t});\n\n/** Capability key for the WAL faucet strategy. */\nexport const walFaucetStrategyKey = <FullCoinType extends string>(\n\tfullCoinType: FullCoinType,\n): `coinType:${FullCoinType}` => `coinType:${fullCoinType}` as const;\n\n/** Per-request shape — the shared account funding request. */\nexport type WalFaucetRequest = AccountFundingRequest;\n\n/** Faucet strategy value — closed over the WAL exchange's object id.\n * The requesting account signs the swap through the shared account\n * funding pipeline. */\nexport type WalFaucetStrategy = AccountFundingStrategy<WalrusPluginError>;\n\n/** Inputs the local-cluster mode passes when constructing this. */\nexport interface WalFaucetStrategyOptions {\n\treadonly exchange: WalExchangeHandle;\n\treadonly sdk: WalSwapSdk;\n}\n\n/** Build the strategy value.\n *\n * The request amount is the SUI MIST amount to spend on the local\n * exchange for WAL. Account funding skips zero amounts before the\n * strategy is invoked; the guard here keeps direct calls no-op. */\nexport const makeWalFaucetStrategy = (opts: WalFaucetStrategyOptions): WalFaucetStrategy => ({\n\tusesAccountSigner: true,\n\trequest: (req) =>\n\t\treq.amount <= 0n\n\t\t\t? Effect.void\n\t\t\t: swapAccountSuiForWal({\n\t\t\t\t\taccount: req.account,\n\t\t\t\t\tsdk: opts.sdk,\n\t\t\t\t\texchange: opts.exchange,\n\t\t\t\t\trecipientAddress: req.address,\n\t\t\t\t\tpaymentMist: req.amount,\n\t\t\t\t}).pipe(Effect.asVoid),\n});\n\n/** Build the StrategyContributor decl. The faucet plugin's\n * dispatcher reads this key off the registry and dispatches WAL\n * funding requests through it. */\nexport const makeWalFaucetContribution = (\n\tfullCoinType: string,\n\topts: WalFaucetStrategyOptions,\n): StrategyContributorDecl<ReturnType<typeof walFaucetStrategyKey>, WalFaucetStrategy> => ({\n\tkind: 'strategy-contributor',\n\tcapabilityKey: walFaucetStrategyKey(fullCoinType),\n\tstrategy: makeWalFaucetStrategy(opts),\n\tautoMounted: true,\n});\n"],"mappings":";;;;;AAwBA,MAAa,eACZ,cAC8B,GAAG,UAAU;;;;;;;AAQ5C,MAAa,oCACZ,iBACkC;CAClC,MAAM,oBAAoB,6CAA6C,KAAK,aAAa;AACzF,KAAI,oBAAoB,OAAO,KAAA,EAC9B,QAAO,YAAY,kBAAkB,GAAG;CAGzC,MAAM,cAAc,gEAAgE,KACnF,aACA;AACD,KAAI,cAAc,OAAO,KAAA,EACxB,QAAO,YAAY;AAGpB,QAAO;;AAGR,MAAa,4BAA4B,iBACxC,aAAa,MAAM,KAAK,CAAC;AAE1B,MAAM,yBAAyB,OAAO,OAAO;CAC5C,UAAU,OAAO;CACjB,MAAM,OAAO;CACb,CAAC;AAEF,MAAa,sBAAsB,SAMlC,OAAO,IAAI,aAAa;AACvB,KAAI,KAAK,qBAAqB,KAAA,GAAW;AACxC,MAAI,CAAC,KAAK,sBAAuB,QAAO,YAAY,KAAK,gBAAgB;AACzE,SAAO,OAAO,OAAO,KACpB,kBACC,YACA,wIACA,CACD;;CAGF,MAAM,QAAQ,OAAO,KAAK,MACxB,IAAI;EAAE,MAAM;EAAU,UAAU,KAAK;EAAkB,EAAE,wBAAwB,UAAU,CAC3F,KACA,OAAO,UAAU,UAChB,kBACC,YACA,0DAA0D,KAAK,iBAAiB,IAAI,MAAM,OAAO,IAAI,MAAM,UAC3G,EAAE,OAAO,CACT,CACD,CACD;AAEF,KAAI,UAAU,MAAM;AACnB,MAAI,CAAC,KAAK,sBAAuB,QAAO,YAAY,KAAK,gBAAgB;AACzE,SAAO,OAAO,OAAO,KACpB,kBACC,YACA,wCAAwC,KAAK,iBAAiB,sEAC9D,CACD;;CAGF,MAAM,SAAS,iCAAiC,MAAM,KAAK;AAC3D,KAAI,WAAW,KAAM,QAAO;AAE5B,QAAO,OAAO,OAAO,KACpB,kBACC,YACA,yDAAyD,MAAM,KAAK,4FACpE,CACD;EACA;;AAGH,MAAa,wBACZ,iBACgC,YAAY;;;;;;AAqB7C,MAAa,yBAAyB,UAAuD;CAC5F,mBAAmB;CACnB,UAAU,QACT,IAAI,UAAU,KACX,OAAO,OACP,qBAAqB;EACrB,SAAS,IAAI;EACb,KAAK,KAAK;EACV,UAAU,KAAK;EACf,kBAAkB,IAAI;EACtB,aAAa,IAAI;EACjB,CAAC,CAAC,KAAK,OAAO,OAAO;CACzB"}
1
+ {"version":3,"file":"faucet-strategy.mjs","names":[],"sources":["../../../src/plugins/walrus/faucet-strategy.ts"],"sourcesContent":["// Walrus WAL faucet strategy.\n//\n// Distilled-doc reference (06-walrus.md §\"Lifecycle phase 7a\"):\n// when the local cluster has a non-empty `exchange`, walrus registers\n// a WAL exchange strategy on the global strategy registry so any\n// `account('alice', { funding: [{ coin: wal, amount }] })` request\n// gets satisfied via SUI → WAL swap on chain.\n//\n// Architecture (StrategyContributor §7): the faucet registry is\n// `capabilityKey: 'coinType:<fullCoinType>'` (distilled-doc\n// convention shared with the faucet plugin's domain:discriminator\n// pattern). The dispatch site doesn't import this strategy — it\n// looks it up by key.\n//\nimport { Effect, Schema } from 'effect';\n\nimport type { ChainProbe } from '../../contracts/chain-probe.ts';\nimport type { AccountFundingRequest, AccountFundingStrategy } from '../account/index.ts';\nimport { walrusPluginError, type WalrusPluginError } from './errors.ts';\nimport type { WalExchangeProbeKey } from './wal-swap.ts';\nimport { swapAccountSuiForWal, type WalExchangeHandle, type WalSwapSdk } from './wal-swap.ts';\n\n/** Full local WAL coin type derived from the deployed Walrus package. */\nexport const walCoinType = <PackageId extends string>(\n\tpackageId: PackageId,\n): `${PackageId}::wal::WAL` => `${packageId}::wal::WAL` as const;\n\n/** Resolve the package id that defines `wal::WAL`.\n *\n * The Walrus deploy summary's `package_id` can be the latest upgraded\n * Walrus package, while Sui coin types use the original package id\n * that defines `wal::WAL`. The protected treasury object is the\n * reliable on-chain anchor for that original id. */\nexport const parseWalCoinTypeFromTreasuryType = (\n\ttreasuryType: string,\n): `${string}::wal::WAL` | null => {\n\tconst protectedTreasury = /^(0x[0-9a-fA-F]+)::wal::ProtectedTreasury$/.exec(treasuryType);\n\tif (protectedTreasury?.[1] !== undefined) {\n\t\treturn walCoinType(protectedTreasury[1]);\n\t}\n\n\tconst treasuryCap = /^0x(?:0+)?2::coin::TreasuryCap<((0x[0-9a-fA-F]+)::wal::WAL)>$/.exec(\n\t\ttreasuryType,\n\t);\n\tif (treasuryCap?.[1] !== undefined) {\n\t\treturn treasuryCap[1] as `${string}::wal::WAL`;\n\t}\n\n\treturn null;\n};\n\nexport const walPackageIdFromCoinType = (fullCoinType: `${string}::wal::WAL`): string =>\n\tfullCoinType.split('::')[0]!;\n\nconst WalTreasuryObjectShape = Schema.Struct({\n\tobjectId: Schema.String,\n\ttype: Schema.String,\n});\n\nexport const resolveWalCoinType = (args: {\n\treadonly probe: ChainProbe<WalExchangeProbeKey>;\n\treadonly treasuryObjectId: string | undefined;\n\treadonly deployPackageId: string;\n\treadonly requireTreasuryObject: boolean;\n}): Effect.Effect<`${string}::wal::WAL`, WalrusPluginError> =>\n\tEffect.gen(function* () {\n\t\tif (args.treasuryObjectId === undefined) {\n\t\t\tif (!args.requireTreasuryObject) return walCoinType(args.deployPackageId);\n\t\t\treturn yield* Effect.fail(\n\t\t\t\twalrusPluginError(\n\t\t\t\t\t'exchange',\n\t\t\t\t\t'walrus.exchange: WAL exchange funding requires treasury_object in walrus deploy output so the original WAL coin type can be resolved.',\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tconst found = yield* args.probe\n\t\t\t.get({ kind: 'object', objectId: args.treasuryObjectId }, WalTreasuryObjectShape, 'lenient')\n\t\t\t.pipe(\n\t\t\t\tEffect.mapError((cause) =>\n\t\t\t\t\twalrusPluginError(\n\t\t\t\t\t\t'exchange',\n\t\t\t\t\t\t`walrus.exchange: failed to resolve WAL treasury object ${args.treasuryObjectId}: ${cause.reason}: ${cause.detail}`,\n\t\t\t\t\t\t{ cause },\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\n\t\tif (found === null) {\n\t\t\tif (!args.requireTreasuryObject) return walCoinType(args.deployPackageId);\n\t\t\treturn yield* Effect.fail(\n\t\t\t\twalrusPluginError(\n\t\t\t\t\t'exchange',\n\t\t\t\t\t`walrus.exchange: WAL treasury object ${args.treasuryObjectId} was not found; cannot derive the WAL coin type for account funding.`,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tconst parsed = parseWalCoinTypeFromTreasuryType(found.type);\n\t\tif (parsed !== null) return parsed;\n\n\t\treturn yield* Effect.fail(\n\t\t\twalrusPluginError(\n\t\t\t\t'exchange',\n\t\t\t\t`walrus.exchange: unexpected WAL treasury object type \"${found.type}\" — expected \"<pkg>::wal::ProtectedTreasury\" or \"0x2::coin::TreasuryCap<<pkg>::wal::WAL>\".`,\n\t\t\t),\n\t\t);\n\t});\n\n/** Capability key for the WAL faucet strategy. */\nexport const walFaucetStrategyKey = <FullCoinType extends string>(\n\tfullCoinType: FullCoinType,\n): `coinType:${FullCoinType}` => `coinType:${fullCoinType}` as const;\n\n/** Per-request shape — the shared account funding request. */\nexport type WalFaucetRequest = AccountFundingRequest;\n\n/** Faucet strategy value — closed over the WAL exchange's object id.\n * The requesting account signs the swap through the shared account\n * funding pipeline. */\nexport type WalFaucetStrategy = AccountFundingStrategy<WalrusPluginError>;\n\n/** Inputs the local-cluster mode passes when constructing this. */\nexport interface WalFaucetStrategyOptions {\n\treadonly exchange: WalExchangeHandle;\n\treadonly sdk: WalSwapSdk;\n}\n\n/** Build the strategy value.\n *\n * The request amount is the SUI MIST amount to spend on the local\n * exchange for WAL. Account funding skips zero amounts before the\n * strategy is invoked; the guard here keeps direct calls no-op. */\nexport const makeWalFaucetStrategy = (opts: WalFaucetStrategyOptions): WalFaucetStrategy => ({\n\tusesAccountSigner: true,\n\t// The swap buys WAL with the recipient account's own SUI, so the recipient\n\t// must be a resolved account with a signer — funding an arbitrary 0x address\n\t// is rejected by the dispatcher/dashboard on this flag.\n\trequiresRecipientAccount: true,\n\trequest: (req) => {\n\t\tif (req.amount <= 0n) return Effect.void;\n\t\tif (req.account === undefined) {\n\t\t\treturn Effect.fail(\n\t\t\t\twalrusPluginError(\n\t\t\t\t\t'fund-wal',\n\t\t\t\t\t'walrus WAL funding spends the recipient account’s own SUI, so it requires a resolved account signer.',\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\treturn swapAccountSuiForWal({\n\t\t\taccount: req.account,\n\t\t\tsdk: opts.sdk,\n\t\t\texchange: opts.exchange,\n\t\t\trecipientAddress: req.address,\n\t\t\tpaymentMist: req.amount,\n\t\t}).pipe(Effect.asVoid);\n\t},\n});\n"],"mappings":";;;;;AAuBA,MAAa,eACZ,cAC8B,GAAG,UAAU;;;;;;;AAQ5C,MAAa,oCACZ,iBACkC;CAClC,MAAM,oBAAoB,6CAA6C,KAAK,aAAa;AACzF,KAAI,oBAAoB,OAAO,KAAA,EAC9B,QAAO,YAAY,kBAAkB,GAAG;CAGzC,MAAM,cAAc,gEAAgE,KACnF,aACA;AACD,KAAI,cAAc,OAAO,KAAA,EACxB,QAAO,YAAY;AAGpB,QAAO;;AAGR,MAAa,4BAA4B,iBACxC,aAAa,MAAM,KAAK,CAAC;AAE1B,MAAM,yBAAyB,OAAO,OAAO;CAC5C,UAAU,OAAO;CACjB,MAAM,OAAO;CACb,CAAC;AAEF,MAAa,sBAAsB,SAMlC,OAAO,IAAI,aAAa;AACvB,KAAI,KAAK,qBAAqB,KAAA,GAAW;AACxC,MAAI,CAAC,KAAK,sBAAuB,QAAO,YAAY,KAAK,gBAAgB;AACzE,SAAO,OAAO,OAAO,KACpB,kBACC,YACA,wIACA,CACD;;CAGF,MAAM,QAAQ,OAAO,KAAK,MACxB,IAAI;EAAE,MAAM;EAAU,UAAU,KAAK;EAAkB,EAAE,wBAAwB,UAAU,CAC3F,KACA,OAAO,UAAU,UAChB,kBACC,YACA,0DAA0D,KAAK,iBAAiB,IAAI,MAAM,OAAO,IAAI,MAAM,UAC3G,EAAE,OAAO,CACT,CACD,CACD;AAEF,KAAI,UAAU,MAAM;AACnB,MAAI,CAAC,KAAK,sBAAuB,QAAO,YAAY,KAAK,gBAAgB;AACzE,SAAO,OAAO,OAAO,KACpB,kBACC,YACA,wCAAwC,KAAK,iBAAiB,sEAC9D,CACD;;CAGF,MAAM,SAAS,iCAAiC,MAAM,KAAK;AAC3D,KAAI,WAAW,KAAM,QAAO;AAE5B,QAAO,OAAO,OAAO,KACpB,kBACC,YACA,yDAAyD,MAAM,KAAK,4FACpE,CACD;EACA;;AAGH,MAAa,wBACZ,iBACgC,YAAY;;;;;;AAqB7C,MAAa,yBAAyB,UAAuD;CAC5F,mBAAmB;CAInB,0BAA0B;CAC1B,UAAU,QAAQ;AACjB,MAAI,IAAI,UAAU,GAAI,QAAO,OAAO;AACpC,MAAI,IAAI,YAAY,KAAA,EACnB,QAAO,OAAO,KACb,kBACC,YACA,uGACA,CACD;AAEF,SAAO,qBAAqB;GAC3B,SAAS,IAAI;GACb,KAAK,KAAK;GACV,UAAU,KAAK;GACf,kBAAkB,IAAI;GACtB,aAAa,IAAI;GACjB,CAAC,CAAC,KAAK,OAAO,OAAO;;CAEvB"}
@@ -1,16 +1,13 @@
1
1
  import { CodegenableDecl } from "../../contracts/codegenable.mjs";
2
- import { LivenessClassifierDecl } from "../../contracts/liveness-classifier.mjs";
3
2
  import { ProjectionDecl } from "../../contracts/projection.mjs";
4
3
  import { RoutableDecl } from "../../contracts/routable.mjs";
5
4
  import { SnapshotableDecl } from "../../contracts/snapshotable.mjs";
6
5
  import { StrategyContributorDecl } from "../../contracts/strategy-contributor.mjs";
7
6
  import { Plugin, ResourceRef } from "../../substrate/plugin.mjs";
8
7
  import { ModeNamespace } from "../../api/mode-narrowed-factory.mjs";
9
- import { SeedObjectsAccumulator } from "../sui/seed-objects.mjs";
10
8
  import { SuiClient } from "../sui/mode/shared.mjs";
11
9
  import { SuiOptions } from "../sui/mode/spec.mjs";
12
10
  import { AccountFundingCoinValue } from "../account/funding.mjs";
13
- import { ForkIncompatibleError } from "../../substrate/runtime/mode-errors.mjs";
14
11
  import { WalrusConfigError, WalrusError, WalrusPhase, WalrusPluginError } from "./errors.mjs";
15
12
  import { WalFaucetStrategy } from "./faucet-strategy.mjs";
16
13
  import { WalrusStorageNode } from "./storage-nodes.mjs";
@@ -62,9 +59,7 @@ declare const walCoin: (walrusMember: ResourceRef<"walrus", WalrusResolved>) =>
62
59
  readonly kind: "projection";
63
60
  } & Omit<ProjectionDecl, "kind">> | Readonly<{
64
61
  readonly kind: "strategy-contributor";
65
- } & Omit<StrategyContributorDecl<string, unknown>, "kind">> | Readonly<{
66
- readonly kind: "liveness-classifier";
67
- } & Omit<LivenessClassifierDecl, "kind">>) | Readonly<{
62
+ } & Omit<StrategyContributorDecl<string, unknown>, "kind">>) | Readonly<{
68
63
  readonly kind: string;
69
64
  } & object>)[]>;
70
65
  /** Local-cluster shorthand. Known deployments are selected through
@@ -73,7 +68,6 @@ declare const walrus: (opts?: {
73
68
  readonly local?: WalrusLocalClusterOptions;
74
69
  }) => Plugin<"walrus", WalrusResolved, readonly [ResourceRef<"sui", SuiClient & {
75
70
  readonly mode: SuiOptions["mode"];
76
- readonly seedObjects: SeedObjectsAccumulator;
77
71
  }>], readonly [SnapshotableDecl, CodegenableDecl<"walrus-network">, StrategyContributorDecl<"walrus-state-registry", {
78
72
  readonly noteName: string;
79
73
  }>, ...(RoutableDecl | {
@@ -91,13 +85,11 @@ declare const walrus: (opts?: {
91
85
  *
92
86
  * Critically, the fork branch exposes ONLY `.known` — calling
93
87
  * `.local` on a fork-mode network is a **compile error** at the
94
- * call site (distilled-doc invariant 12 — type-level refusal).
95
- * Runtime defense-in-depth: see `mode/fork-refusal.ts`. */
88
+ * call site (distilled-doc invariant 12 — type-level refusal). */
96
89
  declare const walrusFor: ModeNamespace<{
97
90
  local: {
98
91
  local: (opts?: WalrusLocalClusterOptions) => Plugin<"walrus", WalrusResolved, readonly [ResourceRef<"sui", SuiClient & {
99
92
  readonly mode: SuiOptions["mode"];
100
- readonly seedObjects: SeedObjectsAccumulator;
101
93
  }>], readonly [SnapshotableDecl, CodegenableDecl<"walrus-network">, StrategyContributorDecl<"walrus-state-registry", {
102
94
  readonly noteName: string;
103
95
  }>, ...(RoutableDecl | {
@@ -124,7 +116,6 @@ declare const walrusFor: ModeNamespace<{
124
116
  walCoinType: null;
125
117
  }, readonly [ResourceRef<"sui", SuiClient & {
126
118
  readonly mode: SuiOptions["mode"];
127
- readonly seedObjects: SeedObjectsAccumulator;
128
119
  }>], readonly [SnapshotableDecl, CodegenableDecl<"walrus-network">, StrategyContributorDecl<"walrus-state-registry", WalrusStateEntry>]>;
129
120
  };
130
121
  live: {
@@ -146,7 +137,6 @@ declare const walrusFor: ModeNamespace<{
146
137
  walCoinType: null;
147
138
  }, readonly [ResourceRef<"sui", SuiClient & {
148
139
  readonly mode: SuiOptions["mode"];
149
- readonly seedObjects: SeedObjectsAccumulator;
150
140
  }>], readonly [SnapshotableDecl, CodegenableDecl<"walrus-network">, StrategyContributorDecl<"walrus-state-registry", WalrusStateEntry>]>;
151
141
  };
152
142
  fork: {
@@ -168,7 +158,6 @@ declare const walrusFor: ModeNamespace<{
168
158
  walCoinType: null;
169
159
  }, readonly [ResourceRef<"sui", SuiClient & {
170
160
  readonly mode: SuiOptions["mode"];
171
- readonly seedObjects: SeedObjectsAccumulator;
172
161
  }>], readonly [SnapshotableDecl, CodegenableDecl<"walrus-network">, StrategyContributorDecl<"walrus-state-registry", WalrusStateEntry>]>;
173
162
  };
174
163
  }>;
@@ -1,15 +1,19 @@
1
1
  import { definePlugin, resource } from "../../substrate/plugin.mjs";
2
- import { pluginErrorContributions } from "../../api/plugin-errors.mjs";
2
+ import "../../api/define-plugin.mjs";
3
3
  import { IdentityContext, StackPathsService } from "../../substrate/runtime/paths.mjs";
4
- import { defineModeNamespace } from "../../api/mode-narrowed-factory.mjs";
5
4
  import { ContainerRuntimeService } from "../../runtime/docker/service.mjs";
6
- import { suiResource } from "../sui/index.mjs";
7
5
  import { ArtifactPublisherService } from "../../substrate/runtime/artifact-publisher/index.mjs";
8
6
  import { chainProbeFor } from "../../substrate/runtime/strategy-registry/chain-probe-for.mjs";
7
+ import "../../substrate/runtime/strategy-registry/index.mjs";
9
8
  import { WALRUS_ERROR_TAGS, walrusPluginError } from "./errors.mjs";
9
+ import "./spans.mjs";
10
10
  import { buildWalrusNetworkName } from "./storage-nodes.mjs";
11
11
  import { makeLocalRoutables } from "./routable.mjs";
12
+ import { pluginErrorContributions } from "../../api/plugin-errors.mjs";
13
+ import { defineModeNamespace } from "../../api/mode-narrowed-factory.mjs";
14
+ import { suiResource } from "../sui/index.mjs";
12
15
  import { coinResourceId } from "../coin/index.mjs";
16
+ import { deriveSubnetPrefix, withSubnetAddressing } from "../../substrate/runtime/subnet-broker.mjs";
13
17
  import { makeCodegenable } from "./codegen.mjs";
14
18
  import { walrusPluginKey } from "./plugin-key.mjs";
15
19
  import { walFaucetStrategyKey } from "./faucet-strategy.mjs";
@@ -26,25 +30,13 @@ const walrusErrorContributions = pluginErrorContributions(WALRUS_ERROR_TAGS);
26
30
  /** Walrus deploy records storage-node listening IPs under this /24.
27
31
  * Docker network create requests the matching subnet explicitly, with
28
32
  * the prefix derived from the Walrus network identity so parallel
29
- * stacks don't all claim the same Docker IPAM range. */
30
- const deriveWalrusSubnetPrefix = (identity) => {
31
- const key = `${identity.app}\0${identity.stack}\0${identity.walrusName}`;
32
- let hash = 2166136261;
33
- for (let i = 0; i < key.length; i += 1) {
34
- hash ^= key.charCodeAt(i);
35
- hash = Math.imul(hash, 16777619) >>> 0;
36
- }
37
- const bucket = hash % (64 * 256);
38
- return `10.${64 + Math.floor(bucket / 256)}.${bucket % 256}`;
39
- };
40
- const walrusNetworkCreateSpec = (spec, subnetPrefix) => ({
41
- ...spec,
42
- subnet: `${subnetPrefix}.0/24`,
43
- gateway: `${subnetPrefix}.1`
44
- });
33
+ * stacks don't all claim the same Docker IPAM range. Walrus claims
34
+ * the `10.64.*` `10.127.*` band; see substrate/runtime/subnet-broker.ts
35
+ * for the algorithm and band coordination with seal. */
36
+ const deriveWalrusSubnetPrefix = (identity) => deriveSubnetPrefix(`${identity.app}\0${identity.stack}\0${identity.walrusName}`, 64);
45
37
  const withWalrusNetworkAddressing = (runtime, walrusNetworkName, subnetPrefix) => ({
46
38
  ...runtime,
47
- ensureNetwork: (spec) => runtime.ensureNetwork(spec.name === walrusNetworkName ? walrusNetworkCreateSpec(spec, subnetPrefix) : spec)
39
+ ensureNetwork: (spec) => runtime.ensureNetwork(spec.name === walrusNetworkName ? withSubnetAddressing(spec, subnetPrefix) : spec)
48
40
  });
49
41
  const buildLocalPlugin = (opts) => {
50
42
  const resolved = resolveLocalClusterOptions(opts);
@@ -53,6 +45,7 @@ const buildLocalPlugin = (opts) => {
53
45
  id: walrusResource.id,
54
46
  dependsOn: [suiResource],
55
47
  role: "service",
48
+ section: "service",
56
49
  pluginKey: walrusKey,
57
50
  start: (deps) => Effect.gen(function* () {
58
51
  const [sui] = deps;
@@ -92,7 +85,8 @@ const buildLocalPlugin = (opts) => {
92
85
  subnetPrefix: walrusSubnetPrefix,
93
86
  walrusNetworkName,
94
87
  suiNetworkName: walrusNetworkName,
95
- deployHostMountPath
88
+ deployHostMountPath,
89
+ stackRoot: stackPaths.stackRoot
96
90
  }, mode);
97
91
  if (boot.mode !== "local") return yield* Effect.die("walrus: mode mismatch in local plugin");
98
92
  return {
@@ -130,6 +124,7 @@ const buildKnownPlugin = (opts) => {
130
124
  id: walrusResource.id,
131
125
  dependsOn: [suiResource],
132
126
  role: "task",
127
+ section: "service",
133
128
  start: () => Effect.succeed({
134
129
  mode: "known",
135
130
  chain: resolved.chain,
@@ -242,6 +237,7 @@ const walCoin = (walrusMember) => {
242
237
  id: resource(coinResourceId("wal")).id,
243
238
  dependsOn: walrusMember,
244
239
  role: "task",
240
+ section: "action",
245
241
  start: (resolved) => Effect.gen(function* () {
246
242
  if (resolved.walCoinType === null) return yield* Effect.fail(walrusPluginError("exchange", "walCoin(...) requires a local Walrus deployment with a WAL package."));
247
243
  return {
@@ -268,8 +264,7 @@ const walrus = (opts) => {
268
264
  *
269
265
  * Critically, the fork branch exposes ONLY `.known` — calling
270
266
  * `.local` on a fork-mode network is a **compile error** at the
271
- * call site (distilled-doc invariant 12 — type-level refusal).
272
- * Runtime defense-in-depth: see `mode/fork-refusal.ts`. */
267
+ * call site (distilled-doc invariant 12 — type-level refusal). */
273
268
  const walrusFor = defineModeNamespace({
274
269
  local: {
275
270
  local: (opts = {}) => buildLocalPlugin(opts),