@mysten-incubation/dev-wallet@0.3.0
Minor Changes
-
b6af6d2: Devstack: thorough-review remediation pass plus follow-up cleanup round.
Highlights:
runStack({ layers })replaced byrunStack({ extendContext }). Custom context extension now
goes through a typed seam.executeSuiTxreturns a discriminated union ($kind: 'ExecutedSuccess' | 'ExecutedFailure').
On-chain failure is a value, not an error. Plugins that previously caught the failure-tag in the
error channel must dispatch on$kindinstead.- New substrate helper
signAndDispatchcompacts the
withTransactionSigner → build → sign → execute → $kind dispatchpattern across five publisher
plugins. - Supervisor module (1.8k LOC) split into 11 per-concern modules under
substrate/runtime/supervisor/. No behavior change. - New
built-in-plugin-layers.tslives inorchestrators/, notruntime/—run.tslifted into
orchestrators/similarly. Layer composition now lives at L3 only. - New L0 helper
routed-url.tsforrenderUrl/routedHostname; L3 router/hostname.ts retained
as an intra-L3 adapter. - Docker image builds now stamp ownership labels (
expectedImageOwnershipLabels); prune can reach
previously-unlabelled images. NewBuildOptions.labelson the container-runtime contract. - Sweep evicts own endpoints and surfaces remaining
ForeignNetworkHolderrather than failing
silently. - Per-app shared-stack pinning:
_per-app_stacks (e.g. shared chain-build cache) are pinned
while any app sibling is live. atomicWriteFilecleanup is now whole-pipeline (open/write/fsync/rename) viaEffect.onError,
not rename-only.cross-process-locktyped errors:StackLockTimeoutError | StackLockIoErrorin the E channel;
no moreEffect.orDie.- Plugin-domain span/log keys namespaced via per-plugin
spans.tsfiles. ChainOperationtyped seam removed (zero plugin adoption signal);ClientWithCoreApiis the
sanctioned SDK cast at plugin boundaries.- ARCHITECTURE.md / STYLE_GUIDE.md rewritten to describe current state (537→308, 894→477 lines).
- New style-enforcement tests:
l4-boundary,no-unknown-as(globs every plugin barrel),
plugin-boundary,span-attr-namespace,substrate/name-blindness.
Dead-code purge and substrate race fixes:
- Orphan modules removed (no consumers):
orchestrators/codegen/extras.ts(inlined into
runtime-composition.ts);plugins/deepbook/routable.ts+ theDEEPBOOK_ENTRYPOINTS
aggregation;plugins/sui/live-faucet-strategy.ts(suiLiveStrategy,LIVE_FAUCET_URLS,
SuiLiveNetwork,SuiLiveStrategyOptions);plugins/sui/seed-objects.ts
(SeedObjectsAccumulator,makeSeedObjectsAccumulator,SEED_OBJECTS_CAPABILITY_KEY). The sui
plugin's emitted-capability count drops from 5 to 4. plugins/walrus/faucet-strategy.ts:makeWalFaucetContributionremoved;
makeWalFaucetStrategyunaffected.orchestrators/router/index.ts: unusedSTATIC_PROVIDER_FILENAMEexport removed.plugins/sui/fork-orchestration.ts:ForkGuardedSdk<Sdk>derived type alias removed;
wrapWithForkGuardnow returnsSdkdirectly (behavior identical).- Capability-sink registration race fixed: install + finalizer wrapped in
Effect.uninterruptible
so an interrupt betweenRef.modifyandaddFinalizercannot leak the sink past scope close. - Cross-process command channel short-read fix:
readSyncmay short-return on NFS / cross-FS;
offset advances bybytesReadrather than the requested length, with a clean bail on
bytesRead <= 0. - Cross-process roster PID-recycle hazard fixed:
heartbeat/release/setIntentnow match
holders via(pid, hostname, startTime)triple via a newisOwnEntryhelper (was matching
(pid, hostname)only). - Background snapshot interrupt now awaits via
Fiber.interrupt(fiber)(was fire-and-forget
fiber.interruptUnsafe()) so a follow-up capture can't start while the previous fiber is still
insidepauseAndCommit/saveImages. - CLI restructure:
cli/main.ts(1338 LOC) split into per-verb wirings under
cli/wirings/{up,apply,snapshot,wipe,prune}.tsplus sharedbuild-verb-layers.ts/
identity.ts/config-loader.tshelpers.main.tsis now argv → identity → deps → dispatch
only (~290 LOC). - Cross-process command-channel
ack/errorrecords gain an optionalpayload: unknownfield
plumbed throughawaitCompletion.snapshot.capturenow carries the captured metadata (or
failure summary / skipped reason) on the reply directly — the CLI no longer tail-fibers
events.ndjsonfor the completion event. - Repo-wide Prettier reformat.
User-visible behavior changes (minor-bump rationale):
- Pyth types removed from the root barrel.
PythFeed,PythHandle,PythOptions,
PythPackageMember, andPythPriceFeedIdno longer re-export from
@mysten-incubation/devstack. They remain reachable via theDeepbookLocalOptions.pythfield
chain. The value helpers (pythPriceFeedId,DEEP_PRICE_FEED_ID,SUI_PRICE_FEED_ID,
USDC_PRICE_FEED_ID) are kept becauseexamples/deepbook-trader/devstack.config.tsis the
market-maker case the architecture permits. - Postgres password format changed.
derivePassword(app, stack, stackRoot)now incorporates
the stack's on-disk runtime root and an sha256 short hash. Existing dev databases created
against the previouspg-${app+stack}format will fail to authenticate on firstpg_isready
probe. Either delete the existing container (docker rm -f) and let devstack recreate it, OR
setpasswordexplicitly onPostgresServiceOptionsfor stable credentials across the upgrade.
Multi-checkout shells of the same(app, stack)now derive distinct passwords by design. - CLI argv-parse failures now exit with code 64 (
USAGE), not 1 (GENERIC). Tests / CI
scripts that pattern-match exit codes for "user error vs internal error" should treat 64 the
same way they treat the--helpexit code.--jsonmode now also emits a structured envelope
for these failures instead of plain stderr. DevstackOptions.stateDiris now honored. The field was declared on the type but silently
ignored byrunStack(onlyruntimeRootwas read). Programs that set
defineDevstack({ stateDir })previously had no effect; they now do.- CLI now honors
config.options.stateDir/defineDevstack({ stateDir }). Thedevstack
CLI loads the config best-effort before resolving identity and feeds itsstateDirinto the
runtime-root ladder. Precedence:--state-dirflag >config.options.stateDir>
$DEVSTACK_STATE_DIR><cwd>/.devstack. The--state-dirflag still wins, and no-config
verbs (prune,wipe) keep resolving without a config. setNetworkEnvnow save/restoresprocess.env.DEVSTACK_NETWORK. In-process CLI invocations
(tests, embedded use) no longer leak--networkenv state into subsequent calls. Single-process
CLI semantics are unchanged.stringifyCauserenamed toformatUnknownError. Plugins importing the substrate helper
directly need to update their import (canonical path:
substrate/runtime/format-unknown-error.ts). The function's behavior is unchanged.- Wallet endpoint constant unified.
WALLET_ENDPOINT_ALIASremoved;WALLET_ENDPOINT_KEYis
the single canonical name. All exports surface through the same module paths. EndpointEntry.wireProtocol,Endpoint.wireProtocol,ResolvedEndpoint.wireProtocol
narrowed from'http' | 'h2c' | stringto'http' | 'h2c' | 'tcp'. Persisted manifests and
projections now reject other values at decode time. Plugins emitting custom wire protocols (none
ship today) would need to extend the literal union.
dev-wallet:
DEVSTACK_WALLET_HTTP_PATH.EXECUTEremoved (devstack-side/executeendpoint deleted; the
dapp-kit / dev-wallet path bypasses it and the protocol shape didn't match the Sui Wallet
Standard).