Exploring Cardano wallets
Overview#
In this guide, we will show you how to create a Cardano wallet, receive some tAda (test ada) in the testnet network and send basic example transactions. We will explore tools like cardano-cli and cardano-wallet on how they can help with these functionalities.
note
This guide assumes you have installed cardano-node and cardano-cli into your system. If not you can refer to Installing cardano-node guide for instructions on how to do that.
You must also connect your cardano-node to the testnet network and make sure it is fully synchronized.
If you are not sure how to do that, It is recommended to read Running cardano-node guide before proceeding.
Cardano Wallets#
So you installed your cardano-node and got it running, you probably even tried to query some simple blockchain data (If you read Running cardano-node guide). But how do you actually create a Cardano wallet, receive and send some ada or tAda tokens?
First we have to look at the applications we can use to create wallets.
Daedalus : Daedalus Wallet is the official Cardano full-node wallet, which is a GUI (Graphical User Interface) application for the Desktop (Linux, MacOS, Windows). That means that users will get to use a nice UI (User Interface), buttons and layout to interact with the Cardano blockchain.
A full-node wallet basically means that it has to synchronize and download the blockchain first before users are able to send transactions and interact with the wallet.
It is open-source mainly being developed by InputOutputGlobal, the development company behind the Cardano protocol and also one of the three foundational entities of the Cardano project.
Yoroi : Yoroi Wallet is the official Cardano light-wallet, It is available as a mobile application and as a browser extension.
A light-wallet means that users will not be forced to download the entire blockchain, Instead Yoroi has a backend server and downloads the blockchain data for the user without the user exposing sensitive data(Private Keys) to the server and ultimately maintaining security. This achieves a faster experience for the user due to the fact the user will not have to wait for hours before being able to use the wallet.
It is open-source mainly being developed by Emurgo, A company based in Japan which focuses on Business and Enterprise adoption of the Cardano blockchain. It is also one of the three foundational entities of the Cardano project.
cardano-wallet :
cardano-walletis a CLI (Command Line Interface) application that provides Cardano wallet functionalities both via command-line parameters or via a Web API.It is the wallet-backend that Daedalus wallet uses under-the-hood so it is also open-source, one of the many Haskell-based Cardano software components being written by InputOutputGlobal.
You can find
cardano-walletREST API documentation here: https://input-output-hk.github.io/cardano-wallet/api/edge/cardano-cli :
cardano-cliis also a CLI (Command Line Interface) application that provides Cardano wallet functionalities. Butcardano-clipurpose is geared more towards general Cardano functionalities like generating keys, building and submitting transactions, managing stake pools certificates, simple blockchain queries like wallet address UTXO and more.It is part of the
cardano-nodeproject repository, so if you compile and installcardano-nodeyou should also havecardano-clias-well. It is one of the many Haskell-based Cardano software components being written by InputOutputGlobal.
warning
Always download the wallets from official sources. There are many fake wallets, malicious software pretending to be Cardano wallets that could potentially steal your tokens / assets.
Creating a wallet#
As mentioned before, in this guide we will only be focusing on the cardano-cli and cardano-wallet since they provide some level of programmability which is important when we are talking about Cardano integrations for different kinds of use-cases.
Creating a wallet with cardano-cli#
note
In this section, We will use the path /home/user/cardano to store all the cardano-cli related files as an example, please replace it with the directory you have choosen to store the files.
important
Please make sure your cardano-node is connected and synchronized to the testnet network before proceeding.
warning
In a production environment, it might not be a good idea to store wallets / keys in a public server unless you know what you are doing.
First, lets create a directory to store all our keys like so:
mkdir -p /home/user/cardano/keysMake sure we are inside the keys directory like so: cd /home/user/cardano/keys
Next, we generate our payment key-pair using cardano-cli:
cardano-cli address key-gen \--verification-key-file /home/user/cardano/keys/payment1.vkey \--signing-key-file /home/user/cardano/keys/payment1.skeycardano-cli address key-gen : generates a payment key-pair.
--verification-key-file : points to the path where you want to save the vkey file.
--signing-key-file : points to the path where you want to save the skey file.
You should now have two files in your keys directory like so:
/home/user/cardano/keys/βββ payment1.skeyβββ payment1.vkey
0 directories, 2 filesLets try to understand what these keys are used for in a very high-level overview that is relevant to our topic:
.vkey/ Public Verification Key : Is used to derive a Cardano wallet address, a wallet address is basically the hash string value that you share to other users to provide them a way to sendada/tAdaor other assets in the Cardano blockchain into your wallet.The verification key file should look something like this:
{ "type": "PaymentVerificationKeyShelley_ed25519", "description": "Payment Verification Key", "cborHex": "582056a29cba161c2a534adae32c4359fda6f90a3f6ae6990491237b28c1caeef0c4"}.skey/ Private Signing Key : Is used to sign / approve transactions for your wallet. As you can imagine, it is very important to not expose this file to the public and must be kept secure.The signing key file should look something like this:
{ "type": "PaymentSigningKeyShelley_ed25519", "description": "Payment Signing Key", "cborHex": "58208c61d557e1b8ddd82107fa506fab1b1565ec76fe96e8fb19a922d5460acd5a5b"}
Since we now have our payment key-pair, the next step would be to generate a wallet address for the testnet network like so:
cardano-cli address build \--payment-verification-key-file /home/user/cardano/keys/payment1.vkey \--out-file /home/user/cardano/keys/payment1.addr \--testnet-magic 1097911063cardano-cli address build: Generates a wallet address from avkeyfile.--payment-verification-key-file: The path to thevkeyfile to be used for the derivation.--out-file: The path to save the wallet address file.--testnet-magic: The NetworkMagic of the network that where you want to use the wallet address.
You should now have payment1.vkey, payment1.skey and payment1.addr in your keys directory. It should look something like this:
/home/user/cardano/keys/βββ payment1.addrβββ payment1.skeyβββ payment1.vkey
0 directories, 3 filesThe payment1.addr file contains the derived wallet address from your vkey file. It should look something like this:
addr_test1vz95zjvtwm9u9mc83uzsfj55tzwf99fgeyt3gmwm9gdw2xgwrvsa5note
You can derive more than one wallet address from a Public Verification Key for more advanced use-cases using cardano-addresses component. Which we discuss in more details here: @TODO: link to article
mainnetaddresses are prefixed with the string valueaddr1.testnetaddresses are prefixed with the string valueaddr_test1.
If you want to create a wallet address to be used on mainnet, please use the --mainnet flag instead of --testnet-magic 1097911063. You can learn more about the different Cardano blockchain networks here.
Querying the wallet UTXO (Unspent Transaction Output) with cardano-cli#
Now that we have a wallet address, we can then query the UTXO of the address like so:
cardano-cli query utxo \--testnet-magic 1097911063 \--address $(cat /home/user/cardano/keys/payment1.addr)cardano-cli query utxo: Queries the wallet address UTXO.--testnet-magic 1097911063: Specifies that we want to query thetestnetCardano network.--address $(cat /home/user/cardano/keys/payment1.addr): The wallet address string value that we want to query, In this case we read the contents of/home/user/cardano/keys/payment1.addrusing thecatcommand and we pass that value to the--addressflag. That means you could also directly paste the wallet address value like so:
--address addr_test1vz95zjvtwm9u9mc83uzsfj55tzwf99fgeyt3gmwm9gdw2xgwrvsa5You should see something like this:
TxHash TxIx Amount--------------------------------------------------------------------------------------Now you might find it odd that there is not much information in the result that was returned the command, but that is totally normal as there are no available UTXO in the specific wallet address that we have queried just yet as it is a new wallet.
Our next step is to request some tAda from the Cardano Testnet Faucet.
Once you requested some tAda from the Cardano Testnet Faucet we can then run the query again and you should see something like this:
TxHash TxIx Amount--------------------------------------------------------------------------------------cf3cf4850c8862f2d698b2ece926578b3815795c9e38d2f907280f02f577cf85 0 1000000000 lovelaceThis result tells us that there is one UTXO with the amount of 1,000,000,000 lovelaces in our specific wallet address, that means our wallet has a balance of 1,000 tAda.
The result also specifies that the UTXO transaction id (TxHash / TxId) is cf3cf4850c8862f2d698b2ece926578b3815795c9e38d2f907280f02f577cf85 with the transaction index of 0.
note
In the Cardano blockchain, the lovelace is the unit used to represent ada in transactions and UTXO.
Where 1 ada is equal to 1,000,000 lovelace, so moving forward we will be using lovelace instead of ada / tAda.
You can also use the TxHash to view the complete transaction via the Cardano Blockchain Explorer for the relevant network. You can check the specific transaction for the example UTXO here: f3cf4850c8862f2d698b2ece926578b3815795c9e38d2f907280f02f577cf85
To learn more about UTXO (unspent transaction output) and how transactions work for the UTXO Model, we recommend watching this lecture by Dr. Lars BrΓΌnjes, Education Director at InputOutputGlobal.
Creating simple transactions#
To have a clearer understanding of how sending transactions work using cardano-cli, first lets create another wallet like so:
Generate payment key-pair
cardano-cli address key-gen \--verification-key-file /home/user/cardano/keys/payment2.vkey \--signing-key-file /home/user/cardano/keys/payment2.skey Generate wallet address
cardano-cli address build \--payment-verification-key-file /home/user/cardano/keys/payment2.vkey \--out-file /home/user/cardano/keys/payment2.addr \--testnet-magic 1097911063Once complete you should have the following directory structure:
/home/user/cardano/keysβββ payment1.addrβββ payment1.skeyβββ payment1.vkeyβββ payment2.addrβββ payment2.skeyβββ payment2.vkey
0 directories, 6 filesQuerying the UTXO for the second wallet payment2.addr should give you a familiar result:
cardano-cli query utxo \--testnet-magic 1097911063 \--address $(cat /home/user/cardano/keys/payment2.addr)UTXO Result
TxHash TxIx Amount--------------------------------------------------------------------------------------Again, this is to be expected as the payment2.addr wallet address and keys has just recently been generated. So we expect that no one has sent any tAda to this wallet yet.
In this example, we now have two wallets. We can call them payment1 and payment2. Now remember that we requested some tAda from the Cardano Testnet Faucet for payment1 wallet, and thats how we have the following:
payment1 wallet: 1,000,000,000 lovelace
UTXO TxHash TxIx Amount--------------------------------------------------------------------------------------cf3cf4850c8862f2d698b2ece926578b3815795c9e38d2f907280f02f577cf85 0 1000000000 lovelacepayment2 wallet: 0 lovelace
UTXO TxHash TxIx Amount--------------------------------------------------------------------------------------Now let's say we want to send 250,000,000 lovelace to payment2 wallet, how can we achieve that?
We start by storing the current on-chain protocol parameters to a JSON file:
Query Protocol Parameters
cardano-cli query protocol-parameters \ --testnet-magic 1097911063 \ --out-file /home/user/cardano/protocol.jsonThis will produce a JSON file that looks something like this:
{ "poolDeposit": 500000000, "protocolVersion": { "minor": 0, "major": 4 }, "minUTxOValue": 1000000, "decentralisationParam": 0, "maxTxSize": 16384, "minPoolCost": 340000000, "minFeeA": 44, "maxBlockBodySize": 65536, "minFeeB": 155381, "eMax": 18, "extraEntropy": { "tag": "NeutralNonce" }, "maxBlockHeaderSize": 1100, "keyDeposit": 2000000, "nOpt": 500, "rho": 3.0e-3, "tau": 0.2, "a0": 0.3}Create draft transaction
Next, we create a draft transaction like so:
cardano-cli transaction build-raw \--tx-in cf3cf4850c8862f2d698b2ece926578b3815795c9e38d2f907280f02f577cf85#0 \--tx-out $(cat /home/user/cardano/keys/payment2.addr)+0 \--tx-out $(cat /home/user/cardano/keys/payment1.addr)+0 \--fee 0 \--out-file /home/user/cardano/tx.draftcardano-cli transaction build-raw : This tells cardano-cli to build a raw transaction.
--tx-in : This specifices the UTXO input that the transaction will use, you can add as many UTXO input as you want by adding multiple --tx-in in the cardano-cli arguments as long as they have a unique TxHash and TxIdx within all your inputs.
--tx-out : This specifies the target wallet address, assets and quantity to be sent to. You can add as many UTXO outputs as you want as long as the total UTXO input can satisfy the assets and quantity specified by the output.
--fee : This specifies the fee amount of the transaction in lovelace.
--out-file : This is the path to the transaction file that will be generated.
In this case, we are just building a draft transaction to calculate how much fee would the transaction need. We can do that by executing the following command:
cardano-cli transaction calculate-min-fee \--tx-body-file /home/user/cardano/tx.draft \--tx-in-count 1 \--tx-out-count 2 \--witness-count 1 \--testnet-magic 1097911063 \--protocol-params-file /home/user/cardano/protocol.jsonYou should see something like this for the output:
174169 LovelaceYou will notice that we use the protocol.json we queried awhile ago to calculate the transaction fee:
--protocol-params-file /home/user/cardano/protocol.jsonThat is because the transaction fee calculation results changes depending on the on-chain protocol parameters.
The --witness-count 1 basically tells cardano-cli that there will be only 1 signing key required for this transaction to be valid. Since the UTXO input involved in this transaction will only be coming from payment1 wallet, so that means we indeed only need 1 key to sign the transaction.
We can then finally build the real transaction like so:
cardano-cli transaction build-raw \--tx-in cf3cf4850c8862f2d698b2ece926578b3815795c9e38d2f907280f02f577cf85#0 \--tx-out $(cat /home/user/cardano/keys/payment2.addr)+250000000 \--tx-out $(cat /home/user/cardano/keys/payment1.addr)+749825831 \--fee 174169 \--out-file /home/user/cardano/tx.draftTo recap, We want to send 250,000,000 lovelace from payment1 wallet to payment2 wallet. Our payment1 wallet had the following UTXO:
TxHash TxIx Amount--------------------------------------------------------------------------------------cf3cf4850c8862f2d698b2ece926578b3815795c9e38d2f907280f02f577cf85 0 1000000000 lovelaceSo we will use the TxHash cf3cf4850c8862f2d698b2ece926578b3815795c9e38d2f907280f02f577cf85 and TxId 0 as our --tx-input.
--tx-in cf3cf4850c8862f2d698b2ece926578b3815795c9e38d2f907280f02f577cf85#0We then tell cardano-cli that the destination of the 250,000,000 lovelace is the wallet address of payment2.
--tx-out $(cat /home/user/cardano/keys/payment2.addr)+250000000Now, we still have 750000000 lovelace as the change amount, so we will simply send it back to ourselves like so:
--tx-out $(cat /home/user/cardano/keys/payment1.addr)+749825831Now an important question you might ask here is that, why is the amount 749825831 lovelace? Well remember that we calculated the fee to be 174169 lovelace and someone has to shoulder the transaction fee, so we decide that payment should pay for the fee with the change lovelace amount. So we calculate that 750000000 - 174169 = 749825831 and so the total change would be 749825831 lovelace.
We then specify the transaction fee like so:
--fee 174169And then we specify where we will save the transaction file:
--out-file /home/user/cardano/tx.draftNow that we have the transaction file, we must sign the transaction in-order to prove that we are the owner of the input UTXO that was used.
cardano-cli transaction sign \--tx-body-file /home/user/cardano/tx.draft \--signing-key-file /home/user/cardano/keys/payment1.skey \--testnet-magic 1097911063 \--out-file /home/user/cardano/tx.signed--signing-key-file /home/user/cardano/keys/payment1.skey : This argument tells the cardano-cli that we will use payment1.skey to sign the transaction.
Finally, we submit the transaction to the blockchain!
cardano-cli transaction submit \--tx-file /home/user/cardano/tx.signed \--testnet-magic 1097911063 important
If you have waited too long to sign and submit the transaction, the fees might've changed during that time and therefore the transaction might get rejected by the network. To solve this, you simply have to recalculate the fees, rebuild the transaction, sign it and submit it!
Checking the balances of both wallets payment1 and payment2:
# payment1 wallet UTXOβ― cardano-cli query utxo --testnet-magic 1097911063 --address $(cat ~/cardano/keys/payment1.addr)
TxHash TxIx Amount--------------------------------------------------------------------------------------63eeeb7e43171aeea0b3d53c5a36236cf9af92d5ee39e99bfadfe0237c46bd91 1 749825303 lovelace
# payment2 wallet UTXOβ― cardano-cli query utxo --testnet-magic 1097911063 --address $(cat ~/cardano/keys/payment2.addr) TxHash TxIx Amount--------------------------------------------------------------------------------------63eeeb7e43171aeea0b3d53c5a36236cf9af92d5ee39e99bfadfe0237c46bd91 0 250000000 lovelaceAs we can see, payment2 now has a UTXO with the amount of 250,000,000 lovelace with the change amount returned to payment1 and has generated a new UTXO with the amount of 749,825,303 lovelace as-well.
Congratulations, You have created and sent your first Cardano transaction using cardano-cli! πππ
Creating a wallet with cardano-wallet#
note
This guide assumes you have installed cardano-wallet into your system. If not you can refer to Installing cardano-wallet guide for instructions on how to do that.
We will use the path /home/user/cardano/wallets to store all the cardano-wallet related files as an example, please replace it with the directory you have choosen to store the files.
important
Please make sure your cardano-node is connected and synchronized to the testnet network before proceeding.
warning
In a production environment, it might not be a good idea to store wallets / keys in a public server unless you know what you are doing.
First, lets create a directory to store all our wallets like so:
mkdir -p /home/user/cardano/walletsStarting cardano-wallet as a REST API server
We will be focusing on the REST API that cardano-wallet provides. In-order to interact with the API, we must first start the server.
cardano-wallet serve \--port 1337 \--testnet /home/user/cardano/testnet-byron-genesis.json \--database /home/user/cardano/wallets/db \--node-socket $CARDANO_NODE_SOCKET_PATHcardano-wallet serve : Runs cardano-wallet as a web server that provides a REST API.
--port : Specifies the port that the web server will listen to for any requests.
You can choose whatever
portnumber you like, but it is recommended to useportnumbers1024and above. See Registered Port for more information.
--testnet : Specifies the Byron genesis file path for the testnet network.
This should match the genesis file that the
cardano-nodeyou are connected is using as-well. If you meant to connect tomainnetthen use the--mainnetflag and themainnetByron genesis file instead.
--database : Specifies the path where the wallet database will be saved.
It is important to note that the wallet creation function requires a passphrase so all the wallet data will be encrypted by the passphrase.
--node-socket : Specifies the cardano-node socket path that will be used by the cardano-wallet to communicate with the node.
The
cardano-nodeuses IPC (Inter-Process-Communication) for communicating with the other Cardano components likecardano-cli,cardano-walletandcardano-db-sync. In Linux and MacOS it uses something called unix sockets and Named Pipes in Windows.Here is an example
--socket-pathargument for Linux:--socket-path /home/user/cardano/db/node.socketAs you can see the argument points to a file since unix sockets are represented as files (like everything else in Linux). In this case we put the socket file in the
dbdirectory that we have just created before.In Windows, the
--socket-pathargument would look something like this:--socket-path "\\\\.\\pipe\\cardano-node-testnet"As you notice its almost like a network
URIor a networkPaththan a file, this is a key difference that you will have to be aware depending on your operating system. You can replace the stringcardano-node-testnetin the argument to whatever you like, this example path in particular is used in the Daedalus Testnet Wallet for Windows.
Once the server is running you should see sometihng like this (among other things):
[cardano-wallet.network:Info:12] [2021-06-03 13:48:24.82 UTC] Protocol parameters for tip are: Decentralization level: 100.00% Transaction parameters: [Fee policy: 155381.0 + 44.0x, Tx max size: 16384] Desired number of pools: 500 Minimum UTxO value: 1.000000 Eras: - byron from -0 - shelley from 74 - allegra from 102 - mary from 112
Slotting parameters for tip are: Slot length: 1s Epoch length: 432000 Active slot coeff: 5.0e-2 Security parameter: 2160 block
[cardano-wallet.main:Info:4] [2021-06-03 13:48:24.86 UTC] Wallet backend server listening on http://127.0.0.1:1337/Checking Wallet Server Information
The first thing we can do to test if the wallet server is working correctly is to query the network information via the API.
curl --request GET \ --url http://localhost:1337/v2/network/information | jqThe result should be something like this:
{ "node_era": "mary", "network_tip": { "slot_number": 408744, "absolute_slot_number": 28359144, "time": "2021-06-03T13:52:40Z", "epoch_number": 135 }, "next_epoch": { "epoch_start_time": "2021-06-03T20:20:16Z", "epoch_number": 136 }, "sync_progress": { "status": "ready" }, "node_tip": { "height": { "unit": "block", "quantity": 2639489 }, "slot_number": 408722, "absolute_slot_number": 28359122, "time": "2021-06-03T13:52:18Z", "epoch_number": 135 }}It is important to make sure that the sync_progress.status is equal to ready before proceeding.
Creating the wallet
To create a wallet we must first generate a wallet recovery phrase using the cardano-wallet in the CLI.
cardano-wallet recovery-phrase generateYou should get a 24-word mnemonic seed in return similar to this:
kit soup various toe cloud humor clip radio medal ladder casino sock various distance staff analyst success trade deal split leaf away pair campWe can now create a Cardano wallet using the /v2/wallets API endpoint:
curl --request POST \ --url http://localhost:1337/v2/wallets \ --header 'Content-Type: application/json' \ --data '{ "name": "test_cf_1", "mnemonic_sentence": ["shift", "badge", "heavy", "action", "tube", "divide", "course", "quality", "capable", "velvet", "cart", "marriage", "vague", "aware", "maximum", "exist", "crime", "file", "analyst", "great", "cabbage", "course", "sad", "apology"], "passphrase": "test123456"}' | jqOur requests payload data looks like this:
{ "name": "test2", "mnemonic_sentence": ["kit", "soup", "various", "toe", "cloud", "humor", "clip", "radio", "medal", "ladder", "casino", "sock", "various", "distance", "staff", "analyst", "success", "trade", "deal", "split", "leaf", "away", "pair", "camp"], "passphrase": "test123456"}name : The name of the wallet.
passphrase : Sets the security phrase to protect the funds inside the wallet. It will be required everytime you need write access to the wallet, more specifically sending assets.
mnemonic_sentence : This is the wallet recovery phrase formatted into a JSON array.
If succesful, you should see something like this:
{ "address_pool_gap": 20, "passphrase": { "last_updated_at": "2021-06-03T14:25:18.2676524Z" }, "balance": { "available": { "unit": "lovelace", "quantity": 0 }, "total": { "unit": "lovelace", "quantity": 0 }, "reward": { "unit": "lovelace", "quantity": 0 } }, "id": "5076b34c6949dbd150eb9c39039037543946bdce", "state": { "status": "syncing", "progress": { "unit": "percent", "quantity": 0 } }, "name": "test_cf_1", "assets": { "available": [], "total": [] }, "tip": { "height": { "unit": "block", "quantity": 0 }, "slot_number": 0, "absolute_slot_number": 0, "time": "2019-07-24T20:20:16Z", "epoch_number": 0 }, "delegation": { "next": [], "active": { "status": "not_delegating" } }}Initially, the newly created/restored wallet will need to be synced before it can be used. You can verify if the wallet is already synced by executing the following request:
curl --request GET --url http://localhost:1337/v2/wallets/c4d4e240d499cce3fed8fd885491803885fdf323 | jq '.state'It is important to note that the c4d4e240d499cce3fed8fd885491803885fdf323 string is actually the wallet.id of the previously generated wallet.
You should see something like this:
{ "status": "ready"}Receiving tAda (test ada)
Now that we have created a wallet, we can now request some tAda from the Testnet Faucet. But before we can do that we must first get a cardano address for our wallet.
We can do that by executing the command:
curl --request GET \ --url 'http://localhost:1337/v2/wallets/5076b34c6949dbd150eb9c39039037543946bdce/addresses?state=unused' | jq '.[0]'The result should be something like this:
{ "derivation_path": [ "1852H", "1815H", "0H", "0", "0" ], "id": "addr_test1qzf9q3qjcaf6kxshwjfw9ge29njtm56r2a08g49l79xgt4je0592agqpwraqajx2dsu2sxj64uese5s4qum293wuc00q7j6vsp", "state": "unused"}It is important to note that the parameter of this request is the wallet id of the target wallet you want to get the address. In this case it is 5076b34c6949dbd150eb9c39039037543946bdce our previously generated wallet.
We are basically querying the first wallet address that has not been used just yet, Indicated by state: "unused". As we can see the wallet address value is: addr_test1qpnjt8umuwr5f2y59avklhu8hd7h2uf4zfanxxr4nmqqsaw679hxgdmrtsjequ8ka27rm8366e6p7au9y89h6slmrjwskfmcef
Now we can finally request some tAda for the wallet address from the Cardano Testnet Faucet.
Once you requested some tAda from the Cardano Testnet Faucet, we can then check if it has arrived into our wallet like so:
curl --request GET \ --url http://localhost:1337/v2/wallets/5076b34c6949dbd150eb9c39039037543946bdce | jq '.balance'You should see something like this:
{ "available": { "unit": "lovelace", "quantity": 1000000000 }, "total": { "unit": "lovelace", "quantity": 1000000000 }, "reward": { "unit": "lovelace", "quantity": 0 }}As we can see here we have a total of 1,000,000,000 lovelace available to spend that we received from the Cardano Testnet Faucet.
Creating simple transactions#
To have a clearer understanding of how sending transactions work using cardano-wallet, first lets create another wallet like so:
Generate recovery-phrase
cardano-wallet recovery-phrase generateRecovery-phrase result
then tattoo copy glance silk kitchen kingdom pioneer off path connect artwork alley smooth also foil glare trouble erupt move position merge scale echoCreate Wallet Request
curl --request POST \ --url http://localhost:1337/v2/wallets \ --header 'Content-Type: application/json' \ --data '{ "name": "test_cf_2", "mnemonic_sentence": ["then", "tattoo", "copy", "glance", "silk", "kitchen", "kingdom", "pioneer", "off", "path", "connect", "artwork", "alley", "smooth", "also", "foil", "glare", "trouble", "erupt", "move", "position", "merge", "scale", "echo"], "passphrase": "test123456"}' | jqCreate Wallet Result
{ "address_pool_gap": 20, "passphrase": { "last_updated_at": "2021-06-04T11:39:06.8887923Z" }, "balance": { "available": { "unit": "lovelace", "quantity": 0 }, "total": { "unit": "lovelace", "quantity": 0 }, "reward": { "unit": "lovelace", "quantity": 0 } }, "id": "4a64b453ad1c1d33bfec4d3ba90bd2456ede35bb", "state": { "status": "syncing", "progress": { "unit": "percent", "quantity": 0 } }, "name": "test_cf_2", "assets": { "available": [], "total": [] }, "tip": { "height": { "unit": "block", "quantity": 0 }, "slot_number": 0, "absolute_slot_number": 0, "time": "2019-07-24T20:20:16Z", "epoch_number": 0 }, "delegation": { "next": [], "active": { "status": "not_delegating" } }}We now have the following wallets:
| WalletId | Wallet Name | Balance(Lovelace) |
|---|---|---|
| 5076b34c6949dbd150eb9c39039037543946bdce | test_cf_1 | 1000000000 |
| 4a64b453ad1c1d33bfec4d3ba90bd2456ede35bb | test_cf_2 | 0 |
Now let's say that we want to send 250,000,000 lovelaces to test_cf_2 wallet. Well first we have to get test_cf_2 wallet address like so:
curl --request GET \ --url 'http://localhost:1337/v2/wallets/4a64b453ad1c1d33bfec4d3ba90bd2456ede35bb/addresses?state=unused' | jq '.[0]'and we should see something like this:
{ "derivation_path": [ "1852H", "1815H", "0H", "0", "0" ], "id": "addr_test1qzyfnjk3zmgzmvnnvnpeguv6se2ptjj3w3uuh30llqe5xdtzdduxxvke8rekwukyn0qt9g5pahasrnrdmv7nr86x537qxdgza0", "state": "unused"}So now that we have test_cf_2 wallet address addr_test1qzyfnjk3zmgzmvnnvnpeguv6se2ptjj3w3uuh30llqe5xdtzdduxxvke8rekwukyn0qt9g5pahasrnrdmv7nr86x537qxdgza0. We can now use it to send some tAda to it from test_cf_1 wallet like so:
curl --request POST \ --url http://localhost:1337/v2/wallets/5076b34c6949dbd150eb9c39039037543946bdce/transactions \ --header 'Content-Type: application/json' \ --data '{ "passphrase": "test123456", "payments": [ { "address": "addr_test1qzyfnjk3zmgzmvnnvnpeguv6se2ptjj3w3uuh30llqe5xdtzdduxxvke8rekwukyn0qt9g5pahasrnrdmv7nr86x537qxdgza0", "amount": { "quantity": 250000000, "unit": "lovelace" } } ]}'note
Remember, we use the test_cf_1 wallet id in the http://localhost:1337/v2/wallets/<walletId> endpoint, because we want the test_cf_1 to send to test_cf_2 wallet address.
Now we can check test_cf_2 wallet balance like so:
curl --request GET \ --url http://localhost:1337/v2/wallets/4a64b453ad1c1d33bfec4d3ba90bd2456ede35bb | jq '.balance'And we should see that indeed the 250,000,000 tAda has been received (you might need to wait for a few seconds).
{ "available": { "unit": "lovelace", "quantity": 250000000 }, "total": { "unit": "lovelace", "quantity": 250000000 }, "reward": { "unit": "lovelace", "quantity": 0 }}Checking test_cf_1 wallet balance should show you something like this:
{ "available": { "unit": "lovelace", "quantity": 749831199 }, "total": { "unit": "lovelace", "quantity": 749831199 }, "reward": { "unit": "lovelace", "quantity": 0 }}Our wallets should now be the following:
| WalletId | Wallet Name | Balance(Lovelace) |
|---|---|---|
| 5076b34c6949dbd150eb9c39039037543946bdce | test_cf_1 | 749831199 |
| 4a64b453ad1c1d33bfec4d3ba90bd2456ede35bb | test_cf_2 | 250000000 |
note
It is important to note that cardano-wallet has automatically determined the fee for the transaction to send 250,000,000 lovelace from wallet test_cf_1 to test_cf_2 and cardano_wallet has deducted the fee from test_cf_1 wallet automatically.
tip
Full documentation of the cardano-wallet REST API can be found here: https://input-output-hk.github.io/cardano-wallet/api/edge
Congratulations, You have created and sent your first Cardano transaction using cardano-wallet! πππ