GETI Explainer

Create Cardano Wallet

On this page I will explain how to generate a Cardano wallet based on mnemonic seed phrase phrase wich gets generated with cardano-wallet CLI.
This tutorial was successful with cardano-wallet-v2022-01-18-linux64.tar.gz
System: Ubuntu 20.04.03 LTS Shell: bash Cardano Node: 1.33.0 (included in cardano-wallet-v2022-01-18)
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 Wallet library.

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!
  1. 1.
    Make shure to copy mainnet-shelley-genesis.json into your $HOME/cardano-wallet folder
  2. 2.
    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.
  3. 3.
    TESTNET: change mainnet-shelley-genesis.json to testnet-shelley-genesis.json in (NOT TESTED)
Create script.
### On air-gapped offline machine!
cat > << HERE
# original work from ilap
# UPDATE by den-is
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
[[ ! -f "$GEN_FILE" ]] && { echo "genesis file does not exit, exiting..." >&2 ; exit 127; }
[[ -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
# 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
MAGIC="--testnet-magic $NW_ID"
CONV="bech32 | bech32 addr_test"
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 "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
cat base.addr_candidate
# 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 \
--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
cat base.addr
cat base.addr_candidate
popd >/dev/null
Now we need to add execution permisson to
### On air-gapped offline machine,
chmod +x
Extract your keys. Update the command with your mnemonic phrase.
### On air-gapped offline machine,
./ 0 extractedPoolKeys/ $(cat mnemonic-phrase.dat)
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
Congratulations! You have generated all your required keys to interact with the Cardano ecosystem.

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:
  1. 1.
    Receive funds on your payment.addr
  2. 2.
    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.
MAINNET: Fully Syncronized Node
TESTNET: Fully Syncronized Node
cardano-cli query utxo \
--address $(cat payment.addr) \
cardano-cli query utxo \
--address $(cat payment.addr) \
--testnet-magic 1097911063
You should see output similar to this. This is your unspent transaction output (UXTO).
TxHash TxIx Lovelace
100322a39d02c2ead.... 0 1000000
PLAN B to check the balance: (TESTNET available) Simply put the output of $(cat payment.addr) into the search field.