@mysten-incubation/devstack 0.0.1 → 0.1.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.
- package/README.md +7 -3
- package/dashboard-ui/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- package/dashboard-ui/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- package/dashboard-ui/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/dashboard-ui/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/dashboard-ui/assets/geist-mono-cyrillic-ext-wght-normal-I4S5GZfc.woff2 +0 -0
- package/dashboard-ui/assets/geist-mono-cyrillic-wght-normal-BmXc_FBt.woff2 +0 -0
- package/dashboard-ui/assets/geist-mono-latin-ext-wght-normal-DrnZ1wKl.woff2 +0 -0
- package/dashboard-ui/assets/geist-mono-latin-wght-normal-B_7UjwxQ.woff2 +0 -0
- package/dashboard-ui/assets/geist-mono-symbols2-wght-normal-GZpp1pK2.woff2 +0 -0
- package/dashboard-ui/assets/geist-mono-vietnamese-wght-normal-D8KDMBhC.woff2 +0 -0
- package/dashboard-ui/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- package/dashboard-ui/assets/index-Bmi1UtAg.js +1356 -0
- package/dashboard-ui/assets/index-D5EShVt4.js +3 -0
- package/dashboard-ui/assets/index-Deml9drg.css +1 -0
- package/dashboard-ui/index.html +13 -0
- package/dist/api/define-capabilities.d.mts +14 -3
- package/dist/api/define-capabilities.mjs +18 -1
- package/dist/api/define-capabilities.mjs.map +1 -1
- package/dist/api/define-devstack.d.mts +1 -1
- package/dist/api/define-devstack.mjs +6 -26
- package/dist/api/define-devstack.mjs.map +1 -1
- package/dist/api/define-plugin.d.mts +1 -0
- package/dist/api/define-plugin.mjs +2 -0
- package/dist/api/inference-network.d.mts +132 -0
- package/dist/api/inference-network.mjs +105 -16
- package/dist/api/inference-network.mjs.map +1 -1
- package/dist/api/plugin-errors.d.mts +7 -0
- package/dist/api/run-stack.d.mts +20 -9
- package/dist/api/run-stack.mjs +56 -29
- package/dist/api/run-stack.mjs.map +1 -1
- package/dist/build-integrations/playwright/config.d.mts +6 -4
- package/dist/build-integrations/playwright/config.mjs +5 -3
- package/dist/build-integrations/playwright/config.mjs.map +1 -1
- package/dist/build-integrations/playwright/errors.d.mts +1 -1
- package/dist/build-integrations/playwright/global-setup.d.mts +43 -17
- package/dist/build-integrations/playwright/global-setup.mjs +250 -13
- package/dist/build-integrations/playwright/global-setup.mjs.map +1 -1
- package/dist/build-integrations/playwright/index.d.mts +5 -3
- package/dist/build-integrations/playwright/index.mjs +4 -2
- package/dist/build-integrations/playwright/stack-context.d.mts +0 -1
- package/dist/build-integrations/playwright/stack-context.mjs +24 -63
- package/dist/build-integrations/playwright/stack-context.mjs.map +1 -1
- package/dist/build-integrations/playwright/wallet-context.d.mts +7 -10
- package/dist/build-integrations/playwright/wallet-context.mjs +8 -13
- package/dist/build-integrations/playwright/wallet-context.mjs.map +1 -1
- package/dist/build-integrations/runtime/cold-start-url.d.mts +5 -0
- package/dist/build-integrations/runtime/cold-start-url.mjs +4 -3
- package/dist/build-integrations/runtime/cold-start-url.mjs.map +1 -1
- package/dist/build-integrations/runtime/conventional-routes.d.mts +51 -0
- package/dist/build-integrations/runtime/conventional-routes.mjs +92 -0
- package/dist/build-integrations/runtime/conventional-routes.mjs.map +1 -0
- package/dist/build-integrations/runtime/discover.d.mts +38 -30
- package/dist/build-integrations/runtime/discover.mjs +73 -70
- package/dist/build-integrations/runtime/discover.mjs.map +1 -1
- package/dist/build-integrations/runtime/endpoint-registry.d.mts +3 -1
- package/dist/build-integrations/runtime/endpoint-registry.mjs +3 -1
- package/dist/build-integrations/runtime/endpoint-registry.mjs.map +1 -1
- package/dist/build-integrations/runtime/index.d.mts +7 -2
- package/dist/build-integrations/runtime/index.mjs +9 -2
- package/dist/build-integrations/runtime/manifest-types.d.mts +2 -0
- package/dist/build-integrations/runtime/manifest-types.mjs +3 -0
- package/dist/build-integrations/runtime/playwright-stack-context-slot.d.mts +29 -0
- package/dist/build-integrations/runtime/playwright-stack-context-slot.mjs +10 -0
- package/dist/build-integrations/runtime/playwright-stack-context-slot.mjs.map +1 -0
- package/dist/build-integrations/runtime/read-stack-context.d.mts +1 -1
- package/dist/build-integrations/runtime/read-stack-context.mjs +10 -4
- package/dist/build-integrations/runtime/read-stack-context.mjs.map +1 -1
- package/dist/build-integrations/runtime/resolve-discovery-env.d.mts +48 -0
- package/dist/build-integrations/runtime/resolve-discovery-env.mjs +42 -0
- package/dist/build-integrations/runtime/resolve-discovery-env.mjs.map +1 -0
- package/dist/build-integrations/runtime/stack-context.d.mts +1 -1
- package/dist/build-integrations/runtime/wallet-paths.mjs +2 -0
- package/dist/build-integrations/vite/index.d.mts +51 -0
- package/dist/build-integrations/vite/index.mjs +73 -0
- package/dist/build-integrations/vite/index.mjs.map +1 -0
- package/dist/build-integrations/vitest/env.d.mts +4 -3
- package/dist/build-integrations/vitest/env.mjs +6 -4
- package/dist/build-integrations/vitest/env.mjs.map +1 -1
- package/dist/build-integrations/vitest/errors.d.mts +25 -4
- package/dist/build-integrations/vitest/errors.mjs +15 -2
- package/dist/build-integrations/vitest/errors.mjs.map +1 -1
- package/dist/build-integrations/vitest/index.d.mts +2 -2
- package/dist/build-integrations/vitest/index.mjs +3 -3
- package/dist/build-integrations/vitest/setup.d.mts +4 -2
- package/dist/build-integrations/vitest/setup.mjs +2 -2
- package/dist/build-integrations/vitest/setup.mjs.map +1 -1
- package/dist/build-integrations/vitest/stack-context.d.mts +0 -1
- package/dist/build-integrations/vitest/stack-context.mjs +33 -13
- package/dist/build-integrations/vitest/stack-context.mjs.map +1 -1
- package/dist/cli/bail.mjs +23 -0
- package/dist/cli/bail.mjs.map +1 -0
- package/dist/{surfaces/cli/commands → cli}/doctor-probes.mjs +26 -16
- package/dist/cli/doctor-probes.mjs.map +1 -0
- package/dist/cli/main.d.mts +15 -1
- package/dist/cli/main.mjs +166 -482
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/prune-direct.mjs +31 -201
- package/dist/cli/prune-direct.mjs.map +1 -1
- package/dist/cli/snapshot-reader.mjs +14 -11
- package/dist/cli/snapshot-reader.mjs.map +1 -1
- package/dist/cli/up-lifecycle.mjs +4 -1
- package/dist/cli/up-lifecycle.mjs.map +1 -1
- package/dist/cli/wirings/apply.mjs +95 -0
- package/dist/cli/wirings/apply.mjs.map +1 -0
- package/dist/cli/wirings/build-verb-layers.mjs +42 -0
- package/dist/cli/wirings/build-verb-layers.mjs.map +1 -0
- package/dist/cli/wirings/config-loader.mjs +69 -0
- package/dist/cli/wirings/config-loader.mjs.map +1 -0
- package/dist/cli/wirings/engine-command.mjs +30 -0
- package/dist/cli/wirings/engine-command.mjs.map +1 -0
- package/dist/cli/wirings/identity.mjs +72 -0
- package/dist/cli/wirings/identity.mjs.map +1 -0
- package/dist/cli/wirings/provide-file-system.mjs +7 -0
- package/dist/cli/wirings/provide-file-system.mjs.map +1 -0
- package/dist/cli/wirings/snapshot.mjs +177 -0
- package/dist/cli/wirings/snapshot.mjs.map +1 -0
- package/dist/cli/wirings/up.mjs +287 -0
- package/dist/cli/wirings/up.mjs.map +1 -0
- package/dist/cli/wirings/wipe.mjs +40 -0
- package/dist/cli/wirings/wipe.mjs.map +1 -0
- package/dist/contracts/capability-decl.d.mts +0 -2
- package/dist/contracts/codegenable.d.mts +43 -0
- package/dist/contracts/container-runtime.d.mts +26 -1
- package/dist/contracts/faucet-strategy.d.mts +25 -0
- package/dist/contracts/funding-strategy.d.mts +42 -0
- package/dist/contracts/plugin-expander.mjs +60 -0
- package/dist/contracts/plugin-expander.mjs.map +1 -0
- package/dist/contracts/projection.d.mts +5 -3
- package/dist/contracts/renderer.d.mts +23 -0
- package/dist/contracts/routable.d.mts +14 -1
- package/dist/contracts/snapshotable.d.mts +25 -3
- package/dist/contracts/wallet-protocol.d.mts +52 -0
- package/dist/contracts/wallet-protocol.mjs +52 -0
- package/dist/contracts/wallet-protocol.mjs.map +1 -0
- package/dist/index.d.mts +26 -25
- package/dist/index.mjs +20 -13
- package/dist/{runtime → orchestrators}/built-in-plugin-layers.mjs +10 -5
- package/dist/orchestrators/built-in-plugin-layers.mjs.map +1 -0
- package/dist/orchestrators/codegen/bindings.d.mts +1 -2
- package/dist/orchestrators/codegen/bindings.mjs +52 -186
- package/dist/orchestrators/codegen/bindings.mjs.map +1 -1
- package/dist/orchestrators/codegen/emit.mjs +19 -1
- package/dist/orchestrators/codegen/emit.mjs.map +1 -1
- package/dist/orchestrators/codegen/errors.mjs +8 -3
- package/dist/orchestrators/codegen/errors.mjs.map +1 -1
- package/dist/orchestrators/codegen/format.mjs +47 -39
- package/dist/orchestrators/codegen/format.mjs.map +1 -1
- package/dist/orchestrators/codegen/gitignore.mjs +3 -1
- package/dist/orchestrators/codegen/gitignore.mjs.map +1 -1
- package/dist/orchestrators/codegen/output-location.mjs +40 -0
- package/dist/orchestrators/codegen/output-location.mjs.map +1 -0
- package/dist/orchestrators/codegen/paths.d.mts +1 -1
- package/dist/orchestrators/codegen/paths.mjs +40 -14
- package/dist/orchestrators/codegen/paths.mjs.map +1 -1
- package/dist/orchestrators/codegen/permissions.mjs +3 -1
- package/dist/orchestrators/codegen/permissions.mjs.map +1 -1
- package/dist/orchestrators/codegen/service.mjs +157 -105
- package/dist/orchestrators/codegen/service.mjs.map +1 -1
- package/dist/orchestrators/lifecycle-prune/errors.mjs +31 -0
- package/dist/orchestrators/lifecycle-prune/errors.mjs.map +1 -0
- package/dist/orchestrators/lifecycle-prune/index.mjs +350 -0
- package/dist/orchestrators/lifecycle-prune/index.mjs.map +1 -0
- package/dist/orchestrators/router/cleanup.mjs +26 -27
- package/dist/orchestrators/router/cleanup.mjs.map +1 -1
- package/dist/orchestrators/router/entrypoints.mjs +2 -2
- package/dist/orchestrators/router/entrypoints.mjs.map +1 -1
- package/dist/orchestrators/router/file-provider.mjs +14 -5
- package/dist/orchestrators/router/file-provider.mjs.map +1 -1
- package/dist/orchestrators/router/hostname.mjs +19 -55
- package/dist/orchestrators/router/hostname.mjs.map +1 -1
- package/dist/orchestrators/router/index.mjs +11 -0
- package/dist/orchestrators/router/profile.mjs +2 -2
- package/dist/orchestrators/router/sentinels.mjs +26 -0
- package/dist/orchestrators/router/sentinels.mjs.map +1 -0
- package/dist/orchestrators/router/service.mjs +40 -37
- package/dist/orchestrators/router/service.mjs.map +1 -1
- package/dist/orchestrators/router/traefik-container.mjs +27 -16
- package/dist/orchestrators/router/traefik-container.mjs.map +1 -1
- package/dist/{substrate/runtime → orchestrators}/run.mjs +26 -21
- package/dist/orchestrators/run.mjs.map +1 -0
- package/dist/orchestrators/runtime-composition.d.mts +1 -1
- package/dist/orchestrators/runtime-composition.mjs +123 -39
- package/dist/orchestrators/runtime-composition.mjs.map +1 -1
- package/dist/orchestrators/snapshot/capture-command.d.mts +1 -0
- package/dist/orchestrators/snapshot/capture-command.mjs +25 -0
- package/dist/orchestrators/snapshot/capture-command.mjs.map +1 -0
- package/dist/orchestrators/snapshot/capture.mjs +42 -28
- package/dist/orchestrators/snapshot/capture.mjs.map +1 -1
- package/dist/orchestrators/snapshot/descriptor.mjs +35 -10
- package/dist/orchestrators/snapshot/descriptor.mjs.map +1 -1
- package/dist/orchestrators/snapshot/identity-guard.mjs +1 -1
- package/dist/orchestrators/snapshot/index.mjs +13 -0
- package/dist/orchestrators/snapshot/integrity.d.mts +1 -1
- package/dist/orchestrators/snapshot/integrity.mjs +73 -17
- package/dist/orchestrators/snapshot/integrity.mjs.map +1 -1
- package/dist/orchestrators/snapshot/pending-marker.d.mts +1 -0
- package/dist/orchestrators/snapshot/pending-marker.mjs +99 -0
- package/dist/orchestrators/snapshot/pending-marker.mjs.map +1 -0
- package/dist/orchestrators/snapshot/phase-error.mjs +23 -0
- package/dist/orchestrators/snapshot/phase-error.mjs.map +1 -0
- package/dist/orchestrators/snapshot/prune.mjs +20 -55
- package/dist/orchestrators/snapshot/prune.mjs.map +1 -1
- package/dist/orchestrators/snapshot/recover-pending.d.mts +1 -0
- package/dist/orchestrators/snapshot/recover-pending.mjs +223 -0
- package/dist/orchestrators/snapshot/recover-pending.mjs.map +1 -0
- package/dist/orchestrators/snapshot/restore.mjs +118 -84
- package/dist/orchestrators/snapshot/restore.mjs.map +1 -1
- package/dist/orchestrators/snapshot/service.mjs +53 -56
- package/dist/orchestrators/snapshot/service.mjs.map +1 -1
- package/dist/orchestrators/snapshot/state-document.d.mts +1 -0
- package/dist/orchestrators/snapshot/state-document.mjs +47 -7
- package/dist/orchestrators/snapshot/state-document.mjs.map +1 -1
- package/dist/orchestrators/snapshot/wipe.mjs +67 -10
- package/dist/orchestrators/snapshot/wipe.mjs.map +1 -1
- package/dist/plugins/account/codegen.mjs +9 -8
- package/dist/plugins/account/codegen.mjs.map +1 -1
- package/dist/plugins/account/errors.d.mts +33 -6
- package/dist/plugins/account/errors.mjs.map +1 -1
- package/dist/plugins/account/funding.d.mts +29 -19
- package/dist/plugins/account/funding.mjs +84 -66
- package/dist/plugins/account/funding.mjs.map +1 -1
- package/dist/plugins/account/index.d.mts +2 -4
- package/dist/plugins/account/index.mjs +64 -31
- package/dist/plugins/account/index.mjs.map +1 -1
- package/dist/plugins/account/keypair.mjs +6 -9
- package/dist/plugins/account/keypair.mjs.map +1 -1
- package/dist/plugins/account/lease.mjs +1 -0
- package/dist/plugins/account/lease.mjs.map +1 -1
- package/dist/plugins/account/registry.d.mts +14 -1
- package/dist/plugins/account/registry.mjs +18 -18
- package/dist/plugins/account/registry.mjs.map +1 -1
- package/dist/plugins/account/service.d.mts +23 -4
- package/dist/plugins/account/service.mjs +83 -45
- package/dist/plugins/account/service.mjs.map +1 -1
- package/dist/plugins/account/snapshot.mjs +2 -5
- package/dist/plugins/account/snapshot.mjs.map +1 -1
- package/dist/plugins/account/spans.mjs +16 -0
- package/dist/plugins/account/spans.mjs.map +1 -0
- package/dist/plugins/account/variants/keystore.mjs +6 -8
- package/dist/plugins/account/variants/keystore.mjs.map +1 -1
- package/dist/plugins/action/build-context.d.mts +3 -2
- package/dist/plugins/action/errors.d.mts +16 -12
- package/dist/plugins/action/errors.mjs.map +1 -1
- package/dist/plugins/action/execute.mjs +65 -103
- package/dist/plugins/action/execute.mjs.map +1 -1
- package/dist/plugins/action/index.d.mts +0 -2
- package/dist/plugins/action/index.mjs +17 -13
- package/dist/plugins/action/index.mjs.map +1 -1
- package/dist/plugins/action/service.mjs +38 -35
- package/dist/plugins/action/service.mjs.map +1 -1
- package/dist/plugins/action/spans.mjs +11 -0
- package/dist/plugins/action/spans.mjs.map +1 -0
- package/dist/plugins/coin/codegen.mjs +9 -8
- package/dist/plugins/coin/codegen.mjs.map +1 -1
- package/dist/plugins/coin/discovery.mjs +8 -4
- package/dist/plugins/coin/discovery.mjs.map +1 -1
- package/dist/plugins/coin/index.d.mts +11 -29
- package/dist/plugins/coin/index.mjs +56 -27
- package/dist/plugins/coin/index.mjs.map +1 -1
- package/dist/plugins/coin/metadata.mjs +8 -15
- package/dist/plugins/coin/metadata.mjs.map +1 -1
- package/dist/plugins/coin/mint.d.mts +30 -11
- package/dist/plugins/coin/mint.mjs +78 -74
- package/dist/plugins/coin/mint.mjs.map +1 -1
- package/dist/plugins/coin/registry.mjs +4 -7
- package/dist/plugins/coin/registry.mjs.map +1 -1
- package/dist/plugins/coin/service.d.mts +39 -1
- package/dist/plugins/coin/service.mjs +11 -4
- package/dist/plugins/coin/service.mjs.map +1 -1
- package/dist/plugins/coin/spans.mjs +20 -0
- package/dist/plugins/coin/spans.mjs.map +1 -0
- package/dist/plugins/dashboard/domain.mjs +402 -0
- package/dist/plugins/dashboard/domain.mjs.map +1 -0
- package/dist/plugins/dashboard/index.d.mts +29 -0
- package/dist/plugins/dashboard/index.mjs +91 -0
- package/dist/plugins/dashboard/index.mjs.map +1 -0
- package/dist/plugins/dashboard/origin-policy.mjs +36 -0
- package/dist/plugins/dashboard/origin-policy.mjs.map +1 -0
- package/dist/plugins/dashboard/routable.mjs +27 -0
- package/dist/plugins/dashboard/routable.mjs.map +1 -0
- package/dist/plugins/dashboard/schema/builder.mjs +21 -0
- package/dist/plugins/dashboard/schema/builder.mjs.map +1 -0
- package/dist/plugins/dashboard/schema/enums.mjs +72 -0
- package/dist/plugins/dashboard/schema/enums.mjs.map +1 -0
- package/dist/plugins/dashboard/schema/root.mjs +351 -0
- package/dist/plugins/dashboard/schema/root.mjs.map +1 -0
- package/dist/plugins/dashboard/schema/types.mjs +508 -0
- package/dist/plugins/dashboard/schema/types.mjs.map +1 -0
- package/dist/plugins/dashboard/schema.mjs +11 -0
- package/dist/plugins/dashboard/schema.mjs.map +1 -0
- package/dist/plugins/dashboard/server.mjs +166 -0
- package/dist/plugins/dashboard/server.mjs.map +1 -0
- package/dist/plugins/deepbook/deploy.mjs +53 -115
- package/dist/plugins/deepbook/deploy.mjs.map +1 -1
- package/dist/plugins/deepbook/errors.mjs +1 -0
- package/dist/plugins/deepbook/errors.mjs.map +1 -1
- package/dist/plugins/deepbook/faucet-strategy.mjs +47 -34
- package/dist/plugins/deepbook/faucet-strategy.mjs.map +1 -1
- package/dist/plugins/deepbook/hash.mjs +9 -0
- package/dist/plugins/deepbook/hash.mjs.map +1 -0
- package/dist/plugins/deepbook/index.d.mts +1 -10
- package/dist/plugins/deepbook/index.mjs +25 -22
- package/dist/plugins/deepbook/index.mjs.map +1 -1
- package/dist/plugins/deepbook/pyth/index.mjs +26 -55
- package/dist/plugins/deepbook/pyth/index.mjs.map +1 -1
- package/dist/plugins/deepbook/snapshot.mjs +17 -29
- package/dist/plugins/deepbook/snapshot.mjs.map +1 -1
- package/dist/plugins/deepbook/spans.mjs +18 -0
- package/dist/plugins/deepbook/spans.mjs.map +1 -0
- package/dist/plugins/deepbook/type-strings.mjs +65 -0
- package/dist/plugins/deepbook/type-strings.mjs.map +1 -0
- package/dist/plugins/deepbook/types.d.mts +2 -3
- package/dist/plugins/deepbook/types.mjs.map +1 -1
- package/dist/plugins/faucet/dispatcher.d.mts +21 -2
- package/dist/plugins/faucet/dispatcher.mjs +1 -2
- package/dist/plugins/faucet/dispatcher.mjs.map +1 -1
- package/dist/plugins/faucet/errors.d.mts +11 -24
- package/dist/plugins/faucet/errors.mjs.map +1 -1
- package/dist/plugins/faucet/http.mjs +33 -14
- package/dist/plugins/faucet/http.mjs.map +1 -1
- package/dist/plugins/faucet/index.d.mts +15 -5
- package/dist/plugins/faucet/index.mjs +3 -0
- package/dist/plugins/faucet/index.mjs.map +1 -1
- package/dist/plugins/faucet/spans.mjs +12 -0
- package/dist/plugins/faucet/spans.mjs.map +1 -0
- package/dist/plugins/host-service/errors.d.mts +1 -1
- package/dist/plugins/host-service/index.mjs +34 -8
- package/dist/plugins/host-service/index.mjs.map +1 -1
- package/dist/plugins/host-service/routable.mjs +2 -1
- package/dist/plugins/host-service/routable.mjs.map +1 -1
- package/dist/plugins/host-service/service.d.mts +21 -0
- package/dist/plugins/host-service/service.mjs +136 -81
- package/dist/plugins/host-service/service.mjs.map +1 -1
- package/dist/plugins/internal/acquire-on-chain-artifact.mjs +23 -0
- package/dist/plugins/internal/acquire-on-chain-artifact.mjs.map +1 -0
- package/dist/plugins/internal/codegen-helpers.mjs +18 -0
- package/dist/plugins/internal/codegen-helpers.mjs.map +1 -0
- package/dist/plugins/internal/funding-failure-error.mjs +32 -0
- package/dist/plugins/internal/funding-failure-error.mjs.map +1 -0
- package/dist/plugins/package/build.mjs +1 -1
- package/dist/plugins/package/build.mjs.map +1 -1
- package/dist/plugins/package/codegen.mjs +26 -0
- package/dist/plugins/package/codegen.mjs.map +1 -1
- package/dist/plugins/package/errors.d.mts +16 -6
- package/dist/plugins/package/errors.mjs.map +1 -1
- package/dist/plugins/package/index.d.mts +0 -4
- package/dist/plugins/package/index.mjs +27 -21
- package/dist/plugins/package/index.mjs.map +1 -1
- package/dist/plugins/package/mode-known.mjs +26 -12
- package/dist/plugins/package/mode-known.mjs.map +1 -1
- package/dist/plugins/package/mode-local.mjs +47 -41
- package/dist/plugins/package/mode-local.mjs.map +1 -1
- package/dist/plugins/package/publish-executor.mjs +55 -114
- package/dist/plugins/package/publish-executor.mjs.map +1 -1
- package/dist/plugins/package/registry.mjs +2 -1
- package/dist/plugins/package/registry.mjs.map +1 -1
- package/dist/plugins/package/service.mjs.map +1 -1
- package/dist/plugins/package/spans.mjs +14 -0
- package/dist/plugins/package/spans.mjs.map +1 -0
- package/dist/plugins/postgres/db-ensure.mjs +19 -12
- package/dist/plugins/postgres/db-ensure.mjs.map +1 -1
- package/dist/plugins/postgres/errors.d.mts +5 -0
- package/dist/plugins/postgres/errors.mjs.map +1 -1
- package/dist/plugins/postgres/index.mjs +10 -17
- package/dist/plugins/postgres/index.mjs.map +1 -1
- package/dist/plugins/postgres/service.mjs +58 -24
- package/dist/plugins/postgres/service.mjs.map +1 -1
- package/dist/plugins/postgres/snapshot.mjs.map +1 -1
- package/dist/plugins/postgres/spans.mjs +11 -0
- package/dist/plugins/postgres/spans.mjs.map +1 -0
- package/dist/plugins/router-entrypoints.mjs +4 -4
- package/dist/plugins/router-entrypoints.mjs.map +1 -1
- package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs +15 -13
- package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs.map +1 -1
- package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs +15 -19
- package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs.map +1 -1
- package/dist/plugins/seal/codegen.d.mts +2 -3
- package/dist/plugins/seal/codegen.mjs.map +1 -1
- package/dist/plugins/seal/config-render.mjs +35 -8
- package/dist/plugins/seal/config-render.mjs.map +1 -1
- package/dist/plugins/seal/deploy.mjs +31 -39
- package/dist/plugins/seal/deploy.mjs.map +1 -1
- package/dist/plugins/seal/errors.d.mts +1 -3
- package/dist/plugins/seal/errors.mjs +7 -1
- package/dist/plugins/seal/errors.mjs.map +1 -1
- package/dist/plugins/seal/index.d.mts +1 -6
- package/dist/plugins/seal/index.mjs +40 -14
- package/dist/plugins/seal/index.mjs.map +1 -1
- package/dist/plugins/seal/key-manager.d.mts +1 -9
- package/dist/plugins/seal/key-manager.mjs +2 -18
- package/dist/plugins/seal/key-manager.mjs.map +1 -1
- package/dist/plugins/seal/key-server.mjs +37 -36
- package/dist/plugins/seal/key-server.mjs.map +1 -1
- package/dist/plugins/seal/keygen.mjs +16 -17
- package/dist/plugins/seal/keygen.mjs.map +1 -1
- package/dist/plugins/seal/mode/fork-known.mjs +36 -14
- package/dist/plugins/seal/mode/fork-known.mjs.map +1 -1
- package/dist/plugins/seal/mode/live.d.mts +6 -4
- package/dist/plugins/seal/mode/live.mjs +14 -21
- package/dist/plugins/seal/mode/live.mjs.map +1 -1
- package/dist/plugins/seal/mode/local-keygen.mjs +57 -21
- package/dist/plugins/seal/mode/local-keygen.mjs.map +1 -1
- package/dist/plugins/seal/registry-publish.mjs +1 -0
- package/dist/plugins/seal/registry-publish.mjs.map +1 -1
- package/dist/plugins/seal/routable.mjs.map +1 -1
- package/dist/plugins/seal/service.mjs.map +1 -1
- package/dist/plugins/seal/spans.mjs +18 -0
- package/dist/plugins/seal/spans.mjs.map +1 -0
- package/dist/plugins/sui/auto-tick.mjs +17 -23
- package/dist/plugins/sui/auto-tick.mjs.map +1 -1
- package/dist/plugins/sui/chain-build-container.mjs +18 -0
- package/dist/plugins/sui/chain-build-container.mjs.map +1 -0
- package/dist/plugins/sui/chain-probe.d.mts +5 -5
- package/dist/plugins/sui/chain-probe.mjs +28 -58
- package/dist/plugins/sui/chain-probe.mjs.map +1 -1
- package/dist/plugins/sui/codegen.mjs +26 -0
- package/dist/plugins/sui/codegen.mjs.map +1 -1
- package/dist/plugins/sui/errors.d.mts +2 -29
- package/dist/plugins/sui/errors.mjs +1 -3
- package/dist/plugins/sui/errors.mjs.map +1 -1
- package/dist/plugins/sui/fork-faucet-strategy.d.mts +1 -0
- package/dist/plugins/sui/fork-faucet-strategy.mjs +55 -0
- package/dist/plugins/sui/fork-faucet-strategy.mjs.map +1 -0
- package/dist/plugins/sui/fork-orchestration.d.mts +1 -0
- package/dist/plugins/sui/fork-orchestration.mjs +170 -2
- package/dist/plugins/sui/fork-orchestration.mjs.map +1 -1
- package/dist/plugins/sui/fork-transaction.d.mts +2 -0
- package/dist/plugins/sui/fork-transaction.mjs +92 -28
- package/dist/plugins/sui/fork-transaction.mjs.map +1 -1
- package/dist/plugins/sui/index.d.mts +33 -70
- package/dist/plugins/sui/index.mjs +58 -35
- package/dist/plugins/sui/index.mjs.map +1 -1
- package/dist/plugins/{faucet/strategies/sui-local.mjs → sui/local-faucet-strategy.mjs} +10 -7
- package/dist/plugins/sui/local-faucet-strategy.mjs.map +1 -0
- package/dist/plugins/sui/mode/external.mjs +7 -13
- package/dist/plugins/sui/mode/external.mjs.map +1 -1
- package/dist/plugins/sui/mode/fork.mjs +136 -59
- package/dist/plugins/sui/mode/fork.mjs.map +1 -1
- package/dist/plugins/sui/mode/live.mjs +10 -16
- package/dist/plugins/sui/mode/live.mjs.map +1 -1
- package/dist/plugins/sui/mode/local.mjs +37 -36
- package/dist/plugins/sui/mode/local.mjs.map +1 -1
- package/dist/plugins/sui/mode/shared-boot.mjs +38 -115
- package/dist/plugins/sui/mode/shared-boot.mjs.map +1 -1
- package/dist/plugins/sui/mode/shared.d.mts +1 -5
- package/dist/plugins/sui/mode/shared.mjs.map +1 -1
- package/dist/plugins/sui/mode/spec.d.mts +18 -0
- package/dist/plugins/sui/move-summary-runner.mjs +207 -0
- package/dist/plugins/sui/move-summary-runner.mjs.map +1 -0
- package/dist/plugins/sui/network-resolver.d.mts +4 -3
- package/dist/plugins/sui/service.mjs.map +1 -1
- package/dist/plugins/sui/snapshot.mjs +3 -0
- package/dist/plugins/sui/snapshot.mjs.map +1 -1
- package/dist/plugins/sui/spans.mjs +17 -0
- package/dist/plugins/sui/spans.mjs.map +1 -0
- package/dist/plugins/wallet/codegen.d.mts +0 -1
- package/dist/plugins/wallet/codegen.mjs +8 -9
- package/dist/plugins/wallet/codegen.mjs.map +1 -1
- package/dist/plugins/wallet/index.d.mts +6 -8
- package/dist/plugins/wallet/index.mjs +46 -35
- package/dist/plugins/wallet/index.mjs.map +1 -1
- package/dist/plugins/wallet/origin-policy.mjs +12 -28
- package/dist/plugins/wallet/origin-policy.mjs.map +1 -1
- package/dist/plugins/wallet/pairing.mjs +6 -4
- package/dist/plugins/wallet/pairing.mjs.map +1 -1
- package/dist/plugins/wallet/protocol.d.mts +1 -0
- package/dist/plugins/wallet/protocol.mjs +5 -44
- package/dist/plugins/wallet/protocol.mjs.map +1 -1
- package/dist/plugins/wallet/routable.mjs +2 -8
- package/dist/plugins/wallet/routable.mjs.map +1 -1
- package/dist/plugins/wallet/server.mjs +36 -44
- package/dist/plugins/wallet/server.mjs.map +1 -1
- package/dist/plugins/wallet/service.d.mts +1 -5
- package/dist/plugins/wallet/service.mjs +22 -18
- package/dist/plugins/wallet/service.mjs.map +1 -1
- package/dist/plugins/wallet/spans.mjs +22 -0
- package/dist/plugins/wallet/spans.mjs.map +1 -0
- package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs +33 -8
- package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs.map +1 -1
- package/dist/plugins/walrus/codegen.d.mts +3 -3
- package/dist/plugins/walrus/codegen.mjs.map +1 -1
- package/dist/plugins/walrus/deploy-paths.mjs +21 -5
- package/dist/plugins/walrus/deploy-paths.mjs.map +1 -1
- package/dist/plugins/walrus/deploy.mjs +67 -69
- package/dist/plugins/walrus/deploy.mjs.map +1 -1
- package/dist/plugins/walrus/errors.mjs +1 -0
- package/dist/plugins/walrus/errors.mjs.map +1 -1
- package/dist/plugins/walrus/faucet-strategy.mjs +12 -7
- package/dist/plugins/walrus/faucet-strategy.mjs.map +1 -1
- package/dist/plugins/walrus/index.d.mts +2 -13
- package/dist/plugins/walrus/index.mjs +18 -23
- package/dist/plugins/walrus/index.mjs.map +1 -1
- package/dist/plugins/walrus/mode/known-deploy.mjs +7 -5
- package/dist/plugins/walrus/mode/known-deploy.mjs.map +1 -1
- package/dist/plugins/walrus/mode/local-cluster.mjs +26 -7
- package/dist/plugins/walrus/mode/local-cluster.mjs.map +1 -1
- package/dist/plugins/walrus/registry-publish.mjs.map +1 -1
- package/dist/plugins/walrus/routable.mjs +7 -23
- package/dist/plugins/walrus/routable.mjs.map +1 -1
- package/dist/plugins/walrus/service.mjs.map +1 -1
- package/dist/plugins/walrus/spans.mjs +18 -0
- package/dist/plugins/walrus/spans.mjs.map +1 -0
- package/dist/plugins/walrus/storage-nodes.d.mts +6 -2
- package/dist/plugins/walrus/storage-nodes.mjs +15 -8
- package/dist/plugins/walrus/storage-nodes.mjs.map +1 -1
- package/dist/plugins/walrus/wal-swap.mjs +58 -15
- package/dist/plugins/walrus/wal-swap.mjs.map +1 -1
- package/dist/primitives/artifact-publisher.d.mts +1 -1
- package/dist/primitives/artifact-publisher.mjs +15 -0
- package/dist/primitives/artifact-publisher.mjs.map +1 -0
- package/dist/runtime/docker/client.mjs +17 -4
- package/dist/runtime/docker/client.mjs.map +1 -1
- package/dist/runtime/docker/container.mjs +219 -132
- package/dist/runtime/docker/container.mjs.map +1 -1
- package/dist/runtime/docker/errors.mjs +0 -6
- package/dist/runtime/docker/errors.mjs.map +1 -1
- package/dist/runtime/docker/exec.mjs +21 -18
- package/dist/runtime/docker/exec.mjs.map +1 -1
- package/dist/runtime/docker/image.mjs +36 -13
- package/dist/runtime/docker/image.mjs.map +1 -1
- package/dist/runtime/docker/index.mjs +14 -0
- package/dist/runtime/docker/inspect-and-decode.mjs +51 -0
- package/dist/runtime/docker/inspect-and-decode.mjs.map +1 -0
- package/dist/runtime/docker/inventory.mjs +14 -11
- package/dist/runtime/docker/inventory.mjs.map +1 -1
- package/dist/runtime/docker/labels.mjs +38 -5
- package/dist/runtime/docker/labels.mjs.map +1 -1
- package/dist/runtime/docker/logs.d.mts +1 -1
- package/dist/runtime/docker/logs.mjs.map +1 -1
- package/dist/runtime/docker/network.mjs +83 -47
- package/dist/runtime/docker/network.mjs.map +1 -1
- package/dist/runtime/docker/render-run-args.mjs +82 -0
- package/dist/runtime/docker/render-run-args.mjs.map +1 -0
- package/dist/runtime/docker/service.d.mts +1 -1
- package/dist/runtime/docker/service.mjs +12 -7
- package/dist/runtime/docker/service.mjs.map +1 -1
- package/dist/runtime/docker/sweep.mjs +118 -43
- package/dist/runtime/docker/sweep.mjs.map +1 -1
- package/dist/runtime/docker/volume.mjs +2 -0
- package/dist/runtime/docker/volume.mjs.map +1 -1
- package/dist/runtime/docker/wrap.mjs +30 -1
- package/dist/runtime/docker/wrap.mjs.map +1 -1
- package/dist/substrate/cross-process.mjs +14 -8
- package/dist/substrate/cross-process.mjs.map +1 -1
- package/dist/substrate/event-time.mjs +33 -0
- package/dist/substrate/event-time.mjs.map +1 -0
- package/dist/substrate/events.d.mts +28 -8
- package/dist/substrate/identity.d.mts +2 -1
- package/dist/substrate/manifest.d.mts +68 -5
- package/dist/substrate/manifest.mjs +34 -5
- package/dist/substrate/manifest.mjs.map +1 -1
- package/dist/substrate/network.d.mts +3 -5
- package/dist/substrate/options.d.mts +0 -2
- package/dist/substrate/plugin.d.mts +13 -0
- package/dist/substrate/plugin.mjs +4 -2
- package/dist/substrate/plugin.mjs.map +1 -1
- package/dist/substrate/projection.d.mts +35 -3
- package/dist/substrate/runtime/artifact-publisher/index.mjs +19 -9
- package/dist/substrate/runtime/artifact-publisher/index.mjs.map +1 -1
- package/dist/substrate/runtime/atomic-write.mjs +97 -32
- package/dist/substrate/runtime/atomic-write.mjs.map +1 -1
- package/dist/substrate/runtime/cache/index.mjs +3 -0
- package/dist/substrate/runtime/cache/schema.mjs +2 -2
- package/dist/substrate/runtime/cache/schema.mjs.map +1 -1
- package/dist/substrate/runtime/cache/service.mjs +9 -7
- package/dist/substrate/runtime/cache/service.mjs.map +1 -1
- package/dist/substrate/runtime/capability-sinks/index.d.mts +1 -1
- package/dist/substrate/runtime/capability-sinks/index.mjs +3 -0
- package/dist/substrate/runtime/capability-sinks/layer.mjs +1 -1
- package/dist/substrate/runtime/capability-sinks/service.d.mts +61 -2
- package/dist/substrate/runtime/capability-sinks/service.mjs +21 -26
- package/dist/substrate/runtime/capability-sinks/service.mjs.map +1 -1
- package/dist/substrate/runtime/config-validation.d.mts +1 -13
- package/dist/substrate/runtime/config-validation.mjs +2 -91
- package/dist/substrate/runtime/config-validation.mjs.map +1 -1
- package/dist/substrate/runtime/container-runtime.d.mts +1 -0
- package/dist/substrate/runtime/container-runtime.mjs +2 -0
- package/dist/substrate/runtime/control-plane/domain.mjs +101 -0
- package/dist/substrate/runtime/control-plane/domain.mjs.map +1 -0
- package/dist/substrate/runtime/control-plane/service.mjs +7 -0
- package/dist/substrate/runtime/control-plane/service.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/command-channel/channel.mjs +46 -19
- package/dist/substrate/runtime/cross-process/command-channel/channel.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs +30 -12
- package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/command-channel/index.mjs +5 -0
- package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs +11 -2
- package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/command-channel/runtime-control-lock.mjs +1 -1
- package/dist/substrate/runtime/cross-process/index.mjs +11 -0
- package/dist/substrate/runtime/cross-process/live-clock.mjs +34 -0
- package/dist/substrate/runtime/cross-process/live-clock.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/liveness.mjs +52 -10
- package/dist/substrate/runtime/cross-process/liveness.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/lock.d.mts +1 -0
- package/dist/substrate/runtime/cross-process/lock.mjs +23 -0
- package/dist/substrate/runtime/cross-process/lock.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs +64 -0
- package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/roster.mjs +97 -83
- package/dist/substrate/runtime/cross-process/roster.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/self-pid.mjs +8 -0
- package/dist/substrate/runtime/cross-process/self-pid.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs +24 -28
- package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/stack-lock.mjs +41 -20
- package/dist/substrate/runtime/cross-process/stack-lock.mjs.map +1 -1
- package/dist/substrate/runtime/current-plugin.mjs +2 -2
- package/dist/substrate/runtime/current-plugin.mjs.map +1 -1
- package/dist/substrate/runtime/errors.mjs +12 -6
- package/dist/substrate/runtime/errors.mjs.map +1 -1
- package/dist/substrate/runtime/format-unknown-error.mjs +30 -0
- package/dist/substrate/runtime/format-unknown-error.mjs.map +1 -0
- package/dist/substrate/runtime/host-bind-mount-owner.mjs +10 -0
- package/dist/substrate/runtime/host-bind-mount-owner.mjs.map +1 -0
- package/dist/substrate/runtime/host-gateway.mjs +20 -0
- package/dist/substrate/runtime/host-gateway.mjs.map +1 -0
- package/dist/substrate/runtime/host-tree-tar/index.mjs +61 -50
- package/dist/substrate/runtime/host-tree-tar/index.mjs.map +1 -1
- package/dist/substrate/runtime/http-probe.d.mts +1 -1
- package/dist/substrate/runtime/index.mjs +14 -0
- package/dist/substrate/runtime/lease-broker/index.d.mts +1 -1
- package/dist/substrate/runtime/lease-broker/index.mjs +2 -0
- package/dist/substrate/runtime/lease-broker/service.d.mts +1 -64
- package/dist/substrate/runtime/lease-broker/service.mjs +1 -1
- package/dist/substrate/runtime/lease-broker/service.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/dep-graph.mjs +22 -3
- package/dist/substrate/runtime/lifecycle/dep-graph.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/index.mjs +9 -0
- package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/plugin-registry.mjs +20 -3
- package/dist/substrate/runtime/lifecycle/plugin-registry.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/selective-restart.mjs +1 -1
- package/dist/substrate/runtime/lifecycle/signals.mjs +5 -5
- package/dist/substrate/runtime/lifecycle/signals.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/state-machine.mjs +1 -1
- package/dist/substrate/runtime/managed-container.d.mts +19 -1
- package/dist/substrate/runtime/managed-container.mjs +20 -1
- package/dist/substrate/runtime/managed-container.mjs.map +1 -1
- package/dist/substrate/runtime/manifest/index.mjs +3 -0
- package/dist/substrate/runtime/manifest/manifest.mjs +15 -11
- package/dist/substrate/runtime/manifest/manifest.mjs.map +1 -1
- package/dist/substrate/runtime/mode-errors.mjs +20 -0
- package/dist/substrate/runtime/mode-errors.mjs.map +1 -0
- package/dist/substrate/runtime/observability/cascade-formatter.mjs +9 -13
- package/dist/substrate/runtime/observability/cascade-formatter.mjs.map +1 -1
- package/dist/substrate/runtime/observability/formatter-registry.mjs +19 -36
- package/dist/substrate/runtime/observability/formatter-registry.mjs.map +1 -1
- package/dist/substrate/runtime/observability/ignore-with-log.d.mts +1 -0
- package/dist/substrate/runtime/observability/ignore-with-log.mjs +17 -0
- package/dist/substrate/runtime/observability/ignore-with-log.mjs.map +1 -0
- package/dist/substrate/runtime/observability/index.d.mts +1 -1
- package/dist/substrate/runtime/observability/index.mjs +13 -0
- package/dist/substrate/runtime/observability/log-store.d.mts +1 -0
- package/dist/substrate/runtime/observability/log-store.mjs +175 -0
- package/dist/substrate/runtime/observability/log-store.mjs.map +1 -0
- package/dist/substrate/runtime/observability/logger.d.mts +2 -1
- package/dist/substrate/runtime/observability/logger.mjs +5 -9
- package/dist/substrate/runtime/observability/logger.mjs.map +1 -1
- package/dist/substrate/runtime/observability/output-truncate.mjs +35 -0
- package/dist/substrate/runtime/observability/output-truncate.mjs.map +1 -0
- package/dist/substrate/runtime/observability/pretty-error.mjs +9 -12
- package/dist/substrate/runtime/observability/pretty-error.mjs.map +1 -1
- package/dist/substrate/runtime/observability/redaction.d.mts +2 -13
- package/dist/substrate/runtime/observability/redaction.mjs +8 -14
- package/dist/substrate/runtime/observability/redaction.mjs.map +1 -1
- package/dist/substrate/runtime/observability/span-store.d.mts +1 -0
- package/dist/substrate/runtime/observability/span-store.mjs +110 -0
- package/dist/substrate/runtime/observability/span-store.mjs.map +1 -0
- package/dist/substrate/runtime/observability/spans.mjs +14 -14
- package/dist/substrate/runtime/observability/spans.mjs.map +1 -1
- package/dist/substrate/runtime/observability/subprocess-capture.mjs +1 -1
- package/dist/substrate/runtime/passthrough-or-wrap.mjs +33 -0
- package/dist/substrate/runtime/passthrough-or-wrap.mjs.map +1 -0
- package/dist/substrate/runtime/paths.d.mts +1 -1
- package/dist/substrate/runtime/paths.mjs +4 -3
- package/dist/substrate/runtime/paths.mjs.map +1 -1
- package/dist/substrate/runtime/phase-preserving-produce.mjs +40 -0
- package/dist/substrate/runtime/phase-preserving-produce.mjs.map +1 -0
- package/dist/substrate/runtime/port-broker/index.mjs +3 -0
- package/dist/substrate/runtime/port-broker/service.mjs +170 -126
- package/dist/substrate/runtime/port-broker/service.mjs.map +1 -1
- package/dist/substrate/runtime/post-acquire-tasks.mjs +1 -1
- package/dist/substrate/runtime/post-acquire-tasks.mjs.map +1 -1
- package/dist/substrate/runtime/probes.d.mts +7 -5
- package/dist/substrate/runtime/probes.mjs +3 -1
- package/dist/substrate/runtime/probes.mjs.map +1 -1
- package/dist/substrate/runtime/projection/index.mjs +4 -0
- package/dist/substrate/runtime/projection/operational-endpoints.mjs +1 -2
- package/dist/substrate/runtime/projection/operational-endpoints.mjs.map +1 -1
- package/dist/substrate/runtime/projection/persisted.mjs +33 -15
- package/dist/substrate/runtime/projection/persisted.mjs.map +1 -1
- package/dist/substrate/runtime/projection/state-ref.mjs +26 -2
- package/dist/substrate/runtime/projection/state-ref.mjs.map +1 -1
- package/dist/substrate/runtime/projection/update.mjs +88 -24
- package/dist/substrate/runtime/projection/update.mjs.map +1 -1
- package/dist/substrate/runtime/random-suffix.mjs +11 -0
- package/dist/substrate/runtime/random-suffix.mjs.map +1 -0
- package/dist/substrate/runtime/retry-policy.d.mts +59 -1
- package/dist/substrate/runtime/retry-policy.mjs +66 -1
- package/dist/substrate/runtime/retry-policy.mjs.map +1 -1
- package/dist/substrate/runtime/routed-url.d.mts +1 -0
- package/dist/substrate/runtime/routed-url.mjs +79 -0
- package/dist/substrate/runtime/routed-url.mjs.map +1 -0
- package/dist/substrate/runtime/runtime-decode.d.mts +1 -1
- package/dist/substrate/runtime/runtime-decode.mjs.map +1 -1
- package/dist/substrate/runtime/scoped-http-server.mjs +2 -3
- package/dist/substrate/runtime/scoped-http-server.mjs.map +1 -1
- package/dist/substrate/runtime/scoped-multimap/index.mjs +2 -0
- package/dist/substrate/runtime/scoped-multimap/service.mjs +52 -0
- package/dist/substrate/runtime/scoped-multimap/service.mjs.map +1 -0
- package/dist/substrate/runtime/scoped-ref-map/index.mjs +2 -0
- package/dist/substrate/runtime/scoped-ref-map/service.mjs +2 -2
- package/dist/substrate/runtime/scoped-ref-map/service.mjs.map +1 -1
- package/dist/substrate/runtime/stage-and-swap/index.mjs +72 -4
- package/dist/substrate/runtime/stage-and-swap/index.mjs.map +1 -1
- package/dist/substrate/runtime/state-store/index.d.mts +1 -0
- package/dist/substrate/runtime/state-store/index.mjs +3 -0
- package/dist/substrate/runtime/state-store/schema.d.mts +1 -0
- package/dist/substrate/runtime/state-store/schema.mjs +19 -14
- package/dist/substrate/runtime/state-store/schema.mjs.map +1 -1
- package/dist/substrate/runtime/state-store/service.d.mts +1 -0
- package/dist/substrate/runtime/state-store/service.mjs +145 -0
- package/dist/substrate/runtime/state-store/service.mjs.map +1 -0
- package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.d.mts +1 -0
- package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.mjs +33 -0
- package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.mjs.map +1 -0
- package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs +1 -1
- package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs.map +1 -1
- package/dist/substrate/runtime/strategy-registry/index.mjs +4 -0
- package/dist/substrate/runtime/strategy-registry/service.mjs +19 -33
- package/dist/substrate/runtime/strategy-registry/service.mjs.map +1 -1
- package/dist/substrate/runtime/subnet-broker.mjs +60 -0
- package/dist/substrate/runtime/subnet-broker.mjs.map +1 -0
- package/dist/substrate/runtime/sui-execute/index.d.mts +21 -1
- package/dist/substrate/runtime/sui-execute/index.mjs +84 -20
- package/dist/substrate/runtime/sui-execute/index.mjs.map +1 -1
- package/dist/substrate/runtime/sui-execute/sign-and-dispatch.d.mts +1 -0
- package/dist/substrate/runtime/sui-execute/sign-and-dispatch.mjs +32 -0
- package/dist/substrate/runtime/sui-execute/sign-and-dispatch.mjs.map +1 -0
- package/dist/substrate/runtime/sui-ledger/object-ref.mjs +32 -0
- package/dist/substrate/runtime/sui-ledger/object-ref.mjs.map +1 -0
- package/dist/substrate/runtime/sui-move-build/index.mjs +93 -19
- package/dist/substrate/runtime/sui-move-build/index.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/acquire-node.mjs +181 -0
- package/dist/substrate/runtime/supervisor/acquire-node.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/background-tasks.mjs +144 -0
- package/dist/substrate/runtime/supervisor/background-tasks.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/command-loop.mjs +68 -0
- package/dist/substrate/runtime/supervisor/command-loop.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs +151 -0
- package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/errors.d.mts +1 -0
- package/dist/substrate/runtime/supervisor/errors.mjs +9 -0
- package/dist/substrate/runtime/supervisor/errors.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/index.d.mts +1 -0
- package/dist/substrate/runtime/supervisor/index.mjs +3 -0
- package/dist/substrate/runtime/supervisor/shutdown.mjs +51 -0
- package/dist/substrate/runtime/supervisor/shutdown.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/start-supervisor.d.mts +1 -0
- package/dist/substrate/runtime/supervisor/start-supervisor.mjs +250 -0
- package/dist/substrate/runtime/supervisor/start-supervisor.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/state.d.mts +1 -0
- package/dist/substrate/runtime/supervisor/state.mjs +22 -0
- package/dist/substrate/runtime/supervisor/state.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/teardown.mjs +57 -0
- package/dist/substrate/runtime/supervisor/teardown.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/types.d.mts +1 -0
- package/dist/substrate/runtime/supervisor/wiring.mjs +133 -0
- package/dist/substrate/runtime/supervisor/wiring.mjs.map +1 -0
- package/dist/substrate/runtime/typed-env.mjs +8 -0
- package/dist/substrate/runtime/typed-env.mjs.map +1 -0
- package/dist/substrate/state-store.d.mts +1 -0
- package/dist/substrate/versioned-doc-schema.mjs +17 -0
- package/dist/substrate/versioned-doc-schema.mjs.map +1 -0
- package/dist/substrate/versioned-doc-sync.mjs +94 -0
- package/dist/substrate/versioned-doc-sync.mjs.map +1 -0
- package/dist/surfaces/cli/command-tree.mjs.map +1 -1
- package/dist/surfaces/cli/commands/index.mjs +9 -0
- package/dist/surfaces/cli/commands/prune-picker-entry.mjs +13 -0
- package/dist/surfaces/cli/commands/prune-picker-entry.mjs.map +1 -0
- package/dist/surfaces/cli/commands/prune-picker.mjs +3 -2
- package/dist/surfaces/cli/commands/prune-picker.mjs.map +1 -1
- package/dist/surfaces/cli/commands/prune.mjs +34 -17
- package/dist/surfaces/cli/commands/prune.mjs.map +1 -1
- package/dist/surfaces/cli/commands/status.mjs +2 -2
- package/dist/surfaces/cli/commands/status.mjs.map +1 -1
- package/dist/surfaces/cli/commands/supervisor-presence.mjs +5 -3
- package/dist/surfaces/cli/commands/supervisor-presence.mjs.map +1 -1
- package/dist/surfaces/cli/commands/wipe.mjs +38 -4
- package/dist/surfaces/cli/commands/wipe.mjs.map +1 -1
- package/dist/surfaces/cli/errors.mjs +1 -1
- package/dist/surfaces/cli/errors.mjs.map +1 -1
- package/dist/surfaces/cli/flags.mjs +0 -1
- package/dist/surfaces/cli/flags.mjs.map +1 -1
- package/dist/surfaces/cli/index.mjs +98 -18
- package/dist/surfaces/cli/index.mjs.map +1 -1
- package/dist/surfaces/cli/output.mjs +1 -0
- package/dist/surfaces/cli/output.mjs.map +1 -1
- package/dist/surfaces/cli/sysexits.mjs +2 -1
- package/dist/surfaces/cli/sysexits.mjs.map +1 -1
- package/dist/surfaces/tui/app.mjs +25 -3
- package/dist/surfaces/tui/app.mjs.map +1 -1
- package/dist/surfaces/tui/display-derivation.mjs +23 -74
- package/dist/surfaces/tui/display-derivation.mjs.map +1 -1
- package/dist/surfaces/tui/event-log.mjs +35 -23
- package/dist/surfaces/tui/event-log.mjs.map +1 -1
- package/dist/surfaces/tui/input.mjs +5 -1
- package/dist/surfaces/tui/input.mjs.map +1 -1
- package/dist/surfaces/tui/plain-renderer.mjs +70 -34
- package/dist/surfaces/tui/plain-renderer.mjs.map +1 -1
- package/package.json +24 -4
- package/dist/contracts/liveness-classifier.d.mts +0 -19
- package/dist/contracts/network-resolver.d.mts +0 -15
- package/dist/contracts/network-resolver.mjs +0 -7
- package/dist/contracts/network-resolver.mjs.map +0 -1
- package/dist/orchestrators/codegen/extras.mjs +0 -16
- package/dist/orchestrators/codegen/extras.mjs.map +0 -1
- package/dist/plugins/deepbook/routable.mjs +0 -21
- package/dist/plugins/deepbook/routable.mjs.map +0 -1
- package/dist/plugins/faucet/service.d.mts +0 -20
- package/dist/plugins/faucet/strategies/sui-local.d.mts +0 -23
- package/dist/plugins/faucet/strategies/sui-local.mjs.map +0 -1
- package/dist/plugins/sui/seed-objects.d.mts +0 -18
- package/dist/plugins/sui/seed-objects.mjs +0 -25
- package/dist/plugins/sui/seed-objects.mjs.map +0 -1
- package/dist/runtime/built-in-plugin-layers.mjs.map +0 -1
- package/dist/substrate/runtime/context-helpers.mjs +0 -32
- package/dist/substrate/runtime/context-helpers.mjs.map +0 -1
- package/dist/substrate/runtime/run.mjs.map +0 -1
- package/dist/substrate/runtime/strategy-registry/faucet-capability-for.mjs +0 -30
- package/dist/substrate/runtime/strategy-registry/faucet-capability-for.mjs.map +0 -1
- package/dist/substrate/runtime/supervisor.d.mts +0 -1
- package/dist/substrate/runtime/supervisor.mjs +0 -831
- package/dist/substrate/runtime/supervisor.mjs.map +0 -1
- package/dist/surfaces/cli/commands/doctor-probes.mjs.map +0 -1
- /package/dist/{substrate/runtime/strategy-registry/faucet-capability-for.d.mts → plugins/faucet/http.d.mts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fork-orchestration.mjs","names":[],"sources":["../../../src/plugins/sui/fork-orchestration.ts"],"sourcesContent":["// Fork-mode orchestration helpers.\n//\n// Owns the runtime SDK guard for surfaces the sui-fork binary panics\n// on. The data-dir lock + seed-manifest meta gate live in the\n// fork-mode builder once that wiring lands; they belong to the same\n// file once they have real implementations to anchor on.\n\nimport { forkUnsupportedError, type ForkUnsupportedError } from './errors.ts';\n\n/** Lock-holder identity persisted alongside the data-dir lock file.\n * Two fork acquires against the same data dir surface this; one\n * wins, the other gets an actionable error. */\nexport interface ForkLockHolder {\n\treadonly pid: number;\n\treadonly host: string;\n\treadonly instanceId: string;\n\treadonly startedAt: number;\n}\n\n/** On-disk seed-manifest snapshot. */\nexport interface ForkMeta {\n\treadonly version: number;\n\treadonly createdAt: number;\n\treadonly upstream: string;\n\treadonly checkpoint?: string;\n\t/** Lowercased + sorted (architecture invariant: configHash MUST\n\t * be stable across orderings). */\n\treadonly seedAddresses: ReadonlyArray<string>;\n\t/** Lowercased + sorted, same invariant. */\n\treadonly seedObjects: ReadonlyArray<string>;\n\t/** Digest of the above four fields. `autoTickMs` is NOT folded\n\t * in (architecture invariant). */\n\treadonly configHash: string;\n\treadonly runtime?: { readonly autoTickMs?: number };\n}\n\n/** Surfaces that the sui-fork binary explicitly panics on. New\n * upstream additions fail OPEN by default — architecture\n * invariant. */\nexport const FORK_UNSUPPORTED_SURFACES: ReadonlyArray<string> = [\n\t// `client.core.*` methods that hit `simulate_transaction` /\n\t// balance-derivation paths the fork binary doesn't implement.\n\t'getBalance',\n\t'listBalances',\n\t'getCoinInfo',\n] as const;\n\n/** Wrap a Sui SDK shim with the fork guard. Property access for a\n * blocklisted surface SYNCHRONOUSLY throws — the wire call never\n * happens, so the fork binary stays up. */\nexport type ForkGuardedSdk<Sdk extends { readonly core: object }> = Omit<Sdk, 'core'> & {\n\treadonly core: Sdk['core'];\n};\n\nexport const wrapWithForkGuard = <Sdk extends { readonly core: object }>(\n\tsdk: Sdk,\n): ForkGuardedSdk<Sdk> => {\n\tconst guardedCore = new Proxy(sdk.core as Record<string, unknown>, {\n\t\tget(target, prop, receiver) {\n\t\t\tif (typeof prop === 'string' && FORK_UNSUPPORTED_SURFACES.includes(prop)) {\n\t\t\t\tconst err: ForkUnsupportedError = forkUnsupportedError(\n\t\t\t\t\t`client.core.${prop}`,\n\t\t\t\t\t'fork mode does not implement this SDK surface — use the impersonation helper ' +\n\t\t\t\t\t\t'or read state via ChainProbe.',\n\t\t\t\t);\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t\treturn Reflect.get(target, prop, receiver);\n\t\t},\n\t}) as Sdk['core'];\n\t// Preserve all SDK fields (e.g. SuiSdkShim's opaque `client` for\n\t// Transaction.build) — only the `core` proxy intercepts; siblings\n\t// like `client` flow through unchanged.\n\treturn { ...sdk, core: guardedCore };\n};\n"],"mappings":";;;;;AAuCA,MAAa,4BAAmD;CAG/D;CACA;CACA;CACA;AASD,MAAa,qBACZ,QACyB;CACzB,MAAM,cAAc,IAAI,MAAM,IAAI,MAAiC,EAClE,IAAI,QAAQ,MAAM,UAAU;AAC3B,MAAI,OAAO,SAAS,YAAY,0BAA0B,SAAS,KAAK,CAMvE,OALkC,qBACjC,eAAe,QACf,6GAGQ;AAEV,SAAO,QAAQ,IAAI,QAAQ,MAAM,SAAS;IAE3C,CAAC;AAIF,QAAO;EAAE,GAAG;EAAK,MAAM;EAAa"}
|
|
1
|
+
{"version":3,"file":"fork-orchestration.mjs","names":["nodeHostname"],"sources":["../../../src/plugins/sui/fork-orchestration.ts"],"sourcesContent":["// Fork-mode orchestration helpers.\n//\n// Owns the runtime SDK guard for surfaces the sui-fork binary panics\n// on, plus the data-dir mutual-exclusion holder protocol (acquire /\n// heartbeat / release) that serializes two stacks against the same\n// `<stackRoot>/sui-fork/<key>` data dir — concurrent writers to a\n// single fork data dir corrupt the binary's RocksDB.\n\nimport { readFileSync, unlinkSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { hostname as nodeHostname } from 'node:os';\n\nimport { Effect, Schedule, Schema, type Scope } from 'effect';\n\nimport { atomicWriteJsonSync } from '../../substrate/runtime/atomic-write.ts';\nimport {\n\tacquireStackLock,\n\tisPidAlive,\n\tprocessStartTime,\n} from '../../substrate/runtime/cross-process/index.ts';\nimport { selfPid } from '../../substrate/runtime/cross-process/self-pid.ts';\nimport { mintRandomSuffix } from '../../substrate/runtime/random-suffix.ts';\nimport { SpanAttr } from '../../substrate/runtime/observability/spans.ts';\nimport { parseVersionedDocumentBodyOrNull } from '../../substrate/versioned-doc-sync.ts';\nimport {\n\tforkUnsupportedError,\n\tsuiPluginError,\n\ttype ForkUnsupportedError,\n\ttype SuiPluginError,\n} from './errors.ts';\n\n/** Lock-holder identity persisted alongside the data-dir lock file.\n * Two fork acquires against the same data dir surface this; one\n * wins, the other gets an actionable error. */\nexport interface ForkLockHolder {\n\treadonly pid: number;\n\treadonly host: string;\n\treadonly instanceId: string;\n\treadonly startedAt: number;\n\t/** FNV-1a hash of `ps -o lstart` for `pid`, captured at claim time\n\t * via the SAME `processStartTime` probe roster/liveness use. Lets\n\t * same-host liveness distinguish a LIVE holder from a recycled-PID\n\t * impostor (a crashed-then-reused pid). `null` when the platform\n\t * couldn't probe — treated conservatively (see `isForkHolderAlive`),\n\t * matching roster's `isOwnEntry` / `checkHolderLiveness` null policy. */\n\treadonly startTime: number | null;\n}\n\n// -----------------------------------------------------------------------------\n// Data-dir mutual-exclusion holder protocol\n// -----------------------------------------------------------------------------\n//\n// `acquireStackLock` is a HOLD-BRIEFLY primitive (it reclaims after\n// ~30s of staleness, so it must NOT be held for the fork's lifetime —\n// cross-process § \"the lock is held BRIEFLY\"). So the long-lived claim\n// on a fork data dir is a HOLDER FILE, mirroring the roster's\n// heartbeat + (pid, host) liveness pattern: we take the brief OS lock\n// only to serialize the read-holder → liveness-check → write-holder\n// critical section, then release it. A scope-bound fiber refreshes\n// `startedAt` on a cadence comfortably under the staleness window so\n// peers see we are alive; a finalizer removes the holder on teardown.\n\n/** Heartbeat cadence — refresh `startedAt` every 10s. Matches the\n * roster's `heartbeatIntervalMillis`. The heartbeat keeps the holder's\n * `startedAt`/`startTime` fresh for diagnostics and so a peer that DOES\n * later add a foreign-host liveness signal has recent data; with the\n * current conservative foreign-host policy (always-alive) it is not a\n * reclaim gate, mirroring the roster heartbeat fiber. */\nconst FORK_HOLDER_HEARTBEAT_INTERVAL_MILLIS = 10_000;\n\n/** Brief acquire timeout for the holder critical section. The OS lock\n * is held only across a read → liveness-check → write, never across\n * I/O — a tight budget keeps peers reacting quickly to a release. */\nconst FORK_HOLDER_LOCK_TIMEOUT_MILLIS = 5_000;\n\n// No `version` field by design. `parseVersionedDocumentBodyOrNull`\n// decodes the raw body against this schema and treats ANY decode miss\n// (including a future shape change) as `null` ⇒ \"no live holder\",\n// which the acquire path handles by reclaiming. Because the holder file\n// is transient (it lives inside the data dir and a wipe removes it —\n// see `forkHolderPath` below), a leftover old-shape body self-heals on\n// the next acquire rather than blocking it. This mirrors stack-lock's\n// precedent for short-lived holder files; persistent docs that must\n// survive a format change use `versionedDocSchema` with a bumped\n// version stamp instead.\nconst ForkLockHolderSchema = Schema.Struct({\n\tpid: Schema.Number,\n\thost: Schema.String,\n\tinstanceId: Schema.String,\n\tstartedAt: Schema.Number,\n\tstartTime: Schema.NullOr(Schema.Number),\n});\n\n/** Holder file lives inside the data dir so it travels with the dir's\n * lifecycle (wipe removes it). */\nexport const forkHolderPath = (dataDir: string): string => join(dataDir, 'holder.json');\n\n/** Is an existing holder alive? Mirrors `liveness.checkHolderLiveness`\n * exactly (the `RosterHolder` shape doesn't fit — that carries\n * `hostname`/`heartbeatAt`, not our `host`/`startedAt` — so we\n * replicate its logic against the `ForkLockHolder` fields):\n *\n * - Foreign-host → ALWAYS ALIVE. Cross-host pid comparison is\n * meaningless, and comparing our `Date.now()` to the holder's\n * `startedAt` (a different host's clock) is clock-skew-unsafe — a\n * >~20s skew on an NFS root could reclaim a LIVE foreign holder and\n * produce dual-writer RocksDB corruption. The NFS-safe trade is to\n * never auto-reclaim a foreign holder; a truly-abandoned one needs\n * manual cleanup (`rm <dataDir>/holder.json`).\n * - Same-host → pid must be live AND its start-time must match, so a\n * crashed-then-recycled pid (an abandoned dir whose pid the kernel\n * handed to an unrelated process) no longer reads as \"in use\".\n *\n * A `null` start-time on either side is handled conservatively the\n * same way roster does — ALIVE — because we have nothing to dispute\n * the recorded identity with (mismatching a probed stamp against a\n * recorded `null`, or vice versa, would falsely harvest a live\n * holder). */\nconst isForkHolderAlive = (holder: ForkLockHolder): boolean => {\n\tif (holder.host !== nodeHostname()) return true;\n\tif (!isPidAlive(holder.pid)) return false;\n\tconst probedStart = processStartTime(holder.pid);\n\tif (probedStart === null) return true;\n\tif (holder.startTime === null) return true;\n\treturn probedStart === holder.startTime;\n};\n\nconst readForkHolder = (path: string): ForkLockHolder | null =>\n\tparseVersionedDocumentBodyOrNull(\n\t\tsafeReadHolderRaw(path),\n\t\tForkLockHolderSchema,\n\t\t'sui-fork.holder',\n\t);\n\n/** Read the holder file's bytes, returning `''` (→ parses to null) on\n * any I/O error. A missing/unreadable holder means \"no live claim\";\n * the caller writes its own. Sync read is correct here — we are\n * inside the brief OS-lock critical section, same non-yielding\n * discipline as the cross-process roster reader. */\nconst safeReadHolderRaw = (path: string): string => {\n\ttry {\n\t\treturn readFileSync(path, 'utf8');\n\t} catch {\n\t\treturn '';\n\t}\n};\n\nconst ownForkHolder = (): ForkLockHolder => {\n\tconst pid = selfPid();\n\treturn {\n\t\tpid,\n\t\thost: nodeHostname(),\n\t\tinstanceId: mintRandomSuffix(8),\n\t\tstartedAt: Date.now(),\n\t\t// Same probe roster/liveness record at claim time — a `null`\n\t\t// (exotic platform / transient `ps` error) propagates verbatim so\n\t\t// the conservative null branch in `isForkHolderAlive` applies.\n\t\tstartTime: processStartTime(pid),\n\t};\n};\n\n/** Run `body` under a BRIEFLY-held `stack.lock`. The lock serializes\n * the holder file's read → liveness-check → write critical section so\n * two claimers never both decide the dir is free. Released the moment\n * `body` completes — never held across the fork's lifetime. */\nconst underStackLock = <A>(\n\tstackLockFile: string,\n\tholderPath: string,\n\tbody: Effect.Effect<A, SuiPluginError>,\n): Effect.Effect<A, SuiPluginError> =>\n\tEffect.scoped(\n\t\tEffect.gen(function* () {\n\t\t\tyield* acquireStackLock(stackLockFile, FORK_HOLDER_LOCK_TIMEOUT_MILLIS).pipe(\n\t\t\t\tEffect.mapError((cause) =>\n\t\t\t\t\tsuiPluginError(\n\t\t\t\t\t\t'fork-lock',\n\t\t\t\t\t\t`sui fork mode: failed to acquire stack lock for data dir ${holderPath}: ${cause._tag}`,\n\t\t\t\t\t\tcause,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn yield* body;\n\t\t}),\n\t);\n\n/** The brief critical section: under `stack.lock`, read any existing\n * holder; if a LIVE one is present, fail with an actionable error;\n * otherwise claim by writing our own holder atomically. Returns the\n * holder we wrote so the heartbeat fiber can refresh it. */\nconst claimForkHolder = (\n\tstackLockFile: string,\n\tholderPath: string,\n): Effect.Effect<ForkLockHolder, SuiPluginError> =>\n\tunderStackLock(\n\t\tstackLockFile,\n\t\tholderPath,\n\t\tEffect.gen(function* () {\n\t\t\tconst existing = readForkHolder(holderPath);\n\t\t\tif (existing !== null && isForkHolderAlive(existing)) {\n\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\tsuiPluginError(\n\t\t\t\t\t\t'fork-lock',\n\t\t\t\t\t\t`sui fork mode: fork data dir ${holderPath} is in use by pid ${existing.pid} on ` +\n\t\t\t\t\t\t\t`${existing.host}; stop that stack or use a different fork key.`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst self = ownForkHolder();\n\t\t\tyield* writeForkHolder(holderPath, self);\n\t\t\treturn self;\n\t\t}),\n\t);\n\n/** Heartbeat: under the brief lock, re-stamp `startedAt` IF the holder\n * on disk is still ours. A peer that reclaimed us (same-host recycled-\n * pid takeover) owns the file now; we must not clobber its claim, so a\n * mismatched `instanceId` makes this a no-op. */\nconst refreshForkHolder = (\n\tstackLockFile: string,\n\tholderPath: string,\n\tself: ForkLockHolder,\n): Effect.Effect<void, SuiPluginError> =>\n\tunderStackLock(\n\t\tstackLockFile,\n\t\tholderPath,\n\t\tEffect.gen(function* () {\n\t\t\tconst current = readForkHolder(holderPath);\n\t\t\tif (current !== null && current.instanceId !== self.instanceId) return;\n\t\t\tyield* writeForkHolder(holderPath, { ...self, startedAt: Date.now() });\n\t\t}),\n\t);\n\n/** Scope-finalizer release: unlink the holder file ONLY if it is still\n * ours. A finalizer that unconditionally `unlinkSync`d by path would,\n * after a legitimate same-host reclaim (our pid crashed-and-recycled,\n * a peer took over), delete the PEER's holder and unprotect a dir the\n * peer is actively writing. Re-reading and matching `instanceId` makes\n * the release a no-op once we no longer own the file. A missing/\n * unreadable holder is already-gone — also a no-op. Best-effort: a\n * crash that skips this is recovered by the next peer's same-host\n * liveness check. */\nconst releaseOwnForkHolder = (holderPath: string, self: ForkLockHolder): void => {\n\tconst current = readForkHolder(holderPath);\n\tif (current !== null && current.instanceId !== self.instanceId) return;\n\ttry {\n\t\tunlinkSync(holderPath);\n\t} catch {\n\t\t// Already gone — ok.\n\t}\n};\n\nconst writeForkHolder = (\n\tpath: string,\n\tholder: ForkLockHolder,\n): Effect.Effect<void, SuiPluginError> =>\n\tEffect.try({\n\t\ttry: () => atomicWriteJsonSync(path, holder),\n\t\tcatch: (cause) =>\n\t\t\tsuiPluginError(\n\t\t\t\t'fork-lock',\n\t\t\t\t`sui fork mode: failed to write fork data-dir holder ${path}.`,\n\t\t\t\tcause,\n\t\t\t),\n\t});\n\n/**\n * Acquire the data-dir holder for the lifetime of the surrounding\n * scope.\n *\n * 1. Briefly take `stack.lock`, read any existing holder, fail if a\n * live peer holds it, else write our own holder. Release the OS\n * lock immediately (the claim outlives the lock).\n * 2. Fork a scope-bound heartbeat fiber that re-takes the brief lock\n * every `FORK_HOLDER_HEARTBEAT_INTERVAL_MILLIS` and refreshes\n * `startedAt` (only while the file is still ours). A heartbeat\n * failure is non-fatal — log and retry next tick (same policy as\n * the roster heartbeat fiber).\n * 3. Register a finalizer that removes our holder file on scope\n * close (wipe / restart / Ctrl-C) — but ONLY if the on-disk holder\n * is still ours, so a legitimate peer reclaim is never clobbered.\n * A crash that skips the finalizer is recovered same-host by the\n * next peer's liveness check (foreign-host needs manual cleanup —\n * the NFS-safe trade in `isForkHolderAlive`).\n */\nexport const acquireForkDataDirHolder = (\n\tstackLockFile: string,\n\tdataDir: string,\n): Effect.Effect<ForkLockHolder, SuiPluginError, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst holderPath = forkHolderPath(dataDir);\n\t\tconst self = yield* claimForkHolder(stackLockFile, holderPath);\n\t\tyield* Effect.addFinalizer(() => Effect.sync(() => releaseOwnForkHolder(holderPath, self)));\n\t\tconst refresh = refreshForkHolder(stackLockFile, holderPath, self).pipe(\n\t\t\tEffect.catch((err) =>\n\t\t\t\tEffect.logWarning('sui fork data-dir holder heartbeat failed; next tick will retry').pipe(\n\t\t\t\t\tEffect.annotateLogs({\n\t\t\t\t\t\t[SpanAttr.phase]: err.phase,\n\t\t\t\t\t\t[SpanAttr.errorMessage]: err.message,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\t\tyield* refresh.pipe(\n\t\t\tEffect.repeat(Schedule.spaced(`${FORK_HOLDER_HEARTBEAT_INTERVAL_MILLIS} millis`)),\n\t\t\tEffect.forkScoped,\n\t\t);\n\t\treturn self;\n\t}).pipe(Effect.withSpan('devstack.plugin.sui.fork.acquireDataDirHolder'));\n\n/** Surfaces that the sui-fork binary explicitly panics on. New\n * upstream additions fail OPEN by default — architecture\n * invariant. */\nexport const FORK_UNSUPPORTED_SURFACES: ReadonlyArray<string> = [\n\t// `client.core.*` methods that hit `simulate_transaction` /\n\t// balance-derivation paths the fork binary doesn't implement.\n\t'getBalance',\n\t'listBalances',\n\t'getCoinInfo',\n] as const;\n\n/** Wrap a Sui SDK shim with the fork guard. Property access for a\n * blocklisted surface SYNCHRONOUSLY throws — the wire call never\n * happens, so the fork binary stays up. */\nexport const wrapWithForkGuard = <Sdk extends { readonly core: object }>(sdk: Sdk): Sdk => {\n\tconst guardedCore = new Proxy(sdk.core as Record<string, unknown>, {\n\t\tget(target, prop, receiver) {\n\t\t\tif (typeof prop === 'string' && FORK_UNSUPPORTED_SURFACES.includes(prop)) {\n\t\t\t\tconst err: ForkUnsupportedError = forkUnsupportedError(\n\t\t\t\t\t`client.core.${prop}`,\n\t\t\t\t\t'fork mode does not implement this SDK surface — use the impersonation helper ' +\n\t\t\t\t\t\t'or read state via ChainProbe.',\n\t\t\t\t);\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t\treturn Reflect.get(target, prop, receiver);\n\t\t},\n\t}) as Sdk['core'];\n\t// Preserve all SDK fields (e.g. SuiSdkShim's opaque `client` for\n\t// Transaction.build) — only the `core` proxy intercepts; siblings\n\t// like `client` flow through unchanged.\n\treturn { ...sdk, core: guardedCore };\n};\n"],"mappings":"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"}
|
|
@@ -1,10 +1,46 @@
|
|
|
1
1
|
import { suiPluginError } from "./errors.mjs";
|
|
2
|
+
import { formatUnknownError } from "../../substrate/runtime/format-unknown-error.mjs";
|
|
2
3
|
import { Effect } from "effect";
|
|
3
4
|
import { normalizeSuiAddress } from "@mysten/sui/utils";
|
|
4
5
|
import { Inputs, TransactionDataBuilder } from "@mysten/sui/transactions";
|
|
5
6
|
//#region src/plugins/sui/fork-transaction.ts
|
|
6
|
-
const FORK_IMPERSONATION_GAS_BUDGET =
|
|
7
|
+
const FORK_IMPERSONATION_GAS_BUDGET = 100000000n;
|
|
7
8
|
const FORK_IMPERSONATION_GAS_PRICE = 1000n;
|
|
9
|
+
/** Canonical SUI gas coin type used to filter `listCoins` when picking
|
|
10
|
+
* a gas/funding coin. Kept local so the sui plugin needn't depend on
|
|
11
|
+
* the account plugin's `SUI_FULL_COIN_TYPE`. */
|
|
12
|
+
const SUI_GAS_COIN_TYPE = "0x2::sui::SUI";
|
|
13
|
+
/** `listCoins` page size while scanning for a sufficient coin. */
|
|
14
|
+
const FORK_COIN_PAGE_SIZE = 50;
|
|
15
|
+
/** Paginate `owner`'s SUI coins and return the first whose balance covers
|
|
16
|
+
* `minBalanceMist` (with that balance), or `undefined` if none across all
|
|
17
|
+
* pages. `listCoins` is paginated and NOT balance-ordered, so a sufficient
|
|
18
|
+
* coin can sit behind dust on a later page — we must page, never sample
|
|
19
|
+
* page 1. Shared by gas selection and the fork faucet. */
|
|
20
|
+
const firstSufficientSuiCoin = async (client, owner, minBalanceMist) => {
|
|
21
|
+
let cursor = null;
|
|
22
|
+
do {
|
|
23
|
+
const page = await client.listCoins({
|
|
24
|
+
owner,
|
|
25
|
+
coinType: SUI_GAS_COIN_TYPE,
|
|
26
|
+
cursor,
|
|
27
|
+
limit: FORK_COIN_PAGE_SIZE
|
|
28
|
+
});
|
|
29
|
+
for (const candidate of page.objects) {
|
|
30
|
+
if (candidate.balance === void 0) continue;
|
|
31
|
+
const balanceMist = BigInt(candidate.balance);
|
|
32
|
+
if (balanceMist >= minBalanceMist) return {
|
|
33
|
+
coin: {
|
|
34
|
+
objectId: candidate.objectId,
|
|
35
|
+
version: String(candidate.version),
|
|
36
|
+
digest: candidate.digest
|
|
37
|
+
},
|
|
38
|
+
balanceMist
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
cursor = page.hasNextPage === true ? page.cursor ?? null : null;
|
|
42
|
+
} while (cursor !== null);
|
|
43
|
+
};
|
|
8
44
|
const prepareForkImpersonationTransaction = (tx, sender, gasPayment) => {
|
|
9
45
|
tx.setSender(sender);
|
|
10
46
|
tx.setGasBudget(FORK_IMPERSONATION_GAS_BUDGET);
|
|
@@ -13,16 +49,20 @@ const prepareForkImpersonationTransaction = (tx, sender, gasPayment) => {
|
|
|
13
49
|
tx.setGasPayment([...gasPayment]);
|
|
14
50
|
if (tx.getData().expiration == null) tx.setExpiration({ None: true });
|
|
15
51
|
};
|
|
16
|
-
const buildForkImpersonationTransactionBytes = (tx, sender, client) => Effect.tryPromise({
|
|
52
|
+
const buildForkImpersonationTransactionBytes = (tx, sender, client, gasCoin) => Effect.tryPromise({
|
|
17
53
|
try: async () => {
|
|
18
|
-
prepareForkImpersonationTransaction(tx, sender, await selectForkImpersonationGasPayment(client, sender));
|
|
54
|
+
prepareForkImpersonationTransaction(tx, sender, gasCoin !== void 0 ? [gasCoin] : await selectForkImpersonationGasPayment(client, sender));
|
|
19
55
|
await tx.prepareForSerialization({});
|
|
20
56
|
const data = tx.getData();
|
|
21
57
|
data.inputs = await Promise.all(data.inputs.map((input) => resolveForkInput(input, client)));
|
|
22
58
|
return TransactionDataBuilder.restore(data).build();
|
|
23
59
|
},
|
|
24
|
-
catch: (cause) =>
|
|
60
|
+
catch: (cause) => {
|
|
61
|
+
if (isSuiPluginError(cause)) return cause;
|
|
62
|
+
return suiPluginError("fork-impersonate", `sui fork mode: failed to build fork impersonation transaction for ${sender}: ${formatUnknownError(cause)}`, cause);
|
|
63
|
+
}
|
|
25
64
|
});
|
|
65
|
+
const isSuiPluginError = (value) => typeof value === "object" && value !== null && value._tag === "SuiPluginError";
|
|
26
66
|
const resolveForkInput = async (input, client) => {
|
|
27
67
|
if (input.UnresolvedObject === void 0) return input;
|
|
28
68
|
const unresolved = input.UnresolvedObject;
|
|
@@ -51,9 +91,16 @@ const resolveForkInput = async (input, client) => {
|
|
|
51
91
|
};
|
|
52
92
|
const objectFromGetObjectResponse = (response) => {
|
|
53
93
|
const object = response.object;
|
|
54
|
-
if (typeof object !== "object" || object === null) throw
|
|
94
|
+
if (typeof object !== "object" || object === null) throw suiPluginError("fork-impersonate", "sui fork mode: getObject returned no object", { responseKeys: describeKeys(response) });
|
|
55
95
|
const candidate = object;
|
|
56
|
-
if (typeof candidate.objectId !== "string" || typeof candidate.version !== "string" || typeof candidate.digest !== "string") throw
|
|
96
|
+
if (typeof candidate.objectId !== "string" || typeof candidate.version !== "string" || typeof candidate.digest !== "string") throw suiPluginError("fork-impersonate", "sui fork mode: getObject returned incomplete object ref", {
|
|
97
|
+
objectKeys: describeKeys(object),
|
|
98
|
+
missing: {
|
|
99
|
+
objectId: typeof candidate.objectId !== "string",
|
|
100
|
+
version: typeof candidate.version !== "string",
|
|
101
|
+
digest: typeof candidate.digest !== "string"
|
|
102
|
+
}
|
|
103
|
+
});
|
|
57
104
|
return {
|
|
58
105
|
objectId: candidate.objectId,
|
|
59
106
|
version: candidate.version,
|
|
@@ -62,35 +109,52 @@ const objectFromGetObjectResponse = (response) => {
|
|
|
62
109
|
};
|
|
63
110
|
};
|
|
64
111
|
const selectForkImpersonationGasPayment = async (client, sender) => {
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
return [
|
|
71
|
-
objectId: coin.objectId,
|
|
72
|
-
version: String(coin.version),
|
|
73
|
-
digest: coin.digest
|
|
74
|
-
}];
|
|
112
|
+
const found = await firstSufficientSuiCoin(client, sender, FORK_IMPERSONATION_GAS_BUDGET);
|
|
113
|
+
if (found === void 0) throw suiPluginError("fork-impersonate", `sui fork mode: no SUI coin >= ${FORK_IMPERSONATION_GAS_BUDGET} MIST (gas budget) found for ${sender}.`, {
|
|
114
|
+
sender,
|
|
115
|
+
requiredMist: FORK_IMPERSONATION_GAS_BUDGET.toString()
|
|
116
|
+
});
|
|
117
|
+
return [found.coin];
|
|
75
118
|
};
|
|
119
|
+
/** Find a SUI coin owned by `owner` that covers `minBalanceMist`, for use as
|
|
120
|
+
* BOTH gas payment and the `splitCoins(tx.gas, …)` funding source in a fork
|
|
121
|
+
* faucet transfer. Paginates the coin set (a sufficient coin can sit behind
|
|
122
|
+
* dust on a later page) and returns the first that qualifies. Fails with an
|
|
123
|
+
* actionable `SuiPluginError` when none exists — reused at boot to validate a
|
|
124
|
+
* configured whale before any funding runs. */
|
|
125
|
+
const selectSufficientForkCoin = (client, owner, minBalanceMist) => Effect.tryPromise({
|
|
126
|
+
try: async () => {
|
|
127
|
+
const found = await firstSufficientSuiCoin(client, owner, minBalanceMist);
|
|
128
|
+
if (found === void 0) throw suiPluginError("fork-impersonate", `sui fork mode: no SUI coin >= ${minBalanceMist} MIST (request + gas budget) found for ${owner}. Use a fork faucet whale with a larger single coin, or fund a smaller amount.`, {
|
|
129
|
+
owner,
|
|
130
|
+
requiredMist: minBalanceMist.toString()
|
|
131
|
+
});
|
|
132
|
+
return found;
|
|
133
|
+
},
|
|
134
|
+
catch: (cause) => {
|
|
135
|
+
if (isSuiPluginError(cause)) return cause;
|
|
136
|
+
return suiPluginError("fork-impersonate", `sui fork mode: failed to select a SUI coin for ${owner}: ${formatUnknownError(cause)}`, cause);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
76
139
|
const verifyForkImpersonationSender = (sender, txBytes) => Effect.try({
|
|
77
140
|
try: () => {
|
|
78
141
|
const actual = TransactionDataBuilder.fromBytes(txBytes).snapshot().sender;
|
|
79
|
-
if (actual == null) throw
|
|
80
|
-
if (normalizeSuiAddress(actual) !== normalizeSuiAddress(sender)) throw
|
|
142
|
+
if (actual == null) throw suiPluginError("fork-impersonate", "sui fork mode: refused impersonation transaction — transaction has no sender", { expectedSender: sender });
|
|
143
|
+
if (normalizeSuiAddress(actual) !== normalizeSuiAddress(sender)) throw suiPluginError("fork-impersonate", "sui fork mode: refused impersonation transaction — sender mismatch", {
|
|
144
|
+
expectedSender: sender,
|
|
145
|
+
actualSender: actual
|
|
146
|
+
});
|
|
81
147
|
},
|
|
82
|
-
catch: (cause) =>
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (cause instanceof Error) return cause.message;
|
|
86
|
-
if (typeof cause === "string") return cause;
|
|
87
|
-
try {
|
|
88
|
-
return JSON.stringify(cause);
|
|
89
|
-
} catch {
|
|
90
|
-
return String(cause);
|
|
148
|
+
catch: (cause) => {
|
|
149
|
+
if (isSuiPluginError(cause)) return cause;
|
|
150
|
+
return suiPluginError("fork-impersonate", `sui fork mode: refused impersonation transaction: ${formatUnknownError(cause)}`, cause);
|
|
91
151
|
}
|
|
152
|
+
});
|
|
153
|
+
const describeKeys = (value) => {
|
|
154
|
+
if (typeof value !== "object" || value === null) return [];
|
|
155
|
+
return Object.keys(value);
|
|
92
156
|
};
|
|
93
157
|
//#endregion
|
|
94
|
-
export { buildForkImpersonationTransactionBytes, verifyForkImpersonationSender };
|
|
158
|
+
export { FORK_IMPERSONATION_GAS_BUDGET, FORK_IMPERSONATION_GAS_PRICE, buildForkImpersonationTransactionBytes, prepareForkImpersonationTransaction, selectSufficientForkCoin, verifyForkImpersonationSender };
|
|
95
159
|
|
|
96
160
|
//# sourceMappingURL=fork-transaction.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fork-transaction.mjs","names":[],"sources":["../../../src/plugins/sui/fork-transaction.ts"],"sourcesContent":["import { Effect } from 'effect';\n\nimport {\n\tInputs,\n\tTransaction,\n\tTransactionDataBuilder,\n\ttype CallArg,\n} from '@mysten/sui/transactions';\nimport { normalizeSuiAddress } from '@mysten/sui/utils';\n\nimport { suiPluginError, type SuiPluginError } from './errors.ts';\n\nexport const FORK_IMPERSONATION_GAS_BUDGET = 1_000_000_000n;\nexport const FORK_IMPERSONATION_GAS_PRICE = 1_000n;\n\ninterface ForkImpersonationGasClient {\n\treadonly getObject: (input: { readonly objectId: string }) => Promise<unknown>;\n\treadonly listCoins: (input: {\n\t\treadonly owner: string;\n\t\treadonly coinType?: string;\n\t\treadonly limit?: number;\n\t}) => Promise<{\n\t\treadonly objects: ReadonlyArray<{\n\t\t\treadonly objectId: string;\n\t\t\treadonly version: string | number | bigint;\n\t\t\treadonly digest: string;\n\t\t\treadonly balance?: string | number | bigint;\n\t\t}>;\n\t}>;\n}\n\nexport const prepareForkImpersonationTransaction = (\n\ttx: Transaction,\n\tsender: string,\n\tgasPayment: ReadonlyArray<{\n\t\treadonly objectId: string;\n\t\treadonly version: string;\n\t\treadonly digest: string;\n\t}>,\n): void => {\n\ttx.setSender(sender);\n\n\ttx.setGasBudget(FORK_IMPERSONATION_GAS_BUDGET);\n\ttx.setGasPrice(FORK_IMPERSONATION_GAS_PRICE);\n\ttx.setGasOwner(sender);\n\ttx.setGasPayment([...gasPayment]);\n\n\tconst data = tx.getData();\n\tif (data.expiration == null) tx.setExpiration({ None: true });\n};\n\nexport const buildForkImpersonationTransactionBytes = (\n\ttx: Transaction,\n\tsender: string,\n\tclient: ForkImpersonationGasClient,\n): Effect.Effect<Uint8Array, SuiPluginError> =>\n\tEffect.tryPromise({\n\t\ttry: async () => {\n\t\t\tconst gasPayment = await selectForkImpersonationGasPayment(client, sender);\n\t\t\tprepareForkImpersonationTransaction(tx, sender, gasPayment);\n\t\t\tawait tx.prepareForSerialization({});\n\t\t\tconst data = tx.getData();\n\t\t\tdata.inputs = await Promise.all(data.inputs.map((input) => resolveForkInput(input, client)));\n\t\t\treturn TransactionDataBuilder.restore(data).build();\n\t\t},\n\t\tcatch: (cause) =>\n\t\t\tsuiPluginError(\n\t\t\t\t'fork-impersonate',\n\t\t\t\t`sui fork mode: failed to build fork impersonation transaction for ${sender}: ${stringifyCause(cause)}`,\n\t\t\t\tcause,\n\t\t\t),\n\t});\n\nconst resolveForkInput = async (\n\tinput: CallArg,\n\tclient: ForkImpersonationGasClient,\n): Promise<CallArg> => {\n\tif (input.UnresolvedObject === undefined) return input;\n\tconst unresolved = input.UnresolvedObject;\n\tif (unresolved.initialSharedVersion != null) {\n\t\treturn Inputs.SharedObjectRef({\n\t\t\tobjectId: unresolved.objectId,\n\t\t\tinitialSharedVersion: unresolved.initialSharedVersion,\n\t\t\tmutable: unresolved.mutable ?? true,\n\t\t});\n\t}\n\tif (unresolved.version != null && unresolved.digest != null) {\n\t\treturn Inputs.ObjectRef({\n\t\t\tobjectId: unresolved.objectId,\n\t\t\tversion: unresolved.version,\n\t\t\tdigest: unresolved.digest,\n\t\t});\n\t}\n\n\tconst object = objectFromGetObjectResponse(\n\t\tawait client.getObject({ objectId: unresolved.objectId }),\n\t);\n\tconst owner = object.owner;\n\tif (owner?.$kind === 'Shared' && owner.Shared !== undefined) {\n\t\treturn Inputs.SharedObjectRef({\n\t\t\tobjectId: object.objectId,\n\t\t\tinitialSharedVersion: owner.Shared.initialSharedVersion,\n\t\t\tmutable: unresolved.mutable ?? true,\n\t\t});\n\t}\n\treturn Inputs.ObjectRef({\n\t\tobjectId: object.objectId,\n\t\tversion: object.version,\n\t\tdigest: object.digest,\n\t});\n};\n\nconst objectFromGetObjectResponse = (\n\tresponse: unknown,\n): {\n\treadonly objectId: string;\n\treadonly version: string;\n\treadonly digest: string;\n\treadonly owner?: {\n\t\treadonly $kind?: string;\n\t\treadonly Shared?: { readonly initialSharedVersion: string };\n\t};\n} => {\n\tconst object = (response as { readonly object?: unknown }).object;\n\tif (typeof object !== 'object' || object === null) {\n\t\tthrow new Error(`getObject returned no object: ${JSON.stringify(response)}`);\n\t}\n\tconst candidate = object as {\n\t\treadonly objectId?: unknown;\n\t\treadonly version?: unknown;\n\t\treadonly digest?: unknown;\n\t\treadonly owner?: {\n\t\t\treadonly $kind?: string;\n\t\t\treadonly Shared?: { readonly initialSharedVersion: string };\n\t\t};\n\t};\n\tif (\n\t\ttypeof candidate.objectId !== 'string' ||\n\t\ttypeof candidate.version !== 'string' ||\n\t\ttypeof candidate.digest !== 'string'\n\t) {\n\t\tthrow new Error(`getObject returned incomplete object ref: ${JSON.stringify(response)}`);\n\t}\n\treturn {\n\t\tobjectId: candidate.objectId,\n\t\tversion: candidate.version,\n\t\tdigest: candidate.digest,\n\t\towner: candidate.owner,\n\t};\n};\n\nconst selectForkImpersonationGasPayment = async (\n\tclient: ForkImpersonationGasClient,\n\tsender: string,\n): Promise<\n\tReadonlyArray<{ readonly objectId: string; readonly version: string; readonly digest: string }>\n> => {\n\tconst response = await client.listCoins({ owner: sender, limit: 1 });\n\tconst coin = response.objects[0];\n\tif (coin === undefined) {\n\t\tthrow new Error(`no SUI gas coins found for ${sender}`);\n\t}\n\treturn [\n\t\t{\n\t\t\tobjectId: coin.objectId,\n\t\t\tversion: String(coin.version),\n\t\t\tdigest: coin.digest,\n\t\t},\n\t];\n};\n\nexport const verifyForkImpersonationSender = (\n\tsender: string,\n\ttxBytes: Uint8Array,\n): Effect.Effect<void, SuiPluginError> =>\n\tEffect.try({\n\t\ttry: () => {\n\t\t\tconst actual = TransactionDataBuilder.fromBytes(txBytes).snapshot().sender;\n\t\t\tif (actual == null) {\n\t\t\t\tthrow new Error('transaction has no sender');\n\t\t\t}\n\t\t\tif (normalizeSuiAddress(actual) !== normalizeSuiAddress(sender)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`transaction sender ${actual} does not match impersonated sender ${sender}`,\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\tcatch: (cause) =>\n\t\t\tsuiPluginError(\n\t\t\t\t'fork-impersonate',\n\t\t\t\t`sui fork mode: refused impersonation transaction: ${stringifyCause(cause)}`,\n\t\t\t\tcause,\n\t\t\t),\n\t});\n\nconst stringifyCause = (cause: unknown): string => {\n\tif (cause instanceof Error) return cause.message;\n\tif (typeof cause === 'string') return cause;\n\ttry {\n\t\treturn JSON.stringify(cause);\n\t} catch {\n\t\treturn String(cause);\n\t}\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"fork-transaction.mjs","names":[],"sources":["../../../src/plugins/sui/fork-transaction.ts"],"sourcesContent":["import { Effect } from 'effect';\n\nimport {\n\tInputs,\n\tTransaction,\n\tTransactionDataBuilder,\n\ttype CallArg,\n} from '@mysten/sui/transactions';\nimport { normalizeSuiAddress } from '@mysten/sui/utils';\n\nimport { suiPluginError, type SuiPluginError } from './errors.ts';\nimport { formatUnknownError } from '../../substrate/runtime/format-unknown-error.ts';\n\n// 0.1 SUI. Deliberately well below the faucet's default per-account fund\n// (1 SUI) so a faucet-funded account keeps headroom to move value:\n// `setGasBudget` reserves the whole gas coin, so a budget equal to the\n// coin balance leaves nothing for `splitCoins(tx.gas, …)` / transfers\n// (InsufficientCoinBalance). 0.1 SUI still covers package publishes.\nexport const FORK_IMPERSONATION_GAS_BUDGET = 100_000_000n;\nexport const FORK_IMPERSONATION_GAS_PRICE = 1_000n;\n\n/** Canonical SUI gas coin type used to filter `listCoins` when picking\n * a gas/funding coin. Kept local so the sui plugin needn't depend on\n * the account plugin's `SUI_FULL_COIN_TYPE`. */\nconst SUI_GAS_COIN_TYPE = '0x2::sui::SUI';\n\n/** `listCoins` page size while scanning for a sufficient coin. */\nconst FORK_COIN_PAGE_SIZE = 50;\n\n/** An object ref usable as gas payment for an impersonation transaction. */\nexport interface ForkGasCoin {\n\treadonly objectId: string;\n\treadonly version: string;\n\treadonly digest: string;\n}\n\nexport interface ForkImpersonationGasClient {\n\treadonly getObject: (input: { readonly objectId: string }) => Promise<unknown>;\n\treadonly listCoins: (input: {\n\t\treadonly owner: string;\n\t\treadonly coinType?: string;\n\t\treadonly limit?: number;\n\t\treadonly cursor?: string | null;\n\t}) => Promise<{\n\t\treadonly objects: ReadonlyArray<{\n\t\t\treadonly objectId: string;\n\t\t\treadonly version: string | number | bigint;\n\t\t\treadonly digest: string;\n\t\t\treadonly balance?: string | number | bigint;\n\t\t}>;\n\t\treadonly hasNextPage?: boolean;\n\t\treadonly cursor?: string | null;\n\t}>;\n}\n\n/** Paginate `owner`'s SUI coins and return the first whose balance covers\n * `minBalanceMist` (with that balance), or `undefined` if none across all\n * pages. `listCoins` is paginated and NOT balance-ordered, so a sufficient\n * coin can sit behind dust on a later page — we must page, never sample\n * page 1. Shared by gas selection and the fork faucet. */\nconst firstSufficientSuiCoin = async (\n\tclient: ForkImpersonationGasClient,\n\towner: string,\n\tminBalanceMist: bigint,\n): Promise<{ readonly coin: ForkGasCoin; readonly balanceMist: bigint } | undefined> => {\n\tlet cursor: string | null = null;\n\tdo {\n\t\tconst page = await client.listCoins({\n\t\t\towner,\n\t\t\tcoinType: SUI_GAS_COIN_TYPE,\n\t\t\tcursor,\n\t\t\tlimit: FORK_COIN_PAGE_SIZE,\n\t\t});\n\t\tfor (const candidate of page.objects) {\n\t\t\tif (candidate.balance === undefined) continue;\n\t\t\tconst balanceMist = BigInt(candidate.balance);\n\t\t\tif (balanceMist >= minBalanceMist) {\n\t\t\t\treturn {\n\t\t\t\t\tcoin: {\n\t\t\t\t\t\tobjectId: candidate.objectId,\n\t\t\t\t\t\tversion: String(candidate.version),\n\t\t\t\t\t\tdigest: candidate.digest,\n\t\t\t\t\t},\n\t\t\t\t\tbalanceMist,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tcursor = page.hasNextPage === true ? (page.cursor ?? null) : null;\n\t} while (cursor !== null);\n\treturn undefined;\n};\n\nexport const prepareForkImpersonationTransaction = (\n\ttx: Transaction,\n\tsender: string,\n\tgasPayment: ReadonlyArray<{\n\t\treadonly objectId: string;\n\t\treadonly version: string;\n\t\treadonly digest: string;\n\t}>,\n): void => {\n\ttx.setSender(sender);\n\n\ttx.setGasBudget(FORK_IMPERSONATION_GAS_BUDGET);\n\ttx.setGasPrice(FORK_IMPERSONATION_GAS_PRICE);\n\ttx.setGasOwner(sender);\n\ttx.setGasPayment([...gasPayment]);\n\n\tconst data = tx.getData();\n\tif (data.expiration == null) tx.setExpiration({ None: true });\n};\n\nexport const buildForkImpersonationTransactionBytes = (\n\ttx: Transaction,\n\tsender: string,\n\tclient: ForkImpersonationGasClient,\n\t/** Pre-selected gas coin. When omitted, the first coin owned by\n\t * `sender` is used (legacy behaviour). The fork faucet passes the\n\t * whale's gas coin via {@link selectSufficientForkCoin} so a\n\t * `splitCoins(tx.gas, …)` funding transfer has enough balance. */\n\tgasCoin?: ForkGasCoin,\n): Effect.Effect<Uint8Array, SuiPluginError> =>\n\tEffect.tryPromise({\n\t\ttry: async () => {\n\t\t\tconst gasPayment =\n\t\t\t\tgasCoin !== undefined ? [gasCoin] : await selectForkImpersonationGasPayment(client, sender);\n\t\t\tprepareForkImpersonationTransaction(tx, sender, gasPayment);\n\t\t\tawait tx.prepareForSerialization({});\n\t\t\tconst data = tx.getData();\n\t\t\tdata.inputs = await Promise.all(data.inputs.map((input) => resolveForkInput(input, client)));\n\t\t\treturn TransactionDataBuilder.restore(data).build();\n\t\t},\n\t\tcatch: (cause) => {\n\t\t\t// Pass through pre-tagged SuiPluginError (thrown by inner\n\t\t\t// helpers with structured response fields) so we don't\n\t\t\t// double-wrap or stringify-leak the response payload.\n\t\t\tif (isSuiPluginError(cause)) return cause;\n\t\t\treturn suiPluginError(\n\t\t\t\t'fork-impersonate',\n\t\t\t\t`sui fork mode: failed to build fork impersonation transaction for ${sender}: ${formatUnknownError(cause)}`,\n\t\t\t\tcause,\n\t\t\t);\n\t\t},\n\t});\n\nconst isSuiPluginError = (value: unknown): value is SuiPluginError =>\n\ttypeof value === 'object' &&\n\tvalue !== null &&\n\t(value as { _tag?: unknown })._tag === 'SuiPluginError';\n\nconst resolveForkInput = async (\n\tinput: CallArg,\n\tclient: ForkImpersonationGasClient,\n): Promise<CallArg> => {\n\tif (input.UnresolvedObject === undefined) return input;\n\tconst unresolved = input.UnresolvedObject;\n\tif (unresolved.initialSharedVersion != null) {\n\t\treturn Inputs.SharedObjectRef({\n\t\t\tobjectId: unresolved.objectId,\n\t\t\tinitialSharedVersion: unresolved.initialSharedVersion,\n\t\t\tmutable: unresolved.mutable ?? true,\n\t\t});\n\t}\n\tif (unresolved.version != null && unresolved.digest != null) {\n\t\treturn Inputs.ObjectRef({\n\t\t\tobjectId: unresolved.objectId,\n\t\t\tversion: unresolved.version,\n\t\t\tdigest: unresolved.digest,\n\t\t});\n\t}\n\n\tconst object = objectFromGetObjectResponse(\n\t\tawait client.getObject({ objectId: unresolved.objectId }),\n\t);\n\tconst owner = object.owner;\n\tif (owner?.$kind === 'Shared' && owner.Shared !== undefined) {\n\t\treturn Inputs.SharedObjectRef({\n\t\t\tobjectId: object.objectId,\n\t\t\tinitialSharedVersion: owner.Shared.initialSharedVersion,\n\t\t\tmutable: unresolved.mutable ?? true,\n\t\t});\n\t}\n\treturn Inputs.ObjectRef({\n\t\tobjectId: object.objectId,\n\t\tversion: object.version,\n\t\tdigest: object.digest,\n\t});\n};\n\nconst objectFromGetObjectResponse = (\n\tresponse: unknown,\n): {\n\treadonly objectId: string;\n\treadonly version: string;\n\treadonly digest: string;\n\treadonly owner?: {\n\t\treadonly $kind?: string;\n\t\treadonly Shared?: { readonly initialSharedVersion: string };\n\t};\n} => {\n\tconst object = (response as { readonly object?: unknown }).object;\n\tif (typeof object !== 'object' || object === null) {\n\t\tthrow suiPluginError('fork-impersonate', 'sui fork mode: getObject returned no object', {\n\t\t\tresponseKeys: describeKeys(response),\n\t\t});\n\t}\n\tconst candidate = object as {\n\t\treadonly objectId?: unknown;\n\t\treadonly version?: unknown;\n\t\treadonly digest?: unknown;\n\t\treadonly owner?: {\n\t\t\treadonly $kind?: string;\n\t\t\treadonly Shared?: { readonly initialSharedVersion: string };\n\t\t};\n\t};\n\tif (\n\t\ttypeof candidate.objectId !== 'string' ||\n\t\ttypeof candidate.version !== 'string' ||\n\t\ttypeof candidate.digest !== 'string'\n\t) {\n\t\tthrow suiPluginError(\n\t\t\t'fork-impersonate',\n\t\t\t'sui fork mode: getObject returned incomplete object ref',\n\t\t\t{\n\t\t\t\tobjectKeys: describeKeys(object),\n\t\t\t\tmissing: {\n\t\t\t\t\tobjectId: typeof candidate.objectId !== 'string',\n\t\t\t\t\tversion: typeof candidate.version !== 'string',\n\t\t\t\t\tdigest: typeof candidate.digest !== 'string',\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}\n\treturn {\n\t\tobjectId: candidate.objectId,\n\t\tversion: candidate.version,\n\t\tdigest: candidate.digest,\n\t\towner: candidate.owner,\n\t};\n};\n\nconst selectForkImpersonationGasPayment = async (\n\tclient: ForkImpersonationGasClient,\n\tsender: string,\n): Promise<\n\tReadonlyArray<{ readonly objectId: string; readonly version: string; readonly digest: string }>\n> => {\n\t// The gas coin must cover the impersonation gas budget. Pick the first SUI\n\t// coin that does (paginating past dust) — not blindly `objects[0]`, which on\n\t// an account holding change coins may be below the budget → InsufficientGas\n\t// even though a larger coin exists.\n\tconst found = await firstSufficientSuiCoin(client, sender, FORK_IMPERSONATION_GAS_BUDGET);\n\tif (found === undefined) {\n\t\tthrow suiPluginError(\n\t\t\t'fork-impersonate',\n\t\t\t`sui fork mode: no SUI coin >= ${FORK_IMPERSONATION_GAS_BUDGET} MIST (gas budget) found for ${sender}.`,\n\t\t\t{ sender, requiredMist: FORK_IMPERSONATION_GAS_BUDGET.toString() },\n\t\t);\n\t}\n\treturn [found.coin];\n};\n\n/** Find a SUI coin owned by `owner` that covers `minBalanceMist`, for use as\n * BOTH gas payment and the `splitCoins(tx.gas, …)` funding source in a fork\n * faucet transfer. Paginates the coin set (a sufficient coin can sit behind\n * dust on a later page) and returns the first that qualifies. Fails with an\n * actionable `SuiPluginError` when none exists — reused at boot to validate a\n * configured whale before any funding runs. */\nexport const selectSufficientForkCoin = (\n\tclient: ForkImpersonationGasClient,\n\towner: string,\n\tminBalanceMist: bigint,\n): Effect.Effect<{ readonly coin: ForkGasCoin; readonly balanceMist: bigint }, SuiPluginError> =>\n\tEffect.tryPromise({\n\t\ttry: async () => {\n\t\t\tconst found = await firstSufficientSuiCoin(client, owner, minBalanceMist);\n\t\t\tif (found === undefined) {\n\t\t\t\tthrow suiPluginError(\n\t\t\t\t\t'fork-impersonate',\n\t\t\t\t\t`sui fork mode: no SUI coin >= ${minBalanceMist} MIST (request + gas budget) found for ` +\n\t\t\t\t\t\t`${owner}. Use a fork faucet whale with a larger single coin, or fund a smaller amount.`,\n\t\t\t\t\t{ owner, requiredMist: minBalanceMist.toString() },\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn found;\n\t\t},\n\t\tcatch: (cause) => {\n\t\t\tif (isSuiPluginError(cause)) return cause;\n\t\t\treturn suiPluginError(\n\t\t\t\t'fork-impersonate',\n\t\t\t\t`sui fork mode: failed to select a SUI coin for ${owner}: ${formatUnknownError(cause)}`,\n\t\t\t\tcause,\n\t\t\t);\n\t\t},\n\t});\n\nexport const verifyForkImpersonationSender = (\n\tsender: string,\n\ttxBytes: Uint8Array,\n): Effect.Effect<void, SuiPluginError> =>\n\tEffect.try({\n\t\ttry: () => {\n\t\t\tconst actual = TransactionDataBuilder.fromBytes(txBytes).snapshot().sender;\n\t\t\tif (actual == null) {\n\t\t\t\tthrow suiPluginError(\n\t\t\t\t\t'fork-impersonate',\n\t\t\t\t\t'sui fork mode: refused impersonation transaction — transaction has no sender',\n\t\t\t\t\t{ expectedSender: sender },\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (normalizeSuiAddress(actual) !== normalizeSuiAddress(sender)) {\n\t\t\t\tthrow suiPluginError(\n\t\t\t\t\t'fork-impersonate',\n\t\t\t\t\t'sui fork mode: refused impersonation transaction — sender mismatch',\n\t\t\t\t\t{ expectedSender: sender, actualSender: actual },\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\tcatch: (cause) => {\n\t\t\tif (isSuiPluginError(cause)) return cause;\n\t\t\treturn suiPluginError(\n\t\t\t\t'fork-impersonate',\n\t\t\t\t`sui fork mode: refused impersonation transaction: ${formatUnknownError(cause)}`,\n\t\t\t\tcause,\n\t\t\t);\n\t\t},\n\t});\n\nconst describeKeys = (value: unknown): ReadonlyArray<string> => {\n\tif (typeof value !== 'object' || value === null) return [];\n\treturn Object.keys(value);\n};\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ChainId } from "../../substrate/brand.mjs";
|
|
2
1
|
import { CodegenableDecl } from "../../contracts/codegenable.mjs";
|
|
2
|
+
import { ChainId } from "../../substrate/brand.mjs";
|
|
3
3
|
import { RoutableDecl } from "../../contracts/routable.mjs";
|
|
4
4
|
import { SnapshotableDecl } from "../../contracts/snapshotable.mjs";
|
|
5
5
|
import { StrategyContributorDecl } from "../../contracts/strategy-contributor.mjs";
|
|
@@ -8,27 +8,19 @@ import { ImageRef } from "../../contracts/container-runtime.mjs";
|
|
|
8
8
|
import { ModeNamespace } from "../../api/mode-narrowed-factory.mjs";
|
|
9
9
|
import { ChainProbe, ChainProbeError, ChainProbeMode } from "../../contracts/chain-probe.mjs";
|
|
10
10
|
import { SuiProbeKey, SuiSdkShim } from "./chain-probe.mjs";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { SeedObjectsAccumulator } from "./seed-objects.mjs";
|
|
14
|
-
import { ForkUnsupportedError, SeedManifestMismatchError, SuiCliError, SuiConfigError, SuiError, SuiFundsReadyError, SuiPluginError } from "./errors.mjs";
|
|
11
|
+
import { FaucetStrategy } from "../faucet/dispatcher.mjs";
|
|
12
|
+
import { ForkUnsupportedError, SuiCliError, SuiConfigError, SuiError, SuiPluginError } from "./errors.mjs";
|
|
15
13
|
import { ForkAdminSurface, SuiClient, WaitForTransactionsReady } from "./mode/shared.mjs";
|
|
16
14
|
import { SuiForkOptions, SuiLiveOptions, SuiLocalOptions, SuiLocalRpcOptions, SuiOptions, SuiPluginMode } from "./mode/spec.mjs";
|
|
17
|
-
import { FundsReadyError, FundsReadyStrategy } from "../../contracts/network-resolver.mjs";
|
|
18
15
|
import { ResolvedSuiNetwork } from "./network-resolver.mjs";
|
|
19
16
|
import { SuiNetworkBindings } from "./codegen.mjs";
|
|
20
|
-
import { Effect } from "effect";
|
|
21
|
-
|
|
22
17
|
//#region src/plugins/sui/index.d.ts
|
|
23
|
-
declare const fundingFaucetLeaseBrokerSymbol: unique symbol;
|
|
24
|
-
/** The Sui plugin's resource identity. The id is `'sui'` (singular). */
|
|
25
18
|
/** Local Sui shorthand. Network/env selection belongs to the CLI or
|
|
26
19
|
* `defineDevstackWith(...)`; plain `sui()` always means an in-stack
|
|
27
20
|
* local validator. */
|
|
28
21
|
declare const sui: (opts?: SuiOptions) => Plugin<"sui", {
|
|
29
|
-
mode: "local" | "
|
|
30
|
-
|
|
31
|
-
[fundingFaucetLeaseBrokerSymbol]: LeaseBroker;
|
|
22
|
+
mode: "local" | "live" | "fork" | "local-rpc";
|
|
23
|
+
fundingFaucetStrategy: FaucetStrategy | null;
|
|
32
24
|
sdk: SuiSdkShim;
|
|
33
25
|
rpcUrl: string;
|
|
34
26
|
faucetUrl: string | null;
|
|
@@ -49,9 +41,7 @@ declare const sui: (opts?: SuiOptions) => Plugin<"sui", {
|
|
|
49
41
|
capabilityKey: `faucet:request:${ChainId}`;
|
|
50
42
|
strategy: FaucetStrategy;
|
|
51
43
|
autoMounted: true;
|
|
52
|
-
}
|
|
53
|
-
readonly waitFundsReady: Effect.Effect<void, SuiPluginError>;
|
|
54
|
-
}> | StrategyContributorDecl<"sui:seed-objects", SeedObjectsAccumulator>)[]]>;
|
|
44
|
+
})[]]>;
|
|
55
45
|
/** Mode-narrowed factory namespace.
|
|
56
46
|
*
|
|
57
47
|
* Usage:
|
|
@@ -65,9 +55,8 @@ declare const sui: (opts?: SuiOptions) => Plugin<"sui", {
|
|
|
65
55
|
declare const suiFor: ModeNamespace<{
|
|
66
56
|
local: {
|
|
67
57
|
local: (opts?: Omit<SuiLocalOptions, "mode">) => Plugin<"sui", {
|
|
68
|
-
mode: "local" | "
|
|
69
|
-
|
|
70
|
-
[fundingFaucetLeaseBrokerSymbol]: LeaseBroker;
|
|
58
|
+
mode: "local" | "live" | "fork" | "local-rpc";
|
|
59
|
+
fundingFaucetStrategy: FaucetStrategy | null;
|
|
71
60
|
sdk: SuiSdkShim;
|
|
72
61
|
rpcUrl: string;
|
|
73
62
|
faucetUrl: string | null;
|
|
@@ -88,13 +77,10 @@ declare const suiFor: ModeNamespace<{
|
|
|
88
77
|
capabilityKey: `faucet:request:${ChainId}`;
|
|
89
78
|
strategy: FaucetStrategy;
|
|
90
79
|
autoMounted: true;
|
|
91
|
-
}
|
|
92
|
-
readonly waitFundsReady: Effect.Effect<void, SuiPluginError>;
|
|
93
|
-
}> | StrategyContributorDecl<"sui:seed-objects", SeedObjectsAccumulator>)[]]>;
|
|
80
|
+
})[]]>;
|
|
94
81
|
localRpc: (opts: Omit<SuiLocalRpcOptions, "mode">) => Plugin<"sui", {
|
|
95
|
-
mode: "local" | "
|
|
96
|
-
|
|
97
|
-
[fundingFaucetLeaseBrokerSymbol]: LeaseBroker;
|
|
82
|
+
mode: "local" | "live" | "fork" | "local-rpc";
|
|
83
|
+
fundingFaucetStrategy: FaucetStrategy | null;
|
|
98
84
|
sdk: SuiSdkShim;
|
|
99
85
|
rpcUrl: string;
|
|
100
86
|
faucetUrl: string | null;
|
|
@@ -115,15 +101,12 @@ declare const suiFor: ModeNamespace<{
|
|
|
115
101
|
capabilityKey: `faucet:request:${ChainId}`;
|
|
116
102
|
strategy: FaucetStrategy;
|
|
117
103
|
autoMounted: true;
|
|
118
|
-
}
|
|
119
|
-
readonly waitFundsReady: Effect.Effect<void, SuiPluginError>;
|
|
120
|
-
}> | StrategyContributorDecl<"sui:seed-objects", SeedObjectsAccumulator>)[]]>;
|
|
104
|
+
})[]]>;
|
|
121
105
|
};
|
|
122
106
|
live: {
|
|
123
107
|
testnet: (opts?: Omit<SuiLiveOptions, "mode" | "network">) => Plugin<"sui", {
|
|
124
|
-
mode: "local" | "
|
|
125
|
-
|
|
126
|
-
[fundingFaucetLeaseBrokerSymbol]: LeaseBroker;
|
|
108
|
+
mode: "local" | "live" | "fork" | "local-rpc";
|
|
109
|
+
fundingFaucetStrategy: FaucetStrategy | null;
|
|
127
110
|
sdk: SuiSdkShim;
|
|
128
111
|
rpcUrl: string;
|
|
129
112
|
faucetUrl: string | null;
|
|
@@ -144,13 +127,10 @@ declare const suiFor: ModeNamespace<{
|
|
|
144
127
|
capabilityKey: `faucet:request:${ChainId}`;
|
|
145
128
|
strategy: FaucetStrategy;
|
|
146
129
|
autoMounted: true;
|
|
147
|
-
}
|
|
148
|
-
readonly waitFundsReady: Effect.Effect<void, SuiPluginError>;
|
|
149
|
-
}> | StrategyContributorDecl<"sui:seed-objects", SeedObjectsAccumulator>)[]]>;
|
|
130
|
+
})[]]>;
|
|
150
131
|
mainnet: (opts?: Omit<SuiLiveOptions, "mode" | "network">) => Plugin<"sui", {
|
|
151
|
-
mode: "local" | "
|
|
152
|
-
|
|
153
|
-
[fundingFaucetLeaseBrokerSymbol]: LeaseBroker;
|
|
132
|
+
mode: "local" | "live" | "fork" | "local-rpc";
|
|
133
|
+
fundingFaucetStrategy: FaucetStrategy | null;
|
|
154
134
|
sdk: SuiSdkShim;
|
|
155
135
|
rpcUrl: string;
|
|
156
136
|
faucetUrl: string | null;
|
|
@@ -171,13 +151,10 @@ declare const suiFor: ModeNamespace<{
|
|
|
171
151
|
capabilityKey: `faucet:request:${ChainId}`;
|
|
172
152
|
strategy: FaucetStrategy;
|
|
173
153
|
autoMounted: true;
|
|
174
|
-
}
|
|
175
|
-
readonly waitFundsReady: Effect.Effect<void, SuiPluginError>;
|
|
176
|
-
}> | StrategyContributorDecl<"sui:seed-objects", SeedObjectsAccumulator>)[]]>;
|
|
154
|
+
})[]]>;
|
|
177
155
|
devnet: (opts?: Omit<SuiLiveOptions, "mode" | "network">) => Plugin<"sui", {
|
|
178
|
-
mode: "local" | "
|
|
179
|
-
|
|
180
|
-
[fundingFaucetLeaseBrokerSymbol]: LeaseBroker;
|
|
156
|
+
mode: "local" | "live" | "fork" | "local-rpc";
|
|
157
|
+
fundingFaucetStrategy: FaucetStrategy | null;
|
|
181
158
|
sdk: SuiSdkShim;
|
|
182
159
|
rpcUrl: string;
|
|
183
160
|
faucetUrl: string | null;
|
|
@@ -198,13 +175,10 @@ declare const suiFor: ModeNamespace<{
|
|
|
198
175
|
capabilityKey: `faucet:request:${ChainId}`;
|
|
199
176
|
strategy: FaucetStrategy;
|
|
200
177
|
autoMounted: true;
|
|
201
|
-
}
|
|
202
|
-
readonly waitFundsReady: Effect.Effect<void, SuiPluginError>;
|
|
203
|
-
}> | StrategyContributorDecl<"sui:seed-objects", SeedObjectsAccumulator>)[]]>;
|
|
178
|
+
})[]]>;
|
|
204
179
|
custom: (opts: Omit<SuiLiveOptions, "mode" | "network">) => Plugin<"sui", {
|
|
205
|
-
mode: "local" | "
|
|
206
|
-
|
|
207
|
-
[fundingFaucetLeaseBrokerSymbol]: LeaseBroker;
|
|
180
|
+
mode: "local" | "live" | "fork" | "local-rpc";
|
|
181
|
+
fundingFaucetStrategy: FaucetStrategy | null;
|
|
208
182
|
sdk: SuiSdkShim;
|
|
209
183
|
rpcUrl: string;
|
|
210
184
|
faucetUrl: string | null;
|
|
@@ -225,15 +199,12 @@ declare const suiFor: ModeNamespace<{
|
|
|
225
199
|
capabilityKey: `faucet:request:${ChainId}`;
|
|
226
200
|
strategy: FaucetStrategy;
|
|
227
201
|
autoMounted: true;
|
|
228
|
-
}
|
|
229
|
-
readonly waitFundsReady: Effect.Effect<void, SuiPluginError>;
|
|
230
|
-
}> | StrategyContributorDecl<"sui:seed-objects", SeedObjectsAccumulator>)[]]>;
|
|
202
|
+
})[]]>;
|
|
231
203
|
};
|
|
232
204
|
fork: {
|
|
233
205
|
mainnet: (opts?: Omit<SuiForkOptions, "mode" | "upstream">) => Plugin<"sui", {
|
|
234
|
-
mode: "local" | "
|
|
235
|
-
|
|
236
|
-
[fundingFaucetLeaseBrokerSymbol]: LeaseBroker;
|
|
206
|
+
mode: "local" | "live" | "fork" | "local-rpc";
|
|
207
|
+
fundingFaucetStrategy: FaucetStrategy | null;
|
|
237
208
|
sdk: SuiSdkShim;
|
|
238
209
|
rpcUrl: string;
|
|
239
210
|
faucetUrl: string | null;
|
|
@@ -254,13 +225,10 @@ declare const suiFor: ModeNamespace<{
|
|
|
254
225
|
capabilityKey: `faucet:request:${ChainId}`;
|
|
255
226
|
strategy: FaucetStrategy;
|
|
256
227
|
autoMounted: true;
|
|
257
|
-
}
|
|
258
|
-
readonly waitFundsReady: Effect.Effect<void, SuiPluginError>;
|
|
259
|
-
}> | StrategyContributorDecl<"sui:seed-objects", SeedObjectsAccumulator>)[]]>;
|
|
228
|
+
})[]]>;
|
|
260
229
|
testnet: (opts?: Omit<SuiForkOptions, "mode" | "upstream">) => Plugin<"sui", {
|
|
261
|
-
mode: "local" | "
|
|
262
|
-
|
|
263
|
-
[fundingFaucetLeaseBrokerSymbol]: LeaseBroker;
|
|
230
|
+
mode: "local" | "live" | "fork" | "local-rpc";
|
|
231
|
+
fundingFaucetStrategy: FaucetStrategy | null;
|
|
264
232
|
sdk: SuiSdkShim;
|
|
265
233
|
rpcUrl: string;
|
|
266
234
|
faucetUrl: string | null;
|
|
@@ -281,13 +249,10 @@ declare const suiFor: ModeNamespace<{
|
|
|
281
249
|
capabilityKey: `faucet:request:${ChainId}`;
|
|
282
250
|
strategy: FaucetStrategy;
|
|
283
251
|
autoMounted: true;
|
|
284
|
-
}
|
|
285
|
-
readonly waitFundsReady: Effect.Effect<void, SuiPluginError>;
|
|
286
|
-
}> | StrategyContributorDecl<"sui:seed-objects", SeedObjectsAccumulator>)[]]>;
|
|
252
|
+
})[]]>;
|
|
287
253
|
devnet: (opts?: Omit<SuiForkOptions, "mode" | "upstream">) => Plugin<"sui", {
|
|
288
|
-
mode: "local" | "
|
|
289
|
-
|
|
290
|
-
[fundingFaucetLeaseBrokerSymbol]: LeaseBroker;
|
|
254
|
+
mode: "local" | "live" | "fork" | "local-rpc";
|
|
255
|
+
fundingFaucetStrategy: FaucetStrategy | null;
|
|
291
256
|
sdk: SuiSdkShim;
|
|
292
257
|
rpcUrl: string;
|
|
293
258
|
faucetUrl: string | null;
|
|
@@ -308,9 +273,7 @@ declare const suiFor: ModeNamespace<{
|
|
|
308
273
|
capabilityKey: `faucet:request:${ChainId}`;
|
|
309
274
|
strategy: FaucetStrategy;
|
|
310
275
|
autoMounted: true;
|
|
311
|
-
}
|
|
312
|
-
readonly waitFundsReady: Effect.Effect<void, SuiPluginError>;
|
|
313
|
-
}> | StrategyContributorDecl<"sui:seed-objects", SeedObjectsAccumulator>)[]]>;
|
|
276
|
+
})[]]>;
|
|
314
277
|
};
|
|
315
278
|
}>;
|
|
316
279
|
//#endregion
|
|
@@ -1,31 +1,76 @@
|
|
|
1
1
|
import { definePlugin, resource } from "../../substrate/plugin.mjs";
|
|
2
|
-
import
|
|
2
|
+
import "../../api/define-plugin.mjs";
|
|
3
3
|
import { IdentityContext, StackPathsService } from "../../substrate/runtime/paths.mjs";
|
|
4
|
-
import { PortBrokerService } from "../../substrate/runtime/port-broker/service.mjs";
|
|
5
|
-
import { defineModeNamespace } from "../../api/mode-narrowed-factory.mjs";
|
|
6
|
-
import { FUNDS_READY_GATE_KEY } from "../../contracts/network-resolver.mjs";
|
|
7
|
-
import { chainProbeCapabilityKey } from "../../contracts/chain-probe.mjs";
|
|
8
4
|
import { ContainerRuntimeService } from "../../runtime/docker/service.mjs";
|
|
9
5
|
import { LeaseBrokerService } from "../../substrate/runtime/lease-broker/service.mjs";
|
|
6
|
+
import "../../substrate/runtime/lease-broker/index.mjs";
|
|
7
|
+
import { PortBrokerService } from "../../substrate/runtime/port-broker/service.mjs";
|
|
8
|
+
import "../../substrate/runtime/port-broker/index.mjs";
|
|
9
|
+
import { chainProbeCapabilityKey } from "../../contracts/chain-probe.mjs";
|
|
10
|
+
import { makeSuiForkRoutables, makeSuiLocalRoutables } from "./routable.mjs";
|
|
11
|
+
import { pluginErrorContributions } from "../../api/plugin-errors.mjs";
|
|
12
|
+
import { defineModeNamespace } from "../../api/mode-narrowed-factory.mjs";
|
|
10
13
|
import { makeCodegenable } from "./codegen.mjs";
|
|
11
14
|
import { makeSnapshotable } from "./snapshot.mjs";
|
|
12
|
-
import { SEED_OBJECTS_CAPABILITY_KEY, makeSeedObjectsAccumulator } from "./seed-objects.mjs";
|
|
13
15
|
import { SUI_ERROR_TAGS } from "./errors.mjs";
|
|
14
|
-
import
|
|
16
|
+
import "./spans.mjs";
|
|
15
17
|
import "./fork-orchestration.mjs";
|
|
18
|
+
import { selectSufficientForkCoin } from "./fork-transaction.mjs";
|
|
19
|
+
import { FORK_FAUCET_WHALE_MIN_COIN_MIST, resolveForkWhale } from "./mode/fork.mjs";
|
|
16
20
|
import { bootSuiService } from "./service.mjs";
|
|
17
21
|
import { faucetCapabilityKey } from "../faucet/dispatcher.mjs";
|
|
18
|
-
import
|
|
22
|
+
import "../faucet/index.mjs";
|
|
23
|
+
import { suiLocalStrategy } from "./local-faucet-strategy.mjs";
|
|
24
|
+
import { suiForkFaucetStrategy } from "./fork-faucet-strategy.mjs";
|
|
25
|
+
import "./chain-build-container.mjs";
|
|
19
26
|
import { Effect } from "effect";
|
|
20
27
|
//#region src/plugins/sui/index.ts
|
|
21
|
-
const fundingFaucetLeaseBrokerSymbol = Symbol("@mysten-incubation/devstack/sui/fundingFaucetLeaseBroker");
|
|
22
28
|
/** The Sui plugin's resource identity. The id is `'sui'` (singular). */
|
|
23
29
|
const suiResource = resource("sui");
|
|
24
30
|
const suiErrorContributions = pluginErrorContributions(SUI_ERROR_TAGS);
|
|
31
|
+
/** Build the funds-ready faucet strategy for the resolved network, or
|
|
32
|
+
* `null` when the network has none. Local/live wrap the HTTP faucet;
|
|
33
|
+
* fork mode impersonates a whale (resolved + validated here). */
|
|
34
|
+
const resolveFundingFaucetStrategy = (opts, client, broker) => {
|
|
35
|
+
if (opts.mode === "fork") return resolveForkFaucetStrategy(opts, client, broker);
|
|
36
|
+
if (client.fundingFaucetUrl === null) return Effect.succeed(null);
|
|
37
|
+
return Effect.succeed(suiLocalStrategy({
|
|
38
|
+
faucetUrl: client.fundingFaucetUrl,
|
|
39
|
+
serialization: {
|
|
40
|
+
broker,
|
|
41
|
+
key: `sui-faucet:${client.chain}`,
|
|
42
|
+
owner: `sui-faucet:${client.chain}`
|
|
43
|
+
}
|
|
44
|
+
}));
|
|
45
|
+
};
|
|
46
|
+
/** Fork-mode faucet: resolve the whale, validate it holds a large enough
|
|
47
|
+
* SUI coin, then build the impersonation strategy. A whale the user set
|
|
48
|
+
* explicitly that fails validation hard-fails the boot; a per-upstream
|
|
49
|
+
* default whale only warns and disables the faucet so the fork still
|
|
50
|
+
* comes up (account funding then surfaces the "no faucet strategy"
|
|
51
|
+
* error only if something actually needs SUI). */
|
|
52
|
+
const resolveForkFaucetStrategy = (opts, client, broker) => Effect.gen(function* () {
|
|
53
|
+
const resolved = resolveForkWhale(opts);
|
|
54
|
+
const fork = client.fork;
|
|
55
|
+
if (resolved === null || fork === null) return null;
|
|
56
|
+
const strategy = suiForkFaucetStrategy({
|
|
57
|
+
whale: resolved.whale,
|
|
58
|
+
fork,
|
|
59
|
+
sdk: client.sdk,
|
|
60
|
+
perRequestCapMist: resolved.perRequestCapMist,
|
|
61
|
+
serialization: {
|
|
62
|
+
broker,
|
|
63
|
+
key: `sui-fork-faucet:${client.chain}`,
|
|
64
|
+
owner: `sui-fork-faucet:${client.chain}`
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
return yield* selectSufficientForkCoin(client.sdk.core, resolved.whale, FORK_FAUCET_WHALE_MIN_COIN_MIST).pipe(Effect.as(strategy), Effect.catchTag("SuiPluginError", (cause) => resolved.explicit ? Effect.fail(cause) : Effect.logWarning(`sui fork mode: default faucet whale ${resolved.whale} is unusable (${cause.message}); disabling the fork faucet. Set faucet.whale to override.`).pipe(Effect.as(null))));
|
|
68
|
+
});
|
|
25
69
|
const buildPlugin = (opts) => {
|
|
26
70
|
return definePlugin({
|
|
27
71
|
id: suiResource.id,
|
|
28
72
|
role: "service",
|
|
73
|
+
section: "service",
|
|
29
74
|
start: () => Effect.gen(function* () {
|
|
30
75
|
const runtime = yield* ContainerRuntimeService;
|
|
31
76
|
const identity = yield* IdentityContext;
|
|
@@ -33,12 +78,11 @@ const buildPlugin = (opts) => {
|
|
|
33
78
|
const portBroker = yield* PortBrokerService;
|
|
34
79
|
const fundingFaucetLeaseBroker = yield* LeaseBrokerService;
|
|
35
80
|
const { client } = yield* bootSuiService(runtime, identity, portBroker, paths, opts);
|
|
36
|
-
const
|
|
81
|
+
const fundingFaucetStrategy = yield* resolveFundingFaucetStrategy(opts, client, fundingFaucetLeaseBroker);
|
|
37
82
|
return {
|
|
38
83
|
...client,
|
|
39
84
|
mode: opts.mode,
|
|
40
|
-
|
|
41
|
-
[fundingFaucetLeaseBrokerSymbol]: fundingFaucetLeaseBroker
|
|
85
|
+
fundingFaucetStrategy
|
|
42
86
|
};
|
|
43
87
|
}),
|
|
44
88
|
capabilities: ({ value, runtime }) => makePluginCapabilities(opts, value, runtime),
|
|
@@ -70,29 +114,10 @@ const makePluginCapabilities = (opts, resolved, acquireCtx) => {
|
|
|
70
114
|
strategy: resolved.chainProbe,
|
|
71
115
|
autoMounted: true
|
|
72
116
|
};
|
|
73
|
-
const
|
|
74
|
-
kind: "strategy-contributor",
|
|
75
|
-
capabilityKey: FUNDS_READY_GATE_KEY,
|
|
76
|
-
strategy: { waitFundsReady: resolved.waitForTransactionsReady.wait },
|
|
77
|
-
autoMounted: true
|
|
78
|
-
};
|
|
79
|
-
const seedObjectsContribution = {
|
|
80
|
-
kind: "strategy-contributor",
|
|
81
|
-
capabilityKey: SEED_OBJECTS_CAPABILITY_KEY,
|
|
82
|
-
strategy: resolved.seedObjects,
|
|
83
|
-
autoMounted: true
|
|
84
|
-
};
|
|
85
|
-
const faucetContribution = resolved.fundingFaucetUrl === null ? [] : [{
|
|
117
|
+
const faucetContribution = resolvedRuntime.fundingFaucetStrategy === null ? [] : [{
|
|
86
118
|
kind: "strategy-contributor",
|
|
87
119
|
capabilityKey: faucetCapabilityKey(realChain),
|
|
88
|
-
strategy:
|
|
89
|
-
faucetUrl: resolved.fundingFaucetUrl,
|
|
90
|
-
serialization: {
|
|
91
|
-
broker: resolvedRuntime[fundingFaucetLeaseBrokerSymbol],
|
|
92
|
-
key: `sui-faucet:${realChain}`,
|
|
93
|
-
owner: `sui-faucet:${realChain}`
|
|
94
|
-
}
|
|
95
|
-
}),
|
|
120
|
+
strategy: resolvedRuntime.fundingFaucetStrategy,
|
|
96
121
|
autoMounted: true
|
|
97
122
|
}];
|
|
98
123
|
const localRoutables = opts.mode === "local" ? makeSuiLocalRoutables({
|
|
@@ -105,8 +130,6 @@ const makePluginCapabilities = (opts, resolved, acquireCtx) => {
|
|
|
105
130
|
codegen,
|
|
106
131
|
chainProbeContribution,
|
|
107
132
|
...faucetContribution,
|
|
108
|
-
fundsReadyContribution,
|
|
109
|
-
seedObjectsContribution,
|
|
110
133
|
...localRoutables,
|
|
111
134
|
...forkRoutables
|
|
112
135
|
];
|