Tatum
Search…
How to set up virtual accounts with XRP, BNB, and XLM
Create multiple virtual accounts from the same xpub and send assets between them instantly and feelessly.
Tatum Virtual Accounts offer unique capabilities to send cryptocurrencies between accounts instantly and without incurring blockchain fees. For each type of blockchain, virtual accounts must be set up in a specific way so that they will integrate and function seamlessly with your app's backend. In this guide, you will learn how to set up virtual accounts to work with the following blockchains:
  • Ripple (XRP)
  • Binance Chain (BNB)
  • Stellar (XLM)

Generate a wallet

In this guide, we will be using XRP to demonstrate how to set up virtual accounts. However, the exact same process applies to BNB and XLM.
All of the virtual accounts for XRP, BNB, or XLM within your app must be connected to the same wallet address on each respective blockchain. If virtual accounts are connected to deposit addresses generated from different addresses from different wallets, they will not function properly.
Use the following API endpoint to generate an XRP wallet:
JavaScript
cURL
cURL + KMS
1
import { generateXrpWallet } from "@tatumio/tatum";
2
import { config } from "dotenv";
3
4
config();
5
6
const generateWallet = () => {
7
const wallet = generateXrpWallet();
8
console.log(wallet);
9
};
10
11
generateWallet();
Copied!
1
curl --request GET \
2
--url https://api-eu1.tatum.io/v3/xrp/account \
3
--header 'x-api-key: REPLACE_KEY_VALUE'
Copied!
1
tatum-kms storemanagedwallet XRP --testnet
Copied!
The response will contain your wallet's xpub in the "address" field and private key in the "secret" field.
Response
1
{
2
address: 'rDWpnpN3KHUz49WZJpwNe2GQLHeSZ62B1d',
3
secret: 'ssKPqjZ9VPg79rEsrHjydRLMM8xgG'
4
}
Copied!

Create virtual accounts

Now, you can generate XRP virtual accounts connected to the xpub of the wallet you have just generated. You can generate as many virtual accounts as you want, but they must all be connected to the same xpub in order to function properly.
Use the following API endpoint to generate XRP virtual accounts. In the "xpub" field, enter the xpub of the wallet you generated in the previous step.
JavaScript
cURL
1
import { Account, Currency, CreateAccount, createAccount } from "@tatumio/tatum";
2
import { config } from "dotenv";
3
4
config();
5
6
const createNewAccount = async () => {
7
const createAccountData: CreateAccount = {
8
currency: Currency.XRP,
9
xpub: wallet.address
10
};
11
const accoun: Account = await createAccount(createAccountData);
12
console.log(accoun);
13
};
14
15
createNewAccount();
Copied!
1
curl --request POST \
2
--url https://api-eu1.tatum.io/v3/ledger/account \
3
--header 'content-type: application/json' \
4
--header 'x-api-key: REPLACE_KEY_VALUE' \
5
--data '{
6
"currency":"XRP",
7
"xpub":"rDWpnpN3KHUz49WZJpwNe2GQLHeSZ62B1d",
8
"customer":{
9
"accountingCurrency":"USD",
10
"customerCountry":"US",
11
"externalId":"123654",
12
"providerCountry":"US"
13
},
14
"compliant":false,
15
"accountCode":"AC_1011_B",
16
"accountingCurrency":"USD",
17
"accountNumber":"123456"
18
}'
Copied!
Response
1
{
2
currency: 'XRP',
3
active: true,
4
balance: { accountBalance: '0', availableBalance: '0' },
5
frozen: false,
6
xpub: 'rDWpnpN3KHUz49WZJpwNe2GQLHeSZ62B1d',
7
accountingCurrency: 'USD',
8
id: '61afba85997b887f543fa7f0'
9
}
Copied!

Create deposit addresses

Finally, we create deposit addresses for each virtual account. Again, these deposit addresses MUST be generated from the xpub of the wallet we generated in the first step. If they are not generated from the same xpub, they will not function properly.
On XRP and XLM, you must freeze a specific amount of assets for each deposit address you create. If you are creating 1,000,000 deposit addresses, this will cost you a ridiculous amount of money. For this reason, every virtual account uses the same deposit address, which is the same address as the wallet's xpub.
Use the following API endpoint to generate deposit addresses for each virtual account:
JavaScript
cURL
1
import { generateDepositAddress, Address } from "@tatumio/tatum";
2
import { config } from "dotenv";
3
4
config();
5
6
const createNewDepositAddress = async () => {
7
const id = account.id;
8
const address: Address = await generateDepositAddress(id);
9
console.log(address);
10
};
11
12
createNewDepositAddress();
Copied!
1
curl --request POST \
2
--url 'https://api-eu1.tatum.io/v3/offchain/account/{id}/address?index=1' \
3
--header 'x-api-key: REPLACE_KEY_VALUE'
Copied!
Response
1
{
2
xpub: 'rDWpnpN3KHUz49WZJpwNe2GQLHeSZ62B1d',
3
derivationKey: 1,
4
address: 'rDWpnpN3KHUz49WZJpwNe2GQLHeSZ62B1d',
5
currency: 'XRP',
6
destinationTag: 1
7
}
Copied!
When users receive deposits from external sources to the deposit address, the user is identified by unique identifiers specific to XRP, BNB, and XLM.\
The fields used to identify users for each blockchain are as follows:\
  • XRP - destinationTag
  • BNB - memo
  • XLM - message
If you try to create a virtual account with a different xpub, or try to create a deposit address for a virtual account with a different xpub, you will encounter the following error:
1
{
2
errorCode: 'account.xpub.bnb',
3
message: 'For BNB, XLM and XRP, only 1 xpub is allowed for API Key. For your ledger account, use already defined xpub and memo field for address differentiation. Please contact support at [email protected] if you need more.'
4
}
Copied!
This is not a bug, it is the expected behavior, and is telling you that you must use the same xpub to create different virtual accounts and deposit addresses on the Ripple blockchain.

And that's it!

Now your XRP virtual accounts should work perfectly and your users can send feeless, instant transactions to each other. All of your assets are in one blockchain address and you can send as many transactions as you want without having to worry about which blockchain address holds how much crypto or how much transaction fees will cost to send funds between accounts.