Toncoin
Overview
Toncoin (TON) is the native asset of the The Open Network (TON) blockchain. It utilizes:
- Account model
- EdDSA signature algorithm
Explorer
https://tonscan.org/
Wallets Types
BitGo enables holding Toncoin in the following wallet types:
| Multisig Cold | Multisig Hot | MPC Cold | MPC Hot | |
|---|---|---|---|---|
| Custody | ❌ | ❌ | ✅ | ✅ |
| Self-Custody | ❌ | ❌ | ✅ | ✅ |
Ticker Symbols
| Mainnet | Testnet |
|---|---|
| TON | TTON |
Faucet
You can use a faucet to obtain free testnet Toncoin for development and testing purposes.
Faucet: https://ton.app/utilities/faucet
Units
Toncoin is divisible by 10-[9] and the base unit is a nanoton (nton):
- 1 Ton = 1000000000 nanoton
- 1 nanoton = 0.000000001 Ton
Wallet Initialization
Note: Toncoin wallets require on-chain initialization before you can use them. Fund a TON wallet with a small amount and make a withdrawal transaction for the wallet to be initialized on chain.
Toncoin v1 Wallets
Older Toncoin wallets only support the EQ address format and withdrawals to EQ addresses. If the destination address is uninitialized, withdrawing to an EQ address results in a bounce back.
Currently, BitGo uses Toncoin v1 wallets with UQ address format. These wallets support withdrawing to both EQ and UQ addresses.
Toncoin v1 wallets with UQ address format don't require on-chain initialization before they can receive deposits, because these addresses are memoId based. When using these wallets, BitGo recommends using UQ addresses for withdrawing and using memo IDs for depositing.
Toncoin supports alphanumeric memoId.
Tokens
The TON blockchain natively supports tokens. To view all BitGo supported tokens on the TON blockchain, see TON Tokens
Create Wallet
Note: To enable Toncoin v1 wallets in your enterprise, you may need to contact [email protected].
export BITGO_EXPRESS_HOST="<YOUR_LOCALHOST>"
export COIN="tton"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export LABEL="<DESIRED_WALLET_NAME>"
export PASSPHRASE="<YOUR_BITGO_LOGIN_PASSPHRASE>"
export ENTERPRISE_ID="<YOUR_ENTERPRISE_ID>"
curl -X POST \
http://$BITGO_EXPRESS_HOST/api/v2/$COIN/wallet/generate \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"label": "'"$LABEL"'",
"passphrase": "'"$PASSPHRASE"'",
"enterprise": "'"$ENTERPRISE_ID"'",
"disableTransactionNotifications": true,
"disableKRSEmail": true
}'const { BitGo } = require('bitgo');
const accessToken = '<YOUR_ACCESS_TOKEN>';
// Initialize the SDK
const bitgo = new BitGo({
accessToken: accessToken,
env: 'test',
});
// Generate hot wallet
async function createHotWalletSimple() {
const newWallet = await bitgo.coin('tton').wallets().generateWallet({
label: '<DESIRED_WALLET_NAME>',
passphrase: '<YOUR_BITGO_LOGIN_PASSWORD>',
});
console.log(JSON.stringify(newWallet, undefined, 2));
}Create Address
Note: Receive addresses for Toncoin v1 wallets have the same root address, but use an incremental memo ID as a differentiator.
export COIN="tton"
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
curl -X POST \
https://app.bitgo-test.com/api/v2/$COIN/wallet/$WALLET_ID/address \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN"const { BitGo } = require('bitgo');
const accessToken = '<YOUR_ACCESS_TOKEN>';
// Initialize the SDK
const bitgo = new BitGo({
accessToken: accessToken,
env: 'custom',
customRootURI: 'https://app.bitgo.com',
});
// Create address
const wallet = await bitgo.coin('tton').wallets().generateWallet({
label: '<DESIRED_WALLET_NAME>',
passphrase: '<YOUR_BITGO_LOGIN_PASSPHRASE>',
});
const address = await wallet.createAddress(
);
// Print address details
console.log(JSON.stringify(address, undefined, 2));Consolidate Balance
Consolidation isn't required for Toncoin v1 wallets that use memo IDs for receive addresses.
Toncoin is an account-based asset and therefore requires consolidating to the base address in order to use the maximum spendable amount.
export BITGO_EXPRESS_HOST="<YOUR_LOCALHOST>"
export COIN="tton"
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export ADDRESS_1="<DESTINATION_ADDRESS_1>"
export ADDRESS_2="<DESTINATION_ADDRESS_2>"
export WALLET_PASSPHRASE="<YOUR_WALLET_PASSPHRASE>"
curl -X POST \
http://$BITGO_EXPRESS_HOST/api/v2/$COIN/wallet/$WALLET_ID/consolidateAccount \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"consolidateAddresses": [
{
"address": "'"$ADDRESS_1"'"
},
{
"address": "'"$ADDRESS_2"'"
}
],
"walletPassphrase": "'"$WALLET_PASSPHRASE"'"
}'const BitGoJS = require('bitgo');
const Promise = require('bluebird');
const bitgo = new BitGoJS.BitGo({ env: 'test' });
const coin = 'tton';
// Enter your wallet ID
const walletId = '<YOUR_WALLET_ID>';
// Enter your wallet passphrase
const walletPassphrase = '<YOUR_WALLET_PASSPHRASE>';
// Enter OTP code
const otp = '<YOUR_OTP>';
// Enter your access token
bitgo.authenticateWithAccessToken({ accessToken });
const wallet = await bitgo.coin(coin).wallets().get({ id: walletId });
// Base address
console.log('Base Address:', wallet.coinSpecific().baseAddress);
// Confirmed balance - sum of the balances of all the addresses
console.log('Confirmed Balance:', wallet.confirmedBalanceString());
// Spendable balance - balance of the base address
console.log('Spendable Balance:', wallet.spendableBalanceString());
const consolidationTxes = await wallet.buildAccountConsolidations();
try {
for (const unsignedConsolidation of consolidationTxes) {
const res = await wallet.sendAccountConsolidation({ walletPassphrase, prebuildTx: unsignedConsolidation });
console.dir(res, { depth: 6 });
}
} catch (e) {
console.error(e);
}
Estimate Fee
export COIN="tton"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
curl -X GET \
https://app.bitgo-test.com/api/v2/$COIN/tx/fee \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN"const BitGoJS = require('../../../src/index.js');
const bitgo = new BitGoJS.BitGo({ env: 'test' });
const Promise = require('bluebird');
const accessToken = '<YOUR_ACCESS_TOKEN>';
const coin = 'tton';
Promise.coroutine(function *() {
bitgo.authenticateWithAccessToken({ accessToken });
bitgo.coin(coin).feeEstimate({ numBlocks: 2 }, function callback(err, res) {
console.dir(res);
});
})();Transact
BitGo's Toncoin (TON) multisig contract currently only supports one sender and one recipient so the sendMany is not supported.
export BITGO_EXPRESS_HOST="<YOUR_LOCALHOST>"
export COIN="tton"
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export ADDRESS="<DESTINATION_ADDRESS>"
export AMOUNT="<AMOUNT_IN_BASE_UNITS>"
export WALLET_PASSPHRASE="<YOUR_WALLET_PASSPHRASE>"
curl -X POST \
http://$BITGO_EXPRESS_HOST/api/v2/$COIN/wallet/$WALLET_ID/sendcoins \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"address": "'"$ADDRESS"'",
"amount": "'"$AMOUNT"'",
"walletPassphrase": "'"$WALLET_PASSPHRASE"'"
}'export BITGO_EXPRESS_HOST="<YOUR_LOCALHOST>"
export COIN="tton"
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export ADDRESS_1="<DESTINATION_ADDRESS_1>"
export ADDRESS_2="<DESTINATION_ADDRESS_2>"
export AMOUNT_1="<AMOUNT_1_IN_BASE_UNITS>"
export AMOUNT_2="<AMOUNT_2_IN_BASE_UNITS>"
export WALLET_PASSPHRASE="<YOUR_WALLET_PASSPHRASE>"
curl -X POST \
http://$BITGO_EXPRESS_HOST/api/v2/$COIN/wallet/$WALLET_ID/sendmany \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"recipients": [
{
"address": "'"$ADDRESS_1"'",
"amount": "'"$AMOUNT_1"'"
},
{
"address": "'"$ADDRESS_2"'",
"amount": "'"$AMOUNT_2"'"
}
],
"walletPassphrase": "'"$WALLET_PASSPHRASE"'"
}'const tx = await fundedWallet.send({
address: `<DESTINATION_ADDRESS>`,
amount: `<AMOUNT>`,
walletPassphrase: process.env.PASSWORD as string,
});let params = {
recipients: [
{
amount: "<AMOUNT_1>",
address: "<DESTINATION_ADDRESS_1>",
},
{
amount: "<AMOUNT_2>",
address: "<DESTINATION_ADDRESS_2>",
},
],
walletPassphrase: "<YOUR_WALLET_PASSPHRASE>",
};
wallet.sendMany(params).then(function (transaction) {
// Print transaction details
console.dir(transaction);
});Updated 2 days ago