# How to Set Up a Multichain Deployment with Multiple Validators Using Starship

> Learn how to set up a multichain deployment with multiple validators using Starship. Define chains and validators in a Helm values file and deploy automatically with a single command.

- Repository: [Hyperweb/starship](https://github.com/hyperweb-io/starship)
- Tags: how-to-guide
- Published: 2026-03-03

---

**To set up a multichain deployment with multiple validators using Starship, define your chains and validator counts in a Helm values file, then run `starship --config <file> install` to deploy the topology automatically.**

Starship is a Helm-based framework maintained by hyperweb-io that orchestrates full blockchain nodes (Cosmos SDK, Ethereum, Solana, etc.) inside Kubernetes clusters. A **multichain deployment with multiple validators** is expressed declaratively through a single YAML configuration, allowing you to spin up interconnected networks without manual node configuration or genesis file distribution.

## Architecture of Multi-Validator Deployments

Starship automates the entire validator lifecycle through Kubernetes-native primitives. The architecture relies on several key components working in concert to bootstrap networks.

### Core Components

- **Helm Chart (`starship/charts/devnet`)**: Templates the Kubernetes resources (StatefulSets, Services, ConfigMaps) for each chain. The validator template at [`templates/chains/cosmos/validator.yaml`](https://github.com/hyperweb-io/starship/blob/main/templates/chains/cosmos/validator.yaml) contains the logic that creates `replicas = numValidators-1` additional validators.
- **Exposer Service**: A sidecar container running alongside each validator that exposes REST (`8081`) and gRPC (`9099`) endpoints, plus an HTTP API for fetching the genesis file (`/genesis`).
- **Registry**: An optional component ([`templates/registry.yaml`](https://github.com/hyperweb-io/starship/blob/main/templates/registry.yaml)) providing unified chain metadata lookup for relayers and external clients.
- **Starship CLI (`cmd/starship`)**: Parses the `--config` flag and orchestrates Helm commands. The entry point is defined in [`cmd/starship/config.go`](https://github.com/hyperweb-io/starship/blob/main/cmd/starship/config.go).
- **Init Scripts**: Bash scripts bundled as ConfigMaps ([`charts/devnet/scripts/create-validator.sh`](https://github.com/hyperweb-io/starship/blob/main/charts/devnet/scripts/create-validator.sh), [`transfer-tokens.sh`](https://github.com/hyperweb-io/starship/blob/main/transfer-tokens.sh), [`chain-rpc-ready.sh`](https://github.com/hyperweb-io/starship/blob/main/chain-rpc-ready.sh)) handle genesis distribution, key recovery, and validator creation automatically.

## Prerequisites and Initial Setup

Begin by cloning the repository and installing the required toolchain.

```bash
git clone https://github.com/hyperweb-io/starship.git
cd starship
make dev-setup

```

Ensure you have a Kubernetes cluster available (Docker Desktop, Kind, or cloud-hosted) and create a target namespace:

```bash
kubectl create namespace starship-e2e-tests

```

## Configuring the Values File for Multiple Validators

The deployment topology is defined in a Helm values file. To run multiple validators for a single chain, set the `numValidators` field greater than `1`.

Create a configuration file based on the example at [`starship/tests/e2e/configs/multi-validator.yaml`](https://github.com/hyperweb-io/starship/blob/main/starship/tests/e2e/configs/multi-validator.yaml):

```yaml
name: starship-e2e-tests
version: 1.7.0

chains:
  - id: osmosis-1
    name: osmosis
    numValidators: 2          # Deploys 1 genesis + 1 additional validator

    ports:
      rest: 1313
      rpc: 26653
      exposer: 38083
      faucet: 8000
    resources:
      cpu: "0.3"
      memory: 600M
    faucet:
      type: starship
      concurrency: 2
      resources:
        cpu: "0.1"
        memory: "200M"

registry:
  enabled: true
  ports:
    rest: 8081
    grpc: 9091

```

When `numValidators` exceeds `1`, the template [`templates/chains/cosmos/validator.yaml`](https://github.com/hyperweb-io/starship/blob/main/templates/chains/cosmos/validator.yaml) sets `podManagementPolicy: Parallel`, allowing additional validators to initialize concurrently.

## Deploying the Multichain Topology

Execute the deployment using the Starship CLI or the provided Makefile:

```bash
make install HELM_FILE=starship/tests/e2e/configs/multi-validator.yaml

```

This command invokes the CLI, which expands internally to:

```bash
helm upgrade --install starship-e2e-tests \
  ./starship/charts/devnet \
  -n starship-e2e-tests \
  -f starship/tests/e2e/configs/multi-validator.yaml

```

Wait for all pods to reach Ready state:

```bash
kubectl -n starship-e2e-tests wait --for=condition=Ready pod --all --timeout=5m

```

Forward ports to interact with the chain locally:

```bash
make port-forward HELM_FILE=starship/tests/e2e/configs/multi-validator.yaml

```

Verify the genesis endpoint is accessible:

```bash
curl -s http://localhost:38083/genesis | jq .chain_id

```

## How Starship Orchestrates Validator Bootstrapping

Starship eliminates manual intervention through a sequence of init containers and post-start hooks defined in [`validator.yaml`](https://github.com/hyperweb-io/starship/blob/main/validator.yaml).

### Genesis Validator Initialization

The first replica (`validator-0`) acts as the genesis creator:

1. Initializes the chain home directory with `chaind init`.
2. Generates the genesis file and stores it in a shared location.
3. Publishes the genesis via the exposer service at `http://<pod-name>:8081/genesis`.

### Additional Validator Join Process

Subsequent validators (`validator-1`, `validator-2`, etc.) run an init container that performs the following actions (excerpt from [`validator.yaml`](https://github.com/hyperweb-io/starship/blob/main/validator.yaml) lines 80-99):

```yaml
- name: init-validator
  image: {{ $chain.image }}
  env:
    - name: KEYS_CONFIG
      value: /configs/keys.json
    - name: GENESIS_HOST
      value: {{ $chain.id }}-validator-0
  command: [ "bash", "-c", '
    VAL_INDEX=${HOSTNAME##*-}
    VAL_NAME=$(jq -r ".validators[0].name" $KEYS_CONFIG)-$VAL_INDEX
    $CHAIN_BIN init $VAL_NAME --chain-id $CHAIN_ID
    jq -r ".validators[0].mnemonic" $KEYS_CONFIG |
      $CHAIN_BIN keys add $VAL_NAME --index $VAL_INDEX --recover --keyring-backend="test"
    curl http://$GENESIS_HOST.$NAMESPACE.svc.cluster.local:$GENESIS_PORT/genesis -o $CHAIN_DIR/config/genesis.json
  ' ]

```

This container:
- Recovers its private key from the [`keys.json`](https://github.com/hyperweb-io/starship/blob/main/keys.json) ConfigMap using the validator index.
- Fetches the genesis file from the genesis validator's exposer.
- Configures `persistent_peers` in [`config.toml`](https://github.com/hyperweb-io/starship/blob/main/config.toml) to establish P2P connectivity.

### Automated Network Participation

After the container starts, a post-start hook (lines 54-78 in [`validator.yaml`](https://github.com/hyperweb-io/starship/blob/main/validator.yaml)) executes:

```yaml
postStart:
  exec:
    command:
      - bash
      - -c
      - |
        set -eux
        VAL_INDEX=${HOSTNAME##*-}
        VAL_NAME="$(jq -r ".validators[0].name" $KEYS_CONFIG)-$VAL_INDEX"
        genesis_host="$GENESIS_HOST.$NAMESPACE.svc.cluster.local"
        until bash -e /scripts/chain-rpc-ready.sh http://$genesis_host:26657; do sleep 10; done
        $CHAIN_BIN keys show $VAL_NAME -a --keyring-backend=test | \
          bash -e /scripts/transfer-tokens.sh - $DENOM http://$genesis_host:8000/credit "true"
        bash -e /scripts/create-validator.sh

```

This hook:
- Polls the genesis validator's RPC until healthy using [`chain-rpc-ready.sh`](https://github.com/hyperweb-io/starship/blob/main/chain-rpc-ready.sh).
- Requests tokens from the faucet via [`transfer-tokens.sh`](https://github.com/hyperweb-io/starship/blob/main/transfer-tokens.sh) if `faucet.enabled` is true.
- Submits a `create-validator` transaction to join the active set.

## Extending to Multiple Chains

To deploy a **multichain** topology, append additional entries to the `chains` list. Each chain receives its own StatefulSet and service endpoints:

```yaml
chains:
  - id: osmosis-1
    name: osmosis
    numValidators: 2
    ports:
      rest: 1313
      rpc: 26653
  - id: cosmoshub-4
    name: cosmoshub
    numValidators: 1
    ports:
      rest: 1317
      rpc: 26657

```

Helm generates distinct resources (`osmosis-validator`, `cosmoshub-validator`) isolated by namespace and service naming conventions.

## Enabling Automated Token Distribution

For validators to self-fund and join the network automatically, configure the Starship-native faucet:

```yaml
faucet:
  type: starship          # Enables built-in faucet

  concurrency: 2
  resources:
    cpu: "0.1"
    memory: "200M"

```

The post-start hook automatically invokes [`transfer-tokens.sh`](https://github.com/hyperweb-io/starship/blob/main/transfer-tokens.sh) against the faucet endpoint (`http://<genesis-host>:8000/credit`) before executing the validator creation script.

## Summary

- **Declare topology** in a single YAML file using the `numValidators` field to scale validator counts per chain.
- **Automate bootstrapping** via init containers in [`templates/chains/cosmos/validator.yaml`](https://github.com/hyperweb-io/starship/blob/main/templates/chains/cosmos/validator.yaml) that distribute genesis files and configure P2P peers without manual SSH.
- **Deploy uniformly** using `starship --config <file> install`, which renders Helm templates and enforces `podManagementPolicy: Parallel` for concurrent validator startup.
- **Fund and validate** automatically through post-start hooks executing [`scripts/transfer-tokens.sh`](https://github.com/hyperweb-io/starship/blob/main/scripts/transfer-tokens.sh) and [`scripts/create-validator.sh`](https://github.com/hyperweb-io/starship/blob/main/scripts/create-validator.sh).
- **Scale to multichain** by adding multiple entries to the `chains` list, with each chain receiving isolated StatefulSets and exposer services.

## Frequently Asked Questions

### What is the minimum number of validators required per chain?

Starship supports deploying a single validator (`numValidators: 1`) for development purposes. However, to test Byzantine fault tolerance or consensus mechanisms, set `numValidators` to `2` or higher. The framework automatically handles the genesis creation for the first replica and joins subsequent validators to the network.

### How does Starship handle genesis file distribution across validators?

The genesis validator (index 0) exposes its genesis file via the sidecar exposer service on port `8081`. Additional validators run an init container that executes `curl` to fetch the genesis from `http://<genesis-host>:8081/genesis` before the chain binary starts, ensuring all validators share identical initial state.

### Can I mix different chain types in a single Starship deployment?

Yes. The `chains` list supports heterogeneous configurations. You can combine Cosmos SDK chains (configured via the cosmos validator template), Ethereum nodes, and Solana validators in the same values file. Each chain definition specifies its own `name`, `image`, and `numValidators`, allowing Starship to render the appropriate Kubernetes resources for each protocol.

### How do I expose local ports to interact with the deployed chains?

Run `make port-forward HELM_FILE=<your-config.yaml>` after deployment. This executes `kubectl port-forward` commands for all services defined in your values file, mapping container ports (e.g., `26657` for RPC, `1317` for REST) to localhost. Alternatively, manually forward specific services using `kubectl port-forward svc/<service-name> <local-port>:<target-port> -n <namespace>`.