Hello Cardano CourseLessons1. Hello World

Lesson #01: Hello World

Welcome to the first lesson of the Cardano Application Development Course! In this session, you’ll set up the Mesh SDK and learn how to create a wallet using MeshWallet and send assets using MeshTxBuilder.

System setup

Before we begin, let’s prepare our system for development. We will be using Node.js v24+ in this course. We recommend nvm to manage your node versions.

Create a package.json file

First, create a new package.json file in the root of your project with the following content:

{
  "type": "module",
  "dependencies": {},
  "scripts": {}
}

Install the necessary packages

Open your terminal and run these commands to install the MeshSDK:

npm install
npm install @meshsdk/core

Here’s how your package.json file should look after installing the package:

{
  "type": "module",
  "dependencies": {
    "@meshsdk/core": "^1.9.0",
  },
  "scripts": {}
}
  • @meshsdk/core: Core functionality for network interactions, wallets, and transactions.

Create a wallet

We will use MeshWallet. This class provides methods to create a new wallet, generate mnemonic phrases, and get the wallet address.

Generate mnemonic phrases

To create a new wallet, we need to generate a mnemonic phrase. A mnemonic phrase is a set of words that can be used to recover your wallet. It is important to keep your mnemonic phrase safe and secure, as it can be used to access your funds.

To create a new wallet mnemonic, do the following:

import { MeshWallet } from "@meshsdk/core";
 
// Generate new mnemonic phrases for your wallet
const mnemonic = MeshWallet.brew();
console.log("Your mnemonic phrases are:", mnemonic);
  • Use the brew method to generate a new mnemonic phrase.

Initialize the wallet and get the wallet address

Now that we have generated a mnemonic phrase, we can initialize the wallet with it. The MeshWallet class provides a method to create a new wallet using the mnemonic phrase.

// Initialize the wallet with a mnemonic key
const wallet = new MeshWallet({
  networkId: 0, // preprod testnet
  key: {
    type: "mnemonic",
    words: mnemonic as string[],
  },
});
 
// Get the wallet address
const address = await wallet.getChangeAddress();
console.log("Your wallet address is:", address);
  • networkId: Specify the network, 0 for preprod testnet.
  • key: Specify the key type and mnemonic phrases.
  • getChangeAddress: Method to get the wallet address.

Run the code

Here is the source code. Create a new file mnemonic.ts and copy the code into it:

import { MeshWallet } from "@meshsdk/core";
 
// Generate new mnemonic phrases for your wallet
const mnemonic = MeshWallet.brew();
console.log("Your mnemonic phrases are:", mnemonic);
 
// Initialize the wallet with a mnemonic key
const wallet = new MeshWallet({
  networkId: 0, // preprod testnet
  key: {
    type: "mnemonic",
    words: mnemonic as string[],
  },
});
 
// Get the wallet address
const address = await wallet.getChangeAddress();
console.log("Your wallet address is:", address);

Update the package.json file to add a script to run the code:

{
  "type": "module",
  "dependencies": {
    "@meshsdk/core": "^1.9.0",
  },
  "scripts": {
    "mnemonic": "node mnemonic.ts"
  }
}

Run the script:

npm run mnemonic

This will generate a new mnemonic phrase and wallet address for you. The output will look something like this:

> mnemonic
> node mnemonic.ts
 
Your mnemonic phrases are: [
  'access',  'spawn',   'taxi',
  'prefer',  'fortune', 'sword',
  'nerve',   'price',   'valid',
  'panther', 'sure',    'hello',
  'layer',   'try',     'grace',
  'seven',   'fossil',  'voice',
  'tobacco', 'circle',  'measure',
  'solar',   'pride',   'together'
]
Your wallet address is: addr_test1qptwuv6dl863u3k93mjrg0hgs0ahl08lfhsudxrwshcsx59cjxatme29s6cl7drjceknunry049shu9eudnsjvwqq9qsuem66d

Send lovelace

Now that we have a wallet and some lovelace, let’s learn how to send lovelace using the Mesh SDK. We will use the MeshTxBuilder class to create a transaction and send it to the network.

Get lovelace from faucet

To get some lovelace for testing, you can use the Cardano Preprod Testnet Faucet. Paste your wallet address and click on the “Request funds” button. You should receive some lovelace in your wallet shortly.

Get Blockfrost API key

In order to create transactions, we need to use APIs to get UTXOs from the network. For this, we will use Blockfrost to get UTXOs and submit transactions. Sign up for a free account and get your API key here.

You should get the preprod API key, which starts with preprod. You can find the API key in the “Projects” section of your Blockfrost account.

Get wallet information

Now, let’s get the wallet information using the MeshWallet class.

// Get wallet data needed for the transaction
const utxos = await wallet.getUtxos();
const changeAddress = await wallet.getChangeAddress();
  • getUtxos: Method to get the UTXOs from the wallet.
  • getChangeAddress: Method to get the change address.

Create a transaction to send lovelace

Now, we will create a transaction to send lovelace using the MeshTxBuilder class.

// Create the transaction
const txBuilder = new MeshTxBuilder({
  fetcher: provider,
  verbose: true, // optional, prints the transaction body
});
 
const unsignedTx = await txBuilder
  .txOut(
    "addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9",
    [{ unit: "lovelace", quantity: "1500000" }]
  )
  .changeAddress(changeAddress)
  .selectUtxosFrom(utxos)
  .complete();
  • txOut: Add the recipient address and amount.
  • changeAddress: Set the change address.
  • selectUtxosFrom: Provide wallet UTXOs into the transaction as inputs.
  • complete: Create the transaction.

Sign and submit the transaction

Now that we have created the transaction, we need to sign it and submit it to the network.

const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
console.log("Transaction hash:", txHash);
  • signTx: Method to sign the transaction, which will return the signed transaction.
  • submitTx: Method to submit the transaction to the network.

Run the code

Here is the source code. Create a new file send-lovelace.ts and copy the code into it:

import { BlockfrostProvider, MeshTxBuilder, MeshWallet } from "@meshsdk/core";
 
// Set up the blockchain provider with your key
const provider = new BlockfrostProvider("YOUR_KEY_HERE");
 
// Initialize the wallet with a mnemonic key
const wallet = new MeshWallet({
  networkId: 0,
  fetcher: provider,
  submitter: provider,
  key: {
    type: "mnemonic",
    words: ["your", "mnemonic", "...", "here"],
  },
});
 
// Get wallet data needed for the transaction
const utxos = await wallet.getUtxos();
const changeAddress = await wallet.getChangeAddress();
 
// Create the transaction
const txBuilder = new MeshTxBuilder({
  fetcher: provider,
  verbose: true, // optional, prints the transaction body
});
 
const unsignedTx = await txBuilder
  .txOut(
    "addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9",
    [{ unit: "lovelace", quantity: "1500000" }]
  )
  .changeAddress(changeAddress)
  .selectUtxosFrom(utxos)
  .complete();
 
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
console.log("Transaction hash:", txHash);

Update the package.json file to add a script to run the code:

{
  "type": "module",
  "dependencies": {
    "@meshsdk/core": "^1.9.0",
  },
  "scripts": {
    "mnemonic": "node mnemonic.ts",
    "send-lovelace": "node send-lovelace.ts"
  }
}

Run the script:

npm run send-lovelace

This will create a transaction to send lovelace to the recipient address and submit it to the network. The output will look something like this:

> send-lovelace
> node send-lovelace.ts
 
txBodyJson - before coin selection {"inputs":[],"outputs":[{"address":"addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9","amount":[{"unit":"lovelace","quantity":"1500000"}]}],"fee":"0","collaterals":[],"requiredSignatures":[],"referenceInputs":[],"mints":[],"changeAddress":"addr_test1qp2k7wnshzngpqw0xmy33hvexw4aeg60yr79x3yeeqt3s2uvldqg2n2p8y4kyjm8sqfyg0tpq9042atz0fr8c3grjmysdp6yv3","metadata":{},"validityRange":{},"certificates":[],"withdrawals":[],"votes":[],"signingKey":[],"chainedTxs":[],"inputsForEvaluation":{},"network":"mainnet","expectedNumberKeyWitnesses":0,"expectedByronAddressWitnesses":[]}
txBodyJson - after coin selection {"inputs":[{"type":"PubKey","txIn":{"txHash":"99d859b305ab8021e497fad0dc55373e50fffd3e7026142fa3cf5accfe0d3aab","txIndex":1,"amount":[{"unit":"lovelace","quantity":"9823719"}],"address":"addr_test1qp2k7wnshzngpqw0xmy33hvexw4aeg60yr79x3yeeqt3s2uvldqg2n2p8y4kyjm8sqfyg0tpq9042atz0fr8c3grjmysdp6yv3"}}],"outputs":[{"address":"addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9","amount":[{"unit":"lovelace","quantity":"1500000"}]},{"address":"addr_test1qp2k7wnshzngpqw0xmy33hvexw4aeg60yr79x3yeeqt3s2uvldqg2n2p8y4kyjm8sqfyg0tpq9042atz0fr8c3grjmysdp6yv3","amount":[{"unit":"lovelace","quantity":"8153730"}]}],"fee":"169989","collaterals":[],"requiredSignatures":[],"referenceInputs":[],"mints":[],"changeAddress":"addr_test1qp2k7wnshzngpqw0xmy33hvexw4aeg60yr79x3yeeqt3s2uvldqg2n2p8y4kyjm8sqfyg0tpq9042atz0fr8c3grjmysdp6yv3","metadata":{},"validityRange":{},"certificates":[],"withdrawals":[],"votes":[],"signingKey":[],"chainedTxs":[],"inputsForEvaluation":{"99d859b305ab8021e497fad0dc55373e50fffd3e7026142fa3cf5accfe0d3aab1":{"input":{"outputIndex":1,"txHash":"99d859b305ab8021e497fad0dc55373e50fffd3e7026142fa3cf5accfe0d3aab"},"output":{"address":"addr_test1qp2k7wnshzngpqw0xmy33hvexw4aeg60yr79x3yeeqt3s2uvldqg2n2p8y4kyjm8sqfyg0tpq9042atz0fr8c3grjmysdp6yv3","amount":[{"unit":"lovelace","quantity":"9823719"}]}}},"network":"mainnet","expectedNumberKeyWitnesses":0,"expectedByronAddressWitnesses":[]}
Transaction hash: 62a825c607e4ca5766325c2fccd7ee98313ff81b7e8a4af67eac421b0f0866ff

You should see the transaction hash in the output.

Note, in the MeshTxBuilder class, we have set verbose: true, which will print the transaction body before and after coin selection. This is useful for debugging and understanding how the transaction is built.

Source code

The source code for this lesson is available on GitHub.

Challenge

Create a transaction that sends multiple assets to multiple addresses. Explore the Mesh SDK docs for more!