Setup Matic Validator Node

We strongly recommend not using a laptop if you are running a full node.

Please note that if you do have a previous setup of Heimdall and Bor installed on your machine, you will have to remove it completely before you proceed. You can follow the instructions in this link to remove Heimdall and Bor completely:

If you're planning on running a Sentry Node alongside your Validator node, we suggest you to use the Sentry Node setup guide to setup your Validator and Sentry nodes simultaneously.

Step 1: Install GO

Install go by following the official docs. Remember to set your $GOPATH, $GOBIN, and $PATH environment variables, for example:

$ mkdir -p $HOME/go/bin
$ echo "export GOPATH=$HOME/go" >> ~/.bash_profile
$ source ~/.bash_profile
$ echo "export GOBIN=$GOPATH/bin" >> ~/.bash_profile
$ source ~/.bash_profile
$ echo "export PATH=$PATH:$GOBIN" >> ~/.bash_profile
$ source ~/.bash_profile

Or we have a script to install go for you

$ curl >
$ bash

Note: Go version 1.11+ is recommended

Step 2: Install RabbitMq

Why do you need RabbitMq?

RabbitMQ is a message-queueing software also known as a message broker or queue manager. Simply said; it is software where queues are defined, to which applications connect in order to transfer a message or messages.

A helper service called bridge which is embedded into heimdall codebase requires rabbit-mq to queue transactions to multiple networks. Installing it should be pretty straightforward. Checkout the download instructions here:

$ rabbitmq-server

Step 3: Install make

You need to install make to run some commands. Using the below commands you can install make depending on your system.

For Ubuntu

$ sudo apt-get install build-essential

For MacOS

$ brew install make

Please note that if you do have a previous setup of Heimdall and Bor installed on your machine, you will have to remove it completely before you proceed. You can follow the instructions in this link to remove Heimdall and Bor completely:

Step 4: Install Heimdall

Next, let's install the latest version of Heimdall. Here, we'll use the master branch, which contains the latest stable release. If necessary, make sure you git checkout the correct released version

$ mkdir -p $GOPATH/src/
$ cd $GOPATH/src/
$ git clone
$ cd heimdall
// Checkout to a public-testnet version.
// For eg: git checkout v0.1.9
$ git checkout <TAG OR BRANCH>
$ make install

That will install the heimdalld and heimdallcli binaries. Verify that everything is OK:

$ heimdalld --help

Set up a new node

$ heimdalld init
$ echo "export HEIMDALLDIR=~/.heimdalld" >> ~/.bashrc
$ source ~/.bashrc

This will emit an output which shows your node id and chain id, these can be changed before starting a chain from the genesis file.

"chain_id": "heimdall-pldzov",
"node_id": "ae8fd49c192f39a400c00b328d4fd109d5bcb71d"

Step 5: Install Bor

$ mkdir -p $GOPATH/src/
$ cd $GOPATH/src/
$ git clone
$ cd bor
// Checkout to a public-testnet version.
// For eg: git checkout v0.1.8
$ git checkout <TAG OR BRANCH>
$ make bor

Now you have bor installed on your local system and the binary is available in the path build/bin/bor

Step 6: Join public testnet

6.1: Get Heimdall genesis config

$ git clone
//NOTE: Do make sure to join the relevant folder
$ cd public-testnets/<testnet version>
// Current testnet version is 2008
// Example: $ cd public-testnets/CS-2008
$ cd without-sentry/
$ echo "export CONFIGPATH=$PWD" >> ~/.bashrc
$ source ~/.bashrc
// copy genesis file to config directory
$ cp $CONFIGPATH/heimdall/config/genesis.json $HEIMDALLDIR/config/genesis.json
// copy config file to config directory
$ cp $CONFIGPATH/heimdall/config/heimdall-config.toml $HEIMDALLDIR/config/heimdall-config.toml

NOTE: In case you do not have a Goerli API key, generate one using:

Add your API key in file ~/.heimdalld/config/heimdall-config.toml under the key "eth_RPC_URL".

Note: If you want to use non-default ports for Heimdall or Bor, Rest server needs flags for new port and non-default node url.

For Example:

heimalld rest-server --heimdalld rest-server --laddr tcp:// --node tcp://localhost:26637

So, if you are using heimdalld-rest-server.service, please edit /etc/systemd/system/heimdalld-rest-server.service with appropriate port and node (heimdalld service) url.

$ heimdalld rest-server --help
Start LCD (light-client daemon), a local REST server
heimdalld rest-server [flags]
--chain-id string The chain ID to connect to
-h, --help help for rest-server
--laddr string The address for the server to listen on (default "tcp://")
--max-open int The number of maximum open connections (default 1000)
--node string Address of the node to connect to (default "tcp://localhost:26657")
--trust-node Trust connected full node (don't verify proofs for responses) (default true)
Global Flags:
--home string directory for config and data (default "/home/ubuntu/.heimdalld")
--log_level string Log level (default "main:info,state:info,*:error")
--trace print out full stack trace on errors
--with-heimdall-config string Heimdall config file path (default <home>/config/heimdall-config.json)

Generate Heimdall private key

If you have received Matic tokens as part of Counter-stake, you need to generate validator key on Heimdall to participate.

The private key required as the input is your Ethereum/Goerli wallet's Private key, where you received the test Matic tokens. You will be able to locate it in the wallet settings, depending on the Ethereum wallet you use.

heimdallcli generate-validatorkey <Your Ethereum/Goerli wallet private key>

This will create priv_validator_key.json in the same folder.

Move this validator key file to heimdall config folder.

mv ./priv_validator_key.json $HEIMDALLDIR/config

6.2: Configure peers for Heimdall

Peers are the other nodes you want to sync to in order to maintain your full node. You can add peers in the file at ~/.heimdalld/config/config.toml under persistent_peers with the format NodeID@IP:PORT or NodeID@DOMAIN:PORT

To see the list of peers, run the following command, you could do so by running the command cat /public-testnets/CS-2008/heimdall/heimdall-seeds.txt.

All you need to do is add 1 Peer from this list to your persistent_peers in the format mentioned above. Make sure that you add at least one peer from the list, else you will run into connection issues. Try to choose a peer randomly from between to ensure you don't overload specific peers.

vi ~/.heimdalld/config/config.toml

6.3: Start & sync Heimdall

Before starting do verify you are on the correct version by running the below command

$ heimdallcli version --long

Run Heimdall

Starting Heimdall is fairly easy, the below command will start heimdall using the genesis file in ~/.heimdalld/config/genesis.json.

$ heimdalld start

In Binaries, running the above command will not create a log. In order to create a log for Heimdall you can run this command instead

$ cd
$ mkdir ~/.heimdalld/logs/
$ heimdalld start > ~/.heimdalld/logs/heimdalld.log 2>&1 &

Run rest-server

The rest-server can be used by external services like explorer, faucets etc to connect to heimdall chain for fetching data and sending transactions.

$ heimdalld rest-server

If you wish to write logs for rest-server you can run this command instead

$ heimdalld rest-server > ~/.heimdalld/logs/heimdalld-rest-server.log 2>&1 &

Run Bridge

Bridge is a helper package that sends transactions to heimdall on behalf of validators. All interactions with other chains happens via this bridge.

$ bridge start --all

Similarly, for Heimdall bridge, you can run this command to write logs for it

$ bridge start --all > ~/.heimdalld/logs/heimdalld-bridge.log 2>&1 &

Note: Bridge won't run without rabbitmq and rest-server so ensure they are running before trying to run bridge.

Reset Heimdall

NOTE: To be used only if you need to restart Heimdall and delete old data in the event of a crash or if there are changes in genesis files.

Use the following to delete blockchain data and reset everything.

$ heimdalld unsafe-reset-all
$ rm -rf $HEIMDALLDIR/bridge

Check sync status

To check the sync status you can run the follwing command on your node

$ curl http://localhost:26657/status
// Output
"jsonrpc": "2.0",
"id": "",
"result": {
"node_info": {
"protocol_version": {
"p2p": "7",
"block": "10",
"app": "0"
"id": "c4abb0ddd80a413f35f9db2d5b4bc573417b95c4",
"listen_addr": "tcp://",
"network": "heimdall-wOVEJp",
"version": "0.31.5",
"channels": "4020212223303800",
"moniker": "Vaibhavs-MacBook-Air.local",
"other": {
"tx_index": "on",
"rpc_address": "tcp://"
"sync_info": {
"latest_block_hash": "E9219F1FBE049B19A919FBF39F46600ADCD7B690C29C92B37408F36046E51C1A",
"latest_app_hash": "99418B51E32845F2164BCBA0772D5D357F548804E66E226287981B61B9A406BD",
"latest_block_height": "3",
"latest_block_time": "2019-12-12T06:45:29.823953Z",
"catching_up": false
"validator_info": {
"address": "EE9DF712A0D9D09A79525ABF05E72D44F796EDD3",
"pub_key": {
"type": "tendermint/PubKeySecp256k1",
"value": "BLwVPibHZJX8//8URR3THmIVSY9lNyuuhCPRjLm57dZP6AJM+XP6Y7nVd3lnZgR1qBOnEnPop8RFEvOUHgeN5X4="
"voting_power": "10"

The key called catching_up will show your sync status, if it's not catching up it means that you are fully synced!

Expected Output

Your heimdall-node should be syncing now! You can check the logs by running the command

$ tail -f ~/.heimdalld/logs/heimdalld.log
$ tail -f ~/.heimdalld/logs/heimdalld-rest-server.log
$ tail -f ~/.heimdalld/logs/heimdalld-bridge.log

If everything's well, then your logs should look something like this:

If you're running into any issues while setting up your Heimdall node, you can refer the Technical FAQs for solutions

You need to make sure that you let Heimdall node sync completely and only then move on to the next steps

6.4: Initialise genesis block for Bor

// Go to 'public-testnets' and testnet version
$ cd $CONFIGPATH/bor
// initialize Genesis Block and peers
$ bash
$ echo "export BORDIR=~/.bor" >> ~/.bashrc

This will create Bor home directory at ~/.bor and data directory at ~/.bor/dataDir

6.5: Configure peers for Bor

To sync blocks on the testnet, you need to add peers. The file static-nodes.json in your relevant public-testnets version folder contains information for all the available seed nodes. It will be already copied using bash command.

Adding additional peers (optional)

If you have certain peers you always want to connect to, you can configure permanent static nodes by putting something like the following example into ~/.bor/dataDir/bor/static-nodes.json


For more info on how to connect to peers see this.

Generate Bor keystore file

To generate a BOR keystore for your validator, you can run the following command. The private key required as the input is your Ethereum/Goerli's wallet Private key. This would be the same private key that yo used for generating your validator-key

heimdallcli generate-keystore <Your Ethereum/>Goerli wallet private key>

Once you run this command you will be requested for a passphrase. A passphrase can be considered as password too. This passphrase will be used to encrypt the keystore file.

This will create a keystore file in UTC format. For example:


Do ls here and you will see the file name in the above format.

Now you will have to move the keystore file to bor data directory.

mv ./UTC-<time>-<address> ~/.bor/keystore/

Add password.txt

Add the password that you entered in the password.txt file

$ vim ~/.bor/password.txt

Add phrase you choose during generating key store file in password.txt

6.7: Start Bor

// You'll find the following in bor directory in Public testnets folder
$ cd $CONFIGPATH/bor
$ bash <Your address>

Expected Output

Your bor-node should be syncing now! Checkout ~/.bor/logs/bor.log to get to the logs 🤩 or you could run the following command:

tail -f ~/.bor/logs/bor.log

If everything's well, then your logs should look something like this:

If you're running into any issues while setting up your Bor node, you can refer the Technical FAQs for solutions.


If your Heimdall and Bor logs are fine, that your node setup is complete. Congratulations on reaching so far!

Once you are done checking the logs or querying the data, you may proceed to staking tokens. Here is you can stake on Matic: How to Stake

In case you encounter blockers or high severity bugs, you can report all such issues/bugs directly to Github issues of respective repositories.

For an issue you have encountered specifically with Heimdall or Heimdall related, you can create an issue in the Heimdall repository:

For issues, you have encountered specifically with Bor or Bor related, you can create an issue in the Bor repository:

For clear identification, you can also use labels to tag the issues reported.

Upon reporting an issue, the Matic Project team will review and update/comment on the status of the issue. Depending on the severity of the issue, the Matic project team may request you to create a PR to provide a fix. Bounties and incentives would be provided for such issues.