@mysten-incubation/devstack 0.1.0 → 0.2.0

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 (858) hide show
  1. package/README.md +7 -4
  2. package/dashboard-ui/assets/grpc-a4usE3Nk.js +3 -0
  3. package/dashboard-ui/assets/index-B82Bh84P.css +1 -0
  4. package/dashboard-ui/assets/index-CRYJ4pru.js +1277 -0
  5. package/dashboard-ui/index.html +2 -2
  6. package/dist/api/define-capabilities.d.mts +1 -20
  7. package/dist/api/define-capabilities.mjs +15 -22
  8. package/dist/api/define-capabilities.mjs.map +1 -1
  9. package/dist/api/define-devstack-with.d.mts +7 -1
  10. package/dist/api/define-devstack-with.mjs.map +1 -1
  11. package/dist/api/define-devstack.mjs.map +1 -1
  12. package/dist/api/define-plugin.d.mts +2 -1
  13. package/dist/api/inference-network.d.mts +31 -17
  14. package/dist/api/inference-network.mjs +40 -43
  15. package/dist/api/inference-network.mjs.map +1 -1
  16. package/dist/api/load-config.mjs +88 -0
  17. package/dist/api/load-config.mjs.map +1 -0
  18. package/dist/api/mode-narrowed-factory.d.mts +1 -1
  19. package/dist/api/mode-narrowed-factory.mjs.map +1 -1
  20. package/dist/api/run-stack-internal.mjs +202 -0
  21. package/dist/api/run-stack-internal.mjs.map +1 -0
  22. package/dist/api/run-stack.d.mts +82 -31
  23. package/dist/api/run-stack.mjs +22 -141
  24. package/dist/api/run-stack.mjs.map +1 -1
  25. package/dist/build-integrations/dapp-kit/index.d.mts +61 -0
  26. package/dist/build-integrations/dapp-kit/index.mjs +58 -0
  27. package/dist/build-integrations/dapp-kit/index.mjs.map +1 -0
  28. package/dist/build-integrations/playwright/config.d.mts +1 -30
  29. package/dist/build-integrations/playwright/config.mjs +1 -27
  30. package/dist/build-integrations/playwright/config.mjs.map +1 -1
  31. package/dist/build-integrations/playwright/errors.d.mts +4 -7
  32. package/dist/build-integrations/playwright/errors.mjs.map +1 -1
  33. package/dist/build-integrations/playwright/global-setup.d.mts +42 -71
  34. package/dist/build-integrations/playwright/global-setup.mjs +142 -218
  35. package/dist/build-integrations/playwright/global-setup.mjs.map +1 -1
  36. package/dist/build-integrations/playwright/index.d.mts +2 -2
  37. package/dist/build-integrations/playwright/index.mjs +2 -2
  38. package/dist/build-integrations/playwright/stack-context.d.mts +3 -1
  39. package/dist/build-integrations/playwright/stack-context.mjs +4 -2
  40. package/dist/build-integrations/playwright/stack-context.mjs.map +1 -1
  41. package/dist/build-integrations/playwright/wallet-context.mjs +44 -19
  42. package/dist/build-integrations/playwright/wallet-context.mjs.map +1 -1
  43. package/dist/build-integrations/runtime/cold-start-url.mjs.map +1 -1
  44. package/dist/build-integrations/runtime/conventional-routes.mjs.map +1 -1
  45. package/dist/build-integrations/runtime/dapp-kit-slot.mjs.map +1 -1
  46. package/dist/build-integrations/runtime/discover.d.mts +6 -4
  47. package/dist/build-integrations/runtime/discover.mjs +15 -4
  48. package/dist/build-integrations/runtime/discover.mjs.map +1 -1
  49. package/dist/build-integrations/runtime/endpoint-registry.mjs.map +1 -1
  50. package/dist/build-integrations/runtime/errors.mjs.map +1 -1
  51. package/dist/build-integrations/runtime/read-stack-context.mjs +3 -3
  52. package/dist/build-integrations/runtime/read-stack-context.mjs.map +1 -1
  53. package/dist/build-integrations/runtime/resolve-discovery-env.d.mts +23 -7
  54. package/dist/build-integrations/runtime/resolve-discovery-env.mjs +25 -12
  55. package/dist/build-integrations/runtime/resolve-discovery-env.mjs.map +1 -1
  56. package/dist/build-integrations/runtime/stack-context.d.mts +2 -2
  57. package/dist/build-integrations/vite/index.d.mts +84 -19
  58. package/dist/build-integrations/vite/index.mjs +203 -28
  59. package/dist/build-integrations/vite/index.mjs.map +1 -1
  60. package/dist/build-integrations/vitest/config.d.mts +20 -2
  61. package/dist/build-integrations/vitest/config.mjs +16 -4
  62. package/dist/build-integrations/vitest/config.mjs.map +1 -1
  63. package/dist/build-integrations/vitest/env.d.mts +18 -10
  64. package/dist/build-integrations/vitest/env.mjs +11 -10
  65. package/dist/build-integrations/vitest/env.mjs.map +1 -1
  66. package/dist/build-integrations/vitest/errors.d.mts +7 -11
  67. package/dist/build-integrations/vitest/errors.mjs +3 -4
  68. package/dist/build-integrations/vitest/errors.mjs.map +1 -1
  69. package/dist/build-integrations/vitest/global-setup.d.mts +35 -0
  70. package/dist/build-integrations/vitest/global-setup.mjs +156 -0
  71. package/dist/build-integrations/vitest/global-setup.mjs.map +1 -0
  72. package/dist/build-integrations/vitest/index.d.mts +3 -2
  73. package/dist/build-integrations/vitest/index.mjs +3 -2
  74. package/dist/build-integrations/vitest/setup.mjs +2 -2
  75. package/dist/build-integrations/vitest/setup.mjs.map +1 -1
  76. package/dist/build-integrations/vitest/stack-context.d.mts +5 -3
  77. package/dist/build-integrations/vitest/stack-context.mjs +3 -2
  78. package/dist/build-integrations/vitest/stack-context.mjs.map +1 -1
  79. package/dist/cli/bail.mjs.map +1 -1
  80. package/dist/cli/doctor-probes.mjs +1 -3
  81. package/dist/cli/doctor-probes.mjs.map +1 -1
  82. package/dist/cli/main.d.mts +23 -1
  83. package/dist/cli/main.mjs +63 -8
  84. package/dist/cli/main.mjs.map +1 -1
  85. package/dist/cli/prune-direct.mjs.map +1 -1
  86. package/dist/cli/snapshot-reader.mjs.map +1 -1
  87. package/dist/cli/up-lifecycle.mjs.map +1 -1
  88. package/dist/cli/wirings/apply.mjs +28 -21
  89. package/dist/cli/wirings/apply.mjs.map +1 -1
  90. package/dist/cli/wirings/codegen.mjs +108 -0
  91. package/dist/cli/wirings/codegen.mjs.map +1 -0
  92. package/dist/cli/wirings/config-loader.mjs +12 -62
  93. package/dist/cli/wirings/config-loader.mjs.map +1 -1
  94. package/dist/cli/wirings/dump-ids.mjs +86 -0
  95. package/dist/cli/wirings/dump-ids.mjs.map +1 -0
  96. package/dist/cli/wirings/engine-command.mjs +1 -1
  97. package/dist/cli/wirings/engine-command.mjs.map +1 -1
  98. package/dist/cli/wirings/identity.mjs +2 -2
  99. package/dist/cli/wirings/identity.mjs.map +1 -1
  100. package/dist/cli/wirings/provide-file-system.mjs.map +1 -1
  101. package/dist/cli/wirings/read-devstack-version.mjs +17 -0
  102. package/dist/cli/wirings/read-devstack-version.mjs.map +1 -0
  103. package/dist/cli/wirings/snapshot.mjs +27 -34
  104. package/dist/cli/wirings/snapshot.mjs.map +1 -1
  105. package/dist/cli/wirings/up-ipc.mjs +147 -0
  106. package/dist/cli/wirings/up-ipc.mjs.map +1 -0
  107. package/dist/cli/wirings/up.mjs +218 -198
  108. package/dist/cli/wirings/up.mjs.map +1 -1
  109. package/dist/cli/wirings/wipe.mjs +1 -1
  110. package/dist/cli/wirings/wipe.mjs.map +1 -1
  111. package/dist/contracts/chain-probe.d.mts +1 -1
  112. package/dist/contracts/chain-probe.mjs +1 -1
  113. package/dist/contracts/chain-probe.mjs.map +1 -1
  114. package/dist/contracts/codegenable.d.mts +60 -6
  115. package/dist/contracts/codegenable.mjs +28 -0
  116. package/dist/contracts/codegenable.mjs.map +1 -0
  117. package/dist/contracts/config-bindings.mjs +162 -0
  118. package/dist/contracts/config-bindings.mjs.map +1 -0
  119. package/dist/contracts/container-runtime.d.mts +23 -17
  120. package/dist/contracts/plugin-expander.mjs.map +1 -1
  121. package/dist/contracts/snapshotable.d.mts +5 -7
  122. package/dist/contracts/wallet-protocol.d.mts +2 -5
  123. package/dist/contracts/wallet-protocol.mjs +2 -5
  124. package/dist/contracts/wallet-protocol.mjs.map +1 -1
  125. package/dist/index.d.mts +21 -26
  126. package/dist/index.mjs +8 -9
  127. package/dist/orchestrators/boot.d.mts +28 -0
  128. package/dist/orchestrators/boot.mjs +440 -0
  129. package/dist/orchestrators/boot.mjs.map +1 -0
  130. package/dist/orchestrators/codegen/bindings.d.mts +13 -1
  131. package/dist/orchestrators/codegen/bindings.mjs +23 -9
  132. package/dist/orchestrators/codegen/bindings.mjs.map +1 -1
  133. package/dist/orchestrators/codegen/config-runtime.mjs +208 -0
  134. package/dist/orchestrators/codegen/config-runtime.mjs.map +1 -0
  135. package/dist/orchestrators/codegen/emit.mjs +1 -1
  136. package/dist/orchestrators/codegen/emit.mjs.map +1 -1
  137. package/dist/orchestrators/codegen/errors.mjs +21 -1
  138. package/dist/orchestrators/codegen/errors.mjs.map +1 -1
  139. package/dist/orchestrators/codegen/format.mjs +2 -0
  140. package/dist/orchestrators/codegen/format.mjs.map +1 -1
  141. package/dist/orchestrators/codegen/gitignore.mjs +30 -11
  142. package/dist/orchestrators/codegen/gitignore.mjs.map +1 -1
  143. package/dist/orchestrators/codegen/id-config.mjs +107 -0
  144. package/dist/orchestrators/codegen/id-config.mjs.map +1 -0
  145. package/dist/orchestrators/codegen/output-location.mjs +23 -31
  146. package/dist/orchestrators/codegen/output-location.mjs.map +1 -1
  147. package/dist/orchestrators/codegen/paths.mjs +8 -1
  148. package/dist/orchestrators/codegen/paths.mjs.map +1 -1
  149. package/dist/orchestrators/codegen/permissions.mjs.map +1 -1
  150. package/dist/orchestrators/codegen/service.mjs +286 -58
  151. package/dist/orchestrators/codegen/service.mjs.map +1 -1
  152. package/dist/orchestrators/layers.mjs +31 -0
  153. package/dist/orchestrators/layers.mjs.map +1 -0
  154. package/dist/orchestrators/lifecycle-prune/errors.mjs.map +1 -1
  155. package/dist/orchestrators/lifecycle-prune/index.mjs +8 -10
  156. package/dist/orchestrators/lifecycle-prune/index.mjs.map +1 -1
  157. package/dist/orchestrators/network-options.d.mts +52 -0
  158. package/dist/orchestrators/network-options.mjs +43 -0
  159. package/dist/orchestrators/network-options.mjs.map +1 -0
  160. package/dist/orchestrators/router/cleanup.mjs.map +1 -1
  161. package/dist/orchestrators/router/cors.mjs.map +1 -1
  162. package/dist/orchestrators/router/entrypoints.mjs.map +1 -1
  163. package/dist/orchestrators/router/errors.mjs.map +1 -1
  164. package/dist/orchestrators/router/file-provider.mjs.map +1 -1
  165. package/dist/orchestrators/router/hostname.mjs.map +1 -1
  166. package/dist/orchestrators/router/profile.mjs +1 -1
  167. package/dist/orchestrators/router/profile.mjs.map +1 -1
  168. package/dist/orchestrators/router/service.d.mts +2 -2
  169. package/dist/orchestrators/router/service.mjs +12 -27
  170. package/dist/orchestrators/router/service.mjs.map +1 -1
  171. package/dist/orchestrators/router/traefik-container.mjs +1 -1
  172. package/dist/orchestrators/router/traefik-container.mjs.map +1 -1
  173. package/dist/orchestrators/snapshot/capture.mjs +171 -195
  174. package/dist/orchestrators/snapshot/capture.mjs.map +1 -1
  175. package/dist/orchestrators/snapshot/descriptor.d.mts +1 -1
  176. package/dist/orchestrators/snapshot/descriptor.mjs +53 -11
  177. package/dist/orchestrators/snapshot/descriptor.mjs.map +1 -1
  178. package/dist/orchestrators/snapshot/identity-guard.mjs +3 -5
  179. package/dist/orchestrators/snapshot/identity-guard.mjs.map +1 -1
  180. package/dist/orchestrators/snapshot/image-bundle-tags.mjs +32 -101
  181. package/dist/orchestrators/snapshot/image-bundle-tags.mjs.map +1 -1
  182. package/dist/orchestrators/snapshot/index.mjs +1 -4
  183. package/dist/orchestrators/snapshot/integrity.mjs.map +1 -1
  184. package/dist/orchestrators/snapshot/interrupted-restore.mjs +116 -0
  185. package/dist/orchestrators/snapshot/interrupted-restore.mjs.map +1 -0
  186. package/dist/orchestrators/snapshot/phase-error.mjs.map +1 -1
  187. package/dist/orchestrators/snapshot/prune.mjs +40 -31
  188. package/dist/orchestrators/snapshot/prune.mjs.map +1 -1
  189. package/dist/orchestrators/snapshot/restore.mjs +221 -196
  190. package/dist/orchestrators/snapshot/restore.mjs.map +1 -1
  191. package/dist/orchestrators/snapshot/service.mjs +72 -62
  192. package/dist/orchestrators/snapshot/service.mjs.map +1 -1
  193. package/dist/orchestrators/snapshot/wipe.mjs +67 -56
  194. package/dist/orchestrators/snapshot/wipe.mjs.map +1 -1
  195. package/dist/plugins/account/codegen.mjs +3 -0
  196. package/dist/plugins/account/codegen.mjs.map +1 -1
  197. package/dist/plugins/account/errors.d.mts +2 -2
  198. package/dist/plugins/account/errors.mjs +1 -4
  199. package/dist/plugins/account/errors.mjs.map +1 -1
  200. package/dist/plugins/account/funding.mjs +3 -27
  201. package/dist/plugins/account/funding.mjs.map +1 -1
  202. package/dist/plugins/account/index.d.mts +3 -8
  203. package/dist/plugins/account/index.mjs +71 -35
  204. package/dist/plugins/account/index.mjs.map +1 -1
  205. package/dist/plugins/account/keypair.d.mts +8 -7
  206. package/dist/plugins/account/keypair.mjs +5 -18
  207. package/dist/plugins/account/keypair.mjs.map +1 -1
  208. package/dist/plugins/account/lease.mjs.map +1 -1
  209. package/dist/plugins/account/registry.d.mts +1 -46
  210. package/dist/plugins/account/registry.mjs.map +1 -1
  211. package/dist/plugins/account/service.d.mts +43 -34
  212. package/dist/plugins/account/service.mjs +9 -54
  213. package/dist/plugins/account/service.mjs.map +1 -1
  214. package/dist/plugins/account/snapshot.mjs.map +1 -1
  215. package/dist/plugins/account/variants/ephemeral.mjs.map +1 -1
  216. package/dist/plugins/account/variants/impersonate.mjs.map +1 -1
  217. package/dist/plugins/account/variants/signer.mjs.map +1 -1
  218. package/dist/plugins/action/discriminator.mjs.map +1 -1
  219. package/dist/plugins/action/errors.mjs +1 -4
  220. package/dist/plugins/action/errors.mjs.map +1 -1
  221. package/dist/plugins/action/execute.mjs +3 -4
  222. package/dist/plugins/action/execute.mjs.map +1 -1
  223. package/dist/plugins/action/index.d.mts +2 -2
  224. package/dist/plugins/action/index.mjs +7 -11
  225. package/dist/plugins/action/index.mjs.map +1 -1
  226. package/dist/plugins/action/service.d.mts +5 -7
  227. package/dist/plugins/action/service.mjs +2 -16
  228. package/dist/plugins/action/service.mjs.map +1 -1
  229. package/dist/plugins/coin/address-resolution.mjs.map +1 -1
  230. package/dist/plugins/coin/codegen.mjs +97 -16
  231. package/dist/plugins/coin/codegen.mjs.map +1 -1
  232. package/dist/plugins/coin/discovery.mjs.map +1 -1
  233. package/dist/plugins/coin/errors.mjs +1 -4
  234. package/dist/plugins/coin/errors.mjs.map +1 -1
  235. package/dist/plugins/coin/index.d.mts +4 -34
  236. package/dist/plugins/coin/index.mjs +47 -28
  237. package/dist/plugins/coin/index.mjs.map +1 -1
  238. package/dist/plugins/coin/metadata.d.mts +1 -0
  239. package/dist/plugins/coin/metadata.mjs +8 -9
  240. package/dist/plugins/coin/metadata.mjs.map +1 -1
  241. package/dist/plugins/coin/mint.mjs +7 -21
  242. package/dist/plugins/coin/mint.mjs.map +1 -1
  243. package/dist/plugins/coin/registry.mjs +33 -20
  244. package/dist/plugins/coin/registry.mjs.map +1 -1
  245. package/dist/plugins/coin/service.d.mts +1 -1
  246. package/dist/plugins/coin/service.mjs +1 -8
  247. package/dist/plugins/coin/service.mjs.map +1 -1
  248. package/dist/plugins/coin/snapshot.mjs.map +1 -1
  249. package/dist/plugins/coin/type-strings.mjs.map +1 -1
  250. package/dist/plugins/dashboard/domain.mjs +106 -167
  251. package/dist/plugins/dashboard/domain.mjs.map +1 -1
  252. package/dist/plugins/dashboard/index.mjs +13 -13
  253. package/dist/plugins/dashboard/index.mjs.map +1 -1
  254. package/dist/plugins/dashboard/origin-policy.mjs +3 -3
  255. package/dist/plugins/dashboard/origin-policy.mjs.map +1 -1
  256. package/dist/plugins/dashboard/routable.mjs.map +1 -1
  257. package/dist/plugins/dashboard/schema/builder.mjs.map +1 -1
  258. package/dist/plugins/dashboard/schema/enums.mjs.map +1 -1
  259. package/dist/plugins/dashboard/schema/root.mjs +23 -44
  260. package/dist/plugins/dashboard/schema/root.mjs.map +1 -1
  261. package/dist/plugins/dashboard/schema/types.mjs +37 -91
  262. package/dist/plugins/dashboard/schema/types.mjs.map +1 -1
  263. package/dist/plugins/dashboard/schema.mjs.map +1 -1
  264. package/dist/plugins/dashboard/server.mjs.map +1 -1
  265. package/dist/plugins/deepbook/codegen.d.mts +12 -11
  266. package/dist/plugins/deepbook/codegen.mjs +108 -11
  267. package/dist/plugins/deepbook/codegen.mjs.map +1 -1
  268. package/dist/plugins/deepbook/deploy.mjs +7 -14
  269. package/dist/plugins/deepbook/deploy.mjs.map +1 -1
  270. package/dist/plugins/deepbook/errors.mjs +4 -2
  271. package/dist/plugins/deepbook/errors.mjs.map +1 -1
  272. package/dist/plugins/deepbook/faucet-strategy.mjs +4 -10
  273. package/dist/plugins/deepbook/faucet-strategy.mjs.map +1 -1
  274. package/dist/plugins/deepbook/hash.mjs.map +1 -1
  275. package/dist/plugins/deepbook/index.d.mts +38 -34
  276. package/dist/plugins/deepbook/index.mjs +133 -64
  277. package/dist/plugins/deepbook/index.mjs.map +1 -1
  278. package/dist/plugins/deepbook/plugin-key.mjs.map +1 -1
  279. package/dist/plugins/deepbook/pyth/index.mjs +4 -8
  280. package/dist/plugins/deepbook/pyth/index.mjs.map +1 -1
  281. package/dist/plugins/deepbook/snapshot.mjs +0 -1
  282. package/dist/plugins/deepbook/snapshot.mjs.map +1 -1
  283. package/dist/plugins/deepbook/type-strings.mjs.map +1 -1
  284. package/dist/plugins/deepbook/types.d.mts +2 -1
  285. package/dist/plugins/deepbook/types.mjs.map +1 -1
  286. package/dist/plugins/faucet/dispatcher.d.mts +3 -3
  287. package/dist/plugins/faucet/dispatcher.mjs.map +1 -1
  288. package/dist/plugins/faucet/errors.mjs.map +1 -1
  289. package/dist/plugins/faucet/http.mjs +2 -10
  290. package/dist/plugins/faucet/http.mjs.map +1 -1
  291. package/dist/plugins/faucet/index.mjs +0 -1
  292. package/dist/plugins/faucet/index.mjs.map +1 -1
  293. package/dist/plugins/host-service/errors.d.mts +1 -3
  294. package/dist/plugins/host-service/errors.mjs +1 -2
  295. package/dist/plugins/host-service/errors.mjs.map +1 -1
  296. package/dist/plugins/host-service/index.d.mts +1 -2
  297. package/dist/plugins/host-service/index.mjs +11 -11
  298. package/dist/plugins/host-service/index.mjs.map +1 -1
  299. package/dist/plugins/host-service/routable.mjs.map +1 -1
  300. package/dist/plugins/host-service/service.mjs +13 -13
  301. package/dist/plugins/host-service/service.mjs.map +1 -1
  302. package/dist/plugins/internal/acquire-on-chain-artifact.mjs.map +1 -1
  303. package/dist/plugins/internal/codegen-helpers.mjs +2 -0
  304. package/dist/plugins/internal/codegen-helpers.mjs.map +1 -1
  305. package/dist/plugins/internal/funding-failure-error.mjs.map +1 -1
  306. package/dist/plugins/{postgres → internal/postgres-sidecar}/connection.mjs +1 -1
  307. package/dist/plugins/internal/postgres-sidecar/connection.mjs.map +1 -0
  308. package/dist/plugins/{postgres → internal/postgres-sidecar}/db-ensure.mjs +30 -16
  309. package/dist/plugins/internal/postgres-sidecar/db-ensure.mjs.map +1 -0
  310. package/dist/plugins/internal/postgres-sidecar/errors.mjs +21 -0
  311. package/dist/plugins/internal/postgres-sidecar/errors.mjs.map +1 -0
  312. package/dist/{substrate/runtime/scoped-multimap → plugins/internal/postgres-sidecar}/index.mjs +1 -0
  313. package/dist/plugins/internal/postgres-sidecar/service.mjs +121 -0
  314. package/dist/plugins/internal/postgres-sidecar/service.mjs.map +1 -0
  315. package/dist/plugins/package/build.mjs +2 -2
  316. package/dist/plugins/package/build.mjs.map +1 -1
  317. package/dist/plugins/package/codegen.d.mts +7 -14
  318. package/dist/plugins/package/codegen.mjs +187 -59
  319. package/dist/plugins/package/codegen.mjs.map +1 -1
  320. package/dist/plugins/package/dep-resolution.mjs +51 -3
  321. package/dist/plugins/package/dep-resolution.mjs.map +1 -1
  322. package/dist/plugins/package/errors.mjs +1 -4
  323. package/dist/plugins/package/errors.mjs.map +1 -1
  324. package/dist/plugins/package/git-source.d.mts +18 -0
  325. package/dist/plugins/package/git-source.mjs +119 -0
  326. package/dist/plugins/package/git-source.mjs.map +1 -0
  327. package/dist/plugins/package/index.d.mts +28 -19
  328. package/dist/plugins/package/index.mjs +107 -32
  329. package/dist/plugins/package/index.mjs.map +1 -1
  330. package/dist/plugins/package/mode-known.mjs +2 -2
  331. package/dist/plugins/package/mode-known.mjs.map +1 -1
  332. package/dist/plugins/package/mode-local.mjs +18 -35
  333. package/dist/plugins/package/mode-local.mjs.map +1 -1
  334. package/dist/plugins/package/publish-executor.mjs +13 -8
  335. package/dist/plugins/package/publish-executor.mjs.map +1 -1
  336. package/dist/plugins/package/publish-output.d.mts +1 -11
  337. package/dist/plugins/package/publish-output.mjs +1 -9
  338. package/dist/plugins/package/publish-output.mjs.map +1 -1
  339. package/dist/plugins/package/registry.d.mts +1 -1
  340. package/dist/plugins/package/registry.mjs +26 -14
  341. package/dist/plugins/package/registry.mjs.map +1 -1
  342. package/dist/plugins/package/service.mjs.map +1 -1
  343. package/dist/plugins/package/snapshot.mjs.map +1 -1
  344. package/dist/plugins/router-entrypoints.mjs +1 -3
  345. package/dist/plugins/router-entrypoints.mjs.map +1 -1
  346. package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs +1 -2
  347. package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs.map +1 -1
  348. package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs +1 -6
  349. package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs.map +1 -1
  350. package/dist/plugins/seal/codegen.d.mts +1 -5
  351. package/dist/plugins/seal/codegen.mjs +83 -12
  352. package/dist/plugins/seal/codegen.mjs.map +1 -1
  353. package/dist/plugins/seal/config-render.mjs +2 -6
  354. package/dist/plugins/seal/config-render.mjs.map +1 -1
  355. package/dist/plugins/seal/deploy.mjs +18 -29
  356. package/dist/plugins/seal/deploy.mjs.map +1 -1
  357. package/dist/plugins/seal/errors.d.mts +4 -5
  358. package/dist/plugins/seal/errors.mjs +1 -8
  359. package/dist/plugins/seal/errors.mjs.map +1 -1
  360. package/dist/plugins/seal/index.d.mts +7 -28
  361. package/dist/plugins/seal/index.mjs +69 -47
  362. package/dist/plugins/seal/index.mjs.map +1 -1
  363. package/dist/plugins/seal/key-manager.mjs.map +1 -1
  364. package/dist/plugins/seal/key-server.mjs +1 -6
  365. package/dist/plugins/seal/key-server.mjs.map +1 -1
  366. package/dist/plugins/seal/keygen.mjs +2 -3
  367. package/dist/plugins/seal/keygen.mjs.map +1 -1
  368. package/dist/plugins/seal/mode/fork-known.mjs.map +1 -1
  369. package/dist/plugins/seal/mode/live.mjs +1 -1
  370. package/dist/plugins/seal/mode/live.mjs.map +1 -1
  371. package/dist/plugins/seal/mode/local-keygen.mjs +4 -10
  372. package/dist/plugins/seal/mode/local-keygen.mjs.map +1 -1
  373. package/dist/plugins/seal/plugin-key.mjs.map +1 -1
  374. package/dist/plugins/seal/registry-publish.mjs.map +1 -1
  375. package/dist/plugins/seal/routable.mjs.map +1 -1
  376. package/dist/plugins/seal/service.mjs.map +1 -1
  377. package/dist/plugins/seal/snapshot.mjs +1 -2
  378. package/dist/plugins/seal/snapshot.mjs.map +1 -1
  379. package/dist/plugins/sui/auto-tick.mjs +5 -5
  380. package/dist/plugins/sui/auto-tick.mjs.map +1 -1
  381. package/dist/plugins/sui/chain-build-container.mjs +2 -2
  382. package/dist/plugins/sui/chain-build-container.mjs.map +1 -1
  383. package/dist/plugins/sui/chain-probe.mjs +4 -4
  384. package/dist/plugins/sui/chain-probe.mjs.map +1 -1
  385. package/dist/plugins/sui/codegen.d.mts +9 -7
  386. package/dist/plugins/sui/codegen.mjs +49 -46
  387. package/dist/plugins/sui/codegen.mjs.map +1 -1
  388. package/dist/plugins/sui/errors.d.mts +1 -1
  389. package/dist/plugins/sui/errors.mjs +1 -9
  390. package/dist/plugins/sui/errors.mjs.map +1 -1
  391. package/dist/{substrate/runtime/sui-execute → plugins/sui/exec}/index.d.mts +1 -1
  392. package/dist/{substrate/runtime/sui-execute → plugins/sui/exec}/index.mjs +3 -7
  393. package/dist/plugins/sui/exec/index.mjs.map +1 -0
  394. package/dist/{substrate/runtime/sui-execute → plugins/sui/exec}/sign-and-dispatch.mjs +1 -1
  395. package/dist/plugins/sui/exec/sign-and-dispatch.mjs.map +1 -0
  396. package/dist/plugins/sui/fork-faucet-strategy.mjs +2 -6
  397. package/dist/plugins/sui/fork-faucet-strategy.mjs.map +1 -1
  398. package/dist/plugins/sui/fork-orchestration.mjs +13 -23
  399. package/dist/plugins/sui/fork-orchestration.mjs.map +1 -1
  400. package/dist/plugins/sui/fork-transaction.mjs.map +1 -1
  401. package/dist/plugins/sui/index.d.mts +34 -83
  402. package/dist/plugins/sui/index.mjs +200 -68
  403. package/dist/plugins/sui/index.mjs.map +1 -1
  404. package/dist/{substrate/runtime/sui-ledger → plugins/sui/ledger}/object-ref.mjs +1 -1
  405. package/dist/plugins/sui/ledger/object-ref.mjs.map +1 -0
  406. package/dist/plugins/sui/local-faucet-strategy.mjs +1 -5
  407. package/dist/plugins/sui/local-faucet-strategy.mjs.map +1 -1
  408. package/dist/plugins/sui/log-attrs.mjs +11 -0
  409. package/dist/plugins/sui/log-attrs.mjs.map +1 -0
  410. package/dist/plugins/sui/mode/external.mjs +4 -12
  411. package/dist/plugins/sui/mode/external.mjs.map +1 -1
  412. package/dist/plugins/sui/mode/fork.mjs +19 -16
  413. package/dist/plugins/sui/mode/fork.mjs.map +1 -1
  414. package/dist/plugins/sui/mode/live.mjs +4 -17
  415. package/dist/plugins/sui/mode/live.mjs.map +1 -1
  416. package/dist/plugins/sui/mode/local.d.mts +1 -0
  417. package/dist/plugins/sui/mode/local.mjs +203 -61
  418. package/dist/plugins/sui/mode/local.mjs.map +1 -1
  419. package/dist/plugins/sui/mode/shared-boot.mjs +18 -23
  420. package/dist/plugins/sui/mode/shared-boot.mjs.map +1 -1
  421. package/dist/plugins/sui/mode/shared.d.mts +6 -7
  422. package/dist/plugins/sui/mode/shared.mjs.map +1 -1
  423. package/dist/plugins/sui/mode/spec.d.mts +23 -6
  424. package/dist/{substrate/runtime/sui-move-build → plugins/sui/move}/index.mjs +28 -30
  425. package/dist/plugins/sui/move/index.mjs.map +1 -0
  426. package/dist/plugins/sui/move-summary-runner.mjs +8 -4
  427. package/dist/plugins/sui/move-summary-runner.mjs.map +1 -1
  428. package/dist/{substrate/network.d.mts → plugins/sui/network-config.d.mts} +11 -10
  429. package/dist/plugins/sui/network-resolver.d.mts +6 -6
  430. package/dist/plugins/sui/routable.mjs.map +1 -1
  431. package/dist/plugins/sui/service.mjs +10 -6
  432. package/dist/plugins/sui/service.mjs.map +1 -1
  433. package/dist/plugins/sui/snapshot.mjs +10 -5
  434. package/dist/plugins/sui/snapshot.mjs.map +1 -1
  435. package/dist/plugins/wallet/codegen.d.mts +8 -6
  436. package/dist/plugins/wallet/codegen.mjs +4 -10
  437. package/dist/plugins/wallet/codegen.mjs.map +1 -1
  438. package/dist/plugins/wallet/errors.mjs +1 -4
  439. package/dist/plugins/wallet/errors.mjs.map +1 -1
  440. package/dist/plugins/wallet/index.d.mts +3 -6
  441. package/dist/plugins/wallet/index.mjs +16 -21
  442. package/dist/plugins/wallet/index.mjs.map +1 -1
  443. package/dist/plugins/wallet/origin-policy.mjs +3 -3
  444. package/dist/plugins/wallet/origin-policy.mjs.map +1 -1
  445. package/dist/plugins/wallet/pairing.mjs +6 -24
  446. package/dist/plugins/wallet/pairing.mjs.map +1 -1
  447. package/dist/plugins/wallet/protocol.mjs.map +1 -1
  448. package/dist/plugins/wallet/routable.mjs.map +1 -1
  449. package/dist/plugins/wallet/server.mjs +17 -24
  450. package/dist/plugins/wallet/server.mjs.map +1 -1
  451. package/dist/plugins/wallet/service.d.mts +2 -2
  452. package/dist/plugins/wallet/service.mjs +4 -15
  453. package/dist/plugins/wallet/service.mjs.map +1 -1
  454. package/dist/plugins/wallet/snapshot.mjs.map +1 -1
  455. package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs +1 -5
  456. package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs.map +1 -1
  457. package/dist/plugins/walrus/codegen.d.mts +2 -13
  458. package/dist/plugins/walrus/codegen.mjs +93 -28
  459. package/dist/plugins/walrus/codegen.mjs.map +1 -1
  460. package/dist/plugins/walrus/deploy-paths.mjs +2 -3
  461. package/dist/plugins/walrus/deploy-paths.mjs.map +1 -1
  462. package/dist/plugins/walrus/deploy.mjs +26 -19
  463. package/dist/plugins/walrus/deploy.mjs.map +1 -1
  464. package/dist/plugins/walrus/errors.mjs +1 -8
  465. package/dist/plugins/walrus/errors.mjs.map +1 -1
  466. package/dist/plugins/walrus/faucet-strategy.mjs +15 -1
  467. package/dist/plugins/walrus/faucet-strategy.mjs.map +1 -1
  468. package/dist/plugins/walrus/index.d.mts +13 -44
  469. package/dist/plugins/walrus/index.mjs +119 -122
  470. package/dist/plugins/walrus/index.mjs.map +1 -1
  471. package/dist/plugins/walrus/mode/known-deploy.mjs +6 -6
  472. package/dist/plugins/walrus/mode/known-deploy.mjs.map +1 -1
  473. package/dist/plugins/walrus/mode/local-cluster.d.mts +2 -2
  474. package/dist/plugins/walrus/mode/local-cluster.mjs +2 -10
  475. package/dist/plugins/walrus/mode/local-cluster.mjs.map +1 -1
  476. package/dist/plugins/walrus/plugin-key.mjs.map +1 -1
  477. package/dist/plugins/walrus/registry-publish.mjs.map +1 -1
  478. package/dist/plugins/walrus/routable.mjs.map +1 -1
  479. package/dist/plugins/walrus/service.mjs.map +1 -1
  480. package/dist/plugins/walrus/snapshot.mjs +3 -3
  481. package/dist/plugins/walrus/snapshot.mjs.map +1 -1
  482. package/dist/plugins/walrus/storage-nodes.mjs +53 -14
  483. package/dist/plugins/walrus/storage-nodes.mjs.map +1 -1
  484. package/dist/plugins/walrus/wal-swap.mjs +4 -8
  485. package/dist/plugins/walrus/wal-swap.mjs.map +1 -1
  486. package/dist/primitives/artifact-publisher.mjs.map +1 -1
  487. package/dist/primitives/cache.d.mts +1 -1
  488. package/dist/runtime/docker/client.mjs +47 -3
  489. package/dist/runtime/docker/client.mjs.map +1 -1
  490. package/dist/runtime/docker/container.mjs +37 -57
  491. package/dist/runtime/docker/container.mjs.map +1 -1
  492. package/dist/runtime/docker/errors.mjs.map +1 -1
  493. package/dist/runtime/docker/exec.mjs +2 -2
  494. package/dist/runtime/docker/exec.mjs.map +1 -1
  495. package/dist/runtime/docker/image.mjs +10 -11
  496. package/dist/runtime/docker/image.mjs.map +1 -1
  497. package/dist/runtime/docker/index.mjs +0 -1
  498. package/dist/runtime/docker/inspect-and-decode.mjs.map +1 -1
  499. package/dist/runtime/docker/inventory.mjs +9 -9
  500. package/dist/runtime/docker/inventory.mjs.map +1 -1
  501. package/dist/runtime/docker/labels.mjs +12 -1
  502. package/dist/runtime/docker/labels.mjs.map +1 -1
  503. package/dist/runtime/docker/network.mjs +6 -6
  504. package/dist/runtime/docker/network.mjs.map +1 -1
  505. package/dist/runtime/docker/render-run-args.mjs.map +1 -1
  506. package/dist/runtime/docker/service.mjs +31 -45
  507. package/dist/runtime/docker/service.mjs.map +1 -1
  508. package/dist/runtime/docker/sweep.mjs +14 -64
  509. package/dist/runtime/docker/sweep.mjs.map +1 -1
  510. package/dist/runtime/docker/volume.mjs +1 -1
  511. package/dist/runtime/docker/volume.mjs.map +1 -1
  512. package/dist/runtime/docker/wrap.mjs +14 -2
  513. package/dist/runtime/docker/wrap.mjs.map +1 -1
  514. package/dist/substrate/brand.d.mts +2 -5
  515. package/dist/substrate/brand.mjs +3 -2
  516. package/dist/substrate/brand.mjs.map +1 -1
  517. package/dist/substrate/cross-process.mjs +2 -16
  518. package/dist/substrate/cross-process.mjs.map +1 -1
  519. package/dist/substrate/event-time.mjs +0 -2
  520. package/dist/substrate/event-time.mjs.map +1 -1
  521. package/dist/substrate/events.d.mts +46 -16
  522. package/dist/substrate/identity.d.mts +11 -5
  523. package/dist/substrate/manifest.d.mts +33 -26
  524. package/dist/substrate/manifest.mjs +8 -3
  525. package/dist/substrate/manifest.mjs.map +1 -1
  526. package/dist/substrate/options.d.mts +33 -4
  527. package/dist/substrate/plugin-ctx.d.mts +70 -0
  528. package/dist/substrate/plugin-ctx.mjs +66 -0
  529. package/dist/substrate/plugin-ctx.mjs.map +1 -0
  530. package/dist/substrate/plugin.d.mts +46 -38
  531. package/dist/substrate/plugin.mjs +13 -9
  532. package/dist/substrate/plugin.mjs.map +1 -1
  533. package/dist/substrate/projection.d.mts +1 -1
  534. package/dist/substrate/runtime/atomic-write.mjs +3 -4
  535. package/dist/substrate/runtime/atomic-write.mjs.map +1 -1
  536. package/dist/substrate/runtime/cache/schema.mjs.map +1 -1
  537. package/dist/substrate/runtime/cache/service.mjs +50 -20
  538. package/dist/substrate/runtime/cache/service.mjs.map +1 -1
  539. package/dist/substrate/runtime/config-validation.mjs.map +1 -1
  540. package/dist/substrate/runtime/control-plane/domain.mjs +34 -12
  541. package/dist/substrate/runtime/control-plane/domain.mjs.map +1 -1
  542. package/dist/substrate/runtime/control-plane/service.mjs.map +1 -1
  543. package/dist/substrate/runtime/cross-process/command-channel/channel.mjs +14 -17
  544. package/dist/substrate/runtime/cross-process/command-channel/channel.mjs.map +1 -1
  545. package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs.map +1 -1
  546. package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs.map +1 -1
  547. package/dist/substrate/runtime/cross-process/command-channel/runtime-control-lock.mjs.map +1 -1
  548. package/dist/substrate/runtime/cross-process/index.mjs +0 -2
  549. package/dist/substrate/runtime/cross-process/live-clock.mjs +1 -1
  550. package/dist/substrate/runtime/cross-process/live-clock.mjs.map +1 -1
  551. package/dist/substrate/runtime/cross-process/liveness.mjs +11 -18
  552. package/dist/substrate/runtime/cross-process/liveness.mjs.map +1 -1
  553. package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs +2 -2
  554. package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs.map +1 -1
  555. package/dist/substrate/runtime/cross-process/roster.mjs +17 -127
  556. package/dist/substrate/runtime/cross-process/roster.mjs.map +1 -1
  557. package/dist/substrate/runtime/cross-process/self-pid.mjs.map +1 -1
  558. package/dist/substrate/runtime/cross-process/stack-lock.mjs +29 -28
  559. package/dist/substrate/runtime/cross-process/stack-lock.mjs.map +1 -1
  560. package/dist/substrate/runtime/current-plugin.mjs.map +1 -1
  561. package/dist/substrate/runtime/errors.mjs +1 -13
  562. package/dist/substrate/runtime/errors.mjs.map +1 -1
  563. package/dist/substrate/runtime/format-unknown-error.mjs.map +1 -1
  564. package/dist/substrate/runtime/host-bind-mount-owner.mjs.map +1 -1
  565. package/dist/substrate/runtime/host-gateway.mjs.map +1 -1
  566. package/dist/substrate/runtime/host-tree-tar/index.mjs +15 -163
  567. package/dist/substrate/runtime/host-tree-tar/index.mjs.map +1 -1
  568. package/dist/substrate/runtime/http-probe.d.mts +1 -3
  569. package/dist/substrate/runtime/http-probe.mjs.map +1 -1
  570. package/dist/substrate/runtime/index.mjs +1 -6
  571. package/dist/substrate/runtime/lease-broker/service.mjs +5 -23
  572. package/dist/substrate/runtime/lease-broker/service.mjs.map +1 -1
  573. package/dist/substrate/runtime/lifecycle/dep-graph.mjs +3 -3
  574. package/dist/substrate/runtime/lifecycle/dep-graph.mjs.map +1 -1
  575. package/dist/substrate/runtime/lifecycle/graph-input-id.d.mts +1 -0
  576. package/dist/substrate/runtime/lifecycle/graph-input-id.mjs +133 -0
  577. package/dist/substrate/runtime/lifecycle/graph-input-id.mjs.map +1 -0
  578. package/dist/substrate/runtime/lifecycle/index.mjs +2 -2
  579. package/dist/substrate/runtime/lifecycle/plugin-registry.d.mts +1 -1
  580. package/dist/substrate/runtime/lifecycle/plugin-registry.mjs +22 -1
  581. package/dist/substrate/runtime/lifecycle/plugin-registry.mjs.map +1 -1
  582. package/dist/substrate/runtime/lifecycle/ready-gate.mjs +2 -15
  583. package/dist/substrate/runtime/lifecycle/ready-gate.mjs.map +1 -1
  584. package/dist/substrate/runtime/lifecycle/selective-restart.mjs +29 -25
  585. package/dist/substrate/runtime/lifecycle/selective-restart.mjs.map +1 -1
  586. package/dist/substrate/runtime/lifecycle/signals.mjs +1 -1
  587. package/dist/substrate/runtime/lifecycle/signals.mjs.map +1 -1
  588. package/dist/substrate/runtime/lifecycle/state-machine.mjs.map +1 -1
  589. package/dist/substrate/runtime/lifecycle/watch-attribution.d.mts +1 -1
  590. package/dist/substrate/runtime/lifecycle/watch-attribution.mjs +0 -1
  591. package/dist/substrate/runtime/lifecycle/watch-attribution.mjs.map +1 -1
  592. package/dist/substrate/runtime/managed-container.d.mts +5 -1
  593. package/dist/substrate/runtime/managed-container.mjs +8 -10
  594. package/dist/substrate/runtime/managed-container.mjs.map +1 -1
  595. package/dist/substrate/runtime/manifest/manifest.mjs +8 -30
  596. package/dist/substrate/runtime/manifest/manifest.mjs.map +1 -1
  597. package/dist/substrate/runtime/mode-errors.d.mts +1 -2
  598. package/dist/substrate/runtime/mode-errors.mjs.map +1 -1
  599. package/dist/substrate/runtime/observability/cascade-formatter.mjs +1 -11
  600. package/dist/substrate/runtime/observability/cascade-formatter.mjs.map +1 -1
  601. package/dist/substrate/runtime/observability/ignore-with-log.mjs.map +1 -1
  602. package/dist/substrate/runtime/observability/index.d.mts +1 -1
  603. package/dist/substrate/runtime/observability/index.mjs +4 -6
  604. package/dist/substrate/runtime/observability/log-attrs.mjs +46 -0
  605. package/dist/substrate/runtime/observability/log-attrs.mjs.map +1 -0
  606. package/dist/substrate/runtime/observability/log-store.mjs.map +1 -1
  607. package/dist/substrate/runtime/observability/logger.mjs +3 -3
  608. package/dist/substrate/runtime/observability/logger.mjs.map +1 -1
  609. package/dist/substrate/runtime/observability/output-truncate.mjs.map +1 -1
  610. package/dist/substrate/runtime/observability/pretty-error.mjs.map +1 -1
  611. package/dist/substrate/runtime/observability/process-lines.mjs.map +1 -1
  612. package/dist/substrate/runtime/observability/redaction.mjs.map +1 -1
  613. package/dist/substrate/runtime/observability/subprocess-capture.mjs +2 -2
  614. package/dist/substrate/runtime/observability/subprocess-capture.mjs.map +1 -1
  615. package/dist/substrate/runtime/passthrough-or-wrap.mjs.map +1 -1
  616. package/dist/substrate/runtime/paths.mjs +27 -9
  617. package/dist/substrate/runtime/paths.mjs.map +1 -1
  618. package/dist/substrate/runtime/phase-preserving-produce.mjs.map +1 -1
  619. package/dist/substrate/runtime/port-broker/service.mjs +10 -27
  620. package/dist/substrate/runtime/port-broker/service.mjs.map +1 -1
  621. package/dist/substrate/runtime/post-acquire-tasks.mjs.map +1 -1
  622. package/dist/substrate/runtime/probes.d.mts +2 -3
  623. package/dist/substrate/runtime/probes.mjs.map +1 -1
  624. package/dist/substrate/runtime/process-supervisor.mjs.map +1 -1
  625. package/dist/substrate/runtime/projection/operational-endpoints.mjs.map +1 -1
  626. package/dist/substrate/runtime/projection/state-ref.mjs.map +1 -1
  627. package/dist/substrate/runtime/projection/update.mjs +87 -11
  628. package/dist/substrate/runtime/projection/update.mjs.map +1 -1
  629. package/dist/substrate/runtime/random-suffix.mjs.map +1 -1
  630. package/dist/substrate/runtime/reconcile/fs-plan.mjs +146 -0
  631. package/dist/substrate/runtime/reconcile/fs-plan.mjs.map +1 -0
  632. package/dist/substrate/runtime/reconcile/graph.mjs +19 -0
  633. package/dist/substrate/runtime/reconcile/graph.mjs.map +1 -0
  634. package/dist/substrate/runtime/reconcile/index.mjs +5 -0
  635. package/dist/substrate/runtime/reconcile/label.mjs +41 -0
  636. package/dist/substrate/runtime/reconcile/label.mjs.map +1 -0
  637. package/dist/substrate/runtime/reconcile/spec.mjs +15 -0
  638. package/dist/substrate/runtime/reconcile/spec.mjs.map +1 -0
  639. package/dist/substrate/runtime/retry-policy.d.mts +2 -3
  640. package/dist/substrate/runtime/retry-policy.mjs.map +1 -1
  641. package/dist/substrate/runtime/routed-url.mjs.map +1 -1
  642. package/dist/substrate/runtime/runtime-decode.mjs.map +1 -1
  643. package/dist/substrate/runtime/scoped-http-server.mjs.map +1 -1
  644. package/dist/substrate/runtime/stage-and-swap/index.mjs +49 -12
  645. package/dist/substrate/runtime/stage-and-swap/index.mjs.map +1 -1
  646. package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.mjs.map +1 -1
  647. package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs.map +1 -1
  648. package/dist/substrate/runtime/strategy-registry/service.mjs +29 -17
  649. package/dist/substrate/runtime/strategy-registry/service.mjs.map +1 -1
  650. package/dist/substrate/runtime/subnet-broker.mjs.map +1 -1
  651. package/dist/substrate/runtime/supervisor/acquire-node.mjs +188 -56
  652. package/dist/substrate/runtime/supervisor/acquire-node.mjs.map +1 -1
  653. package/dist/substrate/runtime/supervisor/background-tasks.mjs +79 -65
  654. package/dist/substrate/runtime/supervisor/background-tasks.mjs.map +1 -1
  655. package/dist/substrate/runtime/supervisor/command-loop.mjs +82 -23
  656. package/dist/substrate/runtime/supervisor/command-loop.mjs.map +1 -1
  657. package/dist/substrate/runtime/supervisor/contribution-dispatcher.mjs +16 -0
  658. package/dist/substrate/runtime/supervisor/contribution-dispatcher.mjs.map +1 -0
  659. package/dist/substrate/runtime/supervisor/errors.mjs +11 -2
  660. package/dist/substrate/runtime/supervisor/errors.mjs.map +1 -1
  661. package/dist/substrate/runtime/supervisor/index.mjs +2 -0
  662. package/dist/substrate/runtime/supervisor/shutdown.mjs +6 -6
  663. package/dist/substrate/runtime/supervisor/shutdown.mjs.map +1 -1
  664. package/dist/substrate/runtime/supervisor/start-supervisor.mjs +60 -70
  665. package/dist/substrate/runtime/supervisor/start-supervisor.mjs.map +1 -1
  666. package/dist/substrate/runtime/supervisor/state.d.mts +1 -1
  667. package/dist/substrate/runtime/supervisor/state.mjs +1 -1
  668. package/dist/substrate/runtime/supervisor/state.mjs.map +1 -1
  669. package/dist/substrate/runtime/supervisor/teardown.mjs +10 -9
  670. package/dist/substrate/runtime/supervisor/teardown.mjs.map +1 -1
  671. package/dist/substrate/runtime/supervisor/wiring.mjs +6 -20
  672. package/dist/substrate/runtime/supervisor/wiring.mjs.map +1 -1
  673. package/dist/substrate/runtime/tar/reader.mjs +216 -0
  674. package/dist/substrate/runtime/tar/reader.mjs.map +1 -0
  675. package/dist/substrate/runtime/typed-env.mjs.map +1 -1
  676. package/dist/substrate/versioned-doc-schema.mjs.map +1 -1
  677. package/dist/substrate/versioned-doc-sync.mjs +5 -5
  678. package/dist/substrate/versioned-doc-sync.mjs.map +1 -1
  679. package/dist/surfaces/cli/command-tree.mjs +49 -7
  680. package/dist/surfaces/cli/command-tree.mjs.map +1 -1
  681. package/dist/surfaces/cli/commands/config.mjs +1 -1
  682. package/dist/surfaces/cli/commands/config.mjs.map +1 -1
  683. package/dist/surfaces/cli/commands/confirm-node.mjs.map +1 -1
  684. package/dist/surfaces/cli/commands/confirm.mjs.map +1 -1
  685. package/dist/surfaces/cli/commands/doctor.mjs +1 -1
  686. package/dist/surfaces/cli/commands/doctor.mjs.map +1 -1
  687. package/dist/surfaces/cli/commands/prune-picker-entry.mjs.map +1 -1
  688. package/dist/surfaces/cli/commands/prune-picker.mjs.map +1 -1
  689. package/dist/surfaces/cli/commands/prune.mjs +1 -1
  690. package/dist/surfaces/cli/commands/prune.mjs.map +1 -1
  691. package/dist/surfaces/cli/commands/snapshot.mjs +1 -1
  692. package/dist/surfaces/cli/commands/snapshot.mjs.map +1 -1
  693. package/dist/surfaces/cli/commands/status.mjs +1 -1
  694. package/dist/surfaces/cli/commands/status.mjs.map +1 -1
  695. package/dist/surfaces/cli/commands/supervisor-presence.mjs.map +1 -1
  696. package/dist/surfaces/cli/commands/wipe.mjs +3 -4
  697. package/dist/surfaces/cli/commands/wipe.mjs.map +1 -1
  698. package/dist/surfaces/cli/envelope.mjs.map +1 -1
  699. package/dist/surfaces/cli/errors.mjs.map +1 -1
  700. package/dist/surfaces/cli/flags.mjs.map +1 -1
  701. package/dist/surfaces/cli/index.mjs +45 -14
  702. package/dist/surfaces/cli/index.mjs.map +1 -1
  703. package/dist/surfaces/cli/output.mjs.map +1 -1
  704. package/dist/surfaces/cli/sysexits.mjs.map +1 -1
  705. package/dist/surfaces/tui/app.mjs +0 -21
  706. package/dist/surfaces/tui/app.mjs.map +1 -1
  707. package/dist/surfaces/tui/dashboard.mjs +0 -48
  708. package/dist/surfaces/tui/dashboard.mjs.map +1 -1
  709. package/dist/surfaces/tui/display-derivation.mjs +80 -16
  710. package/dist/surfaces/tui/display-derivation.mjs.map +1 -1
  711. package/dist/surfaces/tui/errors.mjs.map +1 -1
  712. package/dist/surfaces/tui/event-log.mjs +0 -9
  713. package/dist/surfaces/tui/event-log.mjs.map +1 -1
  714. package/dist/surfaces/tui/heartbeat.mjs.map +1 -1
  715. package/dist/surfaces/tui/index.mjs +2 -2
  716. package/dist/surfaces/tui/index.mjs.map +1 -1
  717. package/dist/surfaces/tui/input.mjs.map +1 -1
  718. package/dist/surfaces/tui/mode-detect.mjs.map +1 -1
  719. package/dist/surfaces/tui/mount-ink.mjs.map +1 -1
  720. package/dist/surfaces/tui/plain-renderer.mjs +26 -19
  721. package/dist/surfaces/tui/plain-renderer.mjs.map +1 -1
  722. package/dist/surfaces/tui/resource-table.mjs +8 -10
  723. package/dist/surfaces/tui/resource-table.mjs.map +1 -1
  724. package/images/postgres/Dockerfile +0 -1
  725. package/images/sui/Dockerfile +27 -54
  726. package/images/sui/entrypoint.sh +17 -179
  727. package/package.json +23 -15
  728. package/dashboard-ui/assets/index-Bmi1UtAg.js +0 -1356
  729. package/dashboard-ui/assets/index-D5EShVt4.js +0 -3
  730. package/dashboard-ui/assets/index-Deml9drg.css +0 -1
  731. package/dist/api/plugin-errors.d.mts +0 -7
  732. package/dist/api/plugin-errors.mjs +0 -10
  733. package/dist/api/plugin-errors.mjs.map +0 -1
  734. package/dist/cli/wirings/build-verb-layers.mjs +0 -42
  735. package/dist/cli/wirings/build-verb-layers.mjs.map +0 -1
  736. package/dist/contracts/capability-decl.d.mts +0 -40
  737. package/dist/orchestrators/built-in-plugin-layers.mjs +0 -54
  738. package/dist/orchestrators/built-in-plugin-layers.mjs.map +0 -1
  739. package/dist/orchestrators/run.mjs +0 -91
  740. package/dist/orchestrators/run.mjs.map +0 -1
  741. package/dist/orchestrators/runtime-composition.d.mts +0 -10
  742. package/dist/orchestrators/runtime-composition.mjs +0 -252
  743. package/dist/orchestrators/runtime-composition.mjs.map +0 -1
  744. package/dist/orchestrators/snapshot/capture-command.d.mts +0 -1
  745. package/dist/orchestrators/snapshot/capture-command.mjs +0 -25
  746. package/dist/orchestrators/snapshot/capture-command.mjs.map +0 -1
  747. package/dist/orchestrators/snapshot/pending-marker.mjs +0 -99
  748. package/dist/orchestrators/snapshot/pending-marker.mjs.map +0 -1
  749. package/dist/orchestrators/snapshot/recover-pending.mjs +0 -223
  750. package/dist/orchestrators/snapshot/recover-pending.mjs.map +0 -1
  751. package/dist/orchestrators/snapshot/state-document.d.mts +0 -1
  752. package/dist/orchestrators/snapshot/state-document.mjs +0 -58
  753. package/dist/orchestrators/snapshot/state-document.mjs.map +0 -1
  754. package/dist/plugins/account/spans.mjs +0 -16
  755. package/dist/plugins/account/spans.mjs.map +0 -1
  756. package/dist/plugins/account/variants/env.mjs +0 -24
  757. package/dist/plugins/account/variants/env.mjs.map +0 -1
  758. package/dist/plugins/account/variants/inline.mjs +0 -13
  759. package/dist/plugins/account/variants/inline.mjs.map +0 -1
  760. package/dist/plugins/account/variants/keystore.mjs +0 -91
  761. package/dist/plugins/account/variants/keystore.mjs.map +0 -1
  762. package/dist/plugins/action/spans.mjs +0 -11
  763. package/dist/plugins/action/spans.mjs.map +0 -1
  764. package/dist/plugins/coin/spans.mjs +0 -20
  765. package/dist/plugins/coin/spans.mjs.map +0 -1
  766. package/dist/plugins/deepbook/spans.mjs +0 -18
  767. package/dist/plugins/deepbook/spans.mjs.map +0 -1
  768. package/dist/plugins/faucet/spans.mjs +0 -12
  769. package/dist/plugins/faucet/spans.mjs.map +0 -1
  770. package/dist/plugins/package/spans.mjs +0 -14
  771. package/dist/plugins/package/spans.mjs.map +0 -1
  772. package/dist/plugins/postgres/codegen.mjs +0 -42
  773. package/dist/plugins/postgres/codegen.mjs.map +0 -1
  774. package/dist/plugins/postgres/connection.d.mts +0 -33
  775. package/dist/plugins/postgres/connection.mjs.map +0 -1
  776. package/dist/plugins/postgres/db-ensure.mjs.map +0 -1
  777. package/dist/plugins/postgres/errors.d.mts +0 -60
  778. package/dist/plugins/postgres/errors.mjs +0 -29
  779. package/dist/plugins/postgres/errors.mjs.map +0 -1
  780. package/dist/plugins/postgres/index.d.mts +0 -37
  781. package/dist/plugins/postgres/index.mjs +0 -68
  782. package/dist/plugins/postgres/index.mjs.map +0 -1
  783. package/dist/plugins/postgres/routable.mjs +0 -33
  784. package/dist/plugins/postgres/routable.mjs.map +0 -1
  785. package/dist/plugins/postgres/service.d.mts +0 -50
  786. package/dist/plugins/postgres/service.mjs +0 -179
  787. package/dist/plugins/postgres/service.mjs.map +0 -1
  788. package/dist/plugins/postgres/snapshot.mjs +0 -32
  789. package/dist/plugins/postgres/snapshot.mjs.map +0 -1
  790. package/dist/plugins/postgres/spans.mjs +0 -11
  791. package/dist/plugins/postgres/spans.mjs.map +0 -1
  792. package/dist/plugins/seal/spans.mjs +0 -18
  793. package/dist/plugins/seal/spans.mjs.map +0 -1
  794. package/dist/plugins/sui/spans.mjs +0 -17
  795. package/dist/plugins/sui/spans.mjs.map +0 -1
  796. package/dist/plugins/wallet/spans.mjs +0 -22
  797. package/dist/plugins/wallet/spans.mjs.map +0 -1
  798. package/dist/plugins/walrus/registry-publish.d.mts +0 -24
  799. package/dist/plugins/walrus/spans.mjs +0 -18
  800. package/dist/plugins/walrus/spans.mjs.map +0 -1
  801. package/dist/runtime/docker/logs.d.mts +0 -1
  802. package/dist/runtime/docker/logs.mjs +0 -34
  803. package/dist/runtime/docker/logs.mjs.map +0 -1
  804. package/dist/substrate/runtime/artifact-publisher/index.mjs +0 -86
  805. package/dist/substrate/runtime/artifact-publisher/index.mjs.map +0 -1
  806. package/dist/substrate/runtime/capability-sinks/index.d.mts +0 -1
  807. package/dist/substrate/runtime/capability-sinks/index.mjs +0 -3
  808. package/dist/substrate/runtime/capability-sinks/layer.d.mts +0 -1
  809. package/dist/substrate/runtime/capability-sinks/layer.mjs +0 -31
  810. package/dist/substrate/runtime/capability-sinks/layer.mjs.map +0 -1
  811. package/dist/substrate/runtime/capability-sinks/service.d.mts +0 -95
  812. package/dist/substrate/runtime/capability-sinks/service.mjs +0 -69
  813. package/dist/substrate/runtime/capability-sinks/service.mjs.map +0 -1
  814. package/dist/substrate/runtime/cross-process/lock.d.mts +0 -1
  815. package/dist/substrate/runtime/cross-process/lock.mjs +0 -23
  816. package/dist/substrate/runtime/cross-process/lock.mjs.map +0 -1
  817. package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs +0 -113
  818. package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs.map +0 -1
  819. package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs +0 -31
  820. package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs.map +0 -1
  821. package/dist/substrate/runtime/observability/formatter-registry.d.mts +0 -1
  822. package/dist/substrate/runtime/observability/formatter-registry.mjs +0 -48
  823. package/dist/substrate/runtime/observability/formatter-registry.mjs.map +0 -1
  824. package/dist/substrate/runtime/observability/span-store.d.mts +0 -1
  825. package/dist/substrate/runtime/observability/span-store.mjs +0 -110
  826. package/dist/substrate/runtime/observability/span-store.mjs.map +0 -1
  827. package/dist/substrate/runtime/observability/spans.d.mts +0 -1
  828. package/dist/substrate/runtime/observability/spans.mjs +0 -87
  829. package/dist/substrate/runtime/observability/spans.mjs.map +0 -1
  830. package/dist/substrate/runtime/projection/index.mjs +0 -4
  831. package/dist/substrate/runtime/projection/persisted.mjs +0 -213
  832. package/dist/substrate/runtime/projection/persisted.mjs.map +0 -1
  833. package/dist/substrate/runtime/scoped-multimap/service.mjs +0 -52
  834. package/dist/substrate/runtime/scoped-multimap/service.mjs.map +0 -1
  835. package/dist/substrate/runtime/scoped-ref-map/index.mjs +0 -2
  836. package/dist/substrate/runtime/scoped-ref-map/service.mjs +0 -83
  837. package/dist/substrate/runtime/scoped-ref-map/service.mjs.map +0 -1
  838. package/dist/substrate/runtime/state-store/index.mjs +0 -3
  839. package/dist/substrate/runtime/state-store/schema.d.mts +0 -1
  840. package/dist/substrate/runtime/state-store/schema.mjs +0 -41
  841. package/dist/substrate/runtime/state-store/schema.mjs.map +0 -1
  842. package/dist/substrate/runtime/state-store/service.d.mts +0 -1
  843. package/dist/substrate/runtime/state-store/service.mjs +0 -145
  844. package/dist/substrate/runtime/state-store/service.mjs.map +0 -1
  845. package/dist/substrate/runtime/sui-execute/index.mjs.map +0 -1
  846. package/dist/substrate/runtime/sui-execute/sign-and-dispatch.mjs.map +0 -1
  847. package/dist/substrate/runtime/sui-ledger/object-ref.mjs.map +0 -1
  848. package/dist/substrate/runtime/sui-move-build/index.mjs.map +0 -1
  849. package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs +0 -151
  850. package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs.map +0 -1
  851. package/dist/substrate/state-store.d.mts +0 -1
  852. /package/dist/orchestrators/{snapshot/pending-marker.d.mts → codegen/id-config.d.mts} +0 -0
  853. /package/dist/orchestrators/snapshot/{recover-pending.d.mts → interrupted-restore.d.mts} +0 -0
  854. /package/dist/{substrate/runtime/sui-execute → plugins/sui/exec}/sign-and-dispatch.d.mts +0 -0
  855. /package/dist/plugins/{postgres/snapshot.d.mts → sui/ledger/object-ref.d.mts} +0 -0
  856. /package/dist/{substrate/runtime/sui-move-build → plugins/sui/move}/index.d.mts +0 -0
  857. /package/dist/substrate/runtime/{state-store/index.d.mts → reconcile/graph.d.mts} +0 -0
  858. /package/dist/substrate/runtime/{cross-process/snapshot-reservation.d.mts → supervisor/contribution-dispatcher.d.mts} +0 -0
@@ -1,46 +1 @@
1
- //#region src/plugins/account/registry.d.ts
2
- /** The strategy value published under `account:<name>`. Carries the
3
- * load-bearing identity columns only — signing closures stay on
4
- * the Account tag's resolved value because their lifetime is
5
- * scope-bounded.
6
- *
7
- * Architecture-distilled (12-account.md "Tighten the resolved-
8
- * account type"): the `source` discriminator is mandatory so
9
- * consumers can branch on impersonation without a `publicKey`
10
- * nullcheck (impersonation accounts have a zero-buffer publicKey
11
- * — a type-level lie). */
12
- interface AccountRegistryEntry {
13
- readonly name: string;
14
- readonly address: string;
15
- readonly scheme: 'ed25519' | 'secp256k1' | 'secp256r1';
16
- readonly source: 'real' | 'impersonate';
17
- readonly funding: AccountRegistryFunding;
18
- }
19
- interface AccountRegistryFunding {
20
- readonly status: 'funded' | 'skipped' | 'unknown';
21
- readonly balanceMist: string | null;
22
- readonly requestedMist: string | null;
23
- readonly entries?: ReadonlyArray<AccountRegistryFundingEntry>;
24
- }
25
- /** Per-entry funding status — the projection's per-row "did we actually
26
- * hit the faucet?" signal.
27
- *
28
- * - `'funded'` — a wire call ran and balance settled.
29
- * - `'already-satisfied'` — the pre-existing balance covered the
30
- * request, so no wire call ran.
31
- * - `'skipped'` — the entry was zero-amount, dropped at
32
- * the funding-pass boundary, or there was
33
- * no registered strategy (cross-cutting
34
- * non-SUI silent-noop).
35
- *
36
- * Splitting `'funded'` from `'already-satisfied'` matches the
37
- * applied-projection invariant in `service.ts:858-887`. */
38
- interface AccountRegistryFundingEntry {
39
- readonly coin: string;
40
- readonly fullCoinType: string;
41
- readonly amount: string;
42
- readonly status: 'funded' | 'already-satisfied' | 'skipped';
43
- }
44
- //#endregion
45
- export { AccountRegistryEntry, AccountRegistryFunding };
46
- //# sourceMappingURL=registry.d.mts.map
1
+ export { };
@@ -1 +1 @@
1
- {"version":3,"file":"registry.mjs","names":[],"sources":["../../../src/plugins/account/registry.ts"],"sourcesContent":["// Account plugin — per-stack registry contribution.\n//\n// Architecture (12-account.md \"Outputs / capabilities provided\"):\n// Account publishes `{name, address}` to a per-stack account\n// registry. Downstream consumers (Wallet, Codegen, the manifest\n// emitter, Coin's deepbook market maker) look accounts up by name.\n//\n// The architecture's `strategy-contributor` capability covers this\n// shape — Account contributes one entry per acquired account under\n// the capability key `account:<name>`. The strategy value is the\n// resolved-account view (sans signing closures, which stay scoped\n// to the acquire body's lifetime; consumers ask the Account tag\n// directly when they need to sign).\n//\n// Distilled-doc opportunity: today's `publishAccount(...)` writes\n// into an engine-singleton registry. The redesign moves it onto the\n// capability-decl surface so the substrate orchestrates dedup-by-\n// name and last-write-wins without an engine import.\n\nimport { projection } from '../../api/define-capabilities.ts';\nimport type { ProjectionDecl } from '../../contracts/projection.ts';\nimport type { StrategyContributorDecl } from '../../contracts/strategy-contributor.ts';\n\n/** Capability key for the per-name account registry. The literal\n * form (`account:<name>`) lets downstream consumers (Coin, Wallet,\n * the manifest emitter) `StrategyFor<Caps, \"account:alice\">` to\n * recover the registered address at the type level. */\nexport type AccountRegistryKey<Name extends string> = `account:${Name}`;\n\nexport const accountRegistryKey = <Name extends string>(name: Name): AccountRegistryKey<Name> =>\n\t`account:${name}` as AccountRegistryKey<Name>;\n\n/** The strategy value published under `account:<name>`. Carries the\n * load-bearing identity columns only — signing closures stay on\n * the Account tag's resolved value because their lifetime is\n * scope-bounded.\n *\n * Architecture-distilled (12-account.md \"Tighten the resolved-\n * account type\"): the `source` discriminator is mandatory so\n * consumers can branch on impersonation without a `publicKey`\n * nullcheck (impersonation accounts have a zero-buffer publicKey\n * — a type-level lie). */\nexport interface AccountRegistryEntry {\n\treadonly name: string;\n\treadonly address: string;\n\treadonly scheme: 'ed25519' | 'secp256k1' | 'secp256r1';\n\treadonly source: 'real' | 'impersonate';\n\treadonly funding: AccountRegistryFunding;\n}\n\nexport interface AccountRegistryFunding {\n\treadonly status: 'funded' | 'skipped' | 'unknown';\n\treadonly balanceMist: string | null;\n\treadonly requestedMist: string | null;\n\treadonly entries?: ReadonlyArray<AccountRegistryFundingEntry>;\n}\n\n/** Per-entry funding status — the projection's per-row \"did we actually\n * hit the faucet?\" signal.\n *\n * - `'funded'` — a wire call ran and balance settled.\n * - `'already-satisfied'` — the pre-existing balance covered the\n * request, so no wire call ran.\n * - `'skipped'` — the entry was zero-amount, dropped at\n * the funding-pass boundary, or there was\n * no registered strategy (cross-cutting\n * non-SUI silent-noop).\n *\n * Splitting `'funded'` from `'already-satisfied'` matches the\n * applied-projection invariant in `service.ts:858-887`. */\nexport interface AccountRegistryFundingEntry {\n\treadonly coin: string;\n\treadonly fullCoinType: string;\n\treadonly amount: string;\n\treadonly status: 'funded' | 'already-satisfied' | 'skipped';\n}\n\n/** Construct the strategy-contributor decl Account emits for one\n * acquired identity. Auto-mounted: the registry's role is\n * infrastructure; the user never types it explicitly. */\nexport const makeAccountRegistryContribution = <Name extends string>(\n\tentry: AccountRegistryEntry & { readonly name: Name },\n): StrategyContributorDecl<AccountRegistryKey<Name>, AccountRegistryEntry> => ({\n\tkind: 'strategy-contributor',\n\tcapabilityKey: accountRegistryKey(entry.name),\n\tstrategy: entry,\n\tautoMounted: true,\n});\n\nexport const makeAccountProjectionContribution = <Name extends string>(\n\tentry: AccountRegistryEntry & { readonly name: Name },\n): ProjectionDecl => {\n\tconst updatedAt = Date.now();\n\tconst key = `account/${entry.name}` as `account/${string}`;\n\treturn projection({\n\t\tkind: 'account',\n\t\tkey,\n\t\tpayload: {\n\t\t\tkey,\n\t\t\trowKey: null,\n\t\t\tname: entry.name,\n\t\t\taddress: entry.address,\n\t\t\tscheme: entry.scheme,\n\t\t\tsource: entry.source,\n\t\t\tfunding: entry.funding,\n\t\t\twalletVisible: false,\n\t\t\tupdatedAt,\n\t\t},\n\t\tat: updatedAt,\n\t});\n};\n"],"mappings":";;AA6BA,MAAa,sBAA2C,SACvD,WAAW;;;;AAkDZ,MAAa,mCACZ,WAC8E;CAC9E,MAAM;CACN,eAAe,mBAAmB,MAAM,KAAK;CAC7C,UAAU;CACV,aAAa;CACb;AAED,MAAa,qCACZ,UACoB;CACpB,MAAM,YAAY,KAAK,KAAK;CAC5B,MAAM,MAAM,WAAW,MAAM;AAC7B,QAAO,WAAW;EACjB,MAAM;EACN;EACA,SAAS;GACR;GACA,QAAQ;GACR,MAAM,MAAM;GACZ,SAAS,MAAM;GACf,QAAQ,MAAM;GACd,QAAQ,MAAM;GACd,SAAS,MAAM;GACf,eAAe;GACf;GACA;EACD,IAAI;EACJ,CAAC"}
1
+ {"version":3,"file":"registry.mjs","names":[],"sources":["../../../src/plugins/account/registry.ts"],"sourcesContent":["// Account plugin — per-stack registry contribution.\n//\n// Architecture (12-account.md \"Outputs / capabilities provided\"):\n// Account publishes `{name, address}` to a per-stack account\n// registry. Downstream consumers (Wallet, Codegen, the manifest\n// emitter, Coin's deepbook market maker) look accounts up by name.\n//\n// The architecture's `strategy-contributor` capability covers this\n// shape — Account contributes one entry per acquired account under\n// the capability key `account:<name>`. The strategy value is the\n// resolved-account view (sans signing closures, which stay scoped\n// to the acquire body's lifetime; consumers ask the Account tag\n// directly when they need to sign).\n\nimport { projection } from '../../api/define-capabilities.ts';\nimport type { ProjectionDecl } from '../../contracts/projection.ts';\nimport type { StrategyContributorDecl } from '../../contracts/strategy-contributor.ts';\n\n/** Capability key for the per-name account registry. The literal\n * form (`account:<name>`) lets downstream consumers (Coin, Wallet,\n * the manifest emitter) `StrategyFor<Caps, \"account:alice\">` to\n * recover the registered address at the type level. */\nexport type AccountRegistryKey<Name extends string> = `account:${Name}`;\n\nexport const accountRegistryKey = <Name extends string>(name: Name): AccountRegistryKey<Name> =>\n\t`account:${name}` as AccountRegistryKey<Name>;\n\n/** The strategy value published under `account:<name>`. Carries the\n * load-bearing identity columns only — signing closures stay on\n * the Account tag's resolved value because their lifetime is\n * scope-bounded.\n *\n * Architecture-distilled (12-account.md \"Tighten the resolved-\n * account type\"): the `source` discriminator is mandatory so\n * consumers can branch on impersonation without a `publicKey`\n * nullcheck (impersonation accounts have a zero-buffer publicKey\n * — a type-level lie). */\nexport interface AccountRegistryEntry {\n\treadonly name: string;\n\treadonly address: string;\n\treadonly scheme: 'ed25519' | 'secp256k1' | 'secp256r1';\n\treadonly source: 'real' | 'impersonate';\n\treadonly funding: AccountRegistryFunding;\n}\n\nexport interface AccountRegistryFunding {\n\treadonly status: 'funded' | 'skipped' | 'unknown';\n\treadonly balanceMist: string | null;\n\treadonly requestedMist: string | null;\n\treadonly entries?: ReadonlyArray<AccountRegistryFundingEntry>;\n}\n\n/** Per-entry funding status — the projection's per-row \"did we actually\n * hit the faucet?\" signal.\n *\n * - `'funded'` — a wire call ran and balance settled.\n * - `'already-satisfied'` — the pre-existing balance covered the\n * request, so no wire call ran.\n * - `'skipped'` — the entry was zero-amount, dropped at\n * the funding-pass boundary, or there was\n * no registered strategy (cross-cutting\n * non-SUI silent-noop).\n *\n * Splitting `'funded'` from `'already-satisfied'` matches the\n * applied-projection invariant in `service.ts:858-887`. */\nexport interface AccountRegistryFundingEntry {\n\treadonly coin: string;\n\treadonly fullCoinType: string;\n\treadonly amount: string;\n\treadonly status: 'funded' | 'already-satisfied' | 'skipped';\n}\n\n/** Construct the strategy-contributor decl Account emits for one\n * acquired identity. Auto-mounted: the registry's role is\n * infrastructure; the user never types it explicitly. */\nexport const makeAccountRegistryContribution = <Name extends string>(\n\tentry: AccountRegistryEntry & { readonly name: Name },\n): StrategyContributorDecl<AccountRegistryKey<Name>, AccountRegistryEntry> => ({\n\tkind: 'strategy-contributor',\n\tcapabilityKey: accountRegistryKey(entry.name),\n\tstrategy: entry,\n\tautoMounted: true,\n});\n\nexport const makeAccountProjectionContribution = <Name extends string>(\n\tentry: AccountRegistryEntry & { readonly name: Name },\n): ProjectionDecl => {\n\tconst updatedAt = Date.now();\n\tconst key = `account/${entry.name}` as `account/${string}`;\n\treturn projection({\n\t\tkind: 'account',\n\t\tkey,\n\t\tpayload: {\n\t\t\tkey,\n\t\t\trowKey: null,\n\t\t\tname: entry.name,\n\t\t\taddress: entry.address,\n\t\t\tscheme: entry.scheme,\n\t\t\tsource: entry.source,\n\t\t\tfunding: entry.funding,\n\t\t\twalletVisible: false,\n\t\t\tupdatedAt,\n\t\t},\n\t\tat: updatedAt,\n\t});\n};\n"],"mappings":";;AAwBA,MAAa,sBAA2C,SACvD,WAAW;;;;AAkDZ,MAAa,mCACZ,WAC8E;CAC9E,MAAM;CACN,eAAe,mBAAmB,MAAM,IAAI;CAC5C,UAAU;CACV,aAAa;AACd;AAEA,MAAa,qCACZ,UACoB;CACpB,MAAM,YAAY,KAAK,IAAI;CAC3B,MAAM,MAAM,WAAW,MAAM;CAC7B,OAAO,WAAW;EACjB,MAAM;EACN;EACA,SAAS;GACR;GACA,QAAQ;GACR,MAAM,MAAM;GACZ,SAAS,MAAM;GACf,QAAQ,MAAM;GACd,QAAQ,MAAM;GACd,SAAS,MAAM;GACf,eAAe;GACf;EACD;EACA,IAAI;CACL,CAAC;AACF"}
@@ -1,45 +1,54 @@
1
+ import { ExecutedFailure, TransactionSignerScope } from "../sui/exec/index.mjs";
1
2
  import { AccountSignError } from "./errors.mjs";
2
- import { ExecutedFailure, TransactionSignerScope } from "../../substrate/runtime/sui-execute/index.mjs";
3
3
  import { AccountFunding, AccountFundingResult } from "./funding.mjs";
4
4
  import { Effect } from "effect";
5
5
 
6
6
  //#region src/plugins/account/service.d.ts
7
+ /** The bring-your-own signer shape the `signer` variant binds. Any
8
+ * `@mysten/sui/cryptography` `Signer` satisfies it — including every
9
+ * `Keypair` (`Ed25519Keypair`, `Secp256k1Keypair`, `Secp256r1Keypair`),
10
+ * hardware wallets, and custom KMS adapters. The structural shape is
11
+ * pinned here rather than importing the SDK's `Signer` so the substrate
12
+ * import surface stays SDK-free; a real `Signer` is assignable to it. */
13
+ interface AccountSignerInput {
14
+ readonly toSuiAddress: () => string;
15
+ readonly getKeyScheme: () => string;
16
+ readonly getPublicKey: () => {
17
+ readonly toRawBytes: () => Uint8Array;
18
+ };
19
+ readonly signTransaction: (tx: Uint8Array) => Promise<{
20
+ readonly bytes: string;
21
+ readonly signature: string;
22
+ }>;
23
+ readonly signPersonalMessage: (msg: Uint8Array) => Promise<{
24
+ readonly bytes: string;
25
+ readonly signature: string;
26
+ }>;
27
+ }
7
28
  /** Account variant discriminated union. The user-facing factory
8
29
  * takes one of these shapes (or omits `opts` entirely for the
9
- * default ephemeral form). */
30
+ * default ephemeral form).
31
+ *
32
+ * Three variants:
33
+ *
34
+ * - `ephemeral` — generate-or-recover an Ed25519 keypair under the
35
+ * stack runtime root, funded by default. This is the bare-form
36
+ * default (`account('alice')`).
37
+ * - `signer` — the single bring-your-own door. Pass any
38
+ * `@mysten/sui/cryptography` `Signer` (hardware wallet, KMS
39
+ * adapter, dApp signer) or any `Keypair`. Loading a secret from an
40
+ * env var or an inline `suiprivkey1...` literal is expressed by
41
+ * building the `Keypair` yourself, e.g.
42
+ * `{ kind: 'signer', signer: Ed25519Keypair.fromSecretKey(process.env.X) }`.
43
+ * - `impersonate` — fork-mode only: execute AS a seeded address with
44
+ * no secret material (sign-and-execute routes through the fork's
45
+ * impersonation submit path). */
10
46
  type AccountOptions<Funding extends AccountFunding = AccountFunding> = {
11
47
  readonly kind: 'ephemeral';
12
48
  readonly funding?: Funding;
13
- } | {
14
- readonly kind: 'keystore';
15
- readonly path: string;
16
- readonly aliasOrAddress: string;
17
- readonly funding?: Funding;
18
- } | {
19
- readonly kind: 'env';
20
- readonly key: string;
21
- readonly funding?: Funding;
22
- } | {
23
- readonly kind: 'inline';
24
- readonly privateKey: string | Uint8Array;
25
- readonly funding?: Funding;
26
49
  } | {
27
50
  readonly kind: 'signer';
28
- readonly signer: {
29
- readonly toSuiAddress: () => string;
30
- readonly getKeyScheme: () => string;
31
- readonly getPublicKey: () => {
32
- readonly toRawBytes: () => Uint8Array;
33
- };
34
- readonly signTransaction: (tx: Uint8Array) => Promise<{
35
- readonly bytes: string;
36
- readonly signature: string;
37
- }>;
38
- readonly signPersonalMessage: (msg: Uint8Array) => Promise<{
39
- readonly bytes: string;
40
- readonly signature: string;
41
- }>;
42
- };
51
+ readonly signer: AccountSignerInput;
43
52
  readonly addressOverride?: string;
44
53
  readonly funding?: Funding;
45
54
  } | {
@@ -60,8 +69,8 @@ interface AccountValue {
60
69
  readonly address: string;
61
70
  readonly scheme: 'ed25519' | 'secp256k1' | 'secp256r1';
62
71
  readonly publicKey: Uint8Array;
63
- /** Source discriminator — `'real'` for ephemeral / keystore / env
64
- * / inline / signer; `'impersonate'` for the fork-only variant. */
72
+ /** Source discriminator — `'real'` for ephemeral / signer;
73
+ * `'impersonate'` for the fork-only variant. */
65
74
  readonly source: 'real' | 'impersonate';
66
75
  /** Sign + execute (the canonical execution surface — per-address
67
76
  * serialized, post-submit transaction-wait included, bounded
@@ -106,7 +115,7 @@ interface TxResult {
106
115
  *
107
116
  * The on-chain `FailedTransaction` projection is the substrate
108
117
  * `ExecutedFailure` shape — single source of truth lives in
109
- * `substrate/runtime/sui-execute/index.ts`. An envelope without a
118
+ * `plugins/sui/exec/index.ts`. An envelope without a
110
119
  * digest fails at projection with `AccountSignError(phase: 'no-digest')`. */
111
120
  type SignAndExecuteResult = {
112
121
  readonly $kind: 'Transaction';
@@ -119,5 +128,5 @@ interface AccountTransactionSigner extends TransactionSignerScope<AccountSignErr
119
128
  readonly signAndExecute: AccountValue['signAndExecute'];
120
129
  }
121
130
  //#endregion
122
- export { AccountOptions, AccountValue, SignAndExecuteResult, TxResult };
131
+ export { AccountOptions, AccountSignerInput, AccountValue, SignAndExecuteResult, TxResult };
123
132
  //# sourceMappingURL=service.d.mts.map
@@ -1,18 +1,13 @@
1
1
  import { FUNDING_BALANCE_READ_TIMEOUT_MS } from "../../substrate/runtime/retry-policy.mjs";
2
2
  import { LeaseBrokerService } from "../../substrate/runtime/lease-broker/service.mjs";
3
3
  import "../../substrate/runtime/lease-broker/index.mjs";
4
- import { SuiSpans } from "../sui/spans.mjs";
5
- import { extractExecuteDigest } from "../../substrate/runtime/sui-execute/index.mjs";
4
+ import { extractExecuteDigest } from "../sui/exec/index.mjs";
6
5
  import "../sui/index.mjs";
7
- import { AccountSpans } from "./spans.mjs";
8
6
  import { accountAcquireError, accountSignError } from "./errors.mjs";
9
7
  import { withAddressLease } from "./lease.mjs";
10
8
  import { DEFAULT_EPHEMERAL_FUND_MIST, SUI_FULL_COIN_TYPE, applyCrossCuttingFunding, fundEphemeralDefault } from "./funding.mjs";
11
9
  import "./keypair.mjs";
12
10
  import { resolveEphemeralVariant } from "./variants/ephemeral.mjs";
13
- import { resolveKeystoreVariant } from "./variants/keystore.mjs";
14
- import { resolveEnvVariant } from "./variants/env.mjs";
15
- import { resolveInlineVariant } from "./variants/inline.mjs";
16
11
  import { resolveSignerVariant } from "./variants/signer.mjs";
17
12
  import { resolveImpersonateVariant } from "./variants/impersonate.mjs";
18
13
  import { Effect } from "effect";
@@ -134,19 +129,6 @@ const resolveVariant = (opts, ctx) => {
134
129
  name: opts.name,
135
130
  secretFilePath: `${ctx.runtimeRoot}/account/${opts.name}.key`
136
131
  });
137
- case "keystore": return resolveKeystoreVariant({
138
- name: opts.name,
139
- path: opts.path,
140
- aliasOrAddress: opts.aliasOrAddress
141
- });
142
- case "env": return resolveEnvVariant({
143
- name: opts.name,
144
- varName: opts.key
145
- });
146
- case "inline": return resolveInlineVariant({
147
- name: opts.name,
148
- privateKey: opts.privateKey
149
- });
150
132
  case "signer": return resolveSignerVariant({
151
133
  name: opts.name,
152
134
  signer: opts.signer,
@@ -281,15 +263,9 @@ const buildClosures = (args) => {
281
263
  };
282
264
  const withTransactionSigner = (body) => withAddressLease(broker, accountName, resolved.address, Effect.gen(function* () {
283
265
  return yield* body(transactionSigner);
284
- })).pipe(Effect.withSpan("devstack.plugin.account.transactionSigner", { attributes: {
285
- [AccountSpans.name]: accountName,
286
- [AccountSpans.address]: resolved.address
287
- } }));
266
+ }));
288
267
  return {
289
- signAndExecute: (tx) => withTransactionSigner((locked) => locked.signAndExecute(tx)).pipe(Effect.withSpan("devstack.plugin.account.signAndExecute", { attributes: {
290
- [AccountSpans.name]: accountName,
291
- [AccountSpans.address]: resolved.address
292
- } })),
268
+ signAndExecute: (tx) => withTransactionSigner((locked) => locked.signAndExecute(tx)),
293
269
  withTransactionSigner,
294
270
  signTransaction: refuse,
295
271
  signPersonalMessage: refuse
@@ -335,22 +311,10 @@ const buildClosures = (args) => {
335
311
  };
336
312
  const withTransactionSigner = (body) => withAddressLease(broker, accountName, resolved.address, Effect.gen(function* () {
337
313
  return yield* body(transactionSigner);
338
- })).pipe(Effect.withSpan("devstack.plugin.account.transactionSigner", { attributes: {
339
- [AccountSpans.name]: accountName,
340
- [AccountSpans.address]: resolved.address
341
- } }));
342
- const signTransaction = (tx) => withTransactionSigner((locked) => locked.signTransaction(tx)).pipe(Effect.withSpan("devstack.plugin.account.signTransaction", { attributes: {
343
- [AccountSpans.name]: accountName,
344
- [AccountSpans.address]: resolved.address
345
- } }));
346
- const signPersonalMessage = (msg) => withAddressLease(broker, accountName, resolved.address, signPersonalWith(signer, msg, accountName, resolved.address)).pipe(Effect.withSpan("devstack.plugin.account.signPersonalMessage", { attributes: {
347
- [AccountSpans.name]: accountName,
348
- [AccountSpans.address]: resolved.address
349
- } }));
350
- const signAndExecute = (tx) => withTransactionSigner((locked) => locked.signAndExecute(tx)).pipe(Effect.withSpan("devstack.plugin.account.signAndExecute", { attributes: {
351
- [AccountSpans.name]: accountName,
352
- [AccountSpans.address]: resolved.address
353
- } }));
314
+ }));
315
+ const signTransaction = (tx) => withTransactionSigner((locked) => locked.signTransaction(tx));
316
+ const signPersonalMessage = (msg) => withAddressLease(broker, accountName, resolved.address, signPersonalWith(signer, msg, accountName, resolved.address));
317
+ const signAndExecute = (tx) => withTransactionSigner((locked) => locked.signAndExecute(tx));
354
318
  return {
355
319
  signAndExecute,
356
320
  withTransactionSigner,
@@ -362,16 +326,7 @@ const buildClosures = (args) => {
362
326
  * the resolved-value projection. */
363
327
  const acquireAccount = (opts, ctx) => Effect.gen(function* () {
364
328
  yield* validateAccountName(opts.name);
365
- yield* Effect.annotateCurrentSpan({
366
- [AccountSpans.name]: opts.name,
367
- [AccountSpans.variant]: opts.kind,
368
- [SuiSpans.mode]: ctx.sui.mode
369
- });
370
329
  const resolved = yield* resolveVariant(opts, ctx);
371
- yield* Effect.annotateCurrentSpan({
372
- [AccountSpans.address]: resolved.address,
373
- [AccountSpans.scheme]: resolved.scheme
374
- });
375
330
  const broker = yield* LeaseBrokerService;
376
331
  const balanceReader = makeFundingBalanceReader(ctx.sui.sdk, ctx.sui.mode === "fork");
377
332
  const defaultFunding = opts.kind === "ephemeral" && opts.funding === void 0 ? {
@@ -387,7 +342,7 @@ const acquireAccount = (opts, ctx) => Effect.gen(function* () {
387
342
  address: resolved.address,
388
343
  amountMist: defaultFunding.amount,
389
344
  suiMode: ctx.sui.mode,
390
- chainId: ctx.sui.chain,
345
+ chainId: ctx.sui.chainId,
391
346
  emitAutoPromotionEvent: ctx.emitAutoPromotionEvent,
392
347
  broker,
393
348
  balanceReader
@@ -425,7 +380,7 @@ const acquireAccount = (opts, ctx) => Effect.gen(function* () {
425
380
  variant: opts.kind,
426
381
  account: value,
427
382
  funding: projected,
428
- chainId: ctx.sui.chain,
383
+ chainId: ctx.sui.chainId,
429
384
  broker,
430
385
  balanceReader
431
386
  });
@@ -1 +1 @@
1
- {"version":3,"file":"service.mjs","names":[],"sources":["../../../src/plugins/account/service.ts"],"sourcesContent":["// Account plugin — service body (main acquire Effect).\n//\n// What this file does:\n//\n// 1. Validate the account name (12-account.md \"Name shape\"\n// invariant) — strict charset, length-bounded. Loud-fail at\n// the factory boundary.\n// 2. Dispatch on the variant discriminator to the right resolver\n// under `variants/`.\n// 3. Coordinate the funding pass (default + cross-cutting).\n// 4. Project the resolved keypair into the user-facing\n// `AccountValue` shape (sign + execute closures).\n//\n// What it does NOT do:\n//\n// - Talk to the chain or the faucet directly — the variant\n// resolvers + the funding helpers own those wires.\n// - Wire the capabilities — that's the barrel's job (`index.ts`).\n//\n// Distilled-doc invariant (\"Acquisition vs signing error split\"):\n// the acquire body emits ONLY `AccountAcquireError`; the resolved\n// value's sign/execute closures emit `AccountSignError`. The two\n// channels never mix.\n//\n// Per-address serialization (architecture invariant): concurrent\n// account-bound transactions for the same address MUST serialize\n// across build + sign + execute. `Transaction.build({ client })`\n// resolves gas/object versions, so taking the lease only while\n// signing still lets two callers build stale object references. The\n// substrate's `LeaseBrokerService` is the L0 primitive: each\n// transaction scope opens a fresh lease keyed by `account:<address>`.\n// The public sign helpers are implemented in terms of that scope so\n// they keep the historical per-address behavior.\n\nimport { Effect } from 'effect';\n\nimport type { Signer, SignatureWithBytes } from '@mysten/sui/cryptography';\n\nimport {\n\taccountAcquireError,\n\taccountSignError,\n\ttype AccountAcquireError,\n\ttype AccountSignError,\n} from './errors.ts';\nimport { type ResolvedKeypair } from './keypair.ts';\nimport {\n\tapplyCrossCuttingFunding,\n\tfundEphemeralDefault,\n\tDEFAULT_EPHEMERAL_FUND_MIST,\n\tSUI_FULL_COIN_TYPE,\n\ttype AccountFunding,\n\ttype AccountFundingResult,\n\ttype AppliedFunding,\n\ttype AppliedFundingEntry,\n\ttype FundingBalanceReader,\n\ttype ProjectedFunding,\n\ttype ProjectedFundingEntry,\n} from './funding.ts';\nimport { resolveEphemeralVariant } from './variants/ephemeral.ts';\nimport { resolveKeystoreVariant } from './variants/keystore.ts';\nimport { resolveEnvVariant } from './variants/env.ts';\nimport { resolveInlineVariant } from './variants/inline.ts';\nimport { resolveSignerVariant } from './variants/signer.ts';\nimport { resolveImpersonateVariant } from './variants/impersonate.ts';\nimport type { StrategyRegistryService } from '../../substrate/runtime/strategy-registry/service.ts';\nimport type { ChainId } from '../../substrate/brand.ts';\nimport {\n\textractExecuteDigest,\n\ttype ExecutedFailure,\n\ttype TransactionSignerScope,\n} from '../../substrate/runtime/sui-execute/index.ts';\nimport {\n\tLeaseBrokerService,\n\ttype LeaseBroker,\n} from '../../substrate/runtime/lease-broker/index.ts';\nimport { FUNDING_BALANCE_READ_TIMEOUT_MS } from '../../substrate/runtime/retry-policy.ts';\nimport { type ForkAdminSurface, type SuiSdkShim, SuiSpans } from '../sui/index.ts';\nimport { withAddressLease } from './lease.ts';\nimport { AccountSpans } from './spans.ts';\n\n// -----------------------------------------------------------------------------\n// User-facing options shape\n// -----------------------------------------------------------------------------\n\n/** Account variant discriminated union. The user-facing factory\n * takes one of these shapes (or omits `opts` entirely for the\n * default ephemeral form). */\nexport type AccountOptions<Funding extends AccountFunding = AccountFunding> =\n\t| {\n\t\t\treadonly kind: 'ephemeral';\n\t\t\treadonly funding?: Funding;\n\t }\n\t| {\n\t\t\treadonly kind: 'keystore';\n\t\t\treadonly path: string;\n\t\t\treadonly aliasOrAddress: string;\n\t\t\treadonly funding?: Funding;\n\t }\n\t| {\n\t\t\treadonly kind: 'env';\n\t\t\treadonly key: string;\n\t\t\treadonly funding?: Funding;\n\t }\n\t| {\n\t\t\treadonly kind: 'inline';\n\t\t\treadonly privateKey: string | Uint8Array;\n\t\t\treadonly funding?: Funding;\n\t }\n\t| {\n\t\t\treadonly kind: 'signer';\n\t\t\treadonly signer: {\n\t\t\t\treadonly toSuiAddress: () => string;\n\t\t\t\treadonly getKeyScheme: () => string;\n\t\t\t\treadonly getPublicKey: () => { readonly toRawBytes: () => Uint8Array };\n\t\t\t\treadonly signTransaction: (\n\t\t\t\t\ttx: Uint8Array,\n\t\t\t\t) => Promise<{ readonly bytes: string; readonly signature: string }>;\n\t\t\t\treadonly signPersonalMessage: (\n\t\t\t\t\tmsg: Uint8Array,\n\t\t\t\t) => Promise<{ readonly bytes: string; readonly signature: string }>;\n\t\t\t};\n\t\t\treadonly addressOverride?: string;\n\t\t\treadonly funding?: Funding;\n\t }\n\t| {\n\t\t\treadonly kind: 'impersonate';\n\t\t\treadonly address: string;\n\t\t\treadonly funding?: Funding;\n\t };\n\nexport type ResolvedAccountOptions<Funding extends AccountFunding = AccountFunding> =\n\tAccountOptions<Funding> & { readonly name: string };\n\n// -----------------------------------------------------------------------------\n// Resolved value (the Tag's resolved-shape)\n// -----------------------------------------------------------------------------\n\n/** Per-account resolved value — the typed handle the Account tag\n * publishes.\n *\n * Architecture-distilled finding (12-account.md \"Tighten the\n * resolved-account type\"): the `source` discriminator is mandatory\n * so consumers can branch on impersonation. Impersonation accounts\n * carry a zero-buffer publicKey — the discriminator is the\n * trustworthy signal. */\nexport interface AccountValue {\n\treadonly name: string;\n\treadonly address: string;\n\treadonly scheme: 'ed25519' | 'secp256k1' | 'secp256r1';\n\treadonly publicKey: Uint8Array;\n\t/** Source discriminator — `'real'` for ephemeral / keystore / env\n\t * / inline / signer; `'impersonate'` for the fork-only variant. */\n\treadonly source: 'real' | 'impersonate';\n\t/** Sign + execute (the canonical execution surface — per-address\n\t * serialized, post-submit transaction-wait included, bounded\n\t * retry on the \"dependent package not found on-chain\" race).\n\t *\n\t * For impersonation accounts, routes through Sui's fork\n\t * admin `impersonate` surface; for real signers, routes\n\t * through the SDK's executeTransaction surface. */\n\treadonly signAndExecute: (\n\t\ttx: Uint8Array,\n\t) => Effect.Effect<SignAndExecuteResult, AccountSignError>;\n\t/** Run a full account-bound transaction critical section.\n\t * Callers that must serialize `Transaction.build({ client })`\n\t * together with signing/execution use the signer passed to this\n\t * callback; the callback runs while the per-address lease is held. */\n\treadonly withTransactionSigner: <A, E, R>(\n\t\tbody: (signer: AccountTransactionSigner) => Effect.Effect<A, E, R>,\n\t) => Effect.Effect<A, E, R>;\n\t/** Sign-only — real signers honor this; impersonation accounts\n\t * throw synchronously (see `variants/impersonate.ts`). */\n\treadonly signTransaction: (\n\t\ttx: Uint8Array,\n\t) => Effect.Effect<{ readonly bytes: string; readonly signature: string }, AccountSignError>;\n\treadonly signPersonalMessage: (\n\t\tmsg: Uint8Array,\n\t) => Effect.Effect<{ readonly bytes: string; readonly signature: string }, AccountSignError>;\n\treadonly funding: AccountFundingResult;\n}\n\n/** Submit result projection — kept narrow so downstream consumers\n * don't depend on the full @mysten/sui execute envelope. Populated\n * only when the on-chain execution succeeded (the `'Transaction'`\n * variant of `SignAndExecuteResult`). */\nexport interface TxResult {\n\treadonly digest: string;\n\treadonly effects: unknown;\n\treadonly objectChanges: ReadonlyArray<unknown>;\n\treadonly balanceChanges: ReadonlyArray<unknown>;\n}\n\n/** Outcome of `signAndExecute`. Mirrors the SDK's discriminated\n * `SuiClientTypes.TransactionResult` shape — on-chain failures are\n * a RETURN VALUE (callers dispatch on `$kind`), NOT an error. Only\n * transport / lifecycle failures (sign refused, RPC unreachable,\n * finality wait broke) surface through `AccountSignError`.\n *\n * The on-chain `FailedTransaction` projection is the substrate\n * `ExecutedFailure` shape — single source of truth lives in\n * `substrate/runtime/sui-execute/index.ts`. An envelope without a\n * digest fails at projection with `AccountSignError(phase: 'no-digest')`. */\nexport type SignAndExecuteResult =\n\t| { readonly $kind: 'Transaction'; readonly Transaction: TxResult }\n\t| { readonly $kind: 'FailedTransaction'; readonly FailedTransaction: ExecutedFailure };\n\nexport interface AccountTransactionSigner extends TransactionSignerScope<AccountSignError> {\n\treadonly signAndExecute: AccountValue['signAndExecute'];\n}\n\n// -----------------------------------------------------------------------------\n// Name validation\n// -----------------------------------------------------------------------------\n\n/** Architecture-distilled invariant: name flows into the resource id, an\n * on-disk path, a manifest key, container labels, and generated\n * TypeScript exports. Keep the public name identifier-safe instead\n * of accepting path-safe spellings that codegen later rejects. */\nconst ACCOUNT_NAME_RE = /^[A-Za-z][A-Za-z0-9_]{0,63}$/;\nconst ACCOUNT_NAME_HINT =\n\t'letters, digits, and underscores; must start with a letter; max 64 chars; cannot be a TypeScript reserved word';\nconst TS_RESERVED_BINDING_NAMES = new Set([\n\t'as',\n\t'async',\n\t'await',\n\t'break',\n\t'case',\n\t'catch',\n\t'class',\n\t'const',\n\t'continue',\n\t'debugger',\n\t'default',\n\t'delete',\n\t'do',\n\t'else',\n\t'enum',\n\t'export',\n\t'extends',\n\t'false',\n\t'finally',\n\t'for',\n\t'from',\n\t'function',\n\t'if',\n\t'import',\n\t'in',\n\t'instanceof',\n\t'let',\n\t'new',\n\t'null',\n\t'of',\n\t'return',\n\t'super',\n\t'switch',\n\t'this',\n\t'throw',\n\t'true',\n\t'try',\n\t'typeof',\n\t'var',\n\t'void',\n\t'while',\n\t'with',\n\t'yield',\n]);\n\nconst accountNameInvalidReason = (name: string): string | null => {\n\tif (!ACCOUNT_NAME_RE.test(name)) {\n\t\treturn `must match ${ACCOUNT_NAME_RE.source}`;\n\t}\n\tif (TS_RESERVED_BINDING_NAMES.has(name)) {\n\t\treturn 'cannot be a TypeScript reserved word';\n\t}\n\treturn null;\n};\n\nexport const assertAccountName = (name: string): void => {\n\tconst reason = accountNameInvalidReason(name);\n\tif (reason !== null) {\n\t\tthrow new TypeError(`Account name '${name}' is invalid — ${reason}. ${ACCOUNT_NAME_HINT}`);\n\t}\n};\n\nexport const validateAccountName = (name: string): Effect.Effect<void, AccountAcquireError> => {\n\tconst reason = accountNameInvalidReason(name);\n\tif (reason !== null) {\n\t\treturn Effect.fail(\n\t\t\taccountAcquireError({\n\t\t\t\tphase: 'validate-name',\n\t\t\t\taccountName: name,\n\t\t\t\tvariant: 'ephemeral',\n\t\t\t\tmessage: `Account name '${name}' is invalid — ${reason}.`,\n\t\t\t\thint: ACCOUNT_NAME_HINT,\n\t\t\t}),\n\t\t);\n\t}\n\treturn Effect.void;\n};\n\n// -----------------------------------------------------------------------------\n// Variant dispatch\n// -----------------------------------------------------------------------------\n\n/** Sui mode + sdk shim — the slice of the resolved `SuiClient` the\n * account service actually consumes. Kept narrow so the variants +\n * funding helpers stay typed at the resolved-fields level (mode,\n * chain, sdk) rather than at the wide `SuiClient` shape. */\nexport interface AccountSuiShim {\n\treadonly mode: 'local' | 'local-rpc' | 'live' | 'fork';\n\treadonly chain: ChainId;\n\t/** SDK shim — exposes `executeTransaction` + `waitForTransaction`\n\t * for the signAndExecute pipeline. */\n\treadonly sdk: SuiSdkShim;\n\treadonly fork?: ForkAdminSurface | null;\n}\n\n/** Per-acquire context — supplied by the barrel from resolved plugin\n * dependencies and per-stack identity.\n *\n * `projectedFunding` carries the funding entries already resolved\n * from each `opts.funding[i].coin` dependency and projected to\n * `{fullCoinType, amount}` BEFORE handing off to `acquireAccount`.\n * The acquire body never sees the raw member refs — keeps the\n * cross-cutting funding dispatch substrate-name-blind. */\nexport interface AccountAcquireContext {\n\treadonly sui: AccountSuiShim;\n\treadonly runtimeRoot: string;\n\treadonly app: string;\n\treadonly stack: string;\n\treadonly emitAutoPromotionEvent: () => Effect.Effect<void>;\n\t/** Projected cross-cutting funding entries. Empty when `opts.funding`\n\t * is absent. The barrel stamps each resolved coin dependency's\n\t * `fullCoinType` here. */\n\treadonly projectedFunding?: ProjectedFunding;\n}\n\n/** Sum an owner's coin balances for `coinType` via `listCoins`. Used in\n * fork mode, where `getBalance` / `listBalances` panic under the fork\n * guard — `listCoins` is the only balance-bearing read fork mode allows. */\nconst sumBalanceViaListCoins = async (\n\tsdk: SuiSdkShim,\n\towner: string,\n\tcoinType: string | undefined,\n): Promise<bigint> => {\n\tlet total = 0n;\n\tlet cursor: string | null = null;\n\tdo {\n\t\tconst page = await sdk.core.listCoins({\n\t\t\towner,\n\t\t\tcoinType: coinType ?? '0x2::sui::SUI',\n\t\t\tcursor,\n\t\t\tlimit: 200,\n\t\t});\n\t\tfor (const coin of page.objects) {\n\t\t\ttotal += BigInt(coin.balance);\n\t\t}\n\t\tcursor = page.hasNextPage ? page.cursor : null;\n\t} while (cursor !== null);\n\treturn total;\n};\n\nconst makeFundingBalanceReader = (sdk: SuiSdkShim, forkMode: boolean): FundingBalanceReader => ({\n\treadBalance: ({ owner, coinType }) =>\n\t\tEffect.promise(async () => {\n\t\t\ttry {\n\t\t\t\t// Fork mode forbids getBalance/listBalances (they panic under the\n\t\t\t\t// fork guard); sum coins via the fork-safe listCoins instead.\n\t\t\t\treturn forkMode\n\t\t\t\t\t? await sumBalanceViaListCoins(sdk, owner, coinType)\n\t\t\t\t\t: balanceAmountFromSdkResponse(await sdk.core.getBalance({ owner, coinType }));\n\t\t\t} catch {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}).pipe(\n\t\t\tEffect.timeoutOrElse({\n\t\t\t\tduration: `${FUNDING_BALANCE_READ_TIMEOUT_MS} millis`,\n\t\t\t\torElse: () => Effect.succeed(null),\n\t\t\t}),\n\t\t),\n});\n\nconst balanceAmountFromSdkResponse = (response: unknown): bigint | null => {\n\tconst outer =\n\t\ttypeof response === 'object' && response !== null && 'balance' in response\n\t\t\t? (response as { readonly balance?: unknown }).balance\n\t\t\t: response;\n\tconst value =\n\t\ttypeof outer === 'object' && outer !== null && 'balance' in outer\n\t\t\t? (outer as { readonly balance?: unknown }).balance\n\t\t\t: outer;\n\tif (typeof value === 'bigint') return value;\n\tif (typeof value === 'number' && Number.isSafeInteger(value) && value >= 0) return BigInt(value);\n\tif (typeof value === 'string' && /^\\d+$/.test(value)) return BigInt(value);\n\treturn null;\n};\n\n/** Dispatch on the variant discriminator. */\nconst resolveVariant = (\n\topts: ResolvedAccountOptions,\n\tctx: AccountAcquireContext,\n): Effect.Effect<ResolvedKeypair, AccountAcquireError> => {\n\tswitch (opts.kind) {\n\t\tcase 'ephemeral':\n\t\t\treturn resolveEphemeralVariant({\n\t\t\t\tname: opts.name,\n\t\t\t\t// Architecture-distilled (12-account.md \"Cross-component\n\t\t\t\t// references\"): persisted key lives under the stack's\n\t\t\t\t// runtime tree. Path shape mirrors the on-disk convention.\n\t\t\t\tsecretFilePath: `${ctx.runtimeRoot}/account/${opts.name}.key`,\n\t\t\t});\n\t\tcase 'keystore':\n\t\t\treturn resolveKeystoreVariant({\n\t\t\t\tname: opts.name,\n\t\t\t\tpath: opts.path,\n\t\t\t\taliasOrAddress: opts.aliasOrAddress,\n\t\t\t});\n\t\tcase 'env':\n\t\t\treturn resolveEnvVariant({\n\t\t\t\tname: opts.name,\n\t\t\t\tvarName: opts.key,\n\t\t\t});\n\t\tcase 'inline':\n\t\t\treturn resolveInlineVariant({\n\t\t\t\tname: opts.name,\n\t\t\t\tprivateKey: opts.privateKey,\n\t\t\t});\n\t\tcase 'signer':\n\t\t\treturn resolveSignerVariant({\n\t\t\t\tname: opts.name,\n\t\t\t\tsigner: opts.signer,\n\t\t\t\t...(opts.addressOverride !== undefined ? { addressOverride: opts.addressOverride } : {}),\n\t\t\t});\n\t\tcase 'impersonate':\n\t\t\treturn resolveImpersonateVariant({\n\t\t\t\tname: opts.name,\n\t\t\t\taddress: opts.address,\n\t\t\t\tsuiMode: ctx.sui.mode,\n\t\t\t});\n\t}\n};\n\n// -----------------------------------------------------------------------------\n// Sign + execute closures\n// -----------------------------------------------------------------------------\n\n/** Promote a Promise-returning sign call into the typed-error\n * channel. The `signer.signTransaction` / `signPersonalMessage`\n * helpers on `@mysten/sui` `Signer` instances are async; the\n * bring-your-own-signer variant uses the same shape. */\nconst signWith = (\n\tsigner: {\n\t\treadonly signTransaction: (\n\t\t\ttx: Uint8Array,\n\t\t) => Promise<{ readonly bytes: string; readonly signature: string }>;\n\t},\n\ttx: Uint8Array,\n\taccountName: string,\n\taddress: string,\n): Effect.Effect<{ readonly bytes: string; readonly signature: string }, AccountSignError> =>\n\tEffect.tryPromise({\n\t\ttry: () => signer.signTransaction(tx),\n\t\tcatch: (cause): AccountSignError =>\n\t\t\taccountSignError({\n\t\t\t\tphase: 'sign',\n\t\t\t\taccountName,\n\t\t\t\taddress,\n\t\t\t\tmessage: `Account '${accountName}': signer.signTransaction() rejected.`,\n\t\t\t\tcause,\n\t\t\t}),\n\t});\n\nconst signPersonalWith = (\n\tsigner: {\n\t\treadonly signPersonalMessage: (\n\t\t\tmsg: Uint8Array,\n\t\t) => Promise<{ readonly bytes: string; readonly signature: string }>;\n\t},\n\tmsg: Uint8Array,\n\taccountName: string,\n\taddress: string,\n): Effect.Effect<{ readonly bytes: string; readonly signature: string }, AccountSignError> =>\n\tEffect.tryPromise({\n\t\ttry: () => signer.signPersonalMessage(msg),\n\t\tcatch: (cause): AccountSignError =>\n\t\t\taccountSignError({\n\t\t\t\tphase: 'sign',\n\t\t\t\taccountName,\n\t\t\t\taddress,\n\t\t\t\tmessage: `Account '${accountName}': signer.signPersonalMessage() rejected.`,\n\t\t\t\tcause,\n\t\t\t}),\n\t});\n\n/** Project the raw `@mysten/sui` executeTransaction response into\n * the narrowed `TxResult` shape consumers depend on. The SDK\n * response carries a discriminated union; the result we surface\n * always carries a digest plus the include-projected sub-fields. */\nconst projectTxResult = (\n\traw: unknown,\n\taccountName: string,\n\taddress: string,\n): Effect.Effect<SignAndExecuteResult, AccountSignError> =>\n\tEffect.gen(function* () {\n\t\t// The SDK's `SuiClientTypes.TransactionResult` is a discriminated\n\t\t// union — `{$kind: 'Transaction', Transaction: {...}}` or\n\t\t// `{$kind: 'FailedTransaction', FailedTransaction: {...}}` —\n\t\t// where each variant carries a non-optional `digest`. Mirror the\n\t\t// shape on-channel so callers dispatch on `$kind`; on-chain\n\t\t// failures are a RETURN VALUE, not an error.\n\t\tconst r = raw as {\n\t\t\t$kind?: 'Transaction' | 'FailedTransaction';\n\t\t\tTransaction?: {\n\t\t\t\tdigest?: string;\n\t\t\t\teffects?: unknown;\n\t\t\t\tobjectTypes?: Readonly<Record<string, string>>;\n\t\t\t\tbalanceChanges?: ReadonlyArray<unknown>;\n\t\t\t};\n\t\t\tFailedTransaction?: {\n\t\t\t\tdigest?: string;\n\t\t\t\tstatus?: { readonly error?: string | { readonly message?: string } };\n\t\t\t};\n\t\t};\n\t\tif (r.$kind === 'FailedTransaction') {\n\t\t\tconst failed = r.FailedTransaction ?? {};\n\t\t\tif (failed.digest === undefined) {\n\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\taccountSignError({\n\t\t\t\t\t\tphase: 'no-digest',\n\t\t\t\t\t\taccountName,\n\t\t\t\t\t\taddress,\n\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t`Account '${accountName}': executeTransaction returned a FailedTransaction ` +\n\t\t\t\t\t\t\t`without a digest — protocol violation, got ` +\n\t\t\t\t\t\t\t`${JSON.stringify(r).slice(0, 200)}`,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst errorRaw = failed.status?.error;\n\t\t\tconst executionError =\n\t\t\t\ttypeof errorRaw === 'string'\n\t\t\t\t\t? errorRaw\n\t\t\t\t\t: typeof errorRaw === 'object' &&\n\t\t\t\t\t\t errorRaw !== null &&\n\t\t\t\t\t\t 'message' in errorRaw &&\n\t\t\t\t\t\t typeof errorRaw.message === 'string'\n\t\t\t\t\t\t? errorRaw.message\n\t\t\t\t\t\t: undefined;\n\t\t\treturn {\n\t\t\t\t$kind: 'FailedTransaction',\n\t\t\t\tFailedTransaction: {\n\t\t\t\t\tdigest: failed.digest,\n\t\t\t\t\t...(executionError !== undefined ? { executionError } : {}),\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tconst tx = r.Transaction;\n\t\tif (tx?.digest === undefined) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\taccountSignError({\n\t\t\t\t\tphase: 'no-digest',\n\t\t\t\t\taccountName,\n\t\t\t\t\taddress,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t`Account '${accountName}': executeTransaction returned a malformed envelope — ` +\n\t\t\t\t\t\t`expected $kind:'Transaction'|'FailedTransaction' with a digest, got ` +\n\t\t\t\t\t\t`${JSON.stringify(r).slice(0, 200)}`,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\treturn {\n\t\t\t$kind: 'Transaction',\n\t\t\tTransaction: {\n\t\t\t\tdigest: tx.digest,\n\t\t\t\teffects: tx.effects ?? null,\n\t\t\t\tobjectChanges: projectObjectChanges(tx.effects, tx.objectTypes ?? {}),\n\t\t\t\tbalanceChanges: tx.balanceChanges ?? [],\n\t\t\t},\n\t\t};\n\t});\n\nconst projectObjectChanges = (\n\teffects: unknown,\n\tobjectTypes: Readonly<Record<string, string>>,\n): ReadonlyArray<unknown> => {\n\tconst changedObjects =\n\t\ttypeof effects === 'object' && effects !== null && 'changedObjects' in effects\n\t\t\t? (\n\t\t\t\t\teffects as {\n\t\t\t\t\t\treadonly changedObjects?: ReadonlyArray<{\n\t\t\t\t\t\t\treadonly objectId?: string;\n\t\t\t\t\t\t\treadonly outputState?: string;\n\t\t\t\t\t\t\treadonly idOperation?: string;\n\t\t\t\t\t\t}>;\n\t\t\t\t\t}\n\t\t\t\t).changedObjects\n\t\t\t: undefined;\n\tif (changedObjects === undefined) return [];\n\treturn changedObjects\n\t\t.filter(\n\t\t\t(\n\t\t\t\tchange,\n\t\t\t): change is {\n\t\t\t\treadonly objectId: string;\n\t\t\t\treadonly outputState?: string;\n\t\t\t\treadonly idOperation?: string;\n\t\t\t} => typeof change.objectId === 'string',\n\t\t)\n\t\t.map((change) => {\n\t\t\tconst objectType = objectTypes[change.objectId];\n\t\t\tconst entry: {\n\t\t\t\ttype: 'published' | 'created' | 'mutated';\n\t\t\t\tobjectId: string;\n\t\t\t\tobjectType?: string;\n\t\t\t\toutputState?: string;\n\t\t\t\tidOperation?: string;\n\t\t\t} = {\n\t\t\t\ttype:\n\t\t\t\t\tchange.outputState === 'PackageWrite'\n\t\t\t\t\t\t? 'published'\n\t\t\t\t\t\t: change.idOperation === 'Created'\n\t\t\t\t\t\t\t? 'created'\n\t\t\t\t\t\t\t: 'mutated',\n\t\t\t\tobjectId: change.objectId,\n\t\t\t};\n\t\t\tif (objectType !== undefined) entry.objectType = objectType;\n\t\t\tif (change.outputState !== undefined) entry.outputState = change.outputState;\n\t\t\tif (change.idOperation !== undefined) entry.idOperation = change.idOperation;\n\t\t\treturn entry;\n\t\t});\n};\n\ninterface BuildClosuresArgs {\n\treadonly accountName: string;\n\treadonly resolved: ResolvedKeypair;\n\treadonly sui: AccountSuiShim;\n\treadonly broker: LeaseBroker;\n\treadonly source: 'real' | 'impersonate';\n}\n\nconst buildClosures = (\n\targs: BuildClosuresArgs,\n): Pick<\n\tAccountValue,\n\t'signAndExecute' | 'withTransactionSigner' | 'signTransaction' | 'signPersonalMessage'\n> => {\n\tconst { accountName, resolved, sui, broker, source } = args;\n\n\t// Impersonation accounts MUST NOT sign — the synthetic signer's\n\t// signTransaction throws synchronously (architecture invariant).\n\t// signAndExecute routes through sui-fork's empty-signature\n\t// execution path while still holding the per-address lease.\n\tif (source === 'impersonate') {\n\t\tconst refuse = <A>(): Effect.Effect<A, AccountSignError> =>\n\t\t\tEffect.fail(\n\t\t\t\taccountSignError({\n\t\t\t\t\tphase: 'impersonation-bypass-attempt',\n\t\t\t\t\taccountName,\n\t\t\t\t\taddress: resolved.address,\n\t\t\t\t\tmessage: `Account '${accountName}' is an impersonation account — sign/execute must route through Sui's fork admin surface.`,\n\t\t\t\t}),\n\t\t\t);\n\t\tconst unlockedSignAndExecute: AccountTransactionSigner['signAndExecute'] = (tx) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst fork = sui.fork ?? null;\n\t\t\t\tif (fork === null) {\n\t\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\t\taccountSignError({\n\t\t\t\t\t\t\tphase: 'submit',\n\t\t\t\t\t\t\taccountName,\n\t\t\t\t\t\t\taddress: resolved.address,\n\t\t\t\t\t\t\tmessage: `Account '${accountName}': impersonation requires a fork-mode Sui client.`,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst submitted = yield* fork.impersonate(resolved.address, tx).pipe(\n\t\t\t\t\tEffect.mapError(\n\t\t\t\t\t\t(cause): AccountSignError =>\n\t\t\t\t\t\t\taccountSignError({\n\t\t\t\t\t\t\t\tphase: 'submit',\n\t\t\t\t\t\t\t\taccountName,\n\t\t\t\t\t\t\t\taddress: resolved.address,\n\t\t\t\t\t\t\t\tmessage: `Account '${accountName}': fork impersonation submit failed.`,\n\t\t\t\t\t\t\t\tcause,\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.tryPromise({\n\t\t\t\t\ttry: () =>\n\t\t\t\t\t\tsui.sdk.core.waitForTransaction({\n\t\t\t\t\t\t\tdigest: submitted.digest,\n\t\t\t\t\t\t}),\n\t\t\t\t\tcatch: (cause): AccountSignError =>\n\t\t\t\t\t\taccountSignError({\n\t\t\t\t\t\t\tphase: 'await-finality',\n\t\t\t\t\t\t\taccountName,\n\t\t\t\t\t\t\taddress: resolved.address,\n\t\t\t\t\t\t\tmessage: `Account '${accountName}': waitForTransaction(${submitted.digest}) failed.`,\n\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t\treturn yield* projectTxResult(submitted.raw, accountName, resolved.address);\n\t\t\t});\n\t\tconst transactionSigner: AccountTransactionSigner = {\n\t\t\tsignTransaction: refuse<{ readonly bytes: string; readonly signature: string }>,\n\t\t\tsignAndExecute: unlockedSignAndExecute,\n\t\t};\n\t\tconst withTransactionSigner: AccountValue['withTransactionSigner'] = (body) =>\n\t\t\twithAddressLease(\n\t\t\t\tbroker,\n\t\t\t\taccountName,\n\t\t\t\tresolved.address,\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\treturn yield* body(transactionSigner);\n\t\t\t\t}),\n\t\t\t).pipe(\n\t\t\t\tEffect.withSpan('devstack.plugin.account.transactionSigner', {\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\t[AccountSpans.name]: accountName,\n\t\t\t\t\t\t[AccountSpans.address]: resolved.address,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t);\n\t\treturn {\n\t\t\tsignAndExecute: (tx) =>\n\t\t\t\twithTransactionSigner((locked) => locked.signAndExecute(tx)).pipe(\n\t\t\t\t\tEffect.withSpan('devstack.plugin.account.signAndExecute', {\n\t\t\t\t\t\tattributes: {\n\t\t\t\t\t\t\t[AccountSpans.name]: accountName,\n\t\t\t\t\t\t\t[AccountSpans.address]: resolved.address,\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\twithTransactionSigner,\n\t\t\tsignTransaction: refuse<{ readonly bytes: string; readonly signature: string }>,\n\t\t\tsignPersonalMessage: refuse<{ readonly bytes: string; readonly signature: string }>,\n\t\t};\n\t}\n\n\t// Both real-keypair and bring-your-own-signer paths satisfy the\n\t// minimal `signTransaction` / `signPersonalMessage` shape (the\n\t// SDK's `Signer` and the BYO `signer` declaration agree on it).\n\tconst signer = resolved.signer as Pick<Signer, 'signTransaction' | 'signPersonalMessage'>;\n\n\tconst unlockedSignTransaction: AccountTransactionSigner['signTransaction'] = (tx) =>\n\t\tsignWith(signer, tx, accountName, resolved.address);\n\n\tconst unlockedSignAndExecute: AccountTransactionSigner['signAndExecute'] = (tx) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst signed: SignatureWithBytes = yield* unlockedSignTransaction(tx);\n\t\t\tconst raw = yield* Effect.tryPromise({\n\t\t\t\ttry: () =>\n\t\t\t\t\tsui.sdk.core.executeTransaction({\n\t\t\t\t\t\ttransaction: tx,\n\t\t\t\t\t\tsignatures: [signed.signature],\n\t\t\t\t\t\tinclude: { effects: true, objectTypes: true },\n\t\t\t\t\t}),\n\t\t\t\tcatch: (cause): AccountSignError =>\n\t\t\t\t\taccountSignError({\n\t\t\t\t\t\tphase: 'submit',\n\t\t\t\t\t\taccountName,\n\t\t\t\t\t\taddress: resolved.address,\n\t\t\t\t\t\tmessage: `Account '${accountName}': executeTransaction transport failed.`,\n\t\t\t\t\t\tcause,\n\t\t\t\t\t}),\n\t\t\t});\n\t\t\tconst digest = extractExecuteDigest(raw);\n\t\t\tif (digest !== undefined) {\n\t\t\t\tyield* Effect.tryPromise({\n\t\t\t\t\ttry: () =>\n\t\t\t\t\t\tsui.sdk.core.waitForTransaction({\n\t\t\t\t\t\t\tdigest,\n\t\t\t\t\t\t}),\n\t\t\t\t\tcatch: (cause): AccountSignError =>\n\t\t\t\t\t\taccountSignError({\n\t\t\t\t\t\t\tphase: 'await-finality',\n\t\t\t\t\t\t\taccountName,\n\t\t\t\t\t\t\taddress: resolved.address,\n\t\t\t\t\t\t\tmessage: `Account '${accountName}': waitForTransaction(${digest}) failed.`,\n\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn yield* projectTxResult(raw, accountName, resolved.address);\n\t\t});\n\n\tconst transactionSigner: AccountTransactionSigner = {\n\t\tsignTransaction: unlockedSignTransaction,\n\t\tsignAndExecute: unlockedSignAndExecute,\n\t};\n\n\tconst withTransactionSigner: AccountValue['withTransactionSigner'] = (body) =>\n\t\twithAddressLease(\n\t\t\tbroker,\n\t\t\taccountName,\n\t\t\tresolved.address,\n\t\t\tEffect.gen(function* () {\n\t\t\t\treturn yield* body(transactionSigner);\n\t\t\t}),\n\t\t).pipe(\n\t\t\tEffect.withSpan('devstack.plugin.account.transactionSigner', {\n\t\t\t\tattributes: {\n\t\t\t\t\t[AccountSpans.name]: accountName,\n\t\t\t\t\t[AccountSpans.address]: resolved.address,\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\n\tconst signTransaction: AccountValue['signTransaction'] = (tx) =>\n\t\twithTransactionSigner((locked) => locked.signTransaction(tx)).pipe(\n\t\t\tEffect.withSpan('devstack.plugin.account.signTransaction', {\n\t\t\t\tattributes: {\n\t\t\t\t\t[AccountSpans.name]: accountName,\n\t\t\t\t\t[AccountSpans.address]: resolved.address,\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\n\tconst signPersonalMessage: AccountValue['signPersonalMessage'] = (msg) =>\n\t\twithAddressLease(\n\t\t\tbroker,\n\t\t\taccountName,\n\t\t\tresolved.address,\n\t\t\tsignPersonalWith(signer, msg, accountName, resolved.address),\n\t\t).pipe(\n\t\t\tEffect.withSpan('devstack.plugin.account.signPersonalMessage', {\n\t\t\t\tattributes: {\n\t\t\t\t\t[AccountSpans.name]: accountName,\n\t\t\t\t\t[AccountSpans.address]: resolved.address,\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\n\tconst signAndExecute: AccountValue['signAndExecute'] = (tx) =>\n\t\twithTransactionSigner((locked) => locked.signAndExecute(tx)).pipe(\n\t\t\tEffect.withSpan('devstack.plugin.account.signAndExecute', {\n\t\t\t\tattributes: {\n\t\t\t\t\t[AccountSpans.name]: accountName,\n\t\t\t\t\t[AccountSpans.address]: resolved.address,\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\n\treturn { signAndExecute, withTransactionSigner, signTransaction, signPersonalMessage };\n};\n\n// -----------------------------------------------------------------------------\n// Acquire orchestration\n// -----------------------------------------------------------------------------\n\n/** Acquire an account. Coordinates variant dispatch + funding +\n * the resolved-value projection. */\nexport const acquireAccount = (\n\topts: ResolvedAccountOptions,\n\tctx: AccountAcquireContext,\n): Effect.Effect<AccountValue, AccountAcquireError, StrategyRegistryService | LeaseBrokerService> =>\n\tEffect.gen(function* () {\n\t\tyield* validateAccountName(opts.name);\n\n\t\tyield* Effect.annotateCurrentSpan({\n\t\t\t[AccountSpans.name]: opts.name,\n\t\t\t[AccountSpans.variant]: opts.kind,\n\t\t\t[SuiSpans.mode]: ctx.sui.mode,\n\t\t});\n\n\t\t// --- variant dispatch ----------------------------------------\n\t\tconst resolved = yield* resolveVariant(opts, ctx);\n\n\t\tyield* Effect.annotateCurrentSpan({\n\t\t\t[AccountSpans.address]: resolved.address,\n\t\t\t[AccountSpans.scheme]: resolved.scheme,\n\t\t});\n\n\t\t// --- lease broker handle (captured once; both funding and the\n\t\t// resolved-value closures share this handle so concurrent\n\t\t// callers serialize through the substrate broker's per-key\n\t\t// FIFO queue) -------------------------------------------\n\t\tconst broker = yield* LeaseBrokerService;\n\t\tconst balanceReader = makeFundingBalanceReader(ctx.sui.sdk, ctx.sui.mode === 'fork');\n\n\t\tconst defaultFunding: ProjectedFundingEntry | null =\n\t\t\topts.kind === 'ephemeral' && opts.funding === undefined\n\t\t\t\t? {\n\t\t\t\t\t\tcoin: 'SUI',\n\t\t\t\t\t\tfullCoinType: SUI_FULL_COIN_TYPE,\n\t\t\t\t\t\tamount: DEFAULT_EPHEMERAL_FUND_MIST,\n\t\t\t\t\t}\n\t\t\t\t: null;\n\t\tconst requestedFunding =\n\t\t\tdefaultFunding === null\n\t\t\t\t? (ctx.projectedFunding ?? [])\n\t\t\t\t: [defaultFunding, ...(ctx.projectedFunding ?? [])];\n\t\tconst appliedDefaultFunding: AppliedFundingEntry[] = [];\n\n\t\t// --- default funding (bare ephemeral only) -------------------\n\t\tif (defaultFunding !== null) {\n\t\t\t// Outcome distinguishes a real faucet call (`'funded'`) from\n\t\t\t// the pre-existing-balance short-circuit (`'already-satisfied'`),\n\t\t\t// so the registry projection doesn't mislabel a no-faucet-call\n\t\t\t// entry as funded. `'skipped'` (zero amount) drops out entirely\n\t\t\t// per the same invariant as the cross-cutting pass.\n\t\t\tconst outcome = yield* fundEphemeralDefault({\n\t\t\t\taccountName: opts.name,\n\t\t\t\taddress: resolved.address,\n\t\t\t\tamountMist: defaultFunding.amount,\n\t\t\t\tsuiMode: ctx.sui.mode,\n\t\t\t\tchainId: ctx.sui.chain,\n\t\t\t\temitAutoPromotionEvent: ctx.emitAutoPromotionEvent,\n\t\t\t\tbroker,\n\t\t\t\tbalanceReader,\n\t\t\t});\n\t\t\tif (outcome !== 'skipped') {\n\t\t\t\tappliedDefaultFunding.push({ ...defaultFunding, outcome });\n\t\t\t}\n\t\t}\n\n\t\tconst source: AccountValue['source'] = opts.kind === 'impersonate' ? 'impersonate' : 'real';\n\t\tconst closures = buildClosures({\n\t\t\taccountName: opts.name,\n\t\t\tresolved,\n\t\t\tsui: ctx.sui,\n\t\t\tbroker,\n\t\t\tsource,\n\t\t});\n\n\t\t// --- project the resolved value ------------------------------\n\t\tconst value: AccountValue = {\n\t\t\tname: opts.name,\n\t\t\taddress: resolved.address,\n\t\t\tscheme: resolved.scheme,\n\t\t\tpublicKey: resolved.publicKey,\n\t\t\tsource,\n\t\t\tfunding: {\n\t\t\t\trequested: requestedFunding,\n\t\t\t\tapplied: appliedDefaultFunding,\n\t\t\t},\n\t\t\t...closures,\n\t\t};\n\n\t\t// --- cross-cutting funding (all variants) --------------------\n\t\t//\n\t\t// The barrel pre-projects each user-supplied `CoinMember` to\n\t\t// `{fullCoinType, amount}` from resolved dependencies so this\n\t\t// dispatch stays substrate-name-blind. The resolved account\n\t\t// handle is passed so strategy providers without admin\n\t\t// capabilities can sign account-owned funding swaps. Missing /\n\t\t// empty `projectedFunding` is a no-op (matches the \"Optional\n\t\t// Faucet is a noop\" invariant).\n\t\tconst projected = ctx.projectedFunding ?? [];\n\t\tlet appliedCrossCuttingFunding: AppliedFunding = [];\n\t\tif (projected.length > 0) {\n\t\t\tappliedCrossCuttingFunding = yield* applyCrossCuttingFunding({\n\t\t\t\taccountName: opts.name,\n\t\t\t\taddress: resolved.address,\n\t\t\t\tvariant: opts.kind,\n\t\t\t\taccount: value,\n\t\t\t\tfunding: projected,\n\t\t\t\tchainId: ctx.sui.chain,\n\t\t\t\tbroker,\n\t\t\t\tbalanceReader,\n\t\t\t});\n\t\t}\n\n\t\treturn {\n\t\t\t...value,\n\t\t\tfunding: {\n\t\t\t\trequested: requestedFunding,\n\t\t\t\tapplied: [...appliedDefaultFunding, ...appliedCrossCuttingFunding],\n\t\t\t},\n\t\t};\n\t});\n"],"mappings":"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"}
1
+ {"version":3,"file":"service.mjs","names":[],"sources":["../../../src/plugins/account/service.ts"],"sourcesContent":["// Account plugin — service body (main acquire Effect).\n//\n// What this file does:\n//\n// 1. Validate the account name (12-account.md \"Name shape\"\n// invariant) — strict charset, length-bounded. Loud-fail at\n// the factory boundary.\n// 2. Dispatch on the variant discriminator to the right resolver\n// under `variants/`.\n// 3. Coordinate the funding pass (default + cross-cutting).\n// 4. Project the resolved keypair into the user-facing\n// `AccountValue` shape (sign + execute closures).\n//\n// What it does NOT do:\n//\n// - Talk to the chain or the faucet directly — the variant\n// resolvers + the funding helpers own those wires.\n// - Wire the capabilities — that's the barrel's job (`index.ts`).\n//\n// Distilled-doc invariant (\"Acquisition vs signing error split\"):\n// the acquire body emits ONLY `AccountAcquireError`; the resolved\n// value's sign/execute closures emit `AccountSignError`. The two\n// channels never mix.\n//\n// Per-address serialization (architecture invariant): concurrent\n// account-bound transactions for the same address MUST serialize\n// across build + sign + execute. `Transaction.build({ client })`\n// resolves gas/object versions, so taking the lease only while\n// signing still lets two callers build stale object references. The\n// substrate's `LeaseBrokerService` is the L0 primitive: each\n// transaction scope opens a fresh lease keyed by `account:<address>`.\n// The public sign helpers are implemented in terms of that scope so\n// they keep the per-address serialization behavior.\n\nimport { Effect } from 'effect';\n\nimport type { Signer, SignatureWithBytes } from '@mysten/sui/cryptography';\n\nimport {\n\taccountAcquireError,\n\taccountSignError,\n\ttype AccountAcquireError,\n\ttype AccountSignError,\n} from './errors.ts';\nimport { type ResolvedKeypair } from './keypair.ts';\nimport {\n\tapplyCrossCuttingFunding,\n\tfundEphemeralDefault,\n\tDEFAULT_EPHEMERAL_FUND_MIST,\n\tSUI_FULL_COIN_TYPE,\n\ttype AccountFunding,\n\ttype AccountFundingResult,\n\ttype AppliedFunding,\n\ttype AppliedFundingEntry,\n\ttype FundingBalanceReader,\n\ttype ProjectedFunding,\n\ttype ProjectedFundingEntry,\n} from './funding.ts';\nimport { resolveEphemeralVariant } from './variants/ephemeral.ts';\nimport { resolveSignerVariant } from './variants/signer.ts';\nimport { resolveImpersonateVariant } from './variants/impersonate.ts';\nimport type { StrategyRegistryService } from '../../substrate/runtime/strategy-registry/service.ts';\nimport {\n\textractExecuteDigest,\n\ttype ExecutedFailure,\n\ttype TransactionSignerScope,\n\ttype ForkAdminSurface,\n\ttype SuiSdkShim,\n} from '../sui/index.ts';\nimport {\n\tLeaseBrokerService,\n\ttype LeaseBroker,\n} from '../../substrate/runtime/lease-broker/index.ts';\nimport { FUNDING_BALANCE_READ_TIMEOUT_MS } from '../../substrate/runtime/retry-policy.ts';\nimport { withAddressLease } from './lease.ts';\n\n// -----------------------------------------------------------------------------\n// User-facing options shape\n// -----------------------------------------------------------------------------\n\n/** The bring-your-own signer shape the `signer` variant binds. Any\n * `@mysten/sui/cryptography` `Signer` satisfies it — including every\n * `Keypair` (`Ed25519Keypair`, `Secp256k1Keypair`, `Secp256r1Keypair`),\n * hardware wallets, and custom KMS adapters. The structural shape is\n * pinned here rather than importing the SDK's `Signer` so the substrate\n * import surface stays SDK-free; a real `Signer` is assignable to it. */\nexport interface AccountSignerInput {\n\treadonly toSuiAddress: () => string;\n\treadonly getKeyScheme: () => string;\n\treadonly getPublicKey: () => { readonly toRawBytes: () => Uint8Array };\n\treadonly signTransaction: (\n\t\ttx: Uint8Array,\n\t) => Promise<{ readonly bytes: string; readonly signature: string }>;\n\treadonly signPersonalMessage: (\n\t\tmsg: Uint8Array,\n\t) => Promise<{ readonly bytes: string; readonly signature: string }>;\n}\n\n/** Account variant discriminated union. The user-facing factory\n * takes one of these shapes (or omits `opts` entirely for the\n * default ephemeral form).\n *\n * Three variants:\n *\n * - `ephemeral` — generate-or-recover an Ed25519 keypair under the\n * stack runtime root, funded by default. This is the bare-form\n * default (`account('alice')`).\n * - `signer` — the single bring-your-own door. Pass any\n * `@mysten/sui/cryptography` `Signer` (hardware wallet, KMS\n * adapter, dApp signer) or any `Keypair`. Loading a secret from an\n * env var or an inline `suiprivkey1...` literal is expressed by\n * building the `Keypair` yourself, e.g.\n * `{ kind: 'signer', signer: Ed25519Keypair.fromSecretKey(process.env.X) }`.\n * - `impersonate` — fork-mode only: execute AS a seeded address with\n * no secret material (sign-and-execute routes through the fork's\n * impersonation submit path). */\nexport type AccountOptions<Funding extends AccountFunding = AccountFunding> =\n\t| {\n\t\t\treadonly kind: 'ephemeral';\n\t\t\treadonly funding?: Funding;\n\t }\n\t| {\n\t\t\treadonly kind: 'signer';\n\t\t\treadonly signer: AccountSignerInput;\n\t\t\treadonly addressOverride?: string;\n\t\t\treadonly funding?: Funding;\n\t }\n\t| {\n\t\t\treadonly kind: 'impersonate';\n\t\t\treadonly address: string;\n\t\t\treadonly funding?: Funding;\n\t };\n\nexport type ResolvedAccountOptions<Funding extends AccountFunding = AccountFunding> =\n\tAccountOptions<Funding> & { readonly name: string };\n\n// -----------------------------------------------------------------------------\n// Resolved value (the Tag's resolved-shape)\n// -----------------------------------------------------------------------------\n\n/** Per-account resolved value — the typed handle the Account tag\n * publishes.\n *\n * Architecture-distilled finding (12-account.md \"Tighten the\n * resolved-account type\"): the `source` discriminator is mandatory\n * so consumers can branch on impersonation. Impersonation accounts\n * carry a zero-buffer publicKey — the discriminator is the\n * trustworthy signal. */\nexport interface AccountValue {\n\treadonly name: string;\n\treadonly address: string;\n\treadonly scheme: 'ed25519' | 'secp256k1' | 'secp256r1';\n\treadonly publicKey: Uint8Array;\n\t/** Source discriminator — `'real'` for ephemeral / signer;\n\t * `'impersonate'` for the fork-only variant. */\n\treadonly source: 'real' | 'impersonate';\n\t/** Sign + execute (the canonical execution surface — per-address\n\t * serialized, post-submit transaction-wait included, bounded\n\t * retry on the \"dependent package not found on-chain\" race).\n\t *\n\t * For impersonation accounts, routes through Sui's fork\n\t * admin `impersonate` surface; for real signers, routes\n\t * through the SDK's executeTransaction surface. */\n\treadonly signAndExecute: (\n\t\ttx: Uint8Array,\n\t) => Effect.Effect<SignAndExecuteResult, AccountSignError>;\n\t/** Run a full account-bound transaction critical section.\n\t * Callers that must serialize `Transaction.build({ client })`\n\t * together with signing/execution use the signer passed to this\n\t * callback; the callback runs while the per-address lease is held. */\n\treadonly withTransactionSigner: <A, E, R>(\n\t\tbody: (signer: AccountTransactionSigner) => Effect.Effect<A, E, R>,\n\t) => Effect.Effect<A, E, R>;\n\t/** Sign-only — real signers honor this; impersonation accounts\n\t * throw synchronously (see `variants/impersonate.ts`). */\n\treadonly signTransaction: (\n\t\ttx: Uint8Array,\n\t) => Effect.Effect<{ readonly bytes: string; readonly signature: string }, AccountSignError>;\n\treadonly signPersonalMessage: (\n\t\tmsg: Uint8Array,\n\t) => Effect.Effect<{ readonly bytes: string; readonly signature: string }, AccountSignError>;\n\treadonly funding: AccountFundingResult;\n}\n\n/** Submit result projection — kept narrow so downstream consumers\n * don't depend on the full @mysten/sui execute envelope. Populated\n * only when the on-chain execution succeeded (the `'Transaction'`\n * variant of `SignAndExecuteResult`). */\nexport interface TxResult {\n\treadonly digest: string;\n\treadonly effects: unknown;\n\treadonly objectChanges: ReadonlyArray<unknown>;\n\treadonly balanceChanges: ReadonlyArray<unknown>;\n}\n\n/** Outcome of `signAndExecute`. Mirrors the SDK's discriminated\n * `SuiClientTypes.TransactionResult` shape — on-chain failures are\n * a RETURN VALUE (callers dispatch on `$kind`), NOT an error. Only\n * transport / lifecycle failures (sign refused, RPC unreachable,\n * finality wait broke) surface through `AccountSignError`.\n *\n * The on-chain `FailedTransaction` projection is the substrate\n * `ExecutedFailure` shape — single source of truth lives in\n * `plugins/sui/exec/index.ts`. An envelope without a\n * digest fails at projection with `AccountSignError(phase: 'no-digest')`. */\nexport type SignAndExecuteResult =\n\t| { readonly $kind: 'Transaction'; readonly Transaction: TxResult }\n\t| { readonly $kind: 'FailedTransaction'; readonly FailedTransaction: ExecutedFailure };\n\nexport interface AccountTransactionSigner extends TransactionSignerScope<AccountSignError> {\n\treadonly signAndExecute: AccountValue['signAndExecute'];\n}\n\n// -----------------------------------------------------------------------------\n// Name validation\n// -----------------------------------------------------------------------------\n\n/** Architecture-distilled invariant: name flows into the resource id, an\n * on-disk path, a manifest key, container labels, and generated\n * TypeScript exports. Keep the public name identifier-safe instead\n * of accepting path-safe spellings that codegen later rejects. */\nconst ACCOUNT_NAME_RE = /^[A-Za-z][A-Za-z0-9_]{0,63}$/;\nconst ACCOUNT_NAME_HINT =\n\t'letters, digits, and underscores; must start with a letter; max 64 chars; cannot be a TypeScript reserved word';\nconst TS_RESERVED_BINDING_NAMES = new Set([\n\t'as',\n\t'async',\n\t'await',\n\t'break',\n\t'case',\n\t'catch',\n\t'class',\n\t'const',\n\t'continue',\n\t'debugger',\n\t'default',\n\t'delete',\n\t'do',\n\t'else',\n\t'enum',\n\t'export',\n\t'extends',\n\t'false',\n\t'finally',\n\t'for',\n\t'from',\n\t'function',\n\t'if',\n\t'import',\n\t'in',\n\t'instanceof',\n\t'let',\n\t'new',\n\t'null',\n\t'of',\n\t'return',\n\t'super',\n\t'switch',\n\t'this',\n\t'throw',\n\t'true',\n\t'try',\n\t'typeof',\n\t'var',\n\t'void',\n\t'while',\n\t'with',\n\t'yield',\n]);\n\nconst accountNameInvalidReason = (name: string): string | null => {\n\tif (!ACCOUNT_NAME_RE.test(name)) {\n\t\treturn `must match ${ACCOUNT_NAME_RE.source}`;\n\t}\n\tif (TS_RESERVED_BINDING_NAMES.has(name)) {\n\t\treturn 'cannot be a TypeScript reserved word';\n\t}\n\treturn null;\n};\n\nexport const assertAccountName = (name: string): void => {\n\tconst reason = accountNameInvalidReason(name);\n\tif (reason !== null) {\n\t\tthrow new TypeError(`Account name '${name}' is invalid — ${reason}. ${ACCOUNT_NAME_HINT}`);\n\t}\n};\n\nexport const validateAccountName = (name: string): Effect.Effect<void, AccountAcquireError> => {\n\tconst reason = accountNameInvalidReason(name);\n\tif (reason !== null) {\n\t\treturn Effect.fail(\n\t\t\taccountAcquireError({\n\t\t\t\tphase: 'validate-name',\n\t\t\t\taccountName: name,\n\t\t\t\tvariant: 'ephemeral',\n\t\t\t\tmessage: `Account name '${name}' is invalid — ${reason}.`,\n\t\t\t\thint: ACCOUNT_NAME_HINT,\n\t\t\t}),\n\t\t);\n\t}\n\treturn Effect.void;\n};\n\n// -----------------------------------------------------------------------------\n// Variant dispatch\n// -----------------------------------------------------------------------------\n\n/** Sui mode + sdk shim — the slice of the resolved `SuiClient` the\n * account service actually consumes. Kept narrow so the variants +\n * funding helpers stay typed at the resolved-fields level (mode,\n * chainId, sdk) rather than at the wide `SuiClient` shape. */\nexport interface AccountSuiShim {\n\treadonly mode: 'local' | 'local-rpc' | 'live' | 'fork';\n\treadonly chainId: string;\n\t/** SDK shim — exposes `executeTransaction` + `waitForTransaction`\n\t * for the signAndExecute pipeline. */\n\treadonly sdk: SuiSdkShim;\n\treadonly fork?: ForkAdminSurface | null;\n}\n\n/** Per-acquire context — supplied by the barrel from resolved plugin\n * dependencies and per-stack identity.\n *\n * `projectedFunding` carries the funding entries already resolved\n * from each `opts.funding[i].coin` dependency and projected to\n * `{fullCoinType, amount}` BEFORE handing off to `acquireAccount`.\n * The acquire body never sees the raw member refs — keeps the\n * cross-cutting funding dispatch substrate-name-blind. */\nexport interface AccountAcquireContext {\n\treadonly sui: AccountSuiShim;\n\treadonly runtimeRoot: string;\n\treadonly app: string;\n\treadonly stack: string;\n\treadonly emitAutoPromotionEvent: () => Effect.Effect<void>;\n\t/** Projected cross-cutting funding entries. Empty when `opts.funding`\n\t * is absent. The barrel stamps each resolved coin dependency's\n\t * `fullCoinType` here. */\n\treadonly projectedFunding?: ProjectedFunding;\n}\n\n/** Sum an owner's coin balances for `coinType` via `listCoins`. Used in\n * fork mode, where `getBalance` / `listBalances` panic under the fork\n * guard — `listCoins` is the only balance-bearing read fork mode allows. */\nconst sumBalanceViaListCoins = async (\n\tsdk: SuiSdkShim,\n\towner: string,\n\tcoinType: string | undefined,\n): Promise<bigint> => {\n\tlet total = 0n;\n\tlet cursor: string | null = null;\n\tdo {\n\t\tconst page = await sdk.core.listCoins({\n\t\t\towner,\n\t\t\tcoinType: coinType ?? '0x2::sui::SUI',\n\t\t\tcursor,\n\t\t\tlimit: 200,\n\t\t});\n\t\tfor (const coin of page.objects) {\n\t\t\ttotal += BigInt(coin.balance);\n\t\t}\n\t\tcursor = page.hasNextPage ? page.cursor : null;\n\t} while (cursor !== null);\n\treturn total;\n};\n\nconst makeFundingBalanceReader = (sdk: SuiSdkShim, forkMode: boolean): FundingBalanceReader => ({\n\treadBalance: ({ owner, coinType }) =>\n\t\tEffect.promise(async () => {\n\t\t\ttry {\n\t\t\t\t// Fork mode forbids getBalance/listBalances (they panic under the\n\t\t\t\t// fork guard); sum coins via the fork-safe listCoins instead.\n\t\t\t\treturn forkMode\n\t\t\t\t\t? await sumBalanceViaListCoins(sdk, owner, coinType)\n\t\t\t\t\t: balanceAmountFromSdkResponse(await sdk.core.getBalance({ owner, coinType }));\n\t\t\t} catch {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}).pipe(\n\t\t\tEffect.timeoutOrElse({\n\t\t\t\tduration: `${FUNDING_BALANCE_READ_TIMEOUT_MS} millis`,\n\t\t\t\torElse: () => Effect.succeed(null),\n\t\t\t}),\n\t\t),\n});\n\nconst balanceAmountFromSdkResponse = (response: unknown): bigint | null => {\n\tconst outer =\n\t\ttypeof response === 'object' && response !== null && 'balance' in response\n\t\t\t? (response as { readonly balance?: unknown }).balance\n\t\t\t: response;\n\tconst value =\n\t\ttypeof outer === 'object' && outer !== null && 'balance' in outer\n\t\t\t? (outer as { readonly balance?: unknown }).balance\n\t\t\t: outer;\n\tif (typeof value === 'bigint') return value;\n\tif (typeof value === 'number' && Number.isSafeInteger(value) && value >= 0) return BigInt(value);\n\tif (typeof value === 'string' && /^\\d+$/.test(value)) return BigInt(value);\n\treturn null;\n};\n\n/** Dispatch on the variant discriminator. */\nconst resolveVariant = (\n\topts: ResolvedAccountOptions,\n\tctx: AccountAcquireContext,\n): Effect.Effect<ResolvedKeypair, AccountAcquireError> => {\n\tswitch (opts.kind) {\n\t\tcase 'ephemeral':\n\t\t\treturn resolveEphemeralVariant({\n\t\t\t\tname: opts.name,\n\t\t\t\t// Architecture-distilled (12-account.md \"Cross-component\n\t\t\t\t// references\"): persisted key lives under the stack's\n\t\t\t\t// runtime tree. Path shape mirrors the on-disk convention.\n\t\t\t\tsecretFilePath: `${ctx.runtimeRoot}/account/${opts.name}.key`,\n\t\t\t});\n\t\tcase 'signer':\n\t\t\treturn resolveSignerVariant({\n\t\t\t\tname: opts.name,\n\t\t\t\tsigner: opts.signer,\n\t\t\t\t...(opts.addressOverride !== undefined ? { addressOverride: opts.addressOverride } : {}),\n\t\t\t});\n\t\tcase 'impersonate':\n\t\t\treturn resolveImpersonateVariant({\n\t\t\t\tname: opts.name,\n\t\t\t\taddress: opts.address,\n\t\t\t\tsuiMode: ctx.sui.mode,\n\t\t\t});\n\t}\n};\n\n// -----------------------------------------------------------------------------\n// Sign + execute closures\n// -----------------------------------------------------------------------------\n\n/** Promote a Promise-returning sign call into the typed-error\n * channel. The `signer.signTransaction` / `signPersonalMessage`\n * helpers on `@mysten/sui` `Signer` instances are async; the\n * bring-your-own-signer variant uses the same shape. */\nconst signWith = (\n\tsigner: {\n\t\treadonly signTransaction: (\n\t\t\ttx: Uint8Array,\n\t\t) => Promise<{ readonly bytes: string; readonly signature: string }>;\n\t},\n\ttx: Uint8Array,\n\taccountName: string,\n\taddress: string,\n): Effect.Effect<{ readonly bytes: string; readonly signature: string }, AccountSignError> =>\n\tEffect.tryPromise({\n\t\ttry: () => signer.signTransaction(tx),\n\t\tcatch: (cause): AccountSignError =>\n\t\t\taccountSignError({\n\t\t\t\tphase: 'sign',\n\t\t\t\taccountName,\n\t\t\t\taddress,\n\t\t\t\tmessage: `Account '${accountName}': signer.signTransaction() rejected.`,\n\t\t\t\tcause,\n\t\t\t}),\n\t});\n\nconst signPersonalWith = (\n\tsigner: {\n\t\treadonly signPersonalMessage: (\n\t\t\tmsg: Uint8Array,\n\t\t) => Promise<{ readonly bytes: string; readonly signature: string }>;\n\t},\n\tmsg: Uint8Array,\n\taccountName: string,\n\taddress: string,\n): Effect.Effect<{ readonly bytes: string; readonly signature: string }, AccountSignError> =>\n\tEffect.tryPromise({\n\t\ttry: () => signer.signPersonalMessage(msg),\n\t\tcatch: (cause): AccountSignError =>\n\t\t\taccountSignError({\n\t\t\t\tphase: 'sign',\n\t\t\t\taccountName,\n\t\t\t\taddress,\n\t\t\t\tmessage: `Account '${accountName}': signer.signPersonalMessage() rejected.`,\n\t\t\t\tcause,\n\t\t\t}),\n\t});\n\n/** Project the raw `@mysten/sui` executeTransaction response into\n * the narrowed `TxResult` shape consumers depend on. The SDK\n * response carries a discriminated union; the result we surface\n * always carries a digest plus the include-projected sub-fields. */\nconst projectTxResult = (\n\traw: unknown,\n\taccountName: string,\n\taddress: string,\n): Effect.Effect<SignAndExecuteResult, AccountSignError> =>\n\tEffect.gen(function* () {\n\t\t// The SDK's `SuiClientTypes.TransactionResult` is a discriminated\n\t\t// union — `{$kind: 'Transaction', Transaction: {...}}` or\n\t\t// `{$kind: 'FailedTransaction', FailedTransaction: {...}}` —\n\t\t// where each variant carries a non-optional `digest`. Mirror the\n\t\t// shape on-channel so callers dispatch on `$kind`; on-chain\n\t\t// failures are a RETURN VALUE, not an error.\n\t\tconst r = raw as {\n\t\t\t$kind?: 'Transaction' | 'FailedTransaction';\n\t\t\tTransaction?: {\n\t\t\t\tdigest?: string;\n\t\t\t\teffects?: unknown;\n\t\t\t\tobjectTypes?: Readonly<Record<string, string>>;\n\t\t\t\tbalanceChanges?: ReadonlyArray<unknown>;\n\t\t\t};\n\t\t\tFailedTransaction?: {\n\t\t\t\tdigest?: string;\n\t\t\t\tstatus?: { readonly error?: string | { readonly message?: string } };\n\t\t\t};\n\t\t};\n\t\tif (r.$kind === 'FailedTransaction') {\n\t\t\tconst failed = r.FailedTransaction ?? {};\n\t\t\tif (failed.digest === undefined) {\n\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\taccountSignError({\n\t\t\t\t\t\tphase: 'no-digest',\n\t\t\t\t\t\taccountName,\n\t\t\t\t\t\taddress,\n\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t`Account '${accountName}': executeTransaction returned a FailedTransaction ` +\n\t\t\t\t\t\t\t`without a digest — protocol violation, got ` +\n\t\t\t\t\t\t\t`${JSON.stringify(r).slice(0, 200)}`,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst errorRaw = failed.status?.error;\n\t\t\tconst executionError =\n\t\t\t\ttypeof errorRaw === 'string'\n\t\t\t\t\t? errorRaw\n\t\t\t\t\t: typeof errorRaw === 'object' &&\n\t\t\t\t\t\t errorRaw !== null &&\n\t\t\t\t\t\t 'message' in errorRaw &&\n\t\t\t\t\t\t typeof errorRaw.message === 'string'\n\t\t\t\t\t\t? errorRaw.message\n\t\t\t\t\t\t: undefined;\n\t\t\treturn {\n\t\t\t\t$kind: 'FailedTransaction',\n\t\t\t\tFailedTransaction: {\n\t\t\t\t\tdigest: failed.digest,\n\t\t\t\t\t...(executionError !== undefined ? { executionError } : {}),\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tconst tx = r.Transaction;\n\t\tif (tx?.digest === undefined) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\taccountSignError({\n\t\t\t\t\tphase: 'no-digest',\n\t\t\t\t\taccountName,\n\t\t\t\t\taddress,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t`Account '${accountName}': executeTransaction returned a malformed envelope — ` +\n\t\t\t\t\t\t`expected $kind:'Transaction'|'FailedTransaction' with a digest, got ` +\n\t\t\t\t\t\t`${JSON.stringify(r).slice(0, 200)}`,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\treturn {\n\t\t\t$kind: 'Transaction',\n\t\t\tTransaction: {\n\t\t\t\tdigest: tx.digest,\n\t\t\t\teffects: tx.effects ?? null,\n\t\t\t\tobjectChanges: projectObjectChanges(tx.effects, tx.objectTypes ?? {}),\n\t\t\t\tbalanceChanges: tx.balanceChanges ?? [],\n\t\t\t},\n\t\t};\n\t});\n\nconst projectObjectChanges = (\n\teffects: unknown,\n\tobjectTypes: Readonly<Record<string, string>>,\n): ReadonlyArray<unknown> => {\n\tconst changedObjects =\n\t\ttypeof effects === 'object' && effects !== null && 'changedObjects' in effects\n\t\t\t? (\n\t\t\t\t\teffects as {\n\t\t\t\t\t\treadonly changedObjects?: ReadonlyArray<{\n\t\t\t\t\t\t\treadonly objectId?: string;\n\t\t\t\t\t\t\treadonly outputState?: string;\n\t\t\t\t\t\t\treadonly idOperation?: string;\n\t\t\t\t\t\t}>;\n\t\t\t\t\t}\n\t\t\t\t).changedObjects\n\t\t\t: undefined;\n\tif (changedObjects === undefined) return [];\n\treturn changedObjects\n\t\t.filter(\n\t\t\t(\n\t\t\t\tchange,\n\t\t\t): change is {\n\t\t\t\treadonly objectId: string;\n\t\t\t\treadonly outputState?: string;\n\t\t\t\treadonly idOperation?: string;\n\t\t\t} => typeof change.objectId === 'string',\n\t\t)\n\t\t.map((change) => {\n\t\t\tconst objectType = objectTypes[change.objectId];\n\t\t\tconst entry: {\n\t\t\t\ttype: 'published' | 'created' | 'mutated';\n\t\t\t\tobjectId: string;\n\t\t\t\tobjectType?: string;\n\t\t\t\toutputState?: string;\n\t\t\t\tidOperation?: string;\n\t\t\t} = {\n\t\t\t\ttype:\n\t\t\t\t\tchange.outputState === 'PackageWrite'\n\t\t\t\t\t\t? 'published'\n\t\t\t\t\t\t: change.idOperation === 'Created'\n\t\t\t\t\t\t\t? 'created'\n\t\t\t\t\t\t\t: 'mutated',\n\t\t\t\tobjectId: change.objectId,\n\t\t\t};\n\t\t\tif (objectType !== undefined) entry.objectType = objectType;\n\t\t\tif (change.outputState !== undefined) entry.outputState = change.outputState;\n\t\t\tif (change.idOperation !== undefined) entry.idOperation = change.idOperation;\n\t\t\treturn entry;\n\t\t});\n};\n\ninterface BuildClosuresArgs {\n\treadonly accountName: string;\n\treadonly resolved: ResolvedKeypair;\n\treadonly sui: AccountSuiShim;\n\treadonly broker: LeaseBroker;\n\treadonly source: 'real' | 'impersonate';\n}\n\nconst buildClosures = (\n\targs: BuildClosuresArgs,\n): Pick<\n\tAccountValue,\n\t'signAndExecute' | 'withTransactionSigner' | 'signTransaction' | 'signPersonalMessage'\n> => {\n\tconst { accountName, resolved, sui, broker, source } = args;\n\n\t// Impersonation accounts MUST NOT sign — the synthetic signer's\n\t// signTransaction throws synchronously (architecture invariant).\n\t// signAndExecute routes through sui-fork's empty-signature\n\t// execution path while still holding the per-address lease.\n\tif (source === 'impersonate') {\n\t\tconst refuse = <A>(): Effect.Effect<A, AccountSignError> =>\n\t\t\tEffect.fail(\n\t\t\t\taccountSignError({\n\t\t\t\t\tphase: 'impersonation-bypass-attempt',\n\t\t\t\t\taccountName,\n\t\t\t\t\taddress: resolved.address,\n\t\t\t\t\tmessage: `Account '${accountName}' is an impersonation account — sign/execute must route through Sui's fork admin surface.`,\n\t\t\t\t}),\n\t\t\t);\n\t\tconst unlockedSignAndExecute: AccountTransactionSigner['signAndExecute'] = (tx) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst fork = sui.fork ?? null;\n\t\t\t\tif (fork === null) {\n\t\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\t\taccountSignError({\n\t\t\t\t\t\t\tphase: 'submit',\n\t\t\t\t\t\t\taccountName,\n\t\t\t\t\t\t\taddress: resolved.address,\n\t\t\t\t\t\t\tmessage: `Account '${accountName}': impersonation requires a fork-mode Sui client.`,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst submitted = yield* fork.impersonate(resolved.address, tx).pipe(\n\t\t\t\t\tEffect.mapError(\n\t\t\t\t\t\t(cause): AccountSignError =>\n\t\t\t\t\t\t\taccountSignError({\n\t\t\t\t\t\t\t\tphase: 'submit',\n\t\t\t\t\t\t\t\taccountName,\n\t\t\t\t\t\t\t\taddress: resolved.address,\n\t\t\t\t\t\t\t\tmessage: `Account '${accountName}': fork impersonation submit failed.`,\n\t\t\t\t\t\t\t\tcause,\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.tryPromise({\n\t\t\t\t\ttry: () =>\n\t\t\t\t\t\tsui.sdk.core.waitForTransaction({\n\t\t\t\t\t\t\tdigest: submitted.digest,\n\t\t\t\t\t\t}),\n\t\t\t\t\tcatch: (cause): AccountSignError =>\n\t\t\t\t\t\taccountSignError({\n\t\t\t\t\t\t\tphase: 'await-finality',\n\t\t\t\t\t\t\taccountName,\n\t\t\t\t\t\t\taddress: resolved.address,\n\t\t\t\t\t\t\tmessage: `Account '${accountName}': waitForTransaction(${submitted.digest}) failed.`,\n\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t\treturn yield* projectTxResult(submitted.raw, accountName, resolved.address);\n\t\t\t});\n\t\tconst transactionSigner: AccountTransactionSigner = {\n\t\t\tsignTransaction: refuse<{ readonly bytes: string; readonly signature: string }>,\n\t\t\tsignAndExecute: unlockedSignAndExecute,\n\t\t};\n\t\tconst withTransactionSigner: AccountValue['withTransactionSigner'] = (body) =>\n\t\t\twithAddressLease(\n\t\t\t\tbroker,\n\t\t\t\taccountName,\n\t\t\t\tresolved.address,\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\treturn yield* body(transactionSigner);\n\t\t\t\t}),\n\t\t\t);\n\t\treturn {\n\t\t\tsignAndExecute: (tx) => withTransactionSigner((locked) => locked.signAndExecute(tx)),\n\t\t\twithTransactionSigner,\n\t\t\tsignTransaction: refuse<{ readonly bytes: string; readonly signature: string }>,\n\t\t\tsignPersonalMessage: refuse<{ readonly bytes: string; readonly signature: string }>,\n\t\t};\n\t}\n\n\t// Both real-keypair and bring-your-own-signer paths satisfy the\n\t// minimal `signTransaction` / `signPersonalMessage` shape (the\n\t// SDK's `Signer` and the BYO `signer` declaration agree on it).\n\tconst signer = resolved.signer as Pick<Signer, 'signTransaction' | 'signPersonalMessage'>;\n\n\tconst unlockedSignTransaction: AccountTransactionSigner['signTransaction'] = (tx) =>\n\t\tsignWith(signer, tx, accountName, resolved.address);\n\n\tconst unlockedSignAndExecute: AccountTransactionSigner['signAndExecute'] = (tx) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst signed: SignatureWithBytes = yield* unlockedSignTransaction(tx);\n\t\t\tconst raw = yield* Effect.tryPromise({\n\t\t\t\ttry: () =>\n\t\t\t\t\tsui.sdk.core.executeTransaction({\n\t\t\t\t\t\ttransaction: tx,\n\t\t\t\t\t\tsignatures: [signed.signature],\n\t\t\t\t\t\tinclude: { effects: true, objectTypes: true },\n\t\t\t\t\t}),\n\t\t\t\tcatch: (cause): AccountSignError =>\n\t\t\t\t\taccountSignError({\n\t\t\t\t\t\tphase: 'submit',\n\t\t\t\t\t\taccountName,\n\t\t\t\t\t\taddress: resolved.address,\n\t\t\t\t\t\tmessage: `Account '${accountName}': executeTransaction transport failed.`,\n\t\t\t\t\t\tcause,\n\t\t\t\t\t}),\n\t\t\t});\n\t\t\tconst digest = extractExecuteDigest(raw);\n\t\t\tif (digest !== undefined) {\n\t\t\t\tyield* Effect.tryPromise({\n\t\t\t\t\ttry: () =>\n\t\t\t\t\t\tsui.sdk.core.waitForTransaction({\n\t\t\t\t\t\t\tdigest,\n\t\t\t\t\t\t}),\n\t\t\t\t\tcatch: (cause): AccountSignError =>\n\t\t\t\t\t\taccountSignError({\n\t\t\t\t\t\t\tphase: 'await-finality',\n\t\t\t\t\t\t\taccountName,\n\t\t\t\t\t\t\taddress: resolved.address,\n\t\t\t\t\t\t\tmessage: `Account '${accountName}': waitForTransaction(${digest}) failed.`,\n\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn yield* projectTxResult(raw, accountName, resolved.address);\n\t\t});\n\n\tconst transactionSigner: AccountTransactionSigner = {\n\t\tsignTransaction: unlockedSignTransaction,\n\t\tsignAndExecute: unlockedSignAndExecute,\n\t};\n\n\tconst withTransactionSigner: AccountValue['withTransactionSigner'] = (body) =>\n\t\twithAddressLease(\n\t\t\tbroker,\n\t\t\taccountName,\n\t\t\tresolved.address,\n\t\t\tEffect.gen(function* () {\n\t\t\t\treturn yield* body(transactionSigner);\n\t\t\t}),\n\t\t);\n\n\tconst signTransaction: AccountValue['signTransaction'] = (tx) =>\n\t\twithTransactionSigner((locked) => locked.signTransaction(tx));\n\n\tconst signPersonalMessage: AccountValue['signPersonalMessage'] = (msg) =>\n\t\twithAddressLease(\n\t\t\tbroker,\n\t\t\taccountName,\n\t\t\tresolved.address,\n\t\t\tsignPersonalWith(signer, msg, accountName, resolved.address),\n\t\t);\n\n\tconst signAndExecute: AccountValue['signAndExecute'] = (tx) =>\n\t\twithTransactionSigner((locked) => locked.signAndExecute(tx));\n\n\treturn { signAndExecute, withTransactionSigner, signTransaction, signPersonalMessage };\n};\n\n// -----------------------------------------------------------------------------\n// Acquire orchestration\n// -----------------------------------------------------------------------------\n\n/** Acquire an account. Coordinates variant dispatch + funding +\n * the resolved-value projection. */\nexport const acquireAccount = (\n\topts: ResolvedAccountOptions,\n\tctx: AccountAcquireContext,\n): Effect.Effect<AccountValue, AccountAcquireError, StrategyRegistryService | LeaseBrokerService> =>\n\tEffect.gen(function* () {\n\t\tyield* validateAccountName(opts.name);\n\n\t\t// --- variant dispatch ----------------------------------------\n\t\tconst resolved = yield* resolveVariant(opts, ctx);\n\n\t\t// --- lease broker handle (captured once; both funding and the\n\t\t// resolved-value closures share this handle so concurrent\n\t\t// callers serialize through the substrate broker's per-key\n\t\t// FIFO queue) -------------------------------------------\n\t\tconst broker = yield* LeaseBrokerService;\n\t\tconst balanceReader = makeFundingBalanceReader(ctx.sui.sdk, ctx.sui.mode === 'fork');\n\n\t\tconst defaultFunding: ProjectedFundingEntry | null =\n\t\t\topts.kind === 'ephemeral' && opts.funding === undefined\n\t\t\t\t? {\n\t\t\t\t\t\tcoin: 'SUI',\n\t\t\t\t\t\tfullCoinType: SUI_FULL_COIN_TYPE,\n\t\t\t\t\t\tamount: DEFAULT_EPHEMERAL_FUND_MIST,\n\t\t\t\t\t}\n\t\t\t\t: null;\n\t\tconst requestedFunding =\n\t\t\tdefaultFunding === null\n\t\t\t\t? (ctx.projectedFunding ?? [])\n\t\t\t\t: [defaultFunding, ...(ctx.projectedFunding ?? [])];\n\t\tconst appliedDefaultFunding: AppliedFundingEntry[] = [];\n\n\t\t// --- default funding (bare ephemeral only) -------------------\n\t\tif (defaultFunding !== null) {\n\t\t\t// Outcome distinguishes a real faucet call (`'funded'`) from\n\t\t\t// the pre-existing-balance short-circuit (`'already-satisfied'`),\n\t\t\t// so the registry projection doesn't mislabel a no-faucet-call\n\t\t\t// entry as funded. `'skipped'` (zero amount) drops out entirely\n\t\t\t// per the same invariant as the cross-cutting pass.\n\t\t\tconst outcome = yield* fundEphemeralDefault({\n\t\t\t\taccountName: opts.name,\n\t\t\t\taddress: resolved.address,\n\t\t\t\tamountMist: defaultFunding.amount,\n\t\t\t\tsuiMode: ctx.sui.mode,\n\t\t\t\tchainId: ctx.sui.chainId,\n\t\t\t\temitAutoPromotionEvent: ctx.emitAutoPromotionEvent,\n\t\t\t\tbroker,\n\t\t\t\tbalanceReader,\n\t\t\t});\n\t\t\tif (outcome !== 'skipped') {\n\t\t\t\tappliedDefaultFunding.push({ ...defaultFunding, outcome });\n\t\t\t}\n\t\t}\n\n\t\tconst source: AccountValue['source'] = opts.kind === 'impersonate' ? 'impersonate' : 'real';\n\t\tconst closures = buildClosures({\n\t\t\taccountName: opts.name,\n\t\t\tresolved,\n\t\t\tsui: ctx.sui,\n\t\t\tbroker,\n\t\t\tsource,\n\t\t});\n\n\t\t// --- project the resolved value ------------------------------\n\t\tconst value: AccountValue = {\n\t\t\tname: opts.name,\n\t\t\taddress: resolved.address,\n\t\t\tscheme: resolved.scheme,\n\t\t\tpublicKey: resolved.publicKey,\n\t\t\tsource,\n\t\t\tfunding: {\n\t\t\t\trequested: requestedFunding,\n\t\t\t\tapplied: appliedDefaultFunding,\n\t\t\t},\n\t\t\t...closures,\n\t\t};\n\n\t\t// --- cross-cutting funding (all variants) --------------------\n\t\t//\n\t\t// The barrel pre-projects each user-supplied `CoinMember` to\n\t\t// `{fullCoinType, amount}` from resolved dependencies so this\n\t\t// dispatch stays substrate-name-blind. The resolved account\n\t\t// handle is passed so strategy providers without admin\n\t\t// capabilities can sign account-owned funding swaps. Missing /\n\t\t// empty `projectedFunding` is a no-op (matches the \"Optional\n\t\t// Faucet is a noop\" invariant).\n\t\tconst projected = ctx.projectedFunding ?? [];\n\t\tlet appliedCrossCuttingFunding: AppliedFunding = [];\n\t\tif (projected.length > 0) {\n\t\t\tappliedCrossCuttingFunding = yield* applyCrossCuttingFunding({\n\t\t\t\taccountName: opts.name,\n\t\t\t\taddress: resolved.address,\n\t\t\t\tvariant: opts.kind,\n\t\t\t\taccount: value,\n\t\t\t\tfunding: projected,\n\t\t\t\tchainId: ctx.sui.chainId,\n\t\t\t\tbroker,\n\t\t\t\tbalanceReader,\n\t\t\t});\n\t\t}\n\n\t\treturn {\n\t\t\t...value,\n\t\t\tfunding: {\n\t\t\t\trequested: requestedFunding,\n\t\t\t\tapplied: [...appliedDefaultFunding, ...appliedCrossCuttingFunding],\n\t\t\t},\n\t\t};\n\t});\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot.mjs","names":[],"sources":["../../../src/plugins/account/snapshot.ts"],"sourcesContent":["// Account plugin — Snapshotable contribution.\n//\n// Architecture §3 + 12-account.md \"Cross-component references\":\n// Account's persisted secret material lives under the runtime tree\n// at `runtime/account/<name>.key` (bech32 secret, 0o600 inside a\n// 0o700 parent). The runtime-rooted tar already captures this via\n// the substrate's auto-included subtree convention — Account just\n// declares the SECRET-MATERIAL flag so the substrate preserves the\n// permissions bits on round-trip.\n//\n// Distilled-doc invariant (\"Restrictive file permissions\"): the\n// 0o600 / 0o700 mode bits are load-bearing. The `secretMaterial:\n// true` flag drives the substrate's mode-bit preservation;\n// re-tightening on warm-start is the runtime's job (snapshot only\n// captures + restores).\n//\n// Variants that do NOT persist secret material (`keystore`, `env`,\n// `inline`, `signer`, `impersonate`) emit an EMPTY snapshot decl\n// with `missingTolerance: 'fine'` so cross-variant restores are\n// clean no-ops.\n\nimport { Effect } from 'effect';\n\nimport type { SnapshotableDecl } from '../../contracts/snapshotable.ts';\nimport type { AccountVariantKind } from './errors.ts';\n\n/** Build the Snapshotable contribution for a resolved variant.\n *\n * Only the `ephemeral` variant declares a persisted subtree, scoped\n * to a single account's key path. */\nexport const makeAccountSnapshotable = (parts: {\n\treadonly accountName: string;\n\treadonly variant: AccountVariantKind;\n\treadonly app: string;\n\treadonly stack: string;\n}): SnapshotableDecl => {\n\tif (parts.variant !== 'ephemeral') {\n\t\treturn {\n\t\t\tkind: 'snapshotable',\n\t\t\tsubtrees: [],\n\t\t\tmissingTolerance: 'fine',\n\t\t};\n\t}\n\n\treturn {\n\t\tkind: 'snapshotable',\n\t\t// Per-account secret file under the runtime tree. The\n\t\t// substrate's runtime-tar already covers `runtime/account/`\n\t\t// inclusively; this opt-in extra is symmetric with Sui's\n\t\t// `sui-fork/` subtree declaration.\n\t\tsubtrees: [`account/${parts.accountName}.key`],\n\t\tmissingTolerance: 'fine',\n\t\tsecretMaterial: true,\n\t\t// Pre-restore identity guard: assert the snapshot was taken\n\t\t// under the same `(app, stack, name)` triplet. The substrate's\n\t\t// identity walker reads this opaquely.\n\t\tpreRestore: Effect.succeed({\n\t\t\tkind: 'account-secret',\n\t\t\taccount: parts.accountName,\n\t\t\tapp: parts.app,\n\t\t\tstack: parts.stack,\n\t\t}),\n\t\tpostRestore: Effect.void,\n\t};\n};\n"],"mappings":";;;;;;AA8BA,MAAa,2BAA2B,UAKhB;AACvB,KAAI,MAAM,YAAY,YACrB,QAAO;EACN,MAAM;EACN,UAAU,EAAE;EACZ,kBAAkB;EAClB;AAGF,QAAO;EACN,MAAM;EAKN,UAAU,CAAC,WAAW,MAAM,YAAY,MAAM;EAC9C,kBAAkB;EAClB,gBAAgB;EAIhB,YAAY,OAAO,QAAQ;GAC1B,MAAM;GACN,SAAS,MAAM;GACf,KAAK,MAAM;GACX,OAAO,MAAM;GACb,CAAC;EACF,aAAa,OAAO;EACpB"}
1
+ {"version":3,"file":"snapshot.mjs","names":[],"sources":["../../../src/plugins/account/snapshot.ts"],"sourcesContent":["// Account plugin — Snapshotable contribution.\n//\n// Architecture §3 + 12-account.md \"Cross-component references\":\n// Account's persisted secret material lives under the runtime tree\n// at `runtime/account/<name>.key` (bech32 secret, 0o600 inside a\n// 0o700 parent). The runtime-rooted tar already captures this via\n// the substrate's auto-included subtree convention — Account just\n// declares the SECRET-MATERIAL flag so the substrate preserves the\n// permissions bits on round-trip.\n//\n// Distilled-doc invariant (\"Restrictive file permissions\"): the\n// 0o600 / 0o700 mode bits are load-bearing. The `secretMaterial:\n// true` flag drives the substrate's mode-bit preservation;\n// re-tightening on warm-start is the runtime's job (snapshot only\n// captures + restores).\n//\n// Variants that do NOT persist secret material (`signer`,\n// `impersonate`) emit an EMPTY snapshot decl with\n// `missingTolerance: 'fine'` so cross-variant restores are clean\n// no-ops.\n\nimport { Effect } from 'effect';\n\nimport type { SnapshotableDecl } from '../../contracts/snapshotable.ts';\nimport type { AccountVariantKind } from './errors.ts';\n\n/** Build the Snapshotable contribution for a resolved variant.\n *\n * Only the `ephemeral` variant declares a persisted subtree, scoped\n * to a single account's key path. */\nexport const makeAccountSnapshotable = (parts: {\n\treadonly accountName: string;\n\treadonly variant: AccountVariantKind;\n\treadonly app: string;\n\treadonly stack: string;\n}): SnapshotableDecl => {\n\tif (parts.variant !== 'ephemeral') {\n\t\treturn {\n\t\t\tkind: 'snapshotable',\n\t\t\tsubtrees: [],\n\t\t\tmissingTolerance: 'fine',\n\t\t};\n\t}\n\n\treturn {\n\t\tkind: 'snapshotable',\n\t\t// Per-account secret file under the runtime tree. The\n\t\t// substrate's runtime-tar already covers `runtime/account/`\n\t\t// inclusively; this opt-in extra is symmetric with Sui's\n\t\t// `sui-fork/` subtree declaration.\n\t\tsubtrees: [`account/${parts.accountName}.key`],\n\t\tmissingTolerance: 'fine',\n\t\tsecretMaterial: true,\n\t\t// Pre-restore identity guard: assert the snapshot was taken\n\t\t// under the same `(app, stack, name)` triplet. The substrate's\n\t\t// identity walker reads this opaquely.\n\t\tpreRestore: Effect.succeed({\n\t\t\tkind: 'account-secret',\n\t\t\taccount: parts.accountName,\n\t\t\tapp: parts.app,\n\t\t\tstack: parts.stack,\n\t\t}),\n\t\tpostRestore: Effect.void,\n\t};\n};\n"],"mappings":";;;;;;AA8BA,MAAa,2BAA2B,UAKhB;CACvB,IAAI,MAAM,YAAY,aACrB,OAAO;EACN,MAAM;EACN,UAAU,CAAC;EACX,kBAAkB;CACnB;CAGD,OAAO;EACN,MAAM;EAKN,UAAU,CAAC,WAAW,MAAM,YAAY,KAAK;EAC7C,kBAAkB;EAClB,gBAAgB;EAIhB,YAAY,OAAO,QAAQ;GAC1B,MAAM;GACN,SAAS,MAAM;GACf,KAAK,MAAM;GACX,OAAO,MAAM;EACd,CAAC;EACD,aAAa,OAAO;CACrB;AACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"ephemeral.mjs","names":[],"sources":["../../../../src/plugins/account/variants/ephemeral.ts"],"sourcesContent":["// Account variant — ephemeral (generate-or-recover, fund-by-default).\n//\n// Distilled-doc invariants:\n//\n// - \"Concurrent first-time keypair persistence\": EXCL-create write.\n// Two parallel generators must not both win; the loser falls\n// back to reading the winner's persisted key.\n// - \"Restrictive file permissions\": 0o600 secret + 0o700 parent.\n// - \"Bare form equals ephemeral-funded\": this resolver is what the\n// bare `account('alice')` factory call lands on.\n// - \"Auto-promotion to fork-impersonate funding\": handled in\n// `funding.ts`; this file just hands off the address. The\n// promotion event is emitted there (loud-by-default).\n//\n// Persistence note: these accounts are \"ephemeral\" relative to user-\n// managed key material, but they are stable inside a devstack runtime\n// root. Package cache keys and wallet accounts depend on that stability\n// across warm starts.\n\nimport { dirname } from 'node:path';\nimport * as nodeFs from 'node:fs/promises';\n\nimport { Effect } from 'effect';\n\nimport { decodeBech32Secret, generateEd25519Keypair, type ResolvedKeypair } from '../keypair.ts';\nimport { accountAcquireError, type AccountAcquireError } from '../errors.ts';\n\nexport interface EphemeralVariantArgs {\n\treadonly name: string;\n\t/** Filesystem path where the bech32 secret will be persisted by\n\t * the resolver and covered by the account snapshot capability. */\n\treadonly secretFilePath: string;\n}\n\ntype WriteResult = 'wrote' | 'exists';\n\nconst isErrnoCode = (cause: unknown, code: string): boolean =>\n\ttypeof cause === 'object' &&\n\tcause !== null &&\n\t'code' in cause &&\n\t(cause as { readonly code?: unknown }).code === code;\n\nconst bestEffortChmod = (path: string, mode: number): Effect.Effect<void> =>\n\tEffect.promise(() => nodeFs.chmod(path, mode)).pipe(Effect.ignore);\n\nconst readPersistedKeypair = (\n\targs: EphemeralVariantArgs,\n\tmessage: string,\n): Effect.Effect<ResolvedKeypair, AccountAcquireError> =>\n\tEffect.gen(function* () {\n\t\tconst raw = yield* Effect.tryPromise({\n\t\t\ttry: () => nodeFs.readFile(args.secretFilePath, 'utf8'),\n\t\t\tcatch: (cause): AccountAcquireError =>\n\t\t\t\taccountAcquireError({\n\t\t\t\t\tphase: 'read-persisted-keypair',\n\t\t\t\t\taccountName: args.name,\n\t\t\t\t\tvariant: 'ephemeral',\n\t\t\t\t\tmessage,\n\t\t\t\t\tcause,\n\t\t\t\t}),\n\t\t});\n\t\tyield* bestEffortChmod(args.secretFilePath, 0o600);\n\t\treturn yield* decodeBech32Secret(raw.trim(), args.name, 'ephemeral');\n\t});\n\nconst readPersistedKeypairIfPresent = (\n\targs: EphemeralVariantArgs,\n): Effect.Effect<ResolvedKeypair | null, AccountAcquireError> =>\n\treadPersistedKeypair(\n\t\targs,\n\t\t`Account '${args.name}': failed to read persisted ephemeral keypair at ${args.secretFilePath}.`,\n\t).pipe(\n\t\tEffect.catch((cause: AccountAcquireError) =>\n\t\t\tisErrnoCode(cause.cause, 'ENOENT') ? Effect.succeed(null) : Effect.fail(cause),\n\t\t),\n\t);\n\nconst persistGeneratedSecret = (\n\targs: EphemeralVariantArgs,\n\tsecret: string,\n): Effect.Effect<WriteResult, AccountAcquireError> =>\n\tEffect.tryPromise({\n\t\ttry: async () => {\n\t\t\tawait nodeFs.mkdir(dirname(args.secretFilePath), { recursive: true, mode: 0o700 });\n\t\t\tawait nodeFs.chmod(dirname(args.secretFilePath), 0o700).catch(() => {});\n\t\t\ttry {\n\t\t\t\tawait nodeFs.writeFile(args.secretFilePath, secret, { flag: 'wx', mode: 0o600 });\n\t\t\t\treturn 'wrote';\n\t\t\t} catch (cause) {\n\t\t\t\tif (isErrnoCode(cause, 'EEXIST')) return 'exists';\n\t\t\t\tthrow cause;\n\t\t\t}\n\t\t},\n\t\tcatch: (cause): AccountAcquireError =>\n\t\t\taccountAcquireError({\n\t\t\t\tphase: 'persist-keypair',\n\t\t\t\taccountName: args.name,\n\t\t\t\tvariant: 'ephemeral',\n\t\t\t\tmessage: `Account '${args.name}': failed to persist ephemeral keypair at ${args.secretFilePath}.`,\n\t\t\t\tcause,\n\t\t\t}),\n\t});\n\n/** Resolve the ephemeral variant — read or generate an Ed25519 keypair.\n *\n * First-time writes use O_EXCL so parallel acquires for the same\n * account cannot both publish different addresses; the loser re-reads\n * the winner's file and returns the persisted identity. */\nexport const resolveEphemeralVariant = (\n\targs: EphemeralVariantArgs,\n): Effect.Effect<ResolvedKeypair, AccountAcquireError> =>\n\tEffect.gen(function* () {\n\t\tconst persisted = yield* readPersistedKeypairIfPresent(args);\n\t\tif (persisted !== null) return persisted;\n\n\t\tconst generated = yield* generateEd25519Keypair(args.name);\n\t\tif (generated.bech32Secret === null) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\taccountAcquireError({\n\t\t\t\t\tphase: 'generate-keypair',\n\t\t\t\t\taccountName: args.name,\n\t\t\t\t\tvariant: 'ephemeral',\n\t\t\t\t\tmessage: `Account '${args.name}': generated keypair did not expose a bech32 secret.`,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tconst writeResult = yield* persistGeneratedSecret(args, generated.bech32Secret);\n\t\tif (writeResult === 'exists') {\n\t\t\treturn yield* readPersistedKeypair(\n\t\t\t\targs,\n\t\t\t\t`Account '${args.name}': lost ephemeral keypair write race at ${args.secretFilePath} and failed to read the winner.`,\n\t\t\t);\n\t\t}\n\n\t\tyield* bestEffortChmod(args.secretFilePath, 0o600);\n\t\treturn generated;\n\t});\n"],"mappings":";;;;;;AAoCA,MAAM,eAAe,OAAgB,SACpC,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACT,MAAsC,SAAS;AAEjD,MAAM,mBAAmB,MAAc,SACtC,OAAO,cAAc,OAAO,MAAM,MAAM,KAAK,CAAC,CAAC,KAAK,OAAO,OAAO;AAEnE,MAAM,wBACL,MACA,YAEA,OAAO,IAAI,aAAa;CACvB,MAAM,MAAM,OAAO,OAAO,WAAW;EACpC,WAAW,OAAO,SAAS,KAAK,gBAAgB,OAAO;EACvD,QAAQ,UACP,oBAAoB;GACnB,OAAO;GACP,aAAa,KAAK;GAClB,SAAS;GACT;GACA;GACA,CAAC;EACH,CAAC;AACF,QAAO,gBAAgB,KAAK,gBAAgB,IAAM;AAClD,QAAO,OAAO,mBAAmB,IAAI,MAAM,EAAE,KAAK,MAAM,YAAY;EACnE;AAEH,MAAM,iCACL,SAEA,qBACC,MACA,YAAY,KAAK,KAAK,mDAAmD,KAAK,eAAe,GAC7F,CAAC,KACD,OAAO,OAAO,UACb,YAAY,MAAM,OAAO,SAAS,GAAG,OAAO,QAAQ,KAAK,GAAG,OAAO,KAAK,MAAM,CAC9E,CACD;AAEF,MAAM,0BACL,MACA,WAEA,OAAO,WAAW;CACjB,KAAK,YAAY;AAChB,QAAM,OAAO,MAAM,QAAQ,KAAK,eAAe,EAAE;GAAE,WAAW;GAAM,MAAM;GAAO,CAAC;AAClF,QAAM,OAAO,MAAM,QAAQ,KAAK,eAAe,EAAE,IAAM,CAAC,YAAY,GAAG;AACvE,MAAI;AACH,SAAM,OAAO,UAAU,KAAK,gBAAgB,QAAQ;IAAE,MAAM;IAAM,MAAM;IAAO,CAAC;AAChF,UAAO;WACC,OAAO;AACf,OAAI,YAAY,OAAO,SAAS,CAAE,QAAO;AACzC,SAAM;;;CAGR,QAAQ,UACP,oBAAoB;EACnB,OAAO;EACP,aAAa,KAAK;EAClB,SAAS;EACT,SAAS,YAAY,KAAK,KAAK,4CAA4C,KAAK,eAAe;EAC/F;EACA,CAAC;CACH,CAAC;;;;;;AAOH,MAAa,2BACZ,SAEA,OAAO,IAAI,aAAa;CACvB,MAAM,YAAY,OAAO,8BAA8B,KAAK;AAC5D,KAAI,cAAc,KAAM,QAAO;CAE/B,MAAM,YAAY,OAAO,uBAAuB,KAAK,KAAK;AAC1D,KAAI,UAAU,iBAAiB,KAC9B,QAAO,OAAO,OAAO,KACpB,oBAAoB;EACnB,OAAO;EACP,aAAa,KAAK;EAClB,SAAS;EACT,SAAS,YAAY,KAAK,KAAK;EAC/B,CAAC,CACF;AAIF,MAAI,OADuB,uBAAuB,MAAM,UAAU,aAAa,MAC3D,SACnB,QAAO,OAAO,qBACb,MACA,YAAY,KAAK,KAAK,0CAA0C,KAAK,eAAe,iCACpF;AAGF,QAAO,gBAAgB,KAAK,gBAAgB,IAAM;AAClD,QAAO;EACN"}
1
+ {"version":3,"file":"ephemeral.mjs","names":[],"sources":["../../../../src/plugins/account/variants/ephemeral.ts"],"sourcesContent":["// Account variant — ephemeral (generate-or-recover, fund-by-default).\n//\n// Distilled-doc invariants:\n//\n// - \"Concurrent first-time keypair persistence\": EXCL-create write.\n// Two parallel generators must not both win; the loser falls\n// back to reading the winner's persisted key.\n// - \"Restrictive file permissions\": 0o600 secret + 0o700 parent.\n// - \"Bare form equals ephemeral-funded\": this resolver is what the\n// bare `account('alice')` factory call lands on.\n// - \"Auto-promotion to fork-impersonate funding\": handled in\n// `funding.ts`; this file just hands off the address. The\n// promotion event is emitted there (loud-by-default).\n//\n// Persistence note: these accounts are \"ephemeral\" relative to user-\n// managed key material, but they are stable inside a devstack runtime\n// root. Package cache keys and wallet accounts depend on that stability\n// across warm starts.\n\nimport { dirname } from 'node:path';\nimport * as nodeFs from 'node:fs/promises';\n\nimport { Effect } from 'effect';\n\nimport { decodeBech32Secret, generateEd25519Keypair, type ResolvedKeypair } from '../keypair.ts';\nimport { accountAcquireError, type AccountAcquireError } from '../errors.ts';\n\nexport interface EphemeralVariantArgs {\n\treadonly name: string;\n\t/** Filesystem path where the bech32 secret will be persisted by\n\t * the resolver and covered by the account snapshot capability. */\n\treadonly secretFilePath: string;\n}\n\ntype WriteResult = 'wrote' | 'exists';\n\nconst isErrnoCode = (cause: unknown, code: string): boolean =>\n\ttypeof cause === 'object' &&\n\tcause !== null &&\n\t'code' in cause &&\n\t(cause as { readonly code?: unknown }).code === code;\n\nconst bestEffortChmod = (path: string, mode: number): Effect.Effect<void> =>\n\tEffect.promise(() => nodeFs.chmod(path, mode)).pipe(Effect.ignore);\n\nconst readPersistedKeypair = (\n\targs: EphemeralVariantArgs,\n\tmessage: string,\n): Effect.Effect<ResolvedKeypair, AccountAcquireError> =>\n\tEffect.gen(function* () {\n\t\tconst raw = yield* Effect.tryPromise({\n\t\t\ttry: () => nodeFs.readFile(args.secretFilePath, 'utf8'),\n\t\t\tcatch: (cause): AccountAcquireError =>\n\t\t\t\taccountAcquireError({\n\t\t\t\t\tphase: 'read-persisted-keypair',\n\t\t\t\t\taccountName: args.name,\n\t\t\t\t\tvariant: 'ephemeral',\n\t\t\t\t\tmessage,\n\t\t\t\t\tcause,\n\t\t\t\t}),\n\t\t});\n\t\tyield* bestEffortChmod(args.secretFilePath, 0o600);\n\t\treturn yield* decodeBech32Secret(raw.trim(), args.name, 'ephemeral');\n\t});\n\nconst readPersistedKeypairIfPresent = (\n\targs: EphemeralVariantArgs,\n): Effect.Effect<ResolvedKeypair | null, AccountAcquireError> =>\n\treadPersistedKeypair(\n\t\targs,\n\t\t`Account '${args.name}': failed to read persisted ephemeral keypair at ${args.secretFilePath}.`,\n\t).pipe(\n\t\tEffect.catch((cause: AccountAcquireError) =>\n\t\t\tisErrnoCode(cause.cause, 'ENOENT') ? Effect.succeed(null) : Effect.fail(cause),\n\t\t),\n\t);\n\nconst persistGeneratedSecret = (\n\targs: EphemeralVariantArgs,\n\tsecret: string,\n): Effect.Effect<WriteResult, AccountAcquireError> =>\n\tEffect.tryPromise({\n\t\ttry: async () => {\n\t\t\tawait nodeFs.mkdir(dirname(args.secretFilePath), { recursive: true, mode: 0o700 });\n\t\t\tawait nodeFs.chmod(dirname(args.secretFilePath), 0o700).catch(() => {});\n\t\t\ttry {\n\t\t\t\tawait nodeFs.writeFile(args.secretFilePath, secret, { flag: 'wx', mode: 0o600 });\n\t\t\t\treturn 'wrote';\n\t\t\t} catch (cause) {\n\t\t\t\tif (isErrnoCode(cause, 'EEXIST')) return 'exists';\n\t\t\t\tthrow cause;\n\t\t\t}\n\t\t},\n\t\tcatch: (cause): AccountAcquireError =>\n\t\t\taccountAcquireError({\n\t\t\t\tphase: 'persist-keypair',\n\t\t\t\taccountName: args.name,\n\t\t\t\tvariant: 'ephemeral',\n\t\t\t\tmessage: `Account '${args.name}': failed to persist ephemeral keypair at ${args.secretFilePath}.`,\n\t\t\t\tcause,\n\t\t\t}),\n\t});\n\n/** Resolve the ephemeral variant — read or generate an Ed25519 keypair.\n *\n * First-time writes use O_EXCL so parallel acquires for the same\n * account cannot both publish different addresses; the loser re-reads\n * the winner's file and returns the persisted identity. */\nexport const resolveEphemeralVariant = (\n\targs: EphemeralVariantArgs,\n): Effect.Effect<ResolvedKeypair, AccountAcquireError> =>\n\tEffect.gen(function* () {\n\t\tconst persisted = yield* readPersistedKeypairIfPresent(args);\n\t\tif (persisted !== null) return persisted;\n\n\t\tconst generated = yield* generateEd25519Keypair(args.name);\n\t\tif (generated.bech32Secret === null) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\taccountAcquireError({\n\t\t\t\t\tphase: 'generate-keypair',\n\t\t\t\t\taccountName: args.name,\n\t\t\t\t\tvariant: 'ephemeral',\n\t\t\t\t\tmessage: `Account '${args.name}': generated keypair did not expose a bech32 secret.`,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tconst writeResult = yield* persistGeneratedSecret(args, generated.bech32Secret);\n\t\tif (writeResult === 'exists') {\n\t\t\treturn yield* readPersistedKeypair(\n\t\t\t\targs,\n\t\t\t\t`Account '${args.name}': lost ephemeral keypair write race at ${args.secretFilePath} and failed to read the winner.`,\n\t\t\t);\n\t\t}\n\n\t\tyield* bestEffortChmod(args.secretFilePath, 0o600);\n\t\treturn generated;\n\t});\n"],"mappings":";;;;;;AAoCA,MAAM,eAAe,OAAgB,SACpC,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACT,MAAsC,SAAS;AAEjD,MAAM,mBAAmB,MAAc,SACtC,OAAO,cAAc,OAAO,MAAM,MAAM,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO,MAAM;AAElE,MAAM,wBACL,MACA,YAEA,OAAO,IAAI,aAAa;CACvB,MAAM,MAAM,OAAO,OAAO,WAAW;EACpC,WAAW,OAAO,SAAS,KAAK,gBAAgB,MAAM;EACtD,QAAQ,UACP,oBAAoB;GACnB,OAAO;GACP,aAAa,KAAK;GAClB,SAAS;GACT;GACA;EACD,CAAC;CACH,CAAC;CACD,OAAO,gBAAgB,KAAK,gBAAgB,GAAK;CACjD,OAAO,OAAO,mBAAmB,IAAI,KAAK,GAAG,KAAK,MAAM,WAAW;AACpE,CAAC;AAEF,MAAM,iCACL,SAEA,qBACC,MACA,YAAY,KAAK,KAAK,mDAAmD,KAAK,eAAe,EAC9F,CAAC,CAAC,KACD,OAAO,OAAO,UACb,YAAY,MAAM,OAAO,QAAQ,IAAI,OAAO,QAAQ,IAAI,IAAI,OAAO,KAAK,KAAK,CAC9E,CACD;AAED,MAAM,0BACL,MACA,WAEA,OAAO,WAAW;CACjB,KAAK,YAAY;EAChB,MAAM,OAAO,MAAM,QAAQ,KAAK,cAAc,GAAG;GAAE,WAAW;GAAM,MAAM;EAAM,CAAC;EACjF,MAAM,OAAO,MAAM,QAAQ,KAAK,cAAc,GAAG,GAAK,CAAC,CAAC,YAAY,CAAC,CAAC;EACtE,IAAI;GACH,MAAM,OAAO,UAAU,KAAK,gBAAgB,QAAQ;IAAE,MAAM;IAAM,MAAM;GAAM,CAAC;GAC/E,OAAO;EACR,SAAS,OAAO;GACf,IAAI,YAAY,OAAO,QAAQ,GAAG,OAAO;GACzC,MAAM;EACP;CACD;CACA,QAAQ,UACP,oBAAoB;EACnB,OAAO;EACP,aAAa,KAAK;EAClB,SAAS;EACT,SAAS,YAAY,KAAK,KAAK,4CAA4C,KAAK,eAAe;EAC/F;CACD,CAAC;AACH,CAAC;;;;;;AAOF,MAAa,2BACZ,SAEA,OAAO,IAAI,aAAa;CACvB,MAAM,YAAY,OAAO,8BAA8B,IAAI;CAC3D,IAAI,cAAc,MAAM,OAAO;CAE/B,MAAM,YAAY,OAAO,uBAAuB,KAAK,IAAI;CACzD,IAAI,UAAU,iBAAiB,MAC9B,OAAO,OAAO,OAAO,KACpB,oBAAoB;EACnB,OAAO;EACP,aAAa,KAAK;EAClB,SAAS;EACT,SAAS,YAAY,KAAK,KAAK;CAChC,CAAC,CACF;CAID,KAAI,OADuB,uBAAuB,MAAM,UAAU,YAAY,OAC1D,UACnB,OAAO,OAAO,qBACb,MACA,YAAY,KAAK,KAAK,0CAA0C,KAAK,eAAe,gCACrF;CAGD,OAAO,gBAAgB,KAAK,gBAAgB,GAAK;CACjD,OAAO;AACR,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"impersonate.mjs","names":[],"sources":["../../../../src/plugins/account/variants/impersonate.ts"],"sourcesContent":["// Account variant — impersonate (fork-mode only).\n//\n// Distilled-doc invariants:\n//\n// - \"Impersonation only on fork\": the variant must refuse outside\n// fork-runtime. The refusal lands at variant-resolution time\n// (typed AccountAcquireError, phase: bind-impersonation-slot).\n//\n// - \"Sign-and-execute is the only execution surface for\n// impersonation\": synthetic impersonation signers must THROW\n// SYNCHRONOUSLY on direct sign calls so accidental bypass is\n// loud, not silent. We surface this through the\n// `SyntheticImpersonationSigner` object's `signTransaction` /\n// `signPersonalMessage` methods.\n//\n// - \"publicKey caveat\": the resolved value's `publicKey` is a\n// zero buffer. The resolved-account TYPE (in `service.ts`)\n// encodes the source discriminator so consumers can't accidentally\n// treat an impersonation publicKey as authoritative.\n//\n// Distilled-doc opportunity: \"Move the synthetic impersonation\n// signer next to the other fork-only helpers\". For now, it stays\n// here because the variant resolver is the only construction site —\n// if Wallet ever needs to materialize impersonation signers directly,\n// we lift this into `plugins/sui/fork-orchestration.ts`.\n\nimport { Effect } from 'effect';\n\nimport { accountAcquireError, accountSignError, type AccountAcquireError } from '../errors.ts';\nimport type { ResolvedKeypair } from '../keypair.ts';\n\nexport interface ImpersonateVariantArgs {\n\treadonly name: string;\n\t/** The address to execute AS. Must appear in the fork's seed\n\t * manifest's owned-object index (typically by being listed\n\t * in `Sui({fork:{seed:{addresses}}})`). */\n\treadonly address: string;\n\t/** Sui's resolved runtime mode — gates the refusal-outside-fork\n\t * check. */\n\treadonly suiMode: 'local' | 'local-rpc' | 'live' | 'fork';\n}\n\n/** The synthetic impersonation signer object. THROWS SYNCHRONOUSLY\n * on direct sign calls; routes `signAndExecute` through the fork's\n * empty-signature submit path (wired in `service.ts`). */\nexport interface SyntheticImpersonationSigner {\n\treadonly _kind: 'impersonate';\n\treadonly toSuiAddress: () => string;\n\treadonly getKeyScheme: () => 'ed25519';\n\treadonly signTransaction: () => never;\n\treadonly signPersonalMessage: () => never;\n}\n\nconst makeSyntheticSigner = (\n\taccountName: string,\n\taddress: string,\n): SyntheticImpersonationSigner => ({\n\t_kind: 'impersonate',\n\ttoSuiAddress: () => address,\n\t// Stable lie: report ed25519 so manifest serialization doesn't\n\t// have to branch. Consumers that need the truth read `source`\n\t// off the resolved-account value (architecture-distilled\n\t// invariant).\n\tgetKeyScheme: () => 'ed25519',\n\tsignTransaction: () => {\n\t\tthrow accountSignError({\n\t\t\tphase: 'impersonation-bypass-attempt',\n\t\t\taccountName,\n\t\t\taddress,\n\t\t\tmessage: `Account '${accountName}' is an impersonation account — direct sign calls are forbidden. Route through signAndExecute (which goes via the fork's impersonation submit path).`,\n\t\t});\n\t},\n\tsignPersonalMessage: () => {\n\t\tthrow accountSignError({\n\t\t\tphase: 'impersonation-bypass-attempt',\n\t\t\taccountName,\n\t\t\taddress,\n\t\t\tmessage: `Account '${accountName}' is an impersonation account — signPersonalMessage is not supported.`,\n\t\t});\n\t},\n});\n\n/** Resolve the impersonate variant.\n *\n * Distilled-doc invariant: refuse outside fork mode. The refusal\n * is a typed acquisition error pointing at the runtime requirement. */\nexport const resolveImpersonateVariant = (\n\targs: ImpersonateVariantArgs,\n): Effect.Effect<ResolvedKeypair, AccountAcquireError> => {\n\tif (args.suiMode !== 'fork') {\n\t\treturn Effect.fail(\n\t\t\taccountAcquireError({\n\t\t\t\tphase: 'bind-impersonation-slot',\n\t\t\t\taccountName: args.name,\n\t\t\t\tvariant: 'impersonate',\n\t\t\t\tmessage: `Account '${args.name}' uses {kind:'impersonate'} but Sui runtime is '${args.suiMode}'. Impersonation only works on fork-mode networks.`,\n\t\t\t\thint: `Switch to suiFor(network).fork.{mainnet|testnet|devnet}(...) — or use a different account variant.`,\n\t\t\t}),\n\t\t);\n\t}\n\treturn Effect.succeed({\n\t\taddress: args.address,\n\t\tscheme: 'ed25519',\n\t\t// Zero-buffer publicKey — the type-level lie. The `source`\n\t\t// discriminator on the resolved AccountValue is the\n\t\t// trustworthy signal.\n\t\tpublicKey: new Uint8Array(32),\n\t\tsigner: makeSyntheticSigner(args.name, args.address),\n\t\tbech32Secret: null,\n\t} satisfies ResolvedKeypair);\n};\n"],"mappings":";;;AAqDA,MAAM,uBACL,aACA,aACmC;CACnC,OAAO;CACP,oBAAoB;CAKpB,oBAAoB;CACpB,uBAAuB;AACtB,QAAM,iBAAiB;GACtB,OAAO;GACP;GACA;GACA,SAAS,YAAY,YAAY;GACjC,CAAC;;CAEH,2BAA2B;AAC1B,QAAM,iBAAiB;GACtB,OAAO;GACP;GACA;GACA,SAAS,YAAY,YAAY;GACjC,CAAC;;CAEH;;;;;AAMD,MAAa,6BACZ,SACyD;AACzD,KAAI,KAAK,YAAY,OACpB,QAAO,OAAO,KACb,oBAAoB;EACnB,OAAO;EACP,aAAa,KAAK;EAClB,SAAS;EACT,SAAS,YAAY,KAAK,KAAK,kDAAkD,KAAK,QAAQ;EAC9F,MAAM;EACN,CAAC,CACF;AAEF,QAAO,OAAO,QAAQ;EACrB,SAAS,KAAK;EACd,QAAQ;EAIR,WAAW,IAAI,WAAW,GAAG;EAC7B,QAAQ,oBAAoB,KAAK,MAAM,KAAK,QAAQ;EACpD,cAAc;EACd,CAA2B"}
1
+ {"version":3,"file":"impersonate.mjs","names":[],"sources":["../../../../src/plugins/account/variants/impersonate.ts"],"sourcesContent":["// Account variant — impersonate (fork-mode only).\n//\n// Distilled-doc invariants:\n//\n// - \"Impersonation only on fork\": the variant must refuse outside\n// fork-runtime. The refusal lands at variant-resolution time\n// (typed AccountAcquireError, phase: bind-impersonation-slot).\n//\n// - \"Sign-and-execute is the only execution surface for\n// impersonation\": synthetic impersonation signers must THROW\n// SYNCHRONOUSLY on direct sign calls so accidental bypass is\n// loud, not silent. We surface this through the\n// `SyntheticImpersonationSigner` object's `signTransaction` /\n// `signPersonalMessage` methods.\n//\n// - \"publicKey caveat\": the resolved value's `publicKey` is a\n// zero buffer. The resolved-account TYPE (in `service.ts`)\n// encodes the source discriminator so consumers can't accidentally\n// treat an impersonation publicKey as authoritative.\n//\n// Distilled-doc opportunity: \"Move the synthetic impersonation\n// signer next to the other fork-only helpers\". For now, it stays\n// here because the variant resolver is the only construction site —\n// if Wallet ever needs to materialize impersonation signers directly,\n// we lift this into `plugins/sui/fork-orchestration.ts`.\n\nimport { Effect } from 'effect';\n\nimport { accountAcquireError, accountSignError, type AccountAcquireError } from '../errors.ts';\nimport type { ResolvedKeypair } from '../keypair.ts';\n\nexport interface ImpersonateVariantArgs {\n\treadonly name: string;\n\t/** The address to execute AS. Must appear in the fork's seed\n\t * manifest's owned-object index (typically by being listed\n\t * in `Sui({fork:{seed:{addresses}}})`). */\n\treadonly address: string;\n\t/** Sui's resolved runtime mode — gates the refusal-outside-fork\n\t * check. */\n\treadonly suiMode: 'local' | 'local-rpc' | 'live' | 'fork';\n}\n\n/** The synthetic impersonation signer object. THROWS SYNCHRONOUSLY\n * on direct sign calls; routes `signAndExecute` through the fork's\n * empty-signature submit path (wired in `service.ts`). */\nexport interface SyntheticImpersonationSigner {\n\treadonly _kind: 'impersonate';\n\treadonly toSuiAddress: () => string;\n\treadonly getKeyScheme: () => 'ed25519';\n\treadonly signTransaction: () => never;\n\treadonly signPersonalMessage: () => never;\n}\n\nconst makeSyntheticSigner = (\n\taccountName: string,\n\taddress: string,\n): SyntheticImpersonationSigner => ({\n\t_kind: 'impersonate',\n\ttoSuiAddress: () => address,\n\t// Stable lie: report ed25519 so manifest serialization doesn't\n\t// have to branch. Consumers that need the truth read `source`\n\t// off the resolved-account value (architecture-distilled\n\t// invariant).\n\tgetKeyScheme: () => 'ed25519',\n\tsignTransaction: () => {\n\t\tthrow accountSignError({\n\t\t\tphase: 'impersonation-bypass-attempt',\n\t\t\taccountName,\n\t\t\taddress,\n\t\t\tmessage: `Account '${accountName}' is an impersonation account — direct sign calls are forbidden. Route through signAndExecute (which goes via the fork's impersonation submit path).`,\n\t\t});\n\t},\n\tsignPersonalMessage: () => {\n\t\tthrow accountSignError({\n\t\t\tphase: 'impersonation-bypass-attempt',\n\t\t\taccountName,\n\t\t\taddress,\n\t\t\tmessage: `Account '${accountName}' is an impersonation account — signPersonalMessage is not supported.`,\n\t\t});\n\t},\n});\n\n/** Resolve the impersonate variant.\n *\n * Distilled-doc invariant: refuse outside fork mode. The refusal\n * is a typed acquisition error pointing at the runtime requirement. */\nexport const resolveImpersonateVariant = (\n\targs: ImpersonateVariantArgs,\n): Effect.Effect<ResolvedKeypair, AccountAcquireError> => {\n\tif (args.suiMode !== 'fork') {\n\t\treturn Effect.fail(\n\t\t\taccountAcquireError({\n\t\t\t\tphase: 'bind-impersonation-slot',\n\t\t\t\taccountName: args.name,\n\t\t\t\tvariant: 'impersonate',\n\t\t\t\tmessage: `Account '${args.name}' uses {kind:'impersonate'} but Sui runtime is '${args.suiMode}'. Impersonation only works on fork-mode networks.`,\n\t\t\t\thint: `Switch to suiFor(network).fork.{mainnet|testnet|devnet}(...) — or use a different account variant.`,\n\t\t\t}),\n\t\t);\n\t}\n\treturn Effect.succeed({\n\t\taddress: args.address,\n\t\tscheme: 'ed25519',\n\t\t// Zero-buffer publicKey — the type-level lie. The `source`\n\t\t// discriminator on the resolved AccountValue is the\n\t\t// trustworthy signal.\n\t\tpublicKey: new Uint8Array(32),\n\t\tsigner: makeSyntheticSigner(args.name, args.address),\n\t\tbech32Secret: null,\n\t} satisfies ResolvedKeypair);\n};\n"],"mappings":";;;AAqDA,MAAM,uBACL,aACA,aACmC;CACnC,OAAO;CACP,oBAAoB;CAKpB,oBAAoB;CACpB,uBAAuB;EACtB,MAAM,iBAAiB;GACtB,OAAO;GACP;GACA;GACA,SAAS,YAAY,YAAY;EAClC,CAAC;CACF;CACA,2BAA2B;EAC1B,MAAM,iBAAiB;GACtB,OAAO;GACP;GACA;GACA,SAAS,YAAY,YAAY;EAClC,CAAC;CACF;AACD;;;;;AAMA,MAAa,6BACZ,SACyD;CACzD,IAAI,KAAK,YAAY,QACpB,OAAO,OAAO,KACb,oBAAoB;EACnB,OAAO;EACP,aAAa,KAAK;EAClB,SAAS;EACT,SAAS,YAAY,KAAK,KAAK,kDAAkD,KAAK,QAAQ;EAC9F,MAAM;CACP,CAAC,CACF;CAED,OAAO,OAAO,QAAQ;EACrB,SAAS,KAAK;EACd,QAAQ;EAIR,WAAW,IAAI,WAAW,EAAE;EAC5B,QAAQ,oBAAoB,KAAK,MAAM,KAAK,OAAO;EACnD,cAAc;CACf,CAA2B;AAC5B"}