@mysten-incubation/devstack 0.0.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/LICENSE +189 -0
- package/README.md +94 -0
- package/dist/_virtual/_rolldown/runtime.mjs +13 -0
- package/dist/api/define-capabilities.d.mts +25 -0
- package/dist/api/define-capabilities.mjs +19 -0
- package/dist/api/define-capabilities.mjs.map +1 -0
- package/dist/api/define-devstack-with.d.mts +41 -0
- package/dist/api/define-devstack-with.mjs +24 -0
- package/dist/api/define-devstack-with.mjs.map +1 -0
- package/dist/api/define-devstack.d.mts +62 -0
- package/dist/api/define-devstack.mjs +108 -0
- package/dist/api/define-devstack.mjs.map +1 -0
- package/dist/api/define-plugin.d.mts +1 -0
- package/dist/api/inference-network.mjs +122 -0
- package/dist/api/inference-network.mjs.map +1 -0
- package/dist/api/mode-narrowed-factory.d.mts +26 -0
- package/dist/api/mode-narrowed-factory.mjs +8 -0
- package/dist/api/mode-narrowed-factory.mjs.map +1 -0
- package/dist/api/plugin-errors.mjs +10 -0
- package/dist/api/plugin-errors.mjs.map +1 -0
- package/dist/api/run-stack.d.mts +82 -0
- package/dist/api/run-stack.mjs +127 -0
- package/dist/api/run-stack.mjs.map +1 -0
- package/dist/build-integrations/playwright/config.d.mts +92 -0
- package/dist/build-integrations/playwright/config.mjs +71 -0
- package/dist/build-integrations/playwright/config.mjs.map +1 -0
- package/dist/build-integrations/playwright/errors.d.mts +82 -0
- package/dist/build-integrations/playwright/errors.mjs +43 -0
- package/dist/build-integrations/playwright/errors.mjs.map +1 -0
- package/dist/build-integrations/playwright/global-setup.d.mts +64 -0
- package/dist/build-integrations/playwright/global-setup.mjs +44 -0
- package/dist/build-integrations/playwright/global-setup.mjs.map +1 -0
- package/dist/build-integrations/playwright/index.d.mts +6 -0
- package/dist/build-integrations/playwright/index.mjs +6 -0
- package/dist/build-integrations/playwright/stack-context.d.mts +95 -0
- package/dist/build-integrations/playwright/stack-context.mjs +277 -0
- package/dist/build-integrations/playwright/stack-context.mjs.map +1 -0
- package/dist/build-integrations/playwright/wallet-context.d.mts +87 -0
- package/dist/build-integrations/playwright/wallet-context.mjs +148 -0
- package/dist/build-integrations/playwright/wallet-context.mjs.map +1 -0
- package/dist/build-integrations/runtime/cold-start-url.d.mts +67 -0
- package/dist/build-integrations/runtime/cold-start-url.mjs +56 -0
- package/dist/build-integrations/runtime/cold-start-url.mjs.map +1 -0
- package/dist/build-integrations/runtime/dapp-kit-slot.mjs +10 -0
- package/dist/build-integrations/runtime/dapp-kit-slot.mjs.map +1 -0
- package/dist/build-integrations/runtime/discover.d.mts +78 -0
- package/dist/build-integrations/runtime/discover.mjs +124 -0
- package/dist/build-integrations/runtime/discover.mjs.map +1 -0
- package/dist/build-integrations/runtime/endpoint-registry.d.mts +26 -0
- package/dist/build-integrations/runtime/endpoint-registry.mjs +41 -0
- package/dist/build-integrations/runtime/endpoint-registry.mjs.map +1 -0
- package/dist/build-integrations/runtime/errors.d.mts +64 -0
- package/dist/build-integrations/runtime/errors.mjs +51 -0
- package/dist/build-integrations/runtime/errors.mjs.map +1 -0
- package/dist/build-integrations/runtime/index.d.mts +7 -0
- package/dist/build-integrations/runtime/index.mjs +6 -0
- package/dist/build-integrations/runtime/read-stack-context.d.mts +38 -0
- package/dist/build-integrations/runtime/read-stack-context.mjs +130 -0
- package/dist/build-integrations/runtime/read-stack-context.mjs.map +1 -0
- package/dist/build-integrations/runtime/stack-context.d.mts +53 -0
- package/dist/build-integrations/vitest/config.d.mts +62 -0
- package/dist/build-integrations/vitest/config.mjs +80 -0
- package/dist/build-integrations/vitest/config.mjs.map +1 -0
- package/dist/build-integrations/vitest/env.d.mts +48 -0
- package/dist/build-integrations/vitest/env.mjs +50 -0
- package/dist/build-integrations/vitest/env.mjs.map +1 -0
- package/dist/build-integrations/vitest/errors.d.mts +44 -0
- package/dist/build-integrations/vitest/errors.mjs +18 -0
- package/dist/build-integrations/vitest/errors.mjs.map +1 -0
- package/dist/build-integrations/vitest/index.d.mts +6 -0
- package/dist/build-integrations/vitest/index.mjs +6 -0
- package/dist/build-integrations/vitest/setup.d.mts +53 -0
- package/dist/build-integrations/vitest/setup.mjs +56 -0
- package/dist/build-integrations/vitest/setup.mjs.map +1 -0
- package/dist/build-integrations/vitest/stack-context.d.mts +58 -0
- package/dist/build-integrations/vitest/stack-context.mjs +67 -0
- package/dist/build-integrations/vitest/stack-context.mjs.map +1 -0
- package/dist/cli/main.d.mts +5 -0
- package/dist/cli/main.mjs +586 -0
- package/dist/cli/main.mjs.map +1 -0
- package/dist/cli/prune-direct.mjs +216 -0
- package/dist/cli/prune-direct.mjs.map +1 -0
- package/dist/cli/snapshot-reader.mjs +73 -0
- package/dist/cli/snapshot-reader.mjs.map +1 -0
- package/dist/cli/up-lifecycle.mjs +28 -0
- package/dist/cli/up-lifecycle.mjs.map +1 -0
- package/dist/contracts/capability-decl.d.mts +42 -0
- package/dist/contracts/chain-probe.d.mts +26 -0
- package/dist/contracts/chain-probe.mjs +8 -0
- package/dist/contracts/chain-probe.mjs.map +1 -0
- package/dist/contracts/codegenable.d.mts +43 -0
- package/dist/contracts/container-runtime.d.mts +245 -0
- package/dist/contracts/liveness-classifier.d.mts +19 -0
- package/dist/contracts/network-resolver.d.mts +15 -0
- package/dist/contracts/network-resolver.mjs +7 -0
- package/dist/contracts/network-resolver.mjs.map +1 -0
- package/dist/contracts/projection.d.mts +15 -0
- package/dist/contracts/routable.d.mts +53 -0
- package/dist/contracts/snapshotable.d.mts +39 -0
- package/dist/contracts/strategy-contributor.d.mts +26 -0
- package/dist/index.d.mts +89 -0
- package/dist/index.mjs +37 -0
- package/dist/orchestrators/codegen/bindings.d.mts +2 -0
- package/dist/orchestrators/codegen/bindings.mjs +340 -0
- package/dist/orchestrators/codegen/bindings.mjs.map +1 -0
- package/dist/orchestrators/codegen/emit.mjs +56 -0
- package/dist/orchestrators/codegen/emit.mjs.map +1 -0
- package/dist/orchestrators/codegen/errors.d.mts +1 -0
- package/dist/orchestrators/codegen/errors.mjs +66 -0
- package/dist/orchestrators/codegen/errors.mjs.map +1 -0
- package/dist/orchestrators/codegen/extras.mjs +16 -0
- package/dist/orchestrators/codegen/extras.mjs.map +1 -0
- package/dist/orchestrators/codegen/format.mjs +109 -0
- package/dist/orchestrators/codegen/format.mjs.map +1 -0
- package/dist/orchestrators/codegen/gitignore.mjs +67 -0
- package/dist/orchestrators/codegen/gitignore.mjs.map +1 -0
- package/dist/orchestrators/codegen/paths.d.mts +1 -0
- package/dist/orchestrators/codegen/paths.mjs +33 -0
- package/dist/orchestrators/codegen/paths.mjs.map +1 -0
- package/dist/orchestrators/codegen/permissions.mjs +6 -0
- package/dist/orchestrators/codegen/permissions.mjs.map +1 -0
- package/dist/orchestrators/codegen/service.d.mts +1 -0
- package/dist/orchestrators/codegen/service.mjs +276 -0
- package/dist/orchestrators/codegen/service.mjs.map +1 -0
- package/dist/orchestrators/router/cleanup.mjs +58 -0
- package/dist/orchestrators/router/cleanup.mjs.map +1 -0
- package/dist/orchestrators/router/cors.mjs +31 -0
- package/dist/orchestrators/router/cors.mjs.map +1 -0
- package/dist/orchestrators/router/entrypoints.d.mts +1 -0
- package/dist/orchestrators/router/entrypoints.mjs +80 -0
- package/dist/orchestrators/router/entrypoints.mjs.map +1 -0
- package/dist/orchestrators/router/errors.d.mts +1 -0
- package/dist/orchestrators/router/errors.mjs +103 -0
- package/dist/orchestrators/router/errors.mjs.map +1 -0
- package/dist/orchestrators/router/file-provider.d.mts +1 -0
- package/dist/orchestrators/router/file-provider.mjs +320 -0
- package/dist/orchestrators/router/file-provider.mjs.map +1 -0
- package/dist/orchestrators/router/hostname.d.mts +1 -0
- package/dist/orchestrators/router/hostname.mjs +107 -0
- package/dist/orchestrators/router/hostname.mjs.map +1 -0
- package/dist/orchestrators/router/index.d.mts +1 -0
- package/dist/orchestrators/router/profile.d.mts +1 -0
- package/dist/orchestrators/router/profile.mjs +109 -0
- package/dist/orchestrators/router/profile.mjs.map +1 -0
- package/dist/orchestrators/router/service.d.mts +3 -0
- package/dist/orchestrators/router/service.mjs +421 -0
- package/dist/orchestrators/router/service.mjs.map +1 -0
- package/dist/orchestrators/router/traefik-container.d.mts +1 -0
- package/dist/orchestrators/router/traefik-container.mjs +229 -0
- package/dist/orchestrators/router/traefik-container.mjs.map +1 -0
- package/dist/orchestrators/runtime-composition.d.mts +10 -0
- package/dist/orchestrators/runtime-composition.mjs +168 -0
- package/dist/orchestrators/runtime-composition.mjs.map +1 -0
- package/dist/orchestrators/snapshot/capture.d.mts +1 -0
- package/dist/orchestrators/snapshot/capture.mjs +350 -0
- package/dist/orchestrators/snapshot/capture.mjs.map +1 -0
- package/dist/orchestrators/snapshot/descriptor.d.mts +1 -0
- package/dist/orchestrators/snapshot/descriptor.mjs +109 -0
- package/dist/orchestrators/snapshot/descriptor.mjs.map +1 -0
- package/dist/orchestrators/snapshot/identity-guard.d.mts +1 -0
- package/dist/orchestrators/snapshot/identity-guard.mjs +132 -0
- package/dist/orchestrators/snapshot/identity-guard.mjs.map +1 -0
- package/dist/orchestrators/snapshot/image-bundle-tags.mjs +207 -0
- package/dist/orchestrators/snapshot/image-bundle-tags.mjs.map +1 -0
- package/dist/orchestrators/snapshot/index.d.mts +1 -0
- package/dist/orchestrators/snapshot/integrity.d.mts +1 -0
- package/dist/orchestrators/snapshot/integrity.mjs +74 -0
- package/dist/orchestrators/snapshot/integrity.mjs.map +1 -0
- package/dist/orchestrators/snapshot/prune.d.mts +1 -0
- package/dist/orchestrators/snapshot/prune.mjs +110 -0
- package/dist/orchestrators/snapshot/prune.mjs.map +1 -0
- package/dist/orchestrators/snapshot/restore.d.mts +1 -0
- package/dist/orchestrators/snapshot/restore.mjs +404 -0
- package/dist/orchestrators/snapshot/restore.mjs.map +1 -0
- package/dist/orchestrators/snapshot/service.d.mts +1 -0
- package/dist/orchestrators/snapshot/service.mjs +296 -0
- package/dist/orchestrators/snapshot/service.mjs.map +1 -0
- package/dist/orchestrators/snapshot/state-document.mjs +18 -0
- package/dist/orchestrators/snapshot/state-document.mjs.map +1 -0
- package/dist/orchestrators/snapshot/wipe.d.mts +1 -0
- package/dist/orchestrators/snapshot/wipe.mjs +59 -0
- package/dist/orchestrators/snapshot/wipe.mjs.map +1 -0
- package/dist/plugins/account/codegen.d.mts +12 -0
- package/dist/plugins/account/codegen.mjs +22 -0
- package/dist/plugins/account/codegen.mjs.map +1 -0
- package/dist/plugins/account/errors.d.mts +44 -0
- package/dist/plugins/account/errors.mjs +16 -0
- package/dist/plugins/account/errors.mjs.map +1 -0
- package/dist/plugins/account/funding.d.mts +94 -0
- package/dist/plugins/account/funding.mjs +199 -0
- package/dist/plugins/account/funding.mjs.map +1 -0
- package/dist/plugins/account/index.d.mts +54 -0
- package/dist/plugins/account/index.mjs +151 -0
- package/dist/plugins/account/index.mjs.map +1 -0
- package/dist/plugins/account/keypair.d.mts +32 -0
- package/dist/plugins/account/keypair.mjs +99 -0
- package/dist/plugins/account/keypair.mjs.map +1 -0
- package/dist/plugins/account/lease.mjs +21 -0
- package/dist/plugins/account/lease.mjs.map +1 -0
- package/dist/plugins/account/registry.d.mts +33 -0
- package/dist/plugins/account/registry.mjs +36 -0
- package/dist/plugins/account/registry.mjs.map +1 -0
- package/dist/plugins/account/service.d.mts +104 -0
- package/dist/plugins/account/service.mjs +405 -0
- package/dist/plugins/account/service.mjs.map +1 -0
- package/dist/plugins/account/snapshot.mjs +33 -0
- package/dist/plugins/account/snapshot.mjs.map +1 -0
- package/dist/plugins/account/variants/env.mjs +24 -0
- package/dist/plugins/account/variants/env.mjs.map +1 -0
- package/dist/plugins/account/variants/ephemeral.mjs +72 -0
- package/dist/plugins/account/variants/ephemeral.mjs.map +1 -0
- package/dist/plugins/account/variants/impersonate.d.mts +16 -0
- package/dist/plugins/account/variants/impersonate.mjs +48 -0
- package/dist/plugins/account/variants/impersonate.mjs.map +1 -0
- package/dist/plugins/account/variants/inline.mjs +13 -0
- package/dist/plugins/account/variants/inline.mjs.map +1 -0
- package/dist/plugins/account/variants/keystore.mjs +93 -0
- package/dist/plugins/account/variants/keystore.mjs.map +1 -0
- package/dist/plugins/account/variants/signer.mjs +31 -0
- package/dist/plugins/account/variants/signer.mjs.map +1 -0
- package/dist/plugins/action/build-context.d.mts +41 -0
- package/dist/plugins/action/discriminator.d.mts +20 -0
- package/dist/plugins/action/discriminator.mjs +13 -0
- package/dist/plugins/action/discriminator.mjs.map +1 -0
- package/dist/plugins/action/errors.d.mts +31 -0
- package/dist/plugins/action/errors.mjs +13 -0
- package/dist/plugins/action/errors.mjs.map +1 -0
- package/dist/plugins/action/execute.d.mts +2 -0
- package/dist/plugins/action/execute.mjs +145 -0
- package/dist/plugins/action/execute.mjs.map +1 -0
- package/dist/plugins/action/index.d.mts +56 -0
- package/dist/plugins/action/index.mjs +82 -0
- package/dist/plugins/action/index.mjs.map +1 -0
- package/dist/plugins/action/service.d.mts +26 -0
- package/dist/plugins/action/service.mjs +84 -0
- package/dist/plugins/action/service.mjs.map +1 -0
- package/dist/plugins/coin/address-resolution.d.mts +34 -0
- package/dist/plugins/coin/address-resolution.mjs +80 -0
- package/dist/plugins/coin/address-resolution.mjs.map +1 -0
- package/dist/plugins/coin/codegen.d.mts +16 -0
- package/dist/plugins/coin/codegen.mjs +21 -0
- package/dist/plugins/coin/codegen.mjs.map +1 -0
- package/dist/plugins/coin/discovery.d.mts +26 -0
- package/dist/plugins/coin/discovery.mjs +112 -0
- package/dist/plugins/coin/discovery.mjs.map +1 -0
- package/dist/plugins/coin/errors.d.mts +48 -0
- package/dist/plugins/coin/errors.mjs +13 -0
- package/dist/plugins/coin/errors.mjs.map +1 -0
- package/dist/plugins/coin/index.d.mts +95 -0
- package/dist/plugins/coin/index.mjs +172 -0
- package/dist/plugins/coin/index.mjs.map +1 -0
- package/dist/plugins/coin/metadata.d.mts +15 -0
- package/dist/plugins/coin/metadata.mjs +99 -0
- package/dist/plugins/coin/metadata.mjs.map +1 -0
- package/dist/plugins/coin/mint.d.mts +34 -0
- package/dist/plugins/coin/mint.mjs +164 -0
- package/dist/plugins/coin/mint.mjs.map +1 -0
- package/dist/plugins/coin/registry.d.mts +1 -0
- package/dist/plugins/coin/registry.mjs +37 -0
- package/dist/plugins/coin/registry.mjs.map +1 -0
- package/dist/plugins/coin/service.d.mts +47 -0
- package/dist/plugins/coin/service.mjs +51 -0
- package/dist/plugins/coin/service.mjs.map +1 -0
- package/dist/plugins/coin/snapshot.mjs +19 -0
- package/dist/plugins/coin/snapshot.mjs.map +1 -0
- package/dist/plugins/coin/type-strings.mjs +49 -0
- package/dist/plugins/coin/type-strings.mjs.map +1 -0
- package/dist/plugins/deepbook/codegen.d.mts +39 -0
- package/dist/plugins/deepbook/codegen.mjs +15 -0
- package/dist/plugins/deepbook/codegen.mjs.map +1 -0
- package/dist/plugins/deepbook/deploy.mjs +437 -0
- package/dist/plugins/deepbook/deploy.mjs.map +1 -0
- package/dist/plugins/deepbook/errors.d.mts +29 -0
- package/dist/plugins/deepbook/errors.mjs +26 -0
- package/dist/plugins/deepbook/errors.mjs.map +1 -0
- package/dist/plugins/deepbook/faucet-strategy.d.mts +8 -0
- package/dist/plugins/deepbook/faucet-strategy.mjs +81 -0
- package/dist/plugins/deepbook/faucet-strategy.mjs.map +1 -0
- package/dist/plugins/deepbook/index.d.mts +171 -0
- package/dist/plugins/deepbook/index.mjs +359 -0
- package/dist/plugins/deepbook/index.mjs.map +1 -0
- package/dist/plugins/deepbook/plugin-key.mjs +7 -0
- package/dist/plugins/deepbook/plugin-key.mjs.map +1 -0
- package/dist/plugins/deepbook/pyth/index.mjs +226 -0
- package/dist/plugins/deepbook/pyth/index.mjs.map +1 -0
- package/dist/plugins/deepbook/routable.mjs +21 -0
- package/dist/plugins/deepbook/routable.mjs.map +1 -0
- package/dist/plugins/deepbook/snapshot.mjs +49 -0
- package/dist/plugins/deepbook/snapshot.mjs.map +1 -0
- package/dist/plugins/deepbook/types.d.mts +125 -0
- package/dist/plugins/deepbook/types.mjs +12 -0
- package/dist/plugins/deepbook/types.mjs.map +1 -0
- package/dist/plugins/faucet/dispatcher.d.mts +9 -0
- package/dist/plugins/faucet/dispatcher.mjs +13 -0
- package/dist/plugins/faucet/dispatcher.mjs.map +1 -0
- package/dist/plugins/faucet/errors.d.mts +86 -0
- package/dist/plugins/faucet/errors.mjs +19 -0
- package/dist/plugins/faucet/errors.mjs.map +1 -0
- package/dist/plugins/faucet/http.mjs +127 -0
- package/dist/plugins/faucet/http.mjs.map +1 -0
- package/dist/plugins/faucet/index.d.mts +43 -0
- package/dist/plugins/faucet/index.mjs +42 -0
- package/dist/plugins/faucet/index.mjs.map +1 -0
- package/dist/plugins/faucet/service.d.mts +20 -0
- package/dist/plugins/faucet/strategies/sui-local.d.mts +23 -0
- package/dist/plugins/faucet/strategies/sui-local.mjs +29 -0
- package/dist/plugins/faucet/strategies/sui-local.mjs.map +1 -0
- package/dist/plugins/host-service/errors.d.mts +27 -0
- package/dist/plugins/host-service/errors.mjs +14 -0
- package/dist/plugins/host-service/errors.mjs.map +1 -0
- package/dist/plugins/host-service/index.d.mts +10 -0
- package/dist/plugins/host-service/index.mjs +48 -0
- package/dist/plugins/host-service/index.mjs.map +1 -0
- package/dist/plugins/host-service/routable.mjs +24 -0
- package/dist/plugins/host-service/routable.mjs.map +1 -0
- package/dist/plugins/host-service/service.d.mts +49 -0
- package/dist/plugins/host-service/service.mjs +375 -0
- package/dist/plugins/host-service/service.mjs.map +1 -0
- package/dist/plugins/package/build.d.mts +1 -0
- package/dist/plugins/package/build.mjs +24 -0
- package/dist/plugins/package/build.mjs.map +1 -0
- package/dist/plugins/package/codegen.d.mts +19 -0
- package/dist/plugins/package/codegen.mjs +41 -0
- package/dist/plugins/package/codegen.mjs.map +1 -0
- package/dist/plugins/package/dep-resolution.mjs +10 -0
- package/dist/plugins/package/dep-resolution.mjs.map +1 -0
- package/dist/plugins/package/errors.d.mts +34 -0
- package/dist/plugins/package/errors.mjs +13 -0
- package/dist/plugins/package/errors.mjs.map +1 -0
- package/dist/plugins/package/index.d.mts +109 -0
- package/dist/plugins/package/index.mjs +207 -0
- package/dist/plugins/package/index.mjs.map +1 -0
- package/dist/plugins/package/mode-known.mjs +41 -0
- package/dist/plugins/package/mode-known.mjs.map +1 -0
- package/dist/plugins/package/mode-local.d.mts +1 -0
- package/dist/plugins/package/mode-local.mjs +183 -0
- package/dist/plugins/package/mode-local.mjs.map +1 -0
- package/dist/plugins/package/publish-executor.mjs +202 -0
- package/dist/plugins/package/publish-executor.mjs.map +1 -0
- package/dist/plugins/package/publish-output.d.mts +28 -0
- package/dist/plugins/package/publish-output.mjs +45 -0
- package/dist/plugins/package/publish-output.mjs.map +1 -0
- package/dist/plugins/package/registry.d.mts +25 -0
- package/dist/plugins/package/registry.mjs +30 -0
- package/dist/plugins/package/registry.mjs.map +1 -0
- package/dist/plugins/package/service.mjs +20 -0
- package/dist/plugins/package/service.mjs.map +1 -0
- package/dist/plugins/package/snapshot.mjs +25 -0
- package/dist/plugins/package/snapshot.mjs.map +1 -0
- package/dist/plugins/postgres/codegen.mjs +42 -0
- package/dist/plugins/postgres/codegen.mjs.map +1 -0
- package/dist/plugins/postgres/connection.d.mts +33 -0
- package/dist/plugins/postgres/connection.mjs +19 -0
- package/dist/plugins/postgres/connection.mjs.map +1 -0
- package/dist/plugins/postgres/db-ensure.mjs +100 -0
- package/dist/plugins/postgres/db-ensure.mjs.map +1 -0
- package/dist/plugins/postgres/errors.d.mts +55 -0
- package/dist/plugins/postgres/errors.mjs +29 -0
- package/dist/plugins/postgres/errors.mjs.map +1 -0
- package/dist/plugins/postgres/index.d.mts +37 -0
- package/dist/plugins/postgres/index.mjs +75 -0
- package/dist/plugins/postgres/index.mjs.map +1 -0
- package/dist/plugins/postgres/routable.mjs +33 -0
- package/dist/plugins/postgres/routable.mjs.map +1 -0
- package/dist/plugins/postgres/service.d.mts +50 -0
- package/dist/plugins/postgres/service.mjs +145 -0
- package/dist/plugins/postgres/service.mjs.map +1 -0
- package/dist/plugins/postgres/snapshot.d.mts +1 -0
- package/dist/plugins/postgres/snapshot.mjs +32 -0
- package/dist/plugins/postgres/snapshot.mjs.map +1 -0
- package/dist/plugins/router-entrypoints.mjs +21 -0
- package/dist/plugins/router-entrypoints.mjs.map +1 -0
- package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs +59 -0
- package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs.map +1 -0
- package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs +132 -0
- package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs.map +1 -0
- package/dist/plugins/seal/codegen.d.mts +19 -0
- package/dist/plugins/seal/codegen.mjs +16 -0
- package/dist/plugins/seal/codegen.mjs.map +1 -0
- package/dist/plugins/seal/config-render.mjs +82 -0
- package/dist/plugins/seal/config-render.mjs.map +1 -0
- package/dist/plugins/seal/deploy.mjs +198 -0
- package/dist/plugins/seal/deploy.mjs.map +1 -0
- package/dist/plugins/seal/errors.d.mts +52 -0
- package/dist/plugins/seal/errors.mjs +19 -0
- package/dist/plugins/seal/errors.mjs.map +1 -0
- package/dist/plugins/seal/index.d.mts +161 -0
- package/dist/plugins/seal/index.mjs +235 -0
- package/dist/plugins/seal/index.mjs.map +1 -0
- package/dist/plugins/seal/key-manager.d.mts +22 -0
- package/dist/plugins/seal/key-manager.mjs +22 -0
- package/dist/plugins/seal/key-manager.mjs.map +1 -0
- package/dist/plugins/seal/key-server.mjs +175 -0
- package/dist/plugins/seal/key-server.mjs.map +1 -0
- package/dist/plugins/seal/keygen.mjs +96 -0
- package/dist/plugins/seal/keygen.mjs.map +1 -0
- package/dist/plugins/seal/mode/fork-known.d.mts +8 -0
- package/dist/plugins/seal/mode/fork-known.mjs +23 -0
- package/dist/plugins/seal/mode/fork-known.mjs.map +1 -0
- package/dist/plugins/seal/mode/live.d.mts +18 -0
- package/dist/plugins/seal/mode/live.mjs +64 -0
- package/dist/plugins/seal/mode/live.mjs.map +1 -0
- package/dist/plugins/seal/mode/local-keygen.mjs +180 -0
- package/dist/plugins/seal/mode/local-keygen.mjs.map +1 -0
- package/dist/plugins/seal/plugin-key.mjs +7 -0
- package/dist/plugins/seal/plugin-key.mjs.map +1 -0
- package/dist/plugins/seal/registry-publish.d.mts +43 -0
- package/dist/plugins/seal/registry-publish.mjs +9 -0
- package/dist/plugins/seal/registry-publish.mjs.map +1 -0
- package/dist/plugins/seal/routable.mjs +57 -0
- package/dist/plugins/seal/routable.mjs.map +1 -0
- package/dist/plugins/seal/service.mjs +17 -0
- package/dist/plugins/seal/service.mjs.map +1 -0
- package/dist/plugins/seal/snapshot.mjs +51 -0
- package/dist/plugins/seal/snapshot.mjs.map +1 -0
- package/dist/plugins/sui/auto-tick.mjs +45 -0
- package/dist/plugins/sui/auto-tick.mjs.map +1 -0
- package/dist/plugins/sui/chain-build-container.d.mts +1 -0
- package/dist/plugins/sui/chain-probe.d.mts +85 -0
- package/dist/plugins/sui/chain-probe.mjs +104 -0
- package/dist/plugins/sui/chain-probe.mjs.map +1 -0
- package/dist/plugins/sui/codegen.d.mts +14 -0
- package/dist/plugins/sui/codegen.mjs +26 -0
- package/dist/plugins/sui/codegen.mjs.map +1 -0
- package/dist/plugins/sui/errors.d.mts +74 -0
- package/dist/plugins/sui/errors.mjs +28 -0
- package/dist/plugins/sui/errors.mjs.map +1 -0
- package/dist/plugins/sui/fork-orchestration.mjs +24 -0
- package/dist/plugins/sui/fork-orchestration.mjs.map +1 -0
- package/dist/plugins/sui/fork-transaction.mjs +96 -0
- package/dist/plugins/sui/fork-transaction.mjs.map +1 -0
- package/dist/plugins/sui/index.d.mts +318 -0
- package/dist/plugins/sui/index.mjs +182 -0
- package/dist/plugins/sui/index.mjs.map +1 -0
- package/dist/plugins/sui/mode/external.mjs +60 -0
- package/dist/plugins/sui/mode/external.mjs.map +1 -0
- package/dist/plugins/sui/mode/fork.mjs +283 -0
- package/dist/plugins/sui/mode/fork.mjs.map +1 -0
- package/dist/plugins/sui/mode/live.mjs +103 -0
- package/dist/plugins/sui/mode/live.mjs.map +1 -0
- package/dist/plugins/sui/mode/local.mjs +293 -0
- package/dist/plugins/sui/mode/local.mjs.map +1 -0
- package/dist/plugins/sui/mode/shared-boot.mjs +254 -0
- package/dist/plugins/sui/mode/shared-boot.mjs.map +1 -0
- package/dist/plugins/sui/mode/shared.d.mts +103 -0
- package/dist/plugins/sui/mode/shared.mjs +12 -0
- package/dist/plugins/sui/mode/shared.mjs.map +1 -0
- package/dist/plugins/sui/mode/spec.d.mts +94 -0
- package/dist/plugins/sui/network-resolver.d.mts +23 -0
- package/dist/plugins/sui/routable.mjs +88 -0
- package/dist/plugins/sui/routable.mjs.map +1 -0
- package/dist/plugins/sui/seed-objects.d.mts +18 -0
- package/dist/plugins/sui/seed-objects.mjs +25 -0
- package/dist/plugins/sui/seed-objects.mjs.map +1 -0
- package/dist/plugins/sui/service.mjs +38 -0
- package/dist/plugins/sui/service.mjs.map +1 -0
- package/dist/plugins/sui/snapshot.mjs +53 -0
- package/dist/plugins/sui/snapshot.mjs.map +1 -0
- package/dist/plugins/wallet/codegen.d.mts +33 -0
- package/dist/plugins/wallet/codegen.mjs +34 -0
- package/dist/plugins/wallet/codegen.mjs.map +1 -0
- package/dist/plugins/wallet/errors.d.mts +66 -0
- package/dist/plugins/wallet/errors.mjs +16 -0
- package/dist/plugins/wallet/errors.mjs.map +1 -0
- package/dist/plugins/wallet/index.d.mts +63 -0
- package/dist/plugins/wallet/index.mjs +126 -0
- package/dist/plugins/wallet/index.mjs.map +1 -0
- package/dist/plugins/wallet/origin-policy.d.mts +1 -0
- package/dist/plugins/wallet/origin-policy.mjs +65 -0
- package/dist/plugins/wallet/origin-policy.mjs.map +1 -0
- package/dist/plugins/wallet/pairing.d.mts +11 -0
- package/dist/plugins/wallet/pairing.mjs +125 -0
- package/dist/plugins/wallet/pairing.mjs.map +1 -0
- package/dist/plugins/wallet/protocol.d.mts +1 -0
- package/dist/plugins/wallet/protocol.mjs +96 -0
- package/dist/plugins/wallet/protocol.mjs.map +1 -0
- package/dist/plugins/wallet/routable.mjs +32 -0
- package/dist/plugins/wallet/routable.mjs.map +1 -0
- package/dist/plugins/wallet/server.d.mts +12 -0
- package/dist/plugins/wallet/server.mjs +317 -0
- package/dist/plugins/wallet/server.mjs.map +1 -0
- package/dist/plugins/wallet/service.d.mts +68 -0
- package/dist/plugins/wallet/service.mjs +97 -0
- package/dist/plugins/wallet/service.mjs.map +1 -0
- package/dist/plugins/wallet/snapshot.d.mts +1 -0
- package/dist/plugins/wallet/snapshot.mjs +14 -0
- package/dist/plugins/wallet/snapshot.mjs.map +1 -0
- package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs +42 -0
- package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs.map +1 -0
- package/dist/plugins/walrus/codegen.d.mts +38 -0
- package/dist/plugins/walrus/codegen.mjs +34 -0
- package/dist/plugins/walrus/codegen.mjs.map +1 -0
- package/dist/plugins/walrus/deploy-paths.mjs +14 -0
- package/dist/plugins/walrus/deploy-paths.mjs.map +1 -0
- package/dist/plugins/walrus/deploy.d.mts +1 -0
- package/dist/plugins/walrus/deploy.mjs +224 -0
- package/dist/plugins/walrus/deploy.mjs.map +1 -0
- package/dist/plugins/walrus/errors.d.mts +38 -0
- package/dist/plugins/walrus/errors.mjs +26 -0
- package/dist/plugins/walrus/errors.mjs.map +1 -0
- package/dist/plugins/walrus/faucet-strategy.d.mts +12 -0
- package/dist/plugins/walrus/faucet-strategy.mjs +62 -0
- package/dist/plugins/walrus/faucet-strategy.mjs.map +1 -0
- package/dist/plugins/walrus/index.d.mts +177 -0
- package/dist/plugins/walrus/index.mjs +284 -0
- package/dist/plugins/walrus/index.mjs.map +1 -0
- package/dist/plugins/walrus/mode/known-deploy.d.mts +25 -0
- package/dist/plugins/walrus/mode/known-deploy.mjs +71 -0
- package/dist/plugins/walrus/mode/known-deploy.mjs.map +1 -0
- package/dist/plugins/walrus/mode/local-cluster.d.mts +34 -0
- package/dist/plugins/walrus/mode/local-cluster.mjs +153 -0
- package/dist/plugins/walrus/mode/local-cluster.mjs.map +1 -0
- package/dist/plugins/walrus/plugin-key.mjs +7 -0
- package/dist/plugins/walrus/plugin-key.mjs.map +1 -0
- package/dist/plugins/walrus/registry-publish.d.mts +24 -0
- package/dist/plugins/walrus/registry-publish.mjs +7 -0
- package/dist/plugins/walrus/registry-publish.mjs.map +1 -0
- package/dist/plugins/walrus/routable.mjs +99 -0
- package/dist/plugins/walrus/routable.mjs.map +1 -0
- package/dist/plugins/walrus/service.mjs +20 -0
- package/dist/plugins/walrus/service.mjs.map +1 -0
- package/dist/plugins/walrus/snapshot.mjs +53 -0
- package/dist/plugins/walrus/snapshot.mjs.map +1 -0
- package/dist/plugins/walrus/storage-nodes.d.mts +15 -0
- package/dist/plugins/walrus/storage-nodes.mjs +154 -0
- package/dist/plugins/walrus/storage-nodes.mjs.map +1 -0
- package/dist/plugins/walrus/wal-swap.d.mts +2 -0
- package/dist/plugins/walrus/wal-swap.mjs +58 -0
- package/dist/plugins/walrus/wal-swap.mjs.map +1 -0
- package/dist/primitives/artifact-publisher.d.mts +12 -0
- package/dist/primitives/cache.d.mts +1 -0
- package/dist/runtime/built-in-plugin-layers.mjs +49 -0
- package/dist/runtime/built-in-plugin-layers.mjs.map +1 -0
- package/dist/runtime/docker/client.d.mts +2 -0
- package/dist/runtime/docker/client.mjs +54 -0
- package/dist/runtime/docker/client.mjs.map +1 -0
- package/dist/runtime/docker/container.d.mts +1 -0
- package/dist/runtime/docker/container.mjs +562 -0
- package/dist/runtime/docker/container.mjs.map +1 -0
- package/dist/runtime/docker/errors.d.mts +1 -0
- package/dist/runtime/docker/errors.mjs +187 -0
- package/dist/runtime/docker/errors.mjs.map +1 -0
- package/dist/runtime/docker/exec.d.mts +1 -0
- package/dist/runtime/docker/exec.mjs +63 -0
- package/dist/runtime/docker/exec.mjs.map +1 -0
- package/dist/runtime/docker/image.d.mts +1 -0
- package/dist/runtime/docker/image.mjs +278 -0
- package/dist/runtime/docker/image.mjs.map +1 -0
- package/dist/runtime/docker/index.d.mts +1 -0
- package/dist/runtime/docker/inventory.d.mts +1 -0
- package/dist/runtime/docker/inventory.mjs +167 -0
- package/dist/runtime/docker/inventory.mjs.map +1 -0
- package/dist/runtime/docker/labels.d.mts +1 -0
- package/dist/runtime/docker/labels.mjs +97 -0
- package/dist/runtime/docker/labels.mjs.map +1 -0
- package/dist/runtime/docker/logs.d.mts +1 -0
- package/dist/runtime/docker/logs.mjs +34 -0
- package/dist/runtime/docker/logs.mjs.map +1 -0
- package/dist/runtime/docker/network.d.mts +1 -0
- package/dist/runtime/docker/network.mjs +168 -0
- package/dist/runtime/docker/network.mjs.map +1 -0
- package/dist/runtime/docker/service.d.mts +9 -0
- package/dist/runtime/docker/service.mjs +266 -0
- package/dist/runtime/docker/service.mjs.map +1 -0
- package/dist/runtime/docker/sweep.d.mts +1 -0
- package/dist/runtime/docker/sweep.mjs +220 -0
- package/dist/runtime/docker/sweep.mjs.map +1 -0
- package/dist/runtime/docker/volume.d.mts +1 -0
- package/dist/runtime/docker/volume.mjs +24 -0
- package/dist/runtime/docker/volume.mjs.map +1 -0
- package/dist/runtime/docker/wrap.d.mts +1 -0
- package/dist/runtime/docker/wrap.mjs +131 -0
- package/dist/runtime/docker/wrap.mjs.map +1 -0
- package/dist/substrate/brand.d.mts +24 -0
- package/dist/substrate/brand.mjs +14 -0
- package/dist/substrate/brand.mjs.map +1 -0
- package/dist/substrate/cross-process.d.mts +1 -0
- package/dist/substrate/cross-process.mjs +28 -0
- package/dist/substrate/cross-process.mjs.map +1 -0
- package/dist/substrate/events.d.mts +117 -0
- package/dist/substrate/identity.d.mts +13 -0
- package/dist/substrate/lifecycle.d.mts +12 -0
- package/dist/substrate/manifest.d.mts +39 -0
- package/dist/substrate/manifest.mjs +33 -0
- package/dist/substrate/manifest.mjs.map +1 -0
- package/dist/substrate/network.d.mts +34 -0
- package/dist/substrate/options.d.mts +23 -0
- package/dist/substrate/plugin.d.mts +101 -0
- package/dist/substrate/plugin.mjs +61 -0
- package/dist/substrate/plugin.mjs.map +1 -0
- package/dist/substrate/projection.d.mts +100 -0
- package/dist/substrate/runtime/artifact-publisher/index.mjs +76 -0
- package/dist/substrate/runtime/artifact-publisher/index.mjs.map +1 -0
- package/dist/substrate/runtime/atomic-write.mjs +106 -0
- package/dist/substrate/runtime/atomic-write.mjs.map +1 -0
- package/dist/substrate/runtime/cache/index.d.mts +1 -0
- package/dist/substrate/runtime/cache/schema.d.mts +1 -0
- package/dist/substrate/runtime/cache/schema.mjs +22 -0
- package/dist/substrate/runtime/cache/schema.mjs.map +1 -0
- package/dist/substrate/runtime/cache/service.d.mts +1 -0
- package/dist/substrate/runtime/cache/service.mjs +89 -0
- package/dist/substrate/runtime/cache/service.mjs.map +1 -0
- package/dist/substrate/runtime/capability-sinks/index.d.mts +1 -0
- package/dist/substrate/runtime/capability-sinks/layer.d.mts +1 -0
- package/dist/substrate/runtime/capability-sinks/layer.mjs +31 -0
- package/dist/substrate/runtime/capability-sinks/layer.mjs.map +1 -0
- package/dist/substrate/runtime/capability-sinks/service.d.mts +36 -0
- package/dist/substrate/runtime/capability-sinks/service.mjs +74 -0
- package/dist/substrate/runtime/capability-sinks/service.mjs.map +1 -0
- package/dist/substrate/runtime/config-validation.d.mts +38 -0
- package/dist/substrate/runtime/config-validation.mjs +137 -0
- package/dist/substrate/runtime/config-validation.mjs.map +1 -0
- package/dist/substrate/runtime/context-helpers.mjs +32 -0
- package/dist/substrate/runtime/context-helpers.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/command-channel/channel.mjs +128 -0
- package/dist/substrate/runtime/cross-process/command-channel/channel.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs +136 -0
- package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs +49 -0
- package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/command-channel/runtime-control-lock.mjs +9 -0
- package/dist/substrate/runtime/cross-process/command-channel/runtime-control-lock.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/liveness.mjs +119 -0
- package/dist/substrate/runtime/cross-process/liveness.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/roster.mjs +275 -0
- package/dist/substrate/runtime/cross-process/roster.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/snapshot-reservation.d.mts +1 -0
- package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs +117 -0
- package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/stack-lock.d.mts +1 -0
- package/dist/substrate/runtime/cross-process/stack-lock.mjs +142 -0
- package/dist/substrate/runtime/cross-process/stack-lock.mjs.map +1 -0
- package/dist/substrate/runtime/current-plugin.mjs +15 -0
- package/dist/substrate/runtime/current-plugin.mjs.map +1 -0
- package/dist/substrate/runtime/errors.d.mts +1 -0
- package/dist/substrate/runtime/errors.mjs +76 -0
- package/dist/substrate/runtime/errors.mjs.map +1 -0
- package/dist/substrate/runtime/host-tree-tar/index.mjs +364 -0
- package/dist/substrate/runtime/host-tree-tar/index.mjs.map +1 -0
- package/dist/substrate/runtime/http-probe.d.mts +35 -0
- package/dist/substrate/runtime/http-probe.mjs +65 -0
- package/dist/substrate/runtime/http-probe.mjs.map +1 -0
- package/dist/substrate/runtime/lease-broker/index.d.mts +1 -0
- package/dist/substrate/runtime/lease-broker/service.d.mts +64 -0
- package/dist/substrate/runtime/lease-broker/service.mjs +155 -0
- package/dist/substrate/runtime/lease-broker/service.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/dep-graph.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/dep-graph.mjs +138 -0
- package/dist/substrate/runtime/lifecycle/dep-graph.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/index.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs +31 -0
- package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/plugin-registry.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/plugin-registry.mjs +133 -0
- package/dist/substrate/runtime/lifecycle/plugin-registry.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/ready-gate.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/ready-gate.mjs +34 -0
- package/dist/substrate/runtime/lifecycle/ready-gate.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/selective-restart.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/selective-restart.mjs +43 -0
- package/dist/substrate/runtime/lifecycle/selective-restart.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/signals.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/signals.mjs +64 -0
- package/dist/substrate/runtime/lifecycle/signals.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/state-machine.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/state-machine.mjs +38 -0
- package/dist/substrate/runtime/lifecycle/state-machine.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/watch-attribution.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/watch-attribution.mjs +27 -0
- package/dist/substrate/runtime/lifecycle/watch-attribution.mjs.map +1 -0
- package/dist/substrate/runtime/managed-container.d.mts +30 -0
- package/dist/substrate/runtime/managed-container.mjs +32 -0
- package/dist/substrate/runtime/managed-container.mjs.map +1 -0
- package/dist/substrate/runtime/manifest/manifest.mjs +73 -0
- package/dist/substrate/runtime/manifest/manifest.mjs.map +1 -0
- package/dist/substrate/runtime/mode-errors.d.mts +36 -0
- package/dist/substrate/runtime/observability/cascade-formatter.d.mts +1 -0
- package/dist/substrate/runtime/observability/cascade-formatter.mjs +135 -0
- package/dist/substrate/runtime/observability/cascade-formatter.mjs.map +1 -0
- package/dist/substrate/runtime/observability/formatter-registry.d.mts +1 -0
- package/dist/substrate/runtime/observability/formatter-registry.mjs +65 -0
- package/dist/substrate/runtime/observability/formatter-registry.mjs.map +1 -0
- package/dist/substrate/runtime/observability/index.d.mts +3 -0
- package/dist/substrate/runtime/observability/logger.d.mts +58 -0
- package/dist/substrate/runtime/observability/logger.mjs +89 -0
- package/dist/substrate/runtime/observability/logger.mjs.map +1 -0
- package/dist/substrate/runtime/observability/pretty-error.d.mts +1 -0
- package/dist/substrate/runtime/observability/pretty-error.mjs +119 -0
- package/dist/substrate/runtime/observability/pretty-error.mjs.map +1 -0
- package/dist/substrate/runtime/observability/process-lines.d.mts +31 -0
- package/dist/substrate/runtime/observability/process-lines.mjs +40 -0
- package/dist/substrate/runtime/observability/process-lines.mjs.map +1 -0
- package/dist/substrate/runtime/observability/redaction.d.mts +28 -0
- package/dist/substrate/runtime/observability/redaction.mjs +45 -0
- package/dist/substrate/runtime/observability/redaction.mjs.map +1 -0
- package/dist/substrate/runtime/observability/spans.d.mts +1 -0
- package/dist/substrate/runtime/observability/spans.mjs +87 -0
- package/dist/substrate/runtime/observability/spans.mjs.map +1 -0
- package/dist/substrate/runtime/observability/subprocess-capture.d.mts +2 -0
- package/dist/substrate/runtime/observability/subprocess-capture.mjs +82 -0
- package/dist/substrate/runtime/observability/subprocess-capture.mjs.map +1 -0
- package/dist/substrate/runtime/paths.d.mts +17 -0
- package/dist/substrate/runtime/paths.mjs +61 -0
- package/dist/substrate/runtime/paths.mjs.map +1 -0
- package/dist/substrate/runtime/port-broker/index.d.mts +1 -0
- package/dist/substrate/runtime/port-broker/service.d.mts +1 -0
- package/dist/substrate/runtime/port-broker/service.mjs +319 -0
- package/dist/substrate/runtime/port-broker/service.mjs.map +1 -0
- package/dist/substrate/runtime/post-acquire-tasks.d.mts +1 -0
- package/dist/substrate/runtime/post-acquire-tasks.mjs +34 -0
- package/dist/substrate/runtime/post-acquire-tasks.mjs.map +1 -0
- package/dist/substrate/runtime/probes.d.mts +51 -0
- package/dist/substrate/runtime/probes.mjs +84 -0
- package/dist/substrate/runtime/probes.mjs.map +1 -0
- package/dist/substrate/runtime/process-supervisor.d.mts +57 -0
- package/dist/substrate/runtime/process-supervisor.mjs +73 -0
- package/dist/substrate/runtime/process-supervisor.mjs.map +1 -0
- package/dist/substrate/runtime/projection/operational-endpoints.mjs +44 -0
- package/dist/substrate/runtime/projection/operational-endpoints.mjs.map +1 -0
- package/dist/substrate/runtime/projection/persisted.mjs +195 -0
- package/dist/substrate/runtime/projection/persisted.mjs.map +1 -0
- package/dist/substrate/runtime/projection/state-ref.mjs +48 -0
- package/dist/substrate/runtime/projection/state-ref.mjs.map +1 -0
- package/dist/substrate/runtime/projection/update.mjs +200 -0
- package/dist/substrate/runtime/projection/update.mjs.map +1 -0
- package/dist/substrate/runtime/retry-policy.d.mts +18 -0
- package/dist/substrate/runtime/retry-policy.mjs +16 -0
- package/dist/substrate/runtime/retry-policy.mjs.map +1 -0
- package/dist/substrate/runtime/run.mjs +86 -0
- package/dist/substrate/runtime/run.mjs.map +1 -0
- package/dist/substrate/runtime/runtime-decode.d.mts +32 -0
- package/dist/substrate/runtime/runtime-decode.mjs +53 -0
- package/dist/substrate/runtime/runtime-decode.mjs.map +1 -0
- package/dist/substrate/runtime/scoped-http-server.mjs +36 -0
- package/dist/substrate/runtime/scoped-http-server.mjs.map +1 -0
- package/dist/substrate/runtime/scoped-ref-map/service.mjs +83 -0
- package/dist/substrate/runtime/scoped-ref-map/service.mjs.map +1 -0
- package/dist/substrate/runtime/stage-and-swap/index.d.mts +1 -0
- package/dist/substrate/runtime/stage-and-swap/index.mjs +131 -0
- package/dist/substrate/runtime/stage-and-swap/index.mjs.map +1 -0
- package/dist/substrate/runtime/state-store/schema.mjs +36 -0
- package/dist/substrate/runtime/state-store/schema.mjs.map +1 -0
- package/dist/substrate/runtime/strategy-registry/chain-probe-for.d.mts +1 -0
- package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs +22 -0
- package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs.map +1 -0
- package/dist/substrate/runtime/strategy-registry/faucet-capability-for.d.mts +1 -0
- package/dist/substrate/runtime/strategy-registry/faucet-capability-for.mjs +30 -0
- package/dist/substrate/runtime/strategy-registry/faucet-capability-for.mjs.map +1 -0
- package/dist/substrate/runtime/strategy-registry/index.d.mts +1 -0
- package/dist/substrate/runtime/strategy-registry/service.d.mts +1 -0
- package/dist/substrate/runtime/strategy-registry/service.mjs +67 -0
- package/dist/substrate/runtime/strategy-registry/service.mjs.map +1 -0
- package/dist/substrate/runtime/sui-execute/index.d.mts +11 -0
- package/dist/substrate/runtime/sui-execute/index.mjs +144 -0
- package/dist/substrate/runtime/sui-execute/index.mjs.map +1 -0
- package/dist/substrate/runtime/sui-move-build/index.d.mts +1 -0
- package/dist/substrate/runtime/sui-move-build/index.mjs +283 -0
- package/dist/substrate/runtime/sui-move-build/index.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor.d.mts +1 -0
- package/dist/substrate/runtime/supervisor.mjs +831 -0
- package/dist/substrate/runtime/supervisor.mjs.map +1 -0
- package/dist/surfaces/cli/command-tree.mjs +276 -0
- package/dist/surfaces/cli/command-tree.mjs.map +1 -0
- package/dist/surfaces/cli/commands/config.mjs +31 -0
- package/dist/surfaces/cli/commands/config.mjs.map +1 -0
- package/dist/surfaces/cli/commands/confirm-node.mjs +26 -0
- package/dist/surfaces/cli/commands/confirm-node.mjs.map +1 -0
- package/dist/surfaces/cli/commands/confirm.mjs +26 -0
- package/dist/surfaces/cli/commands/confirm.mjs.map +1 -0
- package/dist/surfaces/cli/commands/doctor-probes.mjs +452 -0
- package/dist/surfaces/cli/commands/doctor-probes.mjs.map +1 -0
- package/dist/surfaces/cli/commands/doctor.mjs +38 -0
- package/dist/surfaces/cli/commands/doctor.mjs.map +1 -0
- package/dist/surfaces/cli/commands/prune-picker.mjs +347 -0
- package/dist/surfaces/cli/commands/prune-picker.mjs.map +1 -0
- package/dist/surfaces/cli/commands/prune.mjs +178 -0
- package/dist/surfaces/cli/commands/prune.mjs.map +1 -0
- package/dist/surfaces/cli/commands/snapshot.mjs +141 -0
- package/dist/surfaces/cli/commands/snapshot.mjs.map +1 -0
- package/dist/surfaces/cli/commands/status.mjs +95 -0
- package/dist/surfaces/cli/commands/status.mjs.map +1 -0
- package/dist/surfaces/cli/commands/supervisor-presence.mjs +33 -0
- package/dist/surfaces/cli/commands/supervisor-presence.mjs.map +1 -0
- package/dist/surfaces/cli/commands/wipe.mjs +28 -0
- package/dist/surfaces/cli/commands/wipe.mjs.map +1 -0
- package/dist/surfaces/cli/envelope.mjs +43 -0
- package/dist/surfaces/cli/envelope.mjs.map +1 -0
- package/dist/surfaces/cli/errors.mjs +110 -0
- package/dist/surfaces/cli/errors.mjs.map +1 -0
- package/dist/surfaces/cli/flags.mjs +56 -0
- package/dist/surfaces/cli/flags.mjs.map +1 -0
- package/dist/surfaces/cli/index.mjs +418 -0
- package/dist/surfaces/cli/index.mjs.map +1 -0
- package/dist/surfaces/cli/output.mjs +115 -0
- package/dist/surfaces/cli/output.mjs.map +1 -0
- package/dist/surfaces/cli/sysexits.mjs +139 -0
- package/dist/surfaces/cli/sysexits.mjs.map +1 -0
- package/dist/surfaces/tui/app.mjs +104 -0
- package/dist/surfaces/tui/app.mjs.map +1 -0
- package/dist/surfaces/tui/dashboard.mjs +261 -0
- package/dist/surfaces/tui/dashboard.mjs.map +1 -0
- package/dist/surfaces/tui/display-derivation.mjs +395 -0
- package/dist/surfaces/tui/display-derivation.mjs.map +1 -0
- package/dist/surfaces/tui/errors.mjs +11 -0
- package/dist/surfaces/tui/errors.mjs.map +1 -0
- package/dist/surfaces/tui/event-log.mjs +155 -0
- package/dist/surfaces/tui/event-log.mjs.map +1 -0
- package/dist/surfaces/tui/heartbeat.mjs +33 -0
- package/dist/surfaces/tui/heartbeat.mjs.map +1 -0
- package/dist/surfaces/tui/index.mjs +50 -0
- package/dist/surfaces/tui/index.mjs.map +1 -0
- package/dist/surfaces/tui/input.mjs +104 -0
- package/dist/surfaces/tui/input.mjs.map +1 -0
- package/dist/surfaces/tui/mode-detect.mjs +32 -0
- package/dist/surfaces/tui/mode-detect.mjs.map +1 -0
- package/dist/surfaces/tui/mount-ink.mjs +31 -0
- package/dist/surfaces/tui/mount-ink.mjs.map +1 -0
- package/dist/surfaces/tui/plain-renderer.mjs +170 -0
- package/dist/surfaces/tui/plain-renderer.mjs.map +1 -0
- package/dist/surfaces/tui/resource-table.mjs +507 -0
- package/dist/surfaces/tui/resource-table.mjs.map +1 -0
- package/images/_shared/signal-forward.sh +77 -0
- package/images/postgres/Dockerfile +32 -0
- package/images/seal/Dockerfile +68 -0
- package/images/seal/entrypoint.sh +65 -0
- package/images/sui/Dockerfile +73 -0
- package/images/sui/entrypoint.sh +244 -0
- package/images/sui-fork/Dockerfile +53 -0
- package/images/sui-fork/entrypoint.sh +51 -0
- package/images/walrus/Dockerfile +122 -0
- package/images/walrus/deploy-walrus.sh +305 -0
- package/images/walrus/run-walrus.sh +53 -0
- package/package.json +94 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codegen.mjs","names":[],"sources":["../../../src/plugins/wallet/codegen.ts"],"sourcesContent":["// Wallet plugin — Codegenable contribution.\n//\n// Architecture (15-wallet.md §\"Capabilities PRODUCED\" + §\"Codegen\n// emits a `dapp-kit-config.ts`\"):\n//\n// - The browser-side dev-wallet adapter is the cross-boundary\n// consumer. It reads a typed `dapp-kit-config` value at startup,\n// constructs a `DevstackSignerAdapter`, and registers it with\n// `@mysten/dapp-kit`'s wallet-standard surface (in user-app\n// bundle code — devstack itself NEVER imports dapp-kit).\n//\n// - The emitted file lives at `dapp-kit/config.ts` under the staging\n// dir. The generated module owns the exported config value's type.\n//\n// SENSITIVE FLAG (task requirement #5 — manifest-vs-token threat\n// surface):\n//\n// - The emitted file carries the unredacted pair URL (incl. the\n// `#token=<32-hex>` fragment) so the dev-wallet adapter can wire\n// itself up without a side-channel read.\n// - Therefore `sensitive: true`. The codegen orchestrator tightens\n// the file mode to `0o600` on emit AND injects the file path into\n// `.gitignore`.\n//\n// Distilled-doc tension absorbed (15-wallet.md \"Manifest carries\n// unredacted pair URL while token file is 0o600 — pick one\"):\n//\n// We pick \"tighten the emit perms\". The token still lives in a\n// `0o600` side-channel file (see `pairing.ts:tokenPath`), AND the\n// codegen emit is also `0o600` via the sensitive flag. The legacy\n// `.devstack/manifest.json` write that left the pair URL world-\n// readable is GONE — the rewrite no longer emits an unredacted pair\n// URL into the manifest. Only the codegen file carries it, and that\n// file is tightened.\n//\n// See the report's §\"Architecture-doc revisions\" for the\n// architecture-doc note that needs to land alongside this.\n\nimport { Effect } from 'effect';\n\nimport type { CodegenableDecl } from '../../contracts/codegenable.ts';\n\nimport { redactToken } from './pairing.ts';\n\n// ----------------------------------------------------------------------\n// Emitted shape\n// ----------------------------------------------------------------------\n\n/** The typed shape `dapp-kit/config.ts` exports. Downstream consumers\n * (the user-app's dapp-kit boot code) import and consume this.\n *\n * Field shape mirrors what `DevstackSignerAdapter` needs:\n *\n * - `walletUrl` : the wallet HTTP server's URL (router-fronted\n * host form when available, direct-loopback\n * fallback otherwise).\n * - `pairUrl` : `walletUrl` + `/#token=<32-hex>` (single\n * source of truth for the token).\n * - `protocolPaths` : path constants the adapter reads. Mirrored\n * here so the adapter doesn't depend on a\n * separate import.\n * - `chain` : Sui chain id the wallet's accounts are\n * scoped to. Surfaced so dapp-kit can pin its\n * active chain.\n */\nexport interface DappKitConfigBindings {\n\treadonly walletUrl: string;\n\treadonly pairUrl: string;\n\treadonly chain: string;\n\treadonly protocolPaths: {\n\t\treadonly health: string;\n\t\treadonly accounts: string;\n\t\treadonly signTransaction: string;\n\t\treadonly signPersonalMessage: string;\n\t\treadonly execute: string;\n\t};\n}\n\n// ----------------------------------------------------------------------\n// Decl construction\n// ----------------------------------------------------------------------\n\n/**\n * Construct the Codegenable contribution.\n *\n * Emits `dapp-kit/config.ts` with `sensitive: true` → the orchestrator\n * writes the file with `0o600` and gitignores it. The emitted shape\n * carries the unredacted pair URL; the side-channel token file is\n * also `0o600`.\n *\n * The `resolved` arg is supplied AFTER acquire (the substrate's\n * \"resolve-once\" memo). At factory time the barrel passes a\n * placeholder so the type plumbing works; at codegen time the\n * substrate re-evaluates with the resolved values.\n */\nexport const makeWalletCodegen = (\n\tresolved: DappKitConfigBindings,\n): CodegenableDecl<'dapp-kit-config'> => ({\n\tkind: 'codegenable',\n\temitterName: 'dapp-kit-config',\n\toutputPath: 'dapp-kit/config.ts',\n\t// SENSITIVE: drives 0o600 + .gitignore. The architecture has this\n\t// hook (`SnapshotableDecl` mirrors it for the snapshot subtree).\n\tsensitive: true,\n\temit: (ctx) =>\n\t\tEffect.gen(function* () {\n\t\t\t// Span annotation logs ONLY the redacted form — defense-in-\n\t\t\t// depth so any debug-mode span dump doesn't leak the token.\n\t\t\tyield* Effect.annotateCurrentSpan({\n\t\t\t\t'wallet.codegen.pairUrl': redactToken(resolved.pairUrl),\n\t\t\t\t'wallet.codegen.walletUrl': resolved.walletUrl,\n\t\t\t});\n\t\t\tctx.exportConst('dappKitConfig', resolved);\n\t\t\treturn ctx.done();\n\t\t}),\n});\n"],"mappings":";;;;;;;;;;;;;;;;AA+FA,MAAa,qBACZ,cACyC;CACzC,MAAM;CACN,aAAa;CACb,YAAY;CAGZ,WAAW;CACX,OAAO,QACN,OAAO,IAAI,aAAa;AAGvB,SAAO,OAAO,oBAAoB;GACjC,0BAA0B,YAAY,SAAS,QAAQ;GACvD,4BAA4B,SAAS;GACrC,CAAC;AACF,MAAI,YAAY,iBAAiB,SAAS;AAC1C,SAAO,IAAI,MAAM;GAChB;CACH"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
//#region src/plugins/wallet/errors.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Phases for `WalletBootError`. Closed sum — adding a phase means
|
|
4
|
+
* editing this list AND any cause-walker display tables.
|
|
5
|
+
*
|
|
6
|
+
* - `listen` : `http.Server.listen` rejected (typically
|
|
7
|
+
* EADDRINUSE after port-broker forward-scan, or
|
|
8
|
+
* EACCES on a privileged port).
|
|
9
|
+
* - `allocate-port` : the supervisor's port broker could not yield
|
|
10
|
+
* a free port near the preferred one.
|
|
11
|
+
* - `read-token` : the on-disk pairing-token file existed but
|
|
12
|
+
* could not be read (EACCES, EIO).
|
|
13
|
+
* - `write-token` : the freshly-minted token file could not be
|
|
14
|
+
* persisted (ENOSPC, EROFS).
|
|
15
|
+
* - `bind-account` : a consumed account tag failed to resolve at
|
|
16
|
+
* acquire time (re-thrown with a wallet phase).
|
|
17
|
+
* - `route-url` : failed to construct the router-fronted URL
|
|
18
|
+
* for the generated dapp-kit config.
|
|
19
|
+
* - `no-accounts` : account inference resolved to an empty set.
|
|
20
|
+
*/
|
|
21
|
+
type WalletBootPhase = 'listen' | 'allocate-port' | 'read-token' | 'write-token' | 'bind-account' | 'route-url' | 'no-accounts';
|
|
22
|
+
/** Boot-time wallet error — raised by the plugin's acquire body. */
|
|
23
|
+
interface WalletBootError {
|
|
24
|
+
readonly _tag: 'WalletBootError';
|
|
25
|
+
readonly phase: WalletBootPhase;
|
|
26
|
+
readonly message: string;
|
|
27
|
+
readonly hint?: string;
|
|
28
|
+
readonly cause?: unknown;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Phases for `WalletRequestError`. Each maps to an HTTP status the
|
|
32
|
+
* server emits (status code carried explicitly so renderers can keep
|
|
33
|
+
* the mapping in one place rather than re-deriving it).
|
|
34
|
+
*
|
|
35
|
+
* - `origin-missing` : 403 — no Origin header on a protected
|
|
36
|
+
* route (closes the curl/non-browser
|
|
37
|
+
* bypass; mandatory by C12).
|
|
38
|
+
* - `origin-forbidden` : 403 — Origin not in the stack-scoped
|
|
39
|
+
* allowlist.
|
|
40
|
+
* - `unauthorized` : 401 — bearer absent or did not survive
|
|
41
|
+
* constant-time compare.
|
|
42
|
+
* - `route-not-found` : 404 — `/api/v1/devstack/*` path with no
|
|
43
|
+
* handler wired.
|
|
44
|
+
* - `address-not-found` : 404 — sign request named an address the
|
|
45
|
+
* wallet did not bind.
|
|
46
|
+
* - `body-invalid` : 400 — JSON parse, missing required
|
|
47
|
+
* field, non-base64 bytes, body >64 KiB.
|
|
48
|
+
* - `sign-route-failed` : 500 — the routed `AccountValue` sign
|
|
49
|
+
* closure raised an `AccountSignError`.
|
|
50
|
+
*/
|
|
51
|
+
type WalletRequestPhase = 'origin-missing' | 'origin-forbidden' | 'unauthorized' | 'route-not-found' | 'address-not-found' | 'body-invalid' | 'sign-route-failed';
|
|
52
|
+
/** Request-time wallet error — raised by the in-process HTTP handlers.
|
|
53
|
+
* Carries the HTTP status the server will write and an optional inner
|
|
54
|
+
* cause (e.g. an `AccountSignError` for `sign-route-failed`). */
|
|
55
|
+
interface WalletRequestError {
|
|
56
|
+
readonly _tag: 'WalletRequestError';
|
|
57
|
+
readonly phase: WalletRequestPhase;
|
|
58
|
+
readonly httpStatus: number;
|
|
59
|
+
readonly message: string;
|
|
60
|
+
readonly cause?: unknown;
|
|
61
|
+
}
|
|
62
|
+
/** Union of every error a wallet caller may encounter. */
|
|
63
|
+
type WalletError = WalletBootError | WalletRequestError;
|
|
64
|
+
//#endregion
|
|
65
|
+
export { WalletBootError, WalletBootPhase, WalletError, WalletRequestError, WalletRequestPhase };
|
|
66
|
+
//# sourceMappingURL=errors.d.mts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/plugins/wallet/errors.ts
|
|
2
|
+
const walletBootError = (parts) => ({
|
|
3
|
+
_tag: "WalletBootError",
|
|
4
|
+
...parts
|
|
5
|
+
});
|
|
6
|
+
const walletRequestError = (parts) => ({
|
|
7
|
+
_tag: "WalletRequestError",
|
|
8
|
+
...parts
|
|
9
|
+
});
|
|
10
|
+
/** Error tags this plugin contributes — surfaced to the cause walker
|
|
11
|
+
* via `PluginErrorContribution`. */
|
|
12
|
+
const WALLET_ERROR_TAGS = ["WalletBootError", "WalletRequestError"];
|
|
13
|
+
//#endregion
|
|
14
|
+
export { WALLET_ERROR_TAGS, walletBootError, walletRequestError };
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=errors.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.mjs","names":[],"sources":["../../../src/plugins/wallet/errors.ts"],"sourcesContent":["// Wallet plugin — typed errors.\n//\n// Distilled-doc finding (15-wallet.md \"Failure modes\"): the wallet's\n// failure surface separates BOOT-time errors from REQUEST-time errors.\n// Boot errors surface as `WalletBootError` (port allocation, listen\n// failure, token-file write); request errors surface as\n// `WalletRequestError` (auth, origin, route, body parse, sign-route\n// failure). The two channels never mix — request errors flow back to\n// the HTTP client as JSON envelopes, boot errors flow up the supervisor\n// scope.\n//\n// Effect v4: plain interface + `_tag` literal discriminator (no\n// subclassing). Per-plugin tagged-error convention — the cause walker\n// dispatches on `_tag`.\n\n/**\n * Phases for `WalletBootError`. Closed sum — adding a phase means\n * editing this list AND any cause-walker display tables.\n *\n * - `listen` : `http.Server.listen` rejected (typically\n * EADDRINUSE after port-broker forward-scan, or\n * EACCES on a privileged port).\n * - `allocate-port` : the supervisor's port broker could not yield\n * a free port near the preferred one.\n * - `read-token` : the on-disk pairing-token file existed but\n * could not be read (EACCES, EIO).\n * - `write-token` : the freshly-minted token file could not be\n * persisted (ENOSPC, EROFS).\n * - `bind-account` : a consumed account tag failed to resolve at\n * acquire time (re-thrown with a wallet phase).\n * - `route-url` : failed to construct the router-fronted URL\n * for the generated dapp-kit config.\n * - `no-accounts` : account inference resolved to an empty set.\n */\nexport type WalletBootPhase =\n\t| 'listen'\n\t| 'allocate-port'\n\t| 'read-token'\n\t| 'write-token'\n\t| 'bind-account'\n\t| 'route-url'\n\t| 'no-accounts';\n\n/** Boot-time wallet error — raised by the plugin's acquire body. */\nexport interface WalletBootError {\n\treadonly _tag: 'WalletBootError';\n\treadonly phase: WalletBootPhase;\n\treadonly message: string;\n\treadonly hint?: string;\n\treadonly cause?: unknown;\n}\n\nexport const walletBootError = (parts: Omit<WalletBootError, '_tag'>): WalletBootError => ({\n\t_tag: 'WalletBootError',\n\t...parts,\n});\n\n/**\n * Phases for `WalletRequestError`. Each maps to an HTTP status the\n * server emits (status code carried explicitly so renderers can keep\n * the mapping in one place rather than re-deriving it).\n *\n * - `origin-missing` : 403 — no Origin header on a protected\n * route (closes the curl/non-browser\n * bypass; mandatory by C12).\n * - `origin-forbidden` : 403 — Origin not in the stack-scoped\n * allowlist.\n * - `unauthorized` : 401 — bearer absent or did not survive\n * constant-time compare.\n * - `route-not-found` : 404 — `/api/v1/devstack/*` path with no\n * handler wired.\n * - `address-not-found` : 404 — sign request named an address the\n * wallet did not bind.\n * - `body-invalid` : 400 — JSON parse, missing required\n * field, non-base64 bytes, body >64 KiB.\n * - `sign-route-failed` : 500 — the routed `AccountValue` sign\n * closure raised an `AccountSignError`.\n */\nexport type WalletRequestPhase =\n\t| 'origin-missing'\n\t| 'origin-forbidden'\n\t| 'unauthorized'\n\t| 'route-not-found'\n\t| 'address-not-found'\n\t| 'body-invalid'\n\t| 'sign-route-failed';\n\n/** Request-time wallet error — raised by the in-process HTTP handlers.\n * Carries the HTTP status the server will write and an optional inner\n * cause (e.g. an `AccountSignError` for `sign-route-failed`). */\nexport interface WalletRequestError {\n\treadonly _tag: 'WalletRequestError';\n\treadonly phase: WalletRequestPhase;\n\treadonly httpStatus: number;\n\treadonly message: string;\n\treadonly cause?: unknown;\n}\n\nexport const walletRequestError = (\n\tparts: Omit<WalletRequestError, '_tag'>,\n): WalletRequestError => ({ _tag: 'WalletRequestError', ...parts });\n\n/** Union of every error a wallet caller may encounter. */\nexport type WalletError = WalletBootError | WalletRequestError;\n\n/** Error tags this plugin contributes — surfaced to the cause walker\n * via `PluginErrorContribution`. */\nexport const WALLET_ERROR_TAGS: ReadonlyArray<WalletError['_tag']> = [\n\t'WalletBootError',\n\t'WalletRequestError',\n] as const;\n"],"mappings":";AAoDA,MAAa,mBAAmB,WAA2D;CAC1F,MAAM;CACN,GAAG;CACH;AA2CD,MAAa,sBACZ,WACyB;CAAE,MAAM;CAAsB,GAAG;CAAO;;;AAOlE,MAAa,oBAAwD,CACpE,mBACA,qBACA"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { CodegenableDecl } from "../../contracts/codegenable.mjs";
|
|
2
|
+
import { RoutableDecl } from "../../contracts/routable.mjs";
|
|
3
|
+
import { SnapshotableDecl } from "../../contracts/snapshotable.mjs";
|
|
4
|
+
import { Plugin, ResourceRef } from "../../substrate/plugin.mjs";
|
|
5
|
+
import { SeedObjectsAccumulator } from "../sui/seed-objects.mjs";
|
|
6
|
+
import { SuiClient } from "../sui/mode/shared.mjs";
|
|
7
|
+
import { SuiOptions } from "../sui/mode/spec.mjs";
|
|
8
|
+
import { DappKitConfigBindings } from "./codegen.mjs";
|
|
9
|
+
import { WalletBootError, WalletBootPhase, WalletError, WalletRequestError, WalletRequestPhase } from "./errors.mjs";
|
|
10
|
+
import { PairingToken } from "./pairing.mjs";
|
|
11
|
+
import { WalletServerHandle } from "./server.mjs";
|
|
12
|
+
import { WALLET_ACCOUNTS_ALL, WalletAccountMember, WalletOptions, WalletValue } from "./service.mjs";
|
|
13
|
+
//#region src/plugins/wallet/index.d.ts
|
|
14
|
+
/**
|
|
15
|
+
* Construct the wallet plugin.
|
|
16
|
+
*
|
|
17
|
+
* Two parts of the wallet:
|
|
18
|
+
*
|
|
19
|
+
* - HERE: HTTP server + token + pairing protocol + codegen.
|
|
20
|
+
* - DEV-WALLET PACKAGE: `@mysten/dapp-kit`-shaped adapter the
|
|
21
|
+
* user-app's frontend bundle imports.
|
|
22
|
+
*
|
|
23
|
+
* Distilled-doc invariant (15-wallet.md "Always explicit"): the
|
|
24
|
+
* composer NEVER auto-mounts the wallet. The user calls `wallet()`,
|
|
25
|
+
* `wallet({ accounts: 'all' })`, or `wallet({ accounts: [alice, bob] })`
|
|
26
|
+
* and passes the result to `defineDevstack(...)`.
|
|
27
|
+
*
|
|
28
|
+
* ### Security defaults
|
|
29
|
+
*
|
|
30
|
+
* - `bindAddress: '0.0.0.0'`. The router runs in Docker, so on
|
|
31
|
+
* native Linux it reaches this host process through the Docker
|
|
32
|
+
* host-gateway address instead of host loopback. The published
|
|
33
|
+
* wallet URL remains stack-scoped through the router.
|
|
34
|
+
*
|
|
35
|
+
* - `allowLocalhostVite: false`. The bare `http://localhost:<vite>`
|
|
36
|
+
* form is OFF by default — opt-in for headless test runners /
|
|
37
|
+
* custom dev hosts. Defaulting it on would let a sibling stack
|
|
38
|
+
* running vite on the same port pair with this wallet (because
|
|
39
|
+
* `localhost` is not stack-scoped). See `origin-policy.ts` for
|
|
40
|
+
* the rationale.
|
|
41
|
+
*
|
|
42
|
+
* - Pairing token in URL fragment only (`#token=<32-hex>`). Never
|
|
43
|
+
* in query params (would land in access logs / referrers).
|
|
44
|
+
*
|
|
45
|
+
* - Constant-time bearer compare on every request.
|
|
46
|
+
*
|
|
47
|
+
* - Token file `0o600`. Codegen output (`dapp-kit/config.ts`)
|
|
48
|
+
* `0o600` + gitignored via `sensitive: true`.
|
|
49
|
+
*/
|
|
50
|
+
declare function wallet<const Accounts extends ReadonlyArray<WalletAccountMember>>(opts: Omit<WalletOptions, 'accounts'> & {
|
|
51
|
+
readonly accounts: Accounts;
|
|
52
|
+
}): ReturnType<typeof makeWalletMember<Accounts>>;
|
|
53
|
+
declare function wallet(opts: Omit<WalletOptions, 'accounts'> & {
|
|
54
|
+
readonly accounts: typeof WALLET_ACCOUNTS_ALL;
|
|
55
|
+
}): ReturnType<typeof makeWalletMember<readonly []>>;
|
|
56
|
+
declare function wallet(): ReturnType<typeof makeWalletMember<readonly []>>;
|
|
57
|
+
declare function makeWalletMember<Accounts extends ReadonlyArray<WalletAccountMember>>(opts: WalletOptions, accounts: Accounts): Plugin<"wallet", WalletValue, readonly [ResourceRef<"sui", SuiClient & {
|
|
58
|
+
readonly mode: SuiOptions["mode"];
|
|
59
|
+
readonly seedObjects: SeedObjectsAccumulator;
|
|
60
|
+
}>, ...Accounts], readonly [SnapshotableDecl, CodegenableDecl<"dapp-kit-config">, RoutableDecl]>;
|
|
61
|
+
//#endregion
|
|
62
|
+
export { wallet };
|
|
63
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { definePlugin, resource } from "../../substrate/plugin.mjs";
|
|
2
|
+
import { pluginErrorContributions } from "../../api/plugin-errors.mjs";
|
|
3
|
+
import { IdentityContext, StackPathsService } from "../../substrate/runtime/paths.mjs";
|
|
4
|
+
import { PortBrokerService } from "../../substrate/runtime/port-broker/service.mjs";
|
|
5
|
+
import { renderUrl, routerHostname } from "../../orchestrators/router/hostname.mjs";
|
|
6
|
+
import { suiResource } from "../sui/index.mjs";
|
|
7
|
+
import { HOST_SERVICE_DEFAULT_ENTRYPOINT_PORT } from "../host-service/routable.mjs";
|
|
8
|
+
import { WALLET_ERROR_TAGS, walletBootError } from "./errors.mjs";
|
|
9
|
+
import "./protocol.mjs";
|
|
10
|
+
import "./pairing.mjs";
|
|
11
|
+
import { makeWalletCodegen } from "./codegen.mjs";
|
|
12
|
+
import { WALLET_ENTRYPOINT_PORT, makeWalletRoutable } from "./routable.mjs";
|
|
13
|
+
import { makeWalletSnapshotable } from "./snapshot.mjs";
|
|
14
|
+
import "./origin-policy.mjs";
|
|
15
|
+
import "./server.mjs";
|
|
16
|
+
import { acquireWallet } from "./service.mjs";
|
|
17
|
+
import { Effect } from "effect";
|
|
18
|
+
//#region src/plugins/wallet/index.ts
|
|
19
|
+
/** Composer-side expander hook for `wallet({ accounts: 'all' })`. The
|
|
20
|
+
* wallet factory cannot know the stack's account members at its own
|
|
21
|
+
* call site (members are introduced positionally to `defineDevstack`
|
|
22
|
+
* AFTER the wallet factory has returned). The composer detects this
|
|
23
|
+
* symbol on a member returned by the wallet factory, collects every
|
|
24
|
+
* account-providing member from the final stack, and invokes the
|
|
25
|
+
* hook to produce the real wallet member with a populated dependencies
|
|
26
|
+
* tuple — keeping the dep-graph edges accurate.
|
|
27
|
+
*
|
|
28
|
+
* Symbol-keyed (not a named property) so it cannot collide with any
|
|
29
|
+
* user-facing member field. Globally registered via `Symbol.for(...)`
|
|
30
|
+
* so the composer can look it up without importing the wallet
|
|
31
|
+
* module's symbol-binding (this side-steps a TS2742 inferred-type
|
|
32
|
+
* portability error: a `unique symbol`-keyed property in the wallet
|
|
33
|
+
* member's return type would leak the symbol's compile-time identity
|
|
34
|
+
* into the user's `defineDevstack(...)` inferred Stack type, forcing
|
|
35
|
+
* every example's default export to carry an explicit annotation). */
|
|
36
|
+
const WALLET_EXPAND_ACCOUNTS_ALL = Symbol.for("devstack.wallet.expand-accounts-all");
|
|
37
|
+
/** The wallet plugin's resource identity. ONE per stack (15-wallet.md
|
|
38
|
+
* "singleton per stack"). The id is `'wallet'` (singular). */
|
|
39
|
+
const walletResource = resource("wallet");
|
|
40
|
+
const walletErrorContributions = pluginErrorContributions(WALLET_ERROR_TAGS);
|
|
41
|
+
function wallet(opts) {
|
|
42
|
+
const resolvedOpts = opts ?? { accounts: "all" };
|
|
43
|
+
if (resolvedOpts.accounts === "all") {
|
|
44
|
+
const placeholder = makeWalletMember(resolvedOpts, []);
|
|
45
|
+
const expander = (accountMembers) => makeWalletMember({
|
|
46
|
+
...resolvedOpts,
|
|
47
|
+
accounts: accountMembers
|
|
48
|
+
}, accountMembers);
|
|
49
|
+
placeholder[WALLET_EXPAND_ACCOUNTS_ALL] = expander;
|
|
50
|
+
return placeholder;
|
|
51
|
+
}
|
|
52
|
+
return makeWalletMember(resolvedOpts, resolvedOpts.accounts);
|
|
53
|
+
}
|
|
54
|
+
function makeWalletMember(opts, accounts) {
|
|
55
|
+
const dependencies = [suiResource, ...accounts];
|
|
56
|
+
const resolvedOpts = {
|
|
57
|
+
...opts,
|
|
58
|
+
accounts
|
|
59
|
+
};
|
|
60
|
+
return definePlugin({
|
|
61
|
+
id: walletResource.id,
|
|
62
|
+
dependsOn: dependencies,
|
|
63
|
+
role: "service",
|
|
64
|
+
start: (deps) => Effect.gen(function* () {
|
|
65
|
+
const identity = yield* IdentityContext;
|
|
66
|
+
const paths = yield* StackPathsService;
|
|
67
|
+
const portBroker = yield* PortBrokerService;
|
|
68
|
+
const [, ...resolvedAccounts] = deps;
|
|
69
|
+
const routerFrontedUrl = yield* routerHostname(identity, "api").pipe(Effect.map((hostname) => renderUrl({
|
|
70
|
+
protocol: "http",
|
|
71
|
+
hostname,
|
|
72
|
+
port: WALLET_ENTRYPOINT_PORT
|
|
73
|
+
})), Effect.mapError((err) => walletBootError({
|
|
74
|
+
phase: "route-url",
|
|
75
|
+
message: `wallet router URL construction failed: ${err.detail}`,
|
|
76
|
+
cause: err
|
|
77
|
+
})));
|
|
78
|
+
const routedAppOrigin = yield* routerHostname(identity, "dev").pipe(Effect.map((hostname) => renderUrl({
|
|
79
|
+
protocol: "http",
|
|
80
|
+
hostname,
|
|
81
|
+
port: HOST_SERVICE_DEFAULT_ENTRYPOINT_PORT
|
|
82
|
+
})), Effect.mapError((err) => walletBootError({
|
|
83
|
+
phase: "route-url",
|
|
84
|
+
message: `wallet app-origin URL construction failed: ${err.detail}`,
|
|
85
|
+
cause: err
|
|
86
|
+
})));
|
|
87
|
+
return yield* acquireWallet(resolvedOpts, {
|
|
88
|
+
app: identity.app,
|
|
89
|
+
stack: identity.stack,
|
|
90
|
+
chain: identity.chain,
|
|
91
|
+
stateRoot: paths.stackRoot,
|
|
92
|
+
vitePortForThisStack: null,
|
|
93
|
+
allocatePort: (preferred, probeHost) => portBroker.allocate({
|
|
94
|
+
kind: "wallet",
|
|
95
|
+
preferredPort: preferred,
|
|
96
|
+
...probeHost === void 0 ? {} : { probeHost }
|
|
97
|
+
}).pipe(Effect.map((alloc) => alloc.port), Effect.mapError((err) => walletBootError({
|
|
98
|
+
phase: "allocate-port",
|
|
99
|
+
message: `port-broker allocate failed: ${err.detail}`,
|
|
100
|
+
hint: err.reason === "preferred-busy" ? "another plugin in this stack is using your preferred port; omit `port` to let the broker pick." : err.reason === "no-free-port" ? "the wallet kind-window is exhausted; check for stray devstack supervisors holding ports." : "bind-probe failed — likely a privileged port or jail restriction.",
|
|
101
|
+
cause: err
|
|
102
|
+
}))),
|
|
103
|
+
resolveAccounts: () => Effect.succeed(resolvedAccounts),
|
|
104
|
+
routerFrontedUrl,
|
|
105
|
+
routedAppOrigin,
|
|
106
|
+
supervisorCtx: void 0
|
|
107
|
+
});
|
|
108
|
+
}),
|
|
109
|
+
errorContributions: walletErrorContributions,
|
|
110
|
+
capabilities: ({ value: resolved, runtime: acquireCtx }) => {
|
|
111
|
+
return [
|
|
112
|
+
makeWalletSnapshotable(),
|
|
113
|
+
makeWalletCodegen(resolved.bindings),
|
|
114
|
+
makeWalletRoutable({
|
|
115
|
+
app: acquireCtx.identity.app,
|
|
116
|
+
stack: acquireCtx.identity.stack,
|
|
117
|
+
port: resolved.localPort
|
|
118
|
+
})
|
|
119
|
+
];
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
//#endregion
|
|
124
|
+
export { WALLET_EXPAND_ACCOUNTS_ALL, wallet };
|
|
125
|
+
|
|
126
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugins/wallet/index.ts"],"sourcesContent":["// Wallet plugin — barrel + `wallet(opts?)` factory.\n//\n// Architecture (15-wallet.md):\n//\n// The wallet bridges devstack (the supervisor host) and the\n// browser-side dev-wallet adapter (in the separate `dev-wallet`\n// package). Two parts:\n//\n// 1. The IN-PROCESS HTTP server. Owned here. Boot at acquire,\n// serve `/api/v1/devstack/*` routes (health, accounts,\n// sign-transaction, sign-personal-message, execute).\n//\n// 2. The BROWSER-SIDE ADAPTER. Owned by `dev-wallet`. Reads the\n// codegen-emitted `dapp-kit/config.ts`, constructs a\n// `DevstackSignerAdapter`, registers it with `@mysten/dapp-\n// kit`'s wallet-standard surface.\n//\n// The HTTP protocol is the ONE cross-boundary contract. THIS PACKAGE\n// NEVER IMPORTS `@mysten/dapp-kit*` OR `@mysten/wallet-standard`.\n//\n// Capabilities emitted:\n//\n// 1. Snapshotable — pairing token under `wallet/token`.\n// 2. Codegenable — `dapp-kit-config` bindings (the dev-wallet\n// adapter consumes this). Sensitive flag set — 0o600 + gitignore.\n// 3. Routable — wallet UI URL on the stack-scoped router.\n\nimport { Effect } from 'effect';\n\nimport { definePlugin, resource } from '../../api/define-plugin.ts';\nimport { pluginErrorContributions } from '../../api/plugin-errors.ts';\nimport { IdentityContext, StackPathsService } from '../../substrate/runtime/paths.ts';\nimport { PortBrokerService } from '../../substrate/runtime/port-broker/index.ts';\nimport { renderUrl, routerHostname } from '../../orchestrators/router/hostname.ts';\nimport { suiResource } from '../sui/index.ts';\nimport {\n\tHOST_SERVICE_DEFAULT_ENDPOINT_NAME,\n\tHOST_SERVICE_DEFAULT_ENTRYPOINT_PORT,\n} from '../host-service/routable.ts';\n\nimport { makeWalletCodegen } from './codegen.ts';\nimport { WALLET_ERROR_TAGS, walletBootError } from './errors.ts';\nimport { makeWalletRoutable, WALLET_ENTRYPOINT_PORT, WALLET_ROUTE_ROLE } from './routable.ts';\nimport { makeWalletSnapshotable } from './snapshot.ts';\nimport {\n\tacquireWallet,\n\tWALLET_ACCOUNTS_ALL,\n\ttype WalletAcquireContext,\n\ttype WalletAccountMember,\n\ttype WalletOptions,\n\ttype WalletValue,\n} from './service.ts';\nimport type { AnyPlugin } from '../../substrate/plugin.ts';\n\n/** Composer-side expander hook for `wallet({ accounts: 'all' })`. The\n * wallet factory cannot know the stack's account members at its own\n * call site (members are introduced positionally to `defineDevstack`\n * AFTER the wallet factory has returned). The composer detects this\n * symbol on a member returned by the wallet factory, collects every\n * account-providing member from the final stack, and invokes the\n * hook to produce the real wallet member with a populated dependencies\n * tuple — keeping the dep-graph edges accurate.\n *\n * Symbol-keyed (not a named property) so it cannot collide with any\n * user-facing member field. Globally registered via `Symbol.for(...)`\n * so the composer can look it up without importing the wallet\n * module's symbol-binding (this side-steps a TS2742 inferred-type\n * portability error: a `unique symbol`-keyed property in the wallet\n * member's return type would leak the symbol's compile-time identity\n * into the user's `defineDevstack(...)` inferred Stack type, forcing\n * every example's default export to carry an explicit annotation). */\nexport const WALLET_EXPAND_ACCOUNTS_ALL: symbol = Symbol.for('devstack.wallet.expand-accounts-all');\n\n/** Runtime-only expander shape attached to the placeholder wallet\n * member when the user passes `accounts: 'all'`. The composer reads\n * `member[WALLET_EXPAND_ACCOUNTS_ALL](accountMembers)` to mint the\n * resolved-tuple wallet member.\n *\n * Kept as a value-level shape (not a type-level intersection on the\n * factory's return signature) so the symbol-keyed property does NOT\n * leak into the user's inferred Stack type (see TS2742 note above). */\nexport type WalletExpandAccountsAllExpander = (\n\taccountMembers: ReadonlyArray<WalletAccountMember>,\n) => AnyPlugin;\n\n// ----------------------------------------------------------------------\n// Resource identity\n// ----------------------------------------------------------------------\n\n/** The wallet plugin's resource identity. ONE per stack (15-wallet.md\n * \"singleton per stack\"). The id is `'wallet'` (singular). */\nconst walletResource = resource<'wallet', WalletValue>('wallet');\nconst walletErrorContributions = pluginErrorContributions(WALLET_ERROR_TAGS);\n\n// ----------------------------------------------------------------------\n// User-facing factory\n// ----------------------------------------------------------------------\n\n/**\n * Construct the wallet plugin.\n *\n * Two parts of the wallet:\n *\n * - HERE: HTTP server + token + pairing protocol + codegen.\n * - DEV-WALLET PACKAGE: `@mysten/dapp-kit`-shaped adapter the\n * user-app's frontend bundle imports.\n *\n * Distilled-doc invariant (15-wallet.md \"Always explicit\"): the\n * composer NEVER auto-mounts the wallet. The user calls `wallet()`,\n * `wallet({ accounts: 'all' })`, or `wallet({ accounts: [alice, bob] })`\n * and passes the result to `defineDevstack(...)`.\n *\n * ### Security defaults\n *\n * - `bindAddress: '0.0.0.0'`. The router runs in Docker, so on\n * native Linux it reaches this host process through the Docker\n * host-gateway address instead of host loopback. The published\n * wallet URL remains stack-scoped through the router.\n *\n * - `allowLocalhostVite: false`. The bare `http://localhost:<vite>`\n * form is OFF by default — opt-in for headless test runners /\n * custom dev hosts. Defaulting it on would let a sibling stack\n * running vite on the same port pair with this wallet (because\n * `localhost` is not stack-scoped). See `origin-policy.ts` for\n * the rationale.\n *\n * - Pairing token in URL fragment only (`#token=<32-hex>`). Never\n * in query params (would land in access logs / referrers).\n *\n * - Constant-time bearer compare on every request.\n *\n * - Token file `0o600`. Codegen output (`dapp-kit/config.ts`)\n * `0o600` + gitignored via `sensitive: true`.\n */\nexport function wallet<const Accounts extends ReadonlyArray<WalletAccountMember>>(\n\topts: Omit<WalletOptions, 'accounts'> & { readonly accounts: Accounts },\n): ReturnType<typeof makeWalletMember<Accounts>>;\nexport function wallet(\n\topts: Omit<WalletOptions, 'accounts'> & { readonly accounts: typeof WALLET_ACCOUNTS_ALL },\n): ReturnType<typeof makeWalletMember<readonly []>>;\nexport function wallet(): ReturnType<typeof makeWalletMember<readonly []>>;\nexport function wallet(opts?: WalletOptions): AnyPlugin {\n\tconst resolvedOpts: WalletOptions =\n\t\topts ?? ({ accounts: WALLET_ACCOUNTS_ALL } satisfies WalletOptions);\n\tif (resolvedOpts.accounts === WALLET_ACCOUNTS_ALL) {\n\t\t// Deferred placeholder. `dependsOn` carries only `[suiResource]` —\n\t\t// the composer rewrites the member once it knows which account\n\t\t// members are in the stack (api-surface-design §4 D6). Without\n\t\t// composer expansion, the wallet would race account funding;\n\t\t// WITH composer expansion, every per-account dependency edge is\n\t\t// in place by the time the dep-graph builds.\n\t\t//\n\t\t// Type-level: the placeholder's `dependsOn` is `[suiResource]`. A\n\t\t// wider `ReadonlyArray<account/${string}>` would widen the\n\t\t// stack-level `MissingProviders` check to the template literal\n\t\t// (which never reduces to any concrete `account/<name>`), so\n\t\t// the placeholder MUST stay narrow.\n\t\t//\n\t\t// Runtime: the symbol-keyed expander is attached as a value-\n\t\t// only property; the factory's declared return type\n\t\t// intentionally does NOT surface it (a `unique symbol`-keyed\n\t\t// member field would leak into the user's inferred Stack type\n\t\t// and trigger TS2742 \"type cannot be named without a reference\n\t\t// to ./node_modules/.../plugins/wallet\" at every example's\n\t\t// default export).\n\t\tconst placeholder = makeWalletMember(resolvedOpts, [] as const);\n\t\tconst expander: WalletExpandAccountsAllExpander = (accountMembers) =>\n\t\t\tmakeWalletMember({ ...resolvedOpts, accounts: accountMembers }, accountMembers);\n\t\t(placeholder as unknown as Record<symbol, unknown>)[WALLET_EXPAND_ACCOUNTS_ALL] = expander;\n\t\treturn placeholder;\n\t}\n\treturn makeWalletMember(resolvedOpts, resolvedOpts.accounts);\n}\n\nfunction makeWalletMember<Accounts extends ReadonlyArray<WalletAccountMember>>(\n\topts: WalletOptions,\n\taccounts: Accounts,\n) {\n\t// Dependencies MUST include every account ref (15-wallet.md\n\t// \"upstreamKeys MUST include suiResource.id + every account id\" — same\n\t// load-bearing invariant). The substrate's topological scheduler\n\t// uses `dependsOn` to drive build order; without including the\n\t// account refs here, the wallet would race account funding and the\n\t// first `signTransaction` would fail with `address-not-found`.\n\t//\n\tconst dependencies = [suiResource, ...accounts] as const;\n\n\t// The resolved-opts shape acquireWallet sees has accounts pinned to\n\t// the resolved tuple — `'all'` is purely a user-surface convenience\n\t// the composer never propagates to the supervisor.\n\tconst resolvedOpts: WalletOptions<Accounts> = { ...opts, accounts };\n\n\treturn definePlugin({\n\t\tid: walletResource.id,\n\t\tdependsOn: dependencies,\n\t\t// The HTTP server is a long-lived host process; per-request\n\t\t// handlers fork off the supervisor-context fiber but the server\n\t\t// itself lives for the stack's lifetime.\n\t\trole: 'service',\n\t\tstart: (deps) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\t// Pull identity, the stack-paths bundle, and the port-\n\t\t\t\t// broker from the supervisor-provided substrate context.\n\t\t\t\t// `StackPathsService.stackRoot` is the on-disk root for\n\t\t\t\t// per-stack runtime artifacts (incl. `wallet/token`); the\n\t\t\t\t// port broker is per-stack (Layer-driven, one instance per\n\t\t\t\t// stack scope); the wallet's scope hangs off the\n\t\t\t\t// supervisor's `acquireScope`, so any release finalizer\n\t\t\t\t// installed by these primitives unwinds with the rest of\n\t\t\t\t// the plugin's resources on cycle / teardown.\n\t\t\t\tconst identity = yield* IdentityContext;\n\t\t\t\tconst paths = yield* StackPathsService;\n\t\t\t\tconst portBroker = yield* PortBrokerService;\n\n\t\t\t\t// The first dependency is the hard Sui ordering edge; the\n\t\t\t\t// remaining values mirror the explicit account tuple.\n\t\t\t\tconst [, ...resolvedAccounts] = deps;\n\t\t\t\tconst routerFrontedUrl = yield* routerHostname(identity, WALLET_ROUTE_ROLE).pipe(\n\t\t\t\t\tEffect.map((hostname) =>\n\t\t\t\t\t\trenderUrl({\n\t\t\t\t\t\t\tprotocol: 'http',\n\t\t\t\t\t\t\thostname,\n\t\t\t\t\t\t\tport: WALLET_ENTRYPOINT_PORT,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.mapError((err) =>\n\t\t\t\t\t\twalletBootError({\n\t\t\t\t\t\t\tphase: 'route-url',\n\t\t\t\t\t\t\tmessage: `wallet router URL construction failed: ${err.detail}`,\n\t\t\t\t\t\t\tcause: err,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tconst routedAppOrigin = yield* routerHostname(\n\t\t\t\t\tidentity,\n\t\t\t\t\tHOST_SERVICE_DEFAULT_ENDPOINT_NAME,\n\t\t\t\t).pipe(\n\t\t\t\t\tEffect.map((hostname) =>\n\t\t\t\t\t\trenderUrl({\n\t\t\t\t\t\t\tprotocol: 'http',\n\t\t\t\t\t\t\thostname,\n\t\t\t\t\t\t\tport: HOST_SERVICE_DEFAULT_ENTRYPOINT_PORT,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.mapError((err) =>\n\t\t\t\t\t\twalletBootError({\n\t\t\t\t\t\t\tphase: 'route-url',\n\t\t\t\t\t\t\tmessage: `wallet app-origin URL construction failed: ${err.detail}`,\n\t\t\t\t\t\t\tcause: err,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t);\n\n\t\t\t\tconst acquireCtx: WalletAcquireContext = {\n\t\t\t\t\tapp: identity.app,\n\t\t\t\t\tstack: identity.stack,\n\t\t\t\t\tchain: identity.chain,\n\t\t\t\t\tstateRoot: paths.stackRoot,\n\t\t\t\t\tvitePortForThisStack: null,\n\t\t\t\t\tallocatePort: (preferred, probeHost) =>\n\t\t\t\t\t\tportBroker\n\t\t\t\t\t\t\t.allocate({\n\t\t\t\t\t\t\t\tkind: 'wallet',\n\t\t\t\t\t\t\t\tpreferredPort: preferred,\n\t\t\t\t\t\t\t\t...(probeHost === undefined ? {} : { probeHost }),\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.pipe(\n\t\t\t\t\t\t\t\tEffect.map((alloc) => alloc.port),\n\t\t\t\t\t\t\t\tEffect.mapError((err) =>\n\t\t\t\t\t\t\t\t\twalletBootError({\n\t\t\t\t\t\t\t\t\t\tphase: 'allocate-port',\n\t\t\t\t\t\t\t\t\t\tmessage: `port-broker allocate failed: ${err.detail}`,\n\t\t\t\t\t\t\t\t\t\thint:\n\t\t\t\t\t\t\t\t\t\t\terr.reason === 'preferred-busy'\n\t\t\t\t\t\t\t\t\t\t\t\t? 'another plugin in this stack is using your preferred port; omit `port` to let the broker pick.'\n\t\t\t\t\t\t\t\t\t\t\t\t: err.reason === 'no-free-port'\n\t\t\t\t\t\t\t\t\t\t\t\t\t? 'the wallet kind-window is exhausted; check for stray devstack supervisors holding ports.'\n\t\t\t\t\t\t\t\t\t\t\t\t\t: 'bind-probe failed — likely a privileged port or jail restriction.',\n\t\t\t\t\t\t\t\t\t\tcause: err,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t),\n\t\t\t\t\tresolveAccounts: () => Effect.succeed(resolvedAccounts),\n\t\t\t\t\trouterFrontedUrl,\n\t\t\t\t\troutedAppOrigin,\n\t\t\t\t\tsupervisorCtx: undefined,\n\t\t\t\t};\n\n\t\t\t\treturn yield* acquireWallet(resolvedOpts, acquireCtx);\n\t\t\t}),\n\t\terrorContributions: walletErrorContributions,\n\t\t// Dynamic capability factory — receives the resolved\n\t\t// `WalletValue` + acquire context. Stamps the real dapp-kit\n\t\t// bindings (walletUrl, pairUrl, chain id, paths) into the\n\t\t// codegen decl, and the real identity app/stack into the\n\t\t// routable decl.\n\t\tcapabilities: ({ value: resolved, runtime: acquireCtx }) => {\n\t\t\tconst snapshot = makeWalletSnapshotable();\n\t\t\tconst codegen = makeWalletCodegen(resolved.bindings);\n\t\t\tconst routable = makeWalletRoutable({\n\t\t\t\tapp: acquireCtx.identity.app,\n\t\t\t\tstack: acquireCtx.identity.stack,\n\t\t\t\tport: resolved.localPort,\n\t\t\t});\n\t\t\treturn [snapshot, codegen, routable] as const;\n\t\t},\n\t});\n}\n\n// ----------------------------------------------------------------------\n// Re-exports\n// ----------------------------------------------------------------------\n\nexport type {\n\tWalletOptions,\n\tWalletValue,\n\tWalletAccountMember,\n\tWalletAccountsAll,\n} from './service.ts';\nexport { WALLET_ACCOUNTS_ALL } from './service.ts';\nexport type { DappKitConfigBindings } from './codegen.ts';\nexport {\n\tWalletHttpPath,\n\tWALLET_PROTOCOL_PREFIX,\n\tWALLET_AUTH_HEADER,\n\tWALLET_BEARER_PREFIX,\n\tWALLET_TOKEN_FRAGMENT_KEY,\n\tWALLET_TOKEN_HEX_LENGTH,\n\tSignRequestSchema,\n\tSignResponseSchema,\n\tExecuteRequestSchema,\n\tExecuteResponseSchema,\n\tHealthResponseSchema,\n\tAccountsResponseSchema,\n\tAccountSummarySchema,\n\tErrorResponseSchema,\n\tSuiAddressSchema,\n\tBase64Schema,\n\tSignatureSchemeSchema,\n\tAccountSourceSchema,\n\ttype WalletHttpPathValue,\n\ttype SignRequest,\n\ttype SignResponse,\n\ttype ExecuteRequest,\n\ttype ExecuteResponse,\n\ttype HealthResponse,\n\ttype AccountsResponse,\n\ttype AccountSummary,\n\ttype ErrorResponse,\n} from './protocol.ts';\nexport type {\n\tWalletError,\n\tWalletBootError,\n\tWalletBootPhase,\n\tWalletRequestError,\n\tWalletRequestPhase,\n} from './errors.ts';\nexport { WALLET_ERROR_TAGS } from './errors.ts';\nexport type { OriginPolicy, OriginPolicyInputs, OriginCheckResult } from './origin-policy.ts';\nexport { resolveOriginPolicy, checkOrigin, corsHeadersFor } from './origin-policy.ts';\nexport type { PairingToken } from './pairing.ts';\nexport {\n\tmintToken,\n\tacquirePairingToken,\n\ttokenPath,\n\tcomposePairUrl,\n\tparsePairUrl,\n\tparseBearerHeader,\n\tsafeBearerEquals,\n\tredactToken,\n} from './pairing.ts';\nexport { WALLET_ENDPOINT_NAME, makeWalletRoutable } from './routable.ts';\nexport {\n\tdispatch,\n\tstartHttpServer,\n\tMAX_BODY_BYTES,\n\ttype WalletRequest,\n\ttype WalletResponse,\n\ttype WalletServerConfig,\n\ttype WalletServerHandle,\n} from './server.ts';\nexport { makeWalletCodegen } from './codegen.ts';\nexport { makeWalletSnapshotable } from './snapshot.ts';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuEA,MAAa,6BAAqC,OAAO,IAAI,sCAAsC;;;AAoBnG,MAAM,iBAAiB,SAAgC,SAAS;AAChE,MAAM,2BAA2B,yBAAyB,kBAAkB;AAiD5E,SAAgB,OAAO,MAAiC;CACvD,MAAM,eACL,QAAS,EAAE,UAAA,OAA+B;AAC3C,KAAI,aAAa,aAAA,OAAkC;EAqBlD,MAAM,cAAc,iBAAiB,cAAc,EAAE,CAAU;EAC/D,MAAM,YAA6C,mBAClD,iBAAiB;GAAE,GAAG;GAAc,UAAU;GAAgB,EAAE,eAAe;AAC/E,cAAmD,8BAA8B;AAClF,SAAO;;AAER,QAAO,iBAAiB,cAAc,aAAa,SAAS;;AAG7D,SAAS,iBACR,MACA,UACC;CAQD,MAAM,eAAe,CAAC,aAAa,GAAG,SAAS;CAK/C,MAAM,eAAwC;EAAE,GAAG;EAAM;EAAU;AAEnE,QAAO,aAAa;EACnB,IAAI,eAAe;EACnB,WAAW;EAIX,MAAM;EACN,QAAQ,SACP,OAAO,IAAI,aAAa;GAUvB,MAAM,WAAW,OAAO;GACxB,MAAM,QAAQ,OAAO;GACrB,MAAM,aAAa,OAAO;GAI1B,MAAM,GAAG,GAAG,oBAAoB;GAChC,MAAM,mBAAmB,OAAO,eAAe,UAAA,MAA4B,CAAC,KAC3E,OAAO,KAAK,aACX,UAAU;IACT,UAAU;IACV;IACA,MAAM;IACN,CAAC,CACF,EACD,OAAO,UAAU,QAChB,gBAAgB;IACf,OAAO;IACP,SAAS,0CAA0C,IAAI;IACvD,OAAO;IACP,CAAC,CACF,CACD;GACD,MAAM,kBAAkB,OAAO,eAC9B,UAAA,MAEA,CAAC,KACD,OAAO,KAAK,aACX,UAAU;IACT,UAAU;IACV;IACA,MAAM;IACN,CAAC,CACF,EACD,OAAO,UAAU,QAChB,gBAAgB;IACf,OAAO;IACP,SAAS,8CAA8C,IAAI;IAC3D,OAAO;IACP,CAAC,CACF,CACD;AAqCD,UAAO,OAAO,cAAc,cAAc;IAlCzC,KAAK,SAAS;IACd,OAAO,SAAS;IAChB,OAAO,SAAS;IAChB,WAAW,MAAM;IACjB,sBAAsB;IACtB,eAAe,WAAW,cACzB,WACE,SAAS;KACT,MAAM;KACN,eAAe;KACf,GAAI,cAAc,KAAA,IAAY,EAAE,GAAG,EAAE,WAAW;KAChD,CAAC,CACD,KACA,OAAO,KAAK,UAAU,MAAM,KAAK,EACjC,OAAO,UAAU,QAChB,gBAAgB;KACf,OAAO;KACP,SAAS,gCAAgC,IAAI;KAC7C,MACC,IAAI,WAAW,mBACZ,mGACA,IAAI,WAAW,iBACd,6FACA;KACL,OAAO;KACP,CAAC,CACF,CACD;IACH,uBAAuB,OAAO,QAAQ,iBAAiB;IACvD;IACA;IACA,eAAe,KAAA;IAGoC,CAAC;IACpD;EACH,oBAAoB;EAMpB,eAAe,EAAE,OAAO,UAAU,SAAS,iBAAiB;AAQ3D,UAAO;IAPU,wBAOD;IANA,kBAAkB,SAAS,SAMlB;IALR,mBAAmB;KACnC,KAAK,WAAW,SAAS;KACzB,OAAO,WAAW,SAAS;KAC3B,MAAM,SAAS;KACf,CACkC;IAAC;;EAErC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { SpanAttr } from "../../substrate/runtime/observability/spans.mjs";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
//#region src/plugins/wallet/origin-policy.ts
|
|
4
|
+
/**
|
|
5
|
+
* Resolve the per-stack origin allowlist.
|
|
6
|
+
*
|
|
7
|
+
* - Always allowlisted: the stack-scoped router host
|
|
8
|
+
* `http://dev.<stack>.<app>.localhost:<vite-port>`, IF the broker recorded
|
|
9
|
+
* a vite port for this stack.
|
|
10
|
+
* - Conditionally allowlisted: the bare `http://localhost:<vite-port>`
|
|
11
|
+
* form. Off by default; on iff `allowLocalhostVite` is true.
|
|
12
|
+
* - Always allowlisted: any explicit caller-supplied origins from
|
|
13
|
+
* `extraOrigins`.
|
|
14
|
+
*
|
|
15
|
+
* Empty-allowlist policy (vite absent AND no `extraOrigins`): allowed.
|
|
16
|
+
* The wallet boots normally; with an empty allowlist the per-request
|
|
17
|
+
* gate refuses every request (every Origin lands in `forbidden`). This
|
|
18
|
+
* is the correct behavior for a stack composed without any client UI
|
|
19
|
+
* (e.g. node-only smoke / e2e configs) — the wallet's keypair + token
|
|
20
|
+
* are still useful for the host process, but the HTTP surface is
|
|
21
|
+
* effectively closed. A `Effect.logWarning` surfaces the configuration
|
|
22
|
+
* for operator visibility.
|
|
23
|
+
*
|
|
24
|
+
* Returns `Effect<OriginPolicy, WalletBootError>` (the error channel
|
|
25
|
+
* is preserved for future fail-fast modes the resolver may grow).
|
|
26
|
+
*/
|
|
27
|
+
const resolveOriginPolicy = (inputs) => Effect.gen(function* () {
|
|
28
|
+
const allowed = /* @__PURE__ */ new Set();
|
|
29
|
+
const stackScopedHost = inputs.stack === "main" ? `dev.${inputs.app}.localhost` : `dev.${inputs.stack}.${inputs.app}.localhost`;
|
|
30
|
+
if (inputs.vitePortForThisStack !== null) {
|
|
31
|
+
allowed.add(`http://${stackScopedHost}:${inputs.vitePortForThisStack}`);
|
|
32
|
+
if (inputs.allowLocalhostVite) allowed.add(`http://localhost:${inputs.vitePortForThisStack}`);
|
|
33
|
+
}
|
|
34
|
+
if (inputs.routedAppOrigin !== null) allowed.add(inputs.routedAppOrigin);
|
|
35
|
+
for (const o of inputs.extraOrigins) allowed.add(o);
|
|
36
|
+
if (allowed.size === 0) yield* Effect.logWarning("wallet origin allowlist is empty").pipe(Effect.annotateLogs({
|
|
37
|
+
[SpanAttr.app]: inputs.app,
|
|
38
|
+
[SpanAttr.stack]: inputs.stack,
|
|
39
|
+
[SpanAttr.walletLocalhostViteEnabled]: inputs.allowLocalhostVite
|
|
40
|
+
}));
|
|
41
|
+
return {
|
|
42
|
+
allowed,
|
|
43
|
+
localhostViteEnabled: inputs.allowLocalhostVite,
|
|
44
|
+
stackScopedHost
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
const checkOrigin = (policy, headerValue) => {
|
|
48
|
+
if (headerValue === void 0 || headerValue.length === 0) return "missing";
|
|
49
|
+
return policy.allowed.has(headerValue) ? "ok" : "forbidden";
|
|
50
|
+
};
|
|
51
|
+
/** Compose CORS headers for a successful request. Single-allowed-origin
|
|
52
|
+
* echo (browsers don't honor wildcard with credentials, and we want
|
|
53
|
+
* to keep `Access-Control-Allow-Credentials` open for fetch with
|
|
54
|
+
* `credentials: 'include'` if a future codegen seam needs it). */
|
|
55
|
+
const corsHeadersFor = (origin) => ({
|
|
56
|
+
"access-control-allow-origin": origin,
|
|
57
|
+
"access-control-allow-methods": "GET, POST, OPTIONS",
|
|
58
|
+
"access-control-allow-headers": "authorization, content-type",
|
|
59
|
+
"access-control-allow-credentials": "true",
|
|
60
|
+
vary: "origin"
|
|
61
|
+
});
|
|
62
|
+
//#endregion
|
|
63
|
+
export { checkOrigin, corsHeadersFor, resolveOriginPolicy };
|
|
64
|
+
|
|
65
|
+
//# sourceMappingURL=origin-policy.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"origin-policy.mjs","names":[],"sources":["../../../src/plugins/wallet/origin-policy.ts"],"sourcesContent":["// Wallet plugin — CORS / origin allowlist policy.\n//\n// Distilled-doc problem (15-wallet.md \"Cross-stack pairing risk\"): the\n// legacy wallet auto-allowlisted `http://localhost:<vite-port>` per\n// stack. Two sibling stacks running vite on the same `localhost:5175`\n// (or `5176`, etc.) could pair with EITHER wallet — CORS lets the\n// request through, and the bearer token (once leaked once via any\n// channel) is enough to sign.\n//\n// Architecture decision (per task):\n//\n// - Stack-scoped allowlist. The vite-port-derived origin is added to\n// this stack's allowlist ONLY when the substrate's port broker\n// records THIS stack as the owner of that vite port.\n// - The stack-scoped host (e.g. `http://dev.<stack>.<app>.localhost:<port>`)\n// is the canonical browser entry — always allowlisted.\n// - The raw `http://localhost:<port>` form is OFF by default; opt-in\n// via `WalletOptions.allowLocalhostVite: true` for callers who\n// want the legacy behavior (e.g. headless test runners that pin\n// `localhost`). Documented as a security tradeoff in the factory's\n// JSDoc.\n//\n// Why \"origin + bearer together\" (task requirement #3): bearer alone\n// leaves a non-browser-tooling bypass — curl / fetch from a service\n// worker can forge `Authorization` from a leaked token. Browsers\n// always send `Origin`; non-browsers omit it. Demanding BOTH closes\n// the bypass.\n\nimport { Effect } from 'effect';\n\nimport { SpanAttr } from '../../substrate/runtime/observability/spans.ts';\nimport type { WalletBootError } from './errors.ts';\n\n// ----------------------------------------------------------------------\n// Policy shape\n// ----------------------------------------------------------------------\n\n/** Result of resolving the origin allowlist at boot. Captured into\n * the HTTP handler closure so per-request checks are pure-string\n * comparison. */\nexport interface OriginPolicy {\n\treadonly allowed: ReadonlySet<string>;\n\t/** True if the policy permitted the `http://localhost:<vite-port>`\n\t * form. Carried for renderer / log hygiene — surfaces in the\n\t * manifest as a flag so the TUI can warn. */\n\treadonly localhostViteEnabled: boolean;\n\t/** Bare host (e.g. `dev.<stack>.<app>.localhost`) the stack-scoped\n\t * origin resolves under. Captured for log lines. */\n\treadonly stackScopedHost: string;\n}\n\n/** Per-stack inputs the policy resolver needs. Supplied by the\n * substrate at acquire time (port broker + identity); this module\n * doesn't reach into the broker itself. */\nexport interface OriginPolicyInputs {\n\treadonly app: string;\n\treadonly stack: string;\n\treadonly vitePortForThisStack: number | null;\n\treadonly routedAppOrigin: string | null;\n\treadonly extraOrigins: ReadonlyArray<string>;\n\treadonly allowLocalhostVite: boolean;\n}\n\n// ----------------------------------------------------------------------\n// Resolution\n// ----------------------------------------------------------------------\n\n/**\n * Resolve the per-stack origin allowlist.\n *\n * - Always allowlisted: the stack-scoped router host\n * `http://dev.<stack>.<app>.localhost:<vite-port>`, IF the broker recorded\n * a vite port for this stack.\n * - Conditionally allowlisted: the bare `http://localhost:<vite-port>`\n * form. Off by default; on iff `allowLocalhostVite` is true.\n * - Always allowlisted: any explicit caller-supplied origins from\n * `extraOrigins`.\n *\n * Empty-allowlist policy (vite absent AND no `extraOrigins`): allowed.\n * The wallet boots normally; with an empty allowlist the per-request\n * gate refuses every request (every Origin lands in `forbidden`). This\n * is the correct behavior for a stack composed without any client UI\n * (e.g. node-only smoke / e2e configs) — the wallet's keypair + token\n * are still useful for the host process, but the HTTP surface is\n * effectively closed. A `Effect.logWarning` surfaces the configuration\n * for operator visibility.\n *\n * Returns `Effect<OriginPolicy, WalletBootError>` (the error channel\n * is preserved for future fail-fast modes the resolver may grow).\n */\nexport const resolveOriginPolicy = (\n\tinputs: OriginPolicyInputs,\n): Effect.Effect<OriginPolicy, WalletBootError> =>\n\tEffect.gen(function* () {\n\t\tconst allowed = new Set<string>();\n\t\tconst stackScopedHost =\n\t\t\tinputs.stack === 'main'\n\t\t\t\t? `dev.${inputs.app}.localhost`\n\t\t\t\t: `dev.${inputs.stack}.${inputs.app}.localhost`;\n\n\t\tif (inputs.vitePortForThisStack !== null) {\n\t\t\tallowed.add(`http://${stackScopedHost}:${inputs.vitePortForThisStack}`);\n\t\t\tif (inputs.allowLocalhostVite) {\n\t\t\t\tallowed.add(`http://localhost:${inputs.vitePortForThisStack}`);\n\t\t\t}\n\t\t}\n\n\t\tif (inputs.routedAppOrigin !== null) {\n\t\t\tallowed.add(inputs.routedAppOrigin);\n\t\t}\n\n\t\tfor (const o of inputs.extraOrigins) {\n\t\t\tallowed.add(o);\n\t\t}\n\n\t\tif (allowed.size === 0) {\n\t\t\tyield* Effect.logWarning('wallet origin allowlist is empty').pipe(\n\t\t\t\tEffect.annotateLogs({\n\t\t\t\t\t[SpanAttr.app]: inputs.app,\n\t\t\t\t\t[SpanAttr.stack]: inputs.stack,\n\t\t\t\t\t[SpanAttr.walletLocalhostViteEnabled]: inputs.allowLocalhostVite,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tallowed,\n\t\t\tlocalhostViteEnabled: inputs.allowLocalhostVite,\n\t\t\tstackScopedHost,\n\t\t} satisfies OriginPolicy;\n\t});\n\n// ----------------------------------------------------------------------\n// Per-request check\n// ----------------------------------------------------------------------\n\n/** Per-request origin gate. Returns `'missing'` for absent Origin,\n * `'forbidden'` for Origin not in the allowlist, `'ok'` for accepted.\n *\n * Distilled-doc invariant (C12): missing Origin is its OWN refusal\n * shape (closes the curl / non-browser bypass — bearer alone is not\n * enough). */\nexport type OriginCheckResult = 'missing' | 'forbidden' | 'ok';\n\nexport const checkOrigin = (\n\tpolicy: OriginPolicy,\n\theaderValue: string | undefined,\n): OriginCheckResult => {\n\tif (headerValue === undefined || headerValue.length === 0) return 'missing';\n\treturn policy.allowed.has(headerValue) ? 'ok' : 'forbidden';\n};\n\n/** Compose CORS headers for a successful request. Single-allowed-origin\n * echo (browsers don't honor wildcard with credentials, and we want\n * to keep `Access-Control-Allow-Credentials` open for fetch with\n * `credentials: 'include'` if a future codegen seam needs it). */\nexport const corsHeadersFor = (origin: string): Readonly<Record<string, string>> => ({\n\t'access-control-allow-origin': origin,\n\t'access-control-allow-methods': 'GET, POST, OPTIONS',\n\t'access-control-allow-headers': 'authorization, content-type',\n\t'access-control-allow-credentials': 'true',\n\tvary: 'origin',\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA0FA,MAAa,uBACZ,WAEA,OAAO,IAAI,aAAa;CACvB,MAAM,0BAAU,IAAI,KAAa;CACjC,MAAM,kBACL,OAAO,UAAU,SACd,OAAO,OAAO,IAAI,cAClB,OAAO,OAAO,MAAM,GAAG,OAAO,IAAI;AAEtC,KAAI,OAAO,yBAAyB,MAAM;AACzC,UAAQ,IAAI,UAAU,gBAAgB,GAAG,OAAO,uBAAuB;AACvE,MAAI,OAAO,mBACV,SAAQ,IAAI,oBAAoB,OAAO,uBAAuB;;AAIhE,KAAI,OAAO,oBAAoB,KAC9B,SAAQ,IAAI,OAAO,gBAAgB;AAGpC,MAAK,MAAM,KAAK,OAAO,aACtB,SAAQ,IAAI,EAAE;AAGf,KAAI,QAAQ,SAAS,EACpB,QAAO,OAAO,WAAW,mCAAmC,CAAC,KAC5D,OAAO,aAAa;GAClB,SAAS,MAAM,OAAO;GACtB,SAAS,QAAQ,OAAO;GACxB,SAAS,6BAA6B,OAAO;EAC9C,CAAC,CACF;AAGF,QAAO;EACN;EACA,sBAAsB,OAAO;EAC7B;EACA;EACA;AAcH,MAAa,eACZ,QACA,gBACuB;AACvB,KAAI,gBAAgB,KAAA,KAAa,YAAY,WAAW,EAAG,QAAO;AAClE,QAAO,OAAO,QAAQ,IAAI,YAAY,GAAG,OAAO;;;;;;AAOjD,MAAa,kBAAkB,YAAsD;CACpF,+BAA+B;CAC/B,gCAAgC;CAChC,gCAAgC;CAChC,oCAAoC;CACpC,MAAM;CACN"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Effect, FileSystem } from "effect";
|
|
2
|
+
|
|
3
|
+
//#region src/plugins/wallet/pairing.d.ts
|
|
4
|
+
/** A pairing token. Branded so it can't be confused with arbitrary
|
|
5
|
+
* strings at the type level — only this module mints them. */
|
|
6
|
+
type PairingToken = string & {
|
|
7
|
+
readonly __pairingToken: unique symbol;
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
10
|
+
export { PairingToken };
|
|
11
|
+
//# sourceMappingURL=pairing.d.mts.map
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { atomicWriteFile } from "../../substrate/runtime/atomic-write.mjs";
|
|
2
|
+
import { SpanAttr } from "../../substrate/runtime/observability/spans.mjs";
|
|
3
|
+
import { redactText } from "../../substrate/runtime/observability/redaction.mjs";
|
|
4
|
+
import { walletBootError } from "./errors.mjs";
|
|
5
|
+
import { WALLET_BEARER_PREFIX, WALLET_TOKEN_FRAGMENT_KEY } from "./protocol.mjs";
|
|
6
|
+
import { Effect } from "effect";
|
|
7
|
+
import { randomBytes, timingSafeEqual } from "node:crypto";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import { readFile } from "node:fs/promises";
|
|
10
|
+
//#region src/plugins/wallet/pairing.ts
|
|
11
|
+
/** Token-charset regex: lowercase hex, exactly 32 chars. Reject any
|
|
12
|
+
* on-disk value that doesn't match (re-mint). */
|
|
13
|
+
const TOKEN_RE = /^[0-9a-f]{32}$/;
|
|
14
|
+
const asToken = (s) => s;
|
|
15
|
+
/** Mint a fresh token. 16 random bytes → 32 hex chars. */
|
|
16
|
+
const mintToken = () => Effect.sync(() => asToken(randomBytes(16).toString("hex")));
|
|
17
|
+
/** Resolve the on-disk token path under a state root. The state root
|
|
18
|
+
* is supplied by the substrate's identity / state-store config; this
|
|
19
|
+
* helper centralises the layout convention.
|
|
20
|
+
*
|
|
21
|
+
* Convention: `<stateRoot>/wallet/token` — one token per stack, lives
|
|
22
|
+
* alongside other per-stack runtime artifacts. */
|
|
23
|
+
const tokenPath = (stateRoot) => join(stateRoot, "wallet", "token");
|
|
24
|
+
/**
|
|
25
|
+
* Read the on-disk token if it exists and is well-formed; otherwise
|
|
26
|
+
* mint + persist a fresh one via the substrate's atomic-write primitive
|
|
27
|
+
* (mkdir-parent → O_EXCL temp → write → fsync → rename, mode 0o600).
|
|
28
|
+
* Warm starts and snapshot restores both land in the "read existing"
|
|
29
|
+
* branch so a previously-paired dev-wallet keeps working without a
|
|
30
|
+
* re-pair UX.
|
|
31
|
+
*/
|
|
32
|
+
const acquirePairingToken = (path) => Effect.gen(function* () {
|
|
33
|
+
const existing = yield* Effect.tryPromise({
|
|
34
|
+
try: async () => {
|
|
35
|
+
try {
|
|
36
|
+
return await readFile(path, "utf8");
|
|
37
|
+
} catch (err) {
|
|
38
|
+
if (err?.code === "ENOENT") return null;
|
|
39
|
+
throw err;
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
catch: (cause) => walletBootError({
|
|
43
|
+
phase: "read-token",
|
|
44
|
+
message: `read of wallet token file failed at ${path}`,
|
|
45
|
+
hint: "check filesystem permissions / disk availability",
|
|
46
|
+
cause
|
|
47
|
+
})
|
|
48
|
+
});
|
|
49
|
+
if (existing !== null) {
|
|
50
|
+
const trimmed = existing.trim();
|
|
51
|
+
if (TOKEN_RE.test(trimmed)) return asToken(trimmed);
|
|
52
|
+
yield* Effect.logWarning("wallet token file is malformed; re-minting").pipe(Effect.annotateLogs({ [SpanAttr.walletTokenFile]: path }));
|
|
53
|
+
}
|
|
54
|
+
const token = yield* mintToken();
|
|
55
|
+
yield* atomicWriteFile(path, new TextEncoder().encode(token), { mode: 384 }).pipe(Effect.mapError((cause) => walletBootError({
|
|
56
|
+
phase: "write-token",
|
|
57
|
+
message: `failed to persist wallet token at ${path}`,
|
|
58
|
+
hint: "ENOSPC / EROFS / EACCES — boot continues with in-memory token; new pairing required next cycle",
|
|
59
|
+
cause
|
|
60
|
+
})));
|
|
61
|
+
return token;
|
|
62
|
+
});
|
|
63
|
+
/**
|
|
64
|
+
* Compose the pair URL the dev-wallet adapter reads.
|
|
65
|
+
*
|
|
66
|
+
* The token rides the URL FRAGMENT (`#token=...`), never a query
|
|
67
|
+
* parameter. Fragments are not sent to servers, so the token can't
|
|
68
|
+
* land in access logs / referrer headers / Sentry breadcrumbs.
|
|
69
|
+
*/
|
|
70
|
+
const composePairUrl = (walletUrl, token) => `${walletUrl}/#${WALLET_TOKEN_FRAGMENT_KEY}=${token}`;
|
|
71
|
+
/**
|
|
72
|
+
* Parse a raw `Authorization` header value into the bearer token. The
|
|
73
|
+
* dev-wallet adapter copies the token from `url.hash` into the
|
|
74
|
+
* `Authorization: Bearer <token>` header on every request — this
|
|
75
|
+
* helper is the symmetric inverse.
|
|
76
|
+
*
|
|
77
|
+
* Returns `null` on missing / malformed header so the caller can map
|
|
78
|
+
* to the structured `unauthorized` request error.
|
|
79
|
+
*/
|
|
80
|
+
const parseBearerHeader = (header) => {
|
|
81
|
+
if (header === void 0) return null;
|
|
82
|
+
if (!header.startsWith("Bearer ")) return null;
|
|
83
|
+
const raw = header.slice(WALLET_BEARER_PREFIX.length);
|
|
84
|
+
return raw.length === 32 ? raw : null;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Constant-time bearer-token compare. The length-mismatch shortcut is
|
|
88
|
+
* intentional — token length is public knowledge (always 32 hex
|
|
89
|
+
* chars), so leaking "wrong length" is not a credential leak. The
|
|
90
|
+
* shortcut also prevents `timingSafeEqual` from throwing on mismatched
|
|
91
|
+
* buffer sizes.
|
|
92
|
+
*
|
|
93
|
+
* Invariant (15-wallet.md "Token comparison MUST be constant-time"):
|
|
94
|
+
* NEVER `===` two tokens. `===` on strings short-circuits at the first
|
|
95
|
+
* mismatching byte, leaking the prefix byte-by-byte via response-time
|
|
96
|
+
* measurement to a remote attacker.
|
|
97
|
+
*/
|
|
98
|
+
const safeBearerEquals = (a, b) => {
|
|
99
|
+
if (a.length !== b.length) return false;
|
|
100
|
+
const ab = Buffer.from(a, "utf8");
|
|
101
|
+
const bb = Buffer.from(b, "utf8");
|
|
102
|
+
if (ab.length !== bb.length) return false;
|
|
103
|
+
return timingSafeEqual(ab, bb);
|
|
104
|
+
};
|
|
105
|
+
const TOKEN_REDACTION_RULE = {
|
|
106
|
+
kind: "pattern",
|
|
107
|
+
pattern: /([#?&]token=)[A-Za-z0-9]+/g,
|
|
108
|
+
replacement: "$1<redacted>"
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Redact the token fragment from any URL-shaped string for logging /
|
|
112
|
+
* TUI rendering. Defense-in-depth — the engine's log sink should never
|
|
113
|
+
* see the unredacted pair URL anyway, but this exists for callers that
|
|
114
|
+
* accidentally pass `pairUrl` straight into a log line.
|
|
115
|
+
*
|
|
116
|
+
* Distilled-doc opportunity (15-wallet.md): the legacy redactor only
|
|
117
|
+
* covered `#token=`. This regex covers BOTH the fragment form and a
|
|
118
|
+
* hypothetical query form so a future config change doesn't silently
|
|
119
|
+
* leak.
|
|
120
|
+
*/
|
|
121
|
+
const redactToken = (s) => redactText(s, [TOKEN_REDACTION_RULE]);
|
|
122
|
+
//#endregion
|
|
123
|
+
export { acquirePairingToken, composePairUrl, mintToken, parseBearerHeader, redactToken, safeBearerEquals, tokenPath };
|
|
124
|
+
|
|
125
|
+
//# sourceMappingURL=pairing.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pairing.mjs","names":["joinPath"],"sources":["../../../src/plugins/wallet/pairing.ts"],"sourcesContent":["// Wallet plugin — pairing-token discipline.\n//\n// What this module owns (15-wallet.md \"Token comparison MUST be\n// constant-time\", \"Token MUST live in URL fragment (not query)\",\n// \"Token MUST NOT appear in log lines\", \"Token file MUST be mode\n// 0o600\"):\n//\n// 1. Token generation: 16 random bytes → 32 hex chars.\n// 2. Token persistence: file at `<stateRoot>/wallet/token`, mode\n// `0o600`, atomic write.\n// 3. Token rehydration: read-existing-or-mint so warm starts +\n// snapshot restore preserve the dev-wallet pairing.\n// 4. URL-fragment ↔ Authorization-header bridge: helpers that\n// compose the pair URL (token in fragment) and parse the\n// bearer-prefixed header back to the raw token.\n// 5. Constant-time bearer compare: timing-safe equality so a\n// remote attacker can't recover the token byte-by-byte via\n// response-time measurement.\n//\n// What this module does NOT own:\n//\n// - The HTTP server (see `server.ts`).\n// - The CORS / Origin allowlist (see `origin-policy.ts`).\n// - The codegen file (see `codegen.ts`).\n\nimport { Effect, FileSystem } from 'effect';\nimport { randomBytes, timingSafeEqual } from 'node:crypto';\nimport { readFile } from 'node:fs/promises';\nimport { join as joinPath } from 'node:path';\n\nimport { atomicWriteFile } from '../../substrate/runtime/atomic-write.ts';\nimport { redactText, type RedactionRule } from '../../substrate/runtime/observability/index.ts';\nimport { SpanAttr } from '../../substrate/runtime/observability/spans.ts';\nimport { walletBootError, type WalletBootError } from './errors.ts';\nimport {\n\tWALLET_BEARER_PREFIX,\n\tWALLET_TOKEN_FRAGMENT_KEY,\n\tWALLET_TOKEN_HEX_LENGTH,\n} from './protocol.ts';\n\n// ----------------------------------------------------------------------\n// Token shape\n// ----------------------------------------------------------------------\n\n/** A pairing token. Branded so it can't be confused with arbitrary\n * strings at the type level — only this module mints them. */\nexport type PairingToken = string & { readonly __pairingToken: unique symbol };\n\n/** Token-charset regex: lowercase hex, exactly 32 chars. Reject any\n * on-disk value that doesn't match (re-mint). */\nconst TOKEN_RE = /^[0-9a-f]{32}$/;\n\nconst asToken = (s: string): PairingToken => s as PairingToken;\n\n// ----------------------------------------------------------------------\n// Generation\n// ----------------------------------------------------------------------\n\n/** Mint a fresh token. 16 random bytes → 32 hex chars. */\nexport const mintToken = (): Effect.Effect<PairingToken> =>\n\tEffect.sync(() => asToken(randomBytes(16).toString('hex')));\n\n// ----------------------------------------------------------------------\n// Persistence\n// ----------------------------------------------------------------------\n\n/** Resolve the on-disk token path under a state root. The state root\n * is supplied by the substrate's identity / state-store config; this\n * helper centralises the layout convention.\n *\n * Convention: `<stateRoot>/wallet/token` — one token per stack, lives\n * alongside other per-stack runtime artifacts. */\nexport const tokenPath = (stateRoot: string): string => joinPath(stateRoot, 'wallet', 'token');\n\n/**\n * Read the on-disk token if it exists and is well-formed; otherwise\n * mint + persist a fresh one via the substrate's atomic-write primitive\n * (mkdir-parent → O_EXCL temp → write → fsync → rename, mode 0o600).\n * Warm starts and snapshot restores both land in the \"read existing\"\n * branch so a previously-paired dev-wallet keeps working without a\n * re-pair UX.\n */\nexport const acquirePairingToken = (\n\tpath: string,\n): Effect.Effect<PairingToken, WalletBootError, FileSystem.FileSystem> =>\n\tEffect.gen(function* () {\n\t\t// Try to read an existing token.\n\t\tconst existing = yield* Effect.tryPromise({\n\t\t\ttry: async () => {\n\t\t\t\ttry {\n\t\t\t\t\treturn await readFile(path, 'utf8');\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif ((err as NodeJS.ErrnoException)?.code === 'ENOENT') return null;\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\t\t\t},\n\t\t\tcatch: (cause) =>\n\t\t\t\twalletBootError({\n\t\t\t\t\tphase: 'read-token',\n\t\t\t\t\tmessage: `read of wallet token file failed at ${path}`,\n\t\t\t\t\thint: 'check filesystem permissions / disk availability',\n\t\t\t\t\tcause,\n\t\t\t\t}),\n\t\t});\n\n\t\tif (existing !== null) {\n\t\t\tconst trimmed = existing.trim();\n\t\t\tif (TOKEN_RE.test(trimmed)) {\n\t\t\t\treturn asToken(trimmed);\n\t\t\t}\n\t\t\t// Malformed — fall through to mint + overwrite.\n\t\t\tyield* Effect.logWarning('wallet token file is malformed; re-minting').pipe(\n\t\t\t\tEffect.annotateLogs({\n\t\t\t\t\t[SpanAttr.walletTokenFile]: path,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\t// Mint a new one + persist via substrate's atomic-write\n\t\t// (mode 0o600). The token survives partial-write failures: the\n\t\t// in-memory value is authoritative for the current cycle, and a\n\t\t// failed persist surfaces as `write-token` so callers can choose\n\t\t// to fail-fast or continue with a transient pairing.\n\t\tconst token = yield* mintToken();\n\t\tconst bytes = new TextEncoder().encode(token);\n\t\tyield* atomicWriteFile(path, bytes, { mode: 0o600 }).pipe(\n\t\t\tEffect.mapError((cause) =>\n\t\t\t\twalletBootError({\n\t\t\t\t\tphase: 'write-token',\n\t\t\t\t\tmessage: `failed to persist wallet token at ${path}`,\n\t\t\t\t\thint: 'ENOSPC / EROFS / EACCES — boot continues with in-memory token; new pairing required next cycle',\n\t\t\t\t\tcause,\n\t\t\t\t}),\n\t\t\t),\n\t\t);\n\n\t\treturn token;\n\t});\n\n// ----------------------------------------------------------------------\n// Pair-URL composition (fragment-only)\n// ----------------------------------------------------------------------\n\n/**\n * Compose the pair URL the dev-wallet adapter reads.\n *\n * The token rides the URL FRAGMENT (`#token=...`), never a query\n * parameter. Fragments are not sent to servers, so the token can't\n * land in access logs / referrer headers / Sentry breadcrumbs.\n */\nexport const composePairUrl = (walletUrl: string, token: PairingToken): string =>\n\t`${walletUrl}/#${WALLET_TOKEN_FRAGMENT_KEY}=${token}`;\n\n/**\n * Inverse — parse the token out of a pair URL fragment. Used by tests +\n * by the dev-wallet adapter (mirrored there because of the workspace-\n * cycle constraint).\n */\nexport const parsePairUrl = (pairUrl: string): PairingToken | null => {\n\tconst hashIdx = pairUrl.indexOf('#');\n\tif (hashIdx < 0) return null;\n\tconst fragment = pairUrl.slice(hashIdx + 1);\n\tconst prefix = `${WALLET_TOKEN_FRAGMENT_KEY}=`;\n\tif (!fragment.startsWith(prefix)) return null;\n\tconst raw = fragment.slice(prefix.length);\n\treturn TOKEN_RE.test(raw) ? asToken(raw) : null;\n};\n\n// ----------------------------------------------------------------------\n// Authorization-header bridge\n// ----------------------------------------------------------------------\n\n/**\n * Parse a raw `Authorization` header value into the bearer token. The\n * dev-wallet adapter copies the token from `url.hash` into the\n * `Authorization: Bearer <token>` header on every request — this\n * helper is the symmetric inverse.\n *\n * Returns `null` on missing / malformed header so the caller can map\n * to the structured `unauthorized` request error.\n */\nexport const parseBearerHeader = (header: string | undefined): string | null => {\n\tif (header === undefined) return null;\n\tif (!header.startsWith(WALLET_BEARER_PREFIX)) return null;\n\tconst raw = header.slice(WALLET_BEARER_PREFIX.length);\n\t// Don't TOKEN_RE-test here — the constant-time compare against the\n\t// expected token covers shape mismatch (length-difference shortcut\n\t// is acceptable since token length is public knowledge).\n\treturn raw.length === WALLET_TOKEN_HEX_LENGTH ? raw : null;\n};\n\n// ----------------------------------------------------------------------\n// Constant-time compare\n// ----------------------------------------------------------------------\n\n/**\n * Constant-time bearer-token compare. The length-mismatch shortcut is\n * intentional — token length is public knowledge (always 32 hex\n * chars), so leaking \"wrong length\" is not a credential leak. The\n * shortcut also prevents `timingSafeEqual` from throwing on mismatched\n * buffer sizes.\n *\n * Invariant (15-wallet.md \"Token comparison MUST be constant-time\"):\n * NEVER `===` two tokens. `===` on strings short-circuits at the first\n * mismatching byte, leaking the prefix byte-by-byte via response-time\n * measurement to a remote attacker.\n */\nexport const safeBearerEquals = (a: string, b: PairingToken | string): boolean => {\n\tif (a.length !== b.length) return false;\n\t// Both strings are 32 hex chars, ASCII — a fixed-length byte compare\n\t// is sufficient. UTF-8 encoding via `Buffer.from(_, 'utf8')` is\n\t// constant-time for the ASCII subset (each char → 1 byte).\n\tconst ab = Buffer.from(a, 'utf8');\n\tconst bb = Buffer.from(b, 'utf8');\n\tif (ab.length !== bb.length) return false; // defensive\n\treturn timingSafeEqual(ab, bb);\n};\n\n// ----------------------------------------------------------------------\n// Logging hygiene\n// ----------------------------------------------------------------------\n\nconst TOKEN_REDACTION_RULE: RedactionRule = {\n\tkind: 'pattern',\n\tpattern: /([#?&]token=)[A-Za-z0-9]+/g,\n\treplacement: '$1<redacted>',\n};\n\n/**\n * Redact the token fragment from any URL-shaped string for logging /\n * TUI rendering. Defense-in-depth — the engine's log sink should never\n * see the unredacted pair URL anyway, but this exists for callers that\n * accidentally pass `pairUrl` straight into a log line.\n *\n * Distilled-doc opportunity (15-wallet.md): the legacy redactor only\n * covered `#token=`. This regex covers BOTH the fragment form and a\n * hypothetical query form so a future config change doesn't silently\n * leak.\n */\nexport const redactToken = (s: string): string => redactText(s, [TOKEN_REDACTION_RULE]);\n"],"mappings":";;;;;;;;;;;;AAkDA,MAAM,WAAW;AAEjB,MAAM,WAAW,MAA4B;;AAO7C,MAAa,kBACZ,OAAO,WAAW,QAAQ,YAAY,GAAG,CAAC,SAAS,MAAM,CAAC,CAAC;;;;;;;AAY5D,MAAa,aAAa,cAA8BA,KAAS,WAAW,UAAU,QAAQ;;;;;;;;;AAU9F,MAAa,uBACZ,SAEA,OAAO,IAAI,aAAa;CAEvB,MAAM,WAAW,OAAO,OAAO,WAAW;EACzC,KAAK,YAAY;AAChB,OAAI;AACH,WAAO,MAAM,SAAS,MAAM,OAAO;YAC3B,KAAK;AACb,QAAK,KAA+B,SAAS,SAAU,QAAO;AAC9D,UAAM;;;EAGR,QAAQ,UACP,gBAAgB;GACf,OAAO;GACP,SAAS,uCAAuC;GAChD,MAAM;GACN;GACA,CAAC;EACH,CAAC;AAEF,KAAI,aAAa,MAAM;EACtB,MAAM,UAAU,SAAS,MAAM;AAC/B,MAAI,SAAS,KAAK,QAAQ,CACzB,QAAO,QAAQ,QAAQ;AAGxB,SAAO,OAAO,WAAW,6CAA6C,CAAC,KACtE,OAAO,aAAa,GAClB,SAAS,kBAAkB,MAC5B,CAAC,CACF;;CAQF,MAAM,QAAQ,OAAO,WAAW;AAEhC,QAAO,gBAAgB,MADT,IAAI,aAAa,CAAC,OAAO,MACL,EAAE,EAAE,MAAM,KAAO,CAAC,CAAC,KACpD,OAAO,UAAU,UAChB,gBAAgB;EACf,OAAO;EACP,SAAS,qCAAqC;EAC9C,MAAM;EACN;EACA,CAAC,CACF,CACD;AAED,QAAO;EACN;;;;;;;;AAaH,MAAa,kBAAkB,WAAmB,UACjD,GAAG,UAAU,IAAI,0BAA0B,GAAG;;;;;;;;;;AA8B/C,MAAa,qBAAqB,WAA8C;AAC/E,KAAI,WAAW,KAAA,EAAW,QAAO;AACjC,KAAI,CAAC,OAAO,WAAA,UAAgC,CAAE,QAAO;CACrD,MAAM,MAAM,OAAO,MAAM,qBAAqB,OAAO;AAIrD,QAAO,IAAI,WAAA,KAAqC,MAAM;;;;;;;;;;;;;;AAmBvD,MAAa,oBAAoB,GAAW,MAAsC;AACjF,KAAI,EAAE,WAAW,EAAE,OAAQ,QAAO;CAIlC,MAAM,KAAK,OAAO,KAAK,GAAG,OAAO;CACjC,MAAM,KAAK,OAAO,KAAK,GAAG,OAAO;AACjC,KAAI,GAAG,WAAW,GAAG,OAAQ,QAAO;AACpC,QAAO,gBAAgB,IAAI,GAAG;;AAO/B,MAAM,uBAAsC;CAC3C,MAAM;CACN,SAAS;CACT,aAAa;CACb;;;;;;;;;;;;AAaD,MAAa,eAAe,MAAsB,WAAW,GAAG,CAAC,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { Schema } from "effect";
|