Credits to ilap and for sure the great COINCASHEW crew. They have already finished almost 100%of the work and I only try to contribute at least a tiny bit.
Most wallets use a recovery phrase / mnemonic seed length of 15 or 24 words. In this expample we will use 24 words.
Benefits of mnemonic based wallets: Track and control pool rewards from any wallet (Daedalus, YOROI or any other wallet) that support stakings.
Good to know: a mnemonic seed phrase is not a pure random number of 15 to 24 words. Words need to be select from a specific library - not all words from all languages are allowed. Indeed, only specific english lowercase words are allowed. Anyway, will not select the words for our seed manually. We will use the cardano-wallet cli, which is part Cardano Walletlibrary.
1. Download latest cardano-wallet release
2. Lets create the wallet with all necessary keys and phrases
# Uncompress the downloaded file in your home directory
cd $HOME
mkdir cardano-wallet
Now pls copy your downloaded cardano-wallet-v20<XX>-<XX>-<XX>-linux64.tar.gz file into the cardano-wallet folder and uncopress it.
<XX> in cardano-wallet-v20<XX>-<XX>-<XX>-linux64.tar.gz might be different at the time you will create your wallet because their is a new release available!
cd $HOME/cardano-wallet
tar -zxvf cardano-wallet-v20<XX>-<XX>-<XX>-linux64.tar.gz
In the next step we will already be able to generate our mnemonic seed phrase with cardano-wallet cli
# Set PATH variable temporary (within the current shell session)
# to use the cli cardano-wallet
cd $HOME/cardano-wallet
export PATH="$(pwd)/cardano-wallet-v20<XX>-<XX>-<XX>-linux64:$PATH"
Lets generate a 24 words long recovery phrase / mnemonic seed phrase by using the cardano-address cli
# cardano-wallet is located in cardano-wallet-v20<XX>-<XX>-<XX>-linux64
cardano-wallet recovery-phrase generate --size 24 > mnemonic-phrase.dat
Lets have a look inside the mnemonic-phrase.dat file
# you will see 24 words randomly choosen from the allowed
nano mnemonic-phrase.dat
# you will see a line of words separated by spaces:
# word1 word2 word3 word4 ... word24
# about about century destroy ... diet
3. Generate your private cardano wallet keys
These steps must be done on an air-gapped machine. That means the PC, notebook, raspberrypi what ever device you use to generate your wallet is NOT connected to the internet and will never be. You will store informations on this enveronment that will allow attackers to steel youf funds!
Make shure to copy mainnet-shelley-genesis.json into your $HOME/cardano-wallet folder
Check if jq (JASON convert) is installed on your system.
If not run: sudo apt-get install jq
If you get the error: E: Couldn't find package jq you need to update your system and include the specific repositories.
TESTNET: change mainnet-shelley-genesis.json to testnet-shelley-genesis.json in extractPoolStakingKeys.sh(NOT TESTED)
Create extractPoolStakingKeys.sh script.
###
### On air-gapped offline machine!
###
cat > extractPoolStakingKeys.sh << HERE
#!/bin/bash
# original work from ilap https://gist.github.com/ilap/3fd57e39520c90f084d25b0ef2b96894
# UPDATE by den-is https://gist.github.com/den-is/0fb758b07cdb68abc968b3dea689fa9b
CADDR=${CADDR:=$( which cardano-address )}
[[ -z "$CADDR" ]] && { echo "cardano-address cannot be found, exiting..." >&2 ; exit 127; }
CCLI=${CCLI:=$( which cardano-cli )}
[[ -z "$CCLI" ]] && { echo "cardano-cli cannot be found, exiting..." >&2 ; exit 127; }
BECH32=${BECH32:=$( which bech32 )}
[[ -z "$BECH32" ]] && { echo "bech32 cannot be found, exiting..." >&2 ; exit 127; }
# Only 24-word length mnemonic is supported only
[[ "$#" -ne 26 ]] && {
echo "usage: $(basename $0) <change index e.g. 0/1 external/internal> <ouptut dir> <24-word length mnemonic>" >&2
exit 127
}
GEN_FILE=${GEN_FILE:="$HOME/cardano-wallet/mainnet-shelley-genesis.json"}
[[ ! -f "$GEN_FILE" ]] && { echo "genesis file does not exit, exiting..." >&2 ; exit 127; }
IDX=$1
shift
OUT_DIR="$1"
[[ -e "$OUT_DIR" ]] && {
echo "The \"$OUT_DIR\" is already exist delete and run again." >&2
exit 127
} || mkdir -p "$OUT_DIR" && pushd "$OUT_DIR" >/dev/null
shift
MNEMONIC="$*"
# Generate the master key from mnemonics and derive the stake account keys
# as extended private and public keys (xpub, xprv)
echo "$MNEMONIC" |\
"$CADDR" key from-recovery-phrase Shelley > root.prv
cat root.prv |\
"$CADDR" key child 1852H/1815H/0H/2/0 > stake.xprv
cat root.prv |\
"$CADDR" key child 1852H/1815H/0H/$IDX/0 > payment.xprv
# XPrv/XPub conversion to normal private and public key, keep in mind the
# keypars are not a valind Ed25519 signing keypairs.
NW=$(jq '.networkId' -r "$GEN_FILE")
NW_ID=$(jq '.networkMagic' -r "$GEN_FILE")
echo "Generating $NW wallet..."
if [ "$NW" == "Testnet" ]; then
NETWORK=0
MAGIC="--testnet-magic $NW_ID"
CONV="bech32 | bech32 addr_test"
else
NETWORK=1
MAGIC="--mainnet"
CONV="cat"
fi
cat payment.xprv |\
"$CADDR" key public --with-chain-code | tee payment.xpub |\
"$CADDR" address payment --network-tag $NETWORK |\
"$CADDR" address delegation $(cat stake.xprv | "$CADDR" key public --with-chain-code | tee stake.xpub) |\
tee base.addr_candidate |\
"$CADDR" address inspect
echo
echo "Generated from 1852H/1815H/0H/$IDX/0"
if [ "$NW" == "Testnet" ]; then
cat base.addr_candidate | bech32 | bech32 addr_test > base.addr_candidate_test
mv base.addr_candidate_test base.addr_candidate
fi
cat base.addr_candidate
echo
# Convert cardano-addresses extended signing keys to corresponding Shelley-format keys.
"$CCLI" key convert-cardano-address-key --shelley-payment-key --signing-key-file payment.xprv --out-file payment.skey
"$CCLI" key convert-cardano-address-key --shelley-stake-key --signing-key-file stake.xprv --out-file stake.skey
# Get verification keys from signing keys.
"$CCLI" key verification-key --signing-key-file stake.skey --verification-key-file stake.evkey
"$CCLI" key verification-key --signing-key-file payment.skey --verification-key-file payment.evkey
# Get non-extended verification keys from extended verification keys.
"$CCLI" key non-extended-key --extended-verification-key-file stake.evkey --verification-key-file stake.vkey
"$CCLI" key non-extended-key --extended-verification-key-file payment.evkey --verification-key-file payment.vkey
# Build stake and payment addresses
"$CCLI" stake-address build --stake-verification-key-file stake.vkey $MAGIC --out-file stake.addr
"$CCLI" address build --payment-verification-key-file payment.vkey $MAGIC --out-file payment.addr
"$CCLI" address build \
--payment-verification-key-file payment.vkey \
--stake-verification-key-file stake.vkey \
$MAGIC \
--out-file base.addr
echo "Important the base.addr and the base.addr_candidate must be the same"
diff -s base.addr base.addr_candidate
echo
cat base.addr
echo
cat base.addr_candidate
popd >/dev/null
HERE
Now we need to add execution permisson to extractPoolStakingKeys.sh
###
### On air-gapped offline machine,
###
chmod +x extractPoolStakingKeys.sh
Extract your keys. Update the command with your mnemonic phrase.
IMPORTANT: Please check carefully if the base.addr and the base.addr_candidate are identical!
Your new staking keys are in the folder extractedPoolKeys/
Now move payment/stake key pair over to your $HOME/key folder
###
### On air-gapped offline machine,
###
cd extractedPoolKeys/
cp stake.vkey stake.skey stake.addr payment.vkey payment.skey base.addr $HOME
cd $HOME
#Rename to base.addr file to payment.addr
mv base.addr payment.addr
payment.addr, or also known as base.addr from this extraction script, will be the cardano address which holds your pool's pledge.
Finally close all your terminal windows and open new ones with zero history.
###
### On air-gapped offline machine,
###
history -c && history -w
Fund your payment address
Copy payment.addr to your hot environment (with internet connection and fully sycroniced node).
Payment address can be funded from your Daedalus / Yoroi wallet.
Run the following to find your payment address.
cat payment.addr
RECOMMENDATION: Only fund the minimum amount of ADA initally to your new payment.addr to test if everything works as expected. The minimum is 1 ADA.
You should be able to:
Receive funds on your payment.addr
Sent funds from your payment.addr to any other wallet address
You could try to send some ADA to: addr1qyrytjmrf37r0cfas4pa9ss3v3tgqy0m7v4ljmkwtj4m33u4y6asl5ruap3hj6cqhyjn7guh9z4a3ya58xdh064zq8yq4n09fd
After funding your account, check your payment address balance.
Before continuing, your nodes must be fully synchronized to the blockchain. Otherwise, you won't see your funds.