> For the complete documentation index, see [llms.txt](https://geldtiger.gitbook.io/geti-explainer/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://geldtiger.gitbook.io/geti-explainer/create-cardano-wallet.md).

# Create Cardano Wallet

{% hint style="success" %}
This tutorial was successful with [**cardano-wallet-v2022-01-18-linux64.tar.gz**](https://github.com/input-output-hk/cardano-wallet/releases/download/v2022-01-18/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)
{% endhint %}

{% hint style="info" %}
Credits to [<mark style="color:green;">**ilap**</mark> ](https://gist.github.com/ilap/3fd57e39520c90f084d25b0ef2b96894)and for sure the great [<mark style="color:green;">**COINCASHEW**</mark>](https://www.coincashew.com/coins/overview-ada/guide-how-to-build-a-haskell-stakepool-node) crew. They have already finished almost 100%of the work and I  only try to contribute at least a tiny bit.
{% endhint %}

{% hint style="danger" %}
Most wallets use a recovery phrase / mnemonic seed length of **15 or 24** words. In this expample we will use **24** words.
{% endhint %}

{% hint style="success" %}
**Benefits of mnemonic based wallets:** Track and control pool rewards from any wallet (Daedalus, YOROI or any other wallet) that support stakings.
{% endhint %}

{% hint style="info" %}
**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 [<mark style="color:green;">specific english lowercase</mark>](https://github.com/input-output-hk/cardano-wallet/blob/master/specifications/mnemonic/english.txt) 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.&#x20;
{% endhint %}

### 1. Download latest cardano-wallet release

{% embed url="<https://github.com/input-output-hk/cardano-wallet>" %}
Link to latest cardano-wallet release
{% endembed %}

### 2. Lets create the wallet with all necessary keys and phrases

```bash
# 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.

{% hint style="info" %}
**\<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!`
{% endhint %}

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

```bash
# 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

```bash
# 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

```bash
# 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

{% hint style="danger" %}
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!
{% endhint %}

{% hint style="info" %}

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 [<mark style="color:yellow;">**specific repositories**</mark>](https://stackoverflow.com/questions/33184780/install-jq-json-processor-on-ubuntu-10-04).
3. **TESTNET:** change `mainnet-shelley-genesis.json` to `testnet-shelley-genesis.json` in `extractPoolStakingKeys.sh` <mark style="color:red;">**(NOT TESTED)**</mark>
   {% endhint %}

Create `extractPoolStakingKeys.sh` script.

```bash
###
### 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`

```bash
###
### On air-gapped offline machine,
###
chmod +x extractPoolStakingKeys.sh
```

Extract your keys. Update the command with your mnemonic phrase.

```bash
###
### On air-gapped offline machine,
###
./extractPoolStakingKeys.sh 0 extractedPoolKeys/ $(cat mnemonic-phrase.dat)
```

{% hint style="danger" %}
**IMPORTANT:** Please check carefully if the **base.addr** and the **base.addr\_candidate** are identical!
{% endhint %}

Your new staking keys are in the folder `extractedPoolKeys/`

Now move `payment/stake` key pair over to your `$HOME/key` folder

```bash
###
### 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
```

{% hint style="info" %}
**payment.addr**, or also known as **base.addr** from this extraction script, will be the cardano address which holds your pool's pledge.
{% endhint %}

Finally close all your terminal windows and open new ones with zero history.

```bash
###
### On air-gapped offline machine,
###
history -c && history -w
```

{% hint style="success" %}
Congratulations! You have generated all your required keys to interact with the Cardano ecosystem. :thumbsup:
{% endhint %}

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

```bash
cat payment.addr
```

{% hint style="warning" %}
**RECOMMENDATION:** Only fund the minimum amount of ADA initally to your new payment.addr to test if everything works as expected. <mark style="color:purple;background-color:orange;">The minimum is 1 ADA</mark>.

&#x20;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: <mark style="color:green;">`addr1qyrytjmrf37r0cfas4pa9ss3v3tgqy0m7v4ljmkwtj4m33u4y6asl5ruap3hj6cqhyjn7guh9z4a3ya58xdh064zq8yq4n09fd`</mark>
   {% endhint %}

After funding your account, check your payment address balance.

{% hint style="danger" %}
Before continuing, your nodes must be fully synchronized to the blockchain. Otherwise, you won't see your funds.
{% endhint %}

{% tabs %}
{% tab title="MAINNET: Fully Syncronized  Node " %}

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

{% endtab %}

{% tab title="TESTNET: Fully Syncronized  Node " %}

```
cardano-cli query utxo \
    --address $(cat payment.addr) \
    --testnet-magic 1097911063
```

{% endtab %}
{% endtabs %}

You should see output similar to this. This is your unspent transaction output (UXTO).

```
                           TxHash                                 TxIx        Lovelace
----------------------------------------------------------------------------------------
100322a39d02c2ead....                                              0          1000000
```

{% hint style="info" %}
**PLAN B to check the balance:**

[**https://explorer.cardano.org/**](https://explorer.cardano.org/)

[**https://cardanoscan.io**](https://cardanoscan.io) (TESTNET available)\
\
Simply put the output of `$(cat payment.addr)` into the search field.
{% endhint %}
