@mysten-incubation/devstack 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/dashboard-ui/assets/grpc-a4usE3Nk.js +3 -0
- package/dashboard-ui/assets/index-B82Bh84P.css +1 -0
- package/dashboard-ui/assets/index-CRYJ4pru.js +1277 -0
- package/dashboard-ui/index.html +2 -2
- package/dist/api/define-capabilities.d.mts +1 -20
- package/dist/api/define-capabilities.mjs +15 -22
- package/dist/api/define-capabilities.mjs.map +1 -1
- package/dist/api/define-devstack-with.d.mts +7 -1
- package/dist/api/define-devstack-with.mjs.map +1 -1
- package/dist/api/define-devstack.mjs.map +1 -1
- package/dist/api/define-plugin.d.mts +2 -1
- package/dist/api/inference-network.d.mts +31 -17
- package/dist/api/inference-network.mjs +40 -43
- package/dist/api/inference-network.mjs.map +1 -1
- package/dist/api/load-config.mjs +88 -0
- package/dist/api/load-config.mjs.map +1 -0
- package/dist/api/mode-narrowed-factory.d.mts +1 -1
- package/dist/api/mode-narrowed-factory.mjs.map +1 -1
- package/dist/api/run-stack-internal.mjs +202 -0
- package/dist/api/run-stack-internal.mjs.map +1 -0
- package/dist/api/run-stack.d.mts +82 -31
- package/dist/api/run-stack.mjs +22 -141
- package/dist/api/run-stack.mjs.map +1 -1
- package/dist/build-integrations/dapp-kit/index.d.mts +61 -0
- package/dist/build-integrations/dapp-kit/index.mjs +58 -0
- package/dist/build-integrations/dapp-kit/index.mjs.map +1 -0
- package/dist/build-integrations/playwright/config.d.mts +1 -30
- package/dist/build-integrations/playwright/config.mjs +1 -27
- package/dist/build-integrations/playwright/config.mjs.map +1 -1
- package/dist/build-integrations/playwright/errors.d.mts +4 -7
- package/dist/build-integrations/playwright/errors.mjs.map +1 -1
- package/dist/build-integrations/playwright/global-setup.d.mts +42 -71
- package/dist/build-integrations/playwright/global-setup.mjs +142 -218
- package/dist/build-integrations/playwright/global-setup.mjs.map +1 -1
- package/dist/build-integrations/playwright/index.d.mts +2 -2
- package/dist/build-integrations/playwright/index.mjs +2 -2
- package/dist/build-integrations/playwright/stack-context.d.mts +3 -1
- package/dist/build-integrations/playwright/stack-context.mjs +4 -2
- package/dist/build-integrations/playwright/stack-context.mjs.map +1 -1
- package/dist/build-integrations/playwright/wallet-context.mjs +44 -19
- package/dist/build-integrations/playwright/wallet-context.mjs.map +1 -1
- package/dist/build-integrations/runtime/cold-start-url.mjs.map +1 -1
- package/dist/build-integrations/runtime/conventional-routes.mjs.map +1 -1
- package/dist/build-integrations/runtime/dapp-kit-slot.mjs.map +1 -1
- package/dist/build-integrations/runtime/discover.d.mts +6 -4
- package/dist/build-integrations/runtime/discover.mjs +15 -4
- package/dist/build-integrations/runtime/discover.mjs.map +1 -1
- package/dist/build-integrations/runtime/endpoint-registry.mjs.map +1 -1
- package/dist/build-integrations/runtime/errors.mjs.map +1 -1
- package/dist/build-integrations/runtime/read-stack-context.mjs +3 -3
- package/dist/build-integrations/runtime/read-stack-context.mjs.map +1 -1
- package/dist/build-integrations/runtime/resolve-discovery-env.d.mts +23 -7
- package/dist/build-integrations/runtime/resolve-discovery-env.mjs +25 -12
- package/dist/build-integrations/runtime/resolve-discovery-env.mjs.map +1 -1
- package/dist/build-integrations/runtime/stack-context.d.mts +2 -2
- package/dist/build-integrations/vite/index.d.mts +84 -19
- package/dist/build-integrations/vite/index.mjs +203 -28
- package/dist/build-integrations/vite/index.mjs.map +1 -1
- package/dist/build-integrations/vitest/config.d.mts +20 -2
- package/dist/build-integrations/vitest/config.mjs +16 -4
- package/dist/build-integrations/vitest/config.mjs.map +1 -1
- package/dist/build-integrations/vitest/env.d.mts +18 -10
- package/dist/build-integrations/vitest/env.mjs +11 -10
- package/dist/build-integrations/vitest/env.mjs.map +1 -1
- package/dist/build-integrations/vitest/errors.d.mts +7 -11
- package/dist/build-integrations/vitest/errors.mjs +3 -4
- package/dist/build-integrations/vitest/errors.mjs.map +1 -1
- package/dist/build-integrations/vitest/global-setup.d.mts +35 -0
- package/dist/build-integrations/vitest/global-setup.mjs +156 -0
- package/dist/build-integrations/vitest/global-setup.mjs.map +1 -0
- package/dist/build-integrations/vitest/index.d.mts +3 -2
- package/dist/build-integrations/vitest/index.mjs +3 -2
- package/dist/build-integrations/vitest/setup.mjs +2 -2
- package/dist/build-integrations/vitest/setup.mjs.map +1 -1
- package/dist/build-integrations/vitest/stack-context.d.mts +5 -3
- package/dist/build-integrations/vitest/stack-context.mjs +3 -2
- package/dist/build-integrations/vitest/stack-context.mjs.map +1 -1
- package/dist/cli/bail.mjs.map +1 -1
- package/dist/cli/doctor-probes.mjs +1 -3
- package/dist/cli/doctor-probes.mjs.map +1 -1
- package/dist/cli/main.d.mts +23 -1
- package/dist/cli/main.mjs +63 -8
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/prune-direct.mjs.map +1 -1
- package/dist/cli/snapshot-reader.mjs.map +1 -1
- package/dist/cli/up-lifecycle.mjs.map +1 -1
- package/dist/cli/wirings/apply.mjs +28 -21
- package/dist/cli/wirings/apply.mjs.map +1 -1
- package/dist/cli/wirings/codegen.mjs +108 -0
- package/dist/cli/wirings/codegen.mjs.map +1 -0
- package/dist/cli/wirings/config-loader.mjs +12 -62
- package/dist/cli/wirings/config-loader.mjs.map +1 -1
- package/dist/cli/wirings/dump-ids.mjs +86 -0
- package/dist/cli/wirings/dump-ids.mjs.map +1 -0
- package/dist/cli/wirings/engine-command.mjs +1 -1
- package/dist/cli/wirings/engine-command.mjs.map +1 -1
- package/dist/cli/wirings/identity.mjs +2 -2
- package/dist/cli/wirings/identity.mjs.map +1 -1
- package/dist/cli/wirings/provide-file-system.mjs.map +1 -1
- package/dist/cli/wirings/read-devstack-version.mjs +17 -0
- package/dist/cli/wirings/read-devstack-version.mjs.map +1 -0
- package/dist/cli/wirings/snapshot.mjs +27 -34
- package/dist/cli/wirings/snapshot.mjs.map +1 -1
- package/dist/cli/wirings/up-ipc.mjs +147 -0
- package/dist/cli/wirings/up-ipc.mjs.map +1 -0
- package/dist/cli/wirings/up.mjs +218 -198
- package/dist/cli/wirings/up.mjs.map +1 -1
- package/dist/cli/wirings/wipe.mjs +1 -1
- package/dist/cli/wirings/wipe.mjs.map +1 -1
- package/dist/contracts/chain-probe.d.mts +1 -1
- package/dist/contracts/chain-probe.mjs +1 -1
- package/dist/contracts/chain-probe.mjs.map +1 -1
- package/dist/contracts/codegenable.d.mts +60 -6
- package/dist/contracts/codegenable.mjs +28 -0
- package/dist/contracts/codegenable.mjs.map +1 -0
- package/dist/contracts/config-bindings.mjs +162 -0
- package/dist/contracts/config-bindings.mjs.map +1 -0
- package/dist/contracts/container-runtime.d.mts +23 -17
- package/dist/contracts/plugin-expander.mjs.map +1 -1
- package/dist/contracts/snapshotable.d.mts +5 -7
- package/dist/contracts/wallet-protocol.d.mts +2 -5
- package/dist/contracts/wallet-protocol.mjs +2 -5
- package/dist/contracts/wallet-protocol.mjs.map +1 -1
- package/dist/index.d.mts +21 -26
- package/dist/index.mjs +8 -9
- package/dist/orchestrators/boot.d.mts +28 -0
- package/dist/orchestrators/boot.mjs +440 -0
- package/dist/orchestrators/boot.mjs.map +1 -0
- package/dist/orchestrators/codegen/bindings.d.mts +13 -1
- package/dist/orchestrators/codegen/bindings.mjs +23 -9
- package/dist/orchestrators/codegen/bindings.mjs.map +1 -1
- package/dist/orchestrators/codegen/config-runtime.mjs +208 -0
- package/dist/orchestrators/codegen/config-runtime.mjs.map +1 -0
- package/dist/orchestrators/codegen/emit.mjs +1 -1
- package/dist/orchestrators/codegen/emit.mjs.map +1 -1
- package/dist/orchestrators/codegen/errors.mjs +21 -1
- package/dist/orchestrators/codegen/errors.mjs.map +1 -1
- package/dist/orchestrators/codegen/format.mjs +2 -0
- package/dist/orchestrators/codegen/format.mjs.map +1 -1
- package/dist/orchestrators/codegen/gitignore.mjs +30 -11
- package/dist/orchestrators/codegen/gitignore.mjs.map +1 -1
- package/dist/orchestrators/codegen/id-config.mjs +107 -0
- package/dist/orchestrators/codegen/id-config.mjs.map +1 -0
- package/dist/orchestrators/codegen/output-location.mjs +23 -32
- package/dist/orchestrators/codegen/output-location.mjs.map +1 -1
- package/dist/orchestrators/codegen/paths.mjs +8 -1
- package/dist/orchestrators/codegen/paths.mjs.map +1 -1
- package/dist/orchestrators/codegen/permissions.mjs.map +1 -1
- package/dist/orchestrators/codegen/service.mjs +286 -58
- package/dist/orchestrators/codegen/service.mjs.map +1 -1
- package/dist/orchestrators/layers.mjs +31 -0
- package/dist/orchestrators/layers.mjs.map +1 -0
- package/dist/orchestrators/lifecycle-prune/errors.mjs.map +1 -1
- package/dist/orchestrators/lifecycle-prune/index.mjs +8 -10
- package/dist/orchestrators/lifecycle-prune/index.mjs.map +1 -1
- package/dist/orchestrators/network-options.d.mts +52 -0
- package/dist/orchestrators/network-options.mjs +43 -0
- package/dist/orchestrators/network-options.mjs.map +1 -0
- package/dist/orchestrators/router/cleanup.mjs.map +1 -1
- package/dist/orchestrators/router/cors.mjs.map +1 -1
- package/dist/orchestrators/router/entrypoints.mjs.map +1 -1
- package/dist/orchestrators/router/errors.mjs.map +1 -1
- package/dist/orchestrators/router/file-provider.mjs.map +1 -1
- package/dist/orchestrators/router/hostname.mjs.map +1 -1
- package/dist/orchestrators/router/profile.mjs +1 -1
- package/dist/orchestrators/router/profile.mjs.map +1 -1
- package/dist/orchestrators/router/service.d.mts +2 -2
- package/dist/orchestrators/router/service.mjs +12 -27
- package/dist/orchestrators/router/service.mjs.map +1 -1
- package/dist/orchestrators/router/traefik-container.mjs +1 -1
- package/dist/orchestrators/router/traefik-container.mjs.map +1 -1
- package/dist/orchestrators/snapshot/capture.mjs +171 -195
- package/dist/orchestrators/snapshot/capture.mjs.map +1 -1
- package/dist/orchestrators/snapshot/descriptor.d.mts +1 -1
- package/dist/orchestrators/snapshot/descriptor.mjs +53 -11
- package/dist/orchestrators/snapshot/descriptor.mjs.map +1 -1
- package/dist/orchestrators/snapshot/identity-guard.mjs +3 -5
- package/dist/orchestrators/snapshot/identity-guard.mjs.map +1 -1
- package/dist/orchestrators/snapshot/image-bundle-tags.mjs +32 -101
- package/dist/orchestrators/snapshot/image-bundle-tags.mjs.map +1 -1
- package/dist/orchestrators/snapshot/index.mjs +1 -4
- package/dist/orchestrators/snapshot/integrity.mjs.map +1 -1
- package/dist/orchestrators/snapshot/interrupted-restore.mjs +116 -0
- package/dist/orchestrators/snapshot/interrupted-restore.mjs.map +1 -0
- package/dist/orchestrators/snapshot/phase-error.mjs.map +1 -1
- package/dist/orchestrators/snapshot/prune.mjs +40 -31
- package/dist/orchestrators/snapshot/prune.mjs.map +1 -1
- package/dist/orchestrators/snapshot/restore.mjs +221 -196
- package/dist/orchestrators/snapshot/restore.mjs.map +1 -1
- package/dist/orchestrators/snapshot/service.mjs +72 -62
- package/dist/orchestrators/snapshot/service.mjs.map +1 -1
- package/dist/orchestrators/snapshot/wipe.mjs +67 -56
- package/dist/orchestrators/snapshot/wipe.mjs.map +1 -1
- package/dist/plugins/account/codegen.mjs +3 -0
- package/dist/plugins/account/codegen.mjs.map +1 -1
- package/dist/plugins/account/errors.d.mts +2 -2
- package/dist/plugins/account/errors.mjs +1 -4
- package/dist/plugins/account/errors.mjs.map +1 -1
- package/dist/plugins/account/funding.mjs +3 -27
- package/dist/plugins/account/funding.mjs.map +1 -1
- package/dist/plugins/account/index.d.mts +3 -8
- package/dist/plugins/account/index.mjs +71 -35
- package/dist/plugins/account/index.mjs.map +1 -1
- package/dist/plugins/account/keypair.d.mts +8 -7
- package/dist/plugins/account/keypair.mjs +5 -18
- package/dist/plugins/account/keypair.mjs.map +1 -1
- package/dist/plugins/account/lease.mjs.map +1 -1
- package/dist/plugins/account/registry.d.mts +1 -46
- package/dist/plugins/account/registry.mjs.map +1 -1
- package/dist/plugins/account/service.d.mts +43 -34
- package/dist/plugins/account/service.mjs +9 -54
- package/dist/plugins/account/service.mjs.map +1 -1
- package/dist/plugins/account/snapshot.mjs.map +1 -1
- package/dist/plugins/account/variants/ephemeral.mjs.map +1 -1
- package/dist/plugins/account/variants/impersonate.mjs.map +1 -1
- package/dist/plugins/account/variants/signer.mjs.map +1 -1
- package/dist/plugins/action/discriminator.mjs.map +1 -1
- package/dist/plugins/action/errors.mjs +1 -4
- package/dist/plugins/action/errors.mjs.map +1 -1
- package/dist/plugins/action/execute.mjs +3 -4
- package/dist/plugins/action/execute.mjs.map +1 -1
- package/dist/plugins/action/index.d.mts +2 -2
- package/dist/plugins/action/index.mjs +7 -11
- package/dist/plugins/action/index.mjs.map +1 -1
- package/dist/plugins/action/service.d.mts +5 -7
- package/dist/plugins/action/service.mjs +2 -16
- package/dist/plugins/action/service.mjs.map +1 -1
- package/dist/plugins/coin/address-resolution.mjs.map +1 -1
- package/dist/plugins/coin/codegen.mjs +97 -16
- package/dist/plugins/coin/codegen.mjs.map +1 -1
- package/dist/plugins/coin/discovery.mjs.map +1 -1
- package/dist/plugins/coin/errors.mjs +1 -4
- package/dist/plugins/coin/errors.mjs.map +1 -1
- package/dist/plugins/coin/index.d.mts +4 -34
- package/dist/plugins/coin/index.mjs +47 -28
- package/dist/plugins/coin/index.mjs.map +1 -1
- package/dist/plugins/coin/metadata.d.mts +1 -0
- package/dist/plugins/coin/metadata.mjs +8 -9
- package/dist/plugins/coin/metadata.mjs.map +1 -1
- package/dist/plugins/coin/mint.mjs +7 -21
- package/dist/plugins/coin/mint.mjs.map +1 -1
- package/dist/plugins/coin/registry.mjs +33 -20
- package/dist/plugins/coin/registry.mjs.map +1 -1
- package/dist/plugins/coin/service.d.mts +1 -1
- package/dist/plugins/coin/service.mjs +1 -8
- package/dist/plugins/coin/service.mjs.map +1 -1
- package/dist/plugins/coin/snapshot.mjs.map +1 -1
- package/dist/plugins/coin/type-strings.mjs.map +1 -1
- package/dist/plugins/dashboard/domain.mjs +106 -167
- package/dist/plugins/dashboard/domain.mjs.map +1 -1
- package/dist/plugins/dashboard/index.mjs +13 -13
- package/dist/plugins/dashboard/index.mjs.map +1 -1
- package/dist/plugins/dashboard/origin-policy.mjs +3 -3
- package/dist/plugins/dashboard/origin-policy.mjs.map +1 -1
- package/dist/plugins/dashboard/routable.mjs.map +1 -1
- package/dist/plugins/dashboard/schema/builder.mjs.map +1 -1
- package/dist/plugins/dashboard/schema/enums.mjs.map +1 -1
- package/dist/plugins/dashboard/schema/root.mjs +23 -44
- package/dist/plugins/dashboard/schema/root.mjs.map +1 -1
- package/dist/plugins/dashboard/schema/types.mjs +37 -91
- package/dist/plugins/dashboard/schema/types.mjs.map +1 -1
- package/dist/plugins/dashboard/schema.mjs.map +1 -1
- package/dist/plugins/dashboard/server.mjs.map +1 -1
- package/dist/plugins/deepbook/codegen.d.mts +12 -11
- package/dist/plugins/deepbook/codegen.mjs +108 -11
- package/dist/plugins/deepbook/codegen.mjs.map +1 -1
- package/dist/plugins/deepbook/deploy.mjs +7 -14
- package/dist/plugins/deepbook/deploy.mjs.map +1 -1
- package/dist/plugins/deepbook/errors.mjs +4 -2
- package/dist/plugins/deepbook/errors.mjs.map +1 -1
- package/dist/plugins/deepbook/faucet-strategy.mjs +4 -10
- package/dist/plugins/deepbook/faucet-strategy.mjs.map +1 -1
- package/dist/plugins/deepbook/hash.mjs.map +1 -1
- package/dist/plugins/deepbook/index.d.mts +38 -34
- package/dist/plugins/deepbook/index.mjs +133 -64
- package/dist/plugins/deepbook/index.mjs.map +1 -1
- package/dist/plugins/deepbook/plugin-key.mjs.map +1 -1
- package/dist/plugins/deepbook/pyth/index.mjs +4 -8
- package/dist/plugins/deepbook/pyth/index.mjs.map +1 -1
- package/dist/plugins/deepbook/snapshot.mjs +0 -1
- package/dist/plugins/deepbook/snapshot.mjs.map +1 -1
- package/dist/plugins/deepbook/type-strings.mjs.map +1 -1
- package/dist/plugins/deepbook/types.d.mts +2 -1
- package/dist/plugins/deepbook/types.mjs.map +1 -1
- package/dist/plugins/faucet/dispatcher.d.mts +3 -3
- package/dist/plugins/faucet/dispatcher.mjs.map +1 -1
- package/dist/plugins/faucet/errors.mjs.map +1 -1
- package/dist/plugins/faucet/http.mjs +2 -10
- package/dist/plugins/faucet/http.mjs.map +1 -1
- package/dist/plugins/faucet/index.mjs +0 -1
- package/dist/plugins/faucet/index.mjs.map +1 -1
- package/dist/plugins/host-service/errors.d.mts +1 -3
- package/dist/plugins/host-service/errors.mjs +1 -2
- package/dist/plugins/host-service/errors.mjs.map +1 -1
- package/dist/plugins/host-service/index.d.mts +1 -2
- package/dist/plugins/host-service/index.mjs +11 -11
- package/dist/plugins/host-service/index.mjs.map +1 -1
- package/dist/plugins/host-service/routable.mjs.map +1 -1
- package/dist/plugins/host-service/service.mjs +13 -13
- package/dist/plugins/host-service/service.mjs.map +1 -1
- package/dist/plugins/internal/acquire-on-chain-artifact.mjs.map +1 -1
- package/dist/plugins/internal/codegen-helpers.mjs +2 -0
- package/dist/plugins/internal/codegen-helpers.mjs.map +1 -1
- package/dist/plugins/internal/funding-failure-error.mjs.map +1 -1
- package/dist/plugins/{postgres → internal/postgres-sidecar}/connection.mjs +1 -1
- package/dist/plugins/internal/postgres-sidecar/connection.mjs.map +1 -0
- package/dist/plugins/{postgres → internal/postgres-sidecar}/db-ensure.mjs +30 -16
- package/dist/plugins/internal/postgres-sidecar/db-ensure.mjs.map +1 -0
- package/dist/plugins/internal/postgres-sidecar/errors.mjs +21 -0
- package/dist/plugins/internal/postgres-sidecar/errors.mjs.map +1 -0
- package/dist/{substrate/runtime/scoped-multimap → plugins/internal/postgres-sidecar}/index.mjs +1 -0
- package/dist/plugins/internal/postgres-sidecar/service.mjs +121 -0
- package/dist/plugins/internal/postgres-sidecar/service.mjs.map +1 -0
- package/dist/plugins/package/build.mjs +2 -2
- package/dist/plugins/package/build.mjs.map +1 -1
- package/dist/plugins/package/codegen.d.mts +7 -14
- package/dist/plugins/package/codegen.mjs +187 -59
- package/dist/plugins/package/codegen.mjs.map +1 -1
- package/dist/plugins/package/dep-resolution.mjs +51 -3
- package/dist/plugins/package/dep-resolution.mjs.map +1 -1
- package/dist/plugins/package/errors.mjs +1 -4
- package/dist/plugins/package/errors.mjs.map +1 -1
- package/dist/plugins/package/git-source.d.mts +18 -0
- package/dist/plugins/package/git-source.mjs +119 -0
- package/dist/plugins/package/git-source.mjs.map +1 -0
- package/dist/plugins/package/index.d.mts +28 -19
- package/dist/plugins/package/index.mjs +107 -32
- package/dist/plugins/package/index.mjs.map +1 -1
- package/dist/plugins/package/mode-known.mjs +2 -2
- package/dist/plugins/package/mode-known.mjs.map +1 -1
- package/dist/plugins/package/mode-local.mjs +18 -35
- package/dist/plugins/package/mode-local.mjs.map +1 -1
- package/dist/plugins/package/publish-executor.mjs +13 -8
- package/dist/plugins/package/publish-executor.mjs.map +1 -1
- package/dist/plugins/package/publish-output.d.mts +1 -11
- package/dist/plugins/package/publish-output.mjs +1 -9
- package/dist/plugins/package/publish-output.mjs.map +1 -1
- package/dist/plugins/package/registry.d.mts +1 -1
- package/dist/plugins/package/registry.mjs +26 -14
- package/dist/plugins/package/registry.mjs.map +1 -1
- package/dist/plugins/package/service.mjs.map +1 -1
- package/dist/plugins/package/snapshot.mjs.map +1 -1
- package/dist/plugins/router-entrypoints.mjs +1 -3
- package/dist/plugins/router-entrypoints.mjs.map +1 -1
- package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs +1 -2
- package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs.map +1 -1
- package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs +1 -6
- package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs.map +1 -1
- package/dist/plugins/seal/codegen.d.mts +1 -5
- package/dist/plugins/seal/codegen.mjs +83 -12
- package/dist/plugins/seal/codegen.mjs.map +1 -1
- package/dist/plugins/seal/config-render.mjs +2 -6
- package/dist/plugins/seal/config-render.mjs.map +1 -1
- package/dist/plugins/seal/deploy.mjs +18 -29
- package/dist/plugins/seal/deploy.mjs.map +1 -1
- package/dist/plugins/seal/errors.d.mts +4 -5
- package/dist/plugins/seal/errors.mjs +1 -8
- package/dist/plugins/seal/errors.mjs.map +1 -1
- package/dist/plugins/seal/index.d.mts +7 -28
- package/dist/plugins/seal/index.mjs +69 -47
- package/dist/plugins/seal/index.mjs.map +1 -1
- package/dist/plugins/seal/key-manager.mjs.map +1 -1
- package/dist/plugins/seal/key-server.mjs +1 -6
- package/dist/plugins/seal/key-server.mjs.map +1 -1
- package/dist/plugins/seal/keygen.mjs +2 -3
- package/dist/plugins/seal/keygen.mjs.map +1 -1
- package/dist/plugins/seal/mode/fork-known.mjs.map +1 -1
- package/dist/plugins/seal/mode/live.mjs +1 -1
- package/dist/plugins/seal/mode/live.mjs.map +1 -1
- package/dist/plugins/seal/mode/local-keygen.mjs +4 -10
- package/dist/plugins/seal/mode/local-keygen.mjs.map +1 -1
- package/dist/plugins/seal/plugin-key.mjs.map +1 -1
- package/dist/plugins/seal/registry-publish.mjs.map +1 -1
- package/dist/plugins/seal/routable.mjs.map +1 -1
- package/dist/plugins/seal/service.mjs.map +1 -1
- package/dist/plugins/seal/snapshot.mjs +1 -2
- package/dist/plugins/seal/snapshot.mjs.map +1 -1
- package/dist/plugins/sui/auto-tick.mjs +5 -5
- package/dist/plugins/sui/auto-tick.mjs.map +1 -1
- package/dist/plugins/sui/chain-build-container.mjs +2 -2
- package/dist/plugins/sui/chain-build-container.mjs.map +1 -1
- package/dist/plugins/sui/chain-probe.mjs +4 -4
- package/dist/plugins/sui/chain-probe.mjs.map +1 -1
- package/dist/plugins/sui/codegen.d.mts +9 -7
- package/dist/plugins/sui/codegen.mjs +49 -46
- package/dist/plugins/sui/codegen.mjs.map +1 -1
- package/dist/plugins/sui/errors.d.mts +1 -1
- package/dist/plugins/sui/errors.mjs +1 -9
- package/dist/plugins/sui/errors.mjs.map +1 -1
- package/dist/{substrate/runtime/sui-execute → plugins/sui/exec}/index.d.mts +1 -1
- package/dist/{substrate/runtime/sui-execute → plugins/sui/exec}/index.mjs +3 -7
- package/dist/plugins/sui/exec/index.mjs.map +1 -0
- package/dist/{substrate/runtime/sui-execute → plugins/sui/exec}/sign-and-dispatch.mjs +1 -1
- package/dist/plugins/sui/exec/sign-and-dispatch.mjs.map +1 -0
- package/dist/plugins/sui/fork-faucet-strategy.mjs +2 -6
- package/dist/plugins/sui/fork-faucet-strategy.mjs.map +1 -1
- package/dist/plugins/sui/fork-orchestration.mjs +13 -23
- package/dist/plugins/sui/fork-orchestration.mjs.map +1 -1
- package/dist/plugins/sui/fork-transaction.mjs.map +1 -1
- package/dist/plugins/sui/index.d.mts +34 -83
- package/dist/plugins/sui/index.mjs +200 -68
- package/dist/plugins/sui/index.mjs.map +1 -1
- package/dist/{substrate/runtime/sui-ledger → plugins/sui/ledger}/object-ref.mjs +1 -1
- package/dist/plugins/sui/ledger/object-ref.mjs.map +1 -0
- package/dist/plugins/sui/local-faucet-strategy.mjs +1 -5
- package/dist/plugins/sui/local-faucet-strategy.mjs.map +1 -1
- package/dist/plugins/sui/log-attrs.mjs +11 -0
- package/dist/plugins/sui/log-attrs.mjs.map +1 -0
- package/dist/plugins/sui/mode/external.mjs +4 -12
- package/dist/plugins/sui/mode/external.mjs.map +1 -1
- package/dist/plugins/sui/mode/fork.mjs +19 -16
- package/dist/plugins/sui/mode/fork.mjs.map +1 -1
- package/dist/plugins/sui/mode/live.mjs +4 -17
- package/dist/plugins/sui/mode/live.mjs.map +1 -1
- package/dist/plugins/sui/mode/local.d.mts +1 -0
- package/dist/plugins/sui/mode/local.mjs +203 -61
- package/dist/plugins/sui/mode/local.mjs.map +1 -1
- package/dist/plugins/sui/mode/shared-boot.mjs +18 -23
- package/dist/plugins/sui/mode/shared-boot.mjs.map +1 -1
- package/dist/plugins/sui/mode/shared.d.mts +6 -7
- package/dist/plugins/sui/mode/shared.mjs.map +1 -1
- package/dist/plugins/sui/mode/spec.d.mts +23 -6
- package/dist/{substrate/runtime/sui-move-build → plugins/sui/move}/index.mjs +28 -30
- package/dist/plugins/sui/move/index.mjs.map +1 -0
- package/dist/plugins/sui/move-summary-runner.mjs +8 -4
- package/dist/plugins/sui/move-summary-runner.mjs.map +1 -1
- package/dist/{substrate/network.d.mts → plugins/sui/network-config.d.mts} +11 -10
- package/dist/plugins/sui/network-resolver.d.mts +6 -6
- package/dist/plugins/sui/routable.mjs.map +1 -1
- package/dist/plugins/sui/service.mjs +10 -6
- package/dist/plugins/sui/service.mjs.map +1 -1
- package/dist/plugins/sui/snapshot.mjs +10 -5
- package/dist/plugins/sui/snapshot.mjs.map +1 -1
- package/dist/plugins/wallet/codegen.d.mts +8 -6
- package/dist/plugins/wallet/codegen.mjs +4 -10
- package/dist/plugins/wallet/codegen.mjs.map +1 -1
- package/dist/plugins/wallet/errors.mjs +1 -4
- package/dist/plugins/wallet/errors.mjs.map +1 -1
- package/dist/plugins/wallet/index.d.mts +3 -6
- package/dist/plugins/wallet/index.mjs +16 -21
- package/dist/plugins/wallet/index.mjs.map +1 -1
- package/dist/plugins/wallet/origin-policy.mjs +3 -3
- package/dist/plugins/wallet/origin-policy.mjs.map +1 -1
- package/dist/plugins/wallet/pairing.mjs +6 -24
- package/dist/plugins/wallet/pairing.mjs.map +1 -1
- package/dist/plugins/wallet/protocol.mjs.map +1 -1
- package/dist/plugins/wallet/routable.mjs.map +1 -1
- package/dist/plugins/wallet/server.mjs +17 -24
- package/dist/plugins/wallet/server.mjs.map +1 -1
- package/dist/plugins/wallet/service.d.mts +2 -2
- package/dist/plugins/wallet/service.mjs +4 -15
- package/dist/plugins/wallet/service.mjs.map +1 -1
- package/dist/plugins/wallet/snapshot.mjs.map +1 -1
- package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs +1 -5
- package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs.map +1 -1
- package/dist/plugins/walrus/codegen.d.mts +2 -13
- package/dist/plugins/walrus/codegen.mjs +93 -28
- package/dist/plugins/walrus/codegen.mjs.map +1 -1
- package/dist/plugins/walrus/deploy-paths.mjs +2 -3
- package/dist/plugins/walrus/deploy-paths.mjs.map +1 -1
- package/dist/plugins/walrus/deploy.mjs +26 -19
- package/dist/plugins/walrus/deploy.mjs.map +1 -1
- package/dist/plugins/walrus/errors.mjs +1 -8
- package/dist/plugins/walrus/errors.mjs.map +1 -1
- package/dist/plugins/walrus/faucet-strategy.mjs +15 -1
- package/dist/plugins/walrus/faucet-strategy.mjs.map +1 -1
- package/dist/plugins/walrus/index.d.mts +13 -44
- package/dist/plugins/walrus/index.mjs +119 -122
- package/dist/plugins/walrus/index.mjs.map +1 -1
- package/dist/plugins/walrus/mode/known-deploy.mjs +6 -6
- package/dist/plugins/walrus/mode/known-deploy.mjs.map +1 -1
- package/dist/plugins/walrus/mode/local-cluster.d.mts +2 -2
- package/dist/plugins/walrus/mode/local-cluster.mjs +2 -10
- package/dist/plugins/walrus/mode/local-cluster.mjs.map +1 -1
- package/dist/plugins/walrus/plugin-key.mjs.map +1 -1
- package/dist/plugins/walrus/registry-publish.mjs.map +1 -1
- package/dist/plugins/walrus/routable.mjs.map +1 -1
- package/dist/plugins/walrus/service.mjs.map +1 -1
- package/dist/plugins/walrus/snapshot.mjs +3 -3
- package/dist/plugins/walrus/snapshot.mjs.map +1 -1
- package/dist/plugins/walrus/storage-nodes.mjs +53 -14
- package/dist/plugins/walrus/storage-nodes.mjs.map +1 -1
- package/dist/plugins/walrus/wal-swap.mjs +4 -8
- package/dist/plugins/walrus/wal-swap.mjs.map +1 -1
- package/dist/primitives/artifact-publisher.mjs.map +1 -1
- package/dist/primitives/cache.d.mts +1 -1
- package/dist/runtime/docker/client.mjs +47 -3
- package/dist/runtime/docker/client.mjs.map +1 -1
- package/dist/runtime/docker/container.mjs +37 -57
- package/dist/runtime/docker/container.mjs.map +1 -1
- package/dist/runtime/docker/errors.mjs.map +1 -1
- package/dist/runtime/docker/exec.mjs +2 -2
- package/dist/runtime/docker/exec.mjs.map +1 -1
- package/dist/runtime/docker/image.mjs +10 -11
- package/dist/runtime/docker/image.mjs.map +1 -1
- package/dist/runtime/docker/index.mjs +0 -1
- package/dist/runtime/docker/inspect-and-decode.mjs.map +1 -1
- package/dist/runtime/docker/inventory.mjs +9 -9
- package/dist/runtime/docker/inventory.mjs.map +1 -1
- package/dist/runtime/docker/labels.mjs +12 -1
- package/dist/runtime/docker/labels.mjs.map +1 -1
- package/dist/runtime/docker/network.mjs +6 -6
- package/dist/runtime/docker/network.mjs.map +1 -1
- package/dist/runtime/docker/render-run-args.mjs.map +1 -1
- package/dist/runtime/docker/service.mjs +31 -45
- package/dist/runtime/docker/service.mjs.map +1 -1
- package/dist/runtime/docker/sweep.mjs +14 -64
- package/dist/runtime/docker/sweep.mjs.map +1 -1
- package/dist/runtime/docker/volume.mjs +1 -1
- package/dist/runtime/docker/volume.mjs.map +1 -1
- package/dist/runtime/docker/wrap.mjs +14 -2
- package/dist/runtime/docker/wrap.mjs.map +1 -1
- package/dist/substrate/brand.d.mts +2 -5
- package/dist/substrate/brand.mjs +3 -2
- package/dist/substrate/brand.mjs.map +1 -1
- package/dist/substrate/cross-process.mjs +2 -16
- package/dist/substrate/cross-process.mjs.map +1 -1
- package/dist/substrate/event-time.mjs +0 -2
- package/dist/substrate/event-time.mjs.map +1 -1
- package/dist/substrate/events.d.mts +46 -16
- package/dist/substrate/identity.d.mts +11 -5
- package/dist/substrate/manifest.d.mts +33 -26
- package/dist/substrate/manifest.mjs +8 -3
- package/dist/substrate/manifest.mjs.map +1 -1
- package/dist/substrate/options.d.mts +33 -4
- package/dist/substrate/plugin-ctx.d.mts +70 -0
- package/dist/substrate/plugin-ctx.mjs +66 -0
- package/dist/substrate/plugin-ctx.mjs.map +1 -0
- package/dist/substrate/plugin.d.mts +46 -38
- package/dist/substrate/plugin.mjs +13 -9
- package/dist/substrate/plugin.mjs.map +1 -1
- package/dist/substrate/projection.d.mts +1 -1
- package/dist/substrate/runtime/atomic-write.mjs +3 -4
- package/dist/substrate/runtime/atomic-write.mjs.map +1 -1
- package/dist/substrate/runtime/cache/schema.mjs.map +1 -1
- package/dist/substrate/runtime/cache/service.mjs +50 -20
- package/dist/substrate/runtime/cache/service.mjs.map +1 -1
- package/dist/substrate/runtime/config-validation.mjs.map +1 -1
- package/dist/substrate/runtime/control-plane/domain.mjs +34 -12
- package/dist/substrate/runtime/control-plane/domain.mjs.map +1 -1
- package/dist/substrate/runtime/control-plane/service.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/command-channel/channel.mjs +14 -17
- package/dist/substrate/runtime/cross-process/command-channel/channel.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/command-channel/runtime-control-lock.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/index.mjs +0 -2
- package/dist/substrate/runtime/cross-process/live-clock.mjs +1 -1
- package/dist/substrate/runtime/cross-process/live-clock.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/liveness.mjs +11 -18
- package/dist/substrate/runtime/cross-process/liveness.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs +2 -2
- package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/roster.mjs +17 -127
- package/dist/substrate/runtime/cross-process/roster.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/self-pid.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/stack-lock.mjs +29 -28
- package/dist/substrate/runtime/cross-process/stack-lock.mjs.map +1 -1
- package/dist/substrate/runtime/current-plugin.mjs.map +1 -1
- package/dist/substrate/runtime/errors.mjs +1 -13
- package/dist/substrate/runtime/errors.mjs.map +1 -1
- package/dist/substrate/runtime/format-unknown-error.mjs.map +1 -1
- package/dist/substrate/runtime/host-bind-mount-owner.mjs.map +1 -1
- package/dist/substrate/runtime/host-gateway.mjs.map +1 -1
- package/dist/substrate/runtime/host-tree-tar/index.mjs +15 -163
- package/dist/substrate/runtime/host-tree-tar/index.mjs.map +1 -1
- package/dist/substrate/runtime/http-probe.d.mts +1 -3
- package/dist/substrate/runtime/http-probe.mjs.map +1 -1
- package/dist/substrate/runtime/index.mjs +1 -6
- package/dist/substrate/runtime/lease-broker/service.mjs +5 -23
- package/dist/substrate/runtime/lease-broker/service.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/dep-graph.mjs +3 -3
- package/dist/substrate/runtime/lifecycle/dep-graph.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/graph-input-id.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/graph-input-id.mjs +133 -0
- package/dist/substrate/runtime/lifecycle/graph-input-id.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/index.mjs +2 -2
- package/dist/substrate/runtime/lifecycle/plugin-registry.d.mts +1 -1
- package/dist/substrate/runtime/lifecycle/plugin-registry.mjs +22 -1
- package/dist/substrate/runtime/lifecycle/plugin-registry.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/ready-gate.mjs +2 -15
- package/dist/substrate/runtime/lifecycle/ready-gate.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/selective-restart.mjs +29 -25
- package/dist/substrate/runtime/lifecycle/selective-restart.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/signals.mjs +1 -1
- package/dist/substrate/runtime/lifecycle/signals.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/state-machine.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/watch-attribution.d.mts +1 -1
- package/dist/substrate/runtime/lifecycle/watch-attribution.mjs +0 -1
- package/dist/substrate/runtime/lifecycle/watch-attribution.mjs.map +1 -1
- package/dist/substrate/runtime/managed-container.d.mts +5 -1
- package/dist/substrate/runtime/managed-container.mjs +8 -10
- package/dist/substrate/runtime/managed-container.mjs.map +1 -1
- package/dist/substrate/runtime/manifest/manifest.mjs +8 -30
- package/dist/substrate/runtime/manifest/manifest.mjs.map +1 -1
- package/dist/substrate/runtime/mode-errors.d.mts +1 -2
- package/dist/substrate/runtime/mode-errors.mjs.map +1 -1
- package/dist/substrate/runtime/observability/cascade-formatter.mjs +1 -11
- package/dist/substrate/runtime/observability/cascade-formatter.mjs.map +1 -1
- package/dist/substrate/runtime/observability/ignore-with-log.mjs.map +1 -1
- package/dist/substrate/runtime/observability/index.d.mts +1 -1
- package/dist/substrate/runtime/observability/index.mjs +4 -6
- package/dist/substrate/runtime/observability/log-attrs.mjs +46 -0
- package/dist/substrate/runtime/observability/log-attrs.mjs.map +1 -0
- package/dist/substrate/runtime/observability/log-store.mjs.map +1 -1
- package/dist/substrate/runtime/observability/logger.mjs +3 -3
- package/dist/substrate/runtime/observability/logger.mjs.map +1 -1
- package/dist/substrate/runtime/observability/output-truncate.mjs.map +1 -1
- package/dist/substrate/runtime/observability/pretty-error.mjs.map +1 -1
- package/dist/substrate/runtime/observability/process-lines.mjs.map +1 -1
- package/dist/substrate/runtime/observability/redaction.mjs.map +1 -1
- package/dist/substrate/runtime/observability/subprocess-capture.mjs +2 -2
- package/dist/substrate/runtime/observability/subprocess-capture.mjs.map +1 -1
- package/dist/substrate/runtime/passthrough-or-wrap.mjs.map +1 -1
- package/dist/substrate/runtime/paths.mjs +27 -9
- package/dist/substrate/runtime/paths.mjs.map +1 -1
- package/dist/substrate/runtime/phase-preserving-produce.mjs.map +1 -1
- package/dist/substrate/runtime/port-broker/service.mjs +10 -27
- package/dist/substrate/runtime/port-broker/service.mjs.map +1 -1
- package/dist/substrate/runtime/post-acquire-tasks.mjs.map +1 -1
- package/dist/substrate/runtime/probes.d.mts +2 -3
- package/dist/substrate/runtime/probes.mjs.map +1 -1
- package/dist/substrate/runtime/process-supervisor.mjs.map +1 -1
- package/dist/substrate/runtime/projection/operational-endpoints.mjs.map +1 -1
- package/dist/substrate/runtime/projection/state-ref.mjs.map +1 -1
- package/dist/substrate/runtime/projection/update.mjs +87 -11
- package/dist/substrate/runtime/projection/update.mjs.map +1 -1
- package/dist/substrate/runtime/random-suffix.mjs.map +1 -1
- package/dist/substrate/runtime/reconcile/fs-plan.mjs +146 -0
- package/dist/substrate/runtime/reconcile/fs-plan.mjs.map +1 -0
- package/dist/substrate/runtime/reconcile/graph.mjs +19 -0
- package/dist/substrate/runtime/reconcile/graph.mjs.map +1 -0
- package/dist/substrate/runtime/reconcile/index.mjs +5 -0
- package/dist/substrate/runtime/reconcile/label.mjs +41 -0
- package/dist/substrate/runtime/reconcile/label.mjs.map +1 -0
- package/dist/substrate/runtime/reconcile/spec.mjs +15 -0
- package/dist/substrate/runtime/reconcile/spec.mjs.map +1 -0
- package/dist/substrate/runtime/retry-policy.d.mts +2 -3
- package/dist/substrate/runtime/retry-policy.mjs.map +1 -1
- package/dist/substrate/runtime/routed-url.mjs.map +1 -1
- package/dist/substrate/runtime/runtime-decode.mjs.map +1 -1
- package/dist/substrate/runtime/scoped-http-server.mjs.map +1 -1
- package/dist/substrate/runtime/stage-and-swap/index.mjs +49 -12
- package/dist/substrate/runtime/stage-and-swap/index.mjs.map +1 -1
- package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.mjs.map +1 -1
- package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs.map +1 -1
- package/dist/substrate/runtime/strategy-registry/service.mjs +29 -17
- package/dist/substrate/runtime/strategy-registry/service.mjs.map +1 -1
- package/dist/substrate/runtime/subnet-broker.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/acquire-node.mjs +188 -56
- package/dist/substrate/runtime/supervisor/acquire-node.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/background-tasks.mjs +79 -65
- package/dist/substrate/runtime/supervisor/background-tasks.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/command-loop.mjs +82 -23
- package/dist/substrate/runtime/supervisor/command-loop.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/contribution-dispatcher.mjs +16 -0
- package/dist/substrate/runtime/supervisor/contribution-dispatcher.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/errors.mjs +11 -2
- package/dist/substrate/runtime/supervisor/errors.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/index.mjs +2 -0
- package/dist/substrate/runtime/supervisor/shutdown.mjs +6 -6
- package/dist/substrate/runtime/supervisor/shutdown.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/start-supervisor.mjs +60 -70
- package/dist/substrate/runtime/supervisor/start-supervisor.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/state.d.mts +1 -1
- package/dist/substrate/runtime/supervisor/state.mjs +1 -1
- package/dist/substrate/runtime/supervisor/state.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/teardown.mjs +10 -9
- package/dist/substrate/runtime/supervisor/teardown.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/wiring.mjs +6 -20
- package/dist/substrate/runtime/supervisor/wiring.mjs.map +1 -1
- package/dist/substrate/runtime/tar/reader.mjs +216 -0
- package/dist/substrate/runtime/tar/reader.mjs.map +1 -0
- package/dist/substrate/runtime/typed-env.mjs.map +1 -1
- package/dist/substrate/versioned-doc-schema.mjs.map +1 -1
- package/dist/substrate/versioned-doc-sync.mjs +5 -5
- package/dist/substrate/versioned-doc-sync.mjs.map +1 -1
- package/dist/surfaces/cli/command-tree.mjs +49 -7
- package/dist/surfaces/cli/command-tree.mjs.map +1 -1
- package/dist/surfaces/cli/commands/config.mjs +1 -1
- package/dist/surfaces/cli/commands/config.mjs.map +1 -1
- package/dist/surfaces/cli/commands/confirm-node.mjs.map +1 -1
- package/dist/surfaces/cli/commands/confirm.mjs.map +1 -1
- package/dist/surfaces/cli/commands/doctor.mjs +1 -1
- package/dist/surfaces/cli/commands/doctor.mjs.map +1 -1
- package/dist/surfaces/cli/commands/prune-picker-entry.mjs.map +1 -1
- package/dist/surfaces/cli/commands/prune-picker.mjs.map +1 -1
- package/dist/surfaces/cli/commands/prune.mjs +1 -1
- package/dist/surfaces/cli/commands/prune.mjs.map +1 -1
- package/dist/surfaces/cli/commands/snapshot.mjs +1 -1
- package/dist/surfaces/cli/commands/snapshot.mjs.map +1 -1
- package/dist/surfaces/cli/commands/status.mjs +1 -1
- package/dist/surfaces/cli/commands/status.mjs.map +1 -1
- package/dist/surfaces/cli/commands/supervisor-presence.mjs.map +1 -1
- package/dist/surfaces/cli/commands/wipe.mjs +3 -4
- package/dist/surfaces/cli/commands/wipe.mjs.map +1 -1
- package/dist/surfaces/cli/envelope.mjs.map +1 -1
- package/dist/surfaces/cli/errors.mjs.map +1 -1
- package/dist/surfaces/cli/flags.mjs.map +1 -1
- package/dist/surfaces/cli/index.mjs +45 -14
- package/dist/surfaces/cli/index.mjs.map +1 -1
- package/dist/surfaces/cli/output.mjs.map +1 -1
- package/dist/surfaces/cli/sysexits.mjs.map +1 -1
- package/dist/surfaces/tui/app.mjs +0 -21
- package/dist/surfaces/tui/app.mjs.map +1 -1
- package/dist/surfaces/tui/dashboard.mjs +0 -48
- package/dist/surfaces/tui/dashboard.mjs.map +1 -1
- package/dist/surfaces/tui/display-derivation.mjs +80 -16
- package/dist/surfaces/tui/display-derivation.mjs.map +1 -1
- package/dist/surfaces/tui/errors.mjs.map +1 -1
- package/dist/surfaces/tui/event-log.mjs +0 -9
- package/dist/surfaces/tui/event-log.mjs.map +1 -1
- package/dist/surfaces/tui/heartbeat.mjs.map +1 -1
- package/dist/surfaces/tui/index.mjs +2 -2
- package/dist/surfaces/tui/index.mjs.map +1 -1
- package/dist/surfaces/tui/input.mjs.map +1 -1
- package/dist/surfaces/tui/mode-detect.mjs.map +1 -1
- package/dist/surfaces/tui/mount-ink.mjs.map +1 -1
- package/dist/surfaces/tui/plain-renderer.mjs +26 -19
- package/dist/surfaces/tui/plain-renderer.mjs.map +1 -1
- package/dist/surfaces/tui/resource-table.mjs +8 -10
- package/dist/surfaces/tui/resource-table.mjs.map +1 -1
- package/images/postgres/Dockerfile +0 -1
- package/images/sui/Dockerfile +27 -54
- package/images/sui/entrypoint.sh +17 -179
- package/package.json +23 -15
- package/dashboard-ui/assets/index-Bmi1UtAg.js +0 -1356
- package/dashboard-ui/assets/index-D5EShVt4.js +0 -3
- package/dashboard-ui/assets/index-Deml9drg.css +0 -1
- package/dist/api/plugin-errors.d.mts +0 -7
- package/dist/api/plugin-errors.mjs +0 -10
- package/dist/api/plugin-errors.mjs.map +0 -1
- package/dist/cli/wirings/build-verb-layers.mjs +0 -42
- package/dist/cli/wirings/build-verb-layers.mjs.map +0 -1
- package/dist/contracts/capability-decl.d.mts +0 -40
- package/dist/orchestrators/built-in-plugin-layers.mjs +0 -54
- package/dist/orchestrators/built-in-plugin-layers.mjs.map +0 -1
- package/dist/orchestrators/run.mjs +0 -91
- package/dist/orchestrators/run.mjs.map +0 -1
- package/dist/orchestrators/runtime-composition.d.mts +0 -10
- package/dist/orchestrators/runtime-composition.mjs +0 -252
- package/dist/orchestrators/runtime-composition.mjs.map +0 -1
- package/dist/orchestrators/snapshot/capture-command.d.mts +0 -1
- package/dist/orchestrators/snapshot/capture-command.mjs +0 -25
- package/dist/orchestrators/snapshot/capture-command.mjs.map +0 -1
- package/dist/orchestrators/snapshot/pending-marker.mjs +0 -99
- package/dist/orchestrators/snapshot/pending-marker.mjs.map +0 -1
- package/dist/orchestrators/snapshot/recover-pending.mjs +0 -223
- package/dist/orchestrators/snapshot/recover-pending.mjs.map +0 -1
- package/dist/orchestrators/snapshot/state-document.d.mts +0 -1
- package/dist/orchestrators/snapshot/state-document.mjs +0 -58
- package/dist/orchestrators/snapshot/state-document.mjs.map +0 -1
- package/dist/plugins/account/spans.mjs +0 -16
- package/dist/plugins/account/spans.mjs.map +0 -1
- package/dist/plugins/account/variants/env.mjs +0 -24
- package/dist/plugins/account/variants/env.mjs.map +0 -1
- package/dist/plugins/account/variants/inline.mjs +0 -13
- package/dist/plugins/account/variants/inline.mjs.map +0 -1
- package/dist/plugins/account/variants/keystore.mjs +0 -91
- package/dist/plugins/account/variants/keystore.mjs.map +0 -1
- package/dist/plugins/action/spans.mjs +0 -11
- package/dist/plugins/action/spans.mjs.map +0 -1
- package/dist/plugins/coin/spans.mjs +0 -20
- package/dist/plugins/coin/spans.mjs.map +0 -1
- package/dist/plugins/deepbook/spans.mjs +0 -18
- package/dist/plugins/deepbook/spans.mjs.map +0 -1
- package/dist/plugins/faucet/spans.mjs +0 -12
- package/dist/plugins/faucet/spans.mjs.map +0 -1
- package/dist/plugins/package/spans.mjs +0 -14
- package/dist/plugins/package/spans.mjs.map +0 -1
- package/dist/plugins/postgres/codegen.mjs +0 -42
- package/dist/plugins/postgres/codegen.mjs.map +0 -1
- package/dist/plugins/postgres/connection.d.mts +0 -33
- package/dist/plugins/postgres/connection.mjs.map +0 -1
- package/dist/plugins/postgres/db-ensure.mjs.map +0 -1
- package/dist/plugins/postgres/errors.d.mts +0 -60
- package/dist/plugins/postgres/errors.mjs +0 -29
- package/dist/plugins/postgres/errors.mjs.map +0 -1
- package/dist/plugins/postgres/index.d.mts +0 -37
- package/dist/plugins/postgres/index.mjs +0 -68
- package/dist/plugins/postgres/index.mjs.map +0 -1
- package/dist/plugins/postgres/routable.mjs +0 -33
- package/dist/plugins/postgres/routable.mjs.map +0 -1
- package/dist/plugins/postgres/service.d.mts +0 -50
- package/dist/plugins/postgres/service.mjs +0 -179
- package/dist/plugins/postgres/service.mjs.map +0 -1
- package/dist/plugins/postgres/snapshot.mjs +0 -32
- package/dist/plugins/postgres/snapshot.mjs.map +0 -1
- package/dist/plugins/postgres/spans.mjs +0 -11
- package/dist/plugins/postgres/spans.mjs.map +0 -1
- package/dist/plugins/seal/spans.mjs +0 -18
- package/dist/plugins/seal/spans.mjs.map +0 -1
- package/dist/plugins/sui/spans.mjs +0 -17
- package/dist/plugins/sui/spans.mjs.map +0 -1
- package/dist/plugins/wallet/spans.mjs +0 -22
- package/dist/plugins/wallet/spans.mjs.map +0 -1
- package/dist/plugins/walrus/registry-publish.d.mts +0 -24
- package/dist/plugins/walrus/spans.mjs +0 -18
- package/dist/plugins/walrus/spans.mjs.map +0 -1
- package/dist/runtime/docker/logs.d.mts +0 -1
- package/dist/runtime/docker/logs.mjs +0 -34
- package/dist/runtime/docker/logs.mjs.map +0 -1
- package/dist/substrate/runtime/artifact-publisher/index.mjs +0 -86
- package/dist/substrate/runtime/artifact-publisher/index.mjs.map +0 -1
- package/dist/substrate/runtime/capability-sinks/index.d.mts +0 -1
- package/dist/substrate/runtime/capability-sinks/index.mjs +0 -3
- package/dist/substrate/runtime/capability-sinks/layer.d.mts +0 -1
- package/dist/substrate/runtime/capability-sinks/layer.mjs +0 -31
- package/dist/substrate/runtime/capability-sinks/layer.mjs.map +0 -1
- package/dist/substrate/runtime/capability-sinks/service.d.mts +0 -95
- package/dist/substrate/runtime/capability-sinks/service.mjs +0 -69
- package/dist/substrate/runtime/capability-sinks/service.mjs.map +0 -1
- package/dist/substrate/runtime/cross-process/lock.d.mts +0 -1
- package/dist/substrate/runtime/cross-process/lock.mjs +0 -23
- package/dist/substrate/runtime/cross-process/lock.mjs.map +0 -1
- package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs +0 -113
- package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs.map +0 -1
- package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs +0 -31
- package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs.map +0 -1
- package/dist/substrate/runtime/observability/formatter-registry.d.mts +0 -1
- package/dist/substrate/runtime/observability/formatter-registry.mjs +0 -48
- package/dist/substrate/runtime/observability/formatter-registry.mjs.map +0 -1
- package/dist/substrate/runtime/observability/span-store.d.mts +0 -1
- package/dist/substrate/runtime/observability/span-store.mjs +0 -110
- package/dist/substrate/runtime/observability/span-store.mjs.map +0 -1
- package/dist/substrate/runtime/observability/spans.d.mts +0 -1
- package/dist/substrate/runtime/observability/spans.mjs +0 -87
- package/dist/substrate/runtime/observability/spans.mjs.map +0 -1
- package/dist/substrate/runtime/projection/index.mjs +0 -4
- package/dist/substrate/runtime/projection/persisted.mjs +0 -213
- package/dist/substrate/runtime/projection/persisted.mjs.map +0 -1
- package/dist/substrate/runtime/scoped-multimap/service.mjs +0 -52
- package/dist/substrate/runtime/scoped-multimap/service.mjs.map +0 -1
- package/dist/substrate/runtime/scoped-ref-map/index.mjs +0 -2
- package/dist/substrate/runtime/scoped-ref-map/service.mjs +0 -83
- package/dist/substrate/runtime/scoped-ref-map/service.mjs.map +0 -1
- package/dist/substrate/runtime/state-store/index.mjs +0 -3
- package/dist/substrate/runtime/state-store/schema.d.mts +0 -1
- package/dist/substrate/runtime/state-store/schema.mjs +0 -41
- package/dist/substrate/runtime/state-store/schema.mjs.map +0 -1
- package/dist/substrate/runtime/state-store/service.d.mts +0 -1
- package/dist/substrate/runtime/state-store/service.mjs +0 -145
- package/dist/substrate/runtime/state-store/service.mjs.map +0 -1
- package/dist/substrate/runtime/sui-execute/index.mjs.map +0 -1
- package/dist/substrate/runtime/sui-execute/sign-and-dispatch.mjs.map +0 -1
- package/dist/substrate/runtime/sui-ledger/object-ref.mjs.map +0 -1
- package/dist/substrate/runtime/sui-move-build/index.mjs.map +0 -1
- package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs +0 -151
- package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs.map +0 -1
- package/dist/substrate/state-store.d.mts +0 -1
- /package/dist/orchestrators/{snapshot/pending-marker.d.mts → codegen/id-config.d.mts} +0 -0
- /package/dist/orchestrators/snapshot/{recover-pending.d.mts → interrupted-restore.d.mts} +0 -0
- /package/dist/{substrate/runtime/sui-execute → plugins/sui/exec}/sign-and-dispatch.d.mts +0 -0
- /package/dist/plugins/{postgres/snapshot.d.mts → sui/ledger/object-ref.d.mts} +0 -0
- /package/dist/{substrate/runtime/sui-move-build → plugins/sui/move}/index.d.mts +0 -0
- /package/dist/substrate/runtime/{state-store/index.d.mts → reconcile/graph.d.mts} +0 -0
- /package/dist/substrate/runtime/{cross-process/snapshot-reservation.d.mts → supervisor/contribution-dispatcher.d.mts} +0 -0
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import { SpanAttr } from "../../substrate/runtime/observability/spans.mjs";
|
|
2
1
|
import { decodeUnknown } from "../../substrate/runtime/runtime-decode.mjs";
|
|
2
|
+
import { LogAttr } from "../../substrate/runtime/observability/log-attrs.mjs";
|
|
3
3
|
import { makeSpacedRetrySchedule } from "../../substrate/runtime/retry-policy.mjs";
|
|
4
4
|
import { formatUnknownError } from "../../substrate/runtime/format-unknown-error.mjs";
|
|
5
5
|
import { coinError } from "./errors.mjs";
|
|
6
|
-
import { CoinSpans } from "./spans.mjs";
|
|
7
6
|
import { Effect, Schema } from "effect";
|
|
8
7
|
//#region src/plugins/coin/metadata.ts
|
|
9
8
|
/** Per-attempt timeout (5 seconds) — distilled-doc invariant. */
|
|
10
9
|
const METADATA_FETCH_TIMEOUT_MS = 5e3;
|
|
11
|
-
/** Retry schedule — ONE retry at 250ms backoff
|
|
12
|
-
*
|
|
10
|
+
/** Retry schedule — ONE retry at 250ms backoff (250ms spaced, bounded
|
|
11
|
+
* to one retry). */
|
|
13
12
|
const METADATA_RETRY_SCHEDULE = makeSpacedRetrySchedule(250, 1);
|
|
14
13
|
/** On-chain CoinMetadata projection — narrowed to the columns the
|
|
15
14
|
* registry needs. The SDK's full shape carries more (description,
|
|
@@ -52,8 +51,8 @@ const fetchCoinMetadataOnce = (sdk, fullCoinType) => Effect.gen(function* () {
|
|
|
52
51
|
})
|
|
53
52
|
}), Effect.retry(METADATA_RETRY_SCHEDULE), Effect.catch((err) => {
|
|
54
53
|
return Effect.logWarning("coin metadata fetch failed; soft-degrading to null").pipe(Effect.annotateLogs({
|
|
55
|
-
|
|
56
|
-
[
|
|
54
|
+
"coin.type": fullCoinType,
|
|
55
|
+
[LogAttr.errorCause]: formatUnknownError(err.cause)
|
|
57
56
|
}), Effect.as(null));
|
|
58
57
|
}));
|
|
59
58
|
if (raw === null || raw === void 0) return null;
|
|
@@ -61,10 +60,10 @@ const fetchCoinMetadataOnce = (sdk, fullCoinType) => Effect.gen(function* () {
|
|
|
61
60
|
source: "coin metadata RPC response",
|
|
62
61
|
mkError: (issue) => issue
|
|
63
62
|
}).pipe(Effect.catch((issue) => Effect.logWarning("coin metadata response had non-conforming shape; degrading to null").pipe(Effect.annotateLogs({
|
|
64
|
-
|
|
65
|
-
[
|
|
63
|
+
"coin.type": fullCoinType,
|
|
64
|
+
[LogAttr.errorCause]: formatUnknownError(issue.cause ?? issue)
|
|
66
65
|
}), Effect.as(null))));
|
|
67
|
-
})
|
|
66
|
+
});
|
|
68
67
|
/** Bare-coin-type heuristic — distilled-doc 13-coin.md Invariant 3.
|
|
69
68
|
*
|
|
70
69
|
* MUST agree with what `getCoinMetadata` accepts as a coin-type
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.mjs","names":[],"sources":["../../../src/plugins/coin/metadata.ts"],"sourcesContent":["// CoinMetadata fetch + soft-degradation.\n//\n// Distilled-doc 13-coin.md Invariant 8: `getCoinMetadata` failures\n// degrade, do not throw. A timeout or RPC error after one retry\n// returns `null` (logged as a warning); the discovery pipeline keeps\n// going. The next supervisor cycle picks the missing record up.\n//\n// Per-attempt timeout 5s, ONE retry at 250ms backoff (
|
|
1
|
+
{"version":3,"file":"metadata.mjs","names":[],"sources":["../../../src/plugins/coin/metadata.ts"],"sourcesContent":["// CoinMetadata fetch + soft-degradation.\n//\n// Distilled-doc 13-coin.md Invariant 8: `getCoinMetadata` failures\n// degrade, do not throw. A timeout or RPC error after one retry\n// returns `null` (logged as a warning); the discovery pipeline keeps\n// going. The next supervisor cycle picks the missing record up.\n//\n// Per-attempt timeout 5s, ONE retry at 250ms backoff (distilled-doc\n// 13-coin.md §Configuration).\n//\n// In-process per-Layer-invocation cache keyed by fullCoinType. The\n// fullCoinType folds the packageId, so a fresh chain (new genesis)\n// means new packageIds, which means the cache misses naturally —\n// persistence across restart is unnecessary.\n\nimport { Effect, Ref, Schema } from 'effect';\n\nimport { decodeUnknown } from '../../substrate/runtime/runtime-decode.ts';\nimport { LogAttr } from '../../substrate/runtime/observability/log-attrs.ts';\nimport { makeSpacedRetrySchedule } from '../../substrate/runtime/retry-policy.ts';\nimport { formatUnknownError } from '../../substrate/runtime/format-unknown-error.ts';\nimport { coinError, type CoinError } from './errors.ts';\n\n/** Per-attempt timeout (5 seconds) — distilled-doc invariant. */\nexport const METADATA_FETCH_TIMEOUT_MS = 5_000;\n\n/** Retry schedule — ONE retry at 250ms backoff (250ms spaced, bounded\n * to one retry). */\nexport const METADATA_RETRY_SCHEDULE = makeSpacedRetrySchedule(250, 1);\n\n/** On-chain CoinMetadata projection — narrowed to the columns the\n * registry needs. The SDK's full shape carries more (description,\n * raw bytes); we don't.\n *\n * IMPORTANT (chain-probe schema constraint from the last sweep):\n * this Schema MUST NOT depend on any services. `Schema.Schema<T>` is\n * parameterized `<Type, Encoded, R, RD>`; we constrain `R` and `RD`\n * to `never` via `Schema.Codec<T, unknown, never, never>` at the\n * consumer boundary, but the schema literal itself uses ONLY\n * service-free combinators (`Schema.String`, `Schema.Number`,\n * `Schema.optional`). */\nexport const OnchainCoinMetadataShape = Schema.Struct({\n\tid: Schema.String,\n\tdecimals: Schema.Number,\n\tname: Schema.String,\n\tsymbol: Schema.String,\n\tdescription: Schema.optional(Schema.String),\n\ticonUrl: Schema.optional(Schema.String),\n});\n\nexport type OnchainCoinMetadata = typeof OnchainCoinMetadataShape.Type;\n\n/** SDK shim — the surface the discovery pass calls. The Sui plugin's\n * resolved client exposes this via `sdk.core.getCoinMetadata`. Kept\n * narrow (no `@mysten/sui` type import) so this module stays\n * layering-neutral; the consumer hands in the resolved client. */\nexport interface MetadataSdkShim {\n\treadonly core: {\n\t\treadonly getCoinMetadata: (args: { readonly coinType: string }) => Promise<unknown>;\n\t};\n}\n\n/** Per-Layer-invocation cache. `null` means \"we tried and the RPC\n * said the coin had no CoinMetadata\"; `undefined` means \"we haven't\n * asked yet\". */\nexport interface CoinMetadataCache {\n\treadonly get: (fullCoinType: string) => Effect.Effect<OnchainCoinMetadata | null | undefined>;\n\treadonly put: (fullCoinType: string, value: OnchainCoinMetadata | null) => Effect.Effect<void>;\n}\n\n/** Build an empty cache. */\nexport const makeCoinMetadataCache = (): Effect.Effect<CoinMetadataCache> =>\n\tEffect.gen(function* () {\n\t\tconst ref = yield* Ref.make<Record<string, OnchainCoinMetadata | null>>({});\n\t\treturn {\n\t\t\tget: (fullCoinType) =>\n\t\t\t\tRef.get(ref).pipe(Effect.map((m) => (fullCoinType in m ? m[fullCoinType] : undefined))),\n\t\t\tput: (fullCoinType, value) => Ref.update(ref, (m) => ({ ...m, [fullCoinType]: value })),\n\t\t};\n\t});\n\n/** Fetch CoinMetadata for one coin type. Soft-degrades on RPC\n * failure / timeout: returns `null` after the retry budget is\n * exhausted, AND logs a warning.\n *\n * Distilled-doc 13-coin.md Invariant 8: this is intentional. The\n * publish-discovery pass must not fail the whole supervisor cycle on\n * a flaky RPC blip. */\nexport const fetchCoinMetadataOnce = (\n\tsdk: MetadataSdkShim,\n\tfullCoinType: string,\n): Effect.Effect<OnchainCoinMetadata | null> =>\n\tEffect.gen(function* () {\n\t\tconst raw: unknown = yield* Effect.tryPromise({\n\t\t\ttry: () => sdk.core.getCoinMetadata({ coinType: fullCoinType }),\n\t\t\tcatch: (cause): { readonly _tag: 'rpc'; readonly cause: unknown } => ({\n\t\t\t\t_tag: 'rpc',\n\t\t\t\tcause,\n\t\t\t}),\n\t\t}).pipe(\n\t\t\t// Effect v4: `timeoutOrElse` (not `timeoutFail`). The\n\t\t\t// `orElse` branch is the new value (Effect), not just an\n\t\t\t// error constructor — we surface a tagged failure that the\n\t\t\t// downstream `Effect.catch` swallows into `null`.\n\t\t\tEffect.timeoutOrElse({\n\t\t\t\tduration: `${METADATA_FETCH_TIMEOUT_MS} millis`,\n\t\t\t\torElse: () => Effect.fail({ _tag: 'rpc' as const, cause: 'timeout' }),\n\t\t\t}),\n\t\t\tEffect.retry(METADATA_RETRY_SCHEDULE),\n\t\t\tEffect.catch((err): Effect.Effect<unknown> => {\n\t\t\t\treturn Effect.logWarning('coin metadata fetch failed; soft-degrading to null').pipe(\n\t\t\t\t\tEffect.annotateLogs({\n\t\t\t\t\t\t'coin.type': fullCoinType,\n\t\t\t\t\t\t[LogAttr.errorCause]: formatUnknownError(err.cause),\n\t\t\t\t\t}),\n\t\t\t\t\tEffect.as(null),\n\t\t\t\t);\n\t\t\t}),\n\t\t);\n\t\tif (raw === null || raw === undefined) return null;\n\t\treturn yield* decodeUnknown(OnchainCoinMetadataShape, raw, {\n\t\t\tsource: 'coin metadata RPC response',\n\t\t\tmkError: (issue) => issue,\n\t\t}).pipe(\n\t\t\tEffect.catch((issue) =>\n\t\t\t\tEffect.logWarning(\n\t\t\t\t\t'coin metadata response had non-conforming shape; degrading to null',\n\t\t\t\t).pipe(\n\t\t\t\t\tEffect.annotateLogs({\n\t\t\t\t\t\t'coin.type': fullCoinType,\n\t\t\t\t\t\t[LogAttr.errorCause]: formatUnknownError(issue.cause ?? issue),\n\t\t\t\t\t}),\n\t\t\t\t\tEffect.as(null as OnchainCoinMetadata | null),\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\t});\n\n/** Batch-fetch with cache. Each fullCoinType is asked at most once\n * per Layer-invocation. The fetches run concurrently — distilled-doc\n * opportunity (\"Coin discovery is naturally batchable\"). */\nexport const fetchCoinMetadataMany = (\n\tsdk: MetadataSdkShim,\n\tfullCoinTypes: ReadonlyArray<string>,\n\tcache: CoinMetadataCache,\n): Effect.Effect<ReadonlyMap<string, OnchainCoinMetadata | null>> =>\n\tEffect.gen(function* () {\n\t\tconst result = new Map<string, OnchainCoinMetadata | null>();\n\t\tyield* Effect.forEach(\n\t\t\tfullCoinTypes,\n\t\t\t(fullCoinType) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tconst cached = yield* cache.get(fullCoinType);\n\t\t\t\t\tif (cached !== undefined) {\n\t\t\t\t\t\tresult.set(fullCoinType, cached);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst fetched = yield* fetchCoinMetadataOnce(sdk, fullCoinType);\n\t\t\t\t\tyield* cache.put(fullCoinType, fetched);\n\t\t\t\t\tresult.set(fullCoinType, fetched);\n\t\t\t\t}),\n\t\t\t{ concurrency: 'unbounded' },\n\t\t);\n\t\treturn result;\n\t});\n\n/** Bare-coin-type heuristic — distilled-doc 13-coin.md Invariant 3.\n *\n * MUST agree with what `getCoinMetadata` accepts as a coin-type\n * argument: `0xHEX::module::Witness`. Anything else (symbol, witness\n * alone) falls through to the registry path. */\nexport const isBareCoinType = (s: string): boolean => {\n\tif (!s.startsWith('0x')) return false;\n\tif (!s.includes('::')) return false;\n\tif (s.split('::').length !== 3) return false;\n\t// Distilled-doc invariant 7: nested generics rejected at the\n\t// bare-string boundary too. The check fires before the RPC so\n\t// callers see a typed error rather than a downstream decode\n\t// failure.\n\tif (s.includes('<') || s.includes('>')) return false;\n\treturn true;\n};\n\n/** Project a coin-type validation failure to `CoinError`. Surfaces\n * the nested-generic case at the user-facing factory boundary. */\nexport const validateBareCoinType = (identifier: string): CoinError | null => {\n\tif (identifier.includes('<') || identifier.includes('>')) {\n\t\treturn coinError('nested-generic', {\n\t\t\tidentifier,\n\t\t\tmessage: `coin('${identifier}'): nested generics not supported.`,\n\t\t});\n\t}\n\treturn null;\n};\n"],"mappings":";;;;;;;;AAwBA,MAAa,4BAA4B;;;AAIzC,MAAa,0BAA0B,wBAAwB,KAAK,CAAC;;;;;;;;;;;;AAarE,MAAa,2BAA2B,OAAO,OAAO;CACrD,IAAI,OAAO;CACX,UAAU,OAAO;CACjB,MAAM,OAAO;CACb,QAAQ,OAAO;CACf,aAAa,OAAO,SAAS,OAAO,MAAM;CAC1C,SAAS,OAAO,SAAS,OAAO,MAAM;AACvC,CAAC;;;;;;;;AAwCD,MAAa,yBACZ,KACA,iBAEA,OAAO,IAAI,aAAa;CACvB,MAAM,MAAe,OAAO,OAAO,WAAW;EAC7C,WAAW,IAAI,KAAK,gBAAgB,EAAE,UAAU,aAAa,CAAC;EAC9D,QAAQ,WAA8D;GACrE,MAAM;GACN;EACD;CACD,CAAC,CAAC,CAAC,KAKF,OAAO,cAAc;EACpB,UAAU,GAAG,0BAA0B;EACvC,cAAc,OAAO,KAAK;GAAE,MAAM;GAAgB,OAAO;EAAU,CAAC;CACrE,CAAC,GACD,OAAO,MAAM,uBAAuB,GACpC,OAAO,OAAO,QAAgC;EAC7C,OAAO,OAAO,WAAW,oDAAoD,CAAC,CAAC,KAC9E,OAAO,aAAa;GACnB,aAAa;IACZ,QAAQ,aAAa,mBAAmB,IAAI,KAAK;EACnD,CAAC,GACD,OAAO,GAAG,IAAI,CACf;CACD,CAAC,CACF;CACA,IAAI,QAAQ,QAAQ,QAAQ,KAAA,GAAW,OAAO;CAC9C,OAAO,OAAO,cAAc,0BAA0B,KAAK;EAC1D,QAAQ;EACR,UAAU,UAAU;CACrB,CAAC,CAAC,CAAC,KACF,OAAO,OAAO,UACb,OAAO,WACN,oEACD,CAAC,CAAC,KACD,OAAO,aAAa;EACnB,aAAa;GACZ,QAAQ,aAAa,mBAAmB,MAAM,SAAS,KAAK;CAC9D,CAAC,GACD,OAAO,GAAG,IAAkC,CAC7C,CACD,CACD;AACD,CAAC;;;;;;AAmCF,MAAa,kBAAkB,MAAuB;CACrD,IAAI,CAAC,EAAE,WAAW,IAAI,GAAG,OAAO;CAChC,IAAI,CAAC,EAAE,SAAS,IAAI,GAAG,OAAO;CAC9B,IAAI,EAAE,MAAM,IAAI,CAAC,CAAC,WAAW,GAAG,OAAO;CAKvC,IAAI,EAAE,SAAS,GAAG,KAAK,EAAE,SAAS,GAAG,GAAG,OAAO;CAC/C,OAAO;AACR;;;AAIA,MAAa,wBAAwB,eAAyC;CAC7E,IAAI,WAAW,SAAS,GAAG,KAAK,WAAW,SAAS,GAAG,GACtD,OAAO,UAAU,kBAAkB;EAClC;EACA,SAAS,SAAS,WAAW;CAC9B,CAAC;CAEF,OAAO;AACR"}
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { contentHash } from "../../substrate/brand.mjs";
|
|
2
2
|
import { decodeUnknown } from "../../substrate/runtime/runtime-decode.mjs";
|
|
3
|
-
import { isSuiFrameworkObjectForCoin } from "./type-strings.mjs";
|
|
4
3
|
import { formatUnknownError } from "../../substrate/runtime/format-unknown-error.mjs";
|
|
5
|
-
import {
|
|
6
|
-
import { formatExecutedFailure } from "../../substrate/runtime/sui-execute/index.mjs";
|
|
4
|
+
import { formatExecutedFailure } from "../sui/exec/index.mjs";
|
|
7
5
|
import { buildForkImpersonationTransactionBytes } from "../sui/fork-transaction.mjs";
|
|
6
|
+
import { signAndDispatch } from "../sui/exec/sign-and-dispatch.mjs";
|
|
8
7
|
import "../sui/index.mjs";
|
|
9
|
-
import { artifactPublishError } from "../../primitives/artifact-publisher.mjs";
|
|
10
8
|
import { coinError } from "./errors.mjs";
|
|
11
|
-
import {
|
|
9
|
+
import { artifactPublishError } from "../../primitives/artifact-publisher.mjs";
|
|
12
10
|
import { acquireOnChainArtifact } from "../internal/acquire-on-chain-artifact.mjs";
|
|
11
|
+
import { isSuiFrameworkObjectForCoin } from "./type-strings.mjs";
|
|
13
12
|
import { Effect, Schema } from "effect";
|
|
14
13
|
import { Transaction } from "@mysten/sui/transactions";
|
|
15
14
|
//#region src/plugins/coin/mint.ts
|
|
@@ -90,10 +89,10 @@ const isCreatedObjectChange = (raw) => {
|
|
|
90
89
|
* The substrate's `publish` returns the `CachedMint` payload on every
|
|
91
90
|
* path (decoded cached payload on verify-hit, fresh produce on miss);
|
|
92
91
|
* we project it directly to `MintResult`. */
|
|
93
|
-
const performMint = (publisher,
|
|
92
|
+
const performMint = (publisher, chainId, signer, sdk, inputs) => Effect.gen(function* () {
|
|
94
93
|
const cached = yield* acquireOnChainArtifact(publisher, {
|
|
95
94
|
namespace: "coin-mint",
|
|
96
|
-
chain,
|
|
95
|
+
chain: chainId,
|
|
97
96
|
contentHash: buildMintContentHash({
|
|
98
97
|
treasuryCapId: inputs.treasuryCapId,
|
|
99
98
|
recipient: inputs.recipient,
|
|
@@ -102,11 +101,6 @@ const performMint = (publisher, chain, signer, sdk, inputs) => Effect.gen(functi
|
|
|
102
101
|
}),
|
|
103
102
|
verify: (cached) => buildVerifyProbe(sdk, cached.mintedCoinId),
|
|
104
103
|
produce: Effect.gen(function* () {
|
|
105
|
-
yield* Effect.annotateCurrentSpan({
|
|
106
|
-
[CoinSpans.mint.recipient]: inputs.recipient,
|
|
107
|
-
[CoinSpans.mint.fullCoinType]: inputs.fullCoinType,
|
|
108
|
-
[CoinSpans.mint.amount]: inputs.amount.toString()
|
|
109
|
-
});
|
|
110
104
|
return yield* signAndDispatch({
|
|
111
105
|
signerSource: signer,
|
|
112
106
|
buildTxBytes: () => Effect.gen(function* () {
|
|
@@ -132,10 +126,6 @@ const performMint = (publisher, chain, signer, sdk, inputs) => Effect.gen(functi
|
|
|
132
126
|
onSuccess: (ok) => Effect.gen(function* () {
|
|
133
127
|
const mintedCoinId = pickCreatedCoin(ok.objectChanges, inputs.fullCoinType);
|
|
134
128
|
if (mintedCoinId === null) return yield* Effect.fail(artifactPublishError("produce-failed", `coin.mint(${inputs.fullCoinType}): minted Coin<T> not found in objectChanges (digest=${ok.digest}). ` + mintParseError(inputs.fullCoinType, "minted Coin<T> absent in objectChanges").message));
|
|
135
|
-
yield* Effect.annotateCurrentSpan({
|
|
136
|
-
[CoinSpans.mint.digest]: ok.digest,
|
|
137
|
-
[CoinSpans.mint.mintedCoinId]: mintedCoinId
|
|
138
|
-
});
|
|
139
129
|
return {
|
|
140
130
|
digest: ok.digest,
|
|
141
131
|
mintedCoinId,
|
|
@@ -153,11 +143,7 @@ const performMint = (publisher, chain, signer, sdk, inputs) => Effect.gen(functi
|
|
|
153
143
|
amount: BigInt(cached.amount),
|
|
154
144
|
fullCoinType: inputs.fullCoinType
|
|
155
145
|
};
|
|
156
|
-
})
|
|
157
|
-
[CoinSpans.mint.recipient]: inputs.recipient,
|
|
158
|
-
[CoinSpans.mint.fullCoinType]: inputs.fullCoinType,
|
|
159
|
-
[CoinSpans.mint.amount]: inputs.amount.toString()
|
|
160
|
-
} }));
|
|
146
|
+
});
|
|
161
147
|
const mintParseError = (fullCoinType, message) => coinError("mint-parse", {
|
|
162
148
|
identifier: fullCoinType,
|
|
163
149
|
message
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mint.mjs","names":["brandContentHash"],"sources":["../../../src/plugins/coin/mint.ts"],"sourcesContent":["// Generic mint — wraps `0x2::coin::mint_and_transfer<T>` in the\n// `ArtifactPublisher` substrate primitive.\n//\n// Distilled-doc 13-coin.md §\"Lifecycle\" §\"mintFromTreasury\":\n//\n// - Cache key: (chainId, treasuryCapId, recipient, amount)\n// - Verify: lenient probe on the cached minted-coin id\n// (Invariant 1 — vanish-detection)\n// - Produce: sign + execute the `mint_and_transfer<T>` tx,\n// find the minted `Coin<T>` in objectChanges\n// - Register: in-memory note of the mint (no global registry —\n// the resolved value carries everything callers\n// need).\n//\n// Best-effort cache writes (distilled-doc Invariant 2): the mint\n// already settled on chain; a state-store IO defect just means the\n// next supervisor cycle re-mints. Don't let a StateStore failure\n// roll back the mint.\n//\n// Substrate constraint: the `ArtifactPublisher.publish` shape\n// already covers cache + verify + produce + register-on-every-cycle.\n// We compose its spec; the substrate dispatches.\n\nimport { Effect, Schema, type Scope } from 'effect';\nimport { Transaction } from '@mysten/sui/transactions';\n\nimport type { ChainId, ContentHash } from '../../substrate/brand.ts';\nimport { contentHash as brandContentHash } from '../../substrate/brand.ts';\nimport { decodeUnknown } from '../../substrate/runtime/runtime-decode.ts';\nimport {\n\tartifactPublishError,\n\ttype ArtifactPublishError,\n\ttype ArtifactPublisher,\n} from '../../primitives/artifact-publisher.ts';\nimport { acquireOnChainArtifact } from '../internal/acquire-on-chain-artifact.ts';\nimport { formatUnknownError } from '../../substrate/runtime/format-unknown-error.ts';\nimport { formatExecutedFailure } from '../../substrate/runtime/sui-execute/index.ts';\nimport { signAndDispatch } from '../../substrate/runtime/sui-execute/sign-and-dispatch.ts';\nimport {\n\tbuildForkImpersonationTransactionBytes,\n\ttype ClientWithCoreApi,\n\ttype ForkImpersonationGasClient,\n} from '../sui/index.ts';\nimport { coinError, type CoinError } from './errors.ts';\nimport { CoinSpans } from './spans.ts';\nimport { isSuiFrameworkObjectForCoin } from './type-strings.ts';\n\n/** Sign+execute surface narrowed from `AccountValue.signAndExecute`.\n * Mirrors the SDK's discriminated `TransactionResult` return shape —\n * on-chain failures are a return variant (`$kind: 'FailedTransaction'`),\n * not an error.\n *\n * Modelled as a proper $kind-discriminated union (not both-optional\n * fields) so consumers do not need non-null assertions after the\n * `result.$kind === 'FailedTransaction'` narrow. We don't import\n * `SignAndExecuteResult` from the Account plugin barrel directly\n * because the success transaction shape consumed here is narrower\n * (only `digest` + `objectChanges`) than the Account plugin's\n * `TxResult` (which adds `effects` + `balanceChanges` — fields the\n * mint produce body does not surface). The shape is structurally\n * compatible — Account's `signAndExecute` widens to this surface. */\nexport type MintSignAndExecuteResult =\n\t| {\n\t\t\treadonly $kind: 'Transaction';\n\t\t\treadonly Transaction: {\n\t\t\t\treadonly digest: string;\n\t\t\t\treadonly objectChanges: ReadonlyArray<unknown>;\n\t\t\t};\n\t }\n\t| {\n\t\t\treadonly $kind: 'FailedTransaction';\n\t\t\treadonly FailedTransaction: {\n\t\t\t\treadonly digest: string;\n\t\t\t\treadonly executionError?: string;\n\t\t\t};\n\t };\n\nexport interface MintTransactionSigner {\n\treadonly signAndExecute: (\n\t\ttx: Uint8Array,\n\t) => Effect.Effect<\n\t\tMintSignAndExecuteResult,\n\t\t{ readonly _tag: 'AccountSignError'; readonly message: string }\n\t>;\n}\n\nexport interface MintSigner extends MintTransactionSigner {\n\treadonly address: string;\n\treadonly withTransactionSigner: <A, E, R>(\n\t\tbody: (signer: MintTransactionSigner) => Effect.Effect<A, E, R>,\n\t) => Effect.Effect<A, E, R>;\n}\n\n/** Cached payload — the stable id verify re-confirms on every cycle.\n * Distilled-doc invariant: the probe MUST consume a STABLE on-chain\n * identifier (the minted Coin<T>'s objectId), NOT a derived hash. */\nexport interface CachedMint {\n\treadonly digest: string;\n\treadonly mintedCoinId: string;\n\treadonly recipient: string;\n\t/** `amount.toString()` — bigint isn't serializable. */\n\treadonly amount: string;\n}\n\n/** Verify-schema: what we expect when probing the minted coin.\n * IMPORTANT (chain-probe schema constraint from the last sweep):\n * schema literal uses ONLY service-free combinators. */\nexport const MintedCoinVerifyShape = Schema.Struct({\n\tobjectId: Schema.String,\n\ttype: Schema.String,\n});\n\n/** Build the cache-key content hash. Distilled-doc 13-coin.md\n * §\"Persistence model\": key shape is\n * `coin/mint/<chainId>/<treasuryCapId>/<signerAddress>/<recipient>/<amount>`.\n * The substrate's artifact publisher folds in chainId via the\n * `chain` parameter; we fold the remaining columns into `contentHash`.\n *\n * `signerAddress` is folded in because the producing signer is part\n * of the cache identity — reusing the same `(treasuryCap, recipient,\n * amount)` under a different signer MUST miss the cache so the new\n * signer actually re-executes the mint. Mirrors the symmetric\n * `publisherAddress` fold in `plugins/package/mode-local.ts:149-152`.\n * Backlog #6. */\nexport const buildMintContentHash = (parts: {\n\treadonly treasuryCapId: string;\n\treadonly recipient: string;\n\treadonly amount: bigint;\n\treadonly signerAddress: string;\n}): ContentHash =>\n\tbrandContentHash(\n\t\t`mint/${parts.treasuryCapId}/${parts.signerAddress}/${parts.recipient}/${parts.amount.toString()}`,\n\t);\n\nexport interface MintInputs {\n\treadonly fullCoinType: string;\n\treadonly treasuryCapId: string;\n\treadonly recipient: string;\n\treadonly amount: bigint;\n\treadonly gasBudget?: bigint;\n}\n\nexport interface MintResult {\n\t/** Tx digest of the producing mint. Surfaces the cached digest on\n\t * verify-hit (the substrate hands back the decoded `CachedMint`\n\t * payload, which carries it). */\n\treadonly digest: string;\n\treadonly mintedCoinId: string;\n\treadonly recipient: string;\n\treadonly amount: bigint;\n\treadonly fullCoinType: string;\n}\n\n/** Sui SDK shim for the verify probe + transaction build.\n *\n * The `core.getObject` field is the verify-probe surface; the\n * `client` field is the build-target the produce body hands to\n * `Transaction.build({ client })`. */\nexport interface MintSdkShim {\n\treadonly core: {\n\t\treadonly getObject: (args: { readonly objectId: string }) => Promise<unknown>;\n\t\t/** Coin selection for the fork-mode offline build (gas + input\n\t\t * resolution). Reuses the fork impersonation gas client's paginating\n\t\t * signature so `sdk.core` satisfies it exactly — selection walks the\n\t\t * coin set via `cursor`/`hasNextPage`, not a single page. */\n\t\treadonly listCoins: ForkImpersonationGasClient['listCoins'];\n\t};\n\t/** Client reference for `Transaction.build({ client })`. The Sui\n\t * barrel hands in the resolved `SuiGrpcClient`. */\n\treadonly client: ClientWithCoreApi;\n\t/** Fork mode — build offline with explicit gas (the sui-fork binary has\n\t * no `simulate_transaction` for the SDK's gas-estimating `tx.build`). */\n\treadonly forkMode?: boolean;\n}\n\n/** Verify probe — checks the cached minted-coin still exists. Lenient:\n * returns `null` for both not-found AND transient failure (distilled-\n * doc invariant: the next cycle re-derives).\n *\n * IMPORTANT (chain-probe schema constraint): the probe pipeline\n * cannot inject services from the caller. We construct the schema\n * literal at module scope (above) and call `decodeUnknownEffect` —\n * which the substrate's `ChainProbe.get` does internally. This local\n * verify mirrors the call-shape so the constraint is honored.\n *\n * We model the verify here as an inline Effect because the cached\n * minted-coin id is known only AFTER cache lookup — the substrate's\n * `verify` Effect closes over the cached id. */\nconst buildVerifyProbe = (\n\tsdk: MintSdkShim,\n\tmintedCoinIdOpt: string | null,\n): Effect.Effect<typeof MintedCoinVerifyShape.Type | null, never> =>\n\tEffect.gen(function* () {\n\t\tif (mintedCoinIdOpt === null) return null;\n\t\tconst raw: unknown = yield* Effect.tryPromise({\n\t\t\ttry: () => sdk.core.getObject({ objectId: mintedCoinIdOpt }),\n\t\t\tcatch: () => 'transient' as const,\n\t\t}).pipe(\n\t\t\t// Lenient: not-found AND transient both coerce to null. The\n\t\t\t// artifact publisher's cache layer will then re-run produce.\n\t\t\tEffect.catch(() => Effect.succeed(null)),\n\t\t);\n\t\tif (raw === null || raw === undefined) return null;\n\t\t// Best-effort decode. A decode failure on the verify path is\n\t\t// treated as \"object exists but shape changed unexpectedly\" —\n\t\t// still null so the substrate re-mints rather than carry stale\n\t\t// data forward.\n\t\treturn yield* decodeUnknown(MintedCoinVerifyShape, raw, {\n\t\t\tsource: 'minted coin verify response',\n\t\t\tmkError: (issue) => issue,\n\t\t}).pipe(Effect.catch(() => Effect.succeed(null as typeof MintedCoinVerifyShape.Type | null)));\n\t});\n\n/** Object-change shape narrowed for `pickCreatedCoin`. The gRPC\n * client emits `objectType` as a fully-qualified Sui type string on\n * `created` entries; we sniff for the `Coin<T>` substring (inner\n * generic carries the full coin type, so the match is unambiguous —\n * distilled-doc 13-coin.md Invariant 9). */\ninterface CreatedObjectChange {\n\treadonly type: 'created';\n\treadonly objectId: string;\n\treadonly objectType?: string;\n}\n\n/** Find the minted `Coin<T>` in a result's objectChanges. Returns the\n * objectId of the first `created` entry whose `objectType` matches\n * `0x2::coin::Coin<${fullCoinType}>` (or its address-normalized equivalent).\n *\n * Returns `null` on no match — the caller maps that to a typed parse\n * error.\n *\n * The SDK can report the Sui framework address as compact `0x2` or\n * fully padded `0x000...0002`, so this uses the shared type-string\n * normalizer instead of substring matching. */\nexport const pickCreatedCoin = (\n\tchanges: ReadonlyArray<unknown>,\n\tfullCoinType: string,\n): string | null => {\n\tfor (const change of changes) {\n\t\tif (!isCreatedObjectChange(change)) continue;\n\t\tif (\n\t\t\ttypeof change.objectType === 'string' &&\n\t\t\tisSuiFrameworkObjectForCoin(change.objectType, 'Coin', fullCoinType)\n\t\t) {\n\t\t\treturn change.objectId;\n\t\t}\n\t}\n\treturn null;\n};\n\nconst isCreatedObjectChange = (raw: unknown): raw is CreatedObjectChange => {\n\tif (raw === null || typeof raw !== 'object') return false;\n\tconst r = raw as { type?: unknown; objectId?: unknown };\n\treturn r.type === 'created' && typeof r.objectId === 'string';\n};\n\n/** Build the `ArtifactPublisher` spec for one mint round.\n *\n * Substrate dispatches: cache lookup, verify-on-hit, produce-on-\n * miss-or-verify-fail, register-on-every-cycle. We hand it the\n * procedures; the substrate handles best-effort cache writes per\n * Invariant 2.\n *\n * The substrate's `publish` returns the `CachedMint` payload on every\n * path (decoded cached payload on verify-hit, fresh produce on miss);\n * we project it directly to `MintResult`. */\nexport const performMint = (\n\tpublisher: ArtifactPublisher,\n\tchain: ChainId,\n\tsigner: MintSigner,\n\tsdk: MintSdkShim,\n\tinputs: MintInputs,\n): Effect.Effect<MintResult, CoinError | ArtifactPublishError, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst cacheHash = buildMintContentHash({\n\t\t\ttreasuryCapId: inputs.treasuryCapId,\n\t\t\trecipient: inputs.recipient,\n\t\t\tamount: inputs.amount,\n\t\t\tsignerAddress: signer.address,\n\t\t});\n\n\t\tconst cached: CachedMint = yield* acquireOnChainArtifact<\n\t\t\tCachedMint,\n\t\t\ttypeof MintedCoinVerifyShape.Type\n\t\t>(publisher, {\n\t\t\tnamespace: 'coin-mint',\n\t\t\tchain,\n\t\t\tcontentHash: cacheHash,\n\t\t\t// Verify probe runs on cache hit. The artifact publisher threads the\n\t\t\t// cached payload through to its internal probe — our\n\t\t\t// closure here just hands back a \"null = miss\" signal\n\t\t\t// when the cached id has vanished on chain.\n\t\t\t//\n\t\t\t// The artifact publisher substrate now threads the decoded\n\t\t\t// `CachedMint` into `verify(cached)`; we pull\n\t\t\t// `mintedCoinId` off it and probe the chain. Lenient\n\t\t\t// mode masks transient + not-found → null → substrate\n\t\t\t// re-mints rather than carry a stale digest forward.\n\t\t\tverify: (cached) => buildVerifyProbe(sdk, cached.mintedCoinId),\n\t\t\tproduce: Effect.gen(function* () {\n\t\t\t\tyield* Effect.annotateCurrentSpan({\n\t\t\t\t\t[CoinSpans.mint.recipient]: inputs.recipient,\n\t\t\t\t\t[CoinSpans.mint.fullCoinType]: inputs.fullCoinType,\n\t\t\t\t\t[CoinSpans.mint.amount]: inputs.amount.toString(),\n\t\t\t\t});\n\n\t\t\t\t// Drive build → sign → execute → dispatch via the shared\n\t\t\t\t// `signAndDispatch` helper. On-chain `FailedTransaction`\n\t\t\t\t// is a return value (not an error) — surfaced as a\n\t\t\t\t// `produce-failed` artifact error so the cache treats\n\t\t\t\t// this as a re-run candidate. Successful dispatch\n\t\t\t\t// projects to the cached payload.\n\t\t\t\treturn yield* signAndDispatch({\n\t\t\t\t\tsignerSource: signer,\n\t\t\t\t\tbuildTxBytes: () =>\n\t\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\t\t// 1. Build the Move tx — distilled-doc 13-coin.md\n\t\t\t\t\t\t\t// Invariant 9 pins the call shape:\n\t\t\t\t\t\t\t// `0x2::coin::mint_and_transfer<T>(cap, amount, recipient)`.\n\t\t\t\t\t\t\tconst tx = new Transaction();\n\t\t\t\t\t\t\tif (inputs.gasBudget !== undefined) {\n\t\t\t\t\t\t\t\ttx.setGasBudget(inputs.gasBudget);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ttx.setSender(signer.address);\n\t\t\t\t\t\t\ttx.moveCall({\n\t\t\t\t\t\t\t\ttarget: '0x2::coin::mint_and_transfer',\n\t\t\t\t\t\t\t\ttypeArguments: [inputs.fullCoinType],\n\t\t\t\t\t\t\t\targuments: [\n\t\t\t\t\t\t\t\t\ttx.object(inputs.treasuryCapId),\n\t\t\t\t\t\t\t\t\ttx.pure.u64(inputs.amount),\n\t\t\t\t\t\t\t\t\ttx.pure.address(inputs.recipient),\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t// 2. Serialize the tx to BCS bytes while the account lease is\n\t\t\t\t\t\t\t// held. Fork mode must build offline with explicit gas (the\n\t\t\t\t\t\t\t// sui-fork binary has no simulate_transaction); other modes\n\t\t\t\t\t\t\t// use the SDK resolver, which fills gas + object versions.\n\t\t\t\t\t\t\treturn sdk.forkMode === true\n\t\t\t\t\t\t\t\t? yield* buildForkImpersonationTransactionBytes(\n\t\t\t\t\t\t\t\t\t\ttx,\n\t\t\t\t\t\t\t\t\t\tsigner.address,\n\t\t\t\t\t\t\t\t\t\tsdk.core,\n\t\t\t\t\t\t\t\t\t).pipe(\n\t\t\t\t\t\t\t\t\t\tEffect.mapError(\n\t\t\t\t\t\t\t\t\t\t\t(cause): ArtifactPublishError =>\n\t\t\t\t\t\t\t\t\t\t\t\tartifactPublishError(\n\t\t\t\t\t\t\t\t\t\t\t\t\t'produce-failed',\n\t\t\t\t\t\t\t\t\t\t\t\t\t`coin.mint(${inputs.fullCoinType}): fork Transaction.build failed — ${cause.message}`,\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t: yield* Effect.tryPromise({\n\t\t\t\t\t\t\t\t\t\ttry: () => tx.build({ client: sdk.client }),\n\t\t\t\t\t\t\t\t\t\tcatch: (cause): ArtifactPublishError =>\n\t\t\t\t\t\t\t\t\t\t\tartifactPublishError(\n\t\t\t\t\t\t\t\t\t\t\t\t'produce-failed',\n\t\t\t\t\t\t\t\t\t\t\t\t`coin.mint(${inputs.fullCoinType}): Transaction.build failed — ${formatUnknownError(cause)}`,\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}),\n\t\t\t\t\t// 3. Sign + execute via the Account-supplied signer. Map\n\t\t\t\t\t// `AccountSignError` → `ArtifactPublishError`. The\n\t\t\t\t\t// Account plugin's signer handles waitForTransaction internally.\n\t\t\t\t\tmapSignError: (cause): ArtifactPublishError =>\n\t\t\t\t\t\tartifactPublishError(\n\t\t\t\t\t\t\t'produce-failed',\n\t\t\t\t\t\t\t`coin.mint(${inputs.fullCoinType}): signAndExecute failed — ` + cause.message,\n\t\t\t\t\t\t),\n\t\t\t\t\t// 4a. On-chain failure dispatch.\n\t\t\t\t\tonFailed: (failed) =>\n\t\t\t\t\t\tEffect.fail(\n\t\t\t\t\t\t\tartifactPublishError(\n\t\t\t\t\t\t\t\t'produce-failed',\n\t\t\t\t\t\t\t\t`coin.mint(${inputs.fullCoinType}): transaction execution failed on-chain ` +\n\t\t\t\t\t\t\t\t\tformatExecutedFailure(failed),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t// 4b. On success, find the minted `Coin<T>` in objectChanges via the\n\t\t\t\t\t// inner-generic match (distilled-doc Invariant 9).\n\t\t\t\t\t// `mint_and_transfer` emits a fresh `Coin<T>` owned by\n\t\t\t\t\t// the recipient; look it up by the\n\t\t\t\t\t// `0x2::coin::Coin<${fullCoinType}>` substring.\n\t\t\t\t\tonSuccess: (ok) =>\n\t\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\t\tconst mintedCoinId = pickCreatedCoin(ok.objectChanges, inputs.fullCoinType);\n\t\t\t\t\t\t\tif (mintedCoinId === null) {\n\t\t\t\t\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\t\t\t\t\tartifactPublishError(\n\t\t\t\t\t\t\t\t\t\t'produce-failed',\n\t\t\t\t\t\t\t\t\t\t`coin.mint(${inputs.fullCoinType}): minted Coin<T> not found in ` +\n\t\t\t\t\t\t\t\t\t\t\t`objectChanges (digest=${ok.digest}). ` +\n\t\t\t\t\t\t\t\t\t\t\tmintParseError(inputs.fullCoinType, 'minted Coin<T> absent in objectChanges')\n\t\t\t\t\t\t\t\t\t\t\t\t.message,\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\n\t\t\t\t\t\t\tyield* Effect.annotateCurrentSpan({\n\t\t\t\t\t\t\t\t[CoinSpans.mint.digest]: ok.digest,\n\t\t\t\t\t\t\t\t[CoinSpans.mint.mintedCoinId]: mintedCoinId,\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t// 5. Return the cached payload. The artifact publisher caches it under\n\t\t\t\t\t\t\t// the content hash; the next cycle's verify probe (on\n\t\t\t\t\t\t\t// cache hit) will lenient-probe `mintedCoinId`.\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tdigest: ok.digest,\n\t\t\t\t\t\t\t\tmintedCoinId,\n\t\t\t\t\t\t\t\trecipient: inputs.recipient,\n\t\t\t\t\t\t\t\tamount: inputs.amount.toString(),\n\t\t\t\t\t\t\t} satisfies CachedMint;\n\t\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t}),\n\t\t});\n\n\t\t// Project the cached payload to MintResult. The substrate\n\t\t// hands back the decoded `CachedMint` on every path.\n\t\treturn {\n\t\t\tdigest: cached.digest,\n\t\t\tmintedCoinId: cached.mintedCoinId,\n\t\t\trecipient: cached.recipient,\n\t\t\tamount: BigInt(cached.amount),\n\t\t\tfullCoinType: inputs.fullCoinType,\n\t\t};\n\t}).pipe(\n\t\tEffect.withSpan('devstack.plugin.coin.mint', {\n\t\t\tattributes: {\n\t\t\t\t[CoinSpans.mint.recipient]: inputs.recipient,\n\t\t\t\t[CoinSpans.mint.fullCoinType]: inputs.fullCoinType,\n\t\t\t\t[CoinSpans.mint.amount]: inputs.amount.toString(),\n\t\t\t},\n\t\t}),\n\t);\n\n/** Project an artifact publisher-wire error back to a CoinError when the consumer\n * wants a coin-side tagged shape. The artifact publisher boundary is generic; this\n * helper recovers the typed `mint-tx` / `mint-parse` phase the cause\n * walker uses. */\nexport const mintTxError = (fullCoinType: string, message: string, cause?: unknown): CoinError =>\n\tcoinError('mint-tx', {\n\t\tidentifier: fullCoinType,\n\t\tmessage,\n\t\t...(cause !== undefined ? { cause } : {}),\n\t});\n\nexport const mintParseError = (fullCoinType: string, message: string): CoinError =>\n\tcoinError('mint-parse', {\n\t\tidentifier: fullCoinType,\n\t\tmessage,\n\t});\n"],"mappings":";;;;;;;;;;;;;;;;;;AA2GA,MAAa,wBAAwB,OAAO,OAAO;CAClD,UAAU,OAAO;CACjB,MAAM,OAAO;CACb,CAAC;;;;;;;;;;;;;AAcF,MAAa,wBAAwB,UAMpCA,YACC,QAAQ,MAAM,cAAc,GAAG,MAAM,cAAc,GAAG,MAAM,UAAU,GAAG,MAAM,OAAO,UAAU,GAChG;;;;;;;;;;;;;;AAwDF,MAAM,oBACL,KACA,oBAEA,OAAO,IAAI,aAAa;AACvB,KAAI,oBAAoB,KAAM,QAAO;CACrC,MAAM,MAAe,OAAO,OAAO,WAAW;EAC7C,WAAW,IAAI,KAAK,UAAU,EAAE,UAAU,iBAAiB,CAAC;EAC5D,aAAa;EACb,CAAC,CAAC,KAGF,OAAO,YAAY,OAAO,QAAQ,KAAK,CAAC,CACxC;AACD,KAAI,QAAQ,QAAQ,QAAQ,KAAA,EAAW,QAAO;AAK9C,QAAO,OAAO,cAAc,uBAAuB,KAAK;EACvD,QAAQ;EACR,UAAU,UAAU;EACpB,CAAC,CAAC,KAAK,OAAO,YAAY,OAAO,QAAQ,KAAiD,CAAC,CAAC;EAC5F;;;;;;;;;;;AAuBH,MAAa,mBACZ,SACA,iBACmB;AACnB,MAAK,MAAM,UAAU,SAAS;AAC7B,MAAI,CAAC,sBAAsB,OAAO,CAAE;AACpC,MACC,OAAO,OAAO,eAAe,YAC7B,4BAA4B,OAAO,YAAY,QAAQ,aAAa,CAEpE,QAAO,OAAO;;AAGhB,QAAO;;AAGR,MAAM,yBAAyB,QAA6C;AAC3E,KAAI,QAAQ,QAAQ,OAAO,QAAQ,SAAU,QAAO;CACpD,MAAM,IAAI;AACV,QAAO,EAAE,SAAS,aAAa,OAAO,EAAE,aAAa;;;;;;;;;;;;AAatD,MAAa,eACZ,WACA,OACA,QACA,KACA,WAEA,OAAO,IAAI,aAAa;CAQvB,MAAM,SAAqB,OAAO,uBAGhC,WAAW;EACZ,WAAW;EACX;EACA,aAbiB,qBAAqB;GACtC,eAAe,OAAO;GACtB,WAAW,OAAO;GAClB,QAAQ,OAAO;GACf,eAAe,OAAO;GACtB,CAQsB;EAWtB,SAAS,WAAW,iBAAiB,KAAK,OAAO,aAAa;EAC9D,SAAS,OAAO,IAAI,aAAa;AAChC,UAAO,OAAO,oBAAoB;KAChC,UAAU,KAAK,YAAY,OAAO;KAClC,UAAU,KAAK,eAAe,OAAO;KACrC,UAAU,KAAK,SAAS,OAAO,OAAO,UAAU;IACjD,CAAC;AAQF,UAAO,OAAO,gBAAgB;IAC7B,cAAc;IACd,oBACC,OAAO,IAAI,aAAa;KAIvB,MAAM,KAAK,IAAI,aAAa;AAC5B,SAAI,OAAO,cAAc,KAAA,EACxB,IAAG,aAAa,OAAO,UAAU;AAElC,QAAG,UAAU,OAAO,QAAQ;AAC5B,QAAG,SAAS;MACX,QAAQ;MACR,eAAe,CAAC,OAAO,aAAa;MACpC,WAAW;OACV,GAAG,OAAO,OAAO,cAAc;OAC/B,GAAG,KAAK,IAAI,OAAO,OAAO;OAC1B,GAAG,KAAK,QAAQ,OAAO,UAAU;OACjC;MACD,CAAC;AAKF,YAAO,IAAI,aAAa,OACrB,OAAO,uCACP,IACA,OAAO,SACP,IAAI,KACJ,CAAC,KACD,OAAO,UACL,UACA,qBACC,kBACA,aAAa,OAAO,aAAa,qCAAqC,MAAM,UAC5E,CACF,CACD,GACA,OAAO,OAAO,WAAW;MACzB,WAAW,GAAG,MAAM,EAAE,QAAQ,IAAI,QAAQ,CAAC;MAC3C,QAAQ,UACP,qBACC,kBACA,aAAa,OAAO,aAAa,gCAAgC,mBAAmB,MAAM,GAC1F;MACF,CAAC;MACH;IAIH,eAAe,UACd,qBACC,kBACA,aAAa,OAAO,aAAa,+BAA+B,MAAM,QACtE;IAEF,WAAW,WACV,OAAO,KACN,qBACC,kBACA,aAAa,OAAO,aAAa,6CAChC,sBAAsB,OAAO,CAC9B,CACD;IAMF,YAAY,OACX,OAAO,IAAI,aAAa;KACvB,MAAM,eAAe,gBAAgB,GAAG,eAAe,OAAO,aAAa;AAC3E,SAAI,iBAAiB,KACpB,QAAO,OAAO,OAAO,KACpB,qBACC,kBACA,aAAa,OAAO,aAAa,uDACP,GAAG,OAAO,OACnC,eAAe,OAAO,cAAc,yCAAyC,CAC3E,QACH,CACD;AAGF,YAAO,OAAO,oBAAoB;OAChC,UAAU,KAAK,SAAS,GAAG;OAC3B,UAAU,KAAK,eAAe;MAC/B,CAAC;AAKF,YAAO;MACN,QAAQ,GAAG;MACX;MACA,WAAW,OAAO;MAClB,QAAQ,OAAO,OAAO,UAAU;MAChC;MACA;IACH,CAAC;IACD;EACF,CAAC;AAIF,QAAO;EACN,QAAQ,OAAO;EACf,cAAc,OAAO;EACrB,WAAW,OAAO;EAClB,QAAQ,OAAO,OAAO,OAAO;EAC7B,cAAc,OAAO;EACrB;EACA,CAAC,KACF,OAAO,SAAS,6BAA6B,EAC5C,YAAY;EACV,UAAU,KAAK,YAAY,OAAO;EAClC,UAAU,KAAK,eAAe,OAAO;EACrC,UAAU,KAAK,SAAS,OAAO,OAAO,UAAU;CACjD,EACD,CAAC,CACF;AAaF,MAAa,kBAAkB,cAAsB,YACpD,UAAU,cAAc;CACvB,YAAY;CACZ;CACA,CAAC"}
|
|
1
|
+
{"version":3,"file":"mint.mjs","names":["brandContentHash"],"sources":["../../../src/plugins/coin/mint.ts"],"sourcesContent":["// Generic mint — wraps `0x2::coin::mint_and_transfer<T>` in the\n// `ArtifactPublisher` substrate primitive.\n//\n// Distilled-doc 13-coin.md §\"Lifecycle\" §\"mintFromTreasury\":\n//\n// - Cache key: (chainId, treasuryCapId, recipient, amount)\n// - Verify: lenient probe on the cached minted-coin id\n// (Invariant 1 — vanish-detection)\n// - Produce: sign + execute the `mint_and_transfer<T>` tx,\n// find the minted `Coin<T>` in objectChanges\n// - Register: in-memory note of the mint (no global registry —\n// the resolved value carries everything callers\n// need).\n//\n// Best-effort cache writes (distilled-doc Invariant 2): the mint\n// already settled on chain; a cache IO defect just means the\n// next supervisor cycle re-mints. Don't let a cache-write failure\n// roll back the mint.\n//\n// Substrate constraint: the `ArtifactPublisher.publish` shape\n// already covers cache + verify + produce + register-on-every-cycle.\n// We compose its spec; the substrate dispatches.\n\nimport { Effect, Schema, type Scope } from 'effect';\nimport { Transaction } from '@mysten/sui/transactions';\n\nimport type { ContentHash } from '../../substrate/brand.ts';\nimport { contentHash as brandContentHash } from '../../substrate/brand.ts';\nimport { decodeUnknown } from '../../substrate/runtime/runtime-decode.ts';\nimport {\n\tartifactPublishError,\n\ttype ArtifactPublishError,\n\ttype ArtifactPublisher,\n} from '../../primitives/artifact-publisher.ts';\nimport { acquireOnChainArtifact } from '../internal/acquire-on-chain-artifact.ts';\nimport { formatUnknownError } from '../../substrate/runtime/format-unknown-error.ts';\nimport {\n\tbuildForkImpersonationTransactionBytes,\n\tformatExecutedFailure,\n\tsignAndDispatch,\n\ttype ClientWithCoreApi,\n\ttype ForkImpersonationGasClient,\n} from '../sui/index.ts';\nimport { coinError, type CoinError } from './errors.ts';\nimport { isSuiFrameworkObjectForCoin } from './type-strings.ts';\n\n/** Sign+execute surface narrowed from `AccountValue.signAndExecute`.\n * Mirrors the SDK's discriminated `TransactionResult` return shape —\n * on-chain failures are a return variant (`$kind: 'FailedTransaction'`),\n * not an error.\n *\n * Modelled as a proper $kind-discriminated union (not both-optional\n * fields) so consumers do not need non-null assertions after the\n * `result.$kind === 'FailedTransaction'` narrow. We don't import\n * `SignAndExecuteResult` from the Account plugin barrel directly\n * because the success transaction shape consumed here is narrower\n * (only `digest` + `objectChanges`) than the Account plugin's\n * `TxResult` (which adds `effects` + `balanceChanges` — fields the\n * mint produce body does not surface). The shape is structurally\n * compatible — Account's `signAndExecute` widens to this surface. */\ntype MintSignAndExecuteResult =\n\t| {\n\t\t\treadonly $kind: 'Transaction';\n\t\t\treadonly Transaction: {\n\t\t\t\treadonly digest: string;\n\t\t\t\treadonly objectChanges: ReadonlyArray<unknown>;\n\t\t\t};\n\t }\n\t| {\n\t\t\treadonly $kind: 'FailedTransaction';\n\t\t\treadonly FailedTransaction: {\n\t\t\t\treadonly digest: string;\n\t\t\t\treadonly executionError?: string;\n\t\t\t};\n\t };\n\ninterface MintTransactionSigner {\n\treadonly signAndExecute: (\n\t\ttx: Uint8Array,\n\t) => Effect.Effect<\n\t\tMintSignAndExecuteResult,\n\t\t{ readonly _tag: 'AccountSignError'; readonly message: string }\n\t>;\n}\n\nexport interface MintSigner extends MintTransactionSigner {\n\treadonly address: string;\n\treadonly withTransactionSigner: <A, E, R>(\n\t\tbody: (signer: MintTransactionSigner) => Effect.Effect<A, E, R>,\n\t) => Effect.Effect<A, E, R>;\n}\n\n/** Cached payload — the stable id verify re-confirms on every cycle.\n * Distilled-doc invariant: the probe MUST consume a STABLE on-chain\n * identifier (the minted Coin<T>'s objectId), NOT a derived hash. */\nexport interface CachedMint {\n\treadonly digest: string;\n\treadonly mintedCoinId: string;\n\treadonly recipient: string;\n\t/** `amount.toString()` — bigint isn't serializable. */\n\treadonly amount: string;\n}\n\n/** Verify-schema: what we expect when probing the minted coin.\n * IMPORTANT (chain-probe schema constraint from the last sweep):\n * schema literal uses ONLY service-free combinators. */\nexport const MintedCoinVerifyShape = Schema.Struct({\n\tobjectId: Schema.String,\n\ttype: Schema.String,\n});\n\n/** Build the cache-key content hash. Distilled-doc 13-coin.md\n * §\"Persistence model\": key shape is\n * `coin/mint/<chainId>/<treasuryCapId>/<signerAddress>/<recipient>/<amount>`.\n * The substrate's artifact publisher folds in chainId via the\n * `chain` parameter; we fold the remaining columns into `contentHash`.\n *\n * `signerAddress` is folded in because the producing signer is part\n * of the cache identity — reusing the same `(treasuryCap, recipient,\n * amount)` under a different signer MUST miss the cache so the new\n * signer actually re-executes the mint. Mirrors the symmetric\n * `publisherAddress` fold in `plugins/package/mode-local.ts:149-152`.\n * Backlog #6. */\nexport const buildMintContentHash = (parts: {\n\treadonly treasuryCapId: string;\n\treadonly recipient: string;\n\treadonly amount: bigint;\n\treadonly signerAddress: string;\n}): ContentHash =>\n\tbrandContentHash(\n\t\t`mint/${parts.treasuryCapId}/${parts.signerAddress}/${parts.recipient}/${parts.amount.toString()}`,\n\t);\n\nexport interface MintInputs {\n\treadonly fullCoinType: string;\n\treadonly treasuryCapId: string;\n\treadonly recipient: string;\n\treadonly amount: bigint;\n\treadonly gasBudget?: bigint;\n}\n\nexport interface MintResult {\n\t/** Tx digest of the producing mint. Surfaces the cached digest on\n\t * verify-hit (the substrate hands back the decoded `CachedMint`\n\t * payload, which carries it). */\n\treadonly digest: string;\n\treadonly mintedCoinId: string;\n\treadonly recipient: string;\n\treadonly amount: bigint;\n\treadonly fullCoinType: string;\n}\n\n/** Sui SDK shim for the verify probe + transaction build.\n *\n * The `core.getObject` field is the verify-probe surface; the\n * `client` field is the build-target the produce body hands to\n * `Transaction.build({ client })`. */\nexport interface MintSdkShim {\n\treadonly core: {\n\t\treadonly getObject: (args: { readonly objectId: string }) => Promise<unknown>;\n\t\t/** Coin selection for the fork-mode offline build (gas + input\n\t\t * resolution). Reuses the fork impersonation gas client's paginating\n\t\t * signature so `sdk.core` satisfies it exactly — selection walks the\n\t\t * coin set via `cursor`/`hasNextPage`, not a single page. */\n\t\treadonly listCoins: ForkImpersonationGasClient['listCoins'];\n\t};\n\t/** Client reference for `Transaction.build({ client })`. The Sui\n\t * barrel hands in the resolved `SuiGrpcClient`. */\n\treadonly client: ClientWithCoreApi;\n\t/** Fork mode — build offline with explicit gas (the sui-fork binary has\n\t * no `simulate_transaction` for the SDK's gas-estimating `tx.build`). */\n\treadonly forkMode?: boolean;\n}\n\n/** Verify probe — checks the cached minted-coin still exists. Lenient:\n * returns `null` for both not-found AND transient failure (distilled-\n * doc invariant: the next cycle re-derives).\n *\n * IMPORTANT (chain-probe schema constraint): the probe pipeline\n * cannot inject services from the caller. We construct the schema\n * literal at module scope (above) and call `decodeUnknownEffect` —\n * which the substrate's `ChainProbe.get` does internally. This local\n * verify mirrors the call-shape so the constraint is honored.\n *\n * We model the verify here as an inline Effect because the cached\n * minted-coin id is known only AFTER cache lookup — the substrate's\n * `verify` Effect closes over the cached id. */\nconst buildVerifyProbe = (\n\tsdk: MintSdkShim,\n\tmintedCoinIdOpt: string | null,\n): Effect.Effect<typeof MintedCoinVerifyShape.Type | null, never> =>\n\tEffect.gen(function* () {\n\t\tif (mintedCoinIdOpt === null) return null;\n\t\tconst raw: unknown = yield* Effect.tryPromise({\n\t\t\ttry: () => sdk.core.getObject({ objectId: mintedCoinIdOpt }),\n\t\t\tcatch: () => 'transient' as const,\n\t\t}).pipe(\n\t\t\t// Lenient: not-found AND transient both coerce to null. The\n\t\t\t// artifact publisher's cache layer will then re-run produce.\n\t\t\tEffect.catch(() => Effect.succeed(null)),\n\t\t);\n\t\tif (raw === null || raw === undefined) return null;\n\t\t// Best-effort decode. A decode failure on the verify path is\n\t\t// treated as \"object exists but shape changed unexpectedly\" —\n\t\t// still null so the substrate re-mints rather than carry stale\n\t\t// data forward.\n\t\treturn yield* decodeUnknown(MintedCoinVerifyShape, raw, {\n\t\t\tsource: 'minted coin verify response',\n\t\t\tmkError: (issue) => issue,\n\t\t}).pipe(Effect.catch(() => Effect.succeed(null as typeof MintedCoinVerifyShape.Type | null)));\n\t});\n\n/** Object-change shape narrowed for `pickCreatedCoin`. The gRPC\n * client emits `objectType` as a fully-qualified Sui type string on\n * `created` entries; we sniff for the `Coin<T>` substring (inner\n * generic carries the full coin type, so the match is unambiguous —\n * distilled-doc 13-coin.md Invariant 9). */\ninterface CreatedObjectChange {\n\treadonly type: 'created';\n\treadonly objectId: string;\n\treadonly objectType?: string;\n}\n\n/** Find the minted `Coin<T>` in a result's objectChanges. Returns the\n * objectId of the first `created` entry whose `objectType` matches\n * `0x2::coin::Coin<${fullCoinType}>` (or its address-normalized equivalent).\n *\n * Returns `null` on no match — the caller maps that to a typed parse\n * error.\n *\n * The SDK can report the Sui framework address as compact `0x2` or\n * fully padded `0x000...0002`, so this uses the shared type-string\n * normalizer instead of substring matching. */\nexport const pickCreatedCoin = (\n\tchanges: ReadonlyArray<unknown>,\n\tfullCoinType: string,\n): string | null => {\n\tfor (const change of changes) {\n\t\tif (!isCreatedObjectChange(change)) continue;\n\t\tif (\n\t\t\ttypeof change.objectType === 'string' &&\n\t\t\tisSuiFrameworkObjectForCoin(change.objectType, 'Coin', fullCoinType)\n\t\t) {\n\t\t\treturn change.objectId;\n\t\t}\n\t}\n\treturn null;\n};\n\nconst isCreatedObjectChange = (raw: unknown): raw is CreatedObjectChange => {\n\tif (raw === null || typeof raw !== 'object') return false;\n\tconst r = raw as { type?: unknown; objectId?: unknown };\n\treturn r.type === 'created' && typeof r.objectId === 'string';\n};\n\n/** Build the `ArtifactPublisher` spec for one mint round.\n *\n * Substrate dispatches: cache lookup, verify-on-hit, produce-on-\n * miss-or-verify-fail, register-on-every-cycle. We hand it the\n * procedures; the substrate handles best-effort cache writes per\n * Invariant 2.\n *\n * The substrate's `publish` returns the `CachedMint` payload on every\n * path (decoded cached payload on verify-hit, fresh produce on miss);\n * we project it directly to `MintResult`. */\nexport const performMint = (\n\tpublisher: ArtifactPublisher,\n\tchainId: string,\n\tsigner: MintSigner,\n\tsdk: MintSdkShim,\n\tinputs: MintInputs,\n): Effect.Effect<MintResult, CoinError | ArtifactPublishError, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst cacheHash = buildMintContentHash({\n\t\t\ttreasuryCapId: inputs.treasuryCapId,\n\t\t\trecipient: inputs.recipient,\n\t\t\tamount: inputs.amount,\n\t\t\tsignerAddress: signer.address,\n\t\t});\n\n\t\tconst cached: CachedMint = yield* acquireOnChainArtifact<\n\t\t\tCachedMint,\n\t\t\ttypeof MintedCoinVerifyShape.Type\n\t\t>(publisher, {\n\t\t\tnamespace: 'coin-mint',\n\t\t\tchain: chainId,\n\t\t\tcontentHash: cacheHash,\n\t\t\t// Verify probe runs on cache hit. The artifact publisher threads the\n\t\t\t// cached payload through to its internal probe — our\n\t\t\t// closure here just hands back a \"null = miss\" signal\n\t\t\t// when the cached id has vanished on chain.\n\t\t\t//\n\t\t\t// The artifact publisher substrate now threads the decoded\n\t\t\t// `CachedMint` into `verify(cached)`; we pull\n\t\t\t// `mintedCoinId` off it and probe the chain. Lenient\n\t\t\t// mode masks transient + not-found → null → substrate\n\t\t\t// re-mints rather than carry a stale digest forward.\n\t\t\tverify: (cached) => buildVerifyProbe(sdk, cached.mintedCoinId),\n\t\t\tproduce: Effect.gen(function* () {\n\t\t\t\t// Drive build → sign → execute → dispatch via the shared\n\t\t\t\t// `signAndDispatch` helper. On-chain `FailedTransaction`\n\t\t\t\t// is a return value (not an error) — surfaced as a\n\t\t\t\t// `produce-failed` artifact error so the cache treats\n\t\t\t\t// this as a re-run candidate. Successful dispatch\n\t\t\t\t// projects to the cached payload.\n\t\t\t\treturn yield* signAndDispatch({\n\t\t\t\t\tsignerSource: signer,\n\t\t\t\t\tbuildTxBytes: () =>\n\t\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\t\t// 1. Build the Move tx — distilled-doc 13-coin.md\n\t\t\t\t\t\t\t// Invariant 9 pins the call shape:\n\t\t\t\t\t\t\t// `0x2::coin::mint_and_transfer<T>(cap, amount, recipient)`.\n\t\t\t\t\t\t\tconst tx = new Transaction();\n\t\t\t\t\t\t\tif (inputs.gasBudget !== undefined) {\n\t\t\t\t\t\t\t\ttx.setGasBudget(inputs.gasBudget);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ttx.setSender(signer.address);\n\t\t\t\t\t\t\ttx.moveCall({\n\t\t\t\t\t\t\t\ttarget: '0x2::coin::mint_and_transfer',\n\t\t\t\t\t\t\t\ttypeArguments: [inputs.fullCoinType],\n\t\t\t\t\t\t\t\targuments: [\n\t\t\t\t\t\t\t\t\ttx.object(inputs.treasuryCapId),\n\t\t\t\t\t\t\t\t\ttx.pure.u64(inputs.amount),\n\t\t\t\t\t\t\t\t\ttx.pure.address(inputs.recipient),\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t// 2. Serialize the tx to BCS bytes while the account lease is\n\t\t\t\t\t\t\t// held. Fork mode must build offline with explicit gas (the\n\t\t\t\t\t\t\t// sui-fork binary has no simulate_transaction); other modes\n\t\t\t\t\t\t\t// use the SDK resolver, which fills gas + object versions.\n\t\t\t\t\t\t\treturn sdk.forkMode === true\n\t\t\t\t\t\t\t\t? yield* buildForkImpersonationTransactionBytes(tx, signer.address, sdk.core).pipe(\n\t\t\t\t\t\t\t\t\t\tEffect.mapError(\n\t\t\t\t\t\t\t\t\t\t\t(cause): ArtifactPublishError =>\n\t\t\t\t\t\t\t\t\t\t\t\tartifactPublishError(\n\t\t\t\t\t\t\t\t\t\t\t\t\t'produce-failed',\n\t\t\t\t\t\t\t\t\t\t\t\t\t`coin.mint(${inputs.fullCoinType}): fork Transaction.build failed — ${cause.message}`,\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t: yield* Effect.tryPromise({\n\t\t\t\t\t\t\t\t\t\ttry: () => tx.build({ client: sdk.client }),\n\t\t\t\t\t\t\t\t\t\tcatch: (cause): ArtifactPublishError =>\n\t\t\t\t\t\t\t\t\t\t\tartifactPublishError(\n\t\t\t\t\t\t\t\t\t\t\t\t'produce-failed',\n\t\t\t\t\t\t\t\t\t\t\t\t`coin.mint(${inputs.fullCoinType}): Transaction.build failed — ${formatUnknownError(cause)}`,\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}),\n\t\t\t\t\t// 3. Sign + execute via the Account-supplied signer. Map\n\t\t\t\t\t// `AccountSignError` → `ArtifactPublishError`. The\n\t\t\t\t\t// Account plugin's signer handles waitForTransaction internally.\n\t\t\t\t\tmapSignError: (cause): ArtifactPublishError =>\n\t\t\t\t\t\tartifactPublishError(\n\t\t\t\t\t\t\t'produce-failed',\n\t\t\t\t\t\t\t`coin.mint(${inputs.fullCoinType}): signAndExecute failed — ` + cause.message,\n\t\t\t\t\t\t),\n\t\t\t\t\t// 4a. On-chain failure dispatch.\n\t\t\t\t\tonFailed: (failed) =>\n\t\t\t\t\t\tEffect.fail(\n\t\t\t\t\t\t\tartifactPublishError(\n\t\t\t\t\t\t\t\t'produce-failed',\n\t\t\t\t\t\t\t\t`coin.mint(${inputs.fullCoinType}): transaction execution failed on-chain ` +\n\t\t\t\t\t\t\t\t\tformatExecutedFailure(failed),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t// 4b. On success, find the minted `Coin<T>` in objectChanges via the\n\t\t\t\t\t// inner-generic match (distilled-doc Invariant 9).\n\t\t\t\t\t// `mint_and_transfer` emits a fresh `Coin<T>` owned by\n\t\t\t\t\t// the recipient; look it up by the\n\t\t\t\t\t// `0x2::coin::Coin<${fullCoinType}>` substring.\n\t\t\t\t\tonSuccess: (ok) =>\n\t\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\t\tconst mintedCoinId = pickCreatedCoin(ok.objectChanges, inputs.fullCoinType);\n\t\t\t\t\t\t\tif (mintedCoinId === null) {\n\t\t\t\t\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\t\t\t\t\tartifactPublishError(\n\t\t\t\t\t\t\t\t\t\t'produce-failed',\n\t\t\t\t\t\t\t\t\t\t`coin.mint(${inputs.fullCoinType}): minted Coin<T> not found in ` +\n\t\t\t\t\t\t\t\t\t\t\t`objectChanges (digest=${ok.digest}). ` +\n\t\t\t\t\t\t\t\t\t\t\tmintParseError(inputs.fullCoinType, 'minted Coin<T> absent in objectChanges')\n\t\t\t\t\t\t\t\t\t\t\t\t.message,\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\n\t\t\t\t\t\t\t// 5. Return the cached payload. The artifact publisher caches it under\n\t\t\t\t\t\t\t// the content hash; the next cycle's verify probe (on\n\t\t\t\t\t\t\t// cache hit) will lenient-probe `mintedCoinId`.\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tdigest: ok.digest,\n\t\t\t\t\t\t\t\tmintedCoinId,\n\t\t\t\t\t\t\t\trecipient: inputs.recipient,\n\t\t\t\t\t\t\t\tamount: inputs.amount.toString(),\n\t\t\t\t\t\t\t} satisfies CachedMint;\n\t\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t}),\n\t\t});\n\n\t\t// Project the cached payload to MintResult. The substrate\n\t\t// hands back the decoded `CachedMint` on every path.\n\t\treturn {\n\t\t\tdigest: cached.digest,\n\t\t\tmintedCoinId: cached.mintedCoinId,\n\t\t\trecipient: cached.recipient,\n\t\t\tamount: BigInt(cached.amount),\n\t\t\tfullCoinType: inputs.fullCoinType,\n\t\t};\n\t});\n\n/** Project an artifact publisher-wire error back to a CoinError when the consumer\n * wants a coin-side tagged shape. The artifact publisher boundary is generic; this\n * helper recovers the typed `mint-tx` / `mint-parse` phase the cause\n * walker uses. */\nexport const mintTxError = (fullCoinType: string, message: string, cause?: unknown): CoinError =>\n\tcoinError('mint-tx', {\n\t\tidentifier: fullCoinType,\n\t\tmessage,\n\t\t...(cause !== undefined ? { cause } : {}),\n\t});\n\nexport const mintParseError = (fullCoinType: string, message: string): CoinError =>\n\tcoinError('mint-parse', {\n\t\tidentifier: fullCoinType,\n\t\tmessage,\n\t});\n"],"mappings":";;;;;;;;;;;;;;;;;AA0GA,MAAa,wBAAwB,OAAO,OAAO;CAClD,UAAU,OAAO;CACjB,MAAM,OAAO;AACd,CAAC;;;;;;;;;;;;;AAcD,MAAa,wBAAwB,UAMpCA,YACC,QAAQ,MAAM,cAAc,GAAG,MAAM,cAAc,GAAG,MAAM,UAAU,GAAG,MAAM,OAAO,SAAS,GAChG;;;;;;;;;;;;;;AAwDD,MAAM,oBACL,KACA,oBAEA,OAAO,IAAI,aAAa;CACvB,IAAI,oBAAoB,MAAM,OAAO;CACrC,MAAM,MAAe,OAAO,OAAO,WAAW;EAC7C,WAAW,IAAI,KAAK,UAAU,EAAE,UAAU,gBAAgB,CAAC;EAC3D,aAAa;CACd,CAAC,CAAC,CAAC,KAGF,OAAO,YAAY,OAAO,QAAQ,IAAI,CAAC,CACxC;CACA,IAAI,QAAQ,QAAQ,QAAQ,KAAA,GAAW,OAAO;CAK9C,OAAO,OAAO,cAAc,uBAAuB,KAAK;EACvD,QAAQ;EACR,UAAU,UAAU;CACrB,CAAC,CAAC,CAAC,KAAK,OAAO,YAAY,OAAO,QAAQ,IAAgD,CAAC,CAAC;AAC7F,CAAC;;;;;;;;;;;AAuBF,MAAa,mBACZ,SACA,iBACmB;CACnB,KAAK,MAAM,UAAU,SAAS;EAC7B,IAAI,CAAC,sBAAsB,MAAM,GAAG;EACpC,IACC,OAAO,OAAO,eAAe,YAC7B,4BAA4B,OAAO,YAAY,QAAQ,YAAY,GAEnE,OAAO,OAAO;CAEhB;CACA,OAAO;AACR;AAEA,MAAM,yBAAyB,QAA6C;CAC3E,IAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU,OAAO;CACpD,MAAM,IAAI;CACV,OAAO,EAAE,SAAS,aAAa,OAAO,EAAE,aAAa;AACtD;;;;;;;;;;;AAYA,MAAa,eACZ,WACA,SACA,QACA,KACA,WAEA,OAAO,IAAI,aAAa;CAQvB,MAAM,SAAqB,OAAO,uBAGhC,WAAW;EACZ,WAAW;EACX,OAAO;EACP,aAbiB,qBAAqB;GACtC,eAAe,OAAO;GACtB,WAAW,OAAO;GAClB,QAAQ,OAAO;GACf,eAAe,OAAO;EACvB,CAQsB;EAWrB,SAAS,WAAW,iBAAiB,KAAK,OAAO,YAAY;EAC7D,SAAS,OAAO,IAAI,aAAa;GAOhC,OAAO,OAAO,gBAAgB;IAC7B,cAAc;IACd,oBACC,OAAO,IAAI,aAAa;KAIvB,MAAM,KAAK,IAAI,YAAY;KAC3B,IAAI,OAAO,cAAc,KAAA,GACxB,GAAG,aAAa,OAAO,SAAS;KAEjC,GAAG,UAAU,OAAO,OAAO;KAC3B,GAAG,SAAS;MACX,QAAQ;MACR,eAAe,CAAC,OAAO,YAAY;MACnC,WAAW;OACV,GAAG,OAAO,OAAO,aAAa;OAC9B,GAAG,KAAK,IAAI,OAAO,MAAM;OACzB,GAAG,KAAK,QAAQ,OAAO,SAAS;MACjC;KACD,CAAC;KAKD,OAAO,IAAI,aAAa,OACrB,OAAO,uCAAuC,IAAI,OAAO,SAAS,IAAI,IAAI,CAAC,CAAC,KAC5E,OAAO,UACL,UACA,qBACC,kBACA,aAAa,OAAO,aAAa,qCAAqC,MAAM,SAC7E,CACF,CACD,IACC,OAAO,OAAO,WAAW;MACzB,WAAW,GAAG,MAAM,EAAE,QAAQ,IAAI,OAAO,CAAC;MAC1C,QAAQ,UACP,qBACC,kBACA,aAAa,OAAO,aAAa,gCAAgC,mBAAmB,KAAK,GAC1F;KACF,CAAC;IACJ,CAAC;IAIF,eAAe,UACd,qBACC,kBACA,aAAa,OAAO,aAAa,+BAA+B,MAAM,OACvE;IAED,WAAW,WACV,OAAO,KACN,qBACC,kBACA,aAAa,OAAO,aAAa,6CAChC,sBAAsB,MAAM,CAC9B,CACD;IAMD,YAAY,OACX,OAAO,IAAI,aAAa;KACvB,MAAM,eAAe,gBAAgB,GAAG,eAAe,OAAO,YAAY;KAC1E,IAAI,iBAAiB,MACpB,OAAO,OAAO,OAAO,KACpB,qBACC,kBACA,aAAa,OAAO,aAAa,uDACP,GAAG,OAAO,OACnC,eAAe,OAAO,cAAc,wCAAwC,CAAC,CAC3E,OACJ,CACD;KAMD,OAAO;MACN,QAAQ,GAAG;MACX;MACA,WAAW,OAAO;MAClB,QAAQ,OAAO,OAAO,SAAS;KAChC;IACD,CAAC;GACH,CAAC;EACF,CAAC;CACF,CAAC;CAID,OAAO;EACN,QAAQ,OAAO;EACf,cAAc,OAAO;EACrB,WAAW,OAAO;EAClB,QAAQ,OAAO,OAAO,MAAM;EAC5B,cAAc,OAAO;CACtB;AACD,CAAC;AAaF,MAAa,kBAAkB,cAAsB,YACpD,UAAU,cAAc;CACvB,YAAY;CACZ;AACD,CAAC"}
|
|
@@ -1,21 +1,37 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import "../../substrate/runtime/scoped-ref-map/index.mjs";
|
|
3
|
-
import { Context, Effect, Layer } from "effect";
|
|
1
|
+
import { Context, Effect, Layer, Ref } from "effect";
|
|
4
2
|
//#region src/plugins/coin/registry.ts
|
|
5
3
|
const coinKey = (fullCoinType) => fullCoinType;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
4
|
+
/** Build a self-contained last-write-wins `CoinKey -> CoinRecord`
|
|
5
|
+
* registry over a plain `Ref<Map>`. One entry per key (each
|
|
6
|
+
* `register` replaces the key's lone entry under a fresh seq), and
|
|
7
|
+
* `list` returns records ordered by their entry's seq — a re-set of
|
|
8
|
+
* an existing key advances its seq and re-sorts it to the end. */
|
|
9
|
+
const makeCoinRegistry = () => Effect.gen(function* () {
|
|
10
|
+
const store = yield* Ref.make(/* @__PURE__ */ new Map());
|
|
11
|
+
const seqRef = yield* Ref.make(0);
|
|
12
|
+
const set = (key, value) => Effect.gen(function* () {
|
|
13
|
+
const seq = yield* Ref.updateAndGet(seqRef, (n) => n + 1);
|
|
14
|
+
yield* Ref.update(store, (current) => {
|
|
15
|
+
const next = new Map(current);
|
|
16
|
+
next.set(key, {
|
|
17
|
+
value,
|
|
18
|
+
seq
|
|
19
|
+
});
|
|
20
|
+
return next;
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
/** Records in insertion order — keys sorted by their entry's seq
|
|
24
|
+
* (a re-set sorts to the end). */
|
|
25
|
+
const ordered = (state) => [...state.values()].sort((a, b) => a.seq - b.seq).map((e) => e.value);
|
|
26
|
+
return {
|
|
27
|
+
register: (record) => set(coinKey(record.type), record),
|
|
28
|
+
byWitness: (packageName, witness) => Ref.get(store).pipe(Effect.map((state) => {
|
|
29
|
+
const lowered = witness.toLowerCase();
|
|
30
|
+
return ordered(state).find((r) => r.publishingPackageName === packageName && (r.witness === lowered || r.symbol?.toLowerCase() === lowered)) ?? null;
|
|
31
|
+
})),
|
|
32
|
+
byType: (fullCoinType) => Ref.get(store).pipe(Effect.map((state) => state.get(coinKey(fullCoinType))?.value ?? null)),
|
|
33
|
+
list: () => Ref.get(store).pipe(Effect.map(ordered))
|
|
34
|
+
};
|
|
19
35
|
});
|
|
20
36
|
/** Context.Service tag for the per-stack `CoinRegistry`. Plugins
|
|
21
37
|
* yield this in their acquire body. */
|
|
@@ -24,10 +40,7 @@ var CoinRegistryService = class extends Context.Service()("@devstack/plugins/coi
|
|
|
24
40
|
* scope. Boot wiring (CLI / e2e) provides this once per stack;
|
|
25
41
|
* every coin/package/wallet/faucet plugin in the stack yields the
|
|
26
42
|
* SAME instance via Context. */
|
|
27
|
-
const layerCoinRegistry = Layer.effect(CoinRegistryService, Effect.
|
|
28
|
-
const refMap = yield* CoinRefMap.Service;
|
|
29
|
-
return CoinRegistryService.of(wrapRefMap(refMap));
|
|
30
|
-
})).pipe(Layer.provide(CoinRefMap.layer));
|
|
43
|
+
const layerCoinRegistry = Layer.effect(CoinRegistryService, makeCoinRegistry().pipe(Effect.map(CoinRegistryService.of)));
|
|
31
44
|
//#endregion
|
|
32
45
|
export { CoinRegistryService, layerCoinRegistry };
|
|
33
46
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.mjs","names":[],"sources":["../../../src/plugins/coin/registry.ts"],"sourcesContent":["// Per-stack CoinRegistry — owned by the L2 Coin plugin.\n//\n// Architecture (ARCHITECTURE.md § Substrate name-blindness): the\n//
|
|
1
|
+
{"version":3,"file":"registry.mjs","names":[],"sources":["../../../src/plugins/coin/registry.ts"],"sourcesContent":["// Per-stack CoinRegistry — owned by the L2 Coin plugin.\n//\n// Architecture (ARCHITECTURE.md § Substrate name-blindness): the\n// `CoinRecord` shape below carries Sui/Move-coin concepts\n// (`witness`, `treasuryCapId`, `metadataId`, `packageId`,\n// `mvrPlaceholder`, `publishingPackageName`, `moduleName`) — those\n// are L2 concerns, not substrate.\n//\n// The four Sui-specific lookup shapes (`byWitness`, `byType`,\n// `list`, `register`) live on the L2 `CoinRegistry` wrapper, backed\n// by a self-contained last-write-wins `CoinKey -> CoinRecord` map\n// over a plain `Ref<Map>`. The wrapper iterates the snapshot for the\n// witness / type-based queries (cardinality is bounded by declared\n// coins per stack, typically < 10).\n//\n// LWW semantics (formerly the substrate `defineScopedRefMap` single\n// mode): each `set` stamps a fresh monotonic `seq` and replaces the\n// key's lone entry (one entry per key), so `list`/`entries` order\n// keys by their seq — a re-set advances the key's seq and sorts it\n// to the end. Self-contained here because the substrate primitive\n// had exactly two consumers (coin + package); duplicating ~30 lines\n// of LWW twice deletes a shared substrate abstraction.\n//\n// Lifetime: one instance per stack scope (the backing `Ref` lives\n// in the Layer build effect's scope). Plugins yield\n// `CoinRegistryService` from their `acquire` body; the boot wiring\n// (CLI / e2e) provides the resolved instance once per stack.\n\nimport { Context, Effect, Layer, Ref } from 'effect';\n\n/** Discovered-coin record — the value-shape stored in the registry.\n * Superset of the published-coin shape with discovery-populated\n * metadata fields. */\nexport interface CoinRecord {\n\t/** Registry key — the discovered CoinMetadata symbol, falling\n\t * back to the witness name when metadata is absent. Always\n\t * lower-cased for case-insensitive lookups (the original-case\n\t * `symbol` field carries the display form). */\n\treadonly key: string;\n\t/** Fully-qualified on-chain type — `0xPKG::module::Witness`. */\n\treadonly type: string;\n\t/** Lower-cased witness identifier (e.g. `mock_usdc`). Used for\n\t * the `coin.fromPackage(pkg, 'MOCK_USDC')` lookup. */\n\treadonly witness: string;\n\t/** Lower-cased module name. */\n\treadonly moduleName: string;\n\t/** `0` when CoinMetadata absent. */\n\treadonly decimals: number;\n\t/** Display-case symbol from CoinMetadata. Absent when metadata\n\t * fetch failed / coin had no CoinMetadata. */\n\treadonly symbol?: string;\n\treadonly displayName?: string;\n\treadonly iconUrl?: string;\n\t/** Present when the publisher held the cap at publish time AND\n\t * the cap is still address-owned. */\n\treadonly treasuryCapId?: string;\n\treadonly metadataId?: string;\n\t/** The publishing package's id — load-bearing for the\n\t * package-scoped witness lookup. */\n\treadonly packageId: string;\n\t/** Source-of-truth name of the publishing package (the Package\n\t * plugin's symbolic name, NOT the on-chain packageId). Used to\n\t * format error messages and drive the codegen emitter's\n\t * per-package grouping. */\n\treadonly publishingPackageName: string;\n}\n\n/** Registry key — the fully-qualified on-chain coin type. Branded so\n * it serves as a `Map` key without the brand leaking elsewhere. */\nexport type CoinKey = string & { readonly _brand: 'CoinKey' };\n\nconst coinKey = (fullCoinType: string): CoinKey => fullCoinType as CoinKey;\n\n/** Per-stack registry of all discovered coins. The four lookup\n * shapes are Sui-specific projections over the LWW `CoinKey ->\n * CoinRecord` map. */\nexport interface CoinRegistry {\n\treadonly register: (record: CoinRecord) => Effect.Effect<void>;\n\treadonly byWitness: (packageName: string, witness: string) => Effect.Effect<CoinRecord | null>;\n\treadonly byType: (fullCoinType: string) => Effect.Effect<CoinRecord | null>;\n\treadonly list: () => Effect.Effect<ReadonlyArray<CoinRecord>>;\n}\n\n/** One stored entry: the `CoinRecord` plus the monotonic `seq` the\n * last `register` stamped it with. The `seq` drives last-write-wins\n * (highest seq under a key wins) and insertion order (`list` sorts\n * keys by seq). */\ninterface SeqEntry {\n\treadonly value: CoinRecord;\n\treadonly seq: number;\n}\n\n/** Build a self-contained last-write-wins `CoinKey -> CoinRecord`\n * registry over a plain `Ref<Map>`. One entry per key (each\n * `register` replaces the key's lone entry under a fresh seq), and\n * `list` returns records ordered by their entry's seq — a re-set of\n * an existing key advances its seq and re-sorts it to the end. */\nconst makeCoinRegistry = (): Effect.Effect<CoinRegistry> =>\n\tEffect.gen(function* () {\n\t\tconst store = yield* Ref.make<ReadonlyMap<CoinKey, SeqEntry>>(new Map());\n\t\tconst seqRef = yield* Ref.make(0);\n\n\t\tconst set = (key: CoinKey, value: CoinRecord): Effect.Effect<void> =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst seq = yield* Ref.updateAndGet(seqRef, (n) => n + 1);\n\t\t\t\tyield* Ref.update(store, (current) => {\n\t\t\t\t\tconst next = new Map(current);\n\t\t\t\t\tnext.set(key, { value, seq });\n\t\t\t\t\treturn next;\n\t\t\t\t});\n\t\t\t});\n\n\t\t/** Records in insertion order — keys sorted by their entry's seq\n\t\t * (a re-set sorts to the end). */\n\t\tconst ordered = (state: ReadonlyMap<CoinKey, SeqEntry>): ReadonlyArray<CoinRecord> =>\n\t\t\t[...state.values()].sort((a, b) => a.seq - b.seq).map((e) => e.value);\n\n\t\treturn {\n\t\t\tregister: (record) => set(coinKey(record.type), record),\n\t\t\tbyWitness: (packageName, witness) =>\n\t\t\t\tRef.get(store).pipe(\n\t\t\t\t\tEffect.map((state) => {\n\t\t\t\t\t\tconst lowered = witness.toLowerCase();\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\tordered(state).find(\n\t\t\t\t\t\t\t\t(r) =>\n\t\t\t\t\t\t\t\t\tr.publishingPackageName === packageName &&\n\t\t\t\t\t\t\t\t\t(r.witness === lowered || r.symbol?.toLowerCase() === lowered),\n\t\t\t\t\t\t\t) ?? null\n\t\t\t\t\t\t);\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\tbyType: (fullCoinType) =>\n\t\t\t\tRef.get(store).pipe(Effect.map((state) => state.get(coinKey(fullCoinType))?.value ?? null)),\n\t\t\tlist: () => Ref.get(store).pipe(Effect.map(ordered)),\n\t\t};\n\t});\n\n/** Context.Service tag for the per-stack `CoinRegistry`. Plugins\n * yield this in their acquire body. */\nexport class CoinRegistryService extends Context.Service<CoinRegistryService, CoinRegistry>()(\n\t'@devstack/plugins/coin/CoinRegistry',\n) {}\n\n/** Scope-bound Layer materializing one `CoinRegistry` per stack\n * scope. Boot wiring (CLI / e2e) provides this once per stack;\n * every coin/package/wallet/faucet plugin in the stack yields the\n * SAME instance via Context. */\nexport const layerCoinRegistry: Layer.Layer<CoinRegistryService> = Layer.effect(\n\tCoinRegistryService,\n\tmakeCoinRegistry().pipe(Effect.map(CoinRegistryService.of)),\n);\n"],"mappings":";;AAuEA,MAAM,WAAW,iBAAkC;;;;;;AA0BnD,MAAM,yBACL,OAAO,IAAI,aAAa;CACvB,MAAM,QAAQ,OAAO,IAAI,qBAAqC,IAAI,IAAI,CAAC;CACvE,MAAM,SAAS,OAAO,IAAI,KAAK,CAAC;CAEhC,MAAM,OAAO,KAAc,UAC1B,OAAO,IAAI,aAAa;EACvB,MAAM,MAAM,OAAO,IAAI,aAAa,SAAS,MAAM,IAAI,CAAC;EACxD,OAAO,IAAI,OAAO,QAAQ,YAAY;GACrC,MAAM,OAAO,IAAI,IAAI,OAAO;GAC5B,KAAK,IAAI,KAAK;IAAE;IAAO;GAAI,CAAC;GAC5B,OAAO;EACR,CAAC;CACF,CAAC;;;CAIF,MAAM,WAAW,UAChB,CAAC,GAAG,MAAM,OAAO,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,MAAM,EAAE,KAAK;CAErE,OAAO;EACN,WAAW,WAAW,IAAI,QAAQ,OAAO,IAAI,GAAG,MAAM;EACtD,YAAY,aAAa,YACxB,IAAI,IAAI,KAAK,CAAC,CAAC,KACd,OAAO,KAAK,UAAU;GACrB,MAAM,UAAU,QAAQ,YAAY;GACpC,OACC,QAAQ,KAAK,CAAC,CAAC,MACb,MACA,EAAE,0BAA0B,gBAC3B,EAAE,YAAY,WAAW,EAAE,QAAQ,YAAY,MAAM,QACxD,KAAK;EAEP,CAAC,CACF;EACD,SAAS,iBACR,IAAI,IAAI,KAAK,CAAC,CAAC,KAAK,OAAO,KAAK,UAAU,MAAM,IAAI,QAAQ,YAAY,CAAC,CAAC,EAAE,SAAS,IAAI,CAAC;EAC3F,YAAY,IAAI,IAAI,KAAK,CAAC,CAAC,KAAK,OAAO,IAAI,OAAO,CAAC;CACpD;AACD,CAAC;;;AAIF,IAAa,sBAAb,cAAyC,QAAQ,QAA2C,CAAC,CAC5F,qCACD,CAAC,CAAC,CAAC;;;;;AAMH,MAAa,oBAAsD,MAAM,OACxE,qBACA,iBAAiB,CAAC,CAAC,KAAK,OAAO,IAAI,oBAAoB,EAAE,CAAC,CAC3D"}
|
|
@@ -63,7 +63,7 @@ interface CoinValue extends ResolvedCoin {
|
|
|
63
63
|
* narrowed shape; the coin barrel projects the value to the wider
|
|
64
64
|
* `AccountFundingStrategy` cross-plugin contract at the
|
|
65
65
|
* `strategy-contributor` capability boundary (see
|
|
66
|
-
* `coin/index.ts →
|
|
66
|
+
* `coin/index.ts → coinContributions`), wrapping the narrow
|
|
67
67
|
* request fn so the account bus's `{address, amount, account}`
|
|
68
68
|
* shape is satisfied honestly at the boundary.
|
|
69
69
|
*
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { coinError } from "./errors.mjs";
|
|
2
|
-
import { CoinSpans } from "./spans.mjs";
|
|
3
2
|
import { resolveBuiltin, resolveByBareType, resolveByWitness } from "./address-resolution.mjs";
|
|
4
3
|
import { performMint } from "./mint.mjs";
|
|
5
4
|
import { Effect } from "effect";
|
|
6
5
|
//#region src/plugins/coin/service.ts
|
|
7
6
|
/** Resolve a coin instance to the tag's resolved value. */
|
|
8
7
|
const acquireCoin = (form, ctx) => Effect.gen(function* () {
|
|
9
|
-
yield* Effect.annotateCurrentSpan({ [CoinSpans.form]: form.kind });
|
|
10
8
|
const resolved = yield* (() => {
|
|
11
9
|
switch (form.kind) {
|
|
12
10
|
case "witness": return resolveByWitness(ctx.registry, form.publishingPackageName, form.witness);
|
|
@@ -14,11 +12,6 @@ const acquireCoin = (form, ctx) => Effect.gen(function* () {
|
|
|
14
12
|
case "builtin": return Effect.succeed(resolveBuiltin(form.name));
|
|
15
13
|
}
|
|
16
14
|
})();
|
|
17
|
-
yield* Effect.annotateCurrentSpan({
|
|
18
|
-
[CoinSpans.fullCoinType]: resolved.fullCoinType,
|
|
19
|
-
[CoinSpans.decimals]: resolved.decimals,
|
|
20
|
-
[CoinSpans.source]: resolved.source
|
|
21
|
-
});
|
|
22
15
|
const mint = (signer, opts) => {
|
|
23
16
|
const capId = opts.treasuryCapId ?? resolved.treasuryCapId;
|
|
24
17
|
if (capId === void 0) return Effect.fail(coinError("cap-missing", {
|
|
@@ -31,7 +24,7 @@ const acquireCoin = (form, ctx) => Effect.gen(function* () {
|
|
|
31
24
|
recipient: opts.to,
|
|
32
25
|
amount: opts.amount
|
|
33
26
|
};
|
|
34
|
-
return performMint(ctx.publisher, ctx.
|
|
27
|
+
return performMint(ctx.publisher, ctx.chainId, signer, ctx.sdk, inputs);
|
|
35
28
|
};
|
|
36
29
|
const fundingSigner = form.kind === "witness" ? form.fundingSigner : void 0;
|
|
37
30
|
const fundingTreasuryCapId = resolved.treasuryCapId;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.mjs","names":[],"sources":["../../../src/plugins/coin/service.ts"],"sourcesContent":["// Coin plugin — main acquire body.\n//\n// One-shot value resolution: the three address forms unify behind a\n// single `acquireCoin` Effect. The barrel (`index.ts`) constructs ONE\n// `CoinAcquireInputs` per declared coin instance and routes here.\n//\n// What this file does:\n//\n// 1. Dispatch on the address-form discriminator to the right\n// resolver under `address-resolution.ts`.\n// 2. Project the resolved value into the user-facing `ResolvedCoin`\n// shape that the Tag publishes.\n// 3. Project a `mint(...)` closure (lazy mint — captures the\n// resolved fullCoinType + the cap id; defers the substrate-\n// primitive call to mint time so the cache key is keyed on\n// mint-time inputs, not factory-time ones).\n//\n// What it does NOT do:\n//\n// - Consume the LocalPackagePublishOutput — that's the discovery-fold path\n// handled at compose-time in the barrel (the barrel calls into\n// `discovery.ts` + `metadata.ts` to populate the registry as\n// packages publish; this file just READS the registry).\n// - Wire capabilities — the barrel's job.\n\nimport { Effect, type Scope } from 'effect';\n\nimport type { ChainId } from '../../substrate/brand.ts';\nimport type {\n\tArtifactPublishError,\n\tArtifactPublisher,\n} from '../../primitives/artifact-publisher.ts';\nimport {\n\tBUILTIN_COINS,\n\tresolveBuiltin,\n\tresolveByBareType,\n\tresolveByWitness,\n\ttype ResolvedCoin,\n} from './address-resolution.ts';\nimport { coinError, type CoinError } from './errors.ts';\nimport type { MetadataSdkShim } from './metadata.ts';\nimport { CoinSpans } from './spans.ts';\nimport {\n\tperformMint,\n\ttype MintInputs,\n\ttype MintResult,\n\ttype MintSdkShim,\n\ttype MintSigner,\n} from './mint.ts';\nimport type { CoinRegistry } from './registry.ts';\n\n/** Per-instance options threaded into the acquire body. One-of the\n * three address forms. */\nexport type CoinAddressForm =\n\t| {\n\t\t\treadonly kind: 'witness';\n\t\t\treadonly publishingPackageName: string;\n\t\t\treadonly witness: string;\n\t\t\treadonly fundingSigner?: MintSigner;\n\t }\n\t| { readonly kind: 'known'; readonly fullCoinType: string }\n\t| { readonly kind: 'builtin'; readonly name: keyof typeof BUILTIN_COINS };\n\n/** Per-acquire context supplied by the barrel from the BuildContext.\n * Carries the resolved per-stack registry, the Sui-side SDK shim\n * (verify probe + tx build), the chain id, and the\n * `ArtifactPublisher` substrate primitive used by `performMint`. */\nexport interface CoinAcquireContext {\n\treadonly registry: CoinRegistry;\n\treadonly sdk: MetadataSdkShim & MintSdkShim;\n\treadonly chain: ChainId;\n\treadonly publisher: ArtifactPublisher;\n}\n\n/** The tag's resolved value — the three address forms unified PLUS a\n * closure for the generic mint surface. */\nexport interface CoinValue extends ResolvedCoin {\n\t/** Generic mint. Requires the cap id (either resolved from the\n\t * registry record's `treasuryCapId`, or supplied explicitly for\n\t * bare-type coins). Each call yields a fresh artifact publisher round (cache\n\t * hit means short-circuit per the substrate primitive). */\n\treadonly mint: (\n\t\tsigner: MintSigner,\n\t\topts: { readonly to: string; readonly amount: bigint; readonly treasuryCapId?: string },\n\t) => Effect.Effect<MintResult, CoinError | ArtifactPublishError, Scope.Scope>;\n\t/** Self-contained mint that needs NO external signer — present\n\t * exactly when `fundingStrategy` is (witness-form coins whose\n\t * publisher still owns the TreasuryCap). Captures the publisher\n\t * `MintSigner` + the resolved `treasuryCapId` internally and returns\n\t * the full `MintResult` (digest + minted-coin id), unlike\n\t * `fundingStrategy.request` which discards the result.\n\t *\n\t * This is the seam the control-plane dashboard mint ACTION drives:\n\t * the supervisor reads the resolved `CoinValue` and calls this with\n\t * `{to, amount}` — no signer threading needed, because the\n\t * treasury-cap-owning publisher signer is already in-process here\n\t * (the same lease-owning path `fundingStrategy` uses). The Effect is\n\t * self-scoping (wraps `Effect.scoped` over the artifact-publisher\n\t * round), so callers run it directly without a surrounding Scope. */\n\treadonly mintFromCap?: (opts: {\n\t\treadonly to: string;\n\t\treadonly amount: bigint;\n\t}) => Effect.Effect<MintResult, CoinError | ArtifactPublishError>;\n\t/** Centralized funding strategy, present for local package coins\n\t * whose publisher still owns the TreasuryCap. The coin barrel\n\t * publishes it under `coinType:<fullCoinType>` so Account funding\n\t * can mint arbitrary local coins without bespoke example actions.\n\t *\n\t * The request shape is a NARROWED projection of\n\t * `AccountFundingRequest` (`{address, amount}` only — the coin\n\t * strategy doesn't need the resolved account handle since the\n\t * TreasuryCap-owning publisher signs the mint via its own lease\n\t * inside `mint → signAndDispatch`). Direct consumers (deepbook\n\t * seed funding) call `.request({address, amount})` against this\n\t * narrowed shape; the coin barrel projects the value to the wider\n\t * `AccountFundingStrategy` cross-plugin contract at the\n\t * `strategy-contributor` capability boundary (see\n\t * `coin/index.ts → buildCapabilities`), wrapping the narrow\n\t * request fn so the account bus's `{address, amount, account}`\n\t * shape is satisfied honestly at the boundary.\n\t *\n\t * The E channel preserves the tagged vocabulary\n\t * (`CoinError | ArtifactPublishError`) rather than collapsing to\n\t * `unknown`, so direct consumers can catchTag on the typed\n\t * errors. The account-side dispatcher's registry lookup narrows\n\t * the channel to `unknown` at the registry boundary and reads\n\t * `_tag` defensively. */\n\treadonly fundingStrategy?: {\n\t\treadonly request: (req: {\n\t\t\treadonly address: string;\n\t\t\treadonly amount: bigint;\n\t\t}) => Effect.Effect<void, CoinError | ArtifactPublishError>;\n\t};\n}\n\n/** Resolve a coin instance to the tag's resolved value. */\nexport const acquireCoin = (\n\tform: CoinAddressForm,\n\tctx: CoinAcquireContext,\n): Effect.Effect<CoinValue, CoinError> =>\n\tEffect.gen(function* () {\n\t\tyield* Effect.annotateCurrentSpan({\n\t\t\t[CoinSpans.form]: form.kind,\n\t\t});\n\n\t\tconst resolved: ResolvedCoin = yield* (() => {\n\t\t\tswitch (form.kind) {\n\t\t\t\tcase 'witness':\n\t\t\t\t\treturn resolveByWitness(ctx.registry, form.publishingPackageName, form.witness);\n\t\t\t\tcase 'known':\n\t\t\t\t\treturn resolveByBareType(ctx.sdk, form.fullCoinType);\n\t\t\t\tcase 'builtin':\n\t\t\t\t\treturn Effect.succeed(resolveBuiltin(form.name));\n\t\t\t}\n\t\t})();\n\n\t\tyield* Effect.annotateCurrentSpan({\n\t\t\t[CoinSpans.fullCoinType]: resolved.fullCoinType,\n\t\t\t[CoinSpans.decimals]: resolved.decimals,\n\t\t\t[CoinSpans.source]: resolved.source,\n\t\t});\n\n\t\tconst mint: CoinValue['mint'] = (signer, opts) => {\n\t\t\tconst capId = opts.treasuryCapId ?? resolved.treasuryCapId;\n\t\t\tif (capId === undefined) {\n\t\t\t\treturn Effect.fail(\n\t\t\t\t\tcoinError('cap-missing', {\n\t\t\t\t\t\tidentifier: resolved.fullCoinType,\n\t\t\t\t\t\tmessage: `coin('${resolved.fullCoinType}').mint(): no treasury cap available — pass opts.treasuryCapId or use a coin discovered with publisherOwnsCap=true.`,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst inputs: MintInputs = {\n\t\t\t\tfullCoinType: resolved.fullCoinType,\n\t\t\t\ttreasuryCapId: capId,\n\t\t\t\trecipient: opts.to,\n\t\t\t\tamount: opts.amount,\n\t\t\t};\n\t\t\treturn performMint(ctx.publisher, ctx.chain, signer, ctx.sdk, inputs);\n\t\t};\n\t\tconst fundingSigner = form.kind === 'witness' ? form.fundingSigner : undefined;\n\t\tconst fundingTreasuryCapId = resolved.treasuryCapId;\n\t\t// Self-contained mint closure — same capture as `fundingStrategy`\n\t\t// (publisher signer + resolved cap) but returns the full\n\t\t// `MintResult` and self-scopes. Drives the dashboard mint action.\n\t\tconst mintFromCap: CoinValue['mintFromCap'] =\n\t\t\tfundingSigner !== undefined && fundingTreasuryCapId !== undefined\n\t\t\t\t? (opts) =>\n\t\t\t\t\t\tEffect.scoped(\n\t\t\t\t\t\t\tmint(fundingSigner, {\n\t\t\t\t\t\t\t\tto: opts.to,\n\t\t\t\t\t\t\t\tamount: opts.amount,\n\t\t\t\t\t\t\t\ttreasuryCapId: fundingTreasuryCapId,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t)\n\t\t\t\t: undefined;\n\t\tconst fundingStrategy: CoinValue['fundingStrategy'] =\n\t\t\tfundingSigner !== undefined && fundingTreasuryCapId !== undefined\n\t\t\t\t? {\n\t\t\t\t\t\trequest: (req) =>\n\t\t\t\t\t\t\tEffect.scoped(\n\t\t\t\t\t\t\t\tmint(fundingSigner, {\n\t\t\t\t\t\t\t\t\tto: req.address,\n\t\t\t\t\t\t\t\t\tamount: req.amount,\n\t\t\t\t\t\t\t\t\ttreasuryCapId: fundingTreasuryCapId,\n\t\t\t\t\t\t\t\t}).pipe(Effect.asVoid),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t}\n\t\t\t\t: undefined;\n\t\tconst value: CoinValue = {\n\t\t\t...resolved,\n\t\t\tmint,\n\t\t\t...(mintFromCap === undefined ? {} : { mintFromCap }),\n\t\t\t...(fundingStrategy === undefined ? {} : { fundingStrategy }),\n\t\t};\n\t\treturn value;\n\t});\n"],"mappings":";;;;;;;AAwIA,MAAa,eACZ,MACA,QAEA,OAAO,IAAI,aAAa;AACvB,QAAO,OAAO,oBAAoB,GAChC,UAAU,OAAO,KAAK,MACvB,CAAC;CAEF,MAAM,WAAyB,cAAc;AAC5C,UAAQ,KAAK,MAAb;GACC,KAAK,UACJ,QAAO,iBAAiB,IAAI,UAAU,KAAK,uBAAuB,KAAK,QAAQ;GAChF,KAAK,QACJ,QAAO,kBAAkB,IAAI,KAAK,KAAK,aAAa;GACrD,KAAK,UACJ,QAAO,OAAO,QAAQ,eAAe,KAAK,KAAK,CAAC;;KAE/C;AAEJ,QAAO,OAAO,oBAAoB;GAChC,UAAU,eAAe,SAAS;GAClC,UAAU,WAAW,SAAS;GAC9B,UAAU,SAAS,SAAS;EAC7B,CAAC;CAEF,MAAM,QAA2B,QAAQ,SAAS;EACjD,MAAM,QAAQ,KAAK,iBAAiB,SAAS;AAC7C,MAAI,UAAU,KAAA,EACb,QAAO,OAAO,KACb,UAAU,eAAe;GACxB,YAAY,SAAS;GACrB,SAAS,SAAS,SAAS,aAAa;GACxC,CAAC,CACF;EAEF,MAAM,SAAqB;GAC1B,cAAc,SAAS;GACvB,eAAe;GACf,WAAW,KAAK;GAChB,QAAQ,KAAK;GACb;AACD,SAAO,YAAY,IAAI,WAAW,IAAI,OAAO,QAAQ,IAAI,KAAK,OAAO;;CAEtE,MAAM,gBAAgB,KAAK,SAAS,YAAY,KAAK,gBAAgB,KAAA;CACrE,MAAM,uBAAuB,SAAS;CAItC,MAAM,cACL,kBAAkB,KAAA,KAAa,yBAAyB,KAAA,KACpD,SACD,OAAO,OACN,KAAK,eAAe;EACnB,IAAI,KAAK;EACT,QAAQ,KAAK;EACb,eAAe;EACf,CAAC,CACF,GACD,KAAA;CACJ,MAAM,kBACL,kBAAkB,KAAA,KAAa,yBAAyB,KAAA,IACrD,EACA,UAAU,QACT,OAAO,OACN,KAAK,eAAe;EACnB,IAAI,IAAI;EACR,QAAQ,IAAI;EACZ,eAAe;EACf,CAAC,CAAC,KAAK,OAAO,OAAO,CACtB,EACF,GACA,KAAA;AAOJ,QAAO;EALN,GAAG;EACH;EACA,GAAI,gBAAgB,KAAA,IAAY,EAAE,GAAG,EAAE,aAAa;EACpD,GAAI,oBAAoB,KAAA,IAAY,EAAE,GAAG,EAAE,iBAAiB;EAEjD;EACX"}
|
|
1
|
+
{"version":3,"file":"service.mjs","names":[],"sources":["../../../src/plugins/coin/service.ts"],"sourcesContent":["// Coin plugin — main acquire body.\n//\n// One-shot value resolution: the three address forms unify behind a\n// single `acquireCoin` Effect. The barrel (`index.ts`) constructs ONE\n// `CoinAcquireInputs` per declared coin instance and routes here.\n//\n// What this file does:\n//\n// 1. Dispatch on the address-form discriminator to the right\n// resolver under `address-resolution.ts`.\n// 2. Project the resolved value into the user-facing `ResolvedCoin`\n// shape that the Tag publishes.\n// 3. Project a `mint(...)` closure (lazy mint — captures the\n// resolved fullCoinType + the cap id; defers the substrate-\n// primitive call to mint time so the cache key is keyed on\n// mint-time inputs, not factory-time ones).\n//\n// What it does NOT do:\n//\n// - Consume the LocalPackagePublishOutput — that's the discovery-fold path\n// handled at compose-time in the barrel (the barrel calls into\n// `discovery.ts` + `metadata.ts` to populate the registry as\n// packages publish; this file just READS the registry).\n// - Wire capabilities — the barrel's job.\n\nimport { Effect, type Scope } from 'effect';\n\nimport type {\n\tArtifactPublishError,\n\tArtifactPublisher,\n} from '../../primitives/artifact-publisher.ts';\nimport {\n\tBUILTIN_COINS,\n\tresolveBuiltin,\n\tresolveByBareType,\n\tresolveByWitness,\n\ttype ResolvedCoin,\n} from './address-resolution.ts';\nimport { coinError, type CoinError } from './errors.ts';\nimport type { MetadataSdkShim } from './metadata.ts';\nimport {\n\tperformMint,\n\ttype MintInputs,\n\ttype MintResult,\n\ttype MintSdkShim,\n\ttype MintSigner,\n} from './mint.ts';\nimport type { CoinRegistry } from './registry.ts';\n\n/** Per-instance options threaded into the acquire body. One-of the\n * three address forms. */\nexport type CoinAddressForm =\n\t| {\n\t\t\treadonly kind: 'witness';\n\t\t\treadonly publishingPackageName: string;\n\t\t\treadonly witness: string;\n\t\t\treadonly fundingSigner?: MintSigner;\n\t }\n\t| { readonly kind: 'known'; readonly fullCoinType: string }\n\t| { readonly kind: 'builtin'; readonly name: keyof typeof BUILTIN_COINS };\n\n/** Per-acquire context supplied by the barrel from the BuildContext.\n * Carries the resolved per-stack registry, the Sui-side SDK shim\n * (verify probe + tx build), the chain id, and the\n * `ArtifactPublisher` substrate primitive used by `performMint`. */\nexport interface CoinAcquireContext {\n\treadonly registry: CoinRegistry;\n\treadonly sdk: MetadataSdkShim & MintSdkShim;\n\treadonly chainId: string;\n\treadonly publisher: ArtifactPublisher;\n}\n\n/** The tag's resolved value — the three address forms unified PLUS a\n * closure for the generic mint surface. */\nexport interface CoinValue extends ResolvedCoin {\n\t/** Generic mint. Requires the cap id (either resolved from the\n\t * registry record's `treasuryCapId`, or supplied explicitly for\n\t * bare-type coins). Each call yields a fresh artifact publisher round (cache\n\t * hit means short-circuit per the substrate primitive). */\n\treadonly mint: (\n\t\tsigner: MintSigner,\n\t\topts: { readonly to: string; readonly amount: bigint; readonly treasuryCapId?: string },\n\t) => Effect.Effect<MintResult, CoinError | ArtifactPublishError, Scope.Scope>;\n\t/** Self-contained mint that needs NO external signer — present\n\t * exactly when `fundingStrategy` is (witness-form coins whose\n\t * publisher still owns the TreasuryCap). Captures the publisher\n\t * `MintSigner` + the resolved `treasuryCapId` internally and returns\n\t * the full `MintResult` (digest + minted-coin id), unlike\n\t * `fundingStrategy.request` which discards the result.\n\t *\n\t * This is the seam the control-plane dashboard mint ACTION drives:\n\t * the supervisor reads the resolved `CoinValue` and calls this with\n\t * `{to, amount}` — no signer threading needed, because the\n\t * treasury-cap-owning publisher signer is already in-process here\n\t * (the same lease-owning path `fundingStrategy` uses). The Effect is\n\t * self-scoping (wraps `Effect.scoped` over the artifact-publisher\n\t * round), so callers run it directly without a surrounding Scope. */\n\treadonly mintFromCap?: (opts: {\n\t\treadonly to: string;\n\t\treadonly amount: bigint;\n\t}) => Effect.Effect<MintResult, CoinError | ArtifactPublishError>;\n\t/** Centralized funding strategy, present for local package coins\n\t * whose publisher still owns the TreasuryCap. The coin barrel\n\t * publishes it under `coinType:<fullCoinType>` so Account funding\n\t * can mint arbitrary local coins without bespoke example actions.\n\t *\n\t * The request shape is a NARROWED projection of\n\t * `AccountFundingRequest` (`{address, amount}` only — the coin\n\t * strategy doesn't need the resolved account handle since the\n\t * TreasuryCap-owning publisher signs the mint via its own lease\n\t * inside `mint → signAndDispatch`). Direct consumers (deepbook\n\t * seed funding) call `.request({address, amount})` against this\n\t * narrowed shape; the coin barrel projects the value to the wider\n\t * `AccountFundingStrategy` cross-plugin contract at the\n\t * `strategy-contributor` capability boundary (see\n\t * `coin/index.ts → coinContributions`), wrapping the narrow\n\t * request fn so the account bus's `{address, amount, account}`\n\t * shape is satisfied honestly at the boundary.\n\t *\n\t * The E channel preserves the tagged vocabulary\n\t * (`CoinError | ArtifactPublishError`) rather than collapsing to\n\t * `unknown`, so direct consumers can catchTag on the typed\n\t * errors. The account-side dispatcher's registry lookup narrows\n\t * the channel to `unknown` at the registry boundary and reads\n\t * `_tag` defensively. */\n\treadonly fundingStrategy?: {\n\t\treadonly request: (req: {\n\t\t\treadonly address: string;\n\t\t\treadonly amount: bigint;\n\t\t}) => Effect.Effect<void, CoinError | ArtifactPublishError>;\n\t};\n}\n\n/** Resolve a coin instance to the tag's resolved value. */\nexport const acquireCoin = (\n\tform: CoinAddressForm,\n\tctx: CoinAcquireContext,\n): Effect.Effect<CoinValue, CoinError> =>\n\tEffect.gen(function* () {\n\t\tconst resolved: ResolvedCoin = yield* (() => {\n\t\t\tswitch (form.kind) {\n\t\t\t\tcase 'witness':\n\t\t\t\t\treturn resolveByWitness(ctx.registry, form.publishingPackageName, form.witness);\n\t\t\t\tcase 'known':\n\t\t\t\t\treturn resolveByBareType(ctx.sdk, form.fullCoinType);\n\t\t\t\tcase 'builtin':\n\t\t\t\t\treturn Effect.succeed(resolveBuiltin(form.name));\n\t\t\t}\n\t\t})();\n\n\t\tconst mint: CoinValue['mint'] = (signer, opts) => {\n\t\t\tconst capId = opts.treasuryCapId ?? resolved.treasuryCapId;\n\t\t\tif (capId === undefined) {\n\t\t\t\treturn Effect.fail(\n\t\t\t\t\tcoinError('cap-missing', {\n\t\t\t\t\t\tidentifier: resolved.fullCoinType,\n\t\t\t\t\t\tmessage: `coin('${resolved.fullCoinType}').mint(): no treasury cap available — pass opts.treasuryCapId or use a coin discovered with publisherOwnsCap=true.`,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst inputs: MintInputs = {\n\t\t\t\tfullCoinType: resolved.fullCoinType,\n\t\t\t\ttreasuryCapId: capId,\n\t\t\t\trecipient: opts.to,\n\t\t\t\tamount: opts.amount,\n\t\t\t};\n\t\t\treturn performMint(ctx.publisher, ctx.chainId, signer, ctx.sdk, inputs);\n\t\t};\n\t\tconst fundingSigner = form.kind === 'witness' ? form.fundingSigner : undefined;\n\t\tconst fundingTreasuryCapId = resolved.treasuryCapId;\n\t\t// Self-contained mint closure — same capture as `fundingStrategy`\n\t\t// (publisher signer + resolved cap) but returns the full\n\t\t// `MintResult` and self-scopes. Drives the dashboard mint action.\n\t\tconst mintFromCap: CoinValue['mintFromCap'] =\n\t\t\tfundingSigner !== undefined && fundingTreasuryCapId !== undefined\n\t\t\t\t? (opts) =>\n\t\t\t\t\t\tEffect.scoped(\n\t\t\t\t\t\t\tmint(fundingSigner, {\n\t\t\t\t\t\t\t\tto: opts.to,\n\t\t\t\t\t\t\t\tamount: opts.amount,\n\t\t\t\t\t\t\t\ttreasuryCapId: fundingTreasuryCapId,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t)\n\t\t\t\t: undefined;\n\t\tconst fundingStrategy: CoinValue['fundingStrategy'] =\n\t\t\tfundingSigner !== undefined && fundingTreasuryCapId !== undefined\n\t\t\t\t? {\n\t\t\t\t\t\trequest: (req) =>\n\t\t\t\t\t\t\tEffect.scoped(\n\t\t\t\t\t\t\t\tmint(fundingSigner, {\n\t\t\t\t\t\t\t\t\tto: req.address,\n\t\t\t\t\t\t\t\t\tamount: req.amount,\n\t\t\t\t\t\t\t\t\ttreasuryCapId: fundingTreasuryCapId,\n\t\t\t\t\t\t\t\t}).pipe(Effect.asVoid),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t}\n\t\t\t\t: undefined;\n\t\tconst value: CoinValue = {\n\t\t\t...resolved,\n\t\t\tmint,\n\t\t\t...(mintFromCap === undefined ? {} : { mintFromCap }),\n\t\t\t...(fundingStrategy === undefined ? {} : { fundingStrategy }),\n\t\t};\n\t\treturn value;\n\t});\n"],"mappings":";;;;;;AAsIA,MAAa,eACZ,MACA,QAEA,OAAO,IAAI,aAAa;CACvB,MAAM,WAAyB,cAAc;EAC5C,QAAQ,KAAK,MAAb;GACC,KAAK,WACJ,OAAO,iBAAiB,IAAI,UAAU,KAAK,uBAAuB,KAAK,OAAO;GAC/E,KAAK,SACJ,OAAO,kBAAkB,IAAI,KAAK,KAAK,YAAY;GACpD,KAAK,WACJ,OAAO,OAAO,QAAQ,eAAe,KAAK,IAAI,CAAC;EACjD;CACD,EAAA,CAAG;CAEH,MAAM,QAA2B,QAAQ,SAAS;EACjD,MAAM,QAAQ,KAAK,iBAAiB,SAAS;EAC7C,IAAI,UAAU,KAAA,GACb,OAAO,OAAO,KACb,UAAU,eAAe;GACxB,YAAY,SAAS;GACrB,SAAS,SAAS,SAAS,aAAa;EACzC,CAAC,CACF;EAED,MAAM,SAAqB;GAC1B,cAAc,SAAS;GACvB,eAAe;GACf,WAAW,KAAK;GAChB,QAAQ,KAAK;EACd;EACA,OAAO,YAAY,IAAI,WAAW,IAAI,SAAS,QAAQ,IAAI,KAAK,MAAM;CACvE;CACA,MAAM,gBAAgB,KAAK,SAAS,YAAY,KAAK,gBAAgB,KAAA;CACrE,MAAM,uBAAuB,SAAS;CAItC,MAAM,cACL,kBAAkB,KAAA,KAAa,yBAAyB,KAAA,KACpD,SACD,OAAO,OACN,KAAK,eAAe;EACnB,IAAI,KAAK;EACT,QAAQ,KAAK;EACb,eAAe;CAChB,CAAC,CACF,IACA,KAAA;CACJ,MAAM,kBACL,kBAAkB,KAAA,KAAa,yBAAyB,KAAA,IACrD,EACA,UAAU,QACT,OAAO,OACN,KAAK,eAAe;EACnB,IAAI,IAAI;EACR,QAAQ,IAAI;EACZ,eAAe;CAChB,CAAC,CAAC,CAAC,KAAK,OAAO,MAAM,CACtB,EACF,IACC,KAAA;CAOJ,OAAO;EALN,GAAG;EACH;EACA,GAAI,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,YAAY;EACnD,GAAI,oBAAoB,KAAA,IAAY,CAAC,IAAI,EAAE,gBAAgB;CAEjD;AACZ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.mjs","names":[],"sources":["../../../src/plugins/coin/snapshot.ts"],"sourcesContent":["// Coin plugin — Snapshotable contribution.\n//\n// Distilled-doc 13-coin.md §Persistence model:\n//\n// - The mint-cache (`coin
|
|
1
|
+
{"version":3,"file":"snapshot.mjs","names":[],"sources":["../../../src/plugins/coin/snapshot.ts"],"sourcesContent":["// Coin plugin — Snapshotable contribution.\n//\n// Distilled-doc 13-coin.md §Persistence model:\n//\n// - The mint-cache (namespace `coin-mint`, content-addressed by\n// `(chainId, treasuryCapId, signer, recipient, amount)`) lives in\n// the substrate's content-addressed cache under\n// `cache/<namespace>/<chainId>/...` and IS captured by the\n// substrate's auto-included cache subtree. We declare no extra\n// subtrees here.\n// - The `CoinRegistry` is purely in-process; nothing to capture.\n// - Per-Layer-invocation metadata cache is also in-process.\n//\n// The plugin therefore emits a MINIMAL snapshot decl:\n// `missingTolerance: 'fine'` (a fresh stack with no cache entries\n// just re-mints / re-resolves on next acquisition), no subtrees, no\n// containers. The decl exists for shape symmetry with the other\n// plugins and so a per-coin \"wipe\" recipe has a contribution to\n// target in the future.\n\nimport { Effect } from 'effect';\n\nimport type { SnapshotableDecl } from '../../contracts/snapshotable.ts';\n\n/** Identity guard for the snapshot orchestrator. Per-coin record so\n * the substrate can dedup by `(plugin, symbol)` if a future\n * per-coin wipe lands. */\nexport const makeCoinSnapshotable = (parts: { readonly symbol: string }): SnapshotableDecl => ({\n\tkind: 'snapshotable',\n\tsubtrees: [],\n\tmissingTolerance: 'fine',\n\tpreRestore: Effect.succeed({\n\t\tkind: 'coin' as const,\n\t\tsymbol: parts.symbol,\n\t}),\n\tpostRestore: Effect.void,\n});\n"],"mappings":";;;;;AA2BA,MAAa,wBAAwB,WAA0D;CAC9F,MAAM;CACN,UAAU,CAAC;CACX,kBAAkB;CAClB,YAAY,OAAO,QAAQ;EAC1B,MAAM;EACN,QAAQ,MAAM;CACf,CAAC;CACD,aAAa,OAAO;AACrB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type-strings.mjs","names":[],"sources":["../../../src/plugins/coin/type-strings.ts"],"sourcesContent":["export const normalizeSuiAddress = (address: string): string | null => {\n\tif (!address.startsWith('0x')) return null;\n\tconst hex = address.slice(2).toLowerCase();\n\tif (!/^[0-9a-f]+$/.test(hex)) return null;\n\treturn `0x${hex.replace(/^0+/, '') || '0'}`;\n};\n\nexport const normalizeStructTypeAddress = (typeName: string): string | null => {\n\tconst parts = typeName.split('::');\n\tif (parts.length !== 3) return null;\n\tconst [address, moduleName, structName] = parts;\n\tif (address === undefined || moduleName === undefined || structName === undefined) return null;\n\tconst normalizedAddress =\n\t\tnormalizeSuiAddress(address) ?? (address.startsWith('0x') ? address : null);\n\tif (normalizedAddress === null) return null;\n\treturn `${normalizedAddress}::${moduleName}::${structName}`;\n};\n\n/** Parse the inner generic out of Sui-framework `coin::<Wrapper><INNER>`.\n * The SDK may spell the framework address as `0x2` or fully padded\n * `0x000...0002`; normalize before matching. Returns `null` if the\n * inner generic itself carries angle brackets. */\nexport const pickSuiFrameworkInnerGenericFromModule = (\n\tobjectType: string,\n\tmoduleName: string,\n\twrapperName: string,\n): string | null => {\n\tif (!objectType.endsWith('>')) return null;\n\tconst firstSep = objectType.indexOf('::');\n\tconst secondSep = objectType.indexOf('::', firstSep + 2);\n\tif (firstSep === -1 || secondSep === -1) return null;\n\tconst address = objectType.slice(0, firstSep);\n\tconst actualModuleName = objectType.slice(firstSep + 2, secondSep);\n\tconst rest = objectType.slice(secondSep + 2);\n\tif (normalizeSuiAddress(address) !== '0x2') return null;\n\tif (actualModuleName !== moduleName) return null;\n\tconst wrapperPrefix = `${wrapperName}<`;\n\tif (!rest.startsWith(wrapperPrefix)) return null;\n\tconst inner = rest.slice(wrapperPrefix.length, -1);\n\tif (inner.includes('<') || inner.includes('>')) return null;\n\tif (normalizeStructTypeAddress(inner) === null) return null;\n\treturn inner;\n};\n\nexport const pickSuiFrameworkInnerGeneric = (\n\tobjectType: string,\n\twrapperName: string,\n): string | null => pickSuiFrameworkInnerGenericFromModule(objectType, 'coin', wrapperName);\n\nexport const isSuiFrameworkObjectForCoin = (\n\tobjectType: string,\n\twrapperName: string,\n\tfullCoinType: string,\n): boolean => {\n\tconst inner = pickSuiFrameworkInnerGeneric(objectType, wrapperName);\n\tif (inner === null) return false;\n\tconst normalizedInner = normalizeStructTypeAddress(inner);\n\tconst normalizedExpected = normalizeStructTypeAddress(fullCoinType);\n\treturn (\n\t\tnormalizedInner !== null &&\n\t\tnormalizedExpected !== null &&\n\t\tnormalizedInner === normalizedExpected\n\t);\n};\n"],"mappings":";AAAA,MAAa,uBAAuB,YAAmC;
|
|
1
|
+
{"version":3,"file":"type-strings.mjs","names":[],"sources":["../../../src/plugins/coin/type-strings.ts"],"sourcesContent":["export const normalizeSuiAddress = (address: string): string | null => {\n\tif (!address.startsWith('0x')) return null;\n\tconst hex = address.slice(2).toLowerCase();\n\tif (!/^[0-9a-f]+$/.test(hex)) return null;\n\treturn `0x${hex.replace(/^0+/, '') || '0'}`;\n};\n\nexport const normalizeStructTypeAddress = (typeName: string): string | null => {\n\tconst parts = typeName.split('::');\n\tif (parts.length !== 3) return null;\n\tconst [address, moduleName, structName] = parts;\n\tif (address === undefined || moduleName === undefined || structName === undefined) return null;\n\tconst normalizedAddress =\n\t\tnormalizeSuiAddress(address) ?? (address.startsWith('0x') ? address : null);\n\tif (normalizedAddress === null) return null;\n\treturn `${normalizedAddress}::${moduleName}::${structName}`;\n};\n\n/** Parse the inner generic out of Sui-framework `coin::<Wrapper><INNER>`.\n * The SDK may spell the framework address as `0x2` or fully padded\n * `0x000...0002`; normalize before matching. Returns `null` if the\n * inner generic itself carries angle brackets. */\nexport const pickSuiFrameworkInnerGenericFromModule = (\n\tobjectType: string,\n\tmoduleName: string,\n\twrapperName: string,\n): string | null => {\n\tif (!objectType.endsWith('>')) return null;\n\tconst firstSep = objectType.indexOf('::');\n\tconst secondSep = objectType.indexOf('::', firstSep + 2);\n\tif (firstSep === -1 || secondSep === -1) return null;\n\tconst address = objectType.slice(0, firstSep);\n\tconst actualModuleName = objectType.slice(firstSep + 2, secondSep);\n\tconst rest = objectType.slice(secondSep + 2);\n\tif (normalizeSuiAddress(address) !== '0x2') return null;\n\tif (actualModuleName !== moduleName) return null;\n\tconst wrapperPrefix = `${wrapperName}<`;\n\tif (!rest.startsWith(wrapperPrefix)) return null;\n\tconst inner = rest.slice(wrapperPrefix.length, -1);\n\tif (inner.includes('<') || inner.includes('>')) return null;\n\tif (normalizeStructTypeAddress(inner) === null) return null;\n\treturn inner;\n};\n\nexport const pickSuiFrameworkInnerGeneric = (\n\tobjectType: string,\n\twrapperName: string,\n): string | null => pickSuiFrameworkInnerGenericFromModule(objectType, 'coin', wrapperName);\n\nexport const isSuiFrameworkObjectForCoin = (\n\tobjectType: string,\n\twrapperName: string,\n\tfullCoinType: string,\n): boolean => {\n\tconst inner = pickSuiFrameworkInnerGeneric(objectType, wrapperName);\n\tif (inner === null) return false;\n\tconst normalizedInner = normalizeStructTypeAddress(inner);\n\tconst normalizedExpected = normalizeStructTypeAddress(fullCoinType);\n\treturn (\n\t\tnormalizedInner !== null &&\n\t\tnormalizedExpected !== null &&\n\t\tnormalizedInner === normalizedExpected\n\t);\n};\n"],"mappings":";AAAA,MAAa,uBAAuB,YAAmC;CACtE,IAAI,CAAC,QAAQ,WAAW,IAAI,GAAG,OAAO;CACtC,MAAM,MAAM,QAAQ,MAAM,CAAC,CAAC,CAAC,YAAY;CACzC,IAAI,CAAC,cAAc,KAAK,GAAG,GAAG,OAAO;CACrC,OAAO,KAAK,IAAI,QAAQ,OAAO,EAAE,KAAK;AACvC;AAEA,MAAa,8BAA8B,aAAoC;CAC9E,MAAM,QAAQ,SAAS,MAAM,IAAI;CACjC,IAAI,MAAM,WAAW,GAAG,OAAO;CAC/B,MAAM,CAAC,SAAS,YAAY,cAAc;CAC1C,IAAI,YAAY,KAAA,KAAa,eAAe,KAAA,KAAa,eAAe,KAAA,GAAW,OAAO;CAC1F,MAAM,oBACL,oBAAoB,OAAO,MAAM,QAAQ,WAAW,IAAI,IAAI,UAAU;CACvE,IAAI,sBAAsB,MAAM,OAAO;CACvC,OAAO,GAAG,kBAAkB,IAAI,WAAW,IAAI;AAChD;;;;;AAMA,MAAa,0CACZ,YACA,YACA,gBACmB;CACnB,IAAI,CAAC,WAAW,SAAS,GAAG,GAAG,OAAO;CACtC,MAAM,WAAW,WAAW,QAAQ,IAAI;CACxC,MAAM,YAAY,WAAW,QAAQ,MAAM,WAAW,CAAC;CACvD,IAAI,aAAa,MAAM,cAAc,IAAI,OAAO;CAChD,MAAM,UAAU,WAAW,MAAM,GAAG,QAAQ;CAC5C,MAAM,mBAAmB,WAAW,MAAM,WAAW,GAAG,SAAS;CACjE,MAAM,OAAO,WAAW,MAAM,YAAY,CAAC;CAC3C,IAAI,oBAAoB,OAAO,MAAM,OAAO,OAAO;CACnD,IAAI,qBAAqB,YAAY,OAAO;CAC5C,MAAM,gBAAgB,GAAG,YAAY;CACrC,IAAI,CAAC,KAAK,WAAW,aAAa,GAAG,OAAO;CAC5C,MAAM,QAAQ,KAAK,MAAM,cAAc,QAAQ,EAAE;CACjD,IAAI,MAAM,SAAS,GAAG,KAAK,MAAM,SAAS,GAAG,GAAG,OAAO;CACvD,IAAI,2BAA2B,KAAK,MAAM,MAAM,OAAO;CACvD,OAAO;AACR;AAEA,MAAa,gCACZ,YACA,gBACmB,uCAAuC,YAAY,QAAQ,WAAW;AAE1F,MAAa,+BACZ,YACA,aACA,iBACa;CACb,MAAM,QAAQ,6BAA6B,YAAY,WAAW;CAClE,IAAI,UAAU,MAAM,OAAO;CAC3B,MAAM,kBAAkB,2BAA2B,KAAK;CACxD,MAAM,qBAAqB,2BAA2B,YAAY;CAClE,OACC,oBAAoB,QACpB,uBAAuB,QACvB,oBAAoB;AAEtB"}
|