DEV Community

Stepan Bukhlou
Stepan Bukhlou

Posted on

Transferring TONCOIN on the TON (Telegram Open Network) Network Using Python

The TON network is relatively young with limited available documentation and practical guides. Based on this, I decided to contribute by writing this article, where I will show how to transfer TONCOIN tokens on the TON network using Python. I hope this information will be useful to you. Also, please subscribe to our Telegram channel, where you can find free and paid software for working with cryptocurrencies.

Let's get started!

The script uses the asynchronous library aiohttp for sending requests to the API and the asynchronous structure asyncio, which allows handling multiple transactions simultaneously. It also utilizes the TON API and other libraries.

import asyncio
import random
from tonsdk.contract.wallet import Wallets, WalletVersionEnum
from tonsdk.utils import to_nano, bytes_to_b64str
import aiohttp
Enter fullscreen mode Exit fullscreen mode

Specify Immutable Parameters for the Script

Prepare a wallet.txt file in advance, where each address is written on a new line, and fill in the required values in the placeholders.

# Settings
#---------------------------------
SENDER_SEED_PHRASE = ''  # Your mnemonic phrase (only v4r2)
AMOUNT = [0.01, 0.3]      # Range of amount in TON
USE_API_KEY = True       # Whether to use an API key for lower latency
API_KEY = ''             # Your API key from @tonapibot (only mainnet)
SENDER_ADDRESS = ''      # only v4r2
# --------------------------------
Global seqno
Enter fullscreen mode Exit fullscreen mode

Wallet Setup

In the initialization_wallet function, a TON wallet of version v4r2 is created based on the mnemonic phrase. It generates the address and keys used for authorization and sending transactions.

async def initialization_wallet():
    mnemonics = SENDER_SEED_PHRASE.split(' ')
    version = WalletVersionEnum.v4r2

    # Generate keys and create wallet
    mnemonics, pub_k, priv_k, wallet = Wallets.from_mnemonics(mnemonics=mnemonics, version=version, workchain=0)
    return wallet, wallet.address.to_string(True, True, False)
Enter fullscreen mode Exit fullscreen mode

Sending a Transaction

The send function creates a transfer message specifying the recipient's address, the amount, and the sequence number seqno. The data is sent in JSON format via the API, and upon successful execution, a notification about the transfer is displayed.

async def send(session, wallet, recipient_address, seqnoo, post_url):
    # Generate a random amount within the specified range
    amount = round(random.uniform(AMOUNT[0], AMOUNT[1]), 4)

    query = wallet.create_transfer_message(
        to_addr=recipient_address,
        amount=to_nano(float(amount), 'ton'),
        seqno=int(seqnoo)
    )

    # Convert to Base64 format and send the request
    boc = bytes_to_b64str(query["message"].to_boc(False))
    json_data = {"boc": str(boc)}
    async with session.post(post_url, json=json_data) as resp:
        if resp.status == 200:
            print(f'Successfully created transaction. Sending {amount} TON to {recipient_address}...')
            return True, amount
        else:
            return False, None

Enter fullscreen mode Exit fullscreen mode

Waiting for seqno change

Checking seqno helps ensure that the transaction is completed. If seqno changes, the system understands that the previous transaction was successful and can proceed to the next one.

async def wait_for_seqno_change(session, get_url, seqno):
    delay = 0.3 if USE_API_KEY and API_KEY else 2  # Delay depending on the presence of an API key

    while True:
        await asyncio.sleep(delay)
        info = await get_wallet_info(session, get_url)
        if info and info['seqno'] > seqno:
            return True
        await asyncio.sleep(delay)
Enter fullscreen mode Exit fullscreen mode

Getting Wallet Information

To check the wallet's status, including the current seqno, the get_wallet_info function is used. It helps ensure that the system is ready to send the next transaction.

async def get_wallet_info(session, get_url):
    async with session.get(get_url) as response:
        if response.status == 200:
            return await response.json()
        else:
            print(f'Error getting wallet info: {response.status}, {await response.json()}')
        return None
Enter fullscreen mode Exit fullscreen mode

Main Function

In the main function, the wallet is initialized, and recipient addresses are loaded from the file. Then, for each address, tokens are transferred with error handling and seqno updates.

async def main():
    global seqno, SENDER_ADDRESS
    wallet, SENDER_SEED_PHRASE = await initialization_wallet()

    # Form URLs considering the presence of an API key
    get_url = f'https://toncenter.com/api/v3/wallet?address={SENDER_ADDRESS}&api_key={API_KEY}' if API_KEY else \
              f'https://toncenter.com/api/v3/wallet?address={SENDER_ADDRESS}'
    post_url = f'https://toncenter.com/api/v3/message?api_key={API_KEY}' if API_KEY else \
               f'https://toncenter.com/api/v3/message'

    with open('wallet.txt', 'r') as f:
        recipient_addresses = [line.strip() for line in f.readlines()]

    async with aiohttp.ClientSession() as session:
        info = await get_wallet_info(session, get_url)
        seqno = 0 if info['status'] == 'uninit' else info['seqno']

        for recipient_address in recipient_addresses:
            sending, amount = await send(session, wallet, recipient_address, seqno, post_url)
            if sending:
                change = await wait_for_seqno_change(session, get_url, seqno)
                if change:
                    seqno += 1
                    print(f'{amount} TON was sent to {recipient_address}.')
                else:
                    raise Exception(f"Error with {recipient_address}.")
            await asyncio.sleep(0.1 if USE_API_KEY else 1)
Enter fullscreen mode Exit fullscreen mode

Conclusion

That's all you need to transfer TONCOIN tokens to one or multiple addresses. I hope this article was helpful to you, and as a token of appreciation, please subscribe to our Telegram channel - https://t.me/hidden_coding. There you'll find plenty of useful content, especially a lot of free code. We also offer paid software, which you can find in our marketplace — https://t.me/hcmarket_bot?start=referral_361455968.

GitHub: https://github.com/aero25x
Telegram: https://t.me/hidden_coding
Market: https://t.me/hcmarket_bot?start=referral_361455968

Top comments (0)