How to Secure Pledge with Hardware Wallet

This guide describes the process of adding a hardware wallet as a stake pool owner. That way you can secure your pledge and rewards with a hardware wallet like Trezor or Ledger Nano S+/X

Updated: 8/18/23 - removed --cddl-format \ from transaction build in step 7 part 2.

There are basically 3 main things we need to do in order to add hardware wallet: 1) Install cardano-hw-cli on air gapped machine to generate keys. 2) Generate new Pool Registration Certificate and build transaction. 3) Witness and Submit transaction for new Pool Registration Certificate to the blockchain

Before we get started

Good to know: The scripts were tested with a Ledger hardware wallet and using the cardano-hw-cli version 1.12.0 (latest available at the time of writing this guide). They should also work with Trezor wallets.

The new owner becomes active after 2 full epochs, the initial owner of the stake pool cannot be replaced with the new one immediately (unless each of the wallets has enough ADA in it to cover the pledge).

After the second owner and its delegation to the stake pool become active, the pledge can be moved from the initial wallet to the hardware wallet and if desired the first wallet can be removed from the stake pool owners. Removing it is optional. Please note that you can't use your hardware wallet as payment wallet yet, so you may want to keep your original pledge wallet to use as payment for pool updates.

Steps we will take in this guide:

Step 1 - Delegate Hardware Wallet to your Pool

First step is to make sure you delegate you hardware wallet which will be your 2nd pool owner, to your stake pool with Daedalus or Yoroi or Eternl or so on.

Remember you will need at least 4 ADA on your hardware wallet in order to delegate to your pool.

Step 2 - Copy cardano-hw-cli Install Files to USB

For this guide we will be downloading cardano-hw-cli_1.12.0-1.deb. For other distributions than Ubuntu or Debian, download the .tar.gz. extract it and copy cardano-hw-cli somewhere in the PATH (in /usr/local/bin or where cardano-cli is) on your air gapped machine.

Download files can be found here: https://github.com/vacuumlabs/cardano-hw-cli/releases/tag/v1.12.0 Reference: https://github.com/vacuumlabs/cardano-hw-cli/blob/develop/docs/installation.md

Step 3 - Copy udev rules from Ledger Site to USB

For this guide we use ledger, The first time you connect your hardware wallet you may need to add the udev rules. (If your device is on and connect but you get an error that your device isn't connected, then you need add_udev_rules.sh)

For Linux copy the following file to your USB: https://raw.githubusercontent.com/LedgerHQ/udev-rules/master/add_udev_rules.sh #Referrence: https://support.ledger.com/hc/en-us/articles/115005165269-Fix-USB-connection-issues-with-Ledger-Live

and

https://github.com/LedgerHQ/udev-rules

Step 4 - Copy Install Files to Air Gapped Machine and Install

Copy cardano-hw-cli install file and add_udev_rules.sh to air gapped machine.

For this guide we copied the .deb file and add_udev_rules.sh to our $NODE_HOME.

Part 1

Copy cardano-hw-cli install files to air gapped machine.

To Install run the following commands:

cd $NODE_HOME
sudo dpkg --install ./cardano-hw-cli_1.12.0-1.deb

Check install version, run:

cardano-hw-cli version

Good to Know: to find location of cardano-hw-cli run: which cardano-hw-cli

Or If you wish to uninstall cardano-hw-cli, run: sudo dpkg --remove cardano-hw-cli

Part 2 (If using Ledger Device)

Now add udev rules by running the following command:

sudo bash add_udev_rules.sh

Step 5 - Generate Verification Key and Hardware Wallet Signing File

We will now use cardano-hw-cli to extract two files from the hardware wallet: 1) The stake key verification key hw-stake.vkey (".vkey") The hw-stake.vkey file will be required when creating the new stake pool registration certificate. and 2) The hardware signing file hw-stake.hwsfile (".hwsfile") The hw-stake.hwsfile file will be required for witnessing transactions with the hardware wallet.

hw-stake.vkey is not sensitive and may be shared publicly. hw-stake.hwsfile does NOT contain the raw private key.

This script must be executed with the hardware wallet connected to the computer and unlocked, and with the Cardano application started. It will be required to confirm the key export on the hardware wallet.

To generate the verification key and hardware wallet signing file, type:

cd $NODE_HOME
cardano-hw-cli address key-gen \
--path 1852H/1815H/0H/2/0 \
--verification-key-file hw-stake.vkey \
--hw-signing-file hw-stake.hwsfile

Step 6 - Create New Stake Pool Registration Certificate

In order to add a new owner to the stake pool, a new stake pool registration certificate needs to be created. This will secure both your pool pledge account and pool reward account with a hardware wallet.

Since we need to create a new stake pool registration certificate we are going to walk through how to create an env file that contains our pool information and a script to generate a new certificate. This will allow us to make future pool changes easier and help avoid errors.

If you want to skip this step you can see an example command to create new stake pool registration certificate with hardware wallet under the "Standard Method" tab below.

ON Air Gapped Machine

Notice the pool-reward-account and additional pool-ownerstake-verification-key-file lines point to hw-stake.vkey.

1) First let's start by creating a pool-scripts folder in our $NODE_HOME.

cd $NODE_HOME
mkdir pool-scripts

2) Let's create an env file for our pool in the pool-scripts folder:

cat > $NODE_HOME/pool-scripts/env << 'EOF' 
#!/bin/bash

PLEDGE=25000000000  # 25,000 ADA
COST=340000000     #  340 ADA
MARGIN=0.01        #    1 %

NET="--mainnet"  #mainnet
RELAY1_HOST=relay1.stakepool.url
RELAY1_PORT=6000
RELAY2_HOST=relay2.stakepool.url
RELAY2_PORT=6000
METADATA_URL=https://stakepool.url/poolmetadata.json
METADATA_HASH=$(cat $NODE_HOME/poolMetaDataHash.txt)
EOF

Edit all the values to match your data. Paths are based on normal coincashew install, please update paths as necessary. The usual values for port are 3001 or 6000, but any valid port can be used.

It is also possible to use IP Addresses

3) Create pool-registration.sh script in the pool-scripts folder:

cat > $NODE_HOME/pool-scripts/pool-registration.sh << 'EOF' 
#!/bin/bash


source ./env

cardano-cli stake-pool registration-certificate \
--cold-verification-key-file $HOME/cold-keys/node.vkey \
--vrf-verification-key-file $NODE_HOME/vrf.vkey \
--pool-pledge ${PLEDGE} \
--pool-cost ${COST} \
--pool-margin ${MARGIN} \
--pool-reward-account-verification-key-file $NODE_HOME/hw-stake.vkey \
--pool-owner-stake-verification-key-file $NODE_HOME/stake.vkey \
--pool-owner-stake-verification-key-file $NODE_HOME/hw-stake.vkey \
${NET} \
--single-host-pool-relay ${RELAY1_HOST} \
--pool-relay-port ${RELAY1_PORT} \
--single-host-pool-relay ${RELAY2_HOST} \
--pool-relay-port ${RELAY2_PORT} \
--metadata-url ${METADATA_URL} \
--metadata-hash ${METADATA_HASH} \
--out-file $NODE_HOME/pool.cert
EOF

If you are using IP Addresses instead of hostnames for the registered relays, replace --single-host-pool-relay with --pool-relay-ipv4 in the script.

You can register as many relays as you want (one or more). You just have to repeat the --single-host-pool-relay and --pool-relay-port parameters for each of them.

The pledge wallet and the rewards wallet are the same one in this case. But it is possible to create and set different wallets for them. Paths are based on normal coincashew install, please update paths as necessary.

Next:

Add execute permissions to the pool-registration script.

chmod +x $NODE_HOME/pool-scripts/pool-registration.sh

⚠️The script must be executed in order to generate the new stake pool registration certificate, which will need to be submitted with a transaction.

Run pool-registration script with:

cd $NODE_HOME/pool-scripts
./pool-registration.sh

Step 7 - Build Transaction to Submit Stake Pool Registration Certificate

In order to finish adding the hardware wallet as stake pool owner, we must submit Certificate to the blockchain with transactions.

Part 1 - Copy pool.cert to your hot environment.

Copy your pool.cert from air gapped machine to your node

Part 2 - Build Transaction File (tx.raw)

First find UTXO without NFT and change tx-in Run:

cd $NODE_HOME
cardano-cli query utxo \
    --address $(cat payment.addr) \
    --mainnet

Select UTXO without NFT and change tx-in and don't forget to remove<>

cardano-cli transaction build \
--mainnet \
--witness-override 4 \
--tx-in <example: 45de23872ce59c8b6f2fb5e2f39741e0dd8a45f9b496c46ed117396a21b5f4bc#0> \
--change-address $(cat payment.addr) \
--certificate-file pool.cert \
--out-file tx.raw

Now let's double check that we have the correct values for our pool.cert

To double check that we have the correct values for our pool.cert run:

cardano-cli transaction view \
--tx-body-file tx.raw

Step 8 - Transfer tx.raw to Air Gapped Machine

The transaction for submitting the new stake pool registration certificate needs to be signed with 4 signing keys:

  • Witness cold key (node.skey)

  • Witness payment key -to pay the transaction fees (payment.skey)

  • Witness of the first stake pool owner stake key (stake.skey)

  • the hardware wallet stake key -the new pool owner (hw-stake.hwsfile)

When not using a hardware wallet, the transaction to submit a stake pool registration certificate can be signed with one command.

However due to the way the hardware wallet can sign transactions, the transaction must be witnessed by all 4 signing key, and then all the witness files must be combined into a signed transaction file, which will be submitted to the blockchain.

Now we need to do our 4 witnesses. To do so we need to move back to our air gapped machine. Copy your tx.raw file to you air gapped machine. For this guide we will put it in $NODE_HOME

Step 9 - Witness with Cold Key

Now on air gapped let's create first witness with cold key

cd $NODE_HOME
cardano-cli transaction witness \
--tx-body-file tx.raw \
--signing-key-file $HOME/cold-keys/node.skey \
--mainnet \
--out-file tx-cold.witness

Step 10 - Witness with Payment Key

Still on air gapped machine let's create our 2nd witness with payment key.

As of now you can't use your hardware wallet as payment address so you will need to use any other payment address and use it's payment key below.

cd $NODE_HOME
cardano-cli transaction witness \
--tx-body-file tx.raw \
--signing-key-file payment.skey \
--mainnet \
--out-file tx-payment.witness

If you are able in the future to use your hardware wallet as payment wallet you can export the payment key on your air gapped machine by running the following command. When executing this command, the hardware wallet will need to be connected to the computer and unlocked, and with the Cardano application started. It will be required to confirm the export.

How to Export Payment Key from Hardware Wallet

ON AIR GAPPED MACHINE with Hardware wallet plugged in and unlocked with Cardano app opened:

cd $NODE_HOME
cardano-hw-cli address key-gen \
--path 1852H/1815H/0H/0/0 \
--verification-key-file hw-payment.vkey \
--hw-signing-file hw-payment.hwsfile

Step 11 - Witness with Stake Key of First Pool Owner

Still on air gapped machine let's create our 3nd witness with the stake key of the first pool owner.

cd $NODE_HOME
cardano-cli transaction witness \
--tx-body-file tx.raw \
--signing-key-file stake.skey \
--mainnet \
--out-file tx-stake.witness

Step 12 - Witness with hw-Stake Key

When executing this command, the hardware wallet will need to be connected to the computer and unlocked, and with the Cardano application started. It will be required to confirm the witness.

Still on air gapped machine let's create our 4nd and final witness with the hw-stake key of the second pool owner.

cd $NODE_HOME
cardano-hw-cli transaction witness \
--tx-file tx.raw \
--hw-signing-file hw-stake.hwsfile \
--mainnet \
--out-file tx-hw-stake.witness

Step 13 - Assemble Transaction

Now we will create the signed transaction file, which needs to be submitted to the blockchain. Still on air gapped machine assemble transaction by running the following command:

cd $NODE_HOME
cardano-cli transaction assemble \
--tx-body-file tx.raw \
--witness-file tx-cold.witness \
--witness-file tx-payment.witness \
--witness-file tx-stake.witness \
--witness-file tx-hw-stake.witness \
--out-file tx.multisign

Step 14 - Copy tx.multisign to Hot Environment

Copy your tx.multisign from air gapped machine to your node in hot environment.

Step 15 - Submit Signed Transaction File to the Blockchain

Submit transaction to blockchain with this command:

cd $NODE_HOME
cardano-cli transaction submit \
--tx-file tx.multisign \
--mainnet

Wait a few minutes for transaction to reach chain, then you can go to https://cardanoscan.io/ and search your pool. Then scroll down and click on pool updates tab.

Then click on transaction and scroll down to Pool Certificates tab. Here you can confirm the data submitted.

Remember to clean up files and delete files like tx.raw, tx.multisign and pool.cert from your node.

Also a great time to do another backup!

The new owner becomes active after 2 full epochs

So Remember to wait 2 Epochs before transferring funds between wallets so that your pledge is met.

Verify when your Pool Certificate will be active

You can use cexplorer.io to verify when your pool certificate changes will be active.

Go to cexplorer.io and search for your pool and go to your pool page. Then scroll down on your pool page and click on "About" tab.

Now scroll down to Pool Certificates. Here it will show what epoch your changes will be active. You can also see the updates to your Owner Addresses and Reward Address here.

Congratulations you did it!

Updating your Pool Registration Certificate Moving Forward

Next time you want to update your Pool Registration for example to adjust min fee, margin or pledge you will simply nano your env file on your air gapped machine with the updated info you want to use. Use command:

sudo nano $NODE_HOME/pool-scripts/env

Sample env file:

#!/bin/bash

PLEDGE=25000000000  # 25,000 ADA
COST=340000000     #  340 ADA
MARGIN=0.01        #    1 %

NET="--mainnet"  #mainnet
RELAY1_HOST=relay1.stakepool.url
RELAY1_PORT=6000
RELAY2_HOST=relay2.stakepool.url
RELAY2_PORT=6000
METADATA_URL=https://stakepool.url/poolmetadata.json
METADATA_HASH=$(cat $NODE_HOME/poolMetaDataHash.txt)

Then run Steps 6 through Step 15 again and you are all set!

If you need or want to update relays you will need to nano changes to env file and pool-registration.sh from Step 6

Contributors

Thanks to the following pools for helping to put together these guides. Please consider delegating to their pools to support them. Are you a pool? Consider buying them a coffee

Last updated