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. Make shure to copy mainnet-shelley-genesis.json into your $HOME/cardano-wallet folder

  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. 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.

###
### On air-gapped offline machine,
###
./extractPoolStakingKeys.sh 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. Receive funds on your payment.addr

  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.

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

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:

https://explorer.cardano.org/

https://cardanoscan.io (TESTNET available) Simply put the output of $(cat payment.addr) into the search field.

Last updated