Skip to content

feat(cli): release 1.0.0 with the Polkadot environment, the protocol version check and generated release notes - #335

Merged
re-gius merged 11 commits into
mainfrom
chore/release-hardening
Oct 15, 2026
Merged

re-gius merged 11 commits into
mainfrom
chore/release-hardening

Conversation

@re-gius

@re-gius re-gius commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Description

Prepares dotns-sdk 1.0.0 for the dotNS mainnet launch. The CLI now targets Polkadot MainNet by default; pass --env paseo-v2 (or set DOTNS_ENV) for the Paseo TestNet.

Version gate. Before every read and before signing anything, account mapping included, the CLI reads the network's DotnsProtocolRegistry.protocolVersion() and proceeds only when it is exactly one of SUPPORTED_PROTOCOL_VERSIONS (0.8.0, 1.0.0). Any other declaration, none, or a failed read is refused with UnsupportedProtocolVersionError, which says which case applies. DOTNS_SKIP_VERSION_CHECK=1 bypasses the check.

Polkadot environment. --env polkadot (aliases mainnet, polkadot-asset-hub, dot) targets Polkadot Hub and the Polkadot Bulletin chain, with the address book from dotns deployments/polkadot/420420419.json. It is the default environment. QR pairing defaults to the selected environment's People relay (polkadot, paseo or preview). Content verification uses P2P (Bitswap) over the two boot nodes in the Polkadot Bulletin chain spec. No IPFS gateway is configured for Polkadot, so when P2P cannot resolve a CID the content is reported as not verified and no public gateway is probed. Read commands never sign: they no longer map a configured account, and account info reports the mapping. Mapping happens in dotns account map and before writes. Reads that take a name or address no longer need the caller's account to be mapped, since the shared dev account is unmapped on Polkadot.

devnet removed. Its deployment on Paseo Asset Hub predates tld() and protocolVersion(), so the CLI could not use it already: every command read the TLD from its registry and reverted.

Release notes. The release body contains the supported dotNS protocol releases and networks, read from the code. GitHub appends the merged pull requests, leaving out UI-only ones (.github/release.yml). No notes are currently written by hand at release time.

The UI leaves CLI releases. v* tags no longer build, attach, or deploy the UI; the previous production redeploy on every CLI tag is gone. ui-v* keeps its own deploy path, and its production gate now reads the version after the ui-v prefix, so it can open for a stable UI tag. The README marks the UI as unmaintained and unreleased.

Release hardening, mirroring dotns.

  • release.yml is read-only by default; only the release job can write, and it runs in the releases environment.
  • A guard job (tags only, read-only, no environment) refuses a tag whose commit is not on main, before any approval is requested.
  • npm-release.yml is read-only and publishes only a published, non-prerelease release created by the release workflow (github-actions[bot]), so a manual dispatch cannot bypass the approval.

CONTRIBUTING.md gains a Releasing section, and the CLI README lists the new environment variable. The CLI version is 1.0.0.

Type

  • Bug fix
  • Feature
  • Breaking change
  • Documentation
  • Chore

Package

  • @parity/dotns-cli
  • Root/monorepo
  • Documentation

Related Issues

paritytech/dotns#223

Fixes

This closes paritytech/dotns#223

Checklist

Code

  • Follows project style
  • bun run lint passes
  • bun run format passes
  • bun run typecheck passes

Documentation

  • README updated if needed
  • Types updated if needed

Breaking Changes

  • No breaking changes
  • Breaking changes documented below

Breaking changes:

  • The default network is Polkadot MainNet. Without --env or DOTNS_ENV, commands target Polkadot Hub and the Polkadot Bulletin chain, so registrations, transfers and uploads spend real DOT. Pass --env paseo-v2 (or set DOTNS_ENV=paseo-v2) for the previous default.
  • Networks must declare a supported dotNS protocol release. The CLI reads protocolVersion() before every read and before signing, and refuses a network that does not declare 0.8.0 or 1.0.0. polkadot, paseo-v2 and previewnet are unaffected. DOTNS_SKIP_VERSION_CHECK=1 bypasses the check.
  • The devnet environment is removed, from --env devnet and from DOTNS_ENVIRONMENTS / DotnsEnvironmentId in @parity/dotns-cli/core. It was already unusable with this CLI.
  • Read commands no longer map the configured account. A command that reports on the caller (for example store info) asks you to run dotns account map first when the account is unmapped.
  • bulletin verify exits non-zero when the content does not resolve; it previously always exited 0.

Testing

How to test:

  1. bun run test:unit in packages/cli: 411 tests, including the version-gate cases.
  2. bun run dev lookup owner-of e2epoolns01 --env paseo-v2: passes "Checking dotNS protocol version" against Paseo, which declares 1.0.0.
  3. bun run dev lookup name dotns (no --env): reads the Polkadot registry after the version check.

Notes

Before tagging v1.0.0: create the releases environment with a required reviewer and the "release tags" ruleset for v* (repository settings). After the release, add the breaking changes above to the GitHub release, and enable release immutability.

After the release, add the breaking changes above to the GitHub release, starting with the MainNet default.

@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

CI Summary

Check Result
Lint Passed
Lint (UI) Passed
Format Passed
Format (UI) Passed
Typecheck Passed
Typecheck (UI) Passed
Build Passed
Build (UI) Passed
Release Passed
Deploy UI Passed
Deploy Example Passed
Benchmark UI Failed
PR Title Passed
Labels Passed
Test Passed - 417 passed, 0 failed

Release - Passed

Test this PR

Download artifact (GitHub CLI required):

gh run download 38704536322 -n cli-release-0.0.0-pr.335 -R paritytech/dotns-sdk

Install globally:

npm install -g ./parity-dotns-cli-0.0.0-pr.335.tgz

Verify:

dotns --help
Deploy UI — Passed
Stage Status
✓ Build Build succeeded
✓ Deploy Deployed (cached)
Property Value
Domain pr335.dotns.dot
CID bafybeibqqjqtdj4pawnz3psipweibsnwj4ivj3is2ekv2lxlurierphbay (cached)
URL (dot.li) https://pr335.dotns.dot.li
URL (paseo.li) https://pr335.dotns.paseo.li
URL (direct) https://pr335.dotns.dot

View run

Deploy Example — Passed
Stage Status
✓ Site validation Site validated
✓ Deploy Deployed (cached)
Property Value
Domain pr335.dotns-example-site.dot
CID bafybeicx555prsudvmqsdrap7keoilryrudwycdx3ody2rejwqwjwp52u4 (cached)
URL (dot.li) https://pr335.dotns-example-site.dot.li
URL (paseo.li) https://pr335.dotns-example-site.paseo.li
URL (direct) https://pr335.dotns-example-site.dot
Duration 41s

View run

Benchmark UI - Failed (0s)
Property Value
Duration 0s
Domain n/a
CID n/a
Workflow view
Labels

pkg: cli, scope: bulletin, type: docs, type: test, dependencies

Test - Passed

417 passed, 0 failed across 417 tests.

View run

$ bun test tests/unit/
bun test v1.2.6 (8ebd5d53)

::group::tests/unit/store/storeHelp.test.ts:
(pass) store --help lists subcommands [14.00ms]
(pass) store claim --help shows description and auth options [3.00ms]
(pass) store info --help shows auth options [2.00ms]
(pass) store list --help shows options [3.00ms]
(pass) store get --help shows key argument [2.00ms]
(pass) store set --help shows key and value arguments with auth [2.00ms]
(pass) store delete --help shows key argument with auth [2.00ms]

::endgroup::

::group::tests/unit/inspect/prechecks.test.ts:
(pass) releaseName refuses before the approve > a name that is not registered [4.00ms]
(pass) releaseName refuses before the approve > a subname or device name, which has no registrar token [1.00ms]
(pass) releaseName refuses before the approve > a soulbound personhood name
(pass) releaseName refuses before the approve > a failed soulbound read, which aborts the release [1.00ms]
(pass) releaseName refuses before the approve > a name with no escrow position
(pass) releaseName refuses before the approve > a name already released, saying until when the holder may redeem [1.00ms]
(pass) releaseName refuses before the approve > a released name whose deposit was withdrawn, saying nobody can redeem it
(pass) releaseName refuses before the approve > a name owned by another account
(pass) releaseName refuses before the approve > otherwise approves the escrow and then releases
(pass) transferName refuses before the write > a subname or device name, which has no registrar token [1.00ms]
(pass) transferName refuses before the write > a soulbound personhood name
(pass) transferName refuses before the write > a name owned by another account
(pass) transferName refuses before the write > otherwise submits the transfer
(pass) ensureDomainNotRegistered > explains a name inside its redeem window and when registration opens [1.00ms]
(pass) ensureDomainNotRegistered > says only when registration opens once the deposit was withdrawn
(pass) ensureDomainNotRegistered > does not mention a redeem window for a held, unreleased name

::endgroup::

::group::tests/unit/utils/validation.test.ts:
(pass) normaliseLabel > lowercases, trims, and strips a single trailing .dot
(pass) normaliseLabel > strips the given TLD suffix
(pass) isSecondLevelDotName > distinguishes a second-level name from a subdomain under the given TLD
(pass) isCanonicalLabel > accepts lowercase letters, digits and internal hyphens
(pass) isCanonicalLabel > rejects dots, uppercase, spaces and other characters [1.00ms]
(pass) isCanonicalLabel > rejects leading or trailing hyphens, empty and overlong labels
(pass) isSecondLevelDotName > accepts a single label, with or without the .dot suffix
(pass) isSecondLevelDotName > rejects subdomains
(pass) validateCanonicalLabel > throws for a name containing a dot, naming the role
(pass) validateCanonicalLabel > does not throw for a canonical label
(pass) validateDomainLabel trailing digits > accepts labels with no trailing digits
(pass) validateDomainLabel trailing digits > accepts a two-digit suffix
(pass) validateDomainLabel trailing digits > accepts labels with any trailing digit count
(pass) validateDomainLabel trailing digits > rejects labels shorter than three characters
(pass) validateDomainLabel trailing digits > rejects labels with uppercase characters
(pass) validateDomainLabel trailing digits > rejects labels with leading or trailing hyphen
(pass) validateGovernanceLabel base-length rule > accepts base names of five characters or fewer
(pass) validateGovernanceLabel base-length rule > rejects base names longer than five characters
(pass) validateGovernanceLabel base-length rule > measures an ordinary label whole, digits included
(pass) validateGovernanceLabel measures the base name as PopRules does > accepts any digit count while the whole label stays within the reserved band
(pass) validateGovernanceLabel measures the base name as PopRules does > rejects once the label as written leaves the reserved band
(pass) validateGovernanceLabel measures the base name as PopRules does > the NORMAL path accepts any digit count too
(pass) validateGovernanceLabel canonical-label rules > rejects uppercase characters
(pass) validateGovernanceLabel canonical-label rules > rejects labels containing a dot
(pass) validateGovernanceLabel canonical-label rules > rejects leading or trailing hyphen
(pass) validateGovernanceLabel canonical-label rules > rejects labels shorter than three characters
(pass) isPersonhoodLabel > accepts a letters-only name
(pass) isPersonhoodLabel > rejects digits, hyphens, uppercase and the empty string
(pass) isDeviceLabel > accepts a letters-only stem, one separator and exactly two digits
(pass) isDeviceLabel > rejects a stem the gateway pallet could not have issued
(pass) isDeviceLabel > rejects any other digit count or a missing separator
(pass) baseLabelOf > drops the separator and allocated digits from a device label
(pass) baseLabelOf > measures an ordinary label whole
(pass) isSecondLevelDotName with a device name > treats a device name as a single second-level name
(pass) isSecondLevelDotName with a device name > still treats a real subname as a subdomain
(pass) device names on the registration path > validateDomainLabel refuses a device name with the gateway pallet reason
(pass) device names on the registration path > a shape the gateway pallet cannot issue still gets the charset error
(pass) validateExistingNameLabel > accepts a device name [1.00ms]
(pass) validateExistingNameLabel > accepts an ordinary label
(pass) validateExistingNameLabel > still rejects a subname and other malformed input
(pass) validateParentPath > accepts a path at the bound
(pass) validateParentPath > rejects a path one octet over the bound, naming its length
(pass) validateParentPath > accepts ordinary and device-name parents

::endgroup::

::group::tests/unit/utils/contractInteractions.test.ts:
(pass) deriveDomainNode > matches namehashUnder(tldNode, labelhash) [1.00ms]
(pass) deriveDomainNode > different TLDs yield different nodes for the same label
(pass) deriveDomainNode > folds a subname per label from the TLD node
(pass) deriveDomainNode > agrees with viem's namehash of the fully qualified name [1.00ms]
(pass) deriveDomainNode > folds a device name beneath its numeric container
(pass) deriveDomainTokenId > is uint256(node)
(pass) deriveDomainTokenId > known vector: getsome under .dot
(pass) isRevertFlag matches the EVM revert bit > flags=0n gives false
(pass) isRevertFlag matches the EVM revert bit > flags=1n gives true
(pass) isRevertFlag matches the EVM revert bit > flags=2n gives false
(pass) isRevertFlag matches the EVM revert bit > flags=3n gives true
(pass) buildRevertError > empty data names both the unmapped-origin and stale-ABI causes
(pass) buildRevertError > known ABI selector decodes to the named error [2.00ms]
(pass) buildRevertError > unknown selector falls back to raw hex [1.00ms]
(pass) decodeContractRevertError > empty data includes operation context
(pass) decodeContractRevertError > non-empty data decodes against the ABI

::endgroup::

::group::tests/unit/account/accountHelp.test.ts:
(pass) account --help lists subcommands including is-mapped and grant [3.00ms]
(pass) account is-mapped --help shows address argument and --json [2.00ms]
(pass) account grant --help shows label argument and --json [2.00ms]

::endgroup::

::group::tests/unit/delegate/delegateHelp.test.ts:
(pass) delegate --help lists set, revoke, status, records and auth options [12.00ms]
(pass) delegate records --help shows operator argument and --revoke [2.00ms]
(pass) delegate records-status --help shows operator argument and --json [2.00ms]
(pass) delegate set --help shows name and delegate arguments [2.00ms]
(pass) delegate revoke --help shows name argument [1.00ms]
(pass) delegate status --help shows name argument and --json [2.00ms]

::endgroup::

::group::tests/unit/auth/resolveAuthSourceReadOnly.test.ts:
(pass) resolveAuthSourceReadOnly honours environment variables > $label
(pass) resolveAuthSourceReadOnly honours environment variables > $label
(pass) resolveAuthSourceReadOnly honours environment variables > $label
(pass) resolveAuthSourceReadOnly honours environment variables > $label
(pass) resolveAuthSourceReadOnly honours environment variables > $label

::endgroup::

::group::tests/unit/auth/authRevert.test.ts:
(pass) auth set rejects account name with forward slash [4.00ms]
(pass) auth set rejects account name with backslash [1.00ms]
(pass) auth set rejects account name that is just a dot [1.00ms]
(pass) auth set rejects account name that is double dots [2.00ms]
(pass) auth set rejects account name starting with dot [2.00ms]
(pass) auth set rejects account name ending with dot [3.00ms]
(pass) auth set rejects account name with special characters [14.00ms]
(pass) auth set rejects account name that is too long [3.00ms]
(pass) auth use rejects non-existent account [65.00ms]
(pass) auth remove rejects non-existent account [52.00ms]

::endgroup::

::group::tests/unit/auth/authHelp.test.ts:
(pass) root help lists auth command [2.00ms]
(pass) auth help shows options and subcommands [1.00ms]
(pass) auth set help shows all options [2.00ms]
(pass) auth list help shows options [1.00ms]
(pass) auth use help shows options [1.00ms]
(pass) auth remove help shows options [1.00ms]
(pass) auth clear help shows options [1.00ms]
(pass) auth parses keystore-path option [2.00ms]
(pass) auth parses password option [1.00ms]
(pass) auth set parses account option [2.00ms]
(pass) auth set parses mnemonic option [1.00ms]
(pass) auth set parses key-uri option [1.00ms]
(pass) auth help command shows help [2.00ms]
(pass) auth help set shows set command help [2.00ms]
(pass) auth help list shows list command help [1.00ms]
(pass) auth help use shows use command help [2.00ms]
(pass) auth help remove shows remove command help [1.00ms]
(pass) auth help clear shows clear command help [2.00ms]

::endgroup::

::group::tests/unit/auth/auth.test.ts:
(pass) auth set creates keystore and stores multiple accounts [186.00ms]
(pass) auth set accepts account names with special characters [285.00ms]
(pass) auth list reports missing keystore [3.00ms]
(pass) auth list shows all accounts and auth types [190.00ms]
(pass) auth use switches default account [288.03ms]
(pass) auth remove last account clears default [50.01ms]
(pass) auth remove preserves remaining accounts and reassigns default [146.03ms]
(pass) auth clear deletes all accounts [49.01ms]
(pass) resolveAuthSource prefers selected keystore account over ambient env mnemonic [144.03ms]
(pass) resolveAuthSource resolves from env mnemonic when only the default keystore path is given
(pass) resolveAuthSource prefers selected keystore account over ambient env key URI [87.02ms]
(pass) auth set rejects weak password supplied by flag for new keystore [3.00ms]
(pass) auth set rejects weak password supplied by env for new keystore [1.00ms]
(pass) resolveAuthSource default branch carries the dev credential for the retry cache

::endgroup::

::group::tests/unit/primary/primaryHelp.test.ts:
(pass) primary --help lists set, status and auth options [2.00ms]
(pass) primary set --help shows name argument and --json [1.00ms]
(pass) primary status --help shows optional address argument and --json [1.00ms]

::endgroup::

::group::tests/unit/client/storageDepositLimit.test.ts:
(pass) computeStorageDepositLimit > floors at two whole tokens for 10 decimals
(pass) computeStorageDepositLimit > floors at two whole tokens for 12 decimals
(pass) computeStorageDepositLimit > keeps the floor when the buffered estimate is below it
(pass) computeStorageDepositLimit > uses the estimate plus 20% once it exceeds the floor
(pass) ReviveClientWrapper token info > defaults to DEFAULT_NATIVE_TOKEN_DECIMALS and DEFAULT_NATIVE_TOKEN_SYMBOL
(pass) ReviveClientWrapper token info > rejects non-integer and negative decimals
(pass) ReviveClientWrapper token info > rejects an empty symbol
(pass) ReviveClientWrapper token info > createDotnsContext reads token info from the wrapper [2.00ms]
(pass) submitTransaction storage_deposit_limit > applies the connected chain's two-token floor
(pass) submitTransaction storage_deposit_limit > derives the limit from the dry run when it exceeds the floor

::endgroup::

::group::tests/unit/client/chainTokenInfo.test.ts:
(pass) getChainTokenInfo > reads scalar properties [1.00ms]
(pass) getChainTokenInfo > reads the first entry of array properties
(pass) getChainTokenInfo > accepts decimals encoded as a digit string
(pass) getChainTokenInfo > falls back to the defaults with a warning when properties are missing
(pass) getChainTokenInfo > falls back to the default decimals for ""
(pass) getChainTokenInfo > falls back to the default decimals for null
(pass) getChainTokenInfo > falls back to the default decimals for true
(pass) getChainTokenInfo > falls back to the default decimals for -1
(pass) getChainTokenInfo > falls back to the default decimals for 1.5
(pass) getChainTokenInfo > falls back to the default decimals for "1.5"
(pass) getChainTokenInfo > falls back to the default decimals for []
(pass) getChainTokenInfo > falls back to the default symbol for an empty string

::endgroup::

::group::tests/unit/register/subnodePersist.test.ts:
(pass) registerSubnode encodes the persist flag > persists into the owner's store by default [1.00ms]
(pass) registerSubnode encodes the persist flag > skips store indexing when persist is disabled
(pass) registerSubnode bounds the parent path > rejects a parent path over the bound, before writing [1.00ms]

::endgroup::

::group::tests/unit/register/eligibility.test.ts:
(pass) getPriceAndValidateEligibility > a personhood-band name refuses a devicehood holder with the PopRules reason [1.00ms]
(pass) getPriceAndValidateEligibility > a personhood holder passes the personhood band
(pass) getPriceAndValidateEligibility > a device name is refused before any pricing read
(pass) getPriceAndValidateEligibility > a base name reserved for another account names the device-name claim [1.00ms]

::endgroup::

::group::tests/unit/register/registrationManifest.test.ts:
(pass) registration manifest persistence > saves a record and reads it back by label [43.01ms]
(pass) registration manifest persistence > stores the sealed pricing fields losslessly as decimal strings [51.01ms]
(pass) registration manifest persistence > encrypts the secret at rest (never stored in plaintext) [40.01ms]
(pass) registration manifest persistence > decrypts the secret with the correct credential [81.02ms]
(pass) registration manifest persistence > rejects decryption with the wrong credential [93.02ms]
(pass) registration manifest persistence > lists records for the env + caller, newest commit first [81.01ms]
(pass) registration manifest persistence > isolates records by env and caller [82.00ms]
(pass) registration manifest persistence > deletes a record [51.00ms]
(pass) registration manifest persistence > returns empty when nothing is cached
(pass) registration manifest persistence > clear record selection scopes to a requested label [80.00ms]
(pass) registration manifest persistence > clear record selection errors when a requested label is missing [51.00ms]
(pass) resolveManifestCredential > prefers password, then mnemonic, then key URI
(pass) resolveManifestCredential > returns null when no credential is available
(pass) resolveManifestCredential > uses env mnemonic and key URI for registration cache encryption
(pass) TLD ingested from chain > resolveTldInfo reads the deployment TLD
(pass) TLD ingested from chain > retries a transient read failure before resolving [300.00ms]
(pass) TLD ingested from chain > the immutable TLD is cached across calls
(pass) TLD ingested from chain > does not share the cache between clients that share a controller address
(pass) TLD ingested from chain > computeDomainTokenId derives the id under the chain TLD [1.00ms]
(pass) TLD ingested from chain > formatDomainName uses the deployment TLD suffix
(pass) ensureDomainNotRegistered enforces the controller predicate > passes when available(label) is true, checking available not ownerOf
(pass) ensureDomainNotRegistered enforces the controller predicate > throws with the real TLD suffix when available(label) is false

::endgroup::

::group::tests/unit/register/registerOwnerConflicts.test.ts:
(pass) register domain rejects --owner with --transfer [3.00ms]
(pass) register domain rejects --owner with --reverse [2.00ms]
(pass) register domain rejects --owner with --governance [2.00ms]

::endgroup::

::group::tests/unit/register/registerJson.test.ts:
(pass) register domain --help shows --json option [2.00ms]
(pass) register subname --help shows --json option [1.00ms]
(pass) register domain --json emits JSON error when --transfer without --to [1.00ms]

::endgroup::

::group::tests/unit/register/registerHelp.test.ts:
(pass) root help lists register command [2.00ms]
(pass) register help shows subcommands [1.00ms]
(pass) register domain help shows options [2.00ms]
(pass) register subname help shows options [2.00ms]
(pass) register domain parses reverse flag [1.00ms]
(pass) register domain parses governance flag [2.00ms]
(pass) register domain parses owner option [2.00ms]
(pass) register domain parses transfer with destination [2.00ms]
(pass) register domain parses account option [1.00ms]
(pass) register domain parses keystore-path option [2.00ms]
(pass) register domain parses password option [1.00ms]
(pass) register domain parses mnemonic option [2.00ms]
(pass) register domain parses key-uri option [2.00ms]
(pass) register domain parses commitment-buffer option [1.00ms]
(pass) register domain parses commitment-buffer alias --cb [2.00ms]
(pass) register subname parses name and parent [2.00ms]
(pass) register subname parses owner option [2.00ms]
(pass) getCommitmentBufferSeconds defaults to 6 when env is not set
(pass) getCommitmentBufferSeconds reads from DOTNS_COMMITMENT_BUFFER env variable
(pass) COMMITMENT_POLL_INTERVAL_MS is 2000
(pass) COMMITMENT_POLL_TIMEOUT_MS is 30000

::endgroup::

::group::tests/unit/pop/setPopHelp.test.ts:
(pass) root help lists pop command [2.00ms]
(pass) pop help shows commands and description [1.00ms]
(pass) pop help shows auth options [1.00ms]
(pass) pop info help shows description [1.00ms]
(pass) pop status help shows description [1.00ms]
(pass) pop info help shows auth options [1.00ms]
(pass) pop info parses auth options at pop level [2.00ms]
(pass) pop info parses auth options at info level [1.00ms]
(pass) pop help command shows pop help [1.00ms]
(pass) pop help status shows info help [1.00ms]
(pass) pop help info shows info help [2.00ms]

::endgroup::

::group::tests/unit/pop/popJson.test.ts:
(pass) pop info --help shows --json option [2.00ms]
(pass) pop status --help shows --json option [2.00ms]

::endgroup::

::group::tests/unit/lookup/lookupHelp.test.ts:
(pass) lookup --help lists subcommands and auth options [3.00ms]
(pass) lookup name --help shows label argument and options [2.00ms]
(pass) lookup owner-of --help shows label argument and options [2.00ms]
(pass) lookup transfer --help shows label argument and destination option [2.00ms]
(pass) lookup transfer parses destination at transfer level [2.00ms]
(pass) lookup transfer parses auth options at lookup level [1.00ms]

::endgroup::

::group::tests/unit/lookup/lookupNormalisation.test.ts:
(pass) lookup normalises fully-qualified names > performDomainLookup derives the same node for `alice` and `alice.paseo` [1.00ms]
(pass) lookup normalises fully-qualified names > performOwnerOfLookup derives the same node for `alice` and `alice.paseo` [1.00ms]
(pass) lookup normalises fully-qualified names > a name under a different suffix is not stripped
(pass) device names resolve at their folded subnode > a registered device name resolves as its stem beneath the numeric container
(pass) device names resolve at their folded subnode > an unregistered device name reports its folded node and no record [1.00ms]
(pass) lookup folds subnames per label > performDomainLookup queries the EIP-137 node of `blog.alice`
(pass) lookup folds subnames per label > `blog.alice` and `blog.alice.paseo` resolve to the same node
(pass) lookup folds subnames per label > performOwnerOfLookup reads the registry owner, so a subname reports its holder [1.00ms]
(pass) lookup folds subnames per label > performOwnerOfLookup reports an unregistered name as such

::endgroup::

::group::tests/unit/escrow/escrowHelp.test.ts:
(pass) root help lists escrow command [3.00ms]
(pass) escrow help shows the subcommand description and subcommands [1.00ms]
(pass) escrow balance help describes the claimable pull-payment balance [1.00ms]
(pass) escrow positions help describes the list and total [2.00ms]
(pass) escrow status help describes the read-only position lookup [1.00ms]
(pass) escrow release help describes the approve-and-release sequence [2.00ms]
(pass) escrow redeem help describes taking a released name back [1.00ms]
(pass) escrow withdraw help describes the post-cooldown step [1.00ms]
(pass) escrow claim-withdrawal help describes the overpayment ledger [1.00ms]
(pass) escrow refunds help lists list/claim/claim-batch [1.00ms]
(pass) escrow refunds list help exposes pagination options [1.00ms]
(pass) escrow refunds claim help requires an entry id positional [1.00ms]
(pass) escrow refunds claim-batch help accepts variadic ids [1.00ms]

::endgroup::

::group::tests/unit/escrow/escrowFormatting.test.ts:
(pass) formatRefundEntryLine > marks entries past their cooldown as claimable [1.00ms]
(pass) formatRefundEntryLine > marks entries inside their cooldown window with remaining seconds
(pass) formatRefundEntryLine > renders the amount in the chain's native token symbol
(pass) formatRefundEntryLine > truncates large tokenIds for terminal display
(pass) totalEscrowAmount > is zero for no positions
(pass) totalEscrowAmount > sums position amounts
(pass) isRefundableDeposit > is true only when the position holds an amount
(pass) cooldownRemainingSeconds > returns the seconds left, clamped to zero once elapsed
(pass) formatCooldown > formats seconds and minutes
(pass) formatPositionStatus > held when not released
(pass) formatPositionStatus > embeds the cooldown countdown while released and waiting
(pass) formatPositionStatus > claimable once the cooldown elapses
(pass) formatPositionStatus > claimed after withdrawal
(pass) releasePhase > held while the name is not released
(pass) releasePhase > redeemable while released, unwithdrawn and inside the window
(pass) releasePhase > awaiting when the deposit was withdrawn inside the window
(pass) releasePhase > reclaimable once the window elapses, matching the escrow's isReclaimable
(pass) formatReleasePhase > names the phase and the time it changes
(pass) formatPositionsTable > returns no lines for an empty set
(pass) formatPositionsTable > renders a header plus one aligned row per position with the phase and cooldown
(pass) pendingRefunds multi-output decode > decodes to a [ids, entries] tuple [1.00ms]
(pass) pendingRefunds multi-output decode > decodes an empty ledger to a pair of empty arrays [1.00ms]

::endgroup::

::group::tests/unit/escrow/redeem.test.ts:
(pass) redeemName refuses before the write > a name that was never released
(pass) redeemName refuses before the write > a caller who is not the previous holder [1.00ms]
(pass) redeemName refuses before the write > a closed redeem window, saying when it closed
(pass) redeemName refuses before the write > a deposit already withdrawn inside the window
(pass) redeemName refuses before the write > otherwise submits redeem for the token

::endgroup::

::group::tests/unit/cli/paseoCreate3Addresses.test.ts:
(pass) paseo-v2 uses the canonical fresh-deploy address book
(pass) previewnet shares the whole paseo-v2 book
(pass) polkadot uses its own address book

::endgroup::

::group::tests/unit/cli/bulletinRpc.test.ts:
(pass) the default environment resolves to the Polkadot bulletin RPC [1.00ms]
(pass) explicit argument wins over env var and active env
(pass) env var wins over active env config when no explicit argument
(pass) falls back to active env's bulletin RPC
(pass) throws when nothing is configured (synthetic case)
(pass) bulletin cache Asset Hub RPC uses merged CLI rpc before DOTNS_RPC
(pass) bulletin cache Asset Hub RPC uses selected environment when no rpc override exists
(pass) bulletin cache rejects custom Bulletin env override without matching target
(pass) bulletin cache accepts custom Bulletin override with explicit environment
(pass) bulletin cache custom Bulletin with DOTNS_ENV ignores stale DOTNS_RPC
(pass) bulletin cache accepts custom Bulletin override with explicit Asset Hub RPC

::endgroup::

::group::tests/unit/cli/environment.test.ts:
(pass) defaults to polkadot
(pass) accepts friendly paseo-v2 aliases
(pass) accepts polkadot aliases and selects its Asset Hub
(pass) DOTNS_ENV selects rpc and contract set
(pass) --env takes precedence over DOTNS_ENV while --rpc only overrides endpoint
(pass) printCommandHeader emits one contextual line with version, action, target and network

::endgroup::

::group::tests/unit/cli/authOptions.test.ts:
(pass) getAuthOptions resolves a global --env given before a two-level-nested command [1.00ms]
(pass) getAuthOptions lets a command-level --env override the global one
(pass) getAuthOptions resolves the --network alias from the program root
(pass) DOTNS_SIGNER applies when --signer is not passed

::endgroup::

::group::tests/unit/cli/devAccountGuard.test.ts:
(pass) assertSigningAccountConfigured > accepts every source other than the built-in default
(pass) assertSigningAccountConfigured > refuses the default source and points at the opt-in [1.00ms]
⚠  Signing with the shared public dev account that anyone can control.
(pass) assertSigningAccountConfigured > proceeds once the caller opts in
(pass) security warnings survive the --json capture > writeSecurityWarning reaches stderr from inside withCapturedConsole [76.00ms]
• Resolving account
✓ Resolving account
(pass) resolveSigningAuth > refuses when nothing but the default resolves
• Resolving account
✓ Resolving account
⚠  Signing with the shared public dev account that anyone can control.
(pass) resolveSigningAuth > reads the --allow-dev-account option
• Resolving account
✓ Resolving account
⚠  Signing with the shared public dev account that anyone can control.
(pass) resolveSigningAuth > reads DOTNS_ALLOW_DEV_ACCOUNT=1 [1.00ms]

::endgroup::

::group::tests/unit/cli/protocolVersion.test.ts:
(pass) isSupportedProtocolVersion > every listed release is supported [1.00ms]
(pass) isSupportedProtocolVersion > a network that declares nothing is not supported
(pass) isSupportedProtocolVersion > only an exact match is supported
(pass) isSupportedProtocolVersion > a malformed declaration is not supported
(pass) UnsupportedProtocolVersionError > names the declared release and the supported ones
(pass) UnsupportedProtocolVersionError > says when the network declares nothing
(pass) UnsupportedProtocolVersionError > says when the declaration could not be read, and why
(pass) UnsupportedProtocolVersionError > names a non-Error cause
(pass) enforceProtocolVersion > the escape hatch skips the check without touching the chain
(pass) readProtocolVersion > an empty or blank declaration reads as none [1.00ms]
(pass) readProtocolVersion > a padded declaration is trimmed
(pass) checkProtocolVersion > returns a supported declaration [1.00ms]
(pass) checkProtocolVersion > refuses a release outside the list, patch releases included [1.00ms]
(pass) checkProtocolVersion > a failed read is refused with its cause
(pass) assertSupportedProtocolVersion > names the CLI escape hatch, which core leaves out

::endgroup::

::group::tests/unit/cli/qrSigner.test.ts:
⚠ The QR mobile-wallet signer is experimental and still in development; expect rough edges.
(pass) createQrSigner > throws a clear error when no global WebSocket is available [1.00ms]
⚠ The QR mobile-wallet signer is experimental and still in development; expect rough edges.
Approve the signing allowance on your phone to continue.
(pass) createQrSigner > returns the SS58 origin derived from the paired signer's public key

::endgroup::

::group::tests/unit/cli/transfer.test.ts:
(pass) resolveTransferRecipient > returns a raw EVM address in checksummed form without touching the chain
(pass) resolveTransferRecipient > rejects input that is neither an EVM address, SS58 address, nor domain name

::endgroup::

::group::tests/unit/cli/assertExpectedChain.test.ts:
(pass) assertExpectedChain > passes when the chain reports the environment's genesis [1.00ms]
(pass) assertExpectedChain > fails naming both chains on a mismatch
(pass) assertExpectedChain > polkadot refuses a Paseo endpoint
(pass) assertExpectedChain > hash comparison is case-insensitive
(pass) assertExpectedChain > a null pinned hash skips the check
(pass) assertExpectedChain > a bulletin mismatch points at the bulletin knobs
(pass) assertExpectedChain > the escape hatch bypasses the check
(pass) assertExpectedChain > a known chain is named in the error alongside its hash
(pass) assertExpectedChain > the bulletin connection is checked against the bulletin genesis
(pass) assertExpectedChain > the caller can inject the environment

::endgroup::

::group::tests/unit/cli/dotliViewUrls.test.ts:
(pass) paseo-v2 emits only its paseo.li gateway
(pass) previewnet emits no dot.li gateway
(pass) polkadot emits only its dot.li gateway
(pass) passes the label through unchanged, so the TLD is never duplicated

::endgroup::

::group::tests/unit/cli/transferRecipient.test.ts:
(pass) resolveTransferRecipient with a name > a device name resolves to the registry owner of its folded node
(pass) resolveTransferRecipient with a name > an ordinary label resolves through the same registry read
(pass) resolveTransferRecipient with a name > an unregistered name reports it has no owner

::endgroup::

::group::tests/unit/cli/signerKind.test.ts:
(pass) resolveSignerKind > defaults to keystore
(pass) resolveSignerKind > reads DOTNS_SIGNER=qr
(pass) resolveSignerKind > an explicit flag overrides the env var
(pass) resolveSignerKind > an unknown value falls back to keystore
(pass) resolveQrAppId > defaults to the unified product id
(pass) resolveQrAppId > flag beats env beats default
(pass) resolveQrPeopleEndpoints > defaults to the relay of the selected environment
(pass) resolveQrPeopleEndpoints > resolves named stages
(pass) resolveQrPeopleEndpoints > treats a non-stage value as a comma-separated wss list
(pass) resolveQrPeopleEndpoints > rejects a non-wss URL
(pass) resolveQrPeopleEndpoints > rejects an empty/blank value
(pass) resolveQrPeopleEndpoints > rejects a wss URL with embedded credentials
(pass) resolveQrPeopleEndpoints > flag beats env beats default [1.00ms]
(pass) assertSignerOptions > keystore signer allows local-account flags
(pass) assertSignerOptions > qr signer with no local flags is allowed
(pass) assertSignerOptions > qr signer rejects a local-account flag
(pass) assertSignerOptions > qr signer lists every conflicting flag
(pass) assertSignerOptions > qr from env is also guarded
(pass) assertSignerOptions > qr signer rejects a keystore secret supplied via env

::endgroup::

::group::tests/unit/content/contentJson.test.ts:
(pass) content view --help shows --json option [2.00ms]
(pass) content set --help shows --json option [1.00ms]
(pass) content set --json emits JSON error when both mnemonic and key-uri provided [1.00ms]

::endgroup::

::group::tests/unit/content/contentHelp.test.ts:
result:  {
  exitCode: 0,
  standardOutput: "Usage: dotns content [options] [command]\n\nManage domain content hashes\n\nOptions:\n  --env <environment>            dotNS environment: polkadot (default), paseo-v2\n                                 or previewnet (env: DOTNS_ENV)\n  --network <environment>        Alias for --env\n  --rpc <wsUrl>                  WebSocket RPC endpoint (env: DOTNS_RPC)\n  --keystore-path <path>         Keystore path (env: DOTNS_KEYSTORE_PATH)\n  --account <name>               Keystore account name (default: keystore\n                                 default)\n  --password <pw>                Keystore password (env:\n                                 DOTNS_KEYSTORE_PASSWORD)\n  -m, --mnemonic <phrase>        BIP39 mnemonic phrase (env: DOTNS_MNEMONIC)\n  -k, --key-uri <uri>            Substrate key URI (env: DOTNS_KEY_URI)\n  --signer <kind>                Signer: keystore (default) or qr [experimental]\n                                 (env: DOTNS_SIGNER)\n  --qr-app-id <id>               App id for QR pairing (env: DOTNS_QR_APP_ID)\n  --qr-people-rpc <stageOrUrls>  QR pairing relay: polkadot|paseo|preview|stable\n                                 or wss URLs (env: DOTNS_QR_PEOPLE_RPC)\n  --qr-fresh                     Force a fresh QR pairing, ignoring any cached\n                                 session\n  --allow-dev-account            Sign with the shared public dev account when no\n                                 auth is configured (env:\n                                 DOTNS_ALLOW_DEV_ACCOUNT)\n  -h, --help                     display help for command\n\nCommands:\n  view [options] <name>          View domain content hash\n  set [options] <name> <cid>     Set domain content hash (IPFS CID)\n  help [command]                 display help for command\n",
  standardError: "",
  combinedOutput: "Usage: dotns content [options] [command]\n\nManage domain content hashes\n\nOptions:\n  --env <environment>            dotNS environment: polkadot (default), paseo-v2\n                                 or previewnet (env: DOTNS_ENV)\n  --network <environment>        Alias for --env\n  --rpc <wsUrl>                  WebSocket RPC endpoint (env: DOTNS_RPC)\n  --keystore-path <path>         Keystore path (env: DOTNS_KEYSTORE_PATH)\n  --account <name>               Keystore account name (default: keystore\n                                 default)\n  --password <pw>                Keystore password (env:\n                                 DOTNS_KEYSTORE_PASSWORD)\n  -m, --mnemonic <phrase>        BIP39 mnemonic phrase (env: DOTNS_MNEMONIC)\n  -k, --key-uri <uri>            Substrate key URI (env: DOTNS_KEY_URI)\n  --signer <kind>                Signer: keystore (default) or qr [experimental]\n                                 (env: DOTNS_SIGNER)\n  --qr-app-id <id>               App id for QR pairing (env: DOTNS_QR_APP_ID)\n  --qr-people-rpc <stageOrUrls>  QR pairing relay: polkadot|paseo|preview|stable\n                                 or wss URLs (env: DOTNS_QR_PEOPLE_RPC)\n  --qr-fresh                     Force a fresh QR pairing, ignoring any cached\n                                 session\n  --allow-dev-account            Sign with the shared public dev account when no\n                                 auth is configured (env:\n                                 DOTNS_ALLOW_DEV_ACCOUNT)\n  -h, --help                     display help for command\n\nCommands:\n  view [options] <name>          View domain content hash\n  set [options] <name> <cid>     Set domain content hash (IPFS CID)\n  help [command]                 display help for command\n",
}
(pass) content --help lists subcommands and auth options [2.00ms]
(pass) content view --help shows name argument and options [1.00ms]
(pass) content set --help shows name and cid arguments [1.00ms]

::endgroup::

::group::tests/unit/bulletin/bulletinAuthorizer.test.ts:
(pass) bulletin authorizer default > defaults to //Eve, the seeded AllowedAuthorizers account [1.00ms]
(pass) bulletin authorizer default > is distinct from the sudo key, which stays //Alice
(pass) warnIfDevKeyOnTestnet > warns when the default authorizer is used against previewnet
(pass) warnIfDevKeyOnTestnet > warns when the default authorizer is used against polkadot
(pass) warnIfDevKeyOnTestnet > stays silent on paseo-v2 even with the default authorizer
(pass) warnIfDevKeyOnTestnet > stays silent when an explicit signer overrides the default
(pass) getPreviewUrl > returns an https preview link on the environment that has a web app
(pass) getPreviewUrl > returns null (never throws) on an environment with no web app

::endgroup::

::group::tests/unit/bulletin/bulletinCliHelp.test.ts:
(pass) root help lists bulletin command [2.00ms]
(pass) bulletin help shows commands and description [1.00ms]
(pass) bulletin upload help shows all options [2.00ms]
(pass) bulletin upload help shows default values [1.00ms]
(pass) bulletin authorize help shows all options [1.00ms]
(pass) bulletin authorize help shows default values [1.00ms]
(pass) bulletin history help shows options [1.00ms]
(pass) bulletin history:remove help shows usage [1.00ms]
(pass) bulletin history:clear help shows description [2.00ms]
(pass) bulletin help command shows bulletin help [1.00ms]
(pass) bulletin help upload shows upload help [1.00ms]
(pass) bulletin help authorize shows authorize help [1.00ms]
(pass) bulletin status help shows all options [1.00ms]
(pass) bulletin help status shows status help [1.00ms]
(pass) bulletin list alias works [1.00ms]
(pass) bulletin verify help shows usage [1.00ms]
(pass) bulletin help verify shows verify help [1.00ms]

::endgroup::

::group::tests/unit/bulletin/uploadManifest.test.ts:
(pass) upload manifest resume behavior > returns stale manifest when fingerprint does not match [2.00ms]
(pass) upload manifest resume behavior > deduplicates completed blocks by index

::endgroup::

::group::tests/unit/bulletin/verifySingleFileCid.test.ts:
(pass) polkadot verifies over the Bulletin boot nodes [1.00ms]
(pass) reports unresolved without throwing when the environment has no gateway [253.00ms]
(pass) probes no public gateway when the environment has no gateway [1.00ms]

::endgroup::

::group::tests/unit/bulletin/uploadProfiling.test.ts:
(pass) upload profiler > writes schema-complete profile report with peak aggregation [28.00ms]
(pass) upload profiler > default profile path is deterministic for a given fingerprint

::endgroup::

::group::tests/unit/text/textHelp.test.ts:
(pass) text --help lists subcommands and auth options [3.00ms]
(pass) text view --help shows name and key arguments [1.00ms]
(pass) text set --help shows name, key, and value arguments [2.00ms]

::endgroup::

::group::tests/unit/text/textJson.test.ts:
(pass) text view --help shows --json option [2.00ms]
(pass) text set --help shows --json option [2.00ms]
(pass) text set --json emits JSON error when both mnemonic and key-uri provided [1.00ms]

::endgroup::

 417 pass
 0 fail
 1076 expect() calls
Ran 417 tests across 47 files. [3.70s]

@re-gius
re-gius marked this pull request as ready for review October 8, 2026 14:00
@re-gius
re-gius requested a review from a team as a code owner October 8, 2026 14:00
@re-gius re-gius changed the title feat(cli): check the dotNS protocol version, generate release notes, stop releasing the UI feat(cli): release 1.0.0 with the Polkadot environment, the protocol version check and generated release notes Oct 14, 2026
const tokenInfo = await getChainTokenInfo(cacheClient);
assetHubTokenSymbol = tokenInfo.nativeTokenSymbol;
const clientWrapper = new ReviveClientWrapper(typedApi as any, tokenInfo);
const evmAddress = await clientWrapper.getEvmAddress(context.substrateAddress);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to enforceProtocolVersion before this?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, done in 1c2f9ee : --cache runs assertSupportedProtocolVersion before the write

? "it declares no dotNS protocol version"
: `it runs dotNS protocol ${declared}`;
super(
`This network is not supported: ${found}. This version of the SDK supports ${supported}.`,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`This network is not supported: ${found}. This version of the SDK supports ${supported}.`,
`This network is not supported: ${found}. This version of the SDK supports ${supported}. Set DOTNS_SKIP_VERSION_CHECK=1 to use it anyway.`,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

core is the SDK layer, and only the CLI reads that variable. If we'd rather keep env var names out of core, we can append the hint where the CLI catches the error instead, in enforceProtocolVersion

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Went with second option in 425907a

Comment on lines -35 to -37
export const DEVNET_ASSET_HUB_URL = "wss://asset-hub-paseo-rpc.n.dwellir.com";
export const DEVNET_BULLETIN_RPC = "wss://bulletin-paseo.tservices.es:8443";
export const DEVNET_IPFS_GATEWAY_URL = "https://devnet-ipfs.api.polkadotcommunity.foundation/ipfs";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we've dropped devnet, do we want to mention this in the PR desc or in its breaking changes?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any chance we might be using them elsewhere?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's now in the PR description, also saying it was already unused before

Comment thread CONTRIBUTING.md Outdated

## Releasing

Releases publish the CLI (`@parity/dotns-cli`) from `v*` tags. The web UI in `packages/ui` is not released.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Releases publish the CLI (`@parity/dotns-cli`) from `v*` tags. The web UI in `packages/ui` is not released.
Releases publish the CLI (`@parity/dotns-cli`) from `v*` tags. The web UI in `packages/ui` is not released with the CLI; `ui-v*` tags deploy it separately through `deploy-ui.yml`..

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied in 425907a

// exact match is: a network that declares any other release, or none, runs
// contracts this SDK was not built against.
export function isSupportedProtocolVersion(declared: string | null): declared is string {
return declared !== null && (SUPPORTED_PROTOCOL_VERSIONS as readonly string[]).includes(declared);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think here, since we are directly comparing the version string, would the cli start throwing errors even when versions known might be '1.0.0' and the deployed might be '1.0.1'?

Though the semver should ideally be considered non-breaking with only minor backward compatible fixes.

What would be impact of the unsupported version encountered in this check for us.

@re-gius re-gius Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good point. Exact match is a safe choice until we establish a clear compatibility policy for dotNS upgrades (e.g., no breaking changes listed in a patch release), so I would leave exact match for now.

name: ui-release-tarball
path: artifacts

- name: Create release body

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we not want this??

@re-gius re-gius Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intended because the UI leaves the CLI releases so v* tags no longer carry it

Comment thread packages/cli/README.md
Comment thread packages/cli/src/core/protocolVersion.ts

@GHkrishna GHkrishna left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good to me.

I think now that the mainnet becomes default netwrok if --env is not passed we can include that in the description as well as appropriate docs, possibly readme?

Comment thread packages/cli/src/cli/context.ts
@re-gius

re-gius commented Oct 15, 2026

Copy link
Copy Markdown
Collaborator Author

Overall looks good to me.

I think now that the mainnet becomes default netwrok if --env is not passed we can include that in the description as well as appropriate docs, possibly readme?

Agreed, fixed the PR description. The environment table, --help and the root README already said polkadot (default).

@re-gius re-gius removed the pkg: ui label Oct 15, 2026

@GHkrishna GHkrishna left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@GHkrishna

Copy link
Copy Markdown

Agreed, fixed the PR description. The environment table, --help and the root README already said polkadot (default).

Do we want to have this in breaking change, so it endsup in the release notes too?

@re-gius
re-gius merged commit 7267fa9 into main Oct 15, 2026
33 checks passed
@re-gius
re-gius deleted the chore/release-hardening branch October 15, 2026 08:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: The CLI and the UI cannot target mainnet: no mainnet configuration exists

3 participants