How to Generate Cardano Payment and Stake Keys from a Trezor Model T Seed Phrase

Here is a recipe for recovering payment and stake keys if a Trezor Model T is lost or damaged and a new Trezor Model T is not available. (Note that performing this procedure defeats the purpose of using a hardware wallet, however, since it involves typing seed phrases on a computer.) This procedure also works for seed phrases from Daedalus wallets and perhaps also for those from Yoroi wallets; it does not work with the Ledger Nano X–see this Reddit comment for an indication that the mnemonics differ between Ledger and Daedalus. Always use best practices (e.g., a well-secured air-gapped computer) for working securely with seed phrases and for generating private/secret key files.

Prerequisites

This procedure requires cardano-wallet and cardano-cli.

Recovering the root private key.

Enter the 12-word passphrase (Trezor Model T) or 24-word passphrase (Shelley wallet on Daedalus) at the prompt to convert it to the root private key:

BASENAME=my-credentials

cardano-wallet key from-recovery-phrase Shelley > $BASENAME.root.prv

Generate payment keys.

Now generate the private key $BASENAME.payment-0.prv for the first wallet address, and its corresponding public key $BASENAME.payment-0.pub:

cardano-wallet key child 1852H/1815H/0H/0/0    < $BASENAME.root.prv      > $BASENAME.payment-0.prv
cardano-wallet key public --without-chain-code < $BASENAME.payment-0.prv > $BASENAME.payment-0.pub

Other payment keys can be generated by incrementing the last number in the derivation path 1852H/1815H/0H/0/0. The payment keys from Trezor Model T are obtained by incrementing this last digit, but those for Daedalus wallets are obtain from incrementing the last digit of the derivation paths 1852H/1815H/0H/0/0 and 1852H/1815H/0H/1/0.

These keys can be converted to the format most convenient for cardano-cli, using the following commands:

cardano-cli key convert-cardano-address-key --shelley-payment-key \
                                            --signing-key-file $BASENAME.payment-0.prv \
                                            --out-file $BASENAME.payment-0.skey
cardano-cli key verification-key --signing-key-file $BASENAME.payment-0.skey \
                                 --verification-key-file $BASENAME.payment-0.vkey

In particular, $BASENAME.payment-0.skey can be used for signing transactions with cardano-cli: this would allow one to move funds secured by the original wallet.

Generate the stake key.

The procedure for generating the stake key is similar to that for the payment key:

cardano-wallet key child 1852H/1815H/0H/2/0    < $BASENAME.root.prv  > $BASENAME.stake.prv
cardano-wallet key public --without-chain-code < $BASENAME.stake.prv > $BASENAME.stake.pub

cardano-cli key convert-cardano-address-key --shelley-payment-key \
                                            --signing-key-file $BASENAME.stake.prv \
                                            --out-file $BASENAME.stake.skey
cardano-cli key verification-key --signing-key-file $BASENAME.stake.skey \
                                 --verification-key-file $BASENAME.stake.vkey

Generate addresses.

The each payment address is computed from the corresponding payment key and from the stake key:

cardano-cli address build --mainnet \
                          --payment-verification-key $(cat $BASENAME.payment-0.pub) \
                          --stake-verification-key $(cat $BASENAME.stake.pub) \
                          --out-file $BASENAME.payment-0.address

These addresses should match those of the original wallet.

One can also generate the stake address:

cardano-cli stake-address build --mainnet \
                                --stake-verification-key-file $BASENAME.stake.pub \
                                --out-file $BASENAME.stake.address

Addendum

The cardano-address tool performs similar functions to cardano-wallet and cardano-cli.