KMS - Bitcoin Flow from A to Z

This guide covers how to use Tatum Key Management System (KMS) on Bitcoin (and similar blockchains) to generate wallets, private keys, blockchain addresses, and sign transactions locally using KMS.

Steps

1. Generate a BTC Wallet (Mnemonic)

To generate a wallet that is managed by the KMS, use the generatemanagedwallet command in CLI mode.

Request Example:

  • The response contains your wallet mnemonic's signature ID as the first parameter
tatum-kms --path=wallet.dat --testnet generatemanagedwallet BTC

Enter password to access wallet storage:*****

#Response:
{
  "xxx-59be-4792-81c5-yyy": {
    "mnemonic": "urge pulp usage sister evidence arrest palm math please chief egg abuse",
    "xpub": "tpubBCDEF"
  }
}

📘

When you first use KMS, you will be prompted to enter a password to encrypt your data. This password is created the first time you enter it, and you should store it in a safe place.

2. Generate a PrivateKey

PrivateKeys are used to authorize transfers of funds from blockchain addresses. Use the getprivatekey command to generate a private key.

Request Example:

  • Your wallet mnemonic's signature ID
    Signature ID is the first parameter in the Response from Step_1 - Generate a managed wallet.
  • The derivation index of the private key you are generating
    A derivation index can be any value but it must be unique to the wallet you are generating. You may start at “0” (as in the response example above) and work chronologically.
  • The response is the PrivateKey of the derivation index that you have specified
tatum-kms --path=wallet.dat --testnet getprivatekey xxx-59be-4792–81c5-yyy 0

#Response:
{
  "privateKey": "XXXNAV3tX3vWPG4uThixuqdYYY"
}

3. Generate a Blockchain Address

Create an address for the private key that you just generated. You can receive funds to the address and use the private key to send them from the address.

Use the getaddress **** command to generate an address for the same derivation index (0) that you specified in Step_2 - Generate a PrivateKey.

Request Example:

  • Your wallet mnemonic's signature ID
  • The derivation index of the address you are generating — the same derivation index that you specified in Step_2 - Generate a PrivateKey.
  • The response will contain the address you have just generated
tatum-kms --path=wallet.dat --testnet getaddress xxx-59be-4792–81c5-yyy 0

#Respnse:
{
  "address": "AAAA3JPvMuwgpKovMTjBBB"
}

4. Store the PrivateKey in your Wallet

Store the PrivateKey that you have just generated in the wallet using the storemanagedprivatekey command.

Request Example:

  • The response will contain the signature ID of the private key, which you can then use to sign transactions
tatum-kms --path=wallet.dat --testnet storemanagedprivatekey BTC

#When prompted, enter the PrivateKey and the password that you created earlier in this guide.

Enter private key to store:XXXNAV3tX3vWPG4uThixuqdYYY
Enter password to access wallet store:******

#Response:
{
 "signatureId": "QQQ-4b41-4ec9-b66c-WWW"
}

#Now you can export the wallet and review it. Enter the following command to export:
tatum-kms --path=wallet.dat --testnet export

#When prompted, enter your password. 
#The response will give you details about your wallet:
{
 "QQQ-4b41-4ec9-b66c-WWW": {
   "privateKey": "XXXNAV3tX3vWPG4uThixuqdYYY",
   "chain": "BTC",
   "testnet": true
 },
 "xxx-59be-4792-81c5-yyy": {
   "mnemonic": "urge pulp usage sister evidence arrest palm math please chief egg abuse",
   "xpub": "tpubBCDEF",
   "chain": "BTC",
   "testnet": true
 }
}

5. Send test BTC to your new Address

  1. Use a Bitcoin testnet faucet to get some BTC coins. You may use Tatum faucet
  2. See the Address generated in Step_3 - Generate a Blockchain Address - AAAA3JPvMuwgpKovMTjBBB
  3. Send testnet BTC coins to your Address.

6. Enable Daemon mode

Daemon mode is essentially KMS running in the background and listening for pending transactions to sign and broadcast them.

  • Transactions are identified by your API key.
  • You can filter transactions by blockchain.

To enable Daemon mode, enter the code below on your local server.

Request Example:

  • Find Pending transaction to sign by KMS using the following v3 REST API endpoint.
  • KMS frequency checks for pending transactions to sign may be changed using the period parameter.
tatum-kms daemon --path=wallet.dat --testnet --chain=BTC --api-key=your-testnet-api-key --period=10

#You must enter the password to unlock the wallet storage.
#The password is required whenever you start the daemon or restart the daemon after it stopped.

📘

By default, KMS checks for the pending transactions every 5 seconds.

7. Initiate a transaction and let KMS sign it

  1. Send Bitcoin, from Your Production Environment, from your address to any other address.
    Use the standard BTC transaction v3 REST API endpoint
  2. KMS will detect a new pending transaction, sign it locally, and send the transaction to the blockchain.
    v3 REST API endpoint
  3. KMS should also mark the transaction as processed, so that it won't be sent to the blockchain again
    v3 REST API endpoint

Request Example:

  • Request initiated in your Production Environment
  • See Request Body Schema: BtcTransactionFromAddressKMS.
  • Instead of using privateKey, for KMS it's used the signatureId field that contains your signature ID from Step_4 - Store the PrivateKey in your Wallet

curl --location --request POST 'https://api.tatum.io/v3/bitcoin/transaction' \
--header 'x-api-key: {YOUR_API_KEY}' \
--header 'Content-Type: application/json' \
--data-raw '{
"fromAddress": [
       {
           "address": "AAAA3JPvMuwgpKovMTjBBB", //FROM STEP_ 3
           "signatureId": "QQQ-4b41-4ec9-b66c-WWW" //FROM STEP_4
       }
   ],
   "to": [
       {
           "address": "testnet-bitcoin-address",
           "value": 0.00001 //AMOUNT OF BTC TO SEND
       },
       {
           "address": "AAAA3JPvMuwgpKovMTjBBB",
           "value": 0.00007 //AMOUNT OF BTC TO send back to your sender's address 
       }
   ]
}'
//response:
{
   "signatureId": "61fe7c68cf2fbc595cbb89dd"
}

When KMS picks up the pending transaction, it will output something like the following sample:

Processing pending transaction - {
  "withdrawalId": null,
  "chain": "BTC",
  "serializedTransaction": "{\"hash\":\"81e62bdfbfc7bcb66c2a2f17335d033fd98b84c1188a7bb379a2dce9f1cda989\",\"version\":2,\"inputs\":[{\"prevTxId\":\"121702fd7acd1b2cca6bd19658009140730ba26ca67cd222c00f952a111e11f4\",\"outputIndex\":0,\"sequenceNumber\":4294967295,\"script\":\"\",\"scriptString\":\"\",\"output\":{\"satoshis\":2000,\"script\":\"76a914c8e668ee829837a2355c1e234a41f53f86b8156c88ac\"}}],\"outputs\":[{\"satoshis\":1000,\"script\":\"001487c70889f0a1d2f632d216a01472dde71f062aa7\"}],\"nLockTime\":0}",
  "hashes": [
    "b8eb99cd-ba04-4031-a65f-11d6420ebdd1"
  ],
  "index": null,
  "withdrawalResponses": null,
  "id": "61fe7c68cf2fbc595cbb89dd"
}.

8. Get Transaction Details

Using the KMS transaction ID from the id field of the response to the previous request 61fe7c68cf2fbc595cbb89dd, use the Get transaction details - v3 REST API endpoint

Request Example:

  • Returns the details of the signed transaction you performed.
  • The response contains a Bitcoin transaction ID in the txId field: f7572ef070d381612b7594940cc73ec008e796b37a73ff031f3855d2a23c9ade
  • You can check the txId on any Explorer. Example link

curl --request GET
--url https://api.tatum.io/v3/kms/61fe7c68cf2fbc595cbb89dd
--header 'x-api-key: {YOUR_API_KEY}'
//Response:
{
 "withdrawalId": null,
 "chain": "BTC",
 "serializedTransaction": "{\"hash\":\"81e62bdfbfc7bcb66c2a2f17335d033fd98b84c1188a7bb379a2dce9f1cda989\",\"version\":2,\"inputs\":[{\"prevTxId\":\"121702fd7acd1b2cca6bd19658009140730ba26ca67cd222c00f952a111e11f4\",\"outputIndex\":0,\"sequenceNumber\":4294967295,\"script\":\"\",\"scriptString\":\"\",\"output\":{\"satoshis\":2000,\"script\":\"76a914c8e668ee829837a2355c1e234a41f53f86b8156c88ac\"}}],\"outputs\":[{\"satoshis\":1000,\"script\":\"001487c70889f0a1d2f632d216a01472dde71f062aa7\"}],\"nLockTime\":0}",
 "hashes": [
   "b8eb99cd-ba04-4031-a65f-11d6420ebdd1"
 ],
 "index": null,
 "withdrawalResponses": null,
 "txId": "f7572ef070d381612b7594940cc73ec008e796b37a73ff031f3855d2a23c9ade",
 "id": "61fe7c68cf2fbc595cbb89dd"

Goot to Know

  • The wallet storage is encrypted with an AEC cipher and is stored on your local server.
  • The password you provide is used to encrypt the Mnemonics and PrivateKeys inside the file "wallet.dat".
  • You must enter the password to unlock a wallet storage.
  • The password is required whenever you start the Daemon or restart the Daemon after it stops.
  • The API key from your Production Environment must match 1:1 with the API key used in KMS.

❗️

If you lose your password, you will lose access to your Mnemonics and PrivateKeys. Tatum cannot help you.