[Bug]: The CLI never verifies that the connected chain matches the selected environment
@filip-parity is already working on this.
Since Sep 14, 2026.
- Dominant language
- Solidity
- Stars
- 4
- Forks
- 2
- Avg merge
- 1d 18h
- Merged PRs (30d)
- 24
Description
Component
Other
Priority
P2
What happened?
Nothing in the CLI checks that the chain it connected to is the one the user asked for. After resolveDotnsEnvironment picks an environment and resolveRpc picks an endpoint, createReadOnlyChainContext connects and the CLI proceeds straight to contract calls. The environment's chain is never asserted against the chain's own identity. The only spec-name check anywhere is isTestnetSpecName in src/commands/bulletin.ts, and that is for the bulletin chain, not Asset Hub. Grepping for chainId, genesisHash or specName outside that file returns nothing.
Because --rpc and DOTNS_RPC override the endpoint independently of --env, an environment's contract addresses can be used against a completely different chain with no warning. The failure mode is not an error but a wrong answer: reads return whatever that chain happens to hold at those addresses, and writes go to it. This is what makes the two known bugs dangerous rather than merely broken. In #197 --env is silently ignored and the header reports the default network as though it were the one requested. In #221 an environment's addresses are stale, so calls land on addresses holding no code. In both cases a single assertion after connect would have produced a clear error instead of a confident wrong result.
Expected behavior
After connecting, the CLI compares the chain's identity against the selected environment's expected value and fails with a clear message on mismatch, naming both the expected and actual chain.
Reproduction
# previewnet's contract addresses, pointed at the Paseo V2 chain: no warning
dotns lookup owner-of game --env previewnet --rpc wss://paseo-asset-hub-next-rpc.polkadot.io
The command reports Env: Paseo Asset Hub Previewnet while every contract call goes to Paseo V2. Nothing in the output indicates the mismatch.
Additional context
The environment config has no field to check against today, so this needs one: a chain ID, a genesis hash, or both. Chain ID alone is weak here, since the deploy pipeline's own DeploymentNetwork helper maps three different environments and notes that networks can share one, so genesis hash is the stronger choice.
Related and worth folding into the same change: resolveDotnsEnvironment mutates module-level state as a side effect of resolving, via setActiveDotnsEnvironment, so anything later reading getActiveDotnsEnvironment() sees whatever was resolved last rather than what it asked for. Harmless in a one-command-per-process CLI, but packages/ui shares the module, where more than one environment can be live at once.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.