locallycompact / cardano-addresses

Addresses and mnemonic manipulation & derivations

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cardano Addresses



Overview

This module provides mnemonic (backup phrase) creation, and conversion of a mnemonic to seed for wallet restoration, and address derivation functionalities.

Documentation

API documentation is available here.

Command-Line

cardano-address comes with a command-line interface for Linux. See the release artifacts or continuous integration artifacts to get a pre-compiled binary, or build a Docker image. The command-line is self explanatory by using --help on various commands and sub-commands.

💡 Most commands read argument from the standard input. This prevent sensitive information from appearing into your shell history and, makes it easy to pipe commands!

How to generate a recovery phrase (phrase.prv)
$ cardano-address recovery-phrase generate --size 15 > phrase.prv
exercise club noble adult miracle awkward problem olympic puppy private goddess piano fatal fashion vacuum
How to generate a root private key (root.xsk)
$ cardano-address key from-recovery-phrase Shelley < phrase.prv > root.xsk
root_xsk1hqzfzrgskgnpwskxxrv5khs7ess82ecy8za9l5ef7e0afd2849p3zryje8chk39nxtva0sww5me3pzkej4rvd5cae3q3v8eu7556n6pdrp4fdu8nsglynpmcppxxvfdyzdz5gfq3fefjepxhvqspmuyvmvqg8983

ℹ️ Notice the root_xsk prefix to identify a root extended signing (private) key.

How to generate a wallet id based on extended root or account keys (phrase.prv)
$ cat root.xsk
root_xsk1hqzfzrgskgnpwskxxrv5khs7ess82ecy8za9l5ef7e0afd2849p3zryje8chk39nxtva0sww5me3pzkej4rvd5cae3q3v8eu7556n6pdrp4fdu8nsglynpmcppxxvfdyzdz5gfq3fefjepxhvqspmuyvmvqg8983
$ cardano-address key walletid < root.xsk
163ea20ad0611e4815a61c44bb32c82a81538999

$ cardano-address key public --with-chain-code < root.xsk | cardano-address key walletid
163ea20ad0611e4815a61c44bb32c82a81538999

$ cardano-address key child 1852H/1815H/0H < root.xsk > acct.xsk
$ cat acct.xsk
acct_xsk15ztha8ws7qjze5vmdkwqh0ddzvtlgstkg79swazhc5lxns2849plr3msjx082mcmd9hc24ujczk2cjnjwrcz4tjaucw9jqf8h5yc7d84rac0zdckkuhazpam0kleg4sq52ph3e0wn98a64hr8g5cpmh9zqpwtrhy
$ cardano-address key walletid < acct.xsk
15fd6c2130b0758ec7995bf9771d2a6602417c39
$ cardano-address key public --with-chain-code < acct.xsk | cardano-address key walletid
15fd6c2130b0758ec7995bf9771d2a6602417c39
How to generate a private policy key (policy.xsk), a public policy key (policy.vk) and its hash (policy.vkh)
$ cardano-address key child 1855H/1815H/0H < root.xsk > policy.xsk
policy_xsk1hr47zvxgzeeutgq50r965ygwxys86cwp8wdjqftlhan8mw6849pus6vc50dznjs5vkyjcz9usl6964u6nha88slrh8hyex74xnlfehcrkp80cp8wgzkqh22dzy7c48ekhhvvf2zz8hqakjwgfzgrjq5lx538et75

$ cardano-address key child 1855H/1815H/0H < root.xsk | cardano-address key public --with-chain-code > policy.xvk
policy_xvk1e9ngmlhcwhszwyuxwc7anwk6tvzwndldz7j262rvfpd049tq74mq8vzwlszwus9vpw556yfa320nd0wccj5yy0wpmdyusjys8ypf7dgaauf0m

$ cardano-address key child 1855H/1815H/0H < root.xsk | cardano-address key public --without-chain-code > policy.vk
policy_vk1e9ngmlhcwhszwyuxwc7anwk6tvzwndldz7j262rvfpd049tq74mq0ylkrs

$ cardano-address key hash < policy.xvk
policy_vkh1qpc9xly4lc7yt98gcf59kdcqcss6dda4u9g72e775yxpxeypamc
$ cardano-address key hash < policy.vk
policy_vkh1qpc9xly4lc7yt98gcf59kdcqcss6dda4u9g72e775yxpxeypamc
$ cardano-address key hash --hex < policy.vk
0070537c95fe3c4594e8c2685b3700c421a6b7b5e151e567dea10c13

ℹ️ The last segment in the path is the key index and can be incremented up to 2^31-1 to derive more keys.

How to generate a payment verification key (addr.xvk)
$ cardano-address key child 1852H/1815H/0H/0/0 < root.xsk | cardano-address key public --with-chain-code > addr.xvk
addr_xvk1grvg8qzmkmw2n0dm4pd0h3j4dv6yglyammyp733eyj629dc3z28v6wk22nfmru6xz0vl2s3y5xndyd57fu70hrt84c6zkvlwx6fdl7ct9j7yc

ℹ️ The last segment in the path is the key index and can be incremented up to 2^31-1 to derive more keys.

How to generate a stake verification key (stake.xvk)
$ cardano-address key child 1852H/1815H/0H/2/0 < root.xsk | cardano-address key public --with-chain-code > stake.xvk
stake_xvk1658atzttunamzn80204khrg0qfdk5nvmrutlmmpg7xlsyaggwa7h9z4smmeqsvs67qhyqmc2lqa0vy36rf2la74ym8a5p93zp4qtpuq6ky3ve

ℹ️ The last segment in the path is the key index and can be incremented up to 2^31-1 to derive more keys.

How to generate a hash for payment verification key (addr.xvk)
$ cardano-address key child 1852H/1815H/0H/0/0 < root.xsk | cardano-address key public --with-chain-code > addr.xvk
addr_xvk1grvg8qzmkmw2n0dm4pd0h3j4dv6yglyammyp733eyj629dc3z28v6wk22nfmru6xz0vl2s3y5xndyd57fu70hrt84c6zkvlwx6fdl7ct9j7yc
$ cardano-address key hash < addr.xvk
addr_vkh12j28hnmtwcp3n08vy58vyf0arnnrhtavu3lrfdztw0j0jng3d6v
$ cardano-address key hash --hex < addr.xvk
54947bcf6b760319bcec250ec225fd1ce63baface47e34b44b73e4f9

ℹ️ The hashing is available for both stake and payment verification keys. Additional flag '--hex' can be used.

How to generate a payment address from a payment key (payment.addr)
$ cardano-address address payment --network-tag testnet < addr.xvk > payment.addr
addr_test1vp2fg770ddmqxxduasjsas39l5wwvwa04nj8ud95fde7f7guscp6v
How to generate a delegated payment address from a stake key (payment-delegated.addr)
$ cardano-address address delegation $(cat stake.xvk) < payment.addr > payment-delegated.addr
addr_test1qp2fg770ddmqxxduasjsas39l5wwvwa04nj8ud95fde7f70k6tew7wrnx0s4465nx05ajz890g44z0kx6a3gsnms4c4qq8ve0n
How to generate a stake address from a stake key (stake.addr)
$ cardano-address address stake --network-tag testnet < stake.xvk > stake.addr
stake_test1urmd9uh08pen8c26a2fn86weprjh52638mrdwc5gfac2u2s25zpat%
How to inspect address
$ echo addr_test1vp2fg770ddmqxxduasjsas39l5wwvwa04nj8ud95fde7f7guscp6v | cardano-address address inspect
{
    "stake_reference": "none",
    "spending_key_hash_bech32": "addr_vkh12j28hnmtwcp3n08vy58vyf0arnnrhtavu3lrfdztw0j0jng3d6v",
    "address_style": "Shelley",
    "spending_key_hash": "54947bcf6b760319bcec250ec225fd1ce63baface47e34b44b73e4f9",
    "network_tag": 0,
    "address_type": 6
}

$ echo addr_test1qp2fg770ddmqxxduasjsas39l5wwvwa04nj8ud95fde7f70k6tew7wrnx0s4465nx05ajz890g44z0kx6a3gsnms4c4qq8ve0n | cardano-address address inspect
{
    "stake_reference": "by value",
    "stake_key_hash_bech32": "stake_vkh17mf09mecwve7zkh2jve7nkggu4azk5f7cmtk9zz0wzhz5efq2w6",
    "stake_key_hash": "f6d2f2ef387333e15aea9333e9d908e57a2b513ec6d762884f70ae2a",
    "spending_key_hash_bech32": "addr_vkh12j28hnmtwcp3n08vy58vyf0arnnrhtavu3lrfdztw0j0jng3d6v",
    "address_style": "Shelley",
    "spending_key_hash": "54947bcf6b760319bcec250ec225fd1ce63baface47e34b44b73e4f9",
    "network_tag": 0,
    "address_type": 0
}

Details about possible address types are following (refer also to cddl )

address_type binary prefix Meaning
0 0000 base address: keyhash28,keyhash28
1 0001 base address: scripthash28,keyhash28
2 0010 base address: keyhash28,scripthash28
3 0011 base address: scripthash28,scripthash28
4 0100 pointer address: keyhash28, 3 variable length uint
5 0101 pointer address: scripthash28, 3 variable length uint
6 0110 enterprise address: keyhash28
7 0111 enterprise address: scripthash28
8 1000 byron/icarus
14 1110 reward account: keyhash28
15 1111 reward account: scripthash28
How to generate a payment verification key for shared wallet (addr_shared.vk, stake_shared.vk)

Let's generate extended root private key for shared style:

$ cardano-address key from-recovery-phrase Shared < phrase.prv > root_shared.xsk

Now generate payment verification key (role=0 is used). Please note that purpose 1854H is used for multisig.

$ cardano-address key child 1854H/1815H/0H/0/0 < root_shared.xsk | cardano-address key public --without-chain-code > addr_shared.vk
addr_shared_vk1a9h46rvjnqquxz02zyesh0ct29szh7vv9x7r2h87ttmnkgrfgguqhz0mtc

Generating delegation verification key is the similar (the only difference is role=2)

$ cardano-address key child 1854H/1815H/0H/2/0 < root_shared.xsk | cardano-address key public --without-chain-code > stake_shared.vk
stake_shared_vk18a8z5dcrlwene88n84j6dm9yvj5rt296fjtresqnunmacetdcymquyq43z

ℹ️ The last segment in the path is the key index, which can be incremented to derive more keys. Up 2^31-1 keys are possible.

How to construct a multisig script hash (script.hash)

We consider addr_shared.1.vk and addr_shared.2.vk obtained like addr_shared.vk but by replacing the final index by 1 and 2 respectively.

$ cardano-address script hash "all [$(cat addr_shared.1.vk), $(cat addr_shared.2.vk)]" > script.hash
script1gr69m385thgvkrtspk73zmkwk537wxyxuevs2u9cukglvtlkz4k

This script requires the signature from both signing keys corresponding to shared_addr.1.vk and shared_addr.2.vk (ie., shared_addr.1.sk and shared_addr.2.sk) in order to be valid. Similarly, we could require only one of the two signatures:

We can also use extended verification, eiher payment or delegation, keys. They can be obtained as the non-extended ones by using --with-chain-code option rather than --without-chain-option as above. They will give rise to the same script hash as for verification keys chain code is stripped upon calculation.

$ cardano-address script hash "any [$(cat addr_shared.1.xvk), $(cat addr_shared.2.xvk)]"
script1gr69m385thgvkrtspk73zmkwk537wxyxuevs2u9cukglvtlkz4k

which is equivalent (functionally, but not in terms of hash value) to :

$ cardano-address script hash "at_least 1 [$(cat addr_shared.1.xvk), $(cat addr_shared.2.xvk)]"
script13uf3fz3ts5srpjc5zcfe977uvnyvp36wcvxuudryegz0zpjlx6a
How to construct a multisig script hash with timelocks
$  cardano-address script hash "all [$(cat addr_shared.1.xvk), $(cat addr_shared.2.xvk), active_from 100, active_until 120]"
How to validate a script
$  cardano-address script validate "at_least 1 [$(cat addr_shared.1.xvk), $(cat addr_shared.2.xvk), $(cat addr_shared.2.xvk)]"
Validated.

$  cardano-address script validate --recommended  "at_least 1 [$(cat addr_shared.1.xvk), $(cat addr_shared.2.xvk), $(cat addr_shared.2.xvk)]"
Not validated: The list inside a script has duplicate keys (which is not recommended)..
How to get preimage for a script
$ cardano-address script preimage "all [addr_shared_vkh1zxt0uvrza94h3hv4jpv0ttddgnwkvdgeyq8jf9w30mcs6y8w3nq, addr_shared_vkh1y3zl4nqgm96ankt96dsdhc86vd5geny0wr7hu8cpzdfcqskq2cp]"
008201828200581c1196fe3062e96b78dd959058f5adad44dd663519200f2495d17ef10d8200581c2445facc08d975d9d965d360dbe0fa63688ccc8f70fd7e1f01135380

$  cardano-address script preimage "all [addr_shared_vkh1zxt0uvrza94h3hv4jpv0ttddgnwkvdgeyq8jf9w30mcs6y8w3nq, active_from 100, active_until 150]"
008201838200581c1196fe3062e96b78dd959058f5adad44dd663519200f2495d17ef10d8204186482051896
How to generate a payment script address from a script hash (script.addr)
$ cardano-address address payment --network-tag testnet < script.hash > script.addr
addr_test1wqqggtajwkxjgf58v452jz6jl87lt32w3mhez5hd7xz6hugp80tta
Correspondence between keys in cardano-addresses and cardano-cli (key.xsk key.xvk key.vk key.hash)
Let's assume we have mnemonic
$ cat recovery-phrase.prv
nothing heart matrix fly sleep slogan tomato pulse what roof rail since plastic false enlist

Construct root extended private key
$ cardano-address key from-recovery-phrase Shelley < recovery-phrase.prv > root.xprv
root_xsk1apjwjs3ksgm5mnnk0cc5v5emgv0hmafmmy8tffay5s2ffk69830whwznr46672ruucdzwwtv9upv72e4ylrypyz5m6cyh0p00t7n3u3agt20lv32j4kxcqlkzu78nzjx0ysxxlc2ghfz9prxfmrds802xsuhh404~

Construct extended private key for account ix=0H, role=0 and address ix=0
$ cardano-address key child 1852H/1815H/0H/0/0 < root.xprv > key.xsk
addr_xsk1kzl5vgev0u843tfnxqcwg0lmaf7zhdhczddaqhas6dp6m6z98302e3avp8mhu94kxkpj2gss064f74km3rrptafh4fsztekz8k5c469shcvx35wrdmus3xemp984lcwhs0jdtl4pfcsrfspe00h9pej6rg8drvcv

Create extended signing key using cardano-cli
$ cardano-cli key convert-cardano-address-key --shelley-payment-key --signing-key-file key.xsk --out-file key.skey
{
    "type": "PaymentExtendedSigningKeyShelley_ed25519_bip32",
    "description": "",
    "cborHex": "5880b0bf46232c7f0f58ad333030e43ffbea7c2bb6f8135bd05fb0d343ade8453c5eacc7ac09f77e16b635832522107eaa9f56db88c615f537aa6025e6c23da98ae8fbbbf6410e24532f35e9279febb085d2cc05b3b2ada1df77ea1951eb694f3834b0be1868d1c36ef9089b3b094f5fe1d783e4d5fea14e2034c0397bee50e65a1a"
}

The cborhex here contains of 4 parts:
1. prefix 5880 - bytestring of 128 bytes
2. signing key (64 bytes) - b0bf46232c7f0f58ad333030e43ffbea7c2bb6f8135bd05fb0d343ade8453c5eacc7ac09f77e16b635832522107eaa9f56db88c615f537aa6025e6c23da98ae8
3. verification key (32 bytes) - fbbbf6410e24532f35e9279febb085d2cc05b3b2ada1df77ea1951eb694f3834
4. chain code (32 bytes) - b0be1868d1c36ef9089b3b094f5fe1d783e4d5fea14e2034c0397bee50e65a1a

Create corresponding verification key using cardano-cli
$ cardano-cli key verification-key --signing-key-file key.skey --verification-key-file key.vkey
{
    "type": "PaymentExtendedVerificationKeyShelley_ed25519_bip32",
    "description": "",
    "cborHex": "5840fbbbf6410e24532f35e9279febb085d2cc05b3b2ada1df77ea1951eb694f3834b0be1868d1c36ef9089b3b094f5fe1d783e4d5fea14e2034c0397bee50e65a1a"
}
The cborhex here contains of 3 parts:
1. prefix 5840 - bytestring of 64 bytes
2. verification key (32 bytes) - fbbbf6410e24532f35e9279febb085d2cc05b3b2ada1df77ea1951eb694f3834
3. chain code (32 bytes) - b0be1868d1c36ef9089b3b094f5fe1d783e4d5fea14e2034c0397bee50e65a1a

Rule for prefixes:
  - CBOR-encoded bytestring (which is what the 58 identifies)
  - size (80 means 128 bytes, whereas 40 means 64 bytes, 20 means 32 bytes)

Create verification key hash using cardano-cli
$ cardano-cli address key-hash --payment-verification-key-file key.vkey > key.hash
0185545935760c5e370d01e6f4fedbb89b7fd79e115f2837cfab9ea8

Alternatively, we can create non-extended key
$ cardano-address key public --without-chain-code < key.xsk > key.vk
addr_vk1lwalvsgwy3fj7d0fy707hvy96txqtvaj4ksa7al2r9g7k6208q6qmrv9k3

Also, take notice that signing key can be translated to cborhex:
$ cat key.xsk | bech32
b0bf46232c7f0f58ad333030e43ffbea7c2bb6f8135bd05fb0d343ade8453c5eacc7ac09f77e16b635832522107eaa9f56db88c615f537aa6025e6c23da98ae8b0be1868d1c36ef9089b3b094f5fe1d783e4d5fea14e2034c0397bee50e65a1a
(signing key and chain code appended)

Moreover, basing on key.vk one can get hash
$ cardano-cli address key-hash --payment-verification-key $(cat key.vk) > key1.hash
0185545935760c5e370d01e6f4fedbb89b7fd79e115f2837cfab9ea8

Within cardano-addresses one can get cborhex of verification key (with chain code)
$ cardano-address key public --with-chain-code < key.xsk | bech32
fbbbf6410e24532f35e9279febb085d2cc05b3b2ada1df77ea1951eb694f3834b0be1868d1c36ef9089b3b094f5fe1d783e4d5fea14e2034c0397bee50e65a1a
(verification key and chain code appended)

Within cardano-addresses one can get cborhex of verification key (without chain code)
$ cardano-address key public --without-chain-code < key.xsk | bech32
fbbbf6410e24532f35e9279febb085d2cc05b3b2ada1df77ea1951eb694f3834
(verification key without chain code)

Then, we can get compute hash (but here we need to use without chain code):
$ cardano-address key public --without-chain-code < key.xsk | cardano-address key hash | bech32
0185545935760c5e370d01e6f4fedbb89b7fd79e115f2837cfab9ea8

Docker Image

Build

$ docker build -t cardano-address .

Run

Use the auto-remove flag --rm when running commands.

$ docker run --rm cardano-address recovery-phrase generate --size 15
dismiss grit bacon glare napkin satisfy tribe proud carpet bench fantasy rich history face north

Use the interactive flag -i when piping stdin

$ echo "addr1gqtnpvdhqrtpd4g424fcaq7k0ufuzyadt7djygf8qdyzevuph3wczvf2dwyx5u" | docker run --rm -i cardano-addresses address inspect
{
    "address_style": "Shelley",
    "stake_reference": "by pointer",
    "spending_key_hash": "1730b1b700d616d51555538e83d67f13c113ad5f9b22212703482cb3",
    "pointer": {
        "slot_num": 24157,
        "output_index": 42,
        "transaction_index": 177
    },
    "network_tag": 0
}

NPM Package

There is an experimental NPM module for JavaScript and TypeScript available, which works in both NodeJS and the browser.

Here is a code sample showing how it can be used:

var cardanoAddresses = require('cardano-addresses')
var addr = 'addr1gqtnpvdhqrtpd4g424fcaq7k0ufuzyadt7djygf8qdyzevuph3wczvf2dwyx5u'

cardanoAddresses.inspectAddress(addr)
  .then(info => console.log(info)

Contributing

Pull requests are welcome.

When creating a pull request, please make sure that your code adheres to our coding standards.


About

Addresses and mnemonic manipulation & derivations

License:Apache License 2.0


Languages

Language:Haskell 85.8%Language:JavaScript 4.1%Language:TypeScript 3.7%Language:Nix 3.6%Language:HTML 1.4%Language:Ruby 0.6%Language:Shell 0.5%Language:Dockerfile 0.3%