# Pop

Overview

Pop is the platform for building powerful Web3 solutions on Polkadot with Rust.

It transforms the complex landscape of Polkadot development into an effortless and powerful experience, whether you're developing a chain or smart contract. Pop is crafted to be the simplest, fastest, and most intuitive way to bring your ideas to life on Polkadot.

## Pop CLI

GitHub: <https://github.com/r0gue-io/pop-cli>

An all-in-one tool for Polkadot development.

Pop CLI provides an on-ramp for development on Polkadot by providing a simple command line interface for quickly creating, building, testing, and deploying a Polkadot solution; Polkadot chain or smart contract

Install the Pop CLI and start building:

* [Chains](https://learn.onpop.io/v/appchains)
* [Smart Contracts](https://learn.onpop.io/v/contracts)

<figure><img src="/files/w276L68pL7NLeXQcDPRY" alt="Pop CLI"><figcaption></figcaption></figure>


# Pop MCP

Pop MCP is an MCP server that exposes Pop CLI as structured tools for AI clients (contract + chain workflows). Pop CLI must be installed and working:

```bash
pop --version
```

If needed: [Install Pop CLI](/welcome/install-pop-cli)

## Install

Build from source:

```bash
git clone https://github.com/r0gue-io/pop-mcp.git
cd pop-mcp
cargo build --release
```

Server binary: `target/release/pop-mcp-server`

## Connect A Client

Pop MCP runs over stdio. You do not run the server manually. Your AI client launches it.

Pop MCP can sign transactions via `PRIVATE_KEY`. Read-only calls work without it. Use dev keys like `//Alice` and `//Bob` for local networks only.

### Claude Code (CLI)

Project scope (writes `.mcp.json` in the repo):

```bash
claude mcp add pop-mcp --scope project --env PRIVATE_KEY=//Alice -- /absolute/path/to/pop-mcp/target/release/pop-mcp-server
```

Verify:

```bash
claude mcp get pop-mcp
```

### Codex CLI

Config is stored in `~/.codex/config.toml` (or project `.codex/config.toml`).

```bash
codex mcp add pop-mcp --env PRIVATE_KEY=//Alice -- /absolute/path/to/pop-mcp/target/release/pop-mcp-server
```

Verify:

```bash
codex mcp list
```

## Try It (Prompt Workflows)

Once Pop MCP is configured, ask your AI client to do real work. You should see it call tools like `create_contract`, `up_ink_node`, `deploy_contract`, and `call_contract` on your behalf.

### Example 1: Contract quickstart (local node)

Ask:

> Create a new ink! contract project, start a local ink node, build and deploy the contract, then call a read method to show its initial state. After that, call a write method to change state and read it back.

### Example 2: Local network quickstart (relay + Asset Hub)

Ask:

> Start a local Paseo network with Asset Hub, query a couple of storage values (like balances constants and system events), then submit a small balance transfer and show the resulting events.

### Example 3: Clean shutdown

Ask:

> Clean up any nodes and networks you started.

## References

* Pop MCP repo: `https://github.com/r0gue-io/pop-mcp`
* MCP spec: `https://modelcontextprotocol.io`


# Install Pop CLI

> **Quick install (macOS/Linux with Homebrew)**
>
> ```bash
> brew install r0gue-io/pop-cli/pop
> ```
>
> Need Homebrew? Follow [Install Homebrew](#install-homebrew-if-not-installed).

## Other install options

**Using cargo-binstall** (cross-platform, downloads pre-built binaries when available):

```bash
# Install cargo-binstall if you don't have it
curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash

# Install pop-cli
cargo binstall pop-cli --locked
```

**Using Ubuntu PPA:**

```bash
sudo add-apt-repository ppa:r0gue-io/pop
sudo apt-get update
sudo apt-get install pop-cli
```

> If `add-apt-repository` is not found, install it with `sudo apt-get install software-properties-common`.

**Debian/Ubuntu** (using `.deb` package from GitHub Releases):

```bash
sudo dpkg -i pop-cli_*.deb
```

**Nix/NixOS:**

```bash
# Run directly without installing
nix run github:r0gue-io/pop-cli

# Or install to your profile
nix profile install github:r0gue-io/pop-cli
```

**Arch Linux** (using `pacman` with a `.pkg.tar.zst` from GitHub Releases):

```bash
sudo pacman -U pop-cli-*.pkg.tar.zst
```

## 1. Install Pop CLI

### 1.1 For macOS and Linux (Homebrew)

#### Install Homebrew (if not installed)

Run the official installer (more info [here](https://brew.sh)):

```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

Add Homebrew to your PATH (if the installer didn’t do it for you):

* macOS (Apple Silicon):

```bash
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$([ -x /opt/homebrew/bin/brew ] && /opt/homebrew/bin/brew shellenv)"
```

* Linux:

```bash
echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> ~/.profile
eval "$([ -x /home/linuxbrew/.linuxbrew/bin/brew ] && /home/linuxbrew/.linuxbrew/bin/brew shellenv)"
```

Verify:

```bash
brew --version
```

#### Install Pop CLI with Homebrew:

```bash
brew install r0gue-io/pop-cli/pop
```

### 1.2 Build from source (any OS)

Firstly, install Rust:

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

And now build pop-cli from source and install it:

```bash
cargo install --force --locked pop-cli
```

## 2. Set up your environment

> **Recommended next step:** Run `pop install` to set up OS packages, Rust tooling, and optional frontend dependencies.

```bash
pop install
```

> **Warning:** `pop install` may download and run external scripts when dependencies are missing, including the official installers for Homebrew, rustup, nvm, and Bun.

### Install command flags

| Flag                   | Description                                                         |
| ---------------------- | ------------------------------------------------------------------- |
| `-y`, `--skip-confirm` | Skip confirmation prompts and install everything non-interactively. |
| `-f`, `--frontend`     | Install frontend dependencies (Node.js v20+ and Bun).               |

### JSON mode

Use global `--json` for structured automation output:

```bash
pop --json install --skip-confirm
pop --json completion --shell zsh --output ~/.zsh/completions/_pop
```

JSON mode notes:

* `pop --json install` requires `-y/--skip-confirm`.
* `pop --json completion` requires a shell via positional `SHELL` or `--shell`.

### Interactive prompts

By default, `pop install` prompts you before installing OS packages and frontend dependencies. Use `-y` to skip all prompts.

### Rust toolchain setup

`pop install` installs or updates rustup, then:

* Sets the default toolchain to `stable`
* Updates Rust
* Adds the `wasm32-unknown-unknown` target
* Installs components: `cargo`, `clippy`, `rust-analyzer`, `rust-src`, `rust-std`, `rustc`, `rustfmt`

> **Compatibility notes:** Pop CLI targets ink! v6 by default in the latest releases. If you need ink! v5 support, install version `0.10.0`:
>
> ```bash
> cargo install --locked pop-cli --version 0.10.0
> ```

### Installing frontend dependencies

If you plan to use frontend templates with your chains or contracts, you can install the required frontend dependencies:

```bash
pop install -y --frontend
```

This will install:

* Node.js (v20+) via `nvm` if your current `node --version` check fails or is too old
* Bun (required for certain frontend templates like [inkathon](https://github.com/scio-labs/inkathon))

If Bun installs successfully but is not on your PATH yet, Pop CLI checks the default location at `~/.bun/bin/bun`.

These dependencies are automatically checked when you use the `--with-frontend` flag with `pop new chain` or `pop new contract`.

### Set up shell completion

Use `pop completion` to generate shell completion scripts for Bash, Zsh, Fish, PowerShell, or Elvish.

#### Usage

```bash
pop completion [SHELL] [--shell <SHELL>] [--output <PATH>]
```

#### Arguments and flags

| Argument/flag           | Description                                                                                                   |
| ----------------------- | ------------------------------------------------------------------------------------------------------------- |
| `SHELL`                 | Optional positional shell (`bash`, `zsh`, `fish`, `powershell`, `elvish`). Mutually exclusive with `--shell`. |
| `--shell <SHELL>`       | Shell to generate completions for (same values as `SHELL`).                                                   |
| `-o`, `--output <PATH>` | Write the completion script to a file instead of stdout.                                                      |

#### Behavior and defaults

* If you omit `--output`, Pop writes the completion script to stdout.
* If you pass `--output`, Pop writes the file and prints post-install steps for the selected shell.
* If you pass `--output` without a shell, Pop tries to detect the shell from `$SHELL`. If it detects one, it uses that shell and continues. If it cannot detect one and stdin is a TTY, it falls back to interactive setup. If stdin is not a TTY, it returns an error.
* In interactive setup, Pop asks you to choose a shell, suggests a default output path, and confirms before writing the file.

#### Default output paths (interactive)

| Shell        | Default path                                     |
| ------------ | ------------------------------------------------ |
| `bash`       | `~/.local/share/bash-completion/completions/pop` |
| `zsh`        | `~/.zsh/completions/_pop`                        |
| `fish`       | `~/.config/fish/completions/pop.fish`            |
| `powershell` | `~/.config/powershell/Completions/pop.ps1`       |
| `elvish`     | `~/.config/elvish/lib/pop.elv`                   |

#### Post-install steps by shell

| Shell        | Steps                                                                                                                                      |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `bash`       | Source the file once, add `source <PATH>` to `~/.bashrc`, then restart your shell.                                                         |
| `zsh`        | Add the completion directory (the parent of the output file) to `fpath`, run `autoload -Uz compinit && compinit`, then restart your shell. |
| `fish`       | Restart your shell; Fish auto-loads completions from the standard completions directory.                                                   |
| `powershell` | Ensure your PowerShell profile loads the completion file, then restart your shell.                                                         |
| `elvish`     | Ensure your Elvish config loads the completion file, then restart your shell.                                                              |

#### Examples

```bash
pop completion zsh --output ~/.zsh/completions/_pop
```

```bash
pop completion bash > ~/.local/share/bash-completion/completions/pop
```

```bash
pop completion --shell fish --output ~/.config/fish/completions/pop.fish
```

#### Errors and constraints

* `--output` requires a shell if `$SHELL` is not set and stdin is not a TTY.
* The output path cannot be empty.
* Interactive setup requires a resolved home directory.

## 3. Advanced details

### OS packages and behavior

If your OS/distro is unsupported, `pop install` prints a warning and exits without installing OS packages or tooling.

| OS                      | Package manager | Packages installed                                                                                                                                 |
| ----------------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| macOS                   | Homebrew        | `homebrew`, `protobuf`, `openssl`, `cmake`, `rustup`                                                                                               |
| Arch (or compatible)    | `pacman`        | `curl`, `git`, `clang`, `make`, `protobuf`, `rustup`                                                                                               |
| Ubuntu (or compatible)  | `apt`           | `git`, `clang`, `curl`, `libssl-dev`, `protobuf-compiler`, `lsof`, `pkg-config`, `rustup`                                                          |
| Debian (or compatible)  | `apt`           | `git`, `clang`, `curl`, `libssl-dev`, `llvm`, `libudev-dev`, `make`, `protobuf-compiler`, `lsof`, `rustup`                                         |
| Red Hat (or compatible) | `yum`           | `gcc`, `gcc-c++`, `make`, `cmake`, `pkgconf`, `pkgconf-pkg-config`, `clang`, `curl`, `git`, `openssl-devel`, `protobuf-compiler`, `lsof`, `rustup` |

When you pass `--frontend`, `pop install` also installs `unzip` on Arch, Ubuntu, and Debian. **Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Hackathon Guide

One-page hackathon guide for building chains and contracts with Pop CLI.

## Introduction

Pop CLI is an all-in-one tool for Polkadot development. It streamlines both chain and smart contract workflows so you can go from idea → demo during a hackathon.

Pop CLI simplifies development with:

* Quick initialization of development environment.
* Project scaffolding from predefined templates.
* Easy launch and management of local development networks.

> See also: [Quickstart Chain Development with Pop CLI (official Polkadot docs)](https://docs.polkadot.com/develop/toolkit/parachains/quickstart/pop-cli/)
>
> For Polkadot SDK–based chains, ensure your local toolchain is ready: [Install Polkadot SDK Dependencies](https://docs.polkadot.com/develop/parachains/install-polkadot-sdk/).

### Contract Development (ink!) <a href="#contract-development" id="contract-development"></a>

Pop CLI introduces experimental support for [ink! v6 smart contracts](https://use.ink/docs/v6) running on [PolkaVM (RISC-V)](https://github.com/paritytech/polkavm) via `pallet-revive`.

#### TL;DR Flow

```bash
# 1) Scaffold (choose provider/template interactively)
pop new contract

# 2) Build your contract
cd my-contract && pop build --release

# 3) Deploy (Pop CLI will run a local network by default; add `--url` to target a remote RPC)
pop up # `pop up --url wss://passet-hub-paseo.dotters.network`

# 4) Interact with your contract (You can secure signing via browser wallet).
pop call contract # `pop call contract  --use-wallet`
```

**Handy Links**

* [ink! docs](https://use.ink/docs/v6)
* [Launch a Chain to Paseo](https://github.com/r0gue-io/pop-docs/blob/main/pop-cli-for-appchains/guides/launch-a-chain/launch-a-chain-to-paseo.md)
* [Your first ink! smart contract](https://github.com/r0gue-io/pop-docs/blob/main/pop-cli-for-smart-contracts/guides/create-a-new-contract.md)
* [Deploy your contract](https://github.com/r0gue-io/pop-docs/blob/main/pop-cli-for-smart-contracts/guides/deploy.md)
* [Call your contract](https://github.com/r0gue-io/pop-docs/blob/main/pop-cli-for-smart-contracts/guides/call-your-contract.md)
* [Securely Sign Transactions from CLI](https://github.com/r0gue-io/pop-docs/blob/main/pop-cli-for-smart-contracts/guides/securely-sign-transactions-from-cli.md)

### Chain Development <a href="#chain-development" id="chain-development"></a>

Build and run a local chain quickly; deploy when ready.

#### TL;DR Flow

```bash
# 1) Scaffold (choose provider/template interactively)
pop new chain

# 2) Build your chain
cd my-chain && pop build --release

# 3) Run a local network (Zombienet config)
pop up network -f ./network.toml
```

Congrats! You’ve spun up a network with your chain running!

```
┌   Pop CLI : Deploy a chain
│
◇  🚀 Network launched successfully - ctrl-c to terminate
│  ⛓️ paseo-local
│       alice:
│         portal: https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:62551#/explorer
│         logs: tail -f /var/folders/vl/txnq6gdj22s9rn296z0md27w0000gn/T/zombie-c0eb16fc-5d11-4792-aced-493ef972d056/alice/alice.log
│       bob:
│         portal: https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:62555#/explorer
│         logs: tail -f /var/folders/vl/txnq6gdj22s9rn296z0md27w0000gn/T/zombie-c0eb16fc-5d11-4792-aced-493ef972d056/bob/bob.log
│  ⛓️ local_testnet: 2000
│       collator-01:
│         portal: https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:62559#/explorer
│         logs: tail -f /var/folders/vl/txnq6gdj22s9rn296z0md27w0000gn/T/zombie-c0eb16fc-5d11-4792-aced-493ef972d056/collator-01/collator-01.log
│
```

#### Other useful commands

```bash
# 4) Interact with your chain (You can secure signing via browser wallet).
pop call chain # `pop call chain  --use-wallet`

# 5) Register the rollup on Paseo or deploy using Polkadot Deployment Portal
pop up
# And follow the interactive guide:
┌   Pop CLI : Deploy a rollup
│
◆  Select your deployment method:
│  ● Polkadot Deployment Portal (https://staging.deploypolkadot.xyz)
│  ○ Register
```

**Handy Links**

* [Launch a Chain in Development](https://github.com/r0gue-io/pop-docs/blob/main/pop-cli-for-appchains/guides/launch-a-chain/running-your-chain.md)
* [Launch a Chain to Paseo](https://github.com/r0gue-io/pop-docs/blob/main/pop-cli-for-appchains/guides/launch-a-chain/launch-a-chain-to-paseo.md)
* [Deploy a chain with Polkadot Deployment Portal](https://github.com/r0gue-io/pop-docs/blob/main/pop-cli-for-appchains/guides/launch-a-chain/deploy-a-chain-polkadot-deployment-portal.md)
* [Securely Sign Transactions from CLI](https://github.com/r0gue-io/pop-docs/blob/main/pop-cli-for-appchains/guides/securely-sign-transactions-from-cli.md)

### Support & Contribute

* Questions / help? Join our [Telegram](https://web.telegram.org/k/#@pop_support)
* Follow updates on [X](https://x.com/onpopio)
* Found a *bug* or have a *feature request*? [Open an issue](https://github.com/r0gue-io/pop-cli/issues)
* *Want to contribute?* Check out open issues tagged [`good first issue`](https://github.com/r0gue-io/pop-cli/issues?q=is%3Aissue+state%3Aopen+label%3A%22good+first+issue%22)

<figure><img src="/files/w276L68pL7NLeXQcDPRY" alt="Pop CLI"><figcaption></figcaption></figure>


# Build Polkadot Smart Contracts with Rust

<figure><img src="/files/ZDfLgzkuZLNJDiJsnbpe" alt=""><figcaption></figcaption></figure>

Polkadot’s native smart contract language, [ink!](https://use.ink/), allows to create powerful decentralized solutions with Rust. Tap into Polkadot’s unmatched security, multichain composability, and seamless access to native chain features through precompiles.

* Start building with the [ink! documentation](https://use.ink/docs/).
* New to Polkadot? Explore the [Polkadot documentation](https://docs.polkadot.com/).


# Install Pop CLI

> **Quick install (macOS/Linux with Homebrew)**
>
> ```bash
> brew install r0gue-io/pop-cli/pop
> ```
>
> Need Homebrew? Follow [Install Homebrew](#install-homebrew-if-not-installed).

## Other install options

**Using cargo-binstall** (cross-platform, downloads pre-built binaries when available):

```bash
# Install cargo-binstall if you don't have it
curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash

# Install pop-cli
cargo binstall pop-cli --locked
```

**Using Ubuntu PPA:**

```bash
sudo add-apt-repository ppa:r0gue-io/pop
sudo apt-get update
sudo apt-get install pop-cli
```

> If `add-apt-repository` is not found, install it with `sudo apt-get install software-properties-common`.

**Debian/Ubuntu** (using `.deb` package from GitHub Releases):

```bash
sudo dpkg -i pop-cli_*.deb
```

**Nix/NixOS:**

```bash
# Run directly without installing
nix run github:r0gue-io/pop-cli

# Or install to your profile
nix profile install github:r0gue-io/pop-cli
```

**Arch Linux** (using `pacman` with a `.pkg.tar.zst` from GitHub Releases):

```bash
sudo pacman -U pop-cli-*.pkg.tar.zst
```

## 1. Install Pop CLI

### 1.1 For macOS and Linux (Homebrew)

#### Install Homebrew (if not installed)

Run the official installer (more info [here](https://brew.sh)):

```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

Add Homebrew to your PATH (if the installer didn’t do it for you):

* macOS (Apple Silicon):

```bash
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$([ -x /opt/homebrew/bin/brew ] && /opt/homebrew/bin/brew shellenv)"
```

* Linux:

```bash
echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> ~/.profile
eval "$([ -x /home/linuxbrew/.linuxbrew/bin/brew ] && /home/linuxbrew/.linuxbrew/bin/brew shellenv)"
```

Verify:

```bash
brew --version
```

#### Install Pop CLI with Homebrew:

```bash
brew install r0gue-io/pop-cli/pop
```

### 1.2 Build from source (any OS)

Firstly, install Rust:

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

And now build pop-cli from source and install it:

```bash
cargo install --force --locked pop-cli
```

## 2. Set up your environment

> **Recommended next step:** Run `pop install` to set up OS packages, Rust tooling, and optional frontend dependencies.

```bash
pop install
```

> **Warning:** `pop install` may download and run external scripts when dependencies are missing, including the official installers for Homebrew, rustup, nvm, and Bun.

### Install command flags

| Flag                   | Description                                                         |
| ---------------------- | ------------------------------------------------------------------- |
| `-y`, `--skip-confirm` | Skip confirmation prompts and install everything non-interactively. |
| `-f`, `--frontend`     | Install frontend dependencies (Node.js v20+ and Bun).               |

### JSON mode

Use global `--json` for structured automation output:

```bash
pop --json install --skip-confirm
pop --json completion --shell zsh --output ~/.zsh/completions/_pop
```

JSON mode notes:

* `pop --json install` requires `-y/--skip-confirm`.
* `pop --json completion` requires a shell via positional `SHELL` or `--shell`.

### Interactive prompts

By default, `pop install` prompts you before installing OS packages and frontend dependencies. Use `-y` to skip all prompts.

### Rust toolchain setup

`pop install` installs or updates rustup, then:

* Sets the default toolchain to `stable`
* Updates Rust
* Adds the `wasm32-unknown-unknown` target
* Installs components: `cargo`, `clippy`, `rust-analyzer`, `rust-src`, `rust-std`, `rustc`, `rustfmt`

> **Compatibility notes:** Pop CLI targets ink! v6 by default in the latest releases. If you need ink! v5 support, install version `0.10.0`:
>
> ```bash
> cargo install --locked pop-cli --version 0.10.0
> ```

### Installing frontend dependencies

If you plan to use frontend templates, you can install the required frontend dependencies:

```bash
pop install -y --frontend
```

This will install:

* Node.js (v20+) via `nvm` if your current `node --version` check fails or is too old
* Bun (required for certain frontend templates like [inkathon](https://github.com/scio-labs/inkathon))

If Bun installs successfully but is not on your PATH yet, Pop CLI checks the default location at `~/.bun/bin/bun`.

### Set up shell completion

Use `pop completion` to generate shell completion scripts for Bash, Zsh, Fish, PowerShell, or Elvish.

#### Usage

```bash
pop completion [SHELL] [--shell <SHELL>] [--output <PATH>]
```

#### Arguments and flags

| Argument/flag           | Description                                                                                                   |
| ----------------------- | ------------------------------------------------------------------------------------------------------------- |
| `SHELL`                 | Optional positional shell (`bash`, `zsh`, `fish`, `powershell`, `elvish`). Mutually exclusive with `--shell`. |
| `--shell <SHELL>`       | Shell to generate completions for (same values as `SHELL`).                                                   |
| `-o`, `--output <PATH>` | Write the completion script to a file instead of stdout.                                                      |

#### Behavior and defaults

* If you omit `--output`, Pop writes the completion script to stdout.
* If you pass `--output`, Pop writes the file and prints post-install steps for the selected shell.
* If you pass `--output` without a shell, Pop tries to detect the shell from `$SHELL`. If it detects one, it uses that shell and continues. If it cannot detect one and stdin is a TTY, it falls back to interactive setup. If stdin is not a TTY, it returns an error.
* In interactive setup, Pop asks you to choose a shell, suggests a default output path, and confirms before writing the file.

#### Default output paths (interactive)

| Shell        | Default path                                     |
| ------------ | ------------------------------------------------ |
| `bash`       | `~/.local/share/bash-completion/completions/pop` |
| `zsh`        | `~/.zsh/completions/_pop`                        |
| `fish`       | `~/.config/fish/completions/pop.fish`            |
| `powershell` | `~/.config/powershell/Completions/pop.ps1`       |
| `elvish`     | `~/.config/elvish/lib/pop.elv`                   |

#### Post-install steps by shell

| Shell        | Steps                                                                                                                                      |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `bash`       | Source the file once, add `source <PATH>` to `~/.bashrc`, then restart your shell.                                                         |
| `zsh`        | Add the completion directory (the parent of the output file) to `fpath`, run `autoload -Uz compinit && compinit`, then restart your shell. |
| `fish`       | Restart your shell; Fish auto-loads completions from the standard completions directory.                                                   |
| `powershell` | Ensure your PowerShell profile loads the completion file, then restart your shell.                                                         |
| `elvish`     | Ensure your Elvish config loads the completion file, then restart your shell.                                                              |

#### Examples

```bash
pop completion zsh --output ~/.zsh/completions/_pop
```

```bash
pop completion bash > ~/.local/share/bash-completion/completions/pop
```

```bash
pop completion --shell fish --output ~/.config/fish/completions/pop.fish
```

#### Errors and constraints

* `--output` requires a shell if `$SHELL` is not set and stdin is not a TTY.
* The output path cannot be empty.
* Interactive setup requires a resolved home directory.

## 3. Advanced details

### OS packages and behavior

If your OS/distro is unsupported, `pop install` prints a warning and exits without installing OS packages or tooling.

| OS                      | Package manager | Packages installed                                                                                                                                 |
| ----------------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| macOS                   | Homebrew        | `homebrew`, `protobuf`, `openssl`, `cmake`, `rustup`                                                                                               |
| Arch (or compatible)    | `pacman`        | `curl`, `git`, `clang`, `make`, `protobuf`, `rustup`                                                                                               |
| Ubuntu (or compatible)  | `apt`           | `git`, `clang`, `curl`, `libssl-dev`, `protobuf-compiler`, `lsof`, `pkg-config`, `rustup`                                                          |
| Debian (or compatible)  | `apt`           | `git`, `clang`, `curl`, `libssl-dev`, `llvm`, `libudev-dev`, `make`, `protobuf-compiler`, `lsof`, `rustup`                                         |
| Red Hat (or compatible) | `yum`           | `gcc`, `gcc-c++`, `make`, `cmake`, `pkgconf`, `pkgconf-pkg-config`, `clang`, `curl`, `git`, `openssl-devel`, `protobuf-compiler`, `lsof`, `rustup` |

When you pass `--frontend`, `pop install` also installs `unzip` on Arch, Ubuntu, and Debian.

**Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Create a new contract

Use the interactive prompt to scaffold a contract:

```bash
pop new contract
```

If you run `pop new` without a subcommand, Pop CLI prompts you to choose a project type. You can also use the top-level alias `pop n`.

## Command overview

```bash
pop new --list
pop new contract --list
pop new contract <NAME>
```

`pop new --list` prints the available chain and contract templates (based on which features are enabled) and exits. `pop new contract --list` prints only contract templates and exits.

### Command map

* `pop new` (alias: `pop n`)
* `pop new contract` (alias: `pop new c`)

## Options

| Flag                                 | Type    | Default | Description                                                           |
| ------------------------------------ | ------- | ------- | --------------------------------------------------------------------- |
| `--template`, `-t`                   | string  | prompt  | Contract template name.                                               |
| `--list`, `-l`                       | boolean | `false` | List templates and exit.                                              |
| `--with-frontend`, `-f[=<TEMPLATE>]` | string  | none    | Scaffold a frontend template. Use `=` when providing a value.         |
| `--package-manager`                  | string  | auto    | Package manager for frontend scaffolding. Requires `--with-frontend`. |

### JSON mode

Use global `--json` for non-interactive contract generation:

```bash
pop --json new contract my_erc20 --template erc20
```

JSON mode requirements:

* Contract name positional argument is required.
* `--template` is required.
* `--with-frontend` must include a value (for example `--with-frontend=typink`).
* Existing destination paths are not overwritten in JSON mode.

## Examples

```bash
# Interactive contract creation
pop new contract

# List contract templates
pop new contract --list

# Create a new contract using a template
pop new contract my_erc20 --template erc20
```

Pop CLI validates the contract name derived from your path. If it is invalid, the command stops without generating a contract.

## Adding a frontend

You can scaffold your contract with a frontend template using the `--with-frontend` flag. Pop CLI supports the following community frontend templates for contracts:

* [inkathon](https://github.com/scio-labs/inkathon) - Full-stack dApp boilerplate for ink! smart contracts
* [typink](https://github.com/dedotdev/typink) - Type-safe frontend framework for ink! contracts

### Interactive mode

The interactive prompt will ask you to select a frontend template:

```bash
pop new contract my_contract
```

If you pass `--with-frontend` without a value, Pop CLI prompts you to pick a frontend template.

### CLI mode

You can specify the frontend template directly. When you provide a value, you must use `=`:

```bash
# With default frontend template selection
pop new contract my_contract --with-frontend

# With specific frontend template
pop new contract flipper --with-frontend=typink
pop new contract my_contract --with-frontend=inkathon
```

### Frontend dependencies

Pop CLI will automatically check for required dependencies and prompt you to install them if not present:

* Node.js (version 20 or later)
* Bun (required for inkathon template)

You can also install frontend dependencies separately using:

```bash
pop install -y --frontend
```

### Package manager selection

`--package-manager` only works with `--with-frontend`. If you do not provide it, Pop CLI auto-detects in this order: `pnpm`, `bun`, `yarn`, `npm`. The `inkathon` template requires Bun, so Pop CLI ignores any other package manager you specify for `inkathon`.

## Behavior notes

* If the contract path is inside a Rust workspace, Pop CLI adds the contract to the workspace manifest.

### Running the frontend

After scaffolding your contract with a frontend, you can start the frontend development server from your generated contract folder with:

```bash
pop up frontend
```

This command starts the frontend dev server for your contract project. **Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Build

Before we compile your smart contract, make sure to take a look at what an ink! contract consists of in the [documentation](https://use.ink/docs/v6/getting-started/building-your-contract).

To build your ink! smart contract, make sure you are inside your ink! smart contract directory and run the following command:

```shell
pop build
```

or

```
pop build --release
```

## Build options

Most common flags:

| Flag                     | Description                                                                                            |
| ------------------------ | ------------------------------------------------------------------------------------------------------ |
| `PATH` / `--path <path>` | Project directory (defaults to the current directory).                                                 |
| `-r, --release`          | Build in release mode. Conflicts with `--profile`.                                                     |
| \`--profile \<debug      | release                                                                                                |
| `--features <list>`      | Comma-separated feature list.                                                                          |
| `--metadata <spec>`      | Choose the contract metadata spec (run `pop build --help` for supported values).                       |
| `--verifiable`           | Build a verifiable contract (deterministic release build). Conflicts with `--release` and `--profile`. |
| `--image <image>`        | Use a custom image for verifiable builds (requires `--verifiable`).                                    |

### JSON output

Use global `--json` for structured output in scripts:

```shell
pop --json build --path ./my_contract --profile release
```

> \[!NOTE] Verifiable builds require Docker to be running.

**Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Test

To learn how to test your ink! smart contract, from unit tests to e2e testing workflows, go checkout the [ink! testing documentation](https://use.ink/docs/v6/contract-testing/overview).

To run your ink! smart contract's unit tests, make sure you're in the directory of your contract and run the following command:

```bash
pop test
```

If you pass a single positional value and it isn't a directory, Pop treats it as a test filter and runs in the current directory:

```bash
pop test my_test_name
```

### JSON mode

Use global `--json` for structured test results:

```bash
pop --json test
```

`pop --json test --e2e` is not supported. Run E2E tests without `--json`.

Pop checks for an `ink` dependency. If it finds one, it runs contract tests. If it doesn't, Pop runs `cargo test` for non-contract projects and then checks whether the project is a chain.

To run end-to-end (e2e) tests, for which you need a blockchain running:

```bash
 pop test --e2e
```

If you want to run you e2e tests on your own local chain specify the directory path using:

```
 pop test --e2e --node ../my-chain
```

**Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Deploy

Now that we have developed our contract, tested it, we can now deploy it on a blockchain!

### Local Deployment (default)

If no `--url` is provided, Pop CLI automatically launches a local [ink-node](https://github.com/use-ink/ink-node) in the background. If you omit `--url`, Pop CLI prompts you to choose a chain endpoint and defaults to `ws://127.0.0.1:9944`. If that endpoint is not running, Pop CLI offers to start a local ink-node (and Ethereum RPC) in the background. Use `--skip-confirm` to auto-select the local endpoint and auto-start the node when needed.

```bash
pop up -p ./path-to-contract \
  --constructor <constructor_name> \
  --args <arg_1> <arg_2> ... \
  --suri //Alice \
```

* `--path`: points to the contract directory
* `--constructor`: method name (default: `new`)
* `--args`: constructor arguments
* `--value`: balance transferred to the contract (default: `0`)
* `--execute`: deploys the contract (otherwise Pop CLI runs a dry run)
* `--suri`: secret key URI (default: `//Alice`)
* No `--url`: defaults to the local endpoint and can start a local ink-node if needed
* `--use-wallet`: sign with a browser wallet (conflicts with `--suri`)
* `--upload-only`: upload without instantiating
* `--gas` and `--proof-size`: override the dry-run estimate (must be provided together)
* `--skip-build`: skip building (Pop CLI still builds if artifacts are missing)
* `--skip-confirm`: skip prompts and auto-start a local ink-node if needed

> If at anytime you need to stop the node you can do the following:
>
> 1. Find the process ID by running the following command: `lsof -i :9944`
> 2. Kill the process by running the `kill` command and passing in the ID of the process:
>    * `kill -9 3537`

> Tip: Use `pop up ink-node --detach` to keep a local node running and follow the printed `kill -9` command to shut it down.

When you have successfully deployed your contract you will get the following output:

```
pop up -p ./flipper --constructor new --args false --suri //Alice --url ws://127.0.0.1:9944

┌   Pop CLI : Deploy a smart contract
│
◐  Doing a dry run to estimate the gas...                                                                                                    
●  Gas limit Weight { ref_time: 264725731, proof_size: 16689 }
│  
◇  Contract deployed and instantiated: The Contract Address is "5CLPm1CeUvJhZ8GCDZCR7nWZ2m3XXe4X5MtAQK69zEjut36A"
│
└  Deployment complete
```

Save the `Contract Address` which you will need to interact with the contract.

### Deploy to Custom or Public Network

To deploy on a specific network, supply a `--url`:

```bash
pop up --path ./my_contract \
  --url ws://<network-endpoint> \
  --constructor <name> \
  --args <arg_1> <arg_2> \
  --suri <your-SURI-or-use-wallet> 
```

Alternatively, use `--use-wallet` to [sign via browser wallet](/contracts/guides/securely-sign-transactions-from-cli) (PolkadotJS, Talisman, SubWallet) instead of exposing private keys.

### JSON mode

Use global `--json` for structured deployment output:

```bash
pop --json up --path ./my_contract --constructor new --args false --suri //Alice --execute
```

JSON mode constraints for contract deployment:

* `--execute` is required.
* `--use-wallet` is not supported (provide `--suri`).
* `--upload-only` is not supported.

### Gas

Pop CLI performs a dry run to estimate [gas](https://use.ink/basics/gas) before deployment. If you do not pass `--execute`, Pop CLI keeps the dry run result and prompts you before deploying. To find an estimate of how much gas you will need, you can do a "dry-run" of the contract:

```
pop up --constructor new --args false --suri //Alice --dry-run
```

This will perform a dry-run via an RPC call to estimate the gas usage. It does not submit a transaction unless you confirm or pass `--execute`.

```
┌   Pop CLI : Deploy a smart contract
│
◇  Gas limit estimate: Weight { ref_time: 146346224, proof_size: 16689 }
```

You can now see the estimate and make sure your account is properly funded with that amount.

To override the estimate, provide both `--gas` and `--proof-size`:

```bash
pop up --path ./my_contract --constructor new --args false --suri //Alice \
  --gas 1000000 --proof-size 20000 --execute
```

> It is also possible to **only** upload the contract and **not** instantiate by adding `--upload-only`. More on this check out the[ ink! docs](https://use.ink/docs/v6/getting-started/deploy-your-contract).

**Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Call

The `pop call contract` command enables interaction with deployed ink! smart contracts. If you run `pop call` without a subcommand, Pop CLI uses `pop call contract` when it detects a contract project in the current directory.

### What Can You Do?

The `pop call contract` command supports three types of operations:

#### 1. Execute Messages

Submit transactions that modify contract state. These operations require signing, consume gas, and wait for on-chain finalization.

#### 2. Query Messages

Read contract state without making changes. These read-only calls require no signing, incur no gas costs, and return values instantly.

#### 3. Read Storage

Access contract storage fields directly using the storage layout. No signing required and no gas costs.

### Interactive Guidance (Recommended)

Interact with your contract **using** Pop CLI's interactive guidance by simply entering:

```shell
pop call contract
```

First, you will be prompted to select or enter your contract project path. You can type to filter the list and quickly find your desired contract. After selecting your contract, you will be prompted to choose a chain from the list or enter a custom RPC endpoint. If you want to connect to a custom RPC endpoint, select the **"Custom"** option, which allows you to manually type the chain URL.

After selecting your chain, you will be prompted to specify the deployed contract address, then select a message or storage item to call:

* **Execute a message** (function that modifies state, e.g. flip, transfer)
* **Query a message** (read-only function that returns state)
* **Read storage** (direct storage access)

After making your selection, you'll be guided through providing any required arguments and (for messages that modify state) the account to sign the transaction.

### Manual (non-interactive)

If you prefer not to use interactive prompts, you can call your contract by specifying all the required arguments directly:

#### Executing a Message

You can execute a message by specifying the contract path (or the metadata file), contract address, message name, and any arguments.

```shell
pop call contract --path ./flipper --contract 0x48550a4bb374727186c55365b7c9c0a1a31bdafe --message flip --suri //Alice --execute --url ws://localhost:9944/
```

```shell
pop call contract --path ./my_token --contract 0x48550a4bb374727186c55365b7c9c0a1a31bdafe --message transfer --args "0x1234..." "1000" --execute --url ws://localhost:9944/
```

#### Querying Messages

You can query messages by specifying the contract path, contract address, and message name. Query messages return the current value immediately without requiring transaction signing.

```shell
pop call contract --path ./flipper --contract 0x48550a4bb374727186c55365b7c9c0a1a31bdafe --message get --url ws://localhost:9944/
```

#### Reading Storage

Access contract storage fields directly using the storage layout. Storage queries return the current value immediately without requiring transaction signing. For direct storage access, pass the storage field name with `--message`.

```shell
pop call contract --path ./flipper --contract 0x48550a4bb374727186c55365b7c9c0a1a31bdafe --message value --url ws://localhost:9944/
```

### Additional Options

#### Execute vs Dry-Run

If you omit `--execute`, Pop CLI performs a dry run and returns the result without submitting a transaction. Use `--execute` to submit the call on-chain.

If you provide `--gas`, you must also provide `--proof-size`. If you do not provide them, Pop CLI estimates them during execution.

**When do you need signing?**

You need a signer only for executable messages. Read-only queries and storage reads run without signing. If you make a read-only call, Pop CLI ignores `--use-wallet` and runs without a signer.

#### Gas Estimation

Use `--dry-run` to estimate gas consumption before execution without submitting the transaction:

```shell
pop call contract --path ./flipper --contract 0x48550a4bb374727186c55365b7c9c0a1a31bdafe --message flip --dry-run --url ws://localhost:9944/
```

#### Using Wallet for Signing

You can use a browser extension wallet to sign transactions instead of providing a secret URI:

```shell
pop call contract --path ./flipper --contract 0x48550a4bb374727186c55365b7c9c0a1a31bdafe --message flip --use-wallet --url ws://localhost:9944/
```

Or use the shorthand `-w`:

```shell
pop call contract --path ./flipper --contract 0x48550a4bb374727186c55365b7c9c0a1a31bdafe --message flip -w --url ws://localhost:9944/
```

#### Storage Mapping Keys

If you read a storage map, use `--storage-mapping-key` to query a specific key. In interactive mode, leave the key blank to fetch all entries.

```shell
pop call contract --path ./flipper --contract 0x48550a4bb374727186c55365b7c9c0a1a31bdafe --message value --storage-mapping-key "0x..." --url ws://localhost:9944/
```

#### Skip Confirmation

Use `--skip-confirm` or `-y` to submit an executable message without additional prompts.

#### Exit Codes for Automation

`pop call contract` exits with a non-zero code when a call fails (for example RPC failures, bad inputs, or execution errors). This makes it safe to use in scripts and CI pipelines.

### Upcoming: JSON mode (`#993`, pending merge)

`pop call contract` is planned to support global `--json` with structured envelopes once [`#993`](https://github.com/r0gue-io/pop-cli/pull/993) merges.

Planned usage:

```shell
pop --json call contract --path ./flipper --contract 0x48550a4bb374727186c55365b7c9c0a1a31bdafe --message flip --suri //Alice --execute --url ws://localhost:9944/
```

Planned behavior:

* Interactive prompts are disabled in JSON mode; required inputs must be passed via flags.
* Errors are returned with typed codes for automation (`INVALID_INPUT`, `PROMPT_REQUIRED`, `NETWORK_ERROR`, `INTERNAL`).

#### Developer Mode

Use `--dev` for rapid testing during development. This skips gas prompts and confirmation dialogs:

```shell
pop call contract --dev --contract 0x48550a4bb374727186c55365b7c9c0a1a31bdafe --message flip --execute
```

`--dev` is deprecated (since 0.12.0) and will be removed in 0.13.0. Use `--skip-confirm` instead.

### Note on Addresses

If you're using ink! v6, contract addresses are displayed as 20-byte H160 hashes (for example, `0x48550a4bb374727186c55365b7c9c0a1a31bdafe`).

**Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Verify

Verify a smart contract by comparing a local build to a reference bundle or an on-chain deployment.

Use `pop verify` to compare a locally built contract against either a local `.contract` bundle or a deployed contract on a chain.

You can also run the command as `pop v`. Use this command in a contract project with a `Cargo.toml`. It requires the contract feature in Pop CLI (not available in chain-only builds), plus network access when verifying against a deployed contract.

## Usage

```bash
pop verify [--path <PATH> | PATH] --contract-path <FILE>
pop verify [--path <PATH> | PATH] --url <URL> --address <ADDRESS> --image <IMAGE>
```

### JSON mode

Use global `--json` for structured verification results:

```bash
pop --json verify --contract-path ./target/ink/my_contract.contract
```

## Examples

```bash
# Verify against a local .contract bundle
pop verify --contract-path ./target/ink/my_contract.contract

# Verify against a deployed contract
pop verify \
  --url ws://127.0.0.1:9944 \
  --address 5F3sa2TJ... \
  --image <IMAGE>
```

## Verification modes

`pop verify` requires one of these modes:

* Local reference: `--contract-path <FILE>`
* Deployed reference: `--url <URL> --address <ADDRESS> --image <IMAGE>`

If you omit `--contract-path`, Pop requires all three deployed flags.

## Project path resolution

Use `--path` or the positional `PATH` to point at your contract project. If you omit both, Pop uses the current directory.

## Local reference verification

When you verify against a local `.contract` bundle, Pop reads the bundle metadata to determine how it was built:

* If the bundle includes verifiable build info, Pop requires Docker to rebuild the contract.
* Otherwise, Pop checks that your local toolchain and `cargo contract` version match the bundle, then rebuilds locally.

## Deployed reference verification

When you verify a deployed contract, Pop:

* Connects to the chain at `--url` and fetches the deployed contract code hash.
* Rebuilds your local contract using the `--image` Docker image.
* Compares the rebuilt contract hash to the on-chain hash.

Only chains using the latest revive versions are guaranteed to be supported.

## Output

Pop prints a success message when verification passes:

* Local: `The contract is successfully verified ✅`
* Deployed: `The contract deployed on <URL> at address <ADDRESS> is successfully verified ✅`

## Errors and constraints

* If your workspace contains multiple contracts, verification fails. Run the command against a single contract project.
* Deployed verification fails if the chain does not support revive or the contract address is not found.
* Toolchain and `cargo contract` version mismatches will fail verification for non-verifiable bundles.


# Securely Sign Transactions from CLI

Pop CLI provides an option to securely sign transactions from the CLI. It does this by opening a signing portal allowing you to sign the transactions using your browser extension wallet.

## Example Usage: Deploying a Contract

For a full guide on deploying a contract, see [Deploy](/contracts/guides/deploy).

Normally, you would provide `--suri=<private-key>` to interact with the chain. However, this implies a potentially insecure way of handling private keys and should only be used for development accounts. For production accounts and more secure signing, Pop CLI provides the `--use-wallet` option that you can use.

Here is an example of deploying a contract using `--use-wallet`:

```bash
pop up --constructor new --args false --use-wallet
```

This will open a signing portal in your browser. Pop CLI will display the following:

```bash
◇  Wallet signing portal started at http://127.0.0.1:9090.
│
◒  Waiting for signature... Press Ctrl+C to terminate early.
```

Your browser will open a new tab with the following screen at <http://127.0.0.1:9090> (or similar if the port is already in use);

<figure><img src="/files/SubNctx2fRmJkYLIYoCW" alt="" width="450"><figcaption><p>Signing Portal Initial Open</p></figcaption></figure>

Click on the `Connect Wallet` button to connect your browser extension wallet.

<figure><img src="/files/hyGzSW9AcQmu2NNETlhs" alt="" width="450"><figcaption><p>Connect Wallet</p></figcaption></figure>

After connecting your wallet, you will have the option to choose your account and sign the transaction, and finally see the transaction details for signing. Note that for contract calls, the portal will perform a dry-run to alert you if the transaction will succeed, and also estimate the gas costs.

<figure><img src="/files/NdOU7MNKCU2E86nvvJRw" alt="" width="450"><figcaption><p>Transaction Details</p></figcaption></figure>

If the transaction will fail, the dry-run alert will change:

<figure><img src="/files/XpusSCH2Mtw0fDp6w8wy" alt="" width="450"><figcaption><p>Failing Dry Run</p></figcaption></figure>

In this case, you can expand the dry-run alert to see the error details. This example shows an error of the account not having enough funds:

<figure><img src="/files/4qt2gkc9IThlIqnNMUwC" alt="" width="450"><figcaption><p>Expanded Failing Dry Run</p></figcaption></figure>

Once ready to sign, pressing the `Submit` button will open your wallet for signature.

> ⚠️ **It is important to verify transaction details in your wallet before signing.**

<figure><img src="/files/p0elNbm7zf2NVy42dZn0" alt="" width="450"><figcaption><p>Opened Wallet for Signing</p></figcaption></figure>

Signing the transaction will show a success message in the portal. You may close the portal after signing.

After the signed transaction is received, the portal will send the transaction payload to Pop CLI, which will then submit the transaction to the chain.

```bash
◆  Signed payload received.
│
◇  Contract deployed and instantiated:
● The contract address is "5F1P99TD63qZ9bnoxrK7kuzwMWuU7kKKVJJZoVKBYoVQtQeR"
● The contract code hash is "0x9e4bbfc311f58aaffb63d7570651567d40dd76f301f601a0f0a61f3204d49e5b"
```

**Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Launch Passet Hub

Passet Hub is the temporary Asset Hub testnet for smart contract testing on Paseo. With Pop CLI, you can quickly spin up Passet Hub locally without needing to prepare network configuration files.

### Quick Start

Launch Paseo with Passet Hub:

```shell
pop up paseo -p passet-hub:9944
```

This automatically fetches the required binaries and chain-spec generators, so you can start testing your contracts in seconds.

The command will output the RPC endpoints for both Paseo and Passet Hub. Use the Passet Hub endpoint when deploying and interacting with your contracts.

### Learn More

* Learn more about Passet Hub (the temporary Asset Hub testnet) [here](https://forum.polkadot.network/t/testnets-paseo-officially-becomes-the-polkadot-testnet-temporary-passet-hub-chain-for-smart-contracts-testing/13209).

**Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Build a Polkadot Chain

<figure><img src="/files/JWbEhHZqrDTBAFQxC6je" alt=""><figcaption></figcaption></figure>

Build custom blockchain that can operate as solo chains or connect to Polkadot for shared security and interoperability, using the [Polkadot SDK](https://docs.polkadot.com/).

Start building with the [Polkadot documentation](https://docs.polkadot.com/).

**Ready to build your first chain?** [Start here!](/chains/guides/create-a-new-chain)


# Install Pop CLI

> **Quick install (macOS/Linux with Homebrew)**
>
> ```bash
> brew install r0gue-io/pop-cli/pop
> ```
>
> Need Homebrew? Follow [Install Homebrew](#install-homebrew-if-not-installed).

## Other install options

**Using cargo-binstall** (cross-platform, downloads pre-built binaries when available):

```bash
# Install cargo-binstall if you don't have it
curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash

# Install pop-cli
cargo binstall pop-cli --locked
```

**Using Ubuntu PPA:**

```bash
sudo add-apt-repository ppa:r0gue-io/pop
sudo apt-get update
sudo apt-get install pop-cli
```

> If `add-apt-repository` is not found, install it with `sudo apt-get install software-properties-common`.

**Debian/Ubuntu** (using `.deb` package from GitHub Releases):

```bash
sudo dpkg -i pop-cli_*.deb
```

**Nix/NixOS:**

```bash
# Run directly without installing
nix run github:r0gue-io/pop-cli

# Or install to your profile
nix profile install github:r0gue-io/pop-cli
```

**Arch Linux** (using `pacman` with a `.pkg.tar.zst` from GitHub Releases):

```bash
sudo pacman -U pop-cli-*.pkg.tar.zst
```

## 1. Install Pop CLI

### 1.1 For macOS and Linux (Homebrew)

#### Install Homebrew (if not installed)

Run the official installer (more info [here](https://brew.sh)):

```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

Add Homebrew to your PATH (if the installer didn’t do it for you):

* macOS (Apple Silicon):

```bash
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$([ -x /opt/homebrew/bin/brew ] && /opt/homebrew/bin/brew shellenv)"
```

* Linux:

```bash
echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> ~/.profile
eval "$([ -x /home/linuxbrew/.linuxbrew/bin/brew ] && /home/linuxbrew/.linuxbrew/bin/brew shellenv)"
```

Verify:

```bash
brew --version
```

#### Install Pop CLI with Homebrew

```bash
brew install r0gue-io/pop-cli/pop
```

### 1.2 Build from source (any OS)

Firstly, install Rust:

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

And now build pop-cli from source and install it:

```bash
cargo install --force --locked pop-cli
```

> **Note:** Pop CLI requires Rust 1.90 or later.

## 2. Set up your environment

> **Recommended next step:** Run `pop install` to set up OS packages, Rust tooling, and optional frontend dependencies.

```bash
pop install
```

> **Warning:** `pop install` may download and run external scripts when dependencies are missing, including the official installers for Homebrew, rustup, nvm, and Bun.

### Install command flags

| Flag                   | Description                                                         |
| ---------------------- | ------------------------------------------------------------------- |
| `-y`, `--skip-confirm` | Skip confirmation prompts and install everything non-interactively. |
| `-f`, `--frontend`     | Install frontend dependencies (Node.js v20+ and Bun).               |

### JSON mode

Use global `--json` for structured automation output:

```bash
pop --json install --skip-confirm
pop --json completion --shell zsh --output ~/.zsh/completions/_pop
```

JSON mode notes:

* `pop --json install` requires `-y/--skip-confirm`.
* `pop --json completion` requires a shell via positional `SHELL` or `--shell`.

### Interactive prompts

By default, `pop install` prompts you before installing OS packages and frontend dependencies. Use `-y` to skip all prompts.

### Rust toolchain setup

`pop install` installs or updates rustup, then:

* Sets the default toolchain to `stable`
* Updates Rust
* Adds the `wasm32-unknown-unknown` target
* Installs components: `cargo`, `clippy`, `rust-analyzer`, `rust-src`, `rust-std`, `rustc`, `rustfmt`

### Installing frontend dependencies

If you plan to use frontend templates, you can install the required frontend dependencies:

```bash
pop install -y --frontend
```

This will install:

* Node.js (v20+) via `nvm` if your current `node --version` check fails or is too old
* Bun (required for certain frontend templates like [inkathon](https://github.com/scio-labs/inkathon))

If Bun installs successfully but is not on your PATH yet, Pop CLI checks the default location at `~/.bun/bin/bun`.

### Set up shell completion

Use `pop completion` to generate shell completion scripts for Bash, Zsh, Fish, PowerShell, or Elvish.

#### Usage

```bash
pop completion [SHELL] [--shell <SHELL>] [--output <PATH>]
```

#### Arguments and flags

| Argument/flag           | Description                                                                                                   |
| ----------------------- | ------------------------------------------------------------------------------------------------------------- |
| `SHELL`                 | Optional positional shell (`bash`, `zsh`, `fish`, `powershell`, `elvish`). Mutually exclusive with `--shell`. |
| `--shell <SHELL>`       | Shell to generate completions for (same values as `SHELL`).                                                   |
| `-o`, `--output <PATH>` | Write the completion script to a file instead of stdout.                                                      |

#### Behavior and defaults

* If you omit `--output`, Pop writes the completion script to stdout.
* If you pass `--output`, Pop writes the file and prints post-install steps for the selected shell.
* If you pass `--output` without a shell, Pop tries to detect the shell from `$SHELL`. If it detects one, it uses that shell and continues. If it cannot detect one and stdin is a TTY, it falls back to interactive setup. If stdin is not a TTY, it returns an error.
* In interactive setup, Pop asks you to choose a shell, suggests a default output path, and confirms before writing the file.

#### Default output paths (interactive)

| Shell        | Default path                                     |
| ------------ | ------------------------------------------------ |
| `bash`       | `~/.local/share/bash-completion/completions/pop` |
| `zsh`        | `~/.zsh/completions/_pop`                        |
| `fish`       | `~/.config/fish/completions/pop.fish`            |
| `powershell` | `~/.config/powershell/Completions/pop.ps1`       |
| `elvish`     | `~/.config/elvish/lib/pop.elv`                   |

#### Post-install steps by shell

| Shell        | Steps                                                                                                                                      |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `bash`       | Source the file once, add `source <PATH>` to `~/.bashrc`, then restart your shell.                                                         |
| `zsh`        | Add the completion directory (the parent of the output file) to `fpath`, run `autoload -Uz compinit && compinit`, then restart your shell. |
| `fish`       | Restart your shell; Fish auto-loads completions from the standard completions directory.                                                   |
| `powershell` | Ensure your PowerShell profile loads the completion file, then restart your shell.                                                         |
| `elvish`     | Ensure your Elvish config loads the completion file, then restart your shell.                                                              |

#### Examples

```bash
pop completion zsh --output ~/.zsh/completions/_pop
```

```bash
pop completion bash > ~/.local/share/bash-completion/completions/pop
```

```bash
pop completion --shell fish --output ~/.config/fish/completions/pop.fish
```

#### Errors and constraints

* `--output` requires a shell if `$SHELL` is not set and stdin is not a TTY.
* The output path cannot be empty.
* Interactive setup requires a resolved home directory.

## 3. Advanced details

### OS packages and behavior

If your OS/distro is unsupported, `pop install` prints a warning and exits without installing OS packages or tooling.

| OS                      | Package manager | Packages installed                                                                                                                                 |
| ----------------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| macOS                   | Homebrew        | `homebrew`, `protobuf`, `openssl`, `cmake`, `rustup`                                                                                               |
| Arch (or compatible)    | `pacman`        | `curl`, `git`, `clang`, `make`, `protobuf`, `rustup`                                                                                               |
| Ubuntu (or compatible)  | `apt`           | `git`, `clang`, `curl`, `libssl-dev`, `protobuf-compiler`, `lsof`, `pkg-config`, `rustup`                                                          |
| Debian (or compatible)  | `apt`           | `git`, `clang`, `curl`, `libssl-dev`, `llvm`, `libudev-dev`, `make`, `protobuf-compiler`, `lsof`, `rustup`                                         |
| Red Hat (or compatible) | `yum`           | `gcc`, `gcc-c++`, `make`, `cmake`, `pkgconf`, `pkgconf-pkg-config`, `clang`, `curl`, `git`, `openssl-devel`, `protobuf-compiler`, `lsof`, `rustup` |

When you pass `--frontend`, `pop install` also installs `unzip` on Arch, Ubuntu, and Debian.

**Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Create a new chain

Use the interactive prompt to scaffold a chain:

```bash
pop new chain
```

## Templates

Available templates:

* Pop: Standard, Assets, Contracts
* OpenZeppelin: Generic Runtime Template, EVM Template
* Parity: Polkadot SDK's Parachain Template

Pop CLI validates template compatibility. Deprecated templates still appear in the prompt, but Pop CLI warns when you select them.

> Note: Some upstream template names and binaries still say "parachain", this is a Polkadot Chain.

## Options

| Flag                                 | Type    | Default             | Description                                                           |
| ------------------------------------ | ------- | ------------------- | --------------------------------------------------------------------- |
| `--template`, `-t`                   | string  | interactive default | Template name.                                                        |
| `--release-tag`, `-r`                | string  | latest              | Release tag to use for the template.                                  |
| `--symbol`, `-s`                     | string  | `UNIT`              | Token symbol.                                                         |
| `--decimals`, `-d`                   | number  | `12`                | Token decimals.                                                       |
| `--endowment`, `-e`                  | string  | `1u64 << 60`        | Initial endowment for dev accounts.                                   |
| `--verify`, `-v`                     | boolean | `false`             | Verify commit SHA when fetching license and releases.                 |
| `--list`, `-l`                       | boolean | `false`             | List templates and exit.                                              |
| `--with-frontend`, `-f[=<TEMPLATE>]` | string  | none                | Scaffold a frontend template. Use `=` when providing a value.         |
| `--package-manager`                  | string  | auto                | Package manager for frontend scaffolding. Requires `--with-frontend`. |

Token customization options (`--symbol`, `--decimals`, `--endowment`) are only supported for Pop templates and the Parity Generic template. If you pass these options for other templates, Pop CLI warns and proceeds with defaults.

### JSON mode

Use global `--json` for scripting:

```bash
pop --json new chain my-chain --template standard
```

JSON mode requirements:

* Chain name positional argument is required.
* `--with-frontend` must include a value (for example `--with-frontend=create-dot-app`).
* Existing destination paths are not overwritten in JSON mode.

### Endowment validation

`--endowment` accepts a plain integer (for example `1000000`) or a left-shift expression (`1u64 << 60`). If Pop CLI cannot parse the value, it warns and asks whether to fall back to the default endowment. If you decline, the command exits without generating a chain.

### Release and license selection

Pop CLI prints the template license before generation. It then offers the latest three releases that match the template's supported versions. If no matching releases are found and the template declares supported versions, Pop CLI exits with an error. If the template does not declare supported versions, Pop CLI warns and uses the default branch.

## Examples

```bash
# Interactive chain creation
pop new chain

# List chain templates
pop new chain --list

# Specify template explicitly
pop new chain my-chain --template r0gue-io/base-parachain

# Provide token customization in CLI mode
pop new chain my-chain --symbol DOT --decimals 10 --endowment 1000000
```

## Adding a frontend

You can scaffold your chain with a frontend template using the `--with-frontend` flag. Pop CLI supports the following community frontend template for chains:

* [create-dot-app](https://github.com/polkadot-developers/create-dot-app) - Full-stack dApp boilerplate for Polkadot chains

### Interactive mode

The interactive prompt will ask you if you want to include a frontend template:

```bash
pop new chain
```

If you choose to add a frontend, Pop CLI auto-selects the frontend template because only one exists. If you pass `--with-frontend` without a value, Pop CLI uses the same auto-selection behavior.

### CLI mode

You can specify the frontend template directly. When you provide a value, you must use `=`:

```bash
# With default frontend template selection
pop new chain my-chain --with-frontend

# With specific frontend template
pop new chain my-chain --with-frontend=create-dot-app
```

### Frontend dependencies

Pop CLI will automatically check for required dependencies and prompt you to install them if not present:

* Node.js (version 20 or later)

You can also install frontend dependencies separately using:

```bash
pop install -y --frontend
```

### Package manager selection

`--package-manager` only works with `--with-frontend`. If you do not provide it, Pop CLI auto-detects in this order: `pnpm`, `bun`, `yarn`, `npm`.

### Running the frontend

After scaffolding your chain with a frontend, you can start the frontend development server from your generated chain folder with:

```bash
pop up frontend
```

This command starts the frontend dev server for your chain project. **Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Create a new pallet

Use the interactive prompt to scaffold a pallet:

```bash
pop new pallet
```

If you run `pop new` without a subcommand, Pop CLI prompts you to choose between chain, pallet, and contract. You can also use the top-level alias `pop n`.

## Command overview

```bash
pop new pallet
pop new pallet <PATH>
pop new pallet advanced
```

## Options

| Argument/Flag         | Type   | Default        | Description                                                          |
| --------------------- | ------ | -------------- | -------------------------------------------------------------------- |
| `<PATH>`              | string | interactive    | Path or name for the pallet. If omitted, Pop CLI prompts for a path. |
| `--authors`, `-a`     | string | `Anonymous`    | Author name(s) for the pallet metadata.                              |
| `--description`, `-d` | string | `Frame Pallet` | Pallet description.                                                  |

### JSON mode

Use global `--json` for non-interactive generation:

```bash
pop --json new pallet my-pallet
```

JSON mode requirements:

* Pallet name/path is required.
* `advanced` mode must include one or more advanced flags (interactive advanced prompts are disabled).
* Existing destination paths are not overwritten in JSON mode.

## Advanced mode

Use `advanced` to unlock more customization:

```bash
pop new pallet <PATH> advanced
```

If you do not pass any advanced flags, Pop CLI runs an interactive prompt. If you pass any advanced flags, Pop CLI skips prompts and uses your inputs.

| Flag                          | Type    | Default | Description                                                                            |
| ----------------------------- | ------- | ------- | -------------------------------------------------------------------------------------- |
| `--config-common-types`, `-c` | list    | none    | Add common config types to the config trait. Pass multiple values separated by spaces. |
| `--default-config`, `-d`      | boolean | `false` | Add default config implementation (requires at least one config common type).          |
| `--storage`, `-s`             | list    | none    | Add storage items to the pallet. Pass multiple values separated by spaces.             |
| `--genesis-config`, `-g`      | boolean | `false` | Add a genesis config.                                                                  |
| `--custom-origin`, `-o`       | boolean | `false` | Add a custom origin.                                                                   |

Run `pop new pallet advanced --help` to see the available values for `--config-common-types` and `--storage`.

## Behavior notes

* If the pallet path is inside a Rust workspace, Pop CLI adds the pallet to the workspace manifest.
* Pop CLI runs `cargo fmt --all` after generation. If formatting fails, the pallet is still generated.

## Examples

```bash
# Interactive pallet creation
pop new pallet

# Create a pallet in the current directory
pop new pallet my-pallet

# Create a pallet in a nested directory
pop new pallet pallets/my-pallet

# Advanced interactive mode
pop new pallet my-pallet advanced

# Advanced non-interactive mode
pop new pallet my-pallet advanced --config-common-types runtime-origin currency --storage storage-value storage-map --default-config --genesis-config --custom-origin
```


# Build

Use `pop build` (alias: `pop b`) to build a chain node or runtime. If you need a chain spec or genesis artifacts, use `pop build spec`.

To build your chain using Pop CLI

```shell
cd my-chain
pop build
```

```
┌   Pop CLI : Building a chain
│
   Compiling parachain-template-runtime v0.1.0 (/Users/pop/src/my-chain/runtime)
   Compiling parachain-template-node v0.1.0 (/Users/pop/src/my-chain/node)
    Finished release [optimized] target(s) in 1m 20s

└  Build Completed Successfully!
```

If you are outside the project's directory, you can specify the path

```shell
pop build -p ./my-chain
```

You can also pass the project directory positionally:

```shell
pop build ../my-chain
```

## Build options

Most common flags:

| Flag                     | Description                                                                             |
| ------------------------ | --------------------------------------------------------------------------------------- |
| `PATH` / `--path <path>` | Project directory (defaults to the current directory).                                  |
| `-p, --package <name>`   | Build a specific workspace package.                                                     |
| `-r, --release`          | Build in release mode. Conflicts with `--profile`.                                      |
| \`--profile \<debug      | release                                                                                 |
| `--features <list>`      | Comma-separated feature list.                                                           |
| `--benchmark`            | Adds the `runtime-benchmarks` feature.                                                  |
| `--try-runtime`          | Adds the `try-runtime` feature.                                                         |
| `--only-runtime`         | Build only the runtime.                                                                 |
| `--deterministic`        | Build the runtime deterministically (requires Docker/Podman). Implies `--only-runtime`. |
| `--tag <image>`          | Use a specific srtool image tag (requires `--deterministic`).                           |

### JSON output

Use global `--json` for structured output in scripts and CI:

```shell
pop --json build --path ../my-chain --profile release
```

For `build spec` in JSON mode, prompts are disabled. Provide all required flags explicitly (for example `--output`, `--profile`, `--type`, `--chain`, `--protocol-id`, `--genesis-state`, `--genesis-code`, `--deterministic`, plus relay/para-id options for parachains).

> \[!NOTE] If your workspace has multiple runtime crates, Pop CLI prompts you to choose one.

If you are building the chain with the intent to onboard to a Polkadot Relay chain then you can run the following build command:

```
pop build -p ../my-chain --para_id 2000
```

This command will build your chain and generate the chain spec, the WebAssembly runtime, and generate the chain genesis state needed for registering and onboarding onto the Relay chain.

If you need to generate chain specs and genesis artifacts directly, use `pop build spec`:

```shell
pop build spec --para-id 2000 --relay paseo --genesis-state --genesis-code
```

#### Learning Resources

* 🧑‍🏫 To learn about Polkadot in general, [Polkadot.network](https://polkadot.network/) website is a good starting point.
  * ⭕ Learn more about Polkadot chains [here](https://wiki.polkadot.network/docs/learn-parachains).
* 🧑‍🔧 For technical introduction, [here](https://github.com/paritytech/polkadot-sdk#-documentation) are the Polkadot SDK documentation resources.

**Technical Support**

* [Polkadot Stack Exchange](https://polkadot.stackexchange.com/)
  * Create a question and tag it with "[`pop`](https://substrate.stackexchange.com/tags/pop/info)"
  * Share the StackExchange question in our [Pop Support Telegram channel](https://t.me/pop_support)


# Build your chain specification

Generate a plain chain specification and optional artifacts for your chain.

The chain specification ("chain spec") captures the initial state and configuration of your chain. Nodes use it to start a network or to join and sync with an existing one. With Pop CLI you can generate a plain chain spec interactively or non‑interactively, and optionally produce extra artifacts such as genesis state and wasm code, and even inject a deterministically built runtime.

## Interactive walkthrough

Run the command without arguments to be guided through all choices:

```bash
pop build spec
```

This will prompt you for key values like output file name, chain id, relay chain, chain type, protocol id, properties, whether to generate genesis files, and whether to build and inject a deterministic runtime.

> Tip: You can press Tab to accept defaults and type to filter list selections.

### What you’ll typically provide

* Output file name/path for the plain spec (default: ./chain-spec.json)
* Chain (Parachain) ID (default: 2000)
* Chain type (Development / Local / Live)
* Relay chain (paseo, westend, kusama, polkadot and their local variants)
* Protocol ID and optional properties (token symbol/decimals/SS58)
* Whether to also generate genesis state and genesis code files
* Optional: Build the runtime deterministically and inject it into the spec

## Non‑interactive usage

Prefer to skip prompts? Provide flags up front.

```bash
# Minimal example: write a plain chain spec
pop build spec -o ./chain-spec.json

# Provide basics explicitly
pop build spec -o ./chain-spec.json \
  --id 2000 \
  --type Local \
  --relay paseo \
  --protocol-id my-protocol \
  --properties "tokenSymbol=UNIT,decimals=12"

# Include build profile, features, and skip building binaries (if already built)
pop build spec -o ./chain-spec.json \
  --profile release \
  --features foo,bar \
  --skip-build

# Also generate genesis state and wasm code files alongside the spec
pop build spec -o ./chain-spec.json \
  --genesis-state \
  --genesis-code
```

### JSON mode

Use global `--json` to return a structured response:

```bash
pop --json build spec \
  --path ./ \
  --output ./chain-spec.json \
  --profile release \
  --type Local \
  --chain dev \
  --protocol-id my-protocol \
  --default-bootnode true \
  --genesis-state true \
  --genesis-code true \
  --deterministic false \
  --para-id 2000 \
  --relay paseo
```

In JSON mode, interactive prompts are disabled. Missing required flags return an error.

### Deterministic runtime build and injection (optional)

Pop CLI can build your runtime deterministically using srtool and inject the resulting wasm code into the chain spec generation flow.

```bash
# Minimal deterministic build example
pop build spec --deterministic --runtime ./runtime/mainnet

# Optionally specify the runtime package name used by srtool
# note: --package is only applicable when --deterministic is set
pop build spec --deterministic --runtime ./runtime/mainnet --package parachain-template-runtime
```

Notes about flags:

* You can now pass --runtime without --deterministic to pre-select the runtime directory for the command. This alone will not trigger a deterministic build you must add --deterministic to enable srtool.
* The --package flag is available to explicitly set the runtime package name when doing a deterministic build; if omitted, Pop CLI will infer it from the runtime directory.

## Common flags

| Flag                         | Description                                                                                                                            |
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `-p, --path <path>`          | Project directory (default: `./`).                                                                                                     |
| `-o, --output <path>`        | Output path for the plain spec. If you pass a directory or a path without `.json`, Pop CLI writes `chain-spec.json` in that directory. |
| \`--profile \<debug          | release                                                                                                                                |
| `-i, --para-id <id>`         | Parachain ID (ignored when `--is-relay` is set).                                                                                       |
| \`-t, --type \<Development   | Local                                                                                                                                  |
| `-c, --chain <value>`        | Chain spec input (dev, local, custom, or a path to an existing spec).                                                                  |
| `-R, --is-relay`             | Generate a relay chain spec (conflicts with `--para-id` and `--relay`).                                                                |
| \`-r, --relay \<paseo        | westend                                                                                                                                |
| `--id <id>`                  | Chain ID to embed in the spec.                                                                                                         |
| `-P, --protocol-id <id>`     | Protocol ID to embed in the spec.                                                                                                      |
| `--properties <kv>`          | Chain properties string, for example `tokenSymbol=UNIT,decimals=12`.                                                                   |
| \`-S, --genesis-state \<true | false>\`                                                                                                                               |
| \`-C, --genesis-code \<true  | false>\`                                                                                                                               |
| \`-d, --deterministic \<true | false>\`                                                                                                                               |
| `--runtime <path>`           | Runtime directory to use for builds and presets.                                                                                       |
| `--package <name>`           | Runtime package name (requires `--deterministic`).                                                                                     |
| `--raw`                      | Generate a raw chain spec.                                                                                                             |

## Behavior notes

* If `--chain` points to an existing spec file, Pop CLI uses that file as the output path and asks if you want to apply changes.
* `--skip-build` is ignored when node/runtime artifacts are missing. Pop CLI warns and builds anyway.
* `--deterministic` only runs when you enable it explicitly or choose it in the prompt. For `production` builds, the prompt defaults to deterministic.
* `--raw` is generated automatically when you request genesis state or genesis code.
* When you pass `--runtime`, Pop CLI treats the runtime directory as the build target and prompts you to pick a runtime preset if you did not pass `--chain`.

> \[!TIP] Omni-node-based chains: If your chain uses the community `polkadot-omni-node` host (ships only a runtime), you can still use `pop build spec` the same way. Deterministic builds are recommended; Pop can also auto-source the `polkadot-omni-node` binary when needed in related workflows.

## Outputs

Depending on the flags used you’ll get:

* A plain chain spec JSON.
* Optionally, a raw chain spec JSON.
* Optionally, a genesis state file.
* Optionally, a genesis wasm code file.

#### Learning Resources

* 🧑‍🏫 Background on Polkadot/Parachains: wiki.polkadot.network
* 🧑‍🔧 srtool: <https://github.com/paritytech/srtool>

**Need help?**

Ask on Polkadot Stack Exchange (tag it `pop`) or drop by our Telegram: <https://t.me/onpopio>. We're here to help!


# Build your runtime deterministically

The following guide shows how to build deterministic runtimes.

> Note: Omni-node-based chains typically ship only a runtime and rely on the community `polkadot-omni-node` host. In that setup, building your runtime deterministically is especially important since there is no bespoke node binary — the runtime is the source of truth. Pop can automatically source `polkadot-omni-node` when needed.

By default, the Rust compiler generates optimized Wasm binaries, but they aren't always deterministically reproducible. If the Wasm runtime isn't deterministic, each build might produce slightly different bytecode, This can be a problem for blockchain networks where every node must run the exact same runtime.

To ensure deterministic Substrate runtime builds, Pop CLI integrates [SRTool (Substrate Runtime Toolbox)](https://github.com/paritytech/srtool). `SRTool` guarantees that every runtime build produces identical Wasm bytecode, making it reliable for production use. This build requires [Docker](https://www.docker.com/) or [Podman](https://podman.io/) to be installed and running. Pop CLI automatically invokes the `SRTool` image to generate a reproducible and verifiable runtime.

This guide provides a quick overview of the importance of deterministic builds and how to achieve them using Pop CLI:

## Build a deterministic runtime with Pop CLI

While generating your chain spec with `pop build spec`, Pop CLI also gives you the option to build your runtime deterministically and inject it automatically.

Once you select the option to build deterministically, Pop CLI will prompt you to provide the runtime path (by default it's typically located in the runtime/ folder). After confirming, the deterministic build process will begin.

> ⏳ The build may take 10–15 minutes or more, depending on your setup, so be patient!

Once the build is complete, Pop CLI will automatically inject the resulting runtime code into your generated chain spec.

```
◇  Would you like to build the runtime deterministically? This requires a containerization solution (Docker/Podman) and is recommended for production builds.
│  Yes 
│
◆  Enter the directory path where the runtime is located:
│  ./runtime/mainnet 
└ 

◒  Building deterministic runtime...                    
│  ▲  WARNING: You are using docker. It is recommend to use podman instead.
│  
◓  NOTE: This process may take longer than 10-15 minutes. Please be patient...  
```

If you'd prefer not to be prompted interactively, you can specify everything up front via command line:

```
# minimal deterministic build example
pop build spec --deterministic --runtime ./runtime/mainnet

# optionally, specify the runtime package name used by srtool (if your workspace layout differs)
# note: --package is only applicable when --deterministic is set
pop build spec --deterministic --runtime ./runtime/mainnet --package parachain-template-runtime
```

Notes about flags:

* You can pass `--runtime` without `--deterministic` to pre-select the runtime directory for the command. This alone will not trigger a deterministic build; you must add `--deterministic` to enable srtool.
* The `--package` flag is available to explicitly set the runtime package name when doing a deterministic build; if omitted, Pop CLI will infer it from the runtime directory.

## Resources

#### Learning Resources

* 🧑‍🏫 [Build a Deterministic Runtime](https://docs.polkadot.com/develop/parachains/deployment/build-deterministic-runtime/) in the Polkadot docs is a good starting point.
* 🧑‍🔧 For technical introduction, [srtool repository](https://github.com/paritytech/srtool).

**Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Test runtime upgrades

The following guide shows how to test runtime upgrades.

A key feature of Substrate is its support for forkless upgrades. Testing the blockchain runtime upgrade process is essential to ensure a seamless network transition without disruptions.

To simulate and validate the process of upgrading a blockchain's runtime, the `on-runtime-upgrade` executes the [`OnRuntimeUpgrade`](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/trait.OnRuntimeUpgrade.html) hooks of a runtime against the state of a live blockchain or a snapshot.

Hence, there are two subcommands `live` and `snap` to specify the source of the runtime state.

```bash
Usage: pop test on-runtime-upgrade [OPTIONS] [COMMAND]

Commands:
  live  A live chain
  snap  A state snapshot
  help  Print this message or the help of the given subcommand(s)
```

### JSON mode

Use global `--json` for structured output:

```bash
pop --json test on-runtime-upgrade --runtime ./target/release/my_runtime.wasm --checks all live --uri wss://rpc1.paseo.popnetwork.xyz
```

In JSON mode, interactive prompts are disabled. Provide all required runtime/source/check flags explicitly.

## Test migrations

By running the command `pop test on-runtime-upgrade`, you can test the [Runtime Upgrades](https://docs.polkadot.com/develop/parachains/maintenance/runtime-upgrades/) and [Storage Migrations](https://docs.polkadot.com/develop/parachains/maintenance/storage-migrations/) in a simulated environment.

```bash
┌   Pop CLI : Testing migrations
│
◆  Do you want to specify which runtime to run the migration on?
│  If not provided, use the code of the remote node, or a snapshot.
│  ● Yes  / ○ No
└
```

Before running the migration, you will be prompted to confirm if you want to specify which runtime to run the migration on:

* If you choose to specify, you will be prompted to select the runtime to run the migration on. The feature requires your runtime to be [built with `--try-runtime` feature](broken://pages/iluN68guT8MppWAl8pBK).

> Pop CLI will automatically locate the runtime binary based on the provided `--profile`. Pop CLI will automatically build the runtime if not found.

* If not, the migration will be run against the code that's currently running on the remote node or the one stored inside the snapshot file you provide.

> Snapshot can be created with `pop test create-snapshot`.

### Test migrations against a live chain

```bash
◆  Select source of runtime state:
│  ● Live (Run the migrations on top of live state.)
│  ○ Snapshot
|
◇  Enter the live chain of your node:
│  wss://rpc1.paseo.popnetwork.xyz
│
◆  Enter the block hash (optional):
│  0x1234567890abcdef1234567890abcdef
└
```

You'll be asked to enter the URI of a live node and optionally provide a block hash. If a [block hash](https://paritytech.github.io/polkadot-sdk/master/sp_runtime/traits/trait.HashOutput.html) is given, the state will be executed at the specified block hash on the provided network.

To run the migrations on top of live state manually:

```bash
pop test on-runtime-upgrade \
    --runtime=<path_to_runtime_binary> \
    live \
    --uri=wss://rpc1.paseo.popnetwork.xyz \
    --at=0x1234567890abcdef1234567890abcdef
```

***Note***: The specified runtime and the remote node's runtime must have the same name and version. If not, the migration will fail. You can add the flag `--disable-spec-version-check` and `--disable-spec-name-check` to bypass the checks. Pop may also prompt you to disable these checks if it detects a mismatch.

```bash
pop test on-runtime-upgrade \
    --runtime=<path_to_runtime_binary> \
    --disable-spec-version-check \
    --disable-spec-name-check \
    live \
    --uri=wss://rpc1.paseo.popnetwork.xyz \
    --at=0x1234567890abcdef1234567890abcdef
```

After that, you can select the upgrade checks to perform:

```bash
◆  Select upgrade checks to perform:
│  ○ none
│  ● all (Run the `try_state`, `pre_upgrade` and `post_upgrade` checks)
│  ○ try-state
│  ○ pre-and-post
└
```

### Test migrations with a snapshot file

A second approach to test migrations is with a snapshot file. First, you need to create a snapshot file of a live network. You can do this by running the following command:

```bash
pop test create-snapshot
```

The interactive interface to prompts for the live URI and the path of the snapshot file:

```bash
┌   Pop CLI : Creating a snapshot file
│
▲  NOTE: `create-snapshot` only works with the remote node. No runtime required.
│
◇  Enter the URI of the remote node:
│  wss://rpc1.paseo.popnetwork.xyz
│
◇  Enter the path to write the snapshot to (optional):
│  If not provided `<spec-name>-<spec-version>@<block-hash>.snap` will be used.
│  example.snap
```

To skip the interactive prompt, use the `--uri` and `--path` flags:

```bash
pop test create-snapshot --uri wss://rpc1.paseo.popnetwork.xyz ./example.snap
```

If the path of snapshot file is not provided, the default name following a format `<spec-name>-<spec-version>@<block-hash>.snap` will be used. Note that the remote node must be built with `--try-runtime` feature enabled.

Assume there is a snapshot file created with the name `example.snap`:

```bash
◇  Enter path to your snapshot file?
│  Snapshot file can be generated using `pop test create-snapshot` command.
│  ./example.snap
```

To run migrations with a snapshot manually:

```bash
pop test on-runtime-upgrade \
    --runtime=<path_to_runtime_binary> \
    --blocktime=6000 \
    --checks=all \
    snap \
    --path=./example.snap
```

#### Learning Resources

* 🧑‍🏫 To learn about Polkadot in general, [Polkadot.network](https://polkadot.network/) website is a good starting point.
* 🧑‍🔧 For technical introduction of the `try-runtime`, [here](https://paritytech.github.io/try-runtime-cli/try_runtime/).
* Learn more about [Runtime Upgrades](https://docs.polkadot.com/develop/parachains/maintenance/runtime-upgrades/) and [Storage Migrations](https://docs.polkadot.com/develop/parachains/maintenance/storage-migrations).

**Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Upgrade Polkadot SDK dependencies

Upgrade Polkadot SDK dependency versions in a chain project with Pop CLI.

Use `pop upgrade` to update Polkadot SDK dependency versions in a chain project. It rewrites entries in your `Cargo.toml` using a known version mapping.

You can also run the command as `pop ug`. Use this command in a chain project that has a `Cargo.toml`. Network access is required to fetch available Polkadot SDK versions.

## Usage

```bash
pop upgrade [--path <PATH>] [--version <VERSION>]
```

### JSON mode

Use global `--json` for structured output in automation:

```bash
pop --json upgrade --path /path/to/project --version polkadot-stable2509-1
```

In JSON mode, `--version` is required because interactive version selection is disabled.

## Examples

```bash
# Upgrade the current project and select a version interactively
pop upgrade

# Upgrade a specific project directory
pop upgrade --path /path/to/project

# Upgrade a specific Cargo.toml
pop upgrade --path /path/to/project/Cargo.toml

# Upgrade to a specific Polkadot SDK tag
pop upgrade --version polkadot-stable2509-1
```

## How version selection works

If you omit `--version`, Pop fetches available Polkadot SDK release tags from GitHub and prompts you to select one. The prompt is filterable as you type.

If you pass `--version`, Pop skips the prompt and uses your value directly.

## Path resolution

* If `--path` points to a `Cargo.toml`, Pop uses it directly.
* If `--path` points to a directory, Pop appends `Cargo.toml`.
* If you omit `--path`, Pop uses the `Cargo.toml` in your current directory.

## Output and follow-up

After the update, Pop prints a warning that the upgrade may introduce compile errors and recommends running `pop build`. It also prints a success message with the version you selected.

## Errors and constraints

* Missing `Cargo.toml`: `Cargo.toml file not found at specified path`.
* Version mapping fetch failed: `Failed to get version mapping: <error>`.
* Dependency update failed: `Failed to update dependencies: <error>`.


# Benchmarking

[Benchmarking in the Polkadot SDK/Substrate](https://docs.polkadot.com/develop/parachains/testing/benchmarking/) measures execution time and resource usage for pallets and extrinsics, ensuring accurate weight calculations and optimal performance.

With Pop CLI, you can benchmark pallets and extrinsics interactively by managing parameters efficiently. Run the following command to start benchmarking:

```bash
pop bench pallet
```

For automation, use structured output:

```bash
pop --json bench pallet --runtime=target/release/pop-runtime-devnet.wasm --pallet pallet_balances --extrinsic transfer_keep_alive --skip-parameters
```

JSON mode requirements:

* `bench pallet` is the only benchmark command that currently supports `--json`.
* `--runtime` is required.
* For non-`--list` runs, `--pallet`, `--extrinsic`, and `--skip-parameters` are required.
* `--json` cannot be combined with `--json-file`.

Note that the command requires the `frame-omni-bencher` binary to be installed on your local machine.

> Pop CLI will automatically source the `frame-omni-bencher` binary if not found on your local machine.

**Provide a runtime to benchmark**

The command requires a runtime built with the `runtime-benchmarks` feature. Pop CLI detects available runtimes in your project, allowing you to choose one if multiple exist.

```bash
◇  Choose the build profile of the binary that should be used:
│  Release
│
◆  Select the runtime:
│  ○ pop-runtime-testnet
│  ● pop-runtime-devnet
│  ○ pop-runtime-mainnet
└
```

If the binary is missing, Pop CLI builds it with the appropriate build `profile` and features. You can manually specify the runtime binary path using:

```bash
pop bench pallet --runtime=target/release/pop-runtime-devnet.wasm
```

By default, whenever benchmarking starts, the runtime binary will be automatically built to ensure that it is current. You can provide a flag `--no-build` or `-n` manually to skip the build process if there is an existing runtime binary.

```bash
pop bench pallet --no-build
```

**Configure the genesis builder policy and preset**

```bash
◆  Select the genesis builder policy:
│  ● none (Do not provide any genesis state.)
│  ○ runtime
└
```

> Genesis builder policy defines the way to construct the [initial genesis state](https://docs.polkadot.com/develop/parachains/deployment/generate-chain-specs/).

There are two options for the genesis builder policy:

* `none`: Do not provide any genesis state.
* `runtime`: Use the runtime's genesis preset.

To configure the genesis builder manually, you can use the `--genesis-builder` flag. For example:

```bash
pop bench pallet --runtime=target/release/pop-runtime-devnet.wasm --genesis-builder=runtime
```

The genesis preset is configured on the runtime via [`sp_genesis_builder`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/) crates which contains a runtime-api to be implemented by runtimes, in order to express their genesis state.

```bash
◇  Select the genesis builder policy:
│  runtime
│
◇  Found 2 genesis builder presets
│
◆  Select the genesis builder preset:
│  ● development
│  ○ local_testnet
└
```

To configure the genesis builder preset manually, you can use the `--genesis-builder-preset` flag:

```bash
pop bench pallet --runtime=target/release/pop-runtime-devnet.wasm --genesis-builder=runtime --genesis-builder-preset=development
```

**Select pallets and extrinsics**

You'll be prompted to benchmark all pallets or select a specific one. Pop CLI lists all available pallets within the runtime, allowing you to search by name and choose from the list.

```bash
◆  🔎 Search for a pallet to benchmark
│
│  ● cumulus_pallet_parachain_system
│  ○ cumulus_pallet_xcmp_queue
│  ○ frame_system
│  ○ pallet_balances
│  ○ pallet_collator_selection
│  ○ pallet_message_queue
│  ○ pallet_session
│  ○ pallet_sudo
│  ○ pallet_timestamp
└
```

You can simply search for pallets by typing their name and selecting them from the list.

```bash
◆  🔎 Search for a pallet to benchmark
│  pallet_time
│  ● pallet_timestamp
│  ○ pallet_session
│  ○ pallet_sudo
│  ○ pallet_message_queue
│  ○ pallet_balances
│  ○ pallet_collator_selection
└
```

If a pallet is specified, the CLI will prompt you to select the extrinsics you want to benchmark within that pallet. You can select multiple extrinsics by pressing the spacebar. Same as searching for pallets, you can search for extrinsics by typing their name as well.

```bash
◆  🔎 Search for extrinsics to benchmark (select with space)
│
│  ◼ burn_allow_death
│  ◼ burn_keep_alive
│  ◼ force_adjust_total_issuance
│  ◼ force_set_balance_creating
│  ◻ force_set_balance_killing
│  ◻ force_transfer
│  ◻ force_unreserve
│  ◻ transfer_all
│  ◻ transfer_allow_death
│  ◻ transfer_keep_alive
│  ◻ upgrade_accounts
└
```

If `--extrinsic=` and `--pallet=` are provided, the CLI will skip the search and directly benchmark with the specified arguments.

**Manage parameters**

Pop CLI displays all editable parameters, allowing you to preview and modify them as needed. Simply select a parameter to provide a new value.

> To skip parameter configuration, you can use the `--skip-parameters` flag.

```bash
◆  Select the parameter to update:
│  ○ (0) - Pallets: pallet_balances
│  ○ (1) - Extrinsics: 4 selected
│  ○ (2) - Runtime path: tests/runtimes/base_parachain_benchmark.wasm
│  ○ (3) - Genesis builder: runtime
│  ○ (4) - Genesis builder preset: development
│  ○ (5) - Steps: 50
│  ○ (6) - Repeats: 20
│  ○ (7) - High: None
│  ○ (8) - Low: None
│  ○ (9) - Map size: 1000000
│  ○ (10) - Database cache size: 1024
│  ○ (11) - Additional trie layer: 2
│  ○ (12) - No median slope: false
│  ○ (13) - No min square: false
│  ○ (14) - No storage info: false
│  ○ (15) - Weight file template: None
│  ● > Save all parameter changes and continue
└
```

For example, to update the `High` parameter:

```bash
◇  Select the parameter to update:
│  (7) - High: None
│
◆  Provide range values to the parameter "High" (numbers separated by commas)
│  10,50,100
└
```

And you will see the value is updated:

```bash
│  ○ (6) - Repeats: 20
│  ● (7) - High: 10,50,100
│  ○ (8) - Low: None
```

**Save weight output and parameter values to file**

After the providing parameter values, you will be prompted to save the weight output and provided parameter values to a file. If not provided, no weight output will be saved.

```bash
◆  Provide the output file path for benchmark results (optional).
│  ./weight.rs
└
```

To save parameter values, the file path is default to `pop-bench.toml`.

```bash
◆  Provide the output path for benchmark parameter values
│  pop-bench.toml
└
```

Below is the example of the parameter file:

```toml
version = "1"
pallet = "pallet_timestamp"
extrinsic = "*"
exclude_pallets = []
all = false
steps = 50
lowest_range_values = []
highest_range_values = []
repeat = 20
external_repeat = 1
json_output = false
no_median_slopes = false
no_min_squares = false
output_pov_analysis = "median-slopes"
no_verify = false
extra = false
runtime = "runtimes/base_parachain_benchmark.wasm"
allow_missing_host_functions = false
genesis_builder = "Runtime"
genesis_builder_preset = "development"
database_cache_size = 1024
list = false
no_storage_info = false
worst_case_map_values = 1000000
additional_trie_layers = 2
disable_proof_recording = false
skip_parameters = false
skip_confirm = false
```

With the saved parameter file, you can load parameter values from the file by using the `-f` or `--bench-file` flag.

```bash
pop bench -f pop-bench.toml
```

For more advanced parameter configuration, you can run the following command to learn more:

```bash
pop bench --help
```

#### Learning Resources

* 🧑‍🏫 To learn about Polkadot in general, [Polkadot.network](https://polkadot.network/) website is a good starting point.
* 🧑‍🔧 For technical introduction, [here](https://github.com/paritytech/polkadot-sdk#-documentation) are the Polkadot SDK documentation resources.
* To learn about benchmarking, [Polkadot Docs - Benchmarking](https://docs.polkadot.com/develop/parachains/testing/benchmarking/) provides all the fundamentals.
* More advanced breakdown of benchmarking is covered in [Polkadot SDK Docs - Frame Benchmarking Weight](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_benchmarking_weight/index.html).

**Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Deploy

The following guides show how to launch a chain on Polkadot.

A typical development workflow for launching a chain on Polkadot:

1. [Launch a Development Network](/chains/guides/launch-a-chain/running-your-chain) with predefined chains.
2. [Launch a Known Chain](/chains/guides/launch-a-chain/launch-a-known-chain)
3. [Launch a Chain on Paseo](/chains/guides/launch-a-chain/launch-a-chain-to-paseo).
4. [Deploy a Chain With Polkadot Deployment Portal](/chains/guides/launch-a-chain/deploy-a-chain-polkadot-deployment-portal).
5. Launch a Chain on Polkadot (same as Paseo).


# Launch a Chain in Development

To run your chain, you will need to spin up a local network with your chain configuration.

The `pop up` command can help with this.

```shell
pop up network --help
```

Say we want to spin up a local network for your chain. First we need to define a [zombienet](https://github.com/paritytech/zombienet) network configuration file. You can do this in the root of your project.

```
cd my-chain
touch network.toml
```

Add the following configuration, adapting as necessary.

> You can use `paseo-local` for your Relay chain. Paseo is the community-led Polkadot Test Relay chain.

```toml
[relaychain]
chain = "paseo-local"

[[relaychain.nodes]]
name = "alice"
validator = true

[[relaychain.nodes]]
name = "bob"
validator = true

[[parachains]]
id = 2000
default_command = "./target/release/parachain-template-node"

[[parachains.collators]]
name = "collator-01"
```

> This network configuration will launch a relay chain using a `paseo-local` instance of Polkadot with two validator nodes to run the network: `alice` and `bob`. It will also run `parachain-template-node` with one collator node named `collator-01`.

Cool. Let's spin this up, ensuring that your chain binary has been built using `pop build`.

```shell
pop up ./network.toml
```

If this is the first time you are running the `pop up` command, it will prompt you to source the required Polkadot binaries. This will take some time, grab some coffee.

Once all the binaries are sourced, you should have output similar to this.

```
┌   Pop CLI : Deploy a chain
│
◇  🚀 Network launched successfully - ctrl-c to terminate
│  ⛓️ paseo-local
│       alice:
│         portal: https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:62551#/explorer
│         logs: tail -f /var/folders/vl/txnq6gdj22s9rn296z0md27w0000gn/T/zombie-c0eb16fc-5d11-4792-aced-493ef972d056/alice/alice.log
│       bob:
│         portal: https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:62555#/explorer
│         logs: tail -f /var/folders/vl/txnq6gdj22s9rn296z0md27w0000gn/T/zombie-c0eb16fc-5d11-4792-aced-493ef972d056/bob/bob.log
│  ⛓️ local_testnet: 2000
│       collator-01:
│         portal: https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:62559#/explorer
│         logs: tail -f /var/folders/vl/txnq6gdj22s9rn296z0md27w0000gn/T/zombie-c0eb16fc-5d11-4792-aced-493ef972d056/collator-01/collator-01.log
│
```

Congrats! You have now spun up a network with your chain running!

> Under-the-hood, Pop CLI uses zombienet to spin up the network.\
> For more advanced network configurations and options consult the [zombienet repo](https://github.com/paritytech/zombienet)

### Detached mode

Use detached mode to keep the network running in the background:

```shell
pop up network ./network.toml --detach
```

For structured output, use:

```shell
pop --json up network ./network.toml --detach
```

In JSON mode, `--detach` is required and `--cmd` is not supported.

When detached mode starts, Pop CLI:

* Prints the network base directory and `zombie.json` path.
* Prints WebSocket URLs for relay and parachain nodes.
* Polls endpoints until nodes are responsive, then confirms readiness.

To stop a detached network later, run `pop clean network <path-to-zombie.json>` or `pop clean network --all`.

#### Learning Resources

* 🧑‍🏫 To learn about Polkadot in general, [Polkadot.network](https://polkadot.network/) website is a good starting point.
  * ⭕ Learn more about Polkadot chains [here](https://wiki.polkadot.network/docs/learn-parachains).
* 🧑‍🔧 For technical introduction, [here](https://github.com/paritytech/polkadot-sdk#-documentation) are the Polkadot SDK documentation resources.

**Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Launch a Known Chain

With Pop CLI you can quickly spin up a supported chain without needing to prepare network configuration files.

A `supported chain` currently refers to one of the system chains. Pop CLI automatically fetches the required binaries and chain-spec generators so you can launch in seconds. Support for additional chains will be added in the future.

### Example Usage

Spin up Paseo with Asset Hub:

```shell
pop up paseo -p asset-hub
```

Run Kusama on port `8833` with Asset Hub chain assigned to `9944`:

```shell
pop up kusama --port 8833 --parachain asset-hub:9944 -r stable2412-4
```

Launch Polkadot with Asset Hub and a specific ParaId:

```shell
pop up polkadot --port 8833 --parachain asset-hub#3395:9977 -r stable2412-4
```

### Custom Network Configurations

You can still provide a full network configuration file if needed. The `pop up network` command now accepts a positional path argument, eliminating the need for `--file`/`-f`:

```bash
touch paseo-local.toml
```

```toml
[relaychain]
chain = "paseo-local"

[relaychain.genesis_overrides.sudo]
key = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" # Alice

[[relaychain.nodes]]
name = "alice"
rpc_port = 57731
validator = true

[[relaychain.nodes]]
name = "bob"
validator = true

[[relaychain.nodes]]
name = "charlie"
validator = true
```

> For more details on network configuration files, check the [Zombienet documentation](https://docs.polkadot.com/develop/toolkit/parachains/spawn-chains/zombienet/get-started/?utm_source=chatgpt.com#configure-zombienet)

Run the network:

```
pop up network ./paseo-local.toml --verbose
```

#### Learning Resources

* 🧑‍🏫 To learn about [System Chains](https://wiki.polkadot.com/learn/learn-system-chains/) website is a good starting point.
  * ⭕ Learn more about PassetHub (the temporary AssetHub testnet) [here](https://forum.polkadot.network/t/testnets-paseo-officially-becomes-the-polkadot-testnet-temporary-passet-hub-chain-for-smart-contracts-testing/13209).
* 🧑‍🔧 For technical documentation of Paseo Network, [here](https://github.com/paseo-network).

**Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Launch a Chain to Paseo

This guide shows how launch a chain on Paseo (Local or Live)

[Paseo](https://x.com/PaseoNetwork) is the community-run Polkadot Relay chain Testnet. You can test onboarding a chain locally on Paseo Local before deploying it to the live Paseo Testnet.

#### Paseo Local

If you want to test onboarding a chain on your local machine you need to [launch Paseo](/chains/guides/launch-a-chain/launch-a-chain-to-paseo/launch-paseo).

#### Paseo Live

Otherwise you will onboard to [Paseo](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.ibp.network%2Fpaseo#/explorer).

> Note: if not specified, all the following steps are the same for launching on Paseo Local / Live.

## Generate Operational Keys

See here how to [generate keys](/chains/guides/launch-a-chain/launch-a-chain-to-paseo/keys).

### Collator Keys

When running a parachain collator, you typically need **two** distinct key pairs:

1. **Stash Account** – A “long-term savings” or bonded account used for staking or holding tokens on behalf of the collator. This account holds the majority of your funds but is kept protected from routine usage.
2. **Session Key** – The account the collator uses to sign and produce blocks in the network. If compromised, an attacker only gains the ability to author blocks, not access the stash account’s large reserve of funds.

> **Collator:** A collator is the parachain node responsible for producing blocks and maintaining the parachain’s state.

### Chain Manager Key

This account pays for actions like para ID reservation, parachain registration, and acquiring coretime.

### Fund Chain Manager

Now that we have a Chain Manager account we need to fund this account with tokens to perform transactions on behalf of the collator.

#### Paseo Local

```bash
pop call chain --pallet Balances --function transfer_allow_death --url ws://localhost:57731/ --suri //Alice
```

```bash
┌   Pop CLI : Call a chain
│
◇  Select the value for the parameter: dest
│  Id 
│
◇  Enter the value for the parameter: Id
│  <CHAIN MANAGER ACCOUNT SS58 ADDRESS>
│
◇  Enter the value for the parameter: value
│  1000000000000000
│
...
```

> Note: the `--url ws://localhost:57731` parameter should point to a [Paseo Local node](/chains/guides/launch-a-chain/launch-a-chain-to-paseo/launch-paseo#network-endpoints).

#### Paseo Live

Request PAS tokens on [Paseo Faucet](https://faucet.polkadot.io/).

## Setting up the Chain

For the sake of this exercise, let's create a new chain project:

```
pop new chain my-chain
```

> The folder includes a `network.toml` file which can be ignored. This is to launch a network with the chain already onboarded.

### Generate the chain spec

The chain specification holds all the information the node requires to start or sync with the chain's network.

Let's generate a chain spec:

> For more advanced customization `pop build spec --help`

Open the `chain-spec.json` file in your editor.

Make sure to edit your chain spec and:

* **add your account and session keys**
* **specify the starting balance of specific accounts**
* **add the account that will be the sudo account for your chain**

It should look similar to the below:

```json
{
  "name": "My Chain",
  "id": "my_chain",
  "chainType": "Local",
  "bootNodes": [],
  "telemetryEndpoints": null,
  "protocolId": "my_chain",
  "properties": {
    "ss58Format": 42,
    "tokenDecimals": 12,
    "tokenSymbol": "UNIT"
  },
  "relay_chain": "paseo",
  "para_id": 2000,
  "codeSubstitutes": {},
  "genesis": {
    "runtimeGenesis": {
      "code": "...",
      "patch": {
        "balances": {
          "balances": [
            [
              "INSERT_SS58_STASH_ACCOUNT_KEY_COLLATOR_1",
              1152921504606846976
            ],
            [
              "INSERT_SS58_STASH_ACCOUNT_KEY_COLLATOR_2_OPTIONAL",
              1152921504606846976
            ],
          ]
        },
        "collatorSelection": {
          "candidacyBond": 16000000000,
          "invulnerables": [
            "INSERT_SS58_STASH_ACCOUNT_KEY_COLLATOR_1",
            "INSERT_SS58_STASH_ACCOUNT_KEY_COLLATOR_2_OPTIONAL"
          ]
        },
        "parachainInfo": {
          "parachainId": 2000
        },
        "polkadotXcm": {
          "safeXcmVersion": 4
        },
        "session": {
          "keys": [
            [
              "INSERT_SS58_STASH_ACCOUNT_KEY_COLLATOR_1",
              "INSERT_SS58_STASH_ACCOUNT_KEY_COLLATOR_1",
              {
                "aura": "INSERT_SS58_SESSION_KEY_COLLATOR_1"
              }
            ],
            [
              "INSERT_SS58_STASH_ACCOUNT_KEY_COLLATOR_2_OPTIONAL",
              "INSERT_SS58_STASH_ACCOUNT_KEY_COLLATOR_2_OPTIONAL",
              {
                "aura": "INSERT_SS58_SESSION_KEY_COLLATOR_2_OPTIONAL"
              }
            ]
          ]
        },
        "sudo": {
          "key": "INSERT_SS58_SUDO_ACCOUNT_KEY"
        }
      }
    }
  }
}
```

Since we have modified our chain spec, we will need to re-generate the raw chain spec, genesis state and wasm:

```bash
pop build spec --chain chain-spec.json --disable-default-bootnode --genesis-state --genesis-code  
```

```bash
┌   Pop CLI : Generate your chain spec
│
◇  An existing chain spec file is provided. Do you want to make additional changes to it?
│  No 
```

> Pop CLI allows you to provide the path to an existing chain spec file to edit or regenerate the artifacts.

We are now ready to sync with Paseo and start producing blocks!

## Launch the Chain

In order to run your parachain's collator, you will need the raw chain spec of Paseo.

#### Paseo Local

The chain spec file can be found in the output of `pop up network -f network --verbose`. Copy the chain spec file into the `my-chain` directory:

```bash
cd my-chain
cp /var/folders/vl/txnq6gdj22s9rn296z0md27w0000gn/T/zombie-ddb5d2aa-704b-4658-af64-3cf9e3be5573/alice/cfg/paseo-local.json paseo-local-raw.json
```

> Note: Your Paseo chain spec path may differ from the example above.

#### Paseo Live

Copy the [Paseo chain spec file](https://github.com/paseo-network/runtimes/blob/main/chain-specs/paseo-local.raw.json) into the my-chain directory:

### Generate Node Key

We need to generate a node-key for the collator:

#### Using Docker

```bash
cd my-chain
mkdir -p data/chains/my_chain/network
docker run -it parity/subkey:latest generate-node-key > ./data/chains/my_chain/network/secret_ed25519
```

#### On your Machine

```
path/to/polkadot-sdk/target/debug/substrate-node key generate-node-key --file=secret_ed25519 --chain=./chain-spec-raw.json
```

<pre><code><strong>mv secret_ed25519 data/chains/my_chain/network
</strong></code></pre>

### Run Collator

Run the collator with the following command:

```
./target/release/parachain-template-node \
--collator \
--force-authoring \
--chain chain-spec-raw.json \
--base-path ./data \
--port 40333 \
--rpc-port 8845 \
-- \
--sync warp \
--chain paseo-local-raw.json \
--port 57733 \
--rpc-port 57731
```

> The second half of this command specifies the Relay chain node to connect to.

The `--base-path ./data` is specified because the node key was placed into `my-chain/data`. You could use the `--unsafe-force-node-key-generation` flag to delegate the key generation to the node itself (**IMPORTANT**: not advised for a live testnet).

Last, we need to insert the session key into our running collator so that it can sign operational transactions:

```bash
curl -H "Content-Type: application/json" \
--data '{
  "jsonrpc":"2.0",
  "method":"author_insertKey",
  "params":[
    "aura",
    "INSERT_SECRET_SESSION_SEED_PHRASE",
    "INSERT_PUBLIC_SESSION_KEY_HEX_FORMAT"
  ],
  "id":1
}' \
http://localhost:8845
```

Well done! Now look at the logs of your chain and you should see it being synced with Paseo!!!

```bash
2024-12-10 09:06:05 [Relaychain] Warp sync is complete, continuing with state sync.    
2024-12-10 09:06:06 [Relaychain] State sync is complete, continuing with block sync.    
2024-12-10 09:06:06 [Relaychain] 🏆 Imported #47 (0xb04f…12a4 → 0x6adf…6582)    
2024-12-10 09:06:06 [Relaychain] 🏆 Imported #48 (0x6adf…6582 → 0xd036…e502) 
```

Last step is to onboard the chain to Paseo.

### Onboard Chain to Paseo

`pop up` simplifies the process of onboarding a chain to Paseo by automating both the reservation of an ID and its registration. Take the generated genesis state (`para-2000-genesis-state`) and genesis code (`para-2000.wasm`) and run:

```bash
pop up --genesis-state ./para-2000-genesis-state --genesis-code para-2000.wasm 
```

#### Manual registration

If you prefer, you can still execute the steps separately using `pop call chain`.

We can reserve a para ID for the chain using pop cli:

```bash
pop call chain --url ws://localhost:57731
```

```bash
┌   Pop CLI : Call a chain
│
◇  What would you like to do?
│  Reserve a parachain ID 
│
◇  Do you want to use your browser wallet to sign the extrinsic? (Selecting 'No' will prompt you to manually enter the secret key URI for signing, e.g., '//Alice')
│  No
│
◇  Signer of the extrinsic:
│  <CHAIN MANAGER ACCOUNT>
│  
...
       Event Balances ➜ Reserved
         who: <CHAIN MANAGER ACCOUNT>
         amount: 100UNIT
       Event Registrar ➜ Reserved
         para_id: Id(2000)
         who: <CHAIN MANAGER ACCOUNT>
...         
```

In the events we can see the `para_id` that is assigned to the chain. Make sure this is the para ID specified in the chain spec file (and thus the chain artifacts).

Now we register the para ID with the generated genesis state (`para-2000-genesis-state`) and genesis code (`para-2000.wasm`).

```bash
│
◇  Do you want to perform another call?
│  Yes
│
◇  What would you like to do?
│  Register a parachain ID with genesis state and code
│
◇  Enter the value for the parameter: id
│  2000
│
◇  The value for `genesis_head` might be too large to enter. You may enter the path to a file instead.
│  para-2000-genesis-state
│
◇  The value for `validation_code` might be too large to enter. You may enter the path to a file instead.
│  para-2000.wasm
│
◇  Do you want to use your browser wallet to sign the extrinsic? (Selecting 'No' will prompt you to manually enter the secret key URI for signing, e.g., '//Alice')
│  No
│
◇  Signer of the extrinsic:
│  <CHAIN MANAGER ACCOUNT>
│
...
       Event Balances ➜ Withdraw
         who: <CHAIN MANAGER ACCOUNT>
         amount: 90.71989507390UNIT
       Event Balances ➜ Reserved
         who: <CHAIN MANAGER ACCOUNT>
         amount: 3.145826kUNIT
       Event Paras ➜ PvfCheckStarted
         0: ValidationCodeHash(0x1821617486094e18595084b580fe9324a084adedbf80ec61c9d7b75736ab5f5b)
         1: Id(2000)
       Event Registrar ➜ Registered
         para_id: Id(2000)
         manager: <CHAIN MANAGER ACCOUNT>
...
```

Your chain is now registered on Paseo and should produce a block!

In order to validate and get your block finalised by the Relay chain, see [here](/chains/guides/launch-a-chain/launch-a-chain-to-paseo/coretime) how to acquire core time.

> Note: In the examples above, you are prompted to provide a `<private-key>` to interact with the chain. However, this implies a potentially insecure way of handling private keys and should only be used for development accounts. For production accounts and enhanced security, Pop CLI offers the `--use-wallet` option to securely sign transactions. Refer to the [Securely sign transactions from CLI guide](/chains/guides/securely-sign-transactions-from-cli) for detailed instructions.

## Resources

#### Learning Resources

* <https://paritytech.github.io/devops-guide/guides/parachain_deployment.html>
* 🧑‍🏫 To learn about Polkadot in general, [Polkadot.network](https://polkadot.network/) website is a good starting point.
  * ⭕ Learn more about Polkadot chains [here](https://wiki.polkadot.network/docs/learn-parachains).
* 🧑‍🔧 For technical introduction, [here](https://github.com/paritytech/polkadot-sdk#-documentation) are the Polkadot SDK documentation resources.

**Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Launch Paseo

How to spin up the Paseo Relay chain locally

Lets create a configuration file to launch Paseo Local:

```bash
touch paseo-local.toml
```

```toml
[relaychain]
chain = "paseo-local"

[relaychain.genesis_overrides.sudo]
key = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" # Alice

[[relaychain.nodes]]
name = "alice"
rpc_port = 57731
validator = true

[[relaychain.nodes]]
name = "bob"
validator = true

[[relaychain.nodes]]
name = "charlie"
validator = true
```

As you can see, the sudo account (admin of the chain) is overridden with `Alice` account. This allows us to make changes to Paseo Local if needed.

Run the network:

```
pop up network ./paseo-local.toml --verbose
```

> The `--verbose` flag provides us with extra information such as the location of the Paseo Local chain spec file.

<figure><img src="/files/DP75nuQJGTMr1pDagacW" alt=""><figcaption><p>pop up network ./paseo-local.toml --verbose</p></figcaption></figure>

Paseo Local should now be running on your machine and producing blocks!

## Network Endpoints

Based on the `paseo-local.toml` file, the following validator nodes are spun up:

* Alice: ws\://localhost:57731
* Bob: ws\://localhost:57735.
* Charlie: ws\://localhost:57739.

The `rpc_port` for Alice has been specified, the ports for Bob & Charlie are dynamically assigned.

These endpoints come in handy when you want to interact with the chain (e.g. `pop call chain`).

## Configure Paseo Local

As of now, Paseo Local doesn't provide cores to validate chain blocks on demand. We will have to make 2 calls to Paseo Local using `Alice` as admin account.

First, configure Paseo Local to set coretime cores to `1`:

```bash
pop call chain --pallet Configuration --function set_coretime_cores --args "1" --url ws://localhost:57731/ --suri //Alice --sudo --skip-confirm
```

> Note: the specified rpc port `57731` is specified in the created `paseo-local.toml` file and is to interact with the validator `alice`.

Second, assign the core to the on demand pool:

```bash
pop call chain --url ws://localhost:57731 --call 0xff004a0400000a000000040100e100 --suri //Alice --skip-confirm
```

For more examples of network configurations:

* <https://github.com/r0gue-io/pop-cli/tree/main/tests/networks>

For more advanced options, such as specifying the Relay chain version, run the following command:

```
pop up network --help
```

### Learning Resources

* 🧑‍🏫 To learn about Polkadot in general, [Polkadot.network](https://polkadot.network/) website is a good starting point.
  * ⭕ Learn more about Polkadot chains [here](https://wiki.polkadot.network/docs/learn-parachains).
* 🧑‍🔧 For technical introduction, [here](https://github.com/paritytech/polkadot-sdk#-documentation) are the Polkadot SDK documentation resources.

**Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Set up keys

The following guide shows how to generate keys.

There are multiple ways to generate [keys](https://wiki.polkadot.network/docs/learn-accounts) (accounts) on Polkadot, such as:

* [PolkadotJs Signer](https://polkadot.js.org/) or any other custodial
* [PolkaVault](https://wiki.polkadot.network/docs/polkadot-vault)
* [Subkey](https://paritytech.github.io/polkadot-sdk/master/subkey/index.html)

> Account creation should be done securely, such as using an air-gapped computer.

For the sake of this guide, we will use subkey:

#### Using Docker

```bash
docker pull parity/subkey:latest
```

Generate the key:

```bash
docker run -it parity/subkey:latest generate --scheme sr25519
```

#### On your Machine

You can download the [polkadot-sdk](https://github.com/paritytech/polkadot-sdk) and run the following command instead:

```bash
git clone --depth 1 https://github.com/paritytech/polkadot-sdk
cd polkadot-sdk
pop build
./target/debug/polkadot key generate --scheme sr25519
```

You should get an output similar to:

```bash
Secret phrase:       innocent throw harsh wild example reflect sausage leopard lake bottom police enact
  Network ID:        substrate
  Secret seed:       0xee07e6d00ebed8816d3f3839caca779dbddb52e9847159feaf1858dec6adcc6e
  Public key (hex):  0xe0f20cba0c53da3ab427a5bd5b49b3214038a7b89fe4b1b7ea992d153fab495a
  Account ID:        0xe0f20cba0c53da3ab427a5bd5b49b3214038a7b89fe4b1b7ea992d153fab495a
  Public key (SS58): 5H9eVCvHfNMqNhMTL2FVJfy7fPgquCpvCktkMd98Dz9goRBy
  SS58 Address:      5H9eVCvHfNMqNhMTL2FVJfy7fPgquCpvCktkMd98Dz9goRBy
```

> This your key (Polkadot account). Save the secret phrase in a vault securely and never share it.

## Resources

#### Learning Resources

* <https://paritytech.github.io/devops-guide/guides/parachain_deployment.html>
* 🧑‍🏫 To learn about Polkadot in general, [Polkadot.network](https://polkadot.network/) website is a good starting point.
  * ⭕ Learn more about Polkadot chains [here](https://wiki.polkadot.network/docs/learn-parachains).
* 🧑‍🔧 For technical introduction, [here](https://github.com/paritytech/polkadot-sdk#-documentation) are the Polkadot SDK documentation resources.

**Technical SupportNeed help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Acquire Coretime

The following guide shows how to acquire coretime.

In order to get a chain's block validated and finalised by the Relay chain it needs to acquire [coretime](https://wiki.polkadot.network/docs/learn-agile-coretime).

Acquire coretime using the following command:

```bash
pop call chain --url <relay_endpoint>
```

```bash
┌   Pop CLI : Call a chain
│
◇  What would you like to do?
│  Purchase on-demand coretime 
│
◇  Enter the value for the parameter: max_amount
│  10000000
│
◇  Enter the value for the parameter: para_id
│  2000
│
◇  Do you want to use your browser wallet to sign the extrinsic? (Selecting 'No' will prompt you to manually enter the secret key URI for signing, e.g., '//Alice')
│  No
│
◇  Signer of the extrinsic:
│  <CHAIN MANAGER ACCOUNT>
...
       Event OnDemand ➜ OnDemandOrderPlaced
         para_id: Id(2000)
         spot_price: 1mUNIT
         ordered_by: <CHAIN MANAGER ACCOUNT>
...
```

> Note: the `max_amount` (spot price willing to pay for a core) will vary depending on the Relay Network.

If the event `OnDemandOrderPlaced` is returned it means that your block will be validated and finalised!

> Note: In the example above, you are prompted to provide a `<private-key>` to interact with the chain. However, this implies a potentially insecure way of handling private keys and should only be used for development accounts. For production accounts and enhanced security, Pop CLI offers the `--use-wallet` option to securely sign transactions. Refer to the [Securely sign transactions from CLI guide](/chains/guides/securely-sign-transactions-from-cli) for detailed instructions.

## Resources

#### Learning Resources

* <https://paritytech.github.io/devops-guide/guides/parachain_deployment.html>
* 🧑‍🏫 To learn about Polkadot in general, [Polkadot.network](https://polkadot.network/) website is a good starting point.
  * ⭕ Learn more about Polkadot chains [here](https://wiki.polkadot.network/docs/learn-parachains).
* 🧑‍🔧 For technical introduction, [here](https://github.com/paritytech/polkadot-sdk#-documentation) are the Polkadot SDK documentation resources.

**Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Deploy a chain with Polkadot Deployment Portal

This guide explains how to deploy a chain using the Polkadot Deployment Portal.

Pop CLI integrates an external provider for chain deployment, streamlining the process with seamless automation. It handles registration, as detailed in [Launch a Chain to Paseo](/chains/guides/launch-a-chain/launch-a-chain-to-paseo), and once the chain is registered, Pop CLI completes the deployment by integrating with the provider. The provider manages collators and offers a portal UI for monitoring your chain’s status.

### Accessing the Polkadot Deployment Portal (PDP)

Start by [signing up to be a beta tester](https://docs.google.com/forms/d/1th3GKJCSjzrmqwzDs62yA1hGUZnQUCPqmaUYLwSiHo4/viewform?edit_requested=true) to request access to the [Polkadot Deployment Portal](https://www.deploypolkadot.xyz/).

Once accepted, you’ll receive an API key required to deploy through Pop CLI. Keep this key safe, you’ll need it during setup.

> **Note:** Currently, the only supported deployment provider is the [Polkadot Deployment Portal](https://www.deploypolkadot.xyz/), which supports a limited set of templates, built-in collator management, and deployment tracking via its UI.

> **Important:** For now, use the [**staging portal**](https://staging.deploypolkadot.xyz/), this is the version integrated with Pop CLI during the beta phase.

### Starting the Deployment Process

Once you have your API key and access to the Polkadot Deployment Portal, you're ready to deploy your chain.

Execute the following command to start the interactive deployment process:

```shell
pop up
```

Follow the interactive guide:

<figure><img src="/files/FpPKNCX2tvcs0vHBcxwh" alt="pop up"><figcaption><p>pop up flow</p></figcaption></figure>

At the end of the process, Pop CLI will display the URL to the external provider's portal, where you can monitor the status of your deployment. For example, after a successful deployment, the [Polkadot Development Portal](https://www.deploypolkadot.xyz/) provides a UI like the one shown below:

<figure><img src="/files/XCOfOPx7htonx4eW9hqw" alt="Polkadot Development Portal UI"><figcaption><p>Polkadot Development Portal UI</p></figcaption></figure>

During the process, Pop CLI will prompt you for two important choices:

1. Whether to use a pure proxy for registration.
2. Whether to build the runtime deterministically.

#### What is a Pure Proxy?

A pure proxy is an account without private keys, controlled entirely by a designated proxy.

The proxy defines what kind of actions the controller account is allowed to perform on behalf of the pure proxy. There are different [proxy types](https://wiki.polkadot.network/learn/learn-proxies/#proxy-types), each with a specific scope of permissions.

The `ParaRegistration` proxy is designed to limit permissions strictly to paraID reservation and rollup registration, and is recommended for this use case.

> **Note**: `ParaRegistration` is a newly introduced proxy type. Before its availability, the common approach was to use the `Any` proxy as a more general alternative.

*Why Use a Pure Proxy?*

A pure proxy enhances security by keeping private keys hidden and delegating control to an any proxy. It simplifies multisig setups by allowing signatory changes without creating a new account. Highly recommended for chain registration!

To create a pure proxy run:

```shell
pop call
```

```
┌   Pop CLI : Call a chain
│
◇  Which chain would you like to interact with?
│  wss://pas-rpc.stakeworld.io
│
◇  What would you like to do?
│  Create a pure proxy 
│
◇  Select the value for the parameter: proxy_type
│  Any 
│
◇  Enter the value for the parameter: delay
│  0
│
◇  Enter the value for the parameter: index
│  0
│
```

Once the pure proxy is created, retrieve the generated address from the event `PureCreated` and fund it using the [Paseo Faucet](https://faucet.polkadot.io/) to enable transaction execution.

<figure><img src="/files/WvGpi7vO9KBvJ6RpoGbR" alt="pop up"><figcaption></figcaption></figure>

#### What is a Deterministic Runtime Build?

By default, the Rust compiler generates optimized Wasm binaries, but they aren't always deterministically reproducible. If the Wasm runtime isn't deterministic, each build might produce slightly different bytecode, This can be a problem for blockchain networks where every node must run the exact same runtime.

For a complete walkthrough on deterministic builds using Pop CLI, check out our dedicated guide: 👉 [Build your runtime deterministically](/chains/guides/build-your-chain/build-deterministic-runtime)

This build requires [Docker](https://www.docker.com/) or [Podman](https://podman.io/) to be installed and running. Pop CLI automatically invokes the `SRTool` image to generate a reproducible and verifiable runtime.

## Resources

#### Learning Resources

* 🧑‍🏫 <https://docs.polkadot.com/develop/parachains/deployment/>
  * ⭕ Learn more about deterministic runtimes [here](https://docs.polkadot.com/develop/parachains/deployment/build-deterministic-runtime/).
* 🧑‍🔧 Learn more about [Pure Proxies Accounts](https://wiki.polkadot.network/docs/learn-proxies-pure).
* [Polkadot Deployment Portal Documentation](https://www.deploypolkadot.xyz/docs).

**Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Running a post-startup command

The following will guide developers on how to run a command after launch of your network.

Often there is a use case to run a command (or script) upon network initialization.

Say you want to fund accounts on your appchain or run a command to check account balances, Pop CLI allows you to do this via the `--cmd` option that is included in the `pop up network` command:

```
pop up network --help
```

To run a command post-initialization of the network, you can use the `--cmd` flag:

```bash
pop up ./tests/networks/pop.toml --cmd path/to/command
```

Here is an example of a simple script to update account balances on the Polkadot Relay chain:

[https://github.com/brunopgalvao/set-balance](https://github.com/brunopgalvao/set-balance/blob/main/src/main.rs)

Clone and compile the script:

```bash
git clone https://github.com/brunopgalvao/set-balance
cd set-balance
cargo build
```

Create a simple zombienet network.toml file to spin up the Polkadot Relay chain:

```bash
touch network.toml
```

```toml
[relaychain]
chain = "paseo-local"

[[relaychain.nodes]]
name = "alice"
rpc_port = 8833
validator = true

[[relaychain.nodes]]
name = "bob"
validator = true
```

Spin up the Polkadot Relay chain with Pop CLI:

```
pop up network ./network.toml -r v1.8.0 --cmd ./target/debug/set-balance
```

```
┌   Pop CLI : Launch a local network
│
◓  Spinning up network & running command: ../set-balance/target/debug/set-balance                                                                                                             Connecting to the Relay chain...
Preparing to set Alice's balance...
New balance to be set for Alice: 3000000000000000000000
Creating SUDO call to set Alice's balance...
Submitting the transaction to set Alice's balance...
◓  Spinning up network & running command: ../set-balance/target/debug/set-balance                                                                                                             Alice's balance has been successfully set to: 3000000000000000000000
◇  🚀 Network launched successfully - ctrl-c to terminate
│  ⛓️ paseo-local
│       alice:
│         portal: https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:8833#/explorer
│         logs: tail -f /var/folders/vl/txnq6gdj22s9rn296z0md27w0000gn/T/zombie-4299a032-01d0-4704-9c80-64f09b387aec/alice/alice.log
│       bob:
│         portal: https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:53017#/explorer
│         logs: tail -f /var/folders/vl/txnq6gdj22s9rn296z0md27w0000gn/T/zombie-4299a032-01d0-4704-9c80-64f09b387aec/bob/bob.log
│
```

Pop CLI has spun up the Polkadot network and executed the post-startup script.

Alice's account has not been funded!

<figure><img src="/files/01HuOSYP5z32ZlZjUua0" alt="" width="375"><figcaption><p>Alice Dev Account</p></figcaption></figure>

Congrats!

**Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Call

If you run `pop call` without a subcommand, Pop CLI uses `pop call chain` unless it detects a contract project in the current directory. If chain support is disabled and no contract project is detected, it returns an error.

### What Can You Do?

The `pop call chain` command supports three types of operations:

#### 1. Execute Extrinsics

Submit transactions to the chain by calling dispatchable functions. These require signing and will modify chain state.

#### 2. Query Storage

Read storage items from the chain's state. Storage queries don't require signing and can read:

* **Plain storage values** (e.g., System::Number - the current block number)
* **Storage maps** (e.g., System::Account - account information by address)

#### 3. Read Constants

Access constant values defined in the runtime metadata (e.g., System::Version, System::BlockHashCount).

### Interactive Guidance (Recommended)

Interact with a chain **using** Pop CLI's interactive guidance by simply entering:

```shell
pop call chain
```

First, you will be prompted to select which chain you want to interact with from a list of available chains. You can type to filter the list and quickly find your desired chain. If you want to connect to a custom RPC endpoint, select the **"Custom"** option, which allows you to manually type the chain URL.

After selecting your chain, you will be prompted to select a pallet, then choose what you want to do with that pallet:

* **Execute an extrinsic** (function that modifies state, e.g. balance transfer)
* **Query storage**
* **Read constants**

After making your selection, you'll be guided through providing any required arguments and (for extrinsics) the account to sign the transaction.

### Manual (non-interactive)

If you prefer not to use interactive prompts, you can call the chain by specifying all the required arguments directly:

#### Executing an Extrinsic

You can execute an extrinsic by specifying the pallet and function (dispatchable function name) and any arguments.

> \[!TIP] If you receive "Pallet not found" or "Function not found" errors, double-check the case of your pallet and function names. Common examples: use "Balances" (not "balances"), "transfer\_keep\_alive" (not "transferKeepAlive").

```shell
pop call chain --pallet System --function remark --args "0x11" --url ws://localhost:9944 --suri //Alice --sudo
```

To submit directly without the final "submit extrinsic?" prompt, add `--execute`:

```shell
pop call chain --pallet System --function remark --args "0x11" --url ws://localhost:9944 --suri //Alice --execute
```

#### Querying Storage

You can query storage items by specifying the pallet and function (storage item name). Storage queries return the current value immediately without requiring transaction signing. You do not need `--skip-confirm` for read-only calls. If the storage item is a map, provide a key with `--args`. In interactive mode, leave the key blank to query all entries. For composite map keys, you can pass tuple-style arguments (for example `(ASSET_ID,ACCOUNT)`), or provide each key part in order.

```shell
pop call chain --pallet Sudo --function Key --url wss://pas-rpc.stakeworld.io -y
```

```shell
pop call chain --pallet System --function Account --args 0xb815821c5b300d1667d5fc081c06cc4b6addffb90464d68d871ee363b01a127c --url wss://pas-rpc.stakeworld.io -y
```

```shell
# Composite-key storage example (tuple-style key)
pop call chain --pallet Assets --function Account --args '(1984,5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY)' --url ws://localhost:9944/
```

#### Reading Constants

Query constant values from the runtime. Constants are read directly from metadata and don't require signing or keys.

```shell
pop call chain --pallet System --function Version --url wss://pas-rpc.stakeworld.io -y
```

```shell
pop call chain --pallet System --function BlockHashCount --url wss://pas-rpc.stakeworld.io -y
```

### Additional Options

**When do you need signing?**

You need a signer for extrinsics only. Storage queries and constants never require signing.

#### View Metadata

Use `--metadata` to inspect runtime metadata. If you omit `--pallet`, Pop CLI lists all pallets. If you include `--pallet`, it lists calls, storage, and constants for that pallet.

`--metadata` conflicts with `--function`, `--args`, `--suri`, `--use-wallet`, `--call`, and `--sudo`.

```shell
pop call chain --metadata --url ws://localhost:9944/
```

```shell
pop call chain --pallet System --metadata --url ws://localhost:9944/
```

#### Sudo Calls

To dispatch a call with Root origin when the chain's runtime includes `pallet-sudo`, you can wrap the call in a `sudo.sudo()` call by using the `--sudo` flag:

```shell
pop call chain --pallet System --function remark --args "0x11" --url ws://localhost:9944 --suri //Alice --sudo
```

#### Using Wallet for Signing

You can use a browser extension wallet to sign extrinsics instead of providing a secret URI:

```shell
pop call chain --pallet System --function remark --args "0x11" --url ws://localhost:9944/ --use-wallet
```

Or use the shorthand `-w`:

```shell
pop call chain --pallet System --function remark --args "0x11" --url ws://localhost:9944/ -w
```

#### Direct Call Data Submission

If you already have the SCALE-encoded call data and want to directly submit the extrinsic:

```shell
pop call chain --call 0x00000411 --url ws://localhost:9944/ --suri //Alice
```

`--call` conflicts with `--pallet`, `--function`, and `--args`.

```
┌   Pop CLI : Call a chain
│
⚙  Encoded call data: 0x00000411
│  
◇  Do you want to submit the extrinsic?
│  Yes 
│
◇  Extrinsic submitted successfully with hash: "0x60b10fa42fa7bb9e36460d199cef55b28b41dae3f9bb3326fc0e584009ce305b"
│
└  Call complete.
```

#### Skip Confirmation

Use the `--skip-confirm` or `-y` flag to automatically submit extrinsics without prompting for confirmation. This also prevents the prompt to perform another call:

```shell
pop call chain --pallet System --function remark --args "0x11" --url ws://localhost:9944/ --suri //Alice -y
```

If you use `--skip-confirm` with an extrinsic, you must provide a signer with `--suri` or `--use-wallet`.

This is particularly useful for scripting and automation.

If you only want to skip the submit confirmation (but keep other interactive prompts), use `--execute`.

#### Exit Codes for Automation

`pop call chain` exits with a non-zero code when a call fails (for example RPC errors, invalid pallet/function names, or failed submission). This makes shell scripting and CI checks reliable.

### Upcoming: JSON mode (`#993`, pending merge)

`pop call chain` is planned to support global `--json` with structured envelopes once [`#993`](https://github.com/r0gue-io/pop-cli/pull/993) merges.

Planned usage:

```shell
pop --json call chain --pallet System --function remark --args 0x11 --url ws://localhost:9944 --suri //Alice --execute
```

Planned behavior:

* Interactive prompts are disabled in JSON mode; required inputs must be passed via flags.
* Errors are returned with typed codes for automation (`INVALID_INPUT`, `PROMPT_REQUIRED`, `NETWORK_ERROR`, `INTERNAL`).

#### Quick URL Entry

When prompted for a chain, you can select "Custom" to quickly type the chain URL manually, accelerating the process when you already know the endpoint.

### Examples

#### Example 1: Query Current Block Number

```shell
pop call chain --pallet System --function Number --url ws://localhost:9944/
```

#### Example 2: Check an Account Balance

```shell
pop call chain --pallet System --function Account --args "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" --url ws://localhost:9944/
```

#### Example 3: Read Runtime Version

```shell
pop call chain --pallet System --function Version --url ws://localhost:9944/
```

#### Example 4: Transfer with Wallet

```shell
pop call chain --pallet Balances --function transfer_keep_alive --args "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty" "1000000000000" --url wss://rpc.polkadot.io --use-wallet
```

#### Example 5: Sudo Call with Auto-confirm

```shell
pop call chain --pallet System --function set_code --args "./runtime.wasm" --url ws://localhost:9944/ --suri //Alice --sudo -y
```

**Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Fork a chain

Fork a live chain and run a local RPC server with pop fork.

Use `pop fork` (alias: `pop f`) to fork a live chain locally and start an RPC server. This command requires a Pop CLI build with the `chain` feature enabled.

## Usage

```bash
pop fork [<CHAIN> | -e <ENDPOINT>] [options]
```

### JSON mode

Use global `--json` for structured detached-fork output:

```bash
pop --json fork paseo --detach
```

JSON mode requirements:

* `--detach` is required.
* You must pass either `<CHAIN>` or `--endpoint`.

## Flags and arguments

| Flag or argument            | Required | Description                                                                                                                                                           |
| --------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<CHAIN>`                   | No       | Well-known chain to fork (for example: `paseo`, `polkadot`, `kusama`, `westend`, `asset-hub`, `asset-hub-polkadot`).                                                  |
| `-e, --endpoint <ENDPOINT>` | No       | RPC endpoint URL to fork. Parsed as a URL. If omitted, Pop starts an interactive chain/endpoint selection flow.                                                       |
| `-c, --cache <PATH>`        | No       | Path to a SQLite cache file. If omitted, Pop uses an in-memory cache.                                                                                                 |
| `-p, --port <PORT>`         | No       | Port for the local RPC server. If omitted, Pop auto-selects an available port starting from `9944`.                                                                   |
| `--mock-all-signatures`     | No       | Accept all signatures as valid for dev/testing. Default is to accept only magic signatures (`0xdeadbeef`). Do not use for production or security-sensitive scenarios. |
| `--dev`                     | No       | Fund well-known dev accounts (Alice, Bob, Charlie, Dave, Eve, Ferdie) and set Alice as sudo when supported by the chain.                                              |
| `--at <BLOCK_NUMBER>`       | No       | Fork at a specific block number. If omitted, Pop forks at the latest finalized block.                                                                                 |
| `-d, --detach`              | No       | Run the fork in the background. Pop waits until the fork is ready, then prints endpoint info, PID, and log file path.                                                 |

## Behavior notes

* If you do not pass `<CHAIN>` or `--endpoint`, Pop prompts you to pick a chain RPC endpoint.
* When you pass a well-known `<CHAIN>`, Pop tries its known RPC endpoints and falls back to the next endpoint if one fails.
* Pop waits for Ctrl+C. On shutdown, it stops all servers, clears local storage, and warns if cleanup fails.
* When you use `--detach`, Pop starts a background process and waits until the fork is ready before returning. To stop it, run `pop clean node --pid <PID>` or `kill -9 <PID>`.
* If you do not specify a fork point, Pop uses the latest finalized block from the remote RPC as the fork point.
* Storage is fetched lazily from the live chain and cached in SQLite. With `--cache`, the cache is persisted on disk. Without it, Pop uses an in-memory cache.
* After forking, Pop prints explorer links for Polkadot.js Apps and PAPI for the local endpoint.
* Use `RUST_LOG` to control logging (for example: `RUST_LOG=info,pop_fork=debug pop fork paseo`).

## Interactive flow

Use interactive mode when you don't want to pass source flags up front:

1. Run `pop fork`.
2. Select a chain source (for example Local, a known chain, or Custom URL).
3. If needed, provide a custom RPC endpoint URL.
4. Pop starts the fork and prints the local WebSocket RPC URL you can connect to.

## Examples

```bash
# Fork a live chain (uses latest finalized block)
pop fork paseo
```

```bash
# Fork from a specific RPC endpoint
pop fork -e wss://rpc.polkadot.io
```

```bash
# Fork at a specific block
pop fork polkadot --at 1234
```

```bash
# Fork with persistent cache for fast restarts
pop fork -e wss://rpc.polkadot.io --cache ./polkadot-fork.db
```

```bash
# Fork with signature mocking (accept any signature)
pop fork -e wss://rpc.polkadot.io --mock-all-signatures
```

```bash
# Fork and fund dev accounts
pop fork paseo --dev
```

```bash
# Fork in the background and return once ready
pop fork kusama --detach
```

```bash
# Fork Asset Hub (Polkadot)
pop fork asset-hub-polkadot --detach
```

## Example workflow

1. Start the fork.

```bash
pop fork westend --port 9944
```

2. Connect a client to the local RPC endpoint in Polkadot.js Apps.

```
ws://127.0.0.1:9944
```

3. Submit transactions and query state against the local RPC endpoint.

## Supported RPC methods

Use `rpc_methods` to list every supported method at runtime. The fork RPC server exposes these namespaces and methods:

| Namespace | Methods                                                                                                                                                                                                                                                                 |
| --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `chain`   | `chain_getBlockHash`, `chain_getHeader`, `chain_getBlock`, `chain_getFinalizedHead`, `chain_subscribeNewHeads`, `chain_unsubscribeNewHeads`, `chain_subscribeFinalizedHeads`, `chain_unsubscribeFinalizedHeads`, `chain_subscribeAllHeads`, `chain_unsubscribeAllHeads` |
| `state`   | `state_getStorage`, `state_getMetadata`, `state_getRuntimeVersion`, `state_getKeysPaged`, `state_call`, `state_queryStorageAt`, `state_subscribeRuntimeVersion`, `state_unsubscribeRuntimeVersion`, `state_subscribeStorage`, `state_unsubscribeStorage`                |
| `system`  | `system_chain`, `system_name`, `system_version`, `system_health`, `system_properties`, `system_localPeerId`, `system_nodeRoles`, `system_localListenAddresses`, `system_chainType`, `system_syncState`, `system_accountNextIndex`                                       |
| `author`  | `author_submitExtrinsic`, `author_pendingExtrinsics`                                                                                                                                                                                                                    |
| `dev`     | `dev_newBlock`                                                                                                                                                                                                                                                          |

Additional namespaces are available, including `archive`, `chainHead`, `chainSpec`, `payment`, and `transaction`. Use `rpc_methods` to see the full list.

Polkadot.js compatibility aliases are also registered for `chain_subscribeNewHead` and `chain_unsubscribeNewHead`.

```
```


# Securely Sign Transactions from CLI

Pop CLI provides an option to securely sign transactions from the CLI. It does this by opening a signing portal allowing you to sign the transactions using your browser extension wallet.

## Example Usage

For a full guide on calling a chain from Pop CLI, see the [Call a Chain](/chains/guides/call-a-chain) guide.

Normally, you would provide `--suri=<private-key>` to interact with the chain. However, this implies a potentially insecure way of handling private keys and should only be used for development accounts. For production accounts and more secure signing, Pop CLI provides the `--use-wallet` option that you can use.

Here is an example of calling a chain using `--use-wallet`:

```bash
pop call chain --pallet System --function remark --args "0x11" --url ws://localhost:9944/ --use-wallet --skip-confirm
```

This will open a signing portal in your browser. Pop CLI will display the following:

```bash
◇  Wallet signing portal started at http://127.0.0.1:9090.
│
◒  Waiting for signature... Press Ctrl+C to terminate early.
```

Your browser will open a new tab with the following screen at <http://127.0.0.1:9090> (or similar if the port is already in use);

<figure><img src="/files/D07lAV1d7DgT5Fw0vl7f" alt="" width="450"><figcaption><p>Signing Portal Initial Open</p></figcaption></figure>

Click on the `Connect Wallet` button to connect your browser extension wallet.

<figure><img src="/files/8liaLDN4cOqmxqn6gQhJ" alt="" width="450"><figcaption><p>Connect Wallet</p></figcaption></figure>

After connecting your wallet, you will have the option to choose your account and sign the transaction, and finally see the transaction details for signing.

<figure><img src="/files/5RwHii6Q2N00m5rSlRy9" alt="" width="450"><figcaption><p>Transaction Details</p></figcaption></figure>

Once ready to sign, pressing the `Submit` button will open your wallet for signature.

> ⚠️ **It is important to verify transaction details in your wallet before signing.**

<figure><img src="/files/YTTeT30xF3xjlJv4jglb" alt="" width="450"><figcaption><p>Opened Wallet for Signing</p></figcaption></figure>

Signing the transaction will show a success message in the portal. You may close the portal after signing.

After the signed transaction is received, the portal will send the transaction payload to Pop CLI, which will then submit the transaction to the chain.

```bash
◆  Signed payload received.
│
◇  Extrinsic submitted with hash: "0x039076e2760eb1a4d41bf4daf009a0376ba128bd8c51cf365e4a5c5dee07a414"
│
◆  Do you want to perform another call?
│  ○ Yes  / ● No
└
```

**Need help?**

Ask on [Polkadot Stack Exchange](https://polkadot.stackexchange.com/) (tag it [`pop`](https://substrate.stackexchange.com/tags/pop/info)) or drop by [our Telegram](https://t.me/onpopio). We're here to help!


# Hash

Hash data quickly for identifiers, integrity checks, and tooling when building on Polkadot with Pop CLI.

When you're building on Polkadot, you'll often need [hashes](https://docs.polkadot.com/polkadot-protocol/parachain-basics/cryptography/#hash-functions) — to verify files, derive stable identifiers, or work with chain primitives. The `pop hash` command gives you a fast, convenient way to generate these hashes without juggling separate tools.

You can also run the command as `pop h`.

## What you can use it for

* Verify the integrity of artifacts (WASM, configs, datasets) before committing or deploying.
* Turn strings or hex into deterministic IDs for testing or scripting.
* Hash raw transaction/storage bytes when inspecting or debugging.
* Produce quick, non-cryptographic checksums during development loops.

## Quick examples

```bash
# Verify a string or small blob (cryptographic)
pop hash sha2 256 "hello world"

# Hash raw hex bytes (great for tx/storage inspection)
pop hash keccak 256 0x68656c6c6f776f726c64

# Check a runtime you are about to deploy
pop hash blake2 256 /path/to/your/file.wasm

# Append the original bytes to the hash (BLAKE2 or TwoX only)
pop hash blake2 256 --concat "hello world"
```

## Supported algorithms and lengths

| Subcommand | Alias | Lengths (bits)    | `--concat` |
| ---------- | ----- | ----------------- | ---------- |
| `blake2`   | `b2`  | 64, 128, 256, 512 | Yes        |
| `keccak`   | `kk`  | 256, 512          | No         |
| `sha2`     | `s2`  | 256               | No         |
| `twox`     | `xx`  | 64, 128, 256      | Yes        |

## Input handling

The positional `data` argument is inspected in this order:

* If it matches an existing path, Pop reads the file contents. The file must be 3 MiB or smaller.
* If it starts with `0x`, Pop parses it as hex bytes.
* Otherwise, Pop hashes the raw string bytes.

## Output

Pop prints the hash as lowercase hex without a `0x` prefix. If you use `--concat`, the output is the hash bytes followed by the original input bytes, all hex-encoded.

## Errors and constraints

* Unsupported length: `unsupported length: <length>`
* Path exists but is not a file: `specified path is not a file`
* File too large: `file size exceeds maximum code size`

## Tips

* Input can be plain text, 0x-prefixed hex, or a file path — Pop detects it for you.
* Choose the algorithm that fits the job:
  * SHA-2: dependable, broadly used.
  * BLAKE2: fast and secure (widely used in the Polkadot ecosystem).
  * Keccak: common in EVM tooling and ecosystems.
  * xxHash (TwoX): very fast, non-cryptographic for dev workflows.
* Pick an output length that matches your target (256-bit is a solid default; 512-bit for extra margin, 64/128-bit for speedier non-crypto checks).


# Clean local resources

Clean Pop CLI caches, local nodes, or running networks.

Use `pop clean` to remove cached artifacts, stop local nodes, or shut down running networks created by Pop.

You can also run the command as `pop C`.

## Subcommands

* `cache` (alias: `c`): remove cached artifacts.
* `node` (alias: `n`): stop local forks, `ink-node`, and `eth-rpc` processes.
* `network` (alias: `net`): stop local networks created by `pop up`.

## Usage

```bash
pop clean <cache|node|network> [OPTIONS] [PATH]
```

### JSON mode

Use global `--json` for structured output:

```bash
pop --json clean cache --all
pop --json clean node --all
pop --json clean network --all
```

JSON mode requirements:

* `clean cache`: requires `--all`
* `clean node`: requires `--all` or `--pid`
* `clean network`: requires `--all` or `PATH`

## Examples

```bash
# Clean cache entries interactively
pop clean cache

# Remove all cache entries without prompting
pop clean cache --all

# Stop all detected local nodes
pop clean node --all

# Stop specific node PIDs (all must be valid)
pop clean node --pid 1234 5678

# Stop a single network by path to zombie.json
pop clean network /path/to/zombie.json

# Stop a network by directory containing zombie.json
pop clean network /path/to/network-dir

# Stop all networks
pop clean network --all

# Stop a network but keep its state on disk
pop clean network --keep-state
```

## Cache cleanup

`pop clean cache` uses the Pop cache directory at `~/.cache/pop` (or your OS equivalent).

* Without `--all`, Pop prompts you to select which artifacts to delete and asks for confirmation.
* With `--all`, Pop deletes everything without confirmation.
* `--pid` is accepted but has no effect for cache cleanup.

If the cache directory does not exist or is empty, Pop prints a message and exits without changes.

## Node cleanup

`pop clean node` looks for local `ink-node`, `eth-rpc`, and detached `pop fork` processes.

* With `--all`, Pop kills every detected process without confirmation.
* With `--pid`, Pop validates every PID against the detected list. If any PID is invalid, Pop cancels and kills nothing.
* Without `--all` or `--pid`, Pop prompts you to select processes and confirm.

Pop uses `pgrep`, `lsof`, and `kill -9` for detection and shutdown.

If you started a detached fork with `pop fork --detach`, you can stop it with `pop clean node --pid <PID>`.

## Network cleanup

`pop clean network` stops networks created by Pop using Zombienet configs.

* If you provide a `PATH`, it must be a `zombie.json` file or a directory containing `zombie.json`.
* With `--all`, Pop stops all discovered networks without prompting.
* Without `PATH` or `--all`, Pop searches your temp directory for `zombie-<uuid>/zombie.json` entries (skipping any marked with `.CLEARED`) and prompts you to select and confirm.
* With `--keep-state`, Pop stops the network but keeps its state on disk and writes a `.CLEARED` marker.

`pop clean network` requires the `chain` feature. If you installed a contract-only build, this subcommand fails with: `network cleanup requires the \`chain\` feature\`.

## Errors and constraints

* Missing `zombie.json` path: the path must point to `zombie.json` or a directory that contains it.
* Missing cache directory or empty cache: Pop exits without making changes.


# Conversions

Convert addresses between Ethereum and Polkadot formats seamlessly when building cross-chain applications with Pop CLI.

When building applications that bridge Ethereum and Polkadot ecosystems, you'll frequently need to convert addresses between formats. The `pop convert address` command provides a reliable way to transform Ethereum addresses to Substrate/Polkadot addresses and vice versa.

You can also run the command as `pop cv address` or `pop convert a`.

## What you can use it for

* Convert Ethereum addresses to Polkadot/Substrate format for cross-chain operations.
* Transform Polkadot addresses back to Ethereum format for EVM compatibility layers.
* Generate addresses with different SS58 prefixes for various Substrate-based chains.
* Validate address formats and ensure proper cross-chain address mapping.
* Facilitate user experience in multi-chain applications by supporting both address formats.

## Quick examples

```bash
# Convert an Ethereum address to Polkadot format (default prefix 0)
pop convert address 0x742d35Cc6634C0532925a3b844Bc454e4438f44e

# Convert to a specific Substrate chain format (e.g., Kusama prefix 2)
pop convert address 0x742d35Cc6634C0532925a3b844Bc454e4438f44e 2

# Convert a Polkadot address back to Ethereum format
pop convert address 13dKz82CEiU7fKfhfQ5aLpdbXHApLfJH5Z6y2RTZpRwKiNhX

# Convert addresses from different Substrate networks
pop convert address 5Eh2qnm8NwCeDnfBhm2aCfoSffBAeMk914NUs8UDGLuoY6qg
```

## Input formats

`<ADDRESS>` can be one of:

* Ethereum address: `0x` + 40 hex characters.
* Public key: `0x` + 64 hex characters.
* Substrate address: SS58-encoded string.

## How it works

The conversion uses a standardized mapping between Ethereum and Substrate address formats:

* **Ethereum → Substrate**: Takes the 20-byte Ethereum address and extends it with 12 bytes of `0xEE` padding, then encodes it using SS58 format.
* **Substrate/Public key → Ethereum**:
  * If the last 12 bytes are `0xEE`, Pop treats it as an Ethereum-derived address and returns the first 20 bytes.
  * Otherwise, Pop computes `keccak256` of the 32-byte public key and returns the last 20 bytes.

## Output

Pop prints the converted address to stdout. Ethereum outputs are `0x`-prefixed lowercase hex.

## Errors and constraints

* Ethereum inputs must be `0x`-prefixed and exactly 40 hex characters.
* Public keys must be `0x`-prefixed and exactly 64 hex characters.
* Invalid SS58 strings fail validation.

## Tips

* **SS58 prefixes**: Different Substrate chains use different prefixes (Polkadot: 0, Kusama: 2, Generic Substrate: 42). The tool defaults to Polkadot (0) if no prefix is specified.
* **Case sensitivity**: Ethereum addresses are case-insensitive for conversion purposes.
* **Validation**: The tool validates address formats and will reject invalid inputs with clear error messages.
* **Bidirectional**: Pop automatically detects whether you're providing an Ethereum (0x-prefixed) or Substrate address and converts accordingly.
* **Cross-chain compatibility**: Only Substrate addresses originally derived from Ethereum addresses can be converted back (they must have the `0xEE` padding in the last 12 bytes).


