Your wallet private key / 24 word mnemonic is the main secret you must protect in order to secure your funds from theft. The most secure way to protect secrets is via cold storage - meaning hold the secret on a "cold" device that isn't connected to the Internet. By completely disconnecting the secret from the outside world, no hacker could gain access to it.
This is often achieved through the use of hardware wallets (like Trezor and Ledger) that hold the secret and prevent it from being accessed. Unfortunately, the popular hardware wallets don't support TON yet officially. The protocol defined in this repo is similar in the sense that a special offline computer assumes the role of the hardware wallet.
- Setup offline computer - this special computer will hold your TON private key and should never be connected to the Internet
- Sign deployment offline - use the offline computer to sign a new transaction for deploying the TON wallet contract (create BOC file)
- Move BOC and send - move the BOC file to a different online computer and transmit it to TON mainnet using a lite client
- Sign transfer offline - use the offline computer to sign a new send transaction for sending TON coins (create BOC file)
- Move BOC and send - move the BOC file to a different online computer and transmit it to TON mainnet using a lite client
This computer should never be connected to the Internet, so all tools must be installed on it in advance:
-
Build
fift
executableThis command line tool is part of the TON toolchain. Its source code is part of the official TON repo. Build it from source code by following the official instructions or find a trusted source for pre-built binaries that you can just download and use.
-
Download
fift-lib
libraryThis dependency is a standard collection of about 8 fift files. They are part of the official TON repo. Download the files from https://github.com/newton-blockchain/ton/tree/master/crypto/fift/lib. Set the
fift-lib
directory as the environment variableFIFTPATH
by runningexport FIFTPATH=~/ton/fift-lib
. -
Download
wallet-v3.fif
,new-wallet-v3.fif
andwallet-v3-code.fif
The TON core team publishes the official template for a wallet smart contract. In the time of writing, the most recent version is wallet V3. The code is part of the official TON repo. Download wallet-v3.fif, new-wallet-v3.fif and wallet-v3-code.fif from https://github.com/newton-blockchain/ton/blob/master/crypto/smartcont.
-
Build
tonweb-mnemonic.js
JS libraryThis JavaScript library helps manipulate 24 word mnemonics (BIP39) and convert them to functional private keys that can sign TON transactions. The library source code is available here. Build it from source code by running
npm install && npm run build:web && cp dist/web/index.js tonweb-mnemonic.js
or find a trusted source for a pre-built version that you can just download and use. -
Download
ton-mnemonic-pk.html
This offline HTML relies on
tonweb-mnemonic.js
and provides an easy-to-use interface where you can convert an existing 24 word mnemonic (BIP39) to a 32-byte TON-compatible private key file (mywallet.pk
). The private key file (mywallet.pk
) is needed as argument tofift
executable for signing transactions. The HTML is part of this repo and can be downloaded here.
-
Ready
mywallet.pk
The primary secret stored on the offline computer is the private key file. If you only have a 24 word mnemonic (BIP39), open
ton-mnemonic-pk.html
using a web browser (offline), type the mnemonic into the page and use it to generatemywallet.pk
and save it. Never give any unauthorized party access tomywallet.pk
as access to this file gives full access to all your funds. Rename this file for convenience to identify your wallet with a meaningful name (mywallet
will be used as the name throughout this tutorial). -
Sign deployment
Command line:
fift -s new-wallet-v3.fif <workchain-id> <wallet-id> <wallet-filename-without-extension>
new-wallet-v3.fif
- the template for the wallet smart contract downloaded earlierworkchain-id
- normally zero (0) as the wallet will reside on the basic workchainwallet-id
- any integer since multiple wallets can be deployed by the same key, the value698983191
is used by standard wallets as the primary ID, using it will allow seamless import of the wallet into a third-party wallet app in the futurewallet-filename-without-extension
- path to the private key file without the.pk
extension (mywallet.pk
will be justmywallet
)
Example:
fift -s new-wallet-v3.fif 0 698983191 mywallet
Example output:
Creating new advanced v3 wallet in workchain 0 with unique wallet id 698983191 Loading private key from file mywallet.pk ... Bounceable address (for later access): kQBpfCmpfvybimCKMqYOUvLmuoY11VryXhdmjsP8MRvAO6SJ
The public wallet address in the example output is
kQBpfCmpfvybimCKMqYOUvLmuoY11VryXhdmjsP8MRvAO6SJ
-
Save
mywallet.addr
The above command will generate an ADDR file which contains the public wallet address. The ADDR file will be created in the current directory with the name
mywallet.addr
(or any other meaningful name you chose forwallet-filename-without-extension
above). Store the ADDR file for future use, it will be required for signing transfer transactions. This file is not secret, so it does not need heavy protection. -
See output BOC
The above command will generate a BOC file which contains the signed transaction for transmission to TON mainnet. The BOC file will be created in the current directory with the name
mywallet-query.boc
(or any other meaningful name you chose forwallet-filename-without-extension
above).
-
Move BOC
The output BOC should be moved to a regular (online) computer that is connected to the Internet. It is your responsibility to move it securely using any method like a USB-Key or QR code reader and make sure that no other important files (like
mywallet.pk
) get compromised in the process. -
Fund address
Send some TON coins to the public wallet address to fund the contract deployment. An amount of 0.1 TON should suffice. The public wallet address appears in the output of the
fift
command in step 2. -
Prepare
lite-client
The lite client command line tool is another part of the TON toolchain. Its source code is part of the official TON repo. Build it from source code by following the official instructions or find a trusted source for pre-built binaries that you can just download and use.
Download the latest TON mainnet configuration file from https://newton-blockchain.github.io/global.config.json.
-
Send BOC to mainnet
Command line:
lite-client -C global.config.json -c 'sendfile <boc-file>'
global.config.json
- TON mainnet configuration file downloaded earlierboc-file
- path to the BOC file to send
Example:
lite-client -C global.config.json -c 'sendfile mywallet-query.boc'
Example output:
using liteserver 6 with addr [51.195.176.148:4194] [ 1][t 1][2022-03-28 11:18:26.184795][lite-client.h:362][!testnode] conn ready [ 2][t 1][2022-03-28 11:18:26.203706][lite-client.cpp:363][!testnode] server version is 1.1, capabilities 7 [ 3][t 1][2022-03-28 11:18:26.203748][lite-client.cpp:372][!testnode] server time is 1648466306 (delta 0) ... [ 1][t 1][2022-03-28 11:18:26.243543][lite-client.cpp:1150][!testnode] sending query from file mywallet-query.boc [ 3][t 1][2022-03-28 11:18:26.261124][lite-client.cpp:1160][!testnode] external message status is 1
-
Ready
mywallet.pk
The primary secret stored on the offline computer is the private key file. If you only have a 24 word mnemonic (BIP39), open
ton-mnemonic-pk.html
using a web browser (offline), type the mnemonic into the page and use it to generatemywallet.pk
and save it. Never give any unauthorized party access tomywallet.pk
as access to this file gives full access to all your funds. Rename this file for convenience to identify your wallet with a meaningful name (mywallet
will be used as the name throughout this tutorial). -
Ready
mywallet.addr
This file was generated in step 2 when the wallet contract deployment was created. You should have stored this file for future use. This file is not secret, so it does not need heavy protection. If you lost this file, repeat step 2 to create it again (just make sure to use the same arguments you used on the original execution, specifically the wallet ID and the workchain ID).
-
Sign deployment
Command line:
fift -s wallet-v3.fif <wallet-filename-without-extension> <destination-address> <wallet-id> <seq-no> <ton-coin-amount> <boc-output-file> --timeout 86400
wallet-v3.fif
- the template for the wallet smart contract downloaded earlierwallet-filename-without-extension
- path to the private key file without the.pk
extension and the address file without the.addr
extension (mywallet.pk
andmywallet.addr
will be justmywallet
)destination-address
- the public wallet address you want to send TON coins towallet-id
- the wallet ID used when the wallet was deployed, the value698983191
is used by standard wallets as the primary IDseq-no
- the number of external transactions sent to the wallet, can be seen on a block explorer or checked via lite client (in an online computer) by runninglite-client -C global.config.json -c 'runmethod kQBpfCmpfvybimCKMqYOUvLmuoY11VryXhdmjsP8MRvAO6SJ seqno'
using the wallet public addresston-coin-amount
- the decimal amount on TON coins to send, meaning0.1
to send 0.1 TONboc-output-file
- the name of the output BOC file that will be created in the current directorytimeout
- timeout in seconds for sending the BOC to mainnet (default is 60 seconds which is too low)
Example:
fift -s wallet-v3.fif mywallet EQDrjaLahLkMB-hMCmkzOyBuHJ139ZUYmPHu6RRBKnbdLIYI 698983191 17 0.03 tx17 --timeout 86400
Example output:
Source wallet address = 0:697c29a97efc9b8a608a32a60e52f2e6ba8635d55af25e17668ec3fc311bc03b kQBpfCmpfvybimCKMqYOUvLmuoY11VryXhdmjsP8MRvAO6SJ Loading private key from file mywallet.pk Transferring GR$0.03 to account kQDrjaLahLkMB-hMCmkzOyBuHJ139ZUYmPHu6RRBKnbdLD2C = 0:eb8da2da84b90c07e84c0a69333b206e1c9d77f5951898f1eee91441 ... Query expires in 86400 seconds (Saved to file tx17.boc)
-
See output BOC
The above command will generate a BOC file which contains the signed transaction for transmission to TON mainnet. The BOC file will be created in the current directory with the name
tx17.boc
(or what name you chose forboc-output-file
above).
-
Move BOC
The output BOC should be moved to a regular (online) computer that is connected to the Internet. It is your responsibility to move it securely using any method like a USB-Key or QR code reader and make sure that no other important files (like
mywallet.pk
) get compromised in the process. -
Prepare
lite-client
See explanation under step 3.
-
Send BOC to mainnet
Command line:
lite-client -C global.config.json -c 'sendfile <boc-file>'
global.config.json
- TON mainnet configuration file downloaded earlierboc-file
- path to the BOC file to send
Example:
lite-client -C global.config.json -c 'sendfile tx17.boc'
Example output:
using liteserver 6 with addr [51.195.176.148:4194] [ 1][t 1][2022-03-28 11:18:26.184795][lite-client.h:362][!testnode] conn ready [ 2][t 1][2022-03-28 11:18:26.203706][lite-client.cpp:363][!testnode] server version is 1.1, capabilities 7 [ 3][t 1][2022-03-28 11:18:26.203748][lite-client.cpp:372][!testnode] server time is 1648466306 (delta 0) ... [ 1][t 1][2022-03-28 11:18:26.243543][lite-client.cpp:1150][!testnode] sending query from file tx17.boc [ 3][t 1][2022-03-28 11:18:26.261124][lite-client.cpp:1160][!testnode] external message status is 1