- Setup staking cli according to the installation instructions.
- Get a Funded Address and populate the
config.tomlwith its private key. For better security, exportFUNDED_ADDRESS_PRIVATE_KEYas an env var, or even better, use a Ledger hardware wallet and adjustconfig.tomlaccordingly.- Please use hardware wallet for production environment
- Don't commit your
config.tomlfile accidently
- Make sure the wallet is funded with enough balance
- minimum stake: 100,000 MON to register
- sufficient gas to execute the transactions
- Choose between cli or tui mode and execute the
add-validatorworkflow as described below. - Follow the debug and troubleshooting steps below in case of unexpected behaviour or general issues.
monad-keystore to extract private keys and verify the derived keys with their respective public keys!
- Extract your SECP and BLS keys from keystores using the
monad-keystorebinary and the keystore files.
source /home/monad/.env
monad-keystore recover --password "$KEYSTORE_PASSWORD" --keystore-path /home/monad/monad-bft/config/id-secp --key-type secp
monad-keystore recover --password "$KEYSTORE_PASSWORD" --keystore-path /home/monad/monad-bft/config/id-bls --key-type bls- Use the command below and fill in the values carefully before executing the command, if the keys are wrong the funds will be deducted! Replace the variable with actual values.
python staking-cli/main.py add-validator \
--secp-privkey "${SECP_PRIVATE_KEY}" \
--bls-privkey "${BLS_PRIVATE_KEY}" \
--auth-address "${AUTH_ADDRESS}" \
--amount 100_000Authorized address is the address that will have control over validator operations on-chain. This address can be different from the funded address. Make sure you have control over the authorized address you provided.
⚠️ Verify the public keys are matching before enteringyesto continue: If wrong addresses are used, the validator keys will need to rotate and reconfigured.
[13:49:49] INFO SECP Pubkey: 03bbf692002bda53050f22289d4da8fe0bec8b81a6b0d4f641760....
INFO BLS Pubkey: 985d3f7052ac5ad586592ba1a240b0260b5351a9c3973a471fff79....
Do the derived public keys match? (make sure that the private keys were recovered using monad-keystore) [y/n] (n): y
[13:49:52] INFO Tx status: 1
INFO Tx hash: e11114c8e6dd1dc5e0cde400ce5014dab257....Transaction status: 0 means the transaction failed, check debug steps to get the trace.
- Run the staking cli in tui-mode:
python staking-cli/main.py tui- In the
Main Menuchoose option 1 to Add Validator
- Fill in the prompts with the appropriate values
- Verify all the values before executing the transaction
- Make sure the transaction exited with status 1
- Make sure you got a validator-id after command runs
INFO Validator Created! ID: 1, Delegator: 0xF88.....- Make sure you are part of the execution set
python main.py query validator-set --type execution --config-path ~/config.toml | grep {{ SECP PUBKEY }}- Check validator information. After running above command you will get the validator-id of your validator
19: 03bbf6...In this case, 19 is the validator id, it can be used to perform other operations like delegate, undelegate, claim, compound, etc.
- Fetch validator info
python main.py query validator --validator-id 1 --config-path ~/config.toml- Verify all values match in the output
Check transaction status, if 0 the transaction has failed.
For a failed transaction you need to obtain the trace by:
- Getting the tx data:
curl --location 'https://your-monad-rpc-url' \
--header 'Content-Type: application/json' \
--data '{
"jsonrpc":"2.0",
"method":"eth_getTransactionByHash",
"params":[
"0xe57ada....{enter the hash of the failed tx}..."
],
"id":1
}'- Use the data from the above tx to make an
eth_calltx:
curl --location 'https://your-monad-rpc-url' \
--header 'Content-Type: application/json' \
--data '{
"jsonrpc":"2.0",
"method":"eth_call",
"params":[{
"from": "0xf88c... {{ FILL FROM TX DATA }}",
"to": "0x0000000000000000000000000000000000001000 {{ FILL FROM TX DATA }}",
"gas": "0xc350",
"gasPrice": "0xbdfd63e00",
"value": "{{ FILL FROM TX DATA }}",
"data": "0xf145204c0000000000 {{ FILL FROM TX DATA }}.... "
}, "latest"],
"id":1
}'The above would give you the trace response like:
{
"jsonrpc": "2.0",
"error": {
"code": -32603,
"message": "insufficient balance"
},
"id": 1
}In the case you can't debug from the trace, post it on discord or open a ticket.


