Tatum
Search…
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.
This type of transaction consists of 3 steps:
    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.
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

Request
Response
1
curl --location --request POST 'https://api-eu1.tatum.io/v3/offchain/bitcoin/transfer' \
2
--header 'x-api-key: YOUR_API_KEY' \
3
--header 'Content-Type: application/json' \
4
--data-raw '{
5
"senderAccountId": "5fbaca3001421166273b3779",
6
"address": "mpTwPdF8up9kidgcAStriUPwRdnE9MRAg7",
7
"amount": "0.00195",
8
"fee": "0.00005",
9
"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",
10
"xpub": "tpubDF1sYuDKCJr6mGietaVzqGmF2dqdKVBa1DtLJGBX8HXhtHZPv5UBz3WNWU22tiVAYSjqfvfFxMnDs3vM11iQrKej6dq33UCevhiPW9EQAS2"
11
}'
Copied!
1
{
2
"txId": "97bc1c3c23b179cba837e4060c0d07aa399f7ac7d34d91a7405cb5f801b93c8a",
3
"id": "5fbc208c99a159b4e9120c30",
4
"completed": true
5
}
Copied!
We can see that 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. For the response, we can see the transaction ID of the blockchain transaction, the ID of the withdrawal, and the flag, indicating whether the withdrawal was already completed or not.

Getting virtual account transactions

For a withdrawal, a virtual account transaction will be created for the source virtual account.
Request
Response
1
curl --location --request POST 'https://api-eu1.tatum.io/v3/ledger/transaction/account?pageSize=50' \
2
--header 'x-api-key: YOUR_API_KEY' \
3
--header 'Content-Type: application/json' \
4
--data-raw '{
5
"id": "5fbc208c99a159b4e9120c30"
6
}'
Copied!
1
[
2
{
3
"amount": "-0.002",
4
"operationType": "WITHDRAWAL",
5
"transactionType": "DEBIT_WITHDRAWAL",
6
"accountId": "5fbaca3001421166273b3779",
7
"currency": "BTC",
8
"reference": "c66a7a4e-d0f4-41c5-8b10-ef2b607aee6e",
9
"attr": null,
10
"anonymous": false,
11
"senderNote": null,
12
"counterAccountId": "mpTwPdF8up9kidgcAStriUPwRdnE9MRAg7",
13
"paymentId": null,
14
"marketValue": {
15
"currency": "EUR",
16
"source": "CoinGecko",
17
"sourceDate": 1606164328453,
18
"amount": "-30.99387999999999768043"
19
},
20
"created": 1606164620086,
21
"txId": "97bc1c3c23b179cba837e4060c0d07aa399f7ac7d34d91a7405cb5f801b93c8a"
22
},
23
{
24
"amount": "0.001",
25
"operationType": "DEPOSIT",
26
"currency": "BTC",
27
"transactionType": "CREDIT_DEPOSIT",
28
"accountId": "5fbaca3001421166273b3779",
29
"anonymous": false,
30
"reference": "c81a23dd-e162-4e0b-b0ff-e470c64f7b88",
31
"txId": "cd63e729ecc513bc22e8632b69a433126d5621c5f11047f34a0cbe144ce9aaac",
32
"address": "n22crsZTASULKtLqg3XzD1NwV1HnfrQpcd",
33
"marketValue": {
34
"currency": "EUR",
35
"source": "CoinGecko",
36
"sourceDate": 1606164328453,
37
"amount": "15.49693999999999884022"
38
},
39
"created": 1606164532855
40
},
41
{
42
"amount": "0.001",
43
"operationType": "DEPOSIT",
44
"currency": "BTC",
45
"transactionType": "CREDIT_DEPOSIT",
46
"accountId": "5fbaca3001421166273b3779",
47
"anonymous": false,
48
"reference": "be877b89-5398-4bf1-a621-0e7cabb4e41b",
49
"txId": "aee79834efd1def0c6e0672e22524d98d0fa74192d69edfdbfddc54d1883035f",
50
"address": "n22crsZTASULKtLqg3XzD1NwV1HnfrQpcd",
51
"marketValue": {
52
"currency": "EUR",
53
"source": "CoinGecko",
54
"sourceDate": 1606164328453,
55
"amount": "15.49693999999999884022"
56
},
57
"created": 1606164532843
58
}
59
]
Copied!

Getting a Bitcoin transaction

Request
Response
1
curl --location --request GET 'https://api-eu1.tatum.io/v3/bitcoin/transaction/97bc1c3c23b179cba837e4060c0d07aa399f7ac7d34d91a7405cb5f801b93c8a' \
2
--header 'x-api-key: YOUR_API_KEY'
Copied!
1
{
2
"txid": "97bc1c3c23b179cba837e4060c0d07aa399f7ac7d34d91a7405cb5f801b93c8a",
3
"hash": "97bc1c3c23b179cba837e4060c0d07aa399f7ac7d34d91a7405cb5f801b93c8a",
4
"size": 374,
5
"vsize": 374,
6
"version": 2,
7
"locktime": 0,
8
"vin": [
9
{
10
"txid": "aee79834efd1def0c6e0672e22524d98d0fa74192d69edfdbfddc54d1883035f",
11
"scriptSig": {
12
"asm": "30450221009080c34c2d256fd69675d808c8f8b98cf005d99d0b94fabd13dba314638133d402202e4b70a2ea9c89f16a887838b348fd404177515aea2df238990f1fa075c15fbe01 02f3ec43983975622cb97af7a55b895e25536b1355c34d681d5926638dfe2f16f9",
13
"hex": "4830450221009080c34c2d256fd69675d808c8f8b98cf005d99d0b94fabd13dba314638133d402202e4b70a2ea9c89f16a887838b348fd404177515aea2df238990f1fa075c15fbe012102f3ec43983975622cb97af7a55b895e25536b1355c34d681d5926638dfe2f16f9"
14
},
15
"sequence": 4294967295,
16
"vout": 0
17
},
18
{
19
"txid": "cd63e729ecc513bc22e8632b69a433126d5621c5f11047f34a0cbe144ce9aaac",
20
"scriptSig": {
21
"asm": "3045022100f5867400c4d4c7d475a59498b17d24cb03c564cfa813033f56a13c0720e84fb9022077c9cb331e1eb39595caea0a745f0b79137b4a6cb47c01a45c0f0bc5baa4ab7201 02f3ec43983975622cb97af7a55b895e25536b1355c34d681d5926638dfe2f16f9",
22
"hex": "483045022100f5867400c4d4c7d475a59498b17d24cb03c564cfa813033f56a13c0720e84fb9022077c9cb331e1eb39595caea0a745f0b79137b4a6cb47c01a45c0f0bc5baa4ab72012102f3ec43983975622cb97af7a55b895e25536b1355c34d681d5926638dfe2f16f9"
23
},
24
"sequence": 4294967295,
25
"vout": 1
26
}
27
],
28
"vout": [
29
{
30
"value": 0.00195,
31
"n": 0,
32
"scriptPubKey": {
33
"asm": "OP_DUP OP_HASH160 6227212d7fada54f0d0b450d4f2ad7918168eacb OP_EQUALVERIFY OP_CHECKSIG",
34
"hex": "76a9146227212d7fada54f0d0b450d4f2ad7918168eacb88ac",
35
"type": "PUBKEYHASH",
36
"reqSigs": 1,
37
"addresses": [
38
"mpTwPdF8up9kidgcAStriUPwRdnE9MRAg7"
39
]
40
}
41
},
42
{
43
"value": 0,
44
"n": 1,
45
"scriptPubKey": {
46
"asm": "OP_DUP OP_HASH160 ac6dfdfe0653b5f58a6938672ef20adef502b791 OP_EQUALVERIFY OP_CHECKSIG",
47
"hex": "76a914ac6dfdfe0653b5f58a6938672ef20adef502b79188ac",
48
"type": "PUBKEYHASH",
49
"reqSigs": 1,
50
"addresses": [
51
"mwEgHSMSQCMehcT7zPF5oYFVUJiF9572Le"
52
]
53
}
54
}
55
],
56
"blockhash": "00000000000000205a4941c1afd9481ba417533393fd8ad94468b991d668643e",
57
"confirmations": 1,
58
"time": 1606164810,
59
"blocktime": 1606164732,
60
"hex": "02000000025f0383184dc5ddbffded692d1974fad0984d52222e67e0c6f0ded1ef3498e7ae000000006b4830450221009080c34c2d256fd69675d808c8f8b98cf005d99d0b94fabd13dba314638133d402202e4b70a2ea9c89f16a887838b348fd404177515aea2df238990f1fa075c15fbe012102f3ec43983975622cb97af7a55b895e25536b1355c34d681d5926638dfe2f16f9ffffffffacaae94c14be0c4af34710f1c521566d1233a4692b63e822bc13c5ec29e763cd010000006b483045022100f5867400c4d4c7d475a59498b17d24cb03c564cfa813033f56a13c0720e84fb9022077c9cb331e1eb39595caea0a745f0b79137b4a6cb47c01a45c0f0bc5baa4ab72012102f3ec43983975622cb97af7a55b895e25536b1355c34d681d5926638dfe2f16f9ffffffff02b8f90200000000001976a9146227212d7fada54f0d0b450d4f2ad7918168eacb88ac00000000000000001976a914ac6dfdfe0653b5f58a6938672ef20adef502b79188ac00000000"
61
}
Copied!
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.
Last modified 1mo ago