How to send a Bitcoin blockchain transaction from a virtual account
When you work with Tatum Virtual Accounts, you can perform instant transactions between virtual accounts which are not written to the underlying blockchain. But every once and a while, you need to synchronize some of the transactions to the blockchain. In this case, you have to perform a virtual account-to-blockchain transaction. As a prerequisite, you must have a virtual account with credited blockchain transactions available.
Create a withdrawal transaction - this will perform a virtual account transaction from the source account. It will debit the amount from the source account.
Perform a blockchain transaction - in this step, the crypto assets are sent to the recipient's address. The source address of the blockchain transaction can be any blockchain address from your blockchain wallet.
Complete the withdrawal transaction - mark the withdrawal as successful and store the transaction ID of the blockchain transaction to the withdrawal operation. This step must be completed; otherwise, there will be inconsistencies within the virtual account state.
If the blockchain transaction fails, the withdrawal request must be canceled, and the funds will be credited to the originating virtual account.
All of these actions can be performed as one API call for a specific blockchain. We will cover Bitcoin in this section, but it works similarly in others.
Blockchain transactions are signed using a private key via API, which is not a secure way of signing transactions. Your private keys and mnemonics should never leave your security perimeter. To correctly and securely sign a transaction, you can use Tatum CLI from the command line, a specific language library like Tatum JS, the local middleware API, or our complex key management system, Tatum KMS.
Sending Bitcoin from a virtual account to the blockchain
The required parameters are the virtual account's identifier, information about the blockchain wallet, recipient blockchain address, amount to be sent, and blockchain fee to be paid.
import {sendBitcoinOffchainTransaction} from'@tatumio/tatum';/** * Send Bitcoin from Tatum account to address. * This will create Tatum internal withdrawal request with ID. * @param body - request body with data filter - https://apidoc.tatum.io/tag/Blockchain-operations/#operation/BtcTransfer
* @param testnet - true if testnet, false if mainnet */constbody= { senderAccountId:"5fbaca3001421166273b3779", address:"mpTwPdF8up9kidgcAStriUPwRdnE9MRAg7", amount:"0.00195", fee:"0.00005", mnemonic: "behave season capable ridge repair creek seat rescue potato divide fox expose wrestle asthma luggage rack afford pistol ridge modify direct picnic magic cannon",
xpub: "tpubDF1sYuDKCJr6mGietaVzqGmF2dqdKVBa1DtLJGBX8HXhtHZPv5UBz3WNWU22tiVAYSjqfvfFxMnDs3vM11iQrKej6dq33UCevhiPW9EQAS2"
}consttx=sendBitcoinOffchainTransaction(false, body);
The response will contain a transaction ID for the blockchain transaction, the account ID of the virtual account from which the funds were withdrawn, and whether or not the transaction was completed.
For a withdrawal, a virtual account transaction will be created for the source virtual account. To look up the details of this withdrawal transaction, use the find transactions for account endpoint:
import {getTransactionsByAccount} from'@tatumio/tatum';/** * Finds transactions for the account identified by the given account ID. * @param filter - request body with data filter - https://apidoc.tatum.io/tag/Transaction/#operation/getTransactionsByAccountId
* @param pageSize - max number of items per page is 50. * @param offset - optional Offset to obtain next page of the data. */constfilter= { id:"5fbc208c99a159b4e9120c30", }consttx=getTransactionsByAccount(filter,50,0);
Let's take a look at this blockchain transaction. You can see that the transaction consumed two deposit transactions - vin array - these are the two blockchain transactions credited to the account. As an output of the transaction - vout array - there are also two recipients. The first one is the recipient address you entered in the request. The second one is the address from your blockchain wallet with index 0. By default, Tatum uses address 0 of the blockchain wallet as an internal system address, where all the leftovers from the transactions are being acquired. They are used again in the next transaction.
In blockchain transactions, unspent deposits from every blockchain address in the same blockchain wallet are automatically collected at the address 0. This is necessary to fully utilize Tatum's off-chain features.
The logic is the same for the Litecoin and Bitcoin Cash blockchains. Ethereum is based on different principles and will be described in a separate article.