CLI tooling for Polkadot Playground. Installed as the dot command.
curl -fsSL https://raw.githubusercontent.com/paritytech/playground-cli/main/install.sh | bashTo install a specific version:
curl -fsSL https://raw.githubusercontent.com/paritytech/playground-cli/main/install.sh | VERSION=v0.2.0 bashThe installer drops the binary into ~/.polkadot/bin/, symlinks it at ~/.local/bin/dot, appends the path to your shell rc, and then runs dot init so you can finish setup without a second command.
End-to-end first-run setup. Login and toolchain install run concurrently; account setup runs once both have completed successfully.
- Login via the Polkadot mobile app — a QR code is printed to the terminal. Scan it with the app. If you already have a session persisted in
~/.polkadot-apps/, this step is skipped. - Toolchain install —
rustup, nightly,rust-src,cdm, IPFS, andgh. Existing installs are detected and skipped. - Account setup (only if a session is available) — in order:
- Fund — if your balance on Paseo Asset Hub is below 1 PAS, Alice sends 10 PAS (testnet).
- Map —
Revive.map_accountis signed by you on the mobile app so an H160 is associated with your SS58 address. - Allow — Alice grants you 1000 transactions / 100 MB of Bulletin storage.
Flags:
-y, --yes— skip the QR login entirely. Dependencies still install, account setup is skipped (no session).
Self-update from the latest GitHub release. Detects your OS/arch, downloads the corresponding dot-<os>-<arch> asset, verifies HOME is set, and atomically replaces the running binary (write-to-staging-then-rename so the running process is never served a half-written file).
Will build and publish an app + its contracts. Currently accepts and prints its flags:
--contracts— include contract build & deploy--skip-frontend— skip frontend build & deploy--domain <name>— DNS name override (else read frompackage.json)--playground— publish to the playground registry--env <env>—testnet(default) ormainnet-y, --yes— skip interactive prompts
Planned. No behaviour yet.
pnpm install
pnpm buildCompile and install the dot binary to ~/.polkadot/bin/:
pnpm cli:installpnpm test # one-shot
pnpm test:watch # rerun on change
npx tsc --noEmit # type checkTests live alongside the code as *.test.ts. They avoid mocking so deeply that they just re-implement the code under test — real polkadot-api primitives (Enum) stay real so a variant name change is caught.
Every PR automatically publishes a dev release tagged with the branch name. Others can try it with:
curl -fsSL https://raw.githubusercontent.com/paritytech/playground-cli/main/install.sh | VERSION=dev/my-branch bashReleases are triggered by changesets. To cut a release:
- Create a changeset:
pnpm changeset - Commit the generated
.changeset/*.mdfile with your PR - On merge to
main, CI consumes the changeset, bumps the version, compiles binaries, and creates a GitHub release
Uses Biome. Checked in CI on every PR.
pnpm format # fix
pnpm format:check # check only@polkadot-apps/*are pinned tolatestintentionally — they are our own packages and we want the lockfile to track head.@polkadot-api/sdk-inkis pinned to^0.6.2andpolkadot-apito^1.23.3becausechain-clientcurrently embeds an internalPolkadotClientshape that breaks with newer versions. Bump together withchain-clientonly.
- Signer shim (
src/utils/signer.ts) — the default session signer from@polkadot-apps/terminalusessignRaw, which the Polkadot mobile app wraps with<Bytes>…</Bytes>(producing aBadProofon-chain). We delegate togetPolkadotSignerFromPjsfrompolkadot-api/pjs-signer, which formats the payload as polkadot.jsSignerPayloadJSON— exactly what the mobile'sSignPayloadJsonInteractorconsumes. This file can be removed once@polkadot-apps/terminaldefaults tosignPayload. - Connection singleton (
src/utils/connection.ts) — stores the promise (not the resolved client) so concurrent callers share a single WebSocket. Has a 30s timeout and preserves the underlying error viaError.causefor debugging. - Session lifecycle (
src/utils/auth.ts) —getSessionSigner()returns an explicitdestroy()handle. Callers MUST call it (typically from auseEffectcleanup) — the host-papp adapter keeps the Node event loop alive.