Get Started with TON
Set up your first application on TON Blockchain from scratch and discover it's speed, reliability and essential concepts of asynchronous way of thinking.
If you are completely new with programming, this guide is the best choice for you.
This learning path contains 5 modules and should take you around 45 minutes.
🛳 What you will learn
In this tutorial, you'll learn how to easily make blockchain transactions using JavaScript. You could learn to do it without this tutorial, but this way is cool and accessible.
- You will make your own TON Wallet with Tonkeeper
- You will use a testnet faucet to topup your wallet for testing
- You will understand essential concepts of TON smart contracts (Addresses, Cells)
- You will learn how to interact with TON using TypeScript SDK and API provider
- You will compile your first transaction using NFT Miner
You're going to mine an NFT rocket achievement!!!
As the first miners on TON, you will go through the Proof-of-Work smart contract and finally mine a secret reward for your TON wallet. Check it out:
Our goal for today is to mine an NFT! This achievement will stay with you forever.
Finally, you are able to mine this NFT achievement even in mainnet. (it costs only 0,05 TON!)
Video tutorial
Check out this awesome video tutorial created by a member of TON developer community! With this helpful guide, you can complete the tutorial with ease:
About Mining on TON
Today you will show off your talents in the most ancient and fundamental way in blockchain, starting with the grandpa, Bitcoin! ~Mining~
The initial historical mining process on TON was finished a long time ago. After the TON Blockchain launch, POW Giver smart contracts were launched, and everybody could participate. Fortunately, those times are over and the era of Staking has begun.
But right now, you will finish the old ritual of becoming a true TVM Developer. Let's leave the boring Toncoin for the moment and go back to some classics! Let's mine an NFT today! Here is what you will make:
Let's dive deeper into the Onboarding Challenge now.
🦄 Getting started
What do you need to start the Onboarding Challenge?
- Wallet. You need a non-custodial wallet to store an NFT in testnet mode.
- Repository. We will use a ready-made template designed especially for you.
- Developer Environment. Choose between cloud or local, it's up to you.
Prepare a Wallet
As with mining from years ago, you need a non-custodial wallet with its address to receive and store your future reward! Moreover, you need testnet mode enabled to collect some test Toncoin. You will use them to send a final minting transaction to the smart contract later.
So, prepare your wallet using these 2 steps:
- Install the Tonkeeper app on your smartphone.
- Enable test mode in Tonkeeper to use testnet.
Easy! Let's go to the development now.
Project setup
To make your life easier and skip routine low-level stuff, we will use a boilerplate. Please, use the ton-onboarding-challenge template to create your project:

After completing this step, you will get a fully-fledged repository that can be used as your miner's core. Congratulations! ✨
Development environment
Before we cover environment setup, you should know: it's possible to complete this tutorial completely in the cloud! It's free and quick.
Cloud vs Local
If you don't use JavaScript in your everyday life, you don't want to install JavaScript IDE and tools or your computer is not suited to development, it would be faster to use a cloud environment. It's completely free and provided by GitHub.
However, if you're familiar with NodeJS and Git and know how to work with
npm
, it may be more comfortable for you to use a local environment.
Cloud codespace
Good, so you decided to use the cloud today! In 2022 it's easy to start any project in the cloud with one simple step on your GitHub repository:

After this, GitHub will create a special cloud workspace with VSCode Online IDE. You don't need to install git, nodejs or other tools.
Just wait for ~30 seconds so that the terminal will install all dependencies.
Local environment
For local development you need 3 things:
- Git. Essential tool for every developer to work with repositories. Download it here.
- NodeJS. We will use JavaScript with TypeScript mode as the most popular choice for dApp development on TON. Download it here.
- JavaScript IDE. Your normal choice for development. VSCode, for example.
To start development, please:
- Clone your GitHub repository boilerplate
- Open repository in your IDE
Great! After these steps you're ready to get deeper into the TON Blockchain secrets. 👀
🎯 Connect to TON
Okay, what do you need to connect to TON Blockchain?
- Smart contract address as a point of destination. Our goal is to mine an NFT from the proof-of-work smart contract, so we need an address to get current mining complexity.
- API provider to make requests to TON Blockchain. TON has multiple API types for different purposes. We will use the testnet version of toncenter.com API.
- JavaScript SDK to parse the address and prepare it to make an API request. Read more about addresses in TON to understand why we should parse it. We will use ton.js.
Let's go further and understand how to make your very first request to TON Blockchain using toncenter API and ton.js
and get data from the proof-of-work smart contract!
Smart contract addresses
We need to add two addresses to the miner:
- Wallet address which will receive the reward (be sure you use testnet in Tonkeeper!).
- Collection address smart contract to mine an NFT (Copy the address on Getgems).
Open your index.ts
file in your project and create main function with initial constants:
import {Address} from "ton"
async function main () {
const wallet = Address.parse('YOUR_WALLET_ADDRESS');
const collection = Address.parse('COLLECTION_ADDRESS');
}
main()
Why do we need async function main()
function?
Later, you will make some requests to the public API, so you need to wait for responses from the API in your code with some await
constructions. Async/await allows us to save simplicity of code compared to a promises approach.
Why do we need to parse addresses?
In TON, addresses could have different forms and even different flags. Today we will use a user-friendly form, but if you are interested read more about smart contract addresses.
Address.parse()
from ton.js
SDK allows you to create an address object to convert addresses from one form to another easily.
Connect to API provider
We need to connect to the TonCenter API provider hosted on toncenter.com.
In ton.js
, you can use TonClient for that:
import {Address, TonClient} from "ton"
// ... previous code
const client = new TonClient({
endpoint: 'https://testnet.toncenter.com/api/v2/jsonRPC',
apiKey: 'YOUR_API_KEY',
})
If you try to make a request without an API key, you probably will have problems.
The API key allows you to make 10 requests per second. It's not suitable for production, but in our case 10 requests is more than enough for the Onboarding Challenge:
- Get an API key for testnet on the API page
It's better to use an RPC node provider or to run your own ton-http-api instance for that. Read more at the TonCenter API page.
Get Mining Data from TON
Finally, we can try to get some data from TON Blockchain!
Regarding the initial README file of the ton-onboarding-challenge we can see that the latest mining data you can get by running get_mining_data
method.
As a result we should receive an array with these fields:
(
int pow_complexity,
int last_success,
int seed,
int target_delta,
int min_cpl,
int max_cpl
)
How to run a method of any smart contract in TON?
With ton.js
you can run callGetMethod(SMART_CONTRACT_ADDRESS, METHOD)
function.
Try to run this code and read the console output:
// ... previous code
const miningData = await client.callGetMethod(collection, 'get_mining_data')
console.log(miningData)
To run the script you need to write in terminal (in project directory!):
npm run start
Good! If everything is in order, you are successfully connected to the API and have received some data to the console. Probably, you won't understand anything from the raw console output:
{
gas_used: 2374,
stack: [
[
'num',
'0x2880000000000000000000000000000000000000000000000000000000000'
],
[ 'num', '0x63984815' ],
[ 'num', '0x357401cf9b4f2386950faefd6b616264' ],
[ 'num', '0x1e' ],
[ 'num', '0xab' ],
[ 'num', '0xfc' ]
]
}
Yes, we see here how much gas was used to run the method and some num values in hex
format, but even this information is useless for us right now.
We need to convert the hex output to something useful.
Warning: this information is pretty low-level and not necessary for this tutorial. Read about it only if you want to go down to the low-level technical aspects of TON.
- Understand the concepts of TVM and how transactions work in TVM overview.
- After that go deeper in transaction fees concepts to see what the gas is.
- Finally, see the exact values in gas for TVM instructions.
Again, it's not necessary, you can read it later. Let's return to the tutorial!
Make Mining Data user-friendly
Ok, now we must convert hex
numbers to something that we can understand and use.
But we have a problem here. As you see with your output, even hex numbers are pretty big. We can't just move them to the variable and use it, because of JavaScript limitations.
That's why we need bn.js
. It's a library to work with Big Numbers, that are bigger than maximum JavaScript integer values. Use this example to see the Mining Data:
import {BN} from 'bn.js'
// ... previous code
const parseStackNum = (sn: any) => new BN(sn[1].substring(2), 'hex');
const complexity = parseStackNum(miningData.stack[0]);
const last_success = parseStackNum(miningData.stack[1]);
const seed = parseStackNum(miningData.stack[2]);
const target_delta = parseStackNum(miningData.stack[3]);
const min_cpl = parseStackNum(miningData.stack[4]);
const max_cpl = parseStackNum(miningData.stack[5]);
console.log('complexity', complexity);
console.log('last_success', last_success.toString());
console.log('seed', seed);
console.log('target_delta', target_delta.toString());
console.log('min_cpl', min_cpl.toString());
console.log('max_cpl', max_cpl.toString());
As you see, miningData is a stack array with hex numbers. To get the values, we added parseStackNum
function that creates a BN object from hex number.
After that we try to print values in console. Some values are printed as BN, as it will make it more user-friendly for us. Try to run the script again with command:
npm run start
What do you see in console?
Here is an example output:
complexity <BN: 2880000000000000000000000000000000000000000000000000000000000>
last_success 1670924309
seed <BN: 357401cf9b4f2386950faefd6b616264>
target_delta 30
min_cpl 171
max_cpl 252
Let's cover the Mining Data deeper to understand the concepts behind mining:
complexity
is the most important number for miners. It's a Proof-of-Work complexity for the values. You're successful if the final hash is less than complexity.last_success
is a unixtime of the last mining transaction. Every time last_success changes you need to run the miner again, because the seed changes too.seed
is a unique value generated by a smart contract to calculate a hash. If you're interested in how the seed changes, search in the project files withctx_seed
keyword.target_delta
,min_cpl
andmax_cpl
won't be used in our tutorial. But you can always read more about how they are used in smart contracts to calculate proof-of-work complexity in the source files of the collection in your project.
That's it! Now we have the values which we will use in our NFT Miner in the next chapter.
🛠 Prepare an NFT Miner
Hey, you did a great job! You are already connected to TON and got the necessary mining data from TON Blockchain to write a true NFT Miner. We are almost done here.
In this chapter you will prepare a mining message and calculate a hash of the message. After that, you will find a hash that's less than the complexity we got from the smart contract.
That is what a miner is! Simple, isn't it?
Prepare a Mining Message
Ok, what message do we need? What data do we need to send?
Luckily, README file already has the answers to these questions! You can see a table with fields and types of "proof of work Cell". It looks like an array. There are many fields there!
A cell is an essential data structure in TON. It works with bits to make transactions fast. But we won't go so low-level here. Read more in the Cells article if you're interested.
Luckily for you again, all the data structures have already been written with TypeScript for this tutorial. Use a MineMessageParams
object from NftGiver.data.ts to build a transaction with Queries:
import {unixNow} from "./src/lib/utils";
import {MineMessageParams, Queries} from "./src/giver/NftGiver.data";
// ... previous code
const mineParams : MineMessageParams = {
expire: unixNow() + 300, // 5 min is enough to make a transaction
mintTo: wallet, // your wallet
data1: new BN(0), // temp variable to increment in the miner
seed // unique seed from get_mining_data
};
let msg = Queries.mine(mineParams); // transaction builder
Probably, you have a question: where is the op and data2 from the table?
- In the table data1 must be equal to data2. So we can omit filling the data2, the transaction builder did a low-level job for us (see
Queries.mine()
sources). - As
op
is always the same, it is already implemented in transaction builder Queries and in OperationCodes. You can find the op code by going to the source code ofmine()
method.
You might find it interesting to check out the sources, but it is not necessary.
Finally: the NFT Miner
What do we need to make a miner? Let's have a look at this line:
let msg = Queries.mine(mineParams);
We have compiled a message msg
here. The idea of mining is to find a hash msg.hash()
that will be less than complexity
from the last received get_mining_data(). We can increment data1
as many times as we need.
So the pure miner will run infinitely while msg.hash() > complexity
.
Let's see the code adopted for BigNumbers in TypeScript:
let msg = Queries.mine(mineParams);
while (new BN(msg.hash(), 'be').gt(complexity)) {
mineParams.expire = unixNow() + 300
mineParams.data1.iaddn(1)
msg = Queries.mine(mineParams)
}
console.log('Yoo-hoo, you found something!')
A few points about BN functions here:
- We create a big-endian BN object from the
msg.hash()
with'be'
attribute. gt()
means greater than something for comparing BigNumbers.iaddn(1)
means just increment the value.
But this miner is still useless for us! How can we progress from here?
Let's try to add some beauty ✨
We want to make the miner sexy now! How do we do it?
Just follow me, my friend, follow me:
let msg = Queries.mine(mineParams);
let progress = 0;
while (new BN(msg.hash(), 'be').gt(complexity)) {
progress += 1
console.clear()
console.log(`Mining started: please, wait for 30-60 seconds to mine your NFT!`)
console.log(' ')
console.log(`⛏ Mined ${progress} hashes! Last: `, new BN(msg.hash(), 'be').toString())
mineParams.expire = unixNow() + 300
mineParams.data1.iaddn(1)
msg = Queries.mine(mineParams)
}
console.log(' ')
console.log('💎 Mission completed: msg_hash less than pow_complexity found!');
console.log(' ')
console.log('msg_hash: ', new BN(msg.hash(), 'be').toString())
console.log('pow_complexity: ', complexity.toString())
console.log('msg_hash < pow_complexity: ', new BN(msg.hash(), 'be').lt(complexity))
After these small improvements you have got an NFT miner and an understanding of what's going on.
Just check it out! Remember:
npm run start
Cool, isn't it? 😏
But, what do we do next? Ok, you found a hash. But what to do with all this stuff???
🎨 Prepare a Transaction
We need to compile a transaction and send it to the blockchain with your wallet.
This is exactly what we mean by a mining an NFT. We're almost at the finish line now.
Build a payment link
In TON, it's possible to build payment urls in a format like ton://transfer/<address>
with different parameters. It's perfect for us, as we want to build a message and send it to the smart contract with our Tonkeeper wallet:
import {toNano} from "ton"
// ... previous code
console.log(' ');
console.log("💣 WARNING! As soon as you find the hash, you should quickly make a transaction.");
console.log("If someone else makes a transaction, the seed changes, and you have to find a hash again!");
console.log(' ');
// flags work only in user-friendly address form
const collectionAddr = collection.toFriendly({
urlSafe: true,
bounceable: true,
})
// we must convert TON to nanoTON
const amountToSend = toNano('0.05').toString()
// BOC means Bag Of Cells here
const preparedBodyCell = msg.toBoc().toString('base64url')
// final method to build a payment url
const tonDeepLink = (address: string, amount: string, body: string) => {
return `ton://transfer/${address}?amount=${amount}&bin=${body}`;
};
const link = tonDeepLink(collectionAddr, amountToSend, preparedBodyCell);
console.log('🚀 Link to receive an NFT:')
console.log(link);
Okay, let's run the script. Do you see the link? Good.
But what to do with the payment link on your PC?
It's impossible to use it with a wallet on your smartphone! Let's change that now.
Convert link for smartphone
As a solution, the most brilliant minds in the world created a QR code generator specifically for use in terminal. With this tool, you can simply scan the payment link from your Tonkeeper wallet to complete a transaction.
npm install qrcode-terminal
Finally, you need to encode your link
into the QR code and print it in the console:
const qrcode = require('qrcode-terminal');
qrcode.generate(link, {small: true}, function (qrcode : any) {
console.log('🚀 Link to mine your NFT (use Tonkeeper in testnet mode):')
console.log(qrcode);
console.log('* If QR is still too big, please run script from the terminal. (or make the font smaller)')
});
Do you sense the experience in the air? That's you, on your way to becoming a TVM developer.
But we still don't have any testnet coins to make a transaction.
Let's fix that quickly.
⛏ Mine an NFT with wallet
You are now on the cusp of the crowning achievement of your TON career – mining an NFT and becoming a true TVM developer!
Which way do you want to choose?
Simple: Mine in testnet
We have already covered all the steps you need to make your first transaction in the testnet:
- You have activated testnet mode in your Tonkeeper
- You have added to
wallet
your testnet wallet address from Tonkeeper - You have added to
collection
the address of the NFT collection from testnet
Testnet coins
All that’s left is to acquire some testnet TON. You can find a testnet faucet here.
Mine your NFT Rocket
Finally, to mine your rocket, follow these steps:
- Open Tonkeeper wallet on your smartphone which should have some testnet TON.
- Select scan mode on the application to scan a QR code.
- Run your lovely miner to find a hash and wait 30-60 seconds.
- Scan the generated QR code from the miner as quickly as possible!!!
Try it a couple of times because someone could mine the NFT before you! Be quick!
After some time, you will have mined your NFT and become a TVM Developer in TON Blockchain. The ritual is complete. Look at your NFT in Tonkeeper.
Welcome aboard, a true TVM Developer! You did it. 🛳
Genuine: Mine in mainnet
Hey! For anyone who amazed to mine an NFT in mainnet we have a special instruction provided. As an NFT will stay with you forever as an achievement for completing such long and hard quest, we need to check some things before mining:
- You have activated mainnet mode in your Tonkeeper
- You have added to the
wallet
your mainnet wallet address from Tonkeeper - You have added to the
collection
the address of the NFT collection from mainnet - You have changed API provider URL to the mainnet:
- remove
testnet.
subdomain from the API URL - obtain the mainnet API key
- remove
- You have at least 0.1 TON on your mainnet wallet
Mine your NFT Rocket
Finally, to mine your rocket, follow these steps:
- Open Tonkeeper wallet on your smartphone with some real TON.
- Select scan mode on the application to scan a QR code.
- Run your lovely miner to find a hash and wait 30-60 seconds.
- Scan the generated QR code from the miner as quickly as possible!!!
Try it a couple of times because someone could mine the NFT before you! Be quick!
After some time, you will have mined your NFT and become a TVM Developer in TON Blockchain. The ritual is complete. Look at your NFT in Tonkeeper.
Welcome aboard, a TVM Developer! You did it. 🛳
🧙 What's next?
First, take a rest! You did a big task! You are a TVM developer now. But it's only the beginning of the long way. A journey of a thousand miles begins with one step.
After some time, you could discover these materials made for different parts of TON.
Where do you want to go first?
- Smart contracts. TON Hello World: Step-by-step guide for writing your first smart contract
- FunC. What is FunC? Go deeper into TON concepts. FunC Journey: Part 1
- DApps. Write your first DApp on Telegram: Bot for sales of dumplings
- DeFi. Want to launch own token? Mint Your first Jetton
- Web3. Want to understand TON Sites? How to run TON Site
You are one of the first explorers here. If you find any mistakes or feel stacked, please send feedback to @SwiftAdviser. I will fix it ASAP! :)