A Beginner's Guide to TON Blockchain: Creating and Accessing a Wallet

·

The Open Network (TON) Blockchain is a decentralized ecosystem powered by its native cryptocurrency, TON (formerly known as TonCoin). This digital currency is used to pay for transaction fees (gas), similar to ETH on the Ethereum network. If you're exploring the TON ecosystem, you likely already hold some TON and may have a wallet set up.

This step-by-step tutorial will guide you through creating a new TON wallet using a popular wallet application and then accessing it programmatically. This knowledge is essential if you plan to deploy smart contracts or create bots that send and receive TON tokens. We'll also explore how wallets function on TON and become familiar with their operation.

Mainnet vs. Testnet: Choosing Your Environment

The TON blockchain offers two distinct environments: Mainnet and _Testnet_.

While Testnet is initially attractive due to its lack of cost, many developers find Mainnet to be more cost-effective in the long run. Mainnet offers a more reliable and realistic experience. Given that TON transactions are exceptionally cheap—costing around one cent each—a small investment of a few dollars is sufficient for hundreds of transactions, saving valuable development time.

Step 1: Creating a New Wallet with an App

The simplest way to create a TON wallet is to visit the official wallets page and choose a non-custodial wallet application from the list. Non-custodial wallets ensure you retain full control over your private keys, which aligns with the core principle of self-custody in blockchain.

We will use the Tonkeeper application for this guide. Install and open the Tonkeeper app on your mobile device.

By default, Tonkeeper operates on the TON Mainnet. If you prefer to use the Testnet first, you must enable the developer mode. Navigate to the 'Settings' tab and rapidly tap the Tonkeeper logo at the bottom five times. This action will reveal the 'Development menu.' Select 'Switch to Testnet' to change the network. You can use this same menu to return to Mainnet later.

If you haven't connected a wallet, tap the 'Set Up Wallet' button to create a new one. Within seconds, your wallet will be created, and Tonkeeper will display your 24-word recovery phrase.

Step 2: Backing Up Your 24-Word Recovery Phrase

Your recovery phrase is the master key to your wallet and the funds it holds. Losing this phrase will result in a permanent loss of access to your funds. Sharing this phrase with anyone gives them complete control over your assets. It must be kept secret and backed up in a secure location.

The use of a 24-word mnemonic phrase, instead of a string of random characters, is a user-friendly innovation designed to prevent errors when recording the key. These words act as a mnemonic device, making the complex key easier for humans to write down and remember accurately, significantly reducing the risk of typos that could lock users out of their wallets.

Step 3: Inspecting Your Wallet via a Block Explorer

You can copy your wallet address by tapping the area in the top-left corner of the Tonkeeper app or by navigating to the 'Receive' button. A typical TON address looks like this:

kQCJRglfvsQzAIF0UAhkYH6zkdGPFxVNYMH1nPTN_UpDqEFK

This address is public information. You can share it with others to receive funds, but it does not grant anyone access to spend your assets. It's important to remember that wallet addresses are pseudonymous; while they don't directly reveal your real-world identity, someone who knows you and your address can link your transactions to you.

A block explorer is a tool for querying on-chain data and investigating addresses. We will use Tonscan. Remember that Mainnet and Testnet have different explorers (e.g., testnet.tonscan.org for Testnet).

Paste your wallet address into the explorer's search bar. If the wallet is new and unused, its status will be displayed as "Inactive." The "Contract" tab may show a message indicating that the address contains no data in the blockchain, meaning the smart contract has not been deployed yet.

In TON, wallets are smart contracts! This message means the contract code has not been uploaded to the blockchain, so it remains uninitialized.

You might also notice that the address displayed by the explorer differs slightly from the one you entered. This is normal, as there are multiple encoding formats for the same TON address. They all resolve to the same underlying public key.

Step 4: Funding and Deploying Your Wallet Contract

As the explorer shows, your new wallet's balance is zero. It needs to be funded with some TON to pay for the gas required to deploy its contract. A common question is: how can you send coins to a contract that isn't deployed?

On TON, this is not an issue. The blockchain maintains a balance for every address, regardless of whether a smart contract has been deployed at that address. You can send TON to your wallet address before its contract is live.

After sending 2 TON to your address, refresh the block explorer. You will see the balance has updated to 2 TON, but the state likely remains "Inactive."

The wallet contract will deploy when you execute its first outgoing transaction, which requires a positive balance to pay gas fees. Let's send a small amount, say 0.01 TON, to another address using Tonkeeper.

After approving the transaction, refresh the explorer. The status should now be "Active," and the contract type will be displayed (e.g., "Wallet v4 r2"). You will also see that a small fee was deducted from your balance for the deployment and transfer costs.

Step 5: Understanding Wallet Contract Versions

The block explorer identifies your "Contract Type" (e.g., "Wallet v4 r2"). This refers to the version of the smart contract code that powers your wallet. The TON core team has released multiple versions of the standard wallet contract over time, each with potential improvements.

It is entirely possible for a single secret mnemonic phrase to generate wallets of different versions, each with a unique address. This can sometimes cause confusion. If you try to access your funds with your recovery phrase and see a different address with a zero balance, don't panic. It's probable that you are looking at a different wallet version, not that your funds are missing. Always ensure you are interacting with the correct contract version that you initially deployed and funded.

Step 6: Setting Up Your Local Development Environment

To access your wallet programmatically, we will use JavaScript/TypeScript libraries. You need to set up a development environment on your machine.

First, ensure you have Node.js (version 16 or newer) installed. You can verify your installation by running node -v in your terminal.

Choose an IDE with good TypeScript support; Visual Studio Code is a highly recommended, free, and open-source option.

Create a new directory for your project and initialize it to support TypeScript. Open a terminal in your project directory and run:

npm init -y
npm install -D typescript ts-node
npx tsc --init

Next, install the necessary TON libraries:

npm install @ton/ton @ton/crypto @ton/core

Step 7: Programmatically Deriving Your Wallet Address

Our first coding task is to compute our wallet address offline. The address is derived mathematically from the wallet's version and the private key generated from your secret mnemonic phrase.

Create a file named step7.ts with the following content. Important: Replace the placeholder mnemonic with your own 24-word phrase.

import { mnemonicToWalletKey } from "@ton/crypto";
import { WalletContractV4 } from "@ton/ton";

async function main() {
  // Open wallet v4 (ensure this version matches your actual wallet)
  const mnemonic = "unfold sugar water ..."; // your 24 secret words
  const key = await mnemonicToWalletKey(mnemonic.split(" "));
  const wallet = WalletContractV4.create({ publicKey: key.publicKey, workchain: 0 });

  // Print wallet address
  console.log(wallet.address.toString({ testOnly: true })); // Use { testOnly: false } for Mainnet
  // Print wallet workchain
  console.log("workchain:", wallet.address.workChain);
}

main();

Run the script with:

npx ts-node step7.ts

The output should match the address you see in Tonkeeper and the block explorer. Note the workchain number; standard contracts operate on workchain 0.

👉 Explore more developer tools and resources

Crucial Note: If your wallet is a different version (e.g., v3 r2), you must replace WalletContractV4 with the appropriate class, such as WalletContractV3R2.

Step 8: Reading Wallet State from the Blockchain

Now, let's connect to the blockchain network to read live state data from our wallet contract. We will query the current TON balance and the seqno (sequence number), which increments with each outgoing transaction.

To query the network, we need an RPC provider. TON Access is a decentralized service that provides free and unrestricted API access. Install it:

npm install @orbs-network/ton-access

Create a new file, step8.ts, with the following code (remember to use your mnemonic and the correct wallet class):

import { getHttpEndpoint } from "@orbs-network/ton-access";
import { mnemonicToWalletKey } from "@ton/crypto";
import { WalletContractV4, TonClient, fromNano } from "@ton/ton";

async function main() {
  // Open wallet v4
  const mnemonic = "unfold sugar water ..."; // your 24 secret words
  const key = await mnemonicToWalletKey(mnemonic.split(" "));
  const wallet = WalletContractV4.create({ publicKey: key.publicKey, workchain: 0 });

  // Initialize TON RPC client on testnet
  const endpoint = await getHttpEndpoint({ network: "testnet" }); // Use { network: "mainnet" } for Mainnet
  const client = new TonClient({ endpoint });

  // Query balance from chain
  const balance = await client.getBalance(wallet.address);
  console.log("balance:", fromNano(balance)); // Converts balance from nanoTON to TON

  // Query seqno from chain
  const walletContract = client.open(wallet);
  const seqno = await walletContract.getSeqno();
  console.log("seqno:", seqno);
}

main();

Run the script with npx ts-node step8.ts to see your wallet's live balance and sequence number.

Step 9: Sending a Transfer Transaction

The previous operation was read-only. Now, we will perform a privileged write operation: sending TON from our wallet. This requires our private key for signing the transaction.

Create step9.ts. This script will send 0.05 TON to a special address, which will mint a secret NFT from a collection as a reward for completing this tutorial.

import { getHttpEndpoint } from "@orbs-network/ton-access";
import { mnemonicToWalletKey } from "@ton/crypto";
import { TonClient, WalletContractV4, internal } from "@ton/ton";

async function main() {
  // Open wallet v4
  const mnemonic = "unfold sugar water ..."; // your 24 secret words
  const key = await mnemonicToWalletKey(mnemonic.split(" "));
  const wallet = WalletContractV4.create({ publicKey: key.publicKey, workchain: 0 });

  // Initialize TON RPC client on testnet
  const endpoint = await getHttpEndpoint({ network: "testnet" });
  const client = new TonClient({ endpoint });

  // Make sure wallet is deployed
  if (!await client.isContractDeployed(wallet.address)) {
    return console.log("wallet is not deployed");
  }

  const walletContract = client.open(wallet);
  const seqno = await walletContract.getSeqno();

  // Send transfer transaction
  await walletContract.sendTransfer({
    secretKey: key.secretKey,
    seqno: seqno,
    messages: [
      internal({
        to: "EQA4V9tF4lY2S_J-sEQR7aUj9IwW-Ou2vJQlCn--2DLOLR5e", // Reward address
        value: "0.05", // 0.05 TON
        body: "Hello", // Optional comment
        bounce: false,
      })
    ]
  });

  // Wait until transaction is confirmed
  let currentSeqno = seqno;
  while (currentSeqno == seqno) {
    console.log("waiting for transaction to confirm...");
    await sleep(1500);
    currentSeqno = await walletContract.getSeqno();
  }
  console.log("transaction confirmed!");
}

function sleep(ms: number) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

main();

Execute the script with npx ts-node step9.ts. The script will sign and send the transaction. It then waits for validators to include it in a new block by polling the wallet's seqno; a change indicates a successful transaction. You should soon see the NFT in your wallet's collectibles section. You can also look up the outgoing transaction on the Tonscan block explorer.

👉 Get advanced methods for smart contract development

Frequently Asked Questions

What is the difference between a custodial and non-custodial wallet?
A custodial wallet is managed by a third party that holds your private keys on your behalf. This is similar to a traditional bank. A non-custodial wallet gives you full control and responsibility over your private keys and funds. TON's philosophy emphasizes self-custody for true ownership.

Can I use the same mnemonic on Mainnet and Testnet?
Yes, the same mnemonic will generate the same set of private and public keys. However, the addresses and resulting wallets exist on separate, independent networks. Your Mainnet balance and transaction history will not appear on Testnet, and vice-versa.

Why is my wallet 'Inactive' even after receiving funds?
An 'Inactive' status in the block explorer means the wallet's smart contract code has not yet been deployed to the blockchain. The wallet can still receive funds. It will become 'Active' after you initiate its first outgoing transaction, which triggers the contract deployment.

What happens if I send funds to the wrong address?
Transactions on the TON blockchain are irreversible. If you send funds to an incorrect address, they cannot be recovered. Always double-check the address before confirming a transaction. Some addresses may be invalid or non-existent, in which case the transaction may be recoverable due to bouncing, but this is not guaranteed.

How do I choose the correct wallet contract version in my code?
The version you use in your code must match the version of the wallet you created with your app (e.g., Tonkeeper). You can find the version number by checking your wallet's page on a block explorer under "Contract Type." Use the corresponding class from the @ton/ton library (e.g., WalletContractV4, WalletContractV3R2).

Are transaction fees on TON high?
No, one of TON's key advantages is its extremely low transaction fees. A typical transfer costs a fraction of a cent, making it very economical for developers and users alike.

Conclusion

You have successfully created a TON wallet, understood its on-chain state, and learned how to access and control it through code. This foundation is critical for any further development on the TON blockchain, such as building smart contracts or dApps. Remember to always prioritize security, especially when handling your secret mnemonic phrase and private keys.