Using Tatum Key Management System(KMS) to sign transactions

Using Tatum Key Management System(KMS) to sign transactions

Play this article

Although there are many views on the various consensus techniques used in blockchain, companies have been working tirelessly to invent solutions to guarantee that digital signatures are secure when authenticating transactions.

To authorize transactions, DApps produce cryptographic signatures using users' private keys or mnemonics. Although this method is quite effective, it has significant downsides. When users' private keys or mnemonics are hacked, their security is jeopardized, and unauthorized users may be able to sign transactions that the owner did not approve. You don’t want that to happen right? Tatum doesn’t either.

To combat this vulnerability, Tatum developed the Key Management System (KMS), a secure tool that enables DApps to sign transactions without using users' private keys or mnemonics.

I will discuss Tatum and Key Management Systems in this article. I will also use sample codes to demonstrate how to sign transactions using Tatum KMS. To follow along, you will need basic knowledge of JavaScript and blockchain.

Let’s take a deeper look at the topic! 👀

What is Tatum

Tatum is a blockchain framework designed to help developers simplify the complexity of blockchain development processes by unifying more than 40 different blockchain protocols and thousands of digital assets.

Tatum facilitates faster and easier development by offering the following frameworks for blockchain operations:

  • Tatum JS: A unified JavaScript SDK comprising more than 40 blockchain protocols.
  • Tatum KMS: An open-source key management tool used to store private keys, mnemonics, and sign on-site transactions.
  • RPC nodes REST API: A REST API which provides commands for all supported blockchains.
  • Tatum CLI: A blockchain interaction tool accessible via a command line.

What is a Key Management System

The users' private keys are the most essential data in the blockchain ecosystem. The private key and wallet address are generated from the mnemonics used for authenticating wallet owners. The private key should be kept safe to prevent losing the wallet's content, while the wallet address can be shared as it is often referred to as a public key.

Additionally, private keys and mnemonics should be protected because they are the only credentials used to authenticate a wallet. The owner won't be able to access or reclaim the contents of the wallet if they are lost.

How does Tatum KMS work?

Managing and storing private keys and mnemonics calls for a lot of concern and security measures. Tatum provides a better and more secure way to manage these credentials and allow developers to sign transaction easily using its KMS.

Tatum KMS is a comprehensive solution that can be extended to blockchain applications. This solution allows transactions to be signed locally without the need to transfer private keys or mnemonics over the internet.

As a developer, you can use Tatum KMS in your server to generate wallets. For every wallet created by the KMS, a unique identifier signatureId is generated for the private key and mnemonics. Such that when requests are sent to the Tatum API, mnemonics and private keys are replaced with their respective signatureId.

For example, the code below shows an example of how to mint an NFT using fromPrivateKey in the Tatum API endpoint.

const resp = await fetch(
  `https://api-eu1.tatum.io/v3/nft/mint`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': 'YOUR_TATUM_DASHBOARD_API_KEY'
    },
    body: JSON.stringify({
      chain: 'CHAIN_SYMBOL',
      tokenId: '100000',
      to: 'RECEIVING_ADDRESS',      
      contractAddress: 'CONTRACT_ADDRESS',
      url: 'URL_OF_THE_FILE',
      fromPrivateKey: 'PRIVATE_KEY_OF_SENDER'
    })
  }
);

const data = await resp.json();
console.log(data);

In the case where KMS is used, you will have to replace fromPrivateKey with the signatureId, as shown below.

const resp = await fetch(
  `https://api-eu1.tatum.io/v3/nft/mint`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': 'YOUR_TATUM_DASHBOARD_API_KEY'
    },
    body: JSON.stringify({
      chain: 'CHAIN_SYMBOL',
      tokenId: '100000',
      to: 'RECEIVING_ADDRESS',
      contractAddress: 'CONTRACT_ADDRESS',
      url: 'URL_OF_THE_FILE',
      signatureId: 'PRIVATE_KEY_SIGNATURE_ID_OF_SENDER'
    })
  }
);

const data = await resp.json();
console.log(data);

Signing Transactions using Tatum KMS

To use Tatum API in your application, you need authorization in form of an API key. Tatum provides various plans for their customers which include an unlimited free plan for developers and some paid plans with added functionalities.

You can check the official website to start a plan. Login to your Tatum dashboard using either email and password or social authentication.

image.png

At the top-right corner of your Tatum dashboard, click “Create API key” to generate a new API key.

You can use Testnet in development. Make sure you use Mainnet in production You are allowed to create up to two free API keys which can be Mainnet or Testnet.

Next, to set Tatum KMS up in your development environment, visit the GitHub README to install Tatum KMS on your operating system natively or in Docker.

If you’re having issues installing Tatum-KMS, you might be using an NPM version that Tatum-KMS do not support. Currently, the Tatum-KMS works with NPM version 6 and NodeJS>=14.

Tatum KMS is currently available on macOS, Unix and MS Windows. Contact Tatum support or use a virtual machine if your operating system is not supported.

Once you have Tatum configured in your development environment, you can call the Tatum KMS API endpoint in your application.

Getting Pending Transactions

In your application, you can use the Tatum API endpoint below to get pending transactions yet to be signed.

const chain = 'CHAIN_SYMBOL';
const resp = await fetch(
  `https://api-eu1.tatum.io/v3/kms/pending/${chain}?signatures=${SIGNATURE_ID(s)_FROM_KMS}`,
  {
    method: 'GET',
    headers: {
      'x-api-key': 'YOUR_TATUM_DASHBOARD_API_KEY'
    }
  }
);

const data = await resp.text();
console.log(data);

In the code sample above, we called the /kms/pending/${chain} endpoint where the signature query parameter can be multiple signatureIDs separated by spaces(%20) in the URL. The data response is going to be as shown below.

[
  {
    "id": "5e6645712b55823de7ea82f1",
    "chain": "ETH",
    "hashes": [
      "1234987askdjfb1o2873ryskajfb1234987askdjfb1o2873ryskajfb1234987askdjfb1o2873ryskajfb"
    ],
    "serializedTransaction": "alskdjfq8o27fbkasljfbq8o7b4fqo83f7bqejhafbo8q4f",
    "withdrawalId": "5e6645712b55823de7ea82f1",
    "index": 1,
    "txId": "c83f8818db43d9ba4accfe454aa44fc33123d47a4f89d47b314d6748eb0e9bc9",
    "withdrawalResponses": [
      {
        "address": {
          "address": "7c21ed165e294db78b95f0f181086d6f",
          "currency": "BTC",
          "derivationKey": 2147483647,
          "xpub": "xpub6FB4LJzdKNkkpsjggFAGS2p34G48pqjtmSktmK2Ke3k1LKqm9ULsg8bGfDakYUrdhe2EHw5uGKX9DrMbrgYnVfDwrksT4ZVQ3vmgEruo3Ka",
          "destinationTag": 5,
          "memo": "5",
          "message": "5"
        },
        "amount": 0,
        "vIn": "string",
        "vInIndex": 0,
        "scriptPubKey": "string"
      }
    ]
  }
]

Complete Pending Transaction

After getting the pending transactions using the API endpoint in the previous section, you can complete the transaction by calling the API endpoint.

const id = 'TATUM_TRANSACTION_ID';
const txId = 'BLOCKCHAIN_TRANSACTION_ID';
const resp = await fetch(
  `https://api-eu1.tatum.io/v3/kms/${id}/${txId}`,
  {
    method: 'PUT',
    headers: {
      'x-api-key': 'YOUR_TATUM_DASHBOARD_API_KEY'
    }
  }
);

if (resp.status === 204) {
  console.log('success');
} else {
  const data = await resp.text();
  console.log(data);
}

In the code sample above, we called the /kms/${id}/${txId} endpoint, where id is the ID of the pending transaction and txId is the transaction ID of the blockchain transaction.

You will have also noticed we included the API key generated from the Tatum dashboard as x-api-key when calling the API endpoint.

To confirm if the transaction is successful, check the transaction details on Etherscan by browsing https://ropsten.etherscan.io/tx/${txId} where txId is the transaction ID from the blockchain or use the Tatum API endpoint below.

const id = 'TATUM_TRANSACTION_ID';
const resp = await fetch(
  `https://api-eu1.tatum.io/v3/kms/${id}`,
  {
    method: 'GET',
    headers: {
      'x-api-key': 'YOUR_TATUM_DASHBOARD_API_KEY'
    }
  }
);

const data = await resp.text();
console.log(data);

In the above code sample, we called the /kms/${id} endpoint, where id is the transaction ID gotten from Tatum.

Conclusion

Although there are many other key management systems that can be used to manage cryptographic keys, Tatum is a preferred option as it provides other resources that can be used alongside the KMS in the development of blockchain applications.

You can explore more use cases of Tatum KMS. Visit the official documentation to learn how to use other Tatum features.