@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 +1 @@
1
- {"version":3,"file":"service.mjs","names":["brandContentHash"],"sources":["../../../src/plugins/action/service.ts"],"sourcesContent":["// Action plugin — main acquire body.\n//\n// Architecture (16-action.md): an action is a ONE-SHOT on-chain effect\n// that runs once per (chain × content-hash), caches its receipt, and\n// re-fires when its discriminator changes (or the chain regenesises).\n//\n// Implementation: thin wrapper over `ArtifactPublisher`. The\n// substrate handles the cache → verify → produce → register cycle; this\n// file composes the spec:\n//\n// - namespace = `action`\n// - chain = Sui dependency's resolved `chain`\n// - contentHash = hash of (actionName, upstreamResourceIds[], dynamic\n// discriminator if any)\n// - verifySchema = `ActionReceiptSchema` — Schema-validated cached\n// shape so a corrupt entry surfaces as a miss\n// - verify = `chainProbe.get({kind:'transaction', digest},\n// VerifyTxShape, 'lenient')` — null on transient\n// or not-found, NOT raise.\n// - produce = user's `body(ctx)` Effect. Wraps any non-tagged\n// throw in `ActionError({phase:'sign'})`.\n// - register = no-op (Action declares no in-process registry —\n// mirrors v3 `services/action.ts:189-191` \"Action\n// does NOT populate any in-process registries\").\n//\n// Constraints honored:\n//\n// - Cache key folds (name, chainId, dependency resource ids, discriminator?) —\n// 16-action.md invariant #1.\n// - Dynamic discriminator re-runs on EVERY acquire — invariant #6.\n// - Lenient verify probe — invariant #4.\n// - signAndExecute failure routes via ActionError(phase: 'sign') —\n// invariant #8 (mirroring v3's `PublishError({phase:'publish-tx'})`,\n// but tagged separately so action consumers `catchTag('ActionError')`\n// without clashing with package's tagged error).\n\nimport { createHash } from 'node:crypto';\n\nimport { Effect, Schema, type Scope } from 'effect';\n\nimport { contentHash as brandContentHash, type ChainId } from '../../substrate/brand.ts';\nimport type {\n\tArtifactPublishError,\n\tArtifactPublisher,\n} from '../../primitives/artifact-publisher.ts';\nimport type { ChainProbe } from '../../contracts/chain-probe.ts';\nimport type { SuiProbeKey } from '../sui/chain-probe.ts';\nimport type { ActionBuildContext } from './build-context.ts';\nimport { actionError, type ActionError } from './errors.ts';\nimport {\n\tcomposeDiscriminatorMaterial,\n\ttype DynamicDiscriminator,\n\ttype StaticDiscriminator,\n} from './discriminator.ts';\n\n/** Action receipt — the cached value. Minimal shape: digest is the\n * load-bearing identifier (drives verify probe + downstream\n * consumers); the change arrays are surfaced opaquely (typed\n * `unknown` here so the cache schema stays narrow) but the in-memory\n * shape produced by the `ctx.signAndExecute` helper is\n * `ActionObjectChange` (`{ kind: 'created' | 'mutated', objectId,\n * objectType?, outputState?, idOperation? }`). Consumers can cast or\n * use `findCreatedByType`-style helpers — mirrors v3's\n * `pickCreatedByType(r.objectChanges, ...)` pattern from\n * `examples/connect-four/devstack.config.ts`.\n *\n * Distilled doc §\"Capabilities PRODUCED\" — the v3 Action's `TxResult`\n * carries `digest`, `effects`, `objectChanges`, `balanceChanges`. We\n * narrow to the columns that fit the cache + are actually used by\n * downstream consumers. */\nexport interface ActionReceipt {\n\treadonly digest: string;\n\treadonly objectChanges?: ReadonlyArray<unknown>;\n\treadonly balanceChanges?: ReadonlyArray<unknown>;\n}\n\n/** Schema for the cached `ActionReceipt`. `objectChanges` /\n * `balanceChanges` are `Unknown`-typed arrays — we don't enforce the\n * SDK's wide change-shape here because callers project these\n * manually (mirrors v3's `pickCreatedByType(r.objectChanges, ...)`\n * pattern from `examples/connect-four/devstack.config.ts`). */\nexport const ActionReceiptSchema = Schema.Struct({\n\tdigest: Schema.String,\n\tobjectChanges: Schema.optional(Schema.Array(Schema.Unknown)),\n\tbalanceChanges: Schema.optional(Schema.Array(Schema.Unknown)),\n});\n\n/** Verify-probe shape — what `getTransaction(digest)` returns on\n * success. We don't decode the full transaction envelope; presence\n * of the digest field is the \"exists\" signal. The lenient probe\n * already coerces transient + not-found to null. */\nconst VerifyTxShape = Schema.Struct({\n\tdigest: Schema.String,\n});\n\n/** Per-acquire inputs handed to `bootActionService`. The dynamic\n * discriminator is pre-resolved by `index.ts` — at this layer the\n * `staticDiscriminator` + optional `dynamicMaterial` string suffice. */\nexport interface ActionAcquireInputs {\n\treadonly actionName: string;\n\treadonly chainId: ChainId;\n\treadonly staticDiscriminator: StaticDiscriminator;\n\t/** Resolved dynamic-discriminator material — already projected to\n\t * a string at acquire-time by `index.ts` (the callback form\n\t * receives the `ActionBuildContext` there). */\n\treadonly dynamicMaterial: Effect.Effect<string | undefined, ActionError>;\n\t/** The user's body Effect. Receives no parameter — it closes over\n\t * upstream-tag values via the outer `acquire` scope. Returns the\n\t * receipt of the on-chain effect; the plugin caches this. */\n\treadonly body: Effect.Effect<ActionReceipt, ActionError, Scope.Scope>;\n}\n\n/** Resolve a `DynamicDiscriminator` against the action's\n * action context and resolved dependency values. Two input shapes\n * (per `DynamicDiscriminator`) collapse onto\n * `Effect<string | undefined, ActionError>`. */\nexport const resolveDiscriminator = <Deps>(\n\tactionName: string,\n\tdynamic: DynamicDiscriminator<Deps> | undefined,\n\tctx: ActionBuildContext,\n\tdeps: Deps,\n): Effect.Effect<string | undefined, ActionError> => {\n\tif (dynamic === undefined) return Effect.succeed(undefined);\n\tif (typeof dynamic === 'string') return Effect.succeed(dynamic);\n\treturn dynamic(ctx, deps).pipe(\n\t\tEffect.catch(\n\t\t\t(cause): Effect.Effect<string, ActionError> =>\n\t\t\t\tEffect.fail(\n\t\t\t\t\t// If the user's discriminator Effect itself raises an\n\t\t\t\t\t// ActionError, surface it verbatim. Otherwise wrap.\n\t\t\t\t\t(cause as ActionError)._tag === 'ActionError'\n\t\t\t\t\t\t? (cause as ActionError)\n\t\t\t\t\t\t: actionError('discriminator', {\n\t\t\t\t\t\t\t\tactionName,\n\t\t\t\t\t\t\t\tmessage: `Action '${actionName}': discriminator Effect failed.`,\n\t\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t\t}),\n\t\t\t\t),\n\t\t),\n\t);\n};\n\n/** Build the verify-probe Effect for a given cached digest. Lenient\n * mode coerces transient + not-found to null; the substrate then\n * re-produces on null. */\nconst buildVerifyProbe = (\n\tprobe: ChainProbe<SuiProbeKey>,\n\tcachedDigest: string,\n): Effect.Effect<typeof VerifyTxShape.Type | null, never> =>\n\tprobe.get({ kind: 'transaction', digest: cachedDigest }, VerifyTxShape, 'lenient').pipe(\n\t\t// `decode-failed` on verify is stale shape — null so the\n\t\t// substrate re-fires rather than carry forward a mismatch.\n\t\tEffect.catch(() => Effect.succeed(null as typeof VerifyTxShape.Type | null)),\n\t);\n\n/** Main acquire body. Composes the ArtifactSpec for the action\n * and yields it to the publisher.\n *\n * Returns the cached/produced `ActionReceipt`. Errors flow as\n * `ActionError | ArtifactPublishError` — the latter when the substrate\n * itself surfaces a produce-failure wrap. */\nexport const bootActionService = (\n\tpublisher: ArtifactPublisher,\n\tprobe: ChainProbe<SuiProbeKey>,\n\tinputs: ActionAcquireInputs,\n): Effect.Effect<ActionReceipt, ActionError | ArtifactPublishError, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tyield* Effect.annotateCurrentSpan({\n\t\t\t'action.name': inputs.actionName,\n\t\t\t'action.chain': inputs.chainId,\n\t\t});\n\n\t\t// --- Pull the pre-projected dynamic-discriminator material\n\t\t// (every acquire — hit OR miss). The callback form's\n\t\t// `(ctx) => Effect<string>` is invoked by `index.ts` before\n\t\t// reaching here, so this layer sees only the resolved Effect.\n\t\tconst resolvedDynamic = yield* inputs.dynamicMaterial;\n\n\t\t// --- Compose content-hash inputs\n\t\tconst material = composeDiscriminatorMaterial(inputs.staticDiscriminator, resolvedDynamic);\n\t\tconst inputsHash = brandContentHash(createHash('sha256').update(material).digest('hex'));\n\n\t\t// --- Submit the spec to the publisher.\n\t\t//\n\t\t// The artifact publisher substrate decodes the cached `ActionReceipt` and\n\t\t// passes it into `verify(cached)` — so the verify Effect can\n\t\t// pull the digest off the cached payload directly. No\n\t\t// in-process registry-hop required (mirrors the seam pattern\n\t\t// the package plugin's mode-local TODO calls out).\n\t\tconst produced = yield* publisher.publish<ActionReceipt, typeof VerifyTxShape.Type>({\n\t\t\tnamespace: 'action',\n\t\t\tchain: inputs.chainId,\n\t\t\tcontentHash: inputsHash,\n\t\t\tverifySchema: VerifyTxShape,\n\t\t\tverify: (cached) => buildVerifyProbe(probe, cached.digest),\n\t\t\tproduce: Effect.gen(function* () {\n\t\t\t\tyield* Effect.annotateCurrentSpan({\n\t\t\t\t\t'action.phase': 'building',\n\t\t\t\t});\n\t\t\t\tconst receipt: ActionReceipt = yield* inputs.body.pipe(\n\t\t\t\t\tEffect.catch(\n\t\t\t\t\t\t(cause): Effect.Effect<ActionReceipt, ActionError> =>\n\t\t\t\t\t\t\tEffect.fail(\n\t\t\t\t\t\t\t\t(cause as ActionError)?._tag === 'ActionError'\n\t\t\t\t\t\t\t\t\t? (cause as ActionError)\n\t\t\t\t\t\t\t\t\t: actionError('sign', {\n\t\t\t\t\t\t\t\t\t\t\tactionName: inputs.actionName,\n\t\t\t\t\t\t\t\t\t\t\tmessage: `Action '${inputs.actionName}': body Effect failed.`,\n\t\t\t\t\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tyield* Effect.annotateCurrentSpan({\n\t\t\t\t\t'action.phase': 'parsing',\n\t\t\t\t\t'action.digest': receipt.digest,\n\t\t\t\t});\n\t\t\t\treturn receipt;\n\t\t\t}).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: `action.${inputs.actionName} ${err.phase}: ${err.message}`,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t),\n\t\t\tregister: (_artifact) =>\n\t\t\t\t// Action declares no in-process registry (mirrors v3's\n\t\t\t\t// `services/action.ts:189-191` \"Action does NOT populate\n\t\t\t\t// any in-process registries\"). The cached digest is now\n\t\t\t\t// threaded directly via the artifact publisher's `verify(cached)`\n\t\t\t\t// parameter — no register-hop hint required.\n\t\t\t\tEffect.void,\n\t\t});\n\n\t\t// The publisher returns `Produced | Verified`. Both shapes\n\t\t// carry `digest`; the action's resolved value is the cached\n\t\t// receipt (full `ActionReceipt` on produce/decoded-hit, or a\n\t\t// projected `{digest}` on bare-verify-hit). Callers expect the\n\t\t// wider shape — surface defensively.\n\t\tif ('digest' in produced && typeof produced.digest === 'string') {\n\t\t\t// Already-`ActionReceipt`-shaped. Cast through to recover\n\t\t\t// the optional change arrays if present.\n\t\t\treturn produced as ActionReceipt;\n\t\t}\n\t\t// Defensive: unreachable under the current substrate (verify\n\t\t// returns the bare `{digest}` shape; the substrate falls back\n\t\t// to it ONLY when the cached payload failed to decode, which\n\t\t// we treat as miss elsewhere). Surface a parse-phase error.\n\t\treturn yield* Effect.fail(\n\t\t\tactionError('parse', {\n\t\t\t\tactionName: inputs.actionName,\n\t\t\t\tmessage: `Action '${inputs.actionName}': cached payload missing digest.`,\n\t\t\t}),\n\t\t);\n\t});\n"],"mappings":";;;;;AAiFmC,OAAO,OAAO;CAChD,QAAQ,OAAO;CACf,eAAe,OAAO,SAAS,OAAO,MAAM,OAAO,QAAQ,CAAC;CAC5D,gBAAgB,OAAO,SAAS,OAAO,MAAM,OAAO,QAAQ,CAAC;CAC7D,CAAC;;;;;AAMF,MAAM,gBAAgB,OAAO,OAAO,EACnC,QAAQ,OAAO,QACf,CAAC;;;;;AAuBF,MAAa,wBACZ,YACA,SACA,KACA,SACoD;AACpD,KAAI,YAAY,KAAA,EAAW,QAAO,OAAO,QAAQ,KAAA,EAAU;AAC3D,KAAI,OAAO,YAAY,SAAU,QAAO,OAAO,QAAQ,QAAQ;AAC/D,QAAO,QAAQ,KAAK,KAAK,CAAC,KACzB,OAAO,OACL,UACA,OAAO,KAGL,MAAsB,SAAS,gBAC5B,QACD,YAAY,iBAAiB;EAC7B;EACA,SAAS,WAAW,WAAW;EAC/B;EACA,CAAC,CACJ,CACF,CACD;;;;;AAMF,MAAM,oBACL,OACA,iBAEA,MAAM,IAAI;CAAE,MAAM;CAAe,QAAQ;CAAc,EAAE,eAAe,UAAU,CAAC,KAGlF,OAAO,YAAY,OAAO,QAAQ,KAAyC,CAAC,CAC5E;;;;;;;AAQF,MAAa,qBACZ,WACA,OACA,WAEA,OAAO,IAAI,aAAa;AACvB,QAAO,OAAO,oBAAoB;EACjC,eAAe,OAAO;EACtB,gBAAgB,OAAO;EACvB,CAAC;CAMF,MAAM,kBAAkB,OAAO,OAAO;CAGtC,MAAM,WAAW,6BAA6B,OAAO,qBAAqB,gBAAgB;CAC1F,MAAM,aAAaA,YAAiB,WAAW,SAAS,CAAC,OAAO,SAAS,CAAC,OAAO,MAAM,CAAC;CASxF,MAAM,WAAW,OAAO,UAAU,QAAkD;EACnF,WAAW;EACX,OAAO,OAAO;EACd,aAAa;EACb,cAAc;EACd,SAAS,WAAW,iBAAiB,OAAO,OAAO,OAAO;EAC1D,SAAS,OAAO,IAAI,aAAa;AAChC,UAAO,OAAO,oBAAoB,EACjC,gBAAgB,YAChB,CAAC;GACF,MAAM,UAAyB,OAAO,OAAO,KAAK,KACjD,OAAO,OACL,UACA,OAAO,KACL,OAAuB,SAAS,gBAC7B,QACD,YAAY,QAAQ;IACpB,YAAY,OAAO;IACnB,SAAS,WAAW,OAAO,WAAW;IACtC;IACA,CAAC,CACJ,CACF,CACD;AACD,UAAO,OAAO,oBAAoB;IACjC,gBAAgB;IAChB,iBAAiB,QAAQ;IACzB,CAAC;AACF,UAAO;IACN,CAAC,KACF,OAAO,UACL,SAA+B;GAC/B,MAAM;GACN,QAAQ;GACR,QAAQ,UAAU,OAAO,WAAW,GAAG,IAAI,MAAM,IAAI,IAAI;GACzD,EACD,CACD;EACD,WAAW,cAMV,OAAO;EACR,CAAC;AAOF,KAAI,YAAY,YAAY,OAAO,SAAS,WAAW,SAGtD,QAAO;AAMR,QAAO,OAAO,OAAO,KACpB,YAAY,SAAS;EACpB,YAAY,OAAO;EACnB,SAAS,WAAW,OAAO,WAAW;EACtC,CAAC,CACF;EACA"}
1
+ {"version":3,"file":"service.mjs","names":["brandContentHash"],"sources":["../../../src/plugins/action/service.ts"],"sourcesContent":["// Action plugin — main acquire body.\n//\n// Architecture (16-action.md): an action is a ONE-SHOT on-chain effect\n// that runs once per (chain × content-hash), caches its receipt, and\n// re-fires when its discriminator changes (or the chain regenesises).\n//\n// Implementation: thin wrapper over `ArtifactPublisher`. The\n// substrate handles the cache → verify → produce → register cycle; this\n// file composes the spec:\n//\n// - namespace = `action`\n// - chain = Sui dependency's resolved `chain`\n// - contentHash = hash of (actionName, upstreamResourceIds[], dynamic\n// discriminator if any)\n// - verify = `chainProbe.get({kind:'transaction', digest},\n// VerifyTxShape, 'lenient')` — null on transient\n// or not-found, NOT raise.\n// - produce = user's `body(ctx)` Effect. Wraps any non-tagged\n// throw in `ActionError({phase:'sign'})`.\n// - register = no-op (Action declares no in-process registry —\n// mirrors v3 `services/action.ts:189-191` \"Action\n// does NOT populate any in-process registries\").\n//\n// Constraints honored:\n//\n// - Cache key folds (name, chainId, dependency resource ids, discriminator?) —\n// 16-action.md invariant #1.\n// - Dynamic discriminator re-runs on EVERY acquire — invariant #6.\n// - Lenient verify probe — invariant #4.\n// - signAndExecute failure routes via ActionError(phase: 'sign') —\n// invariant #8 (mirroring v3's `PublishError({phase:'publish-tx'})`,\n// but tagged separately so action consumers `catchTag('ActionError')`\n// without clashing with package's tagged error).\n\nimport { createHash } from 'node:crypto';\n\nimport { Cause, Effect, Schema, type Scope } from 'effect';\n\nimport { contentHash as brandContentHash, type ChainId } from '../../substrate/brand.ts';\nimport {\n\tartifactPublishError,\n\ttype ArtifactPublishError,\n\ttype ArtifactPublisher,\n} from '../../primitives/artifact-publisher.ts';\nimport { acquireOnChainArtifact } from '../internal/acquire-on-chain-artifact.ts';\nimport { withPhasePreservingProduce } from '../../substrate/runtime/phase-preserving-produce.ts';\nimport type { ChainProbe } from '../../contracts/chain-probe.ts';\nimport type { SuiProbeKey } from '../sui/index.ts';\nimport type { ActionBuildContext } from './build-context.ts';\nimport { actionError, type ActionError } from './errors.ts';\nimport {\n\tcomposeDiscriminatorMaterial,\n\ttype DynamicDiscriminator,\n\ttype StaticDiscriminator,\n} from './discriminator.ts';\nimport { ActionSpans } from './spans.ts';\n\n/** Action receipt — the cached value. Minimal shape: digest is the\n * load-bearing identifier (drives verify probe + downstream\n * consumers); the change arrays are surfaced opaquely (typed\n * `unknown` here so the cache schema stays narrow) but the in-memory\n * shape produced by the `ctx.signAndExecute` helper is\n * `ActionObjectChange` (`{ kind: 'created' | 'mutated', objectId,\n * objectType?, outputState?, idOperation? }`). Consumers can cast or\n * use `findCreatedByType`-style helpers — mirrors v3's\n * `pickCreatedByType(r.objectChanges, ...)` pattern from\n * `examples/connect-four/devstack.config.ts`.\n *\n * Distilled doc §\"Capabilities PRODUCED\" — the v3 Action's `TxResult`\n * carries `digest`, `effects`, `objectChanges`, `balanceChanges`. We\n * narrow to the columns that fit the cache + are actually used by\n * downstream consumers. */\nexport interface ActionReceipt {\n\treadonly digest: string;\n\treadonly objectChanges?: ReadonlyArray<unknown>;\n\treadonly balanceChanges?: ReadonlyArray<unknown>;\n}\n\n/** Schema for the cached `ActionReceipt`. `objectChanges` /\n * `balanceChanges` are `Unknown`-typed arrays — we don't enforce the\n * SDK's wide change-shape here because callers project these\n * manually (mirrors v3's `pickCreatedByType(r.objectChanges, ...)`\n * pattern from `examples/connect-four/devstack.config.ts`). */\nexport const ActionReceiptSchema = Schema.Struct({\n\tdigest: Schema.String,\n\tobjectChanges: Schema.optional(Schema.Array(Schema.Unknown)),\n\tbalanceChanges: Schema.optional(Schema.Array(Schema.Unknown)),\n});\n\n/** Verify-probe shape — what `getTransaction(digest)` returns on\n * success. We don't decode the full transaction envelope; presence\n * of the digest field is the \"exists\" signal. The lenient probe\n * already coerces transient + not-found to null. */\nconst VerifyTxShape = Schema.Struct({\n\tdigest: Schema.String,\n});\n\n/** Per-acquire inputs handed to `bootActionService`. The dynamic\n * discriminator is pre-resolved by `index.ts` — at this layer the\n * `staticDiscriminator` + optional `dynamicMaterial` string suffice. */\nexport interface ActionAcquireInputs {\n\treadonly actionName: string;\n\treadonly chainId: ChainId;\n\treadonly staticDiscriminator: StaticDiscriminator;\n\t/** Resolved dynamic-discriminator material — already projected to\n\t * a string at acquire-time by `index.ts` (the callback form\n\t * receives the `ActionBuildContext` there). */\n\treadonly dynamicMaterial: Effect.Effect<string | undefined, ActionError>;\n\t/** The user's body Effect. Receives no parameter — it closes over\n\t * upstream-tag values via the outer `acquire` scope. Returns the\n\t * receipt of the on-chain effect; the plugin caches this. */\n\treadonly body: Effect.Effect<ActionReceipt, ActionError, Scope.Scope>;\n}\n\n/** Resolve a `DynamicDiscriminator` against the action's\n * action context and resolved dependency values. Two input shapes\n * (per `DynamicDiscriminator`) collapse onto\n * `Effect<string | undefined, ActionError>`. */\nexport const resolveDiscriminator = <Deps>(\n\tdynamic: DynamicDiscriminator<Deps> | undefined,\n\tctx: ActionBuildContext,\n\tdeps: Deps,\n): Effect.Effect<string | undefined, ActionError> => {\n\tif (dynamic === undefined) return Effect.succeed(undefined);\n\tif (typeof dynamic === 'string') return Effect.succeed(dynamic);\n\t// The dynamic discriminator's error channel is typed `ActionError`\n\t// (see `DynamicDiscriminator<Deps>` in `discriminator.ts`), so user\n\t// failures already arrive in the tagged shape — no wrap or\n\t// re-projection needed. (Prior code ran `Effect.catch` to fall\n\t// through tag-or-wrap, but the channel is exhaustively\n\t// ActionError; the wrap branch was unreachable.)\n\treturn dynamic(ctx, deps);\n};\n\n/** Build the verify-probe Effect for a given cached digest. Lenient\n * mode coerces transient + not-found to null; the substrate then\n * re-produces on null. */\nconst buildVerifyProbe = (\n\tprobe: ChainProbe<SuiProbeKey>,\n\tcachedDigest: string,\n): Effect.Effect<typeof VerifyTxShape.Type | null, never> =>\n\tprobe.get({ kind: 'transaction', digest: cachedDigest }, VerifyTxShape, 'lenient').pipe(\n\t\t// `decode-failed` on verify is stale shape — null so the\n\t\t// substrate re-fires rather than carry forward a mismatch.\n\t\tEffect.catch(() => Effect.succeed(null as typeof VerifyTxShape.Type | null)),\n\t);\n\n/** Main acquire body. Composes the ArtifactSpec for the action\n * and yields it to the publisher.\n *\n * Returns the cached/produced `ActionReceipt`. Errors flow as\n * `ActionError | ArtifactPublishError` — the latter when the substrate\n * itself surfaces a produce-failure wrap. */\nexport const bootActionService = (\n\tpublisher: ArtifactPublisher,\n\tprobe: ChainProbe<SuiProbeKey>,\n\tinputs: ActionAcquireInputs,\n): Effect.Effect<ActionReceipt, ActionError | ArtifactPublishError, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tyield* Effect.annotateCurrentSpan({\n\t\t\t[ActionSpans.name]: inputs.actionName,\n\t\t\t[ActionSpans.chain]: inputs.chainId,\n\t\t});\n\n\t\t// --- Pull the pre-projected dynamic-discriminator material\n\t\t// (every acquire — hit OR miss). The callback form's\n\t\t// `(ctx) => Effect<string>` is invoked by `index.ts` before\n\t\t// reaching here, so this layer sees only the resolved Effect.\n\t\tconst resolvedDynamic = yield* inputs.dynamicMaterial;\n\n\t\t// --- Compose content-hash inputs\n\t\tconst material = composeDiscriminatorMaterial(inputs.staticDiscriminator, resolvedDynamic);\n\t\tconst inputsHash = brandContentHash(createHash('sha256').update(material).digest('hex'));\n\n\t\t// --- Phase-preserving produce.\n\t\t//\n\t\t// `publisher.publish`'s `produce` channel must surface failures\n\t\t// as `ArtifactPublishError` per the substrate contract. That\n\t\t// erases the original `ActionError.phase`.\n\t\t// `withPhasePreservingProduce` stashes the typed `ActionError`\n\t\t// in a Ref BEFORE the mapError boundary so the outer recovery\n\t\t// (`recoverTypedError`) can re-raise it untouched. The caller in\n\t\t// `index.ts` then sees the original `phase` rather than a\n\t\t// uniformly-stamped `'sign'`.\n\t\tconst typedProduce = Effect.gen(function* () {\n\t\t\tyield* Effect.annotateCurrentSpan({\n\t\t\t\t[ActionSpans.phase]: 'building',\n\t\t\t});\n\t\t\t// `inputs.body` is a USER-SUPPLIED Effect. Two failure\n\t\t\t// surfaces must collapse onto a single `ActionError`:\n\t\t\t//\n\t\t\t// 1. Typed `ActionError` on the failure channel —\n\t\t\t// `catchTag('ActionError')` re-raises untouched so\n\t\t\t// the original `phase` survives.\n\t\t\t// 2. Defects (sync `throw` inside the body, `die(...)`)\n\t\t\t// bypass typed catches entirely — `catchCause` is\n\t\t\t// the only seam that sees them. Defects get\n\t\t\t// rebadged to `phase: 'sign'` so a user body that\n\t\t\t// throws lands on the typed channel rather than\n\t\t\t// crashing the produce step. Interrupt-only causes\n\t\t\t// propagate untouched so cancellation semantics\n\t\t\t// survive.\n\t\t\tconst receipt: ActionReceipt = yield* inputs.body.pipe(\n\t\t\t\tEffect.catchCause((cause) => {\n\t\t\t\t\t// 1. Typed `ActionError` on the failure channel —\n\t\t\t\t\t// re-raise untouched so the original `phase`\n\t\t\t\t\t// survives the downstream re-wrap step.\n\t\t\t\t\tconst failed = Cause.findError(cause);\n\t\t\t\t\tif (failed._tag === 'Success') {\n\t\t\t\t\t\treturn Effect.fail(failed.success);\n\t\t\t\t\t}\n\t\t\t\t\t// 2. Interrupt-only causes propagate untouched so\n\t\t\t\t\t// cancellation semantics survive.\n\t\t\t\t\tif (Cause.hasInterruptsOnly(cause)) {\n\t\t\t\t\t\treturn Effect.failCause(cause);\n\t\t\t\t\t}\n\t\t\t\t\t// 3. Defects (sync `throw` inside the body, `die(...)`)\n\t\t\t\t\t// bypass typed catches entirely — `catchCause` is\n\t\t\t\t\t// the only seam that sees them. Rebadge to\n\t\t\t\t\t// `phase: 'sign'` so a user body that throws\n\t\t\t\t\t// lands on the typed channel rather than crashing\n\t\t\t\t\t// the produce step.\n\t\t\t\t\tconst defect = Cause.findDefect(cause);\n\t\t\t\t\tconst defectValue =\n\t\t\t\t\t\tdefect._tag === 'Success' ? defect.success : Cause.squash(cause);\n\t\t\t\t\treturn Effect.fail(\n\t\t\t\t\t\tactionError('sign', {\n\t\t\t\t\t\t\tactionName: inputs.actionName,\n\t\t\t\t\t\t\tmessage: `Action '${inputs.actionName}': body Effect raised a defect.`,\n\t\t\t\t\t\t\tcause: defectValue,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}),\n\t\t\t);\n\t\t\tyield* Effect.annotateCurrentSpan({\n\t\t\t\t[ActionSpans.phase]: 'parsing',\n\t\t\t\t[ActionSpans.digest]: receipt.digest,\n\t\t\t});\n\t\t\treturn receipt;\n\t\t});\n\n\t\tconst { wrappedProduce, recoverTypedError } = yield* withPhasePreservingProduce({\n\t\t\tproduce: typedProduce,\n\t\t\twrapProduceError: (err: ActionError): ArtifactPublishError =>\n\t\t\t\tartifactPublishError(\n\t\t\t\t\t'produce-failed',\n\t\t\t\t\t`action.${inputs.actionName} ${err.phase}: ${err.message}`,\n\t\t\t\t),\n\t\t});\n\n\t\t// --- Submit the spec to the publisher.\n\t\t//\n\t\t// The artifact publisher substrate decodes the cached `ActionReceipt` and\n\t\t// passes it into `verify(cached)` — so the verify Effect can\n\t\t// pull the digest off the cached payload directly. No\n\t\t// in-process registry-hop required (mirrors the seam pattern\n\t\t// the package plugin's mode-local TODO calls out).\n\t\tconst receipt: ActionReceipt = yield* acquireOnChainArtifact<\n\t\t\tActionReceipt,\n\t\t\ttypeof VerifyTxShape.Type\n\t\t>(publisher, {\n\t\t\tnamespace: 'action',\n\t\t\tchain: inputs.chainId,\n\t\t\tcontentHash: inputsHash,\n\t\t\tverify: (cached) => buildVerifyProbe(probe, cached.digest),\n\t\t\tproduce: wrappedProduce,\n\t\t}).pipe(recoverTypedError);\n\n\t\t// The substrate hands back the decoded `ActionReceipt` on every\n\t\t// path (decoded cached payload on hit, fresh produce on miss).\n\t\treturn receipt;\n\t}).pipe(\n\t\t// Outer span so the per-action `annotateCurrentSpan` annotations\n\t\t// above attach to a real span instead of dropping silently when\n\t\t// `bootActionService` is invoked outside a parent span.\n\t\tEffect.withSpan('devstack.plugin.action.boot', {\n\t\t\tattributes: {\n\t\t\t\t[ActionSpans.name]: inputs.actionName,\n\t\t\t\t[ActionSpans.chain]: inputs.chainId,\n\t\t\t},\n\t\t}),\n\t);\n"],"mappings":";;;;;;;;;AAmFmC,OAAO,OAAO;CAChD,QAAQ,OAAO;CACf,eAAe,OAAO,SAAS,OAAO,MAAM,OAAO,QAAQ,CAAC;CAC5D,gBAAgB,OAAO,SAAS,OAAO,MAAM,OAAO,QAAQ,CAAC;CAC7D,CAAC;;;;;AAMF,MAAM,gBAAgB,OAAO,OAAO,EACnC,QAAQ,OAAO,QACf,CAAC;;;;;AAuBF,MAAa,wBACZ,SACA,KACA,SACoD;AACpD,KAAI,YAAY,KAAA,EAAW,QAAO,OAAO,QAAQ,KAAA,EAAU;AAC3D,KAAI,OAAO,YAAY,SAAU,QAAO,OAAO,QAAQ,QAAQ;AAO/D,QAAO,QAAQ,KAAK,KAAK;;;;;AAM1B,MAAM,oBACL,OACA,iBAEA,MAAM,IAAI;CAAE,MAAM;CAAe,QAAQ;CAAc,EAAE,eAAe,UAAU,CAAC,KAGlF,OAAO,YAAY,OAAO,QAAQ,KAAyC,CAAC,CAC5E;;;;;;;AAQF,MAAa,qBACZ,WACA,OACA,WAEA,OAAO,IAAI,aAAa;AACvB,QAAO,OAAO,oBAAoB;GAChC,YAAY,OAAO,OAAO;GAC1B,YAAY,QAAQ,OAAO;EAC5B,CAAC;CAMF,MAAM,kBAAkB,OAAO,OAAO;CAGtC,MAAM,WAAW,6BAA6B,OAAO,qBAAqB,gBAAgB;CAC1F,MAAM,aAAaA,YAAiB,WAAW,SAAS,CAAC,OAAO,SAAS,CAAC,OAAO,MAAM,CAAC;CAqExF,MAAM,EAAE,gBAAgB,sBAAsB,OAAO,2BAA2B;EAC/E,SA1DoB,OAAO,IAAI,aAAa;AAC5C,UAAO,OAAO,oBAAoB,GAChC,YAAY,QAAQ,YACrB,CAAC;GAeF,MAAM,UAAyB,OAAO,OAAO,KAAK,KACjD,OAAO,YAAY,UAAU;IAI5B,MAAM,SAAS,MAAM,UAAU,MAAM;AACrC,QAAI,OAAO,SAAS,UACnB,QAAO,OAAO,KAAK,OAAO,QAAQ;AAInC,QAAI,MAAM,kBAAkB,MAAM,CACjC,QAAO,OAAO,UAAU,MAAM;IAQ/B,MAAM,SAAS,MAAM,WAAW,MAAM;IACtC,MAAM,cACL,OAAO,SAAS,YAAY,OAAO,UAAU,MAAM,OAAO,MAAM;AACjE,WAAO,OAAO,KACb,YAAY,QAAQ;KACnB,YAAY,OAAO;KACnB,SAAS,WAAW,OAAO,WAAW;KACtC,OAAO;KACP,CAAC,CACF;KACA,CACF;AACD,UAAO,OAAO,oBAAoB;KAChC,YAAY,QAAQ;KACpB,YAAY,SAAS,QAAQ;IAC9B,CAAC;AACF,UAAO;IAIc;EACrB,mBAAmB,QAClB,qBACC,kBACA,UAAU,OAAO,WAAW,GAAG,IAAI,MAAM,IAAI,IAAI,UACjD;EACF,CAAC;AAsBF,QAAO,OAb+B,uBAGpC,WAAW;EACZ,WAAW;EACX,OAAO,OAAO;EACd,aAAa;EACb,SAAS,WAAW,iBAAiB,OAAO,OAAO,OAAO;EAC1D,SAAS;EACT,CAAC,CAAC,KAAK,kBAAkB;EAKzB,CAAC,KAIF,OAAO,SAAS,+BAA+B,EAC9C,YAAY;EACV,YAAY,OAAO,OAAO;EAC1B,YAAY,QAAQ,OAAO;CAC5B,EACD,CAAC,CACF"}
@@ -0,0 +1,11 @@
1
+ //#region src/plugins/action/spans.ts
2
+ const ActionSpans = {
3
+ name: "action.name",
4
+ chain: "action.chain",
5
+ phase: "action.phase",
6
+ digest: "action.digest"
7
+ };
8
+ //#endregion
9
+ export { ActionSpans };
10
+
11
+ //# sourceMappingURL=spans.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spans.mjs","names":[],"sources":["../../../src/plugins/action/spans.ts"],"sourcesContent":["// Action plugin span-attribute vocabulary. Plugin-local — substrate's\n// `SpanAttr` carries only engine-dimensional + http/process generic\n// keys; plugin-domain keys live next to the plugin that owns them.\n//\n// Callsite pattern: `Effect.annotateCurrentSpan({ [ActionSpans.name]:\n// inputs.actionName })`. Free-form string literals are a STYLE_GUIDE §16\n// violation.\n\nexport const ActionSpans = {\n\tname: 'action.name',\n\tchain: 'action.chain',\n\tphase: 'action.phase',\n\tdigest: 'action.digest',\n} as const;\n"],"mappings":";AAQA,MAAa,cAAc;CAC1B,MAAM;CACN,OAAO;CACP,OAAO;CACP,QAAQ;CACR"}
@@ -1,19 +1,20 @@
1
- import { Effect } from "effect";
1
+ import { defineSimpleConstExport } from "../internal/codegen-helpers.mjs";
2
2
  //#region src/plugins/coin/codegen.ts
3
3
  /** Construct the Codegenable contribution for one coin instance.
4
4
  *
5
5
  * Emitter name is literal `coin/${symbol}` so the orchestrator can
6
6
  * group them and folds them into a single `coins.ts` at staging
7
7
  * time. Mirrors `account/${name}` naming in the Account plugin. */
8
- const makeCoinCodegen = (parts) => ({
9
- kind: "codegenable",
8
+ const makeCoinCodegen = (parts) => defineSimpleConstExport({
10
9
  emitterName: `coin/${parts.symbol}`,
11
10
  outputPath: `coins/${parts.symbol}.ts`,
12
- sensitive: false,
13
- emit: (ctx) => Effect.sync(() => {
14
- ctx.exportConst(parts.symbol, parts.resolved);
15
- return ctx.done();
16
- })
11
+ exportName: parts.symbol,
12
+ value: parts.resolved,
13
+ aggregate: {
14
+ kind: "coin",
15
+ bucket: "coins.ts",
16
+ project: (exported) => exported
17
+ }
17
18
  });
18
19
  //#endregion
19
20
  export { makeCoinCodegen };
@@ -1 +1 @@
1
- {"version":3,"file":"codegen.mjs","names":[],"sources":["../../../src/plugins/coin/codegen.ts"],"sourcesContent":["// Coin plugin — Codegenable contribution.\n//\n// Distilled-doc 13-coin.md §\"Files written\": the codegen orchestrator\n// projects the per-stack CoinRegistry into a generated `coins.ts`\n// table:\n//\n// export const coins = {\n// mUSDC: { type, decimals, sdkCoin, symbol, ... },\n// mWETH: { type, decimals, sdkCoin, symbol, ... },\n// } as const;\n// export type CoinName = keyof typeof coins;\n//\n// This file declares the SEAM — the typed binding shape and the\n// per-coin contribution. The heavy lift (writing the bytes, merging\n// all coins into one file) happens in the codegen orchestrator\n// (plugin/codegen layer, NOT this plugin); it walks every member's\n// caps tuple, finds the Coin-emitted contributions, and emits ONE\n// `coins.ts` referencing every entry.\n//\n// Per-coin shape mirrors the v3 `CoinEntry` (manifest schema) sans\n// the `sdkCoin` runtime projection — that lives in the SDK adapter\n// at codegen time, not in the binding shape.\n\nimport { Effect } from 'effect';\n\nimport type { CodegenableDecl } from '../../contracts/codegenable.ts';\n\n/** The typed shape per emitted coin record. */\nexport interface CoinBindings {\n\treadonly symbol: string;\n\treadonly fullCoinType: string;\n\treadonly decimals: number;\n\treadonly displayName?: string;\n\treadonly iconUrl?: string;\n\treadonly treasuryCapId?: string;\n\treadonly metadataId?: string;\n\treadonly packageId?: string;\n\treadonly source: 'registry' | 'on-chain' | 'builtin';\n}\n\n/** Construct the Codegenable contribution for one coin instance.\n *\n * Emitter name is literal `coin/${symbol}` so the orchestrator can\n * group them and folds them into a single `coins.ts` at staging\n * time. Mirrors `account/${name}` naming in the Account plugin. */\nexport const makeCoinCodegen = <Symbol extends string>(parts: {\n\treadonly symbol: Symbol;\n\treadonly resolved: CoinBindings;\n}): CodegenableDecl<`coin/${Symbol}`> => ({\n\tkind: 'codegenable',\n\temitterName: `coin/${parts.symbol}` as `coin/${Symbol}`,\n\toutputPath: `coins/${parts.symbol}.ts`,\n\tsensitive: false,\n\temit: (ctx) =>\n\t\tEffect.sync(() => {\n\t\t\tctx.exportConst(parts.symbol, parts.resolved);\n\t\t\treturn ctx.done();\n\t\t}),\n});\n"],"mappings":";;;;;;;AA6CA,MAAa,mBAA0C,WAGb;CACzC,MAAM;CACN,aAAa,QAAQ,MAAM;CAC3B,YAAY,SAAS,MAAM,OAAO;CAClC,WAAW;CACX,OAAO,QACN,OAAO,WAAW;AACjB,MAAI,YAAY,MAAM,QAAQ,MAAM,SAAS;AAC7C,SAAO,IAAI,MAAM;GAChB;CACH"}
1
+ {"version":3,"file":"codegen.mjs","names":[],"sources":["../../../src/plugins/coin/codegen.ts"],"sourcesContent":["// Coin plugin — Codegenable contribution.\n//\n// Distilled-doc 13-coin.md §\"Files written\": the codegen orchestrator\n// projects the per-stack CoinRegistry into a generated `coins.ts`\n// table:\n//\n// export const coins = {\n// mUSDC: { type, decimals, sdkCoin, symbol, ... },\n// mWETH: { type, decimals, sdkCoin, symbol, ... },\n// } as const;\n// export type CoinName = keyof typeof coins;\n//\n// This file declares the SEAM — the typed binding shape and the\n// per-coin contribution. The heavy lift (writing the bytes, merging\n// all coins into one file) happens in the codegen orchestrator\n// (plugin/codegen layer, NOT this plugin); it walks every member's\n// caps tuple, finds the Coin-emitted contributions, and emits ONE\n// `coins.ts` referencing every entry.\n//\n// Per-coin shape mirrors the v3 `CoinEntry` (manifest schema) sans\n// the `sdkCoin` runtime projection — that lives in the SDK adapter\n// at codegen time, not in the binding shape.\n\nimport type { CodegenableDecl } from '../../contracts/codegenable.ts';\n\nimport { defineSimpleConstExport } from '../internal/codegen-helpers.ts';\n\n/** The typed shape per emitted coin record. */\nexport interface CoinBindings {\n\treadonly symbol: string;\n\treadonly fullCoinType: string;\n\treadonly decimals: number;\n\treadonly displayName?: string;\n\treadonly iconUrl?: string;\n\treadonly treasuryCapId?: string;\n\treadonly metadataId?: string;\n\treadonly packageId?: string;\n\treadonly source: 'registry' | 'on-chain' | 'builtin';\n}\n\n/** Construct the Codegenable contribution for one coin instance.\n *\n * Emitter name is literal `coin/${symbol}` so the orchestrator can\n * group them and folds them into a single `coins.ts` at staging\n * time. Mirrors `account/${name}` naming in the Account plugin. */\nexport const makeCoinCodegen = <Symbol extends string>(parts: {\n\treadonly symbol: Symbol;\n\treadonly resolved: CoinBindings;\n}): CodegenableDecl<`coin/${Symbol}`> =>\n\tdefineSimpleConstExport({\n\t\temitterName: `coin/${parts.symbol}` as `coin/${Symbol}`,\n\t\toutputPath: `coins/${parts.symbol}.ts`,\n\t\texportName: parts.symbol,\n\t\tvalue: parts.resolved,\n\t\taggregate: {\n\t\t\tkind: 'coin',\n\t\t\tbucket: 'coins.ts',\n\t\t\t// Pass-through: this decl's exported map already keys by\n\t\t\t// coin symbol, which is the aggregate's merge key.\n\t\t\tproject: (exported) => exported,\n\t\t},\n\t});\n"],"mappings":";;;;;;;AA6CA,MAAa,mBAA0C,UAItD,wBAAwB;CACvB,aAAa,QAAQ,MAAM;CAC3B,YAAY,SAAS,MAAM,OAAO;CAClC,YAAY,MAAM;CAClB,OAAO,MAAM;CACb,WAAW;EACV,MAAM;EACN,QAAQ;EAGR,UAAU,aAAa;EACvB;CACD,CAAC"}
@@ -29,15 +29,19 @@ const pickNumber = (json, key) => {
29
29
  const value = json[key];
30
30
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
31
31
  };
32
+ /** Project the `json` payload of a `created` object change into the
33
+ * metadata fields the discovery aggregate consumes. Always returns a
34
+ * `Partial<...>` (never `null`) — an empty object is the natural "no
35
+ * fields recognised" outcome and lets callers spread unconditionally
36
+ * without an `??` fallback. */
32
37
  const pickMetadata = (change) => {
33
38
  const json = change.json;
34
- if (json === null || typeof json !== "object" || Array.isArray(json)) return null;
39
+ if (json === null || typeof json !== "object" || Array.isArray(json)) return {};
35
40
  const record = json;
36
41
  const decimals = pickNumber(record, "decimals");
37
42
  const symbol = pickString(record, "symbol");
38
43
  const displayName = pickString(record, "name");
39
44
  const iconUrl = pickString(record, "iconUrl") ?? pickString(record, "icon_url");
40
- if (decimals === void 0 && symbol === void 0 && displayName === void 0 && iconUrl === void 0) return null;
41
45
  return {
42
46
  ...decimals === void 0 ? {} : { decimals },
43
47
  ...symbol === void 0 ? {} : { symbol },
@@ -71,14 +75,14 @@ const discoverCoinsFromPublish = (output) => {
71
75
  if (metaInner !== null && change.objectId !== void 0) {
72
76
  metadata.set(metaInner, {
73
77
  id: change.objectId,
74
- ...pickMetadata(change) ?? {}
78
+ ...pickMetadata(change)
75
79
  });
76
80
  continue;
77
81
  }
78
82
  const currencyInner = pickSuiFrameworkInnerGenericFromModule(change.objectType, "coin_registry", "Currency");
79
83
  if (currencyInner !== null && change.objectId !== void 0) metadata.set(currencyInner, {
80
84
  id: change.objectId,
81
- ...pickMetadata(change) ?? {}
85
+ ...pickMetadata(change)
82
86
  });
83
87
  }
84
88
  const allTypes = new Set([...caps.keys(), ...metadata.keys()]);
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.mjs","names":[],"sources":["../../../src/plugins/coin/discovery.ts"],"sourcesContent":["// Coin auto-discovery — pure projection over a `LocalPackagePublishOutput`.\n//\n// Distilled-doc 13-coin.md §\"Capabilities PRODUCED\" §\"Registry\n// entries\" + Invariant 6 + Invariant 7:\n//\n// - Iterate `output.objectChanges`,\n// - Find paired Sui-framework `coin::TreasuryCap<T>` +\n// `coin::CoinMetadata<T>`,\n// - Reject nested generics (`TreasuryCap<A<B>>` returns no record),\n// - Sort ascending by fullCoinType for deterministic order.\n//\n// This file is PURE — no Effect, no RPC. Metadata enrichment (the\n// `getCoinMetadata` RPC fold) lives in `metadata.ts`; we just emit\n// the raw discovered shape here. The input is structural so Coin does\n// not import Package internals.\n\nimport {\n\tpickSuiFrameworkInnerGeneric,\n\tpickSuiFrameworkInnerGenericFromModule,\n} from './type-strings.ts';\n\nexport interface CoinDiscoveryObjectChange {\n\treadonly type: 'created' | 'published' | 'mutated' | 'wrapped' | 'transferred';\n\treadonly objectId?: string;\n\treadonly objectType?: string;\n\treadonly owner?: unknown;\n\treadonly json?: unknown;\n}\n\nexport interface CoinDiscoveryPublishOutput {\n\treadonly publisher: string;\n\treadonly objectChanges: ReadonlyArray<CoinDiscoveryObjectChange>;\n}\n\n/** A discovered coin pulled out of a publish output. The downstream\n * metadata enricher in `metadata.ts` turns this into a full\n * `CoinRecord`. */\nexport interface DiscoveredCoin {\n\t/** `0xPKG::module::Witness`. */\n\treadonly fullCoinType: string;\n\t/** Lower-cased witness name. */\n\treadonly witness: string;\n\t/** Lower-cased module name. */\n\treadonly moduleName: string;\n\treadonly treasuryCapId?: string;\n\treadonly treasuryCapOwner?: string;\n\treadonly metadataId?: string;\n\treadonly decimals?: number;\n\treadonly symbol?: string;\n\treadonly displayName?: string;\n\treadonly iconUrl?: string;\n\t/** True when the cap is address-owned by the publisher at the\n\t * end of the publish tx. Distilled-doc invariant: the faucet's\n\t * treasury-cap-mint auto-registration is gated off this flag. */\n\treadonly publisherOwnsCap: boolean;\n}\n\ninterface DiscoveredMetadata {\n\treadonly id: string;\n\treadonly decimals?: number;\n\treadonly symbol?: string;\n\treadonly displayName?: string;\n\treadonly iconUrl?: string;\n}\n\n/** Extract module + witness from `0xPKG::module::Witness`. */\nconst splitCoinType = (\n\tfullCoinType: string,\n): { readonly moduleName: string; readonly witness: string } | null => {\n\tconst parts = fullCoinType.split('::');\n\tif (parts.length !== 3) return null;\n\tconst [, moduleName, witness] = parts;\n\tif (moduleName === undefined || witness === undefined) return null;\n\treturn { moduleName, witness };\n};\n\n/** Read the address owner from a package-publish-output change. Handles\n * the SDK's discriminated owner-shape; non-address owners surface as\n * `undefined`. The owner shape varies across SDK versions; this\n * helper covers the common surface and degrades gracefully. */\nconst pickAddressOwner = (change: CoinDiscoveryObjectChange): string | undefined => {\n\tconst owner = change.owner as\n\t\t| { readonly AddressOwner?: string; readonly $kind?: string }\n\t\t| string\n\t\t| undefined;\n\tif (owner === undefined || owner === null) return undefined;\n\tif (typeof owner === 'string') return owner; // some SDK projections flatten\n\tif (typeof owner === 'object' && 'AddressOwner' in owner) {\n\t\treturn owner.AddressOwner;\n\t}\n\treturn undefined;\n};\n\nconst pickString = (json: Record<string, unknown>, key: string): string | undefined => {\n\tconst value = json[key];\n\treturn typeof value === 'string' && value.length > 0 ? value : undefined;\n};\n\nconst pickNumber = (json: Record<string, unknown>, key: string): number | undefined => {\n\tconst value = json[key];\n\treturn typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n};\n\nconst pickMetadata = (change: CoinDiscoveryObjectChange): Omit<DiscoveredMetadata, 'id'> | null => {\n\tconst json = change.json;\n\tif (json === null || typeof json !== 'object' || Array.isArray(json)) return null;\n\tconst record = json as Record<string, unknown>;\n\tconst decimals = pickNumber(record, 'decimals');\n\tconst symbol = pickString(record, 'symbol');\n\tconst displayName = pickString(record, 'name');\n\tconst iconUrl = pickString(record, 'iconUrl') ?? pickString(record, 'icon_url');\n\tif (\n\t\tdecimals === undefined &&\n\t\tsymbol === undefined &&\n\t\tdisplayName === undefined &&\n\t\ticonUrl === undefined\n\t) {\n\t\treturn null;\n\t}\n\treturn {\n\t\t...(decimals === undefined ? {} : { decimals }),\n\t\t...(symbol === undefined ? {} : { symbol }),\n\t\t...(displayName === undefined ? {} : { displayName }),\n\t\t...(iconUrl === undefined ? {} : { iconUrl }),\n\t};\n};\n\n/** Walk a publish output for coin pairs.\n *\n * Sort ascending by fullCoinType — distilled-doc invariant 6 — so\n * the registry sees a stable order across re-runs of the same\n * publish.\n *\n * Pure. No Effect / RPC. */\nexport const discoverCoinsFromPublish = (\n\toutput: CoinDiscoveryPublishOutput,\n): ReadonlyArray<DiscoveredCoin> => {\n\tconst publisher = output.publisher;\n\t// Two passes over the changes: collect caps, collect metadata,\n\t// then JOIN on fullCoinType. The straightforward \"iterate once and\n\t// build per-coin records\" is harder to read when the two object\n\t// types interleave in the output.\n\tconst caps = new Map<string, { readonly id: string; readonly owner: string | undefined }>();\n\tconst metadata = new Map<string, DiscoveredMetadata>();\n\n\tfor (const change of output.objectChanges) {\n\t\tif (change.type !== 'created') continue;\n\t\tif (!change.objectType) continue;\n\t\tconst capInner = pickSuiFrameworkInnerGeneric(change.objectType, 'TreasuryCap');\n\t\tif (capInner !== null && change.objectId !== undefined) {\n\t\t\tcaps.set(capInner, {\n\t\t\t\tid: change.objectId,\n\t\t\t\towner: pickAddressOwner(change),\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tconst metaInner = pickSuiFrameworkInnerGeneric(change.objectType, 'CoinMetadata');\n\t\tif (metaInner !== null && change.objectId !== undefined) {\n\t\t\tmetadata.set(metaInner, {\n\t\t\t\tid: change.objectId,\n\t\t\t\t...(pickMetadata(change) ?? {}),\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tconst currencyInner = pickSuiFrameworkInnerGenericFromModule(\n\t\t\tchange.objectType,\n\t\t\t'coin_registry',\n\t\t\t'Currency',\n\t\t);\n\t\tif (currencyInner !== null && change.objectId !== undefined) {\n\t\t\tmetadata.set(currencyInner, {\n\t\t\t\tid: change.objectId,\n\t\t\t\t...(pickMetadata(change) ?? {}),\n\t\t\t});\n\t\t}\n\t}\n\n\t// Union the two sets of coin types — a coin with only a cap or\n\t// only metadata is still a coin (distilled-doc invariant: we\n\t// surface degraded records rather than drop them).\n\tconst allTypes = new Set<string>([...caps.keys(), ...metadata.keys()]);\n\tconst records: Array<DiscoveredCoin> = [];\n\tfor (const fullCoinType of allTypes) {\n\t\tconst parts = splitCoinType(fullCoinType);\n\t\tif (!parts) continue;\n\t\tconst cap = caps.get(fullCoinType);\n\t\tconst meta = metadata.get(fullCoinType);\n\t\tconst publisherOwnsCap = cap !== undefined && cap.owner === publisher;\n\t\trecords.push({\n\t\t\tfullCoinType,\n\t\t\twitness: parts.witness.toLowerCase(),\n\t\t\tmoduleName: parts.moduleName.toLowerCase(),\n\t\t\ttreasuryCapId: cap?.id,\n\t\t\ttreasuryCapOwner: cap?.owner,\n\t\t\tmetadataId: meta?.id,\n\t\t\t...(meta?.decimals === undefined ? {} : { decimals: meta.decimals }),\n\t\t\t...(meta?.symbol === undefined ? {} : { symbol: meta.symbol }),\n\t\t\t...(meta?.displayName === undefined ? {} : { displayName: meta.displayName }),\n\t\t\t...(meta?.iconUrl === undefined ? {} : { iconUrl: meta.iconUrl }),\n\t\t\tpublisherOwnsCap,\n\t\t});\n\t}\n\t// Distilled-doc invariant 6: ascending sort by fullCoinType. Stable\n\t// across re-runs so the \"first wins on collision\" tie-break is\n\t// deterministic.\n\trecords.sort((a, b) =>\n\t\ta.fullCoinType < b.fullCoinType ? -1 : a.fullCoinType > b.fullCoinType ? 1 : 0,\n\t);\n\treturn records;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"discovery.mjs","names":[],"sources":["../../../src/plugins/coin/discovery.ts"],"sourcesContent":["// Coin auto-discovery — pure projection over a `LocalPackagePublishOutput`.\n//\n// Distilled-doc 13-coin.md §\"Capabilities PRODUCED\" §\"Registry\n// entries\" + Invariant 6 + Invariant 7:\n//\n// - Iterate `output.objectChanges`,\n// - Find paired Sui-framework `coin::TreasuryCap<T>` +\n// `coin::CoinMetadata<T>`,\n// - Reject nested generics (`TreasuryCap<A<B>>` returns no record),\n// - Sort ascending by fullCoinType for deterministic order.\n//\n// This file is PURE — no Effect, no RPC. Metadata enrichment (the\n// `getCoinMetadata` RPC fold) lives in `metadata.ts`; we just emit\n// the raw discovered shape here. The input is structural so Coin does\n// not import Package internals.\n\nimport {\n\tpickSuiFrameworkInnerGeneric,\n\tpickSuiFrameworkInnerGenericFromModule,\n} from './type-strings.ts';\n\nexport interface CoinDiscoveryObjectChange {\n\treadonly type: 'created' | 'published' | 'mutated' | 'wrapped' | 'transferred';\n\treadonly objectId?: string;\n\treadonly objectType?: string;\n\treadonly owner?: unknown;\n\treadonly json?: unknown;\n}\n\nexport interface CoinDiscoveryPublishOutput {\n\treadonly publisher: string;\n\treadonly objectChanges: ReadonlyArray<CoinDiscoveryObjectChange>;\n}\n\n/** A discovered coin pulled out of a publish output. The downstream\n * metadata enricher in `metadata.ts` turns this into a full\n * `CoinRecord`. */\nexport interface DiscoveredCoin {\n\t/** `0xPKG::module::Witness`. */\n\treadonly fullCoinType: string;\n\t/** Lower-cased witness name. */\n\treadonly witness: string;\n\t/** Lower-cased module name. */\n\treadonly moduleName: string;\n\treadonly treasuryCapId?: string;\n\treadonly treasuryCapOwner?: string;\n\treadonly metadataId?: string;\n\treadonly decimals?: number;\n\treadonly symbol?: string;\n\treadonly displayName?: string;\n\treadonly iconUrl?: string;\n\t/** True when the cap is address-owned by the publisher at the\n\t * end of the publish tx. Distilled-doc invariant: the faucet's\n\t * treasury-cap-mint auto-registration is gated off this flag. */\n\treadonly publisherOwnsCap: boolean;\n}\n\ninterface DiscoveredMetadata {\n\treadonly id: string;\n\treadonly decimals?: number;\n\treadonly symbol?: string;\n\treadonly displayName?: string;\n\treadonly iconUrl?: string;\n}\n\n/** Extract module + witness from `0xPKG::module::Witness`. */\nconst splitCoinType = (\n\tfullCoinType: string,\n): { readonly moduleName: string; readonly witness: string } | null => {\n\tconst parts = fullCoinType.split('::');\n\tif (parts.length !== 3) return null;\n\tconst [, moduleName, witness] = parts;\n\tif (moduleName === undefined || witness === undefined) return null;\n\treturn { moduleName, witness };\n};\n\n/** Read the address owner from a package-publish-output change. Handles\n * the SDK's discriminated owner-shape; non-address owners surface as\n * `undefined`. The owner shape varies across SDK versions; this\n * helper covers the common surface and degrades gracefully. */\nconst pickAddressOwner = (change: CoinDiscoveryObjectChange): string | undefined => {\n\tconst owner = change.owner as\n\t\t| { readonly AddressOwner?: string; readonly $kind?: string }\n\t\t| string\n\t\t| undefined;\n\tif (owner === undefined || owner === null) return undefined;\n\tif (typeof owner === 'string') return owner; // some SDK projections flatten\n\tif (typeof owner === 'object' && 'AddressOwner' in owner) {\n\t\treturn owner.AddressOwner;\n\t}\n\treturn undefined;\n};\n\nconst pickString = (json: Record<string, unknown>, key: string): string | undefined => {\n\tconst value = json[key];\n\treturn typeof value === 'string' && value.length > 0 ? value : undefined;\n};\n\nconst pickNumber = (json: Record<string, unknown>, key: string): number | undefined => {\n\tconst value = json[key];\n\treturn typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n};\n\n/** Project the `json` payload of a `created` object change into the\n * metadata fields the discovery aggregate consumes. Always returns a\n * `Partial<...>` (never `null`) — an empty object is the natural \"no\n * fields recognised\" outcome and lets callers spread unconditionally\n * without an `??` fallback. */\nconst pickMetadata = (\n\tchange: CoinDiscoveryObjectChange,\n): Partial<Omit<DiscoveredMetadata, 'id'>> => {\n\tconst json = change.json;\n\tif (json === null || typeof json !== 'object' || Array.isArray(json)) return {};\n\tconst record = json as Record<string, unknown>;\n\tconst decimals = pickNumber(record, 'decimals');\n\tconst symbol = pickString(record, 'symbol');\n\tconst displayName = pickString(record, 'name');\n\tconst iconUrl = pickString(record, 'iconUrl') ?? pickString(record, 'icon_url');\n\treturn {\n\t\t...(decimals === undefined ? {} : { decimals }),\n\t\t...(symbol === undefined ? {} : { symbol }),\n\t\t...(displayName === undefined ? {} : { displayName }),\n\t\t...(iconUrl === undefined ? {} : { iconUrl }),\n\t};\n};\n\n/** Walk a publish output for coin pairs.\n *\n * Sort ascending by fullCoinType — distilled-doc invariant 6 — so\n * the registry sees a stable order across re-runs of the same\n * publish.\n *\n * Pure. No Effect / RPC. */\nexport const discoverCoinsFromPublish = (\n\toutput: CoinDiscoveryPublishOutput,\n): ReadonlyArray<DiscoveredCoin> => {\n\tconst publisher = output.publisher;\n\t// Two passes over the changes: collect caps, collect metadata,\n\t// then JOIN on fullCoinType. The straightforward \"iterate once and\n\t// build per-coin records\" is harder to read when the two object\n\t// types interleave in the output.\n\tconst caps = new Map<string, { readonly id: string; readonly owner: string | undefined }>();\n\tconst metadata = new Map<string, DiscoveredMetadata>();\n\n\tfor (const change of output.objectChanges) {\n\t\tif (change.type !== 'created') continue;\n\t\tif (!change.objectType) continue;\n\t\tconst capInner = pickSuiFrameworkInnerGeneric(change.objectType, 'TreasuryCap');\n\t\tif (capInner !== null && change.objectId !== undefined) {\n\t\t\tcaps.set(capInner, {\n\t\t\t\tid: change.objectId,\n\t\t\t\towner: pickAddressOwner(change),\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tconst metaInner = pickSuiFrameworkInnerGeneric(change.objectType, 'CoinMetadata');\n\t\tif (metaInner !== null && change.objectId !== undefined) {\n\t\t\tmetadata.set(metaInner, {\n\t\t\t\tid: change.objectId,\n\t\t\t\t...pickMetadata(change),\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tconst currencyInner = pickSuiFrameworkInnerGenericFromModule(\n\t\t\tchange.objectType,\n\t\t\t'coin_registry',\n\t\t\t'Currency',\n\t\t);\n\t\tif (currencyInner !== null && change.objectId !== undefined) {\n\t\t\tmetadata.set(currencyInner, {\n\t\t\t\tid: change.objectId,\n\t\t\t\t...pickMetadata(change),\n\t\t\t});\n\t\t}\n\t}\n\n\t// Union the two sets of coin types — a coin with only a cap or\n\t// only metadata is still a coin (distilled-doc invariant: we\n\t// surface degraded records rather than drop them).\n\tconst allTypes = new Set<string>([...caps.keys(), ...metadata.keys()]);\n\tconst records: Array<DiscoveredCoin> = [];\n\tfor (const fullCoinType of allTypes) {\n\t\tconst parts = splitCoinType(fullCoinType);\n\t\tif (!parts) continue;\n\t\tconst cap = caps.get(fullCoinType);\n\t\tconst meta = metadata.get(fullCoinType);\n\t\tconst publisherOwnsCap = cap !== undefined && cap.owner === publisher;\n\t\trecords.push({\n\t\t\tfullCoinType,\n\t\t\twitness: parts.witness.toLowerCase(),\n\t\t\tmoduleName: parts.moduleName.toLowerCase(),\n\t\t\ttreasuryCapId: cap?.id,\n\t\t\ttreasuryCapOwner: cap?.owner,\n\t\t\tmetadataId: meta?.id,\n\t\t\t...(meta?.decimals === undefined ? {} : { decimals: meta.decimals }),\n\t\t\t...(meta?.symbol === undefined ? {} : { symbol: meta.symbol }),\n\t\t\t...(meta?.displayName === undefined ? {} : { displayName: meta.displayName }),\n\t\t\t...(meta?.iconUrl === undefined ? {} : { iconUrl: meta.iconUrl }),\n\t\t\tpublisherOwnsCap,\n\t\t});\n\t}\n\t// Distilled-doc invariant 6: ascending sort by fullCoinType. Stable\n\t// across re-runs so the \"first wins on collision\" tie-break is\n\t// deterministic.\n\trecords.sort((a, b) =>\n\t\ta.fullCoinType < b.fullCoinType ? -1 : a.fullCoinType > b.fullCoinType ? 1 : 0,\n\t);\n\treturn records;\n};\n"],"mappings":"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"}
@@ -1,10 +1,9 @@
1
1
  import { CodegenableDecl } from "../../contracts/codegenable.mjs";
2
2
  import { SnapshotableDecl } from "../../contracts/snapshotable.mjs";
3
- import { StrategyContributorDecl } from "../../contracts/strategy-contributor.mjs";
4
3
  import { AnyResourceRef, Plugin, ResourceRef } from "../../substrate/plugin.mjs";
5
- import { SeedObjectsAccumulator } from "../sui/seed-objects.mjs";
6
4
  import { SuiClient } from "../sui/mode/shared.mjs";
7
5
  import { SuiOptions } from "../sui/mode/spec.mjs";
6
+ import { AccountFundingRequest } from "../../contracts/funding-strategy.mjs";
8
7
  import { ArtifactPublishError } from "../../primitives/artifact-publisher.mjs";
9
8
  import { CoinError, CoinPhase } from "./errors.mjs";
10
9
  import { MintResult, MintSigner } from "./mint.mjs";
@@ -16,7 +15,6 @@ import { DiscoveredCoin } from "./discovery.mjs";
16
15
  import { Effect } from "effect";
17
16
 
18
17
  //#region src/plugins/coin/index.d.ts
19
- type CoinResourceId<Sym extends string> = `coin:${Sym}`;
20
18
  type PackageNameOf<Pkg extends PackageMember> = Pkg extends ResourceRef<`package:${infer Name}`, PackageMemberValue> ? Name : string;
21
19
  /** A user-supplied package ref. The user passes the result of
22
20
  * `localPackage('foo', …)` / `knownPackage('foo', …)` — NOT a bare string
@@ -36,60 +34,44 @@ declare const coin: {
36
34
  readonly pkg: Pkg;
37
35
  readonly sui: ResourceRef<"sui", SuiClient & {
38
36
  readonly mode: SuiOptions["mode"];
39
- readonly seedObjects: SeedObjectsAccumulator;
40
37
  }>;
41
38
  } extends infer T ? T extends {
42
39
  readonly pkg: Pkg;
43
40
  readonly sui: ResourceRef<"sui", SuiClient & {
44
41
  readonly mode: SuiOptions["mode"];
45
- readonly seedObjects: SeedObjectsAccumulator;
46
42
  }>;
47
- } ? T extends Readonly<Record<string, AnyResourceRef>> ? readonly T[keyof T][] : readonly [] : never : never, readonly [SnapshotableDecl, CodegenableDecl<`coin/${string}`>, StrategyContributorDecl<"coin-registry", {
48
- readonly symbol: string;
49
- }>, ...{
43
+ } ? T extends Readonly<Record<string, AnyResourceRef>> ? readonly T[keyof T][] : readonly [] : never : never, readonly [SnapshotableDecl, CodegenableDecl<`coin/${string}`>, ...{
50
44
  kind: "strategy-contributor";
51
45
  capabilityKey: `coinType:${string}`;
52
46
  strategy: {
53
- readonly request: (req: {
54
- readonly address: string;
55
- readonly amount: bigint;
56
- }) => Effect.Effect<void, CoinError | ArtifactPublishError>;
47
+ usesAccountSigner: true;
48
+ request: (req: AccountFundingRequest<unknown>) => Effect.Effect<void, ArtifactPublishError | CoinError, never>;
57
49
  };
58
50
  autoMounted: true;
59
51
  }[]]>;
60
52
  readonly known: <FullType extends string>(fullCoinType: FullType) => Plugin<`coin:${string}`, CoinValue, readonly ResourceRef<"sui", SuiClient & {
61
53
  readonly mode: SuiOptions["mode"];
62
- readonly seedObjects: SeedObjectsAccumulator;
63
- }>[], readonly [SnapshotableDecl, CodegenableDecl<`coin/${string}`>, StrategyContributorDecl<"coin-registry", {
64
- readonly symbol: string;
65
- }>, ...{
54
+ }>[], readonly [SnapshotableDecl, CodegenableDecl<`coin/${string}`>, ...{
66
55
  kind: "strategy-contributor";
67
56
  capabilityKey: `coinType:${string}`;
68
57
  strategy: {
69
- readonly request: (req: {
70
- readonly address: string;
71
- readonly amount: bigint;
72
- }) => Effect.Effect<void, CoinError | ArtifactPublishError>;
58
+ usesAccountSigner: true;
59
+ request: (req: AccountFundingRequest<unknown>) => Effect.Effect<void, ArtifactPublishError | CoinError, never>;
73
60
  };
74
61
  autoMounted: true;
75
62
  }[]]>;
76
63
  readonly builtin: <Name extends keyof typeof BUILTIN_COINS>(name: Name) => Plugin<`coin:${Name}`, CoinValue, readonly ResourceRef<"sui", SuiClient & {
77
64
  readonly mode: SuiOptions["mode"];
78
- readonly seedObjects: SeedObjectsAccumulator;
79
- }>[], readonly [SnapshotableDecl, CodegenableDecl<`coin/${string}`>, StrategyContributorDecl<"coin-registry", {
80
- readonly symbol: string;
81
- }>, ...{
65
+ }>[], readonly [SnapshotableDecl, CodegenableDecl<`coin/${string}`>, ...{
82
66
  kind: "strategy-contributor";
83
67
  capabilityKey: `coinType:${string}`;
84
68
  strategy: {
85
- readonly request: (req: {
86
- readonly address: string;
87
- readonly amount: bigint;
88
- }) => Effect.Effect<void, CoinError | ArtifactPublishError>;
69
+ usesAccountSigner: true;
70
+ request: (req: AccountFundingRequest<unknown>) => Effect.Effect<void, ArtifactPublishError | CoinError, never>;
89
71
  };
90
72
  autoMounted: true;
91
73
  }[]]>;
92
74
  };
93
75
  //#endregion
94
- export { CoinResourceId, PackageMember, coin };
76
+ export { PackageMember, coin };
95
77
  //# sourceMappingURL=index.d.mts.map
@@ -1,34 +1,57 @@
1
1
  import { definePlugin, resource } from "../../substrate/plugin.mjs";
2
- import { pluginErrorContributions } from "../../api/plugin-errors.mjs";
3
- import { suiResource } from "../sui/index.mjs";
2
+ import "../../api/define-plugin.mjs";
4
3
  import { ArtifactPublisherService } from "../../substrate/runtime/artifact-publisher/index.mjs";
5
4
  import "./discovery.mjs";
6
- import { COIN_REGISTRY_CAPABILITY_KEY, CoinRegistryService } from "./registry.mjs";
5
+ import { CoinRegistryService } from "./registry.mjs";
6
+ import { pluginErrorContributions } from "../../api/plugin-errors.mjs";
7
+ import { suiResource } from "../sui/index.mjs";
7
8
  import { makeCoinCodegen } from "./codegen.mjs";
8
9
  import { makeCoinSnapshotable } from "./snapshot.mjs";
9
10
  import { COIN_ERROR_TAGS } from "./errors.mjs";
11
+ import "./spans.mjs";
10
12
  import "./metadata.mjs";
11
13
  import "./address-resolution.mjs";
12
14
  import "./mint.mjs";
13
15
  import { acquireCoin } from "./service.mjs";
14
16
  import { Effect } from "effect";
17
+ import { createHash } from "node:crypto";
15
18
  //#region src/plugins/coin/index.ts
16
19
  const coinErrorContributions = pluginErrorContributions(COIN_ERROR_TAGS);
17
20
  const coinFundingCapabilityKey = (fullCoinType) => `coinType:${fullCoinType}`;
18
21
  /** Resource id constructor. The symbolic name is part of the resource identity
19
22
  * so the substrate's compose-time dedup catches collisions. */
20
23
  const coinResourceId = (symbol) => `coin:${symbol}`;
21
- const packageNameFromMember = (pkg) => pkg.id.slice(8);
22
- const projectCoinSdk = (sui) => {
23
- const grpcClient = sui.sdk.client;
24
- return {
25
- core: {
26
- getObject: sui.sdk.core.getObject,
27
- getCoinMetadata: (args) => grpcClient.core.getCoinMetadata(args)
28
- },
29
- client: sui.sdk.client
30
- };
24
+ /** Maximum length of the readable prefix in a `coin.known(...)` resource
25
+ * id. Two long coin types sharing this prefix length would silently
26
+ * collide in the substrate's compose-time dedup (string equality on
27
+ * the resource id), so beyond this length we append a short hash of
28
+ * the full coin type to disambiguate. */
29
+ const COIN_KNOWN_PREFIX_MAX = 60;
30
+ /** Length of the SHA-256 hex suffix appended to long `coin.known(...)`
31
+ * resource ids. Eight chars (~32 bits) is the same width used by other
32
+ * collision-disambiguation hashes in the package (e.g. router profile,
33
+ * fork preimage suffixes). */
34
+ const COIN_KNOWN_HASH_SUFFIX_LEN = 8;
35
+ /** Derive a stable, human-readable, collision-free resource-id segment
36
+ * for `coin.known(fullCoinType)`. Short types pass through as the
37
+ * readable `<addr>_<module>_<witness>` form; long types get a hash
38
+ * suffix so two types sharing a 60-char prefix can coexist. */
39
+ const coinKnownResourceKey = (fullCoinType) => {
40
+ const readable = fullCoinType.replace(/^0x/, "").replace(/::/g, "_");
41
+ if (readable.length <= COIN_KNOWN_PREFIX_MAX) return readable;
42
+ const hash = createHash("sha256").update(fullCoinType).digest("hex").slice(0, COIN_KNOWN_HASH_SUFFIX_LEN);
43
+ return `${readable.slice(0, COIN_KNOWN_PREFIX_MAX - COIN_KNOWN_HASH_SUFFIX_LEN - 1)}_${hash}`;
31
44
  };
45
+ const packageNameFromMember = (pkg) => pkg.id.slice(8);
46
+ const projectCoinSdk = (sui) => ({
47
+ core: {
48
+ getObject: sui.sdk.core.getObject,
49
+ getCoinMetadata: (args) => sui.sdk.client.core.getCoinMetadata(args),
50
+ listCoins: sui.sdk.core.listCoins
51
+ },
52
+ client: sui.sdk.client,
53
+ forkMode: sui.fork !== null
54
+ });
32
55
  const buildCapabilities = (symbol, resolved) => {
33
56
  const bindings = {
34
57
  symbol: resolved.symbol ?? symbol,
@@ -41,22 +64,25 @@ const buildCapabilities = (symbol, resolved) => {
41
64
  ...resolved.metadataId !== void 0 ? { metadataId: resolved.metadataId } : {},
42
65
  ...resolved.packageId !== void 0 ? { packageId: resolved.packageId } : {}
43
66
  };
67
+ const snap = makeCoinSnapshotable({ symbol });
68
+ const codegen = makeCoinCodegen({
69
+ symbol,
70
+ resolved: bindings
71
+ });
72
+ const narrowStrategy = resolved.fundingStrategy;
44
73
  return [
45
- makeCoinSnapshotable({ symbol }),
46
- makeCoinCodegen({
47
- symbol,
48
- resolved: bindings
49
- }),
50
- {
51
- kind: "strategy-contributor",
52
- capabilityKey: COIN_REGISTRY_CAPABILITY_KEY,
53
- strategy: { symbol },
54
- autoMounted: true
55
- },
56
- ...resolved.fundingStrategy === void 0 ? [] : [{
74
+ snap,
75
+ codegen,
76
+ ...narrowStrategy === void 0 ? [] : [{
57
77
  kind: "strategy-contributor",
58
78
  capabilityKey: coinFundingCapabilityKey(resolved.fullCoinType),
59
- strategy: resolved.fundingStrategy,
79
+ strategy: {
80
+ usesAccountSigner: true,
81
+ request: (req) => narrowStrategy.request({
82
+ address: req.address,
83
+ amount: req.amount
84
+ })
85
+ },
60
86
  autoMounted: true
61
87
  }]
62
88
  ];
@@ -83,6 +109,7 @@ const fromPackage = (pkg, witnessName) => {
83
109
  sui: suiResource
84
110
  },
85
111
  role: "task",
112
+ section: "action",
86
113
  start: ({ pkg: resolved, sui }) => Effect.gen(function* () {
87
114
  const artifactPublisher = yield* ArtifactPublisherService;
88
115
  const registry = yield* CoinRegistryService;
@@ -110,11 +137,12 @@ const fromPackage = (pkg, witnessName) => {
110
137
  * invariant. Resource id uses a deterministic-but-readable derivation of
111
138
  * the coin type so collisions surface at compose time. */
112
139
  const known = (fullCoinType) => {
113
- const id = fullCoinType.replace(/^0x/, "").replace(/::/g, "_").slice(0, 60);
140
+ const id = coinKnownResourceKey(fullCoinType);
114
141
  return definePlugin({
115
142
  id: resource(coinResourceId(id)).id,
116
143
  dependsOn: { sui: suiResource },
117
144
  role: "task",
145
+ section: "action",
118
146
  start: ({ sui }) => Effect.gen(function* () {
119
147
  const publisher = yield* ArtifactPublisherService;
120
148
  const registry = yield* CoinRegistryService;
@@ -141,6 +169,7 @@ const builtin = (name) => {
141
169
  id: resource(coinResourceId(name)).id,
142
170
  dependsOn: { sui: suiResource },
143
171
  role: "task",
172
+ section: "action",
144
173
  start: ({ sui }) => Effect.gen(function* () {
145
174
  const publisher = yield* ArtifactPublisherService;
146
175
  const registry = yield* CoinRegistryService;
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugins/coin/index.ts"],"sourcesContent":["// Coin plugin — barrel + `coin(...)` factory family.\n//\n// Architecture (13-coin.md): Coin is the user-facing primitive family\n// for *addressing* custom Move coin types. It does NOT publish Move\n// modules itself — the Package plugin publishes; coin auto-discovery\n// (in `discovery.ts`) folds the publish output into the per-stack\n// `CoinRegistry`; this factory resolves user-supplied addresses\n// (witness / bare-type / builtin) against that registry plus the live RPC.\n//\n// User-facing factory shape — three variants mirroring the address\n// forms:\n//\n// coin.fromPackage(pkg, 'MOCK_USDC') // package member → registry\n// coin.known('0x...::deep::DEEP') // bare → live RPC\n// coin.builtin('sui') // protocol-defined constant\n//\n// (A `coin(identifier)` convenience entry is intentionally NOT\n// exposed — distilled-doc 13-coin.md Pain point #6 documents how the\n// \"guess the form from the string\" path is a footgun. The three-form\n// surface forces the user to make the disambiguation explicit at the\n// call site.)\n//\n// Resource id: `'coin:<package>/<witness>'` for package-scoped coins and\n// `'coin:<identifier>'` for known/builtin coins — one tag per declared\n// coin instance, so the substrate's compose-time dedup detects collisions\n// cleanly. Mirrors the Package plugin's per-instance resource identity.\n\nimport { Effect } from 'effect';\n\nimport { definePlugin, resource, type ResourceRef } from '../../api/define-plugin.ts';\nimport { pluginErrorContributions } from '../../api/plugin-errors.ts';\nimport type { CodegenableDecl } from '../../contracts/codegenable.ts';\nimport type { SnapshotableDecl } from '../../contracts/snapshotable.ts';\nimport type { StrategyContributorDecl } from '../../contracts/strategy-contributor.ts';\nimport { ArtifactPublisherService } from '../../substrate/runtime/artifact-publisher/index.ts';\nimport { suiResource } from '../sui/index.ts';\nimport type { SuiClient } from '../sui/index.ts';\nimport type { AccountFundingStrategy } from '../account/funding.ts';\n\nimport { makeCoinCodegen, type CoinBindings } from './codegen.ts';\nimport { makeCoinSnapshotable } from './snapshot.ts';\nimport { COIN_REGISTRY_CAPABILITY_KEY, CoinRegistryService } from './registry.ts';\nimport { COIN_ERROR_TAGS } from './errors.ts';\nimport { acquireCoin, type CoinAddressForm, type CoinValue } from './service.ts';\nimport { BUILTIN_COINS } from './address-resolution.ts';\nimport type { MetadataSdkShim } from './metadata.ts';\nimport type { MintSdkShim } from './mint.ts';\n\nconst coinErrorContributions = pluginErrorContributions(COIN_ERROR_TAGS);\n\nexport const coinFundingCapabilityKey = <FullType extends string>(\n\tfullCoinType: FullType,\n): `coinType:${FullType}` => `coinType:${fullCoinType}` as const;\n\n// ---------------------------------------------------------------------------\n// Resource — one per declared coin instance, keyed by explicit address form.\n// ---------------------------------------------------------------------------\n\n/** Resource id constructor. The symbolic name is part of the resource identity\n * so the substrate's compose-time dedup catches collisions. */\nexport const coinResourceId = <Sym extends string>(symbol: Sym): `coin:${Sym}` => `coin:${symbol}`;\n\nexport type CoinResourceId<Sym extends string> = `coin:${Sym}`;\n\ntype PackageNameOf<Pkg extends PackageMember> =\n\tPkg extends ResourceRef<`package:${infer Name}`, PackageMemberValue> ? Name : string;\n\ntype PackageCoinResourceKey<\n\tPkg extends PackageMember,\n\tWit extends string,\n> = `${PackageNameOf<Pkg>}/${Lowercase<Wit>}`;\n\nconst packageNameFromMember = <Pkg extends PackageMember>(pkg: Pkg): PackageNameOf<Pkg> =>\n\tpkg.id.slice('package:'.length) as PackageNameOf<Pkg>;\n\n// ---------------------------------------------------------------------------\n// SDK shim projection\n// ---------------------------------------------------------------------------\n//\n// The coin plugin's resolvers need three Sui surfaces: `core.getObject`\n// (mint verify probe), `core.getCoinMetadata` (bare-type address form),\n// and the opaque `client` (`Transaction.build({client})` in the mint\n// produce body).\n//\n// `sui.sdk.core.getObject` is on the typed `SuiSdkShim`; `getCoinMetadata`\n// lives on the underlying `SuiGrpcClient` reached via the opaque\n// `sui.sdk.client`. We project both onto a single `MetadataSdkShim &\n// MintSdkShim` here at the boundary — the cast mirrors STYLE_GUIDE §14\n// (localized cast through an opaque SDK surface), kept narrow to one\n// method projection.\n\nconst projectCoinSdk = (sui: SuiClient): MetadataSdkShim & MintSdkShim => {\n\tconst grpcClient = sui.sdk.client as {\n\t\treadonly core: {\n\t\t\treadonly getCoinMetadata: (args: { readonly coinType: string }) => Promise<unknown>;\n\t\t};\n\t};\n\treturn {\n\t\tcore: {\n\t\t\tgetObject: sui.sdk.core.getObject,\n\t\t\tgetCoinMetadata: (args) => grpcClient.core.getCoinMetadata(args),\n\t\t},\n\t\tclient: sui.sdk.client,\n\t};\n};\n\n// ---------------------------------------------------------------------------\n// Per-form capability builders — dynamic (POST-acquire). Receive the\n// resolved `CoinValue` so codegen bindings stamp the REAL fullCoinType\n// + decimals instead of placeholder values.\n// ---------------------------------------------------------------------------\n\nconst buildCapabilities = (symbol: string, resolved: CoinValue) => {\n\tconst bindings: CoinBindings = {\n\t\tsymbol: resolved.symbol ?? symbol,\n\t\tfullCoinType: resolved.fullCoinType,\n\t\tdecimals: resolved.decimals,\n\t\tsource: resolved.source,\n\t\t...(resolved.displayName !== undefined ? { displayName: resolved.displayName } : {}),\n\t\t...(resolved.iconUrl !== undefined ? { iconUrl: resolved.iconUrl } : {}),\n\t\t...(resolved.treasuryCapId !== undefined ? { treasuryCapId: resolved.treasuryCapId } : {}),\n\t\t...(resolved.metadataId !== undefined ? { metadataId: resolved.metadataId } : {}),\n\t\t...(resolved.packageId !== undefined ? { packageId: resolved.packageId } : {}),\n\t};\n\tconst snap: SnapshotableDecl = makeCoinSnapshotable({ symbol });\n\tconst codegen: CodegenableDecl<`coin/${string}`> = makeCoinCodegen({\n\t\tsymbol,\n\t\tresolved: bindings,\n\t});\n\t// Auto-mounted strategy contribution — siblings (Wallet, Faucet's\n\t// treasury-cap mint, Deepbook market-maker) read the per-stack\n\t// registry via this seam. The actual `CoinRegistry` instance is\n\t// wired at compose time (one registry per stack); each coin\n\t// contributes its `register(record)` call as a side effect at\n\t// acquire.\n\tconst registryContribution: StrategyContributorDecl<\n\t\ttypeof COIN_REGISTRY_CAPABILITY_KEY,\n\t\t{ readonly symbol: string }\n\t> = {\n\t\tkind: 'strategy-contributor',\n\t\tcapabilityKey: COIN_REGISTRY_CAPABILITY_KEY,\n\t\tstrategy: { symbol },\n\t\tautoMounted: true,\n\t};\n\tconst fundingContribution =\n\t\tresolved.fundingStrategy === undefined\n\t\t\t? []\n\t\t\t: [\n\t\t\t\t\t{\n\t\t\t\t\t\tkind: 'strategy-contributor',\n\t\t\t\t\t\tcapabilityKey: coinFundingCapabilityKey(resolved.fullCoinType),\n\t\t\t\t\t\tstrategy: resolved.fundingStrategy,\n\t\t\t\t\t\tautoMounted: true,\n\t\t\t\t\t} satisfies StrategyContributorDecl<`coinType:${string}`, AccountFundingStrategy>,\n\t\t\t\t];\n\treturn [snap, codegen, registryContribution, ...fundingContribution] as const;\n};\n\n// ---------------------------------------------------------------------------\n// Form 1: coin.fromPackage(pkg, witness) — package-scoped registry lookup\n// ---------------------------------------------------------------------------\n\n/** A user-supplied package ref. The user passes the result of\n * `localPackage('foo', …)` / `knownPackage('foo', …)` — NOT a bare string\n * value. Generic over the literal package name so the witness-form\n * coin's dependency preserves the per-package resource id. */\nexport interface PackageMemberValue {\n\treadonly name: string;\n\treadonly packageId: string;\n\treadonly publisher?: import('./mint.ts').MintSigner;\n}\n\nexport type PackageMember<Name extends string = string> = ResourceRef<\n\t`package:${Name}`,\n\tPackageMemberValue\n>;\n\n/** Resolve a coin by `(publishing package member, witness)`. Forces\n * a dep edge on the publishing package's resource — the substrate ensures\n * the publish has completed before this resolves.\n *\n * Resource identity includes both the package's symbolic name and the\n * witness name, so two packages can expose the same witness without\n * colliding in the substrate graph.\n *\n * Pass the package MEMBER (the value returned by `localPackage(...)`\n * / `knownPackage(...)`). The factory\n * projects it to a dependency resource and receives the package value\n * in `start`. */\nexport const fromPackage = <const Pkg extends PackageMember, Wit extends string>(\n\tpkg: Pkg,\n\twitnessName: Wit,\n) => {\n\tconst packageName = packageNameFromMember(pkg);\n\tconst symbol = witnessName.toLowerCase() as Lowercase<Wit>;\n\tconst resourceKey = `${packageName}/${symbol}` as PackageCoinResourceKey<Pkg, Wit>;\n\tconst coinRef = resource<CoinResourceId<typeof resourceKey>, CoinValue>(\n\t\tcoinResourceId(resourceKey),\n\t);\n\treturn definePlugin({\n\t\tid: coinRef.id,\n\t\tdependsOn: { pkg, sui: suiResource },\n\t\trole: 'task',\n\t\tstart: ({ pkg: resolved, sui }) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst artifactPublisher = yield* ArtifactPublisherService;\n\t\t\t\tconst registry = yield* CoinRegistryService;\n\t\t\t\tconst form: CoinAddressForm = {\n\t\t\t\t\tkind: 'witness',\n\t\t\t\t\tpublishingPackageName: resolved.name,\n\t\t\t\t\twitness: witnessName,\n\t\t\t\t\t...(resolved.publisher === undefined ? {} : { fundingSigner: resolved.publisher }),\n\t\t\t\t};\n\t\t\t\treturn yield* acquireCoin(form, {\n\t\t\t\t\tregistry,\n\t\t\t\t\tsdk: projectCoinSdk(sui),\n\t\t\t\t\tchain: sui.chain,\n\t\t\t\t\tpublisher: artifactPublisher,\n\t\t\t\t});\n\t\t\t}),\n\t\terrorContributions: coinErrorContributions,\n\t\tcapabilities: ({ value }) => buildCapabilities(symbol, value),\n\t});\n};\n\n// ---------------------------------------------------------------------------\n// Form 2: coin.known(fullCoinType) — bare on-chain type\n// ---------------------------------------------------------------------------\n\n/** Resolve a coin by bare on-chain type via `getCoinMetadata`.\n * Used for live-net coins (mainnet DEEP, USDC etc.) that no local\n * `Package(...)` publishes.\n *\n * Soft-degrades to `decimals: 0` on RPC failure — distilled-doc\n * invariant. Resource id uses a deterministic-but-readable derivation of\n * the coin type so collisions surface at compose time. */\nexport const known = <FullType extends string>(fullCoinType: FullType) => {\n\t// Derive a resource id from the type: keep it readable but unique. The\n\t// substrate's compose-time dedup uses string equality on the id.\n\tconst id = fullCoinType.replace(/^0x/, '').replace(/::/g, '_').slice(0, 60);\n\tconst coinRef = resource<CoinResourceId<typeof id>, CoinValue>(\n\t\tcoinResourceId(id) as CoinResourceId<typeof id>,\n\t);\n\treturn definePlugin({\n\t\tid: coinRef.id,\n\t\tdependsOn: { sui: suiResource },\n\t\trole: 'task',\n\t\tstart: ({ sui }) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst publisher = yield* ArtifactPublisherService;\n\t\t\t\tconst registry = yield* CoinRegistryService;\n\t\t\t\tconst form: CoinAddressForm = { kind: 'known', fullCoinType };\n\t\t\t\treturn yield* acquireCoin(form, {\n\t\t\t\t\tregistry,\n\t\t\t\t\tsdk: projectCoinSdk(sui),\n\t\t\t\t\tchain: sui.chain,\n\t\t\t\t\tpublisher,\n\t\t\t\t});\n\t\t\t}),\n\t\terrorContributions: coinErrorContributions,\n\t\tcapabilities: ({ value }) => buildCapabilities(id, value),\n\t});\n};\n\n// ---------------------------------------------------------------------------\n// Form 3: coin.builtin('sui') — protocol-defined constant\n// ---------------------------------------------------------------------------\n\n/** Resolve a protocol-defined builtin coin. Currently `'sui'` only —\n * distilled-doc 13-coin.md Invariant 4: SUI is `0x2::sui::SUI`,\n * decimals=9. No RPC, no registry. */\nexport const builtin = <Name extends keyof typeof BUILTIN_COINS>(name: Name) => {\n\tconst symbol = name; // 'sui' today\n\tconst coinRef = resource<CoinResourceId<Name>, CoinValue>(coinResourceId(name));\n\treturn definePlugin({\n\t\tid: coinRef.id,\n\t\tdependsOn: { sui: suiResource },\n\t\trole: 'task',\n\t\tstart: ({ sui }) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst publisher = yield* ArtifactPublisherService;\n\t\t\t\tconst registry = yield* CoinRegistryService;\n\t\t\t\tconst form: CoinAddressForm = { kind: 'builtin', name };\n\t\t\t\treturn yield* acquireCoin(form, {\n\t\t\t\t\tregistry,\n\t\t\t\t\tsdk: projectCoinSdk(sui),\n\t\t\t\t\tchain: sui.chain,\n\t\t\t\t\tpublisher,\n\t\t\t\t});\n\t\t\t}),\n\t\terrorContributions: coinErrorContributions,\n\t\tcapabilities: ({ value }) => buildCapabilities(symbol, value),\n\t});\n};\n\n// ---------------------------------------------------------------------------\n// Public `coin` namespace\n// ---------------------------------------------------------------------------\n\n/** User-facing factory namespace. Three variants — see file header for\n * the rationale on not exposing a `coin(identifier)` form-guessing\n * entry. */\nexport const coin = {\n\tfromPackage,\n\tknown,\n\tbuiltin,\n} as const;\n\n// ---------------------------------------------------------------------------\n// Re-exports — advanced callers (Wallet, Faucet, Deepbook, examples)\n// ---------------------------------------------------------------------------\n\nexport type { CoinValue, CoinAddressForm } from './service.ts';\nexport type { ResolvedCoin, BuiltinCoinName } from './address-resolution.ts';\nexport { BUILTIN_COINS } from './address-resolution.ts';\n\nexport type { CoinRecord, CoinRegistry, CoinKey } from './registry.ts';\nexport {\n\tCOIN_REGISTRY_CAPABILITY_KEY,\n\tCoinRegistryService,\n\tcoinRegistryLayer,\n} from './registry.ts';\n\nexport type { CoinBindings } from './codegen.ts';\n\nexport type { DiscoveredCoin } from './discovery.ts';\nexport { discoverCoinsFromPublish } from './discovery.ts';\n\nexport type { MetadataSdkShim, OnchainCoinMetadata, CoinMetadataCache } from './metadata.ts';\nexport {\n\tOnchainCoinMetadataShape,\n\tMETADATA_FETCH_TIMEOUT_MS,\n\tMETADATA_RETRY_SCHEDULE,\n\tfetchCoinMetadataOnce,\n\tfetchCoinMetadataMany,\n\tmakeCoinMetadataCache,\n\tisBareCoinType,\n\tvalidateBareCoinType,\n} from './metadata.ts';\n\nexport type { MintInputs, MintResult, MintSigner, MintSdkShim, CachedMint } from './mint.ts';\nexport { performMint, MintedCoinVerifyShape, mintTxError, mintParseError } from './mint.ts';\n\nexport type { CoinError, CoinPhase } from './errors.ts';\nexport { coinError, COIN_ERROR_TAGS } from './errors.ts';\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugins/coin/index.ts"],"sourcesContent":["// Coin plugin — barrel + `coin(...)` factory family.\n//\n// Architecture (13-coin.md): Coin is the user-facing primitive family\n// for *addressing* custom Move coin types. It does NOT publish Move\n// modules itself — the Package plugin publishes; coin auto-discovery\n// (in `discovery.ts`) folds the publish output into the per-stack\n// `CoinRegistry`; this factory resolves user-supplied addresses\n// (witness / bare-type / builtin) against that registry plus the live RPC.\n//\n// User-facing factory shape — three variants mirroring the address\n// forms:\n//\n// coin.fromPackage(pkg, 'MOCK_USDC') // package member → registry\n// coin.known('0x...::deep::DEEP') // bare → live RPC\n// coin.builtin('sui') // protocol-defined constant\n//\n// (A `coin(identifier)` convenience entry is intentionally NOT\n// exposed — distilled-doc 13-coin.md Pain point #6 documents how the\n// \"guess the form from the string\" path is a footgun. The three-form\n// surface forces the user to make the disambiguation explicit at the\n// call site.)\n//\n// Resource id: `'coin:<package>/<witness>'` for package-scoped coins and\n// `'coin:<identifier>'` for known/builtin coins — one tag per declared\n// coin instance, so the substrate's compose-time dedup detects collisions\n// cleanly. Mirrors the Package plugin's per-instance resource identity.\n\nimport { createHash } from 'node:crypto';\n\nimport { Effect } from 'effect';\n\nimport { definePlugin, resource, type ResourceRef } from '../../api/define-plugin.ts';\nimport { pluginErrorContributions } from '../../api/plugin-errors.ts';\nimport type { CodegenableDecl } from '../../contracts/codegenable.ts';\nimport type { SnapshotableDecl } from '../../contracts/snapshotable.ts';\nimport type { StrategyContributorDecl } from '../../contracts/strategy-contributor.ts';\nimport { ArtifactPublisherService } from '../../substrate/runtime/artifact-publisher/index.ts';\nimport { suiResource } from '../sui/index.ts';\nimport type { SuiClient } from '../sui/index.ts';\nimport type { AccountFundingStrategy } from '../../contracts/funding-strategy.ts';\n\nimport { makeCoinCodegen, type CoinBindings } from './codegen.ts';\nimport { makeCoinSnapshotable } from './snapshot.ts';\nimport { CoinRegistryService } from './registry.ts';\nimport { COIN_ERROR_TAGS } from './errors.ts';\nimport { acquireCoin, type CoinAddressForm, type CoinValue } from './service.ts';\nimport { BUILTIN_COINS } from './address-resolution.ts';\nimport type { MetadataSdkShim } from './metadata.ts';\nimport type { MintSdkShim } from './mint.ts';\n\nconst coinErrorContributions = pluginErrorContributions(COIN_ERROR_TAGS);\n\nexport const coinFundingCapabilityKey = <FullType extends string>(\n\tfullCoinType: FullType,\n): `coinType:${FullType}` => `coinType:${fullCoinType}` as const;\n\n// ---------------------------------------------------------------------------\n// Resource — one per declared coin instance, keyed by explicit address form.\n// ---------------------------------------------------------------------------\n\n/** Resource id constructor. The symbolic name is part of the resource identity\n * so the substrate's compose-time dedup catches collisions. */\nexport const coinResourceId = <Sym extends string>(symbol: Sym): `coin:${Sym}` => `coin:${symbol}`;\n\nexport type CoinResourceId<Sym extends string> = `coin:${Sym}`;\n\n/** Maximum length of the readable prefix in a `coin.known(...)` resource\n * id. Two long coin types sharing this prefix length would silently\n * collide in the substrate's compose-time dedup (string equality on\n * the resource id), so beyond this length we append a short hash of\n * the full coin type to disambiguate. */\nconst COIN_KNOWN_PREFIX_MAX = 60;\n\n/** Length of the SHA-256 hex suffix appended to long `coin.known(...)`\n * resource ids. Eight chars (~32 bits) is the same width used by other\n * collision-disambiguation hashes in the package (e.g. router profile,\n * fork preimage suffixes). */\nconst COIN_KNOWN_HASH_SUFFIX_LEN = 8;\n\n/** Derive a stable, human-readable, collision-free resource-id segment\n * for `coin.known(fullCoinType)`. Short types pass through as the\n * readable `<addr>_<module>_<witness>` form; long types get a hash\n * suffix so two types sharing a 60-char prefix can coexist. */\nconst coinKnownResourceKey = (fullCoinType: string): string => {\n\tconst readable = fullCoinType.replace(/^0x/, '').replace(/::/g, '_');\n\tif (readable.length <= COIN_KNOWN_PREFIX_MAX) {\n\t\treturn readable;\n\t}\n\tconst hash = createHash('sha256')\n\t\t.update(fullCoinType)\n\t\t.digest('hex')\n\t\t.slice(0, COIN_KNOWN_HASH_SUFFIX_LEN);\n\t// The readable prefix is truncated to leave room for the `_` divider\n\t// (`-1`) and the hash suffix (`-COIN_KNOWN_HASH_SUFFIX_LEN`), so the\n\t// resulting `<prefix>_<hash>` id has total length\n\t// ≤ COIN_KNOWN_PREFIX_MAX — bounded and deterministic per input.\n\treturn `${readable.slice(0, COIN_KNOWN_PREFIX_MAX - COIN_KNOWN_HASH_SUFFIX_LEN - 1)}_${hash}`;\n};\n\ntype PackageNameOf<Pkg extends PackageMember> =\n\tPkg extends ResourceRef<`package:${infer Name}`, PackageMemberValue> ? Name : string;\n\ntype PackageCoinResourceKey<\n\tPkg extends PackageMember,\n\tWit extends string,\n> = `${PackageNameOf<Pkg>}/${Lowercase<Wit>}`;\n\nconst packageNameFromMember = <Pkg extends PackageMember>(pkg: Pkg): PackageNameOf<Pkg> =>\n\tpkg.id.slice('package:'.length) as PackageNameOf<Pkg>;\n\n// ---------------------------------------------------------------------------\n// SDK shim projection\n// ---------------------------------------------------------------------------\n//\n// The coin plugin's resolvers need three Sui surfaces: `core.getObject`\n// (mint verify probe), `core.getCoinMetadata` (bare-type address form),\n// and the opaque `client` (`Transaction.build({client})` in the mint\n// produce body).\n//\n// `sui.sdk.core.getObject` lives on the typed `SuiSdkShim` directly;\n// `getCoinMetadata` lives on the underlying `ClientWithCoreApi['core']`\n// reached via `sui.sdk.client.core`. Project both onto the combined\n// `MetadataSdkShim & MintSdkShim` here at the boundary.\n\nconst projectCoinSdk = (sui: SuiClient): MetadataSdkShim & MintSdkShim => ({\n\tcore: {\n\t\tgetObject: sui.sdk.core.getObject,\n\t\tgetCoinMetadata: (args) => sui.sdk.client.core.getCoinMetadata(args),\n\t\tlistCoins: sui.sdk.core.listCoins,\n\t},\n\tclient: sui.sdk.client,\n\t// Fork mode mints offline with explicit gas (sui-fork has no simulate).\n\tforkMode: sui.fork !== null,\n});\n\n// ---------------------------------------------------------------------------\n// Per-form capability builders — dynamic (POST-acquire). Receive the\n// resolved `CoinValue` so codegen bindings stamp the REAL fullCoinType\n// + decimals instead of placeholder values.\n// ---------------------------------------------------------------------------\n\nconst buildCapabilities = (symbol: string, resolved: CoinValue) => {\n\tconst bindings: CoinBindings = {\n\t\tsymbol: resolved.symbol ?? symbol,\n\t\tfullCoinType: resolved.fullCoinType,\n\t\tdecimals: resolved.decimals,\n\t\tsource: resolved.source,\n\t\t...(resolved.displayName !== undefined ? { displayName: resolved.displayName } : {}),\n\t\t...(resolved.iconUrl !== undefined ? { iconUrl: resolved.iconUrl } : {}),\n\t\t...(resolved.treasuryCapId !== undefined ? { treasuryCapId: resolved.treasuryCapId } : {}),\n\t\t...(resolved.metadataId !== undefined ? { metadataId: resolved.metadataId } : {}),\n\t\t...(resolved.packageId !== undefined ? { packageId: resolved.packageId } : {}),\n\t};\n\tconst snap: SnapshotableDecl = makeCoinSnapshotable({ symbol });\n\tconst codegen: CodegenableDecl<`coin/${string}`> = makeCoinCodegen({\n\t\tsymbol,\n\t\tresolved: bindings,\n\t});\n\t// Project the coin's narrow `{address, amount}`-shaped strategy\n\t// to the wider cross-plugin `AccountFundingStrategy` contract\n\t// (`{address, amount, account}`) at the capability boundary. The\n\t// coin publisher signs the mint via its own lease (see\n\t// `coin/service.ts → mint`), so `account` is dropped honestly\n\t// here — the type-level contract is satisfied structurally\n\t// without a misleading `as` cast on the contribution literal.\n\t// Direct consumers (e.g. deepbook seed funding) keep using the\n\t// narrow shape on `CoinValue.fundingStrategy` directly.\n\tconst narrowStrategy = resolved.fundingStrategy;\n\tconst fundingContribution =\n\t\tnarrowStrategy === undefined\n\t\t\t? []\n\t\t\t: [\n\t\t\t\t\t{\n\t\t\t\t\t\tkind: 'strategy-contributor',\n\t\t\t\t\t\tcapabilityKey: coinFundingCapabilityKey(resolved.fullCoinType),\n\t\t\t\t\t\tstrategy: {\n\t\t\t\t\t\t\t// usesAccountSigner: true — the coin strategy mints via\n\t\t\t\t\t\t\t// the publisher account's own `withTransactionSigner`,\n\t\t\t\t\t\t\t// which acquires the per-address lease\n\t\t\t\t\t\t\t// `account:<publisherAddress>` internally (service.ts\n\t\t\t\t\t\t\t// mint -> performMint -> signAndDispatch). The account\n\t\t\t\t\t\t\t// funding dispatcher must therefore NOT wrap the request\n\t\t\t\t\t\t\t// in its own `account:<fundedAddress>` lease. Two reasons:\n\t\t\t\t\t\t\t// 1. The funded account is a passive `recipient` in\n\t\t\t\t\t\t\t// `mint_and_transfer` — it neither signs nor\n\t\t\t\t\t\t\t// contributes objects, so the funded-address lease\n\t\t\t\t\t\t\t// serializes nothing; the publisher lease already\n\t\t\t\t\t\t\t// serializes the only account whose gas + treasury\n\t\t\t\t\t\t\t// cap the mint consumes.\n\t\t\t\t\t\t\t// 2. When the funded address IS the publisher address\n\t\t\t\t\t\t\t// (fund a publisher with a coin it published), the\n\t\t\t\t\t\t\t// dispatcher's `account:<funded>` lease and the\n\t\t\t\t\t\t\t// mint's `account:<publisher>` lease collapse to the\n\t\t\t\t\t\t\t// same non-reentrant key, so the inner acquire would\n\t\t\t\t\t\t\t// block forever. Owning the lease inside the strategy\n\t\t\t\t\t\t\t// (signalled by this flag) makes self-funding\n\t\t\t\t\t\t\t// single-acquire and deadlock-free while leaving the\n\t\t\t\t\t\t\t// cross-account path's mint + publisher lease\n\t\t\t\t\t\t\t// unchanged.\n\t\t\t\t\t\t\t// Mirrors deepbook's DEEP strategy (faucet-strategy.ts),\n\t\t\t\t\t\t\t// which sets the same flag and self-acquires via\n\t\t\t\t\t\t\t// `req.account.withTransactionSigner`.\n\t\t\t\t\t\t\tusesAccountSigner: true,\n\t\t\t\t\t\t\trequest: (req) =>\n\t\t\t\t\t\t\t\tnarrowStrategy.request({ address: req.address, amount: req.amount }),\n\t\t\t\t\t\t} satisfies AccountFundingStrategy,\n\t\t\t\t\t\tautoMounted: true,\n\t\t\t\t\t} satisfies StrategyContributorDecl<`coinType:${string}`, AccountFundingStrategy>,\n\t\t\t\t];\n\treturn [snap, codegen, ...fundingContribution] as const;\n};\n\n// ---------------------------------------------------------------------------\n// Form 1: coin.fromPackage(pkg, witness) — package-scoped registry lookup\n// ---------------------------------------------------------------------------\n\n/** A user-supplied package ref. The user passes the result of\n * `localPackage('foo', …)` / `knownPackage('foo', …)` — NOT a bare string\n * value. Generic over the literal package name so the witness-form\n * coin's dependency preserves the per-package resource id. */\nexport interface PackageMemberValue {\n\treadonly name: string;\n\treadonly packageId: string;\n\treadonly publisher?: import('./mint.ts').MintSigner;\n}\n\nexport type PackageMember<Name extends string = string> = ResourceRef<\n\t`package:${Name}`,\n\tPackageMemberValue\n>;\n\n/** Resolve a coin by `(publishing package member, witness)`. Forces\n * a dep edge on the publishing package's resource — the substrate ensures\n * the publish has completed before this resolves.\n *\n * Resource identity includes both the package's symbolic name and the\n * witness name, so two packages can expose the same witness without\n * colliding in the substrate graph.\n *\n * Pass the package MEMBER (the value returned by `localPackage(...)`\n * / `knownPackage(...)`). The factory\n * projects it to a dependency resource and receives the package value\n * in `start`. */\nexport const fromPackage = <const Pkg extends PackageMember, Wit extends string>(\n\tpkg: Pkg,\n\twitnessName: Wit,\n) => {\n\tconst packageName = packageNameFromMember(pkg);\n\tconst symbol = witnessName.toLowerCase() as Lowercase<Wit>;\n\tconst resourceKey = `${packageName}/${symbol}` as PackageCoinResourceKey<Pkg, Wit>;\n\tconst coinRef = resource<CoinResourceId<typeof resourceKey>, CoinValue>(\n\t\tcoinResourceId(resourceKey),\n\t);\n\treturn definePlugin({\n\t\tid: coinRef.id,\n\t\tdependsOn: { pkg, sui: suiResource },\n\t\trole: 'task',\n\t\t// Coin lifecycle is action-shaped — uses the action section bucket;\n\t\t// see substrate/projection.ts `RowSection` for the canonical list.\n\t\t// All three coin factories (`fromPackage` / `known` / `builtin`)\n\t\t// share this deliberate bucketing; promoting to a dedicated\n\t\t// `'coin'` section would ripple through every projection / TUI\n\t\t// consumer for marginal display value.\n\t\tsection: 'action',\n\t\tstart: ({ pkg: resolved, sui }) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst artifactPublisher = yield* ArtifactPublisherService;\n\t\t\t\tconst registry = yield* CoinRegistryService;\n\t\t\t\tconst form: CoinAddressForm = {\n\t\t\t\t\tkind: 'witness',\n\t\t\t\t\tpublishingPackageName: resolved.name,\n\t\t\t\t\twitness: witnessName,\n\t\t\t\t\t...(resolved.publisher === undefined ? {} : { fundingSigner: resolved.publisher }),\n\t\t\t\t};\n\t\t\t\treturn yield* acquireCoin(form, {\n\t\t\t\t\tregistry,\n\t\t\t\t\tsdk: projectCoinSdk(sui),\n\t\t\t\t\tchain: sui.chain,\n\t\t\t\t\tpublisher: artifactPublisher,\n\t\t\t\t});\n\t\t\t}),\n\t\terrorContributions: coinErrorContributions,\n\t\tcapabilities: ({ value }) => buildCapabilities(symbol, value),\n\t});\n};\n\n// ---------------------------------------------------------------------------\n// Form 2: coin.known(fullCoinType) — bare on-chain type\n// ---------------------------------------------------------------------------\n\n/** Resolve a coin by bare on-chain type via `getCoinMetadata`.\n * Used for live-net coins (mainnet DEEP, USDC etc.) that no local\n * `Package(...)` publishes.\n *\n * Soft-degrades to `decimals: 0` on RPC failure — distilled-doc\n * invariant. Resource id uses a deterministic-but-readable derivation of\n * the coin type so collisions surface at compose time. */\nexport const known = <FullType extends string>(fullCoinType: FullType) => {\n\t// Derive a resource id from the type: keep it readable but unique.\n\t// The substrate's compose-time dedup uses string equality on the id,\n\t// so two long coin types that share a 60-char prefix MUST NOT collide.\n\t// When the projection truncates, append a short hash of the FULL coin\n\t// type so the suffix disambiguates the two — the readable prefix\n\t// stays human-recognizable while the hash guarantees uniqueness.\n\tconst id = coinKnownResourceKey(fullCoinType);\n\tconst coinRef = resource<CoinResourceId<typeof id>, CoinValue>(\n\t\tcoinResourceId(id) as CoinResourceId<typeof id>,\n\t);\n\treturn definePlugin({\n\t\tid: coinRef.id,\n\t\tdependsOn: { sui: suiResource },\n\t\trole: 'task',\n\t\tsection: 'action',\n\t\tstart: ({ sui }) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst publisher = yield* ArtifactPublisherService;\n\t\t\t\tconst registry = yield* CoinRegistryService;\n\t\t\t\tconst form: CoinAddressForm = { kind: 'known', fullCoinType };\n\t\t\t\treturn yield* acquireCoin(form, {\n\t\t\t\t\tregistry,\n\t\t\t\t\tsdk: projectCoinSdk(sui),\n\t\t\t\t\tchain: sui.chain,\n\t\t\t\t\tpublisher,\n\t\t\t\t});\n\t\t\t}),\n\t\terrorContributions: coinErrorContributions,\n\t\tcapabilities: ({ value }) => buildCapabilities(id, value),\n\t});\n};\n\n// ---------------------------------------------------------------------------\n// Form 3: coin.builtin('sui') — protocol-defined constant\n// ---------------------------------------------------------------------------\n\n/** Resolve a protocol-defined builtin coin. Currently `'sui'` only —\n * distilled-doc 13-coin.md Invariant 4: SUI is `0x2::sui::SUI`,\n * decimals=9. No RPC, no registry. */\nexport const builtin = <Name extends keyof typeof BUILTIN_COINS>(name: Name) => {\n\tconst symbol = name; // 'sui' today\n\tconst coinRef = resource<CoinResourceId<Name>, CoinValue>(coinResourceId(name));\n\treturn definePlugin({\n\t\tid: coinRef.id,\n\t\tdependsOn: { sui: suiResource },\n\t\trole: 'task',\n\t\tsection: 'action',\n\t\tstart: ({ sui }) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst publisher = yield* ArtifactPublisherService;\n\t\t\t\tconst registry = yield* CoinRegistryService;\n\t\t\t\tconst form: CoinAddressForm = { kind: 'builtin', name };\n\t\t\t\treturn yield* acquireCoin(form, {\n\t\t\t\t\tregistry,\n\t\t\t\t\tsdk: projectCoinSdk(sui),\n\t\t\t\t\tchain: sui.chain,\n\t\t\t\t\tpublisher,\n\t\t\t\t});\n\t\t\t}),\n\t\terrorContributions: coinErrorContributions,\n\t\tcapabilities: ({ value }) => buildCapabilities(symbol, value),\n\t});\n};\n\n// ---------------------------------------------------------------------------\n// Public `coin` namespace\n// ---------------------------------------------------------------------------\n\n/** User-facing factory namespace. Three variants — see file header for\n * the rationale on not exposing a `coin(identifier)` form-guessing\n * entry. */\nexport const coin = {\n\tfromPackage,\n\tknown,\n\tbuiltin,\n} as const;\n\n// ---------------------------------------------------------------------------\n// Re-exports — advanced callers (Wallet, Faucet, Deepbook, examples)\n// ---------------------------------------------------------------------------\n\nexport type { CoinValue, CoinAddressForm } from './service.ts';\nexport type { ResolvedCoin, BuiltinCoinName } from './address-resolution.ts';\nexport { BUILTIN_COINS } from './address-resolution.ts';\n\nexport type { CoinRecord, CoinRegistry, CoinKey } from './registry.ts';\nexport { CoinRegistryService, layerCoinRegistry } from './registry.ts';\n\nexport type { CoinBindings } from './codegen.ts';\n\nexport type { DiscoveredCoin } from './discovery.ts';\nexport { discoverCoinsFromPublish } from './discovery.ts';\n\nexport type { MetadataSdkShim, OnchainCoinMetadata, CoinMetadataCache } from './metadata.ts';\nexport {\n\tOnchainCoinMetadataShape,\n\tMETADATA_FETCH_TIMEOUT_MS,\n\tMETADATA_RETRY_SCHEDULE,\n\tfetchCoinMetadataOnce,\n\tfetchCoinMetadataMany,\n\tmakeCoinMetadataCache,\n\tisBareCoinType,\n\tvalidateBareCoinType,\n} from './metadata.ts';\n\nexport type { MintInputs, MintResult, MintSigner, MintSdkShim, CachedMint } from './mint.ts';\nexport { performMint, MintedCoinVerifyShape, mintTxError, mintParseError } from './mint.ts';\n\nexport type { CoinError, CoinPhase } from './errors.ts';\nexport { coinError, COIN_ERROR_TAGS } from './errors.ts';\n\nexport { CoinSpans } from './spans.ts';\n"],"mappings":"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"}
@@ -1,7 +1,9 @@
1
- import { decodeUnknown } from "../../substrate/runtime/runtime-decode.mjs";
2
1
  import { SpanAttr } from "../../substrate/runtime/observability/spans.mjs";
2
+ import { decodeUnknown } from "../../substrate/runtime/runtime-decode.mjs";
3
3
  import { makeSpacedRetrySchedule } from "../../substrate/runtime/retry-policy.mjs";
4
+ import { formatUnknownError } from "../../substrate/runtime/format-unknown-error.mjs";
4
5
  import { coinError } from "./errors.mjs";
6
+ import { CoinSpans } from "./spans.mjs";
5
7
  import { Effect, Schema } from "effect";
6
8
  //#region src/plugins/coin/metadata.ts
7
9
  /** Per-attempt timeout (5 seconds) — distilled-doc invariant. */
@@ -50,8 +52,8 @@ const fetchCoinMetadataOnce = (sdk, fullCoinType) => Effect.gen(function* () {
50
52
  })
51
53
  }), Effect.retry(METADATA_RETRY_SCHEDULE), Effect.catch((err) => {
52
54
  return Effect.logWarning("coin metadata fetch failed; soft-degrading to null").pipe(Effect.annotateLogs({
53
- [SpanAttr.coinType]: fullCoinType,
54
- [SpanAttr.errorCause]: stringifyCause(err.cause)
55
+ [CoinSpans.type]: fullCoinType,
56
+ [SpanAttr.errorCause]: formatUnknownError(err.cause)
55
57
  }), Effect.as(null));
56
58
  }));
57
59
  if (raw === null || raw === void 0) return null;
@@ -59,10 +61,10 @@ const fetchCoinMetadataOnce = (sdk, fullCoinType) => Effect.gen(function* () {
59
61
  source: "coin metadata RPC response",
60
62
  mkError: (issue) => issue
61
63
  }).pipe(Effect.catch((issue) => Effect.logWarning("coin metadata response had non-conforming shape; degrading to null").pipe(Effect.annotateLogs({
62
- [SpanAttr.coinType]: fullCoinType,
63
- [SpanAttr.errorCause]: stringifyCause(issue.cause ?? issue)
64
+ [CoinSpans.type]: fullCoinType,
65
+ [SpanAttr.errorCause]: formatUnknownError(issue.cause ?? issue)
64
66
  }), Effect.as(null))));
65
- }).pipe(Effect.withSpan("coin.metadata.fetch", { attributes: { fullCoinType } }));
67
+ }).pipe(Effect.withSpan("devstack.plugin.coin.metadata.fetch", { attributes: { [CoinSpans.metadata.fullCoinType]: fullCoinType } }));
66
68
  /** Bare-coin-type heuristic — distilled-doc 13-coin.md Invariant 3.
67
69
  *
68
70
  * MUST agree with what `getCoinMetadata` accepts as a coin-type
@@ -84,15 +86,6 @@ const validateBareCoinType = (identifier) => {
84
86
  });
85
87
  return null;
86
88
  };
87
- const stringifyCause = (cause) => {
88
- if (cause instanceof Error) return cause.message;
89
- if (typeof cause === "string") return cause;
90
- try {
91
- return JSON.stringify(cause);
92
- } catch {
93
- return String(cause);
94
- }
95
- };
96
89
  //#endregion
97
90
  export { METADATA_FETCH_TIMEOUT_MS, METADATA_RETRY_SCHEDULE, OnchainCoinMetadataShape, fetchCoinMetadataOnce, isBareCoinType, validateBareCoinType };
98
91