Cardano-client-lib: Transaction with Metadata in Java — Part II

In this post, we will see how you can create and post a transaction with metadata to Cardano network in a Java application using cardano-client-lib.

Cardano-client-lib is a Java library which provides support to create, sign and submit transaction to the Cardano network. Check Part-I of this series to know more about Cardano-client-lib and the other functionalities provided by this library.

In this post we will be using Blockfrost backend Api.

Cardano Metadata as defined in this blog :-

Metadata tells the story of a transaction and there are many ways to interact with this story. Developers can take advantage of metadata by embedding details directly into a transaction, and ada users can search for specific information in the Cardano Explorer. The data can be added directly, or, for larger amounts, it is possible to create a Merkle tree of the data and put the root hash of the Merkle tree on the blockchain. Once this is done, it can be proved that the data existed at a specific point of time and that it remains permanently on the chain for future reference.

Cardano-client-lib provides simple apis to create metadata. It also provides helpers to convert metadata to JSON and vice versa.

Let’s create a payment transaction and add some metadata to it.

  1. Project and account setup

If you have not setup your project yet, please follow the step-1 to step-6 from Part I.

2. Create a metadata object

To create a metadata object, you have to start with CBORMetadata class. You can also use CBORMetadataMap and CBORMetadataList if you want to set the value as Map or List.

CBORMetadataMap productDetailsMap
= new CBORMetadataMap()
.put("code", "PROD-800")
.put("slno", "SL20000039484");

CBORMetadataList tagList
= new CBORMetadataList()

Metadata metadata = new CBORMetadata()
.put(new BigInteger("670001"), productDetailsMap)
.put(new BigInteger("670002"), tagList);

In the above example, we are first creating a Map which contains code and serial no. We are then creating a List to hold multiple tags.

Finally, we are creating a Metadata object and setting productDetailsMap and tagList with metadata labels 670001, 670002 respectively.

You can create a multi-level nested structure, but the top-level object should be Metadata.

3. Create a transaction request object

As explained in the Part I, let’s create a transaction with PaymentTransaction class.

PaymentTransaction paymentTransaction =

4. Calculate TTL (Time-to-Live)

Use BlockService to get the latest slot number and then calculate ttl.

long ttl = blockService.getLastestBlock().getValue().getSlot() + 1000;
TransactionDetailsParams detailsParams =

5. Calculate Fee

Use FeeCalculatorService to calculate fee. Make sure to send all three parameters “PaymentTransaction, TransactionDetailsParams and Metadata” to FeeCalculatorService.

Set the calculated fee in PaymentTransaction request.

BigInteger fee 
= feeCalculationService.calculateFee(paymentTransaction, detailsParams, metadata);


6. Submit Transaction with Metadata

Now submit the transaction request to the network using TransactionHelperService.

Note: Make sure to pass “metadata” parameter in the transfer call.

Result<String> result
= transactionHelperService.transfer(paymentTransaction, detailsParams, metadata);
System.out.println("Transaction Id: " + result.getValue());
System.out.println("Transaction failed: " + result);

7. Check transaction details in Cardano Explorer

Now go to Cardano Testnet Explorer and check the transaction details.

It may take some time for the transaction to be mined.

Now you can see the metadata in Cardano explorer.

Metadata can be added to a Native token transfer in similar ways.

Metadata Helper Class

There are few helper classes which can be used to convert a JSON (No Schema) object to metadata format and vice-versa.

But the Json payload has to follow the format mentioned in this wiki.


Check also:


Full Source code

A developer’s journey in blockchain world