- Generate a mnemonic; wallet will be still in
nonexiststatus. - Derive the public key and the wallet address out of it.
- Put some funds to the address; wallet account will move to
uninitstatus. - Deploy code of wallet contract to that address; account will move to
activestatus.
Derive wallet address
The following algorithm is used by wallet apps, and has to be replicated if the same wallet address should be generated programmatically. A wallet account’s address is derived fromStateInit that stores in its data field two values:
public_key, dependent on the mnemonic;wallet_id, a special salt-like field, dependent on the wallet contract type and thenetwork_id.
Sometimes
wallet_id is also called subwallet_id in some of the libraries and documentation. They mean the same thing.wallet_id has to be known to compute the address.
Default wallet_id values
For Wallet V4R2
wallet_id is defined as first 4 bytes from TON mainnet blockchain initial state hash. There is no specific logic why this number was chosen, community needed some default value and this one works well enough.
For Wallet V5, wallet_id is different between Mainnet and Testnet for security reasons. There will be different wallet addresses for different networks with the same mnemonic. This prevents replaying transactions from testnet on mainnet, and ensuing loss of funds. The wallet_id value is obtained from
network_id:-239for mainnet,-3for testnet,wallet_version: currently always0,subwallet_number:0by default,workchain:0for basechain
Algorithm here is presented for educational purposes, in most cases there is no need to reimplement it. Use the existing implementation from TON SDKs instead.
Examples
The following examples use wrappers for wallet contracts from the@ton/ton TypeScript SDK.
Wallet V4R2
Wallet V5
Comments
TON wallet apps can attach short human-readable notes — commonly called comments — to outgoing internal messages. On-chain they are just message bodies with a specific layout that ecosystem agreed to interpret as text.Comment format
- The first 32 bits of the incoming message body must be the opcode
0x00000000. This value signals that the rest of the payload should be treated as a comment. - The remaining bytes are UTF-8 encoded text. Wallet apps should tolerate invalid or empty strings — many senders emit messages without a comment or with zero-length payloads.
- When parsing, always inspect the opcode before assuming a text comment. If the opcode differs, fall back to handling other contract-specific payloads.
- native Toncoin transfers between wallets;
- Jetton transfers, where the wallet forwards an internal message to the token wallet along with the comment payload;
- NFT transfers, where the comment travels in the same forwarding message that moves the ownership record.
Attaching a comment when sending
To include a comment in an outgoing transfer, construct an internal message body that starts with0x00000000 and append the UTF-8 bytes of the note YOU want to share. Most wallet libraries expose helpers for this, but the underlying steps are:
- Allocate a cell.
- Store the 32-bit zero opcode.
- Store the text as a byte string (UTF-8 encoded).
- Send the internal message along with the desired Toncoin, Jettons, or NFT payload.