Skip to main content

TON Blockchain SDK

Project description

pytoniq

Pytoniq is a Python SDK for the TON Blockchain. Currently, it has native ADNL over TCP connection to Liteservers, boc types implementation, wrappers for almost all TLB schemes from block.tlb, automaic TL schemes serialization/deserialization, some popular contracts wrappers.

  • Work in progress

Documentation

GitBook

Installation

pip install pytoniq 

Examples

You can find them in the examples folder.

Blockstore

The library can prove all data it receives from a Liteserver (Learn about trust levels here). If you want to use LiteClient with the zero trust level, at the first time run library will prove block link from the init_block to the last masterchain block. Last proved blocks will be stored in the .blockstore folder. The file data contains ttl and gen_utime of the last synced key block, its data serialized according to the BlockIdExt TL scheme (but in big–endian), last synced masterchain block data. Filename is first 88 bytes of data described above with init block hash.

General usage examples

Transactions parsing

import asyncio

from pytoniq import LiteClient, MessageAny


async def main():
    client = LiteClient.from_mainnet_config(ls_i=0, trust_level=2)

    await client.connect()

    trs = await client.get_transactions(address='EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG', count=3)
    print(trs)  # [{'account_addr': '6f5bc67986e06430961d9df00433926a4cd92e597ddd8aa6043645ac20bd1782', 'lt': 39515024000004, 'prev_trans_hash': b'\xe93\xfaM"\xc6Cz\x1a\x8a\xfad\x8fe:\xf9sP!\xa4\x8bG\x02KJm^)w\x02Vq', 'prev_trans_lt': 39515024000003, 'now': 1690098531, 'outmsg_cnt': 0, 'orig_status': {'type_': 'active'}, 'end_status': {'type_': 'active'}, 'in_msg': {'info': {'ihr_disabled': True, 'bounce': True, 'bounced': False, 'src': Address<EQAPYSNXK9Ha7o8Z2cnROAYC22-IMzczCNIX7LsU39YZH8bP>, 'dest': Address<EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG>, 'value': {'grams': 1000, 'other': None}, 'value_coins': 1000, 'ihr_fee': 0, 'fwd_fee': 733339, 'created_lt': 39515024000003, 'created_at': 1690098531}, 'init': None, 'body': <Cell 0[] -> 0 refs>}, 'out_msgs': None, 'total_fees': {'grams': 0, 'other': None}, 'state_update': {'old_hash': b'\xd6U\xcc\x0bD\xf2\xaeh\xcf\xe8\xb7I\xa8v\x1a9\xee\x87\x12\xa0\xdb#\xe4\xc3\xa5\xf3\xf5\xae&\x01\xc7\xa7', 'new_hash': b"\x05\xa9\x7fx\xac\r'\xe2\x0e\xddX\xd2M\xe7\xd4\x19ZG\x08J\xe0\r\xeaW\xdd\xf5\xbdX\x86\x82\xf6*"}, 'description': {'type_': 'ordinary', 'credit_first': False, 'storage_ph': {'storage_fees_collected': 0, 'storage_fees_due': None, 'status_change': {'type_': 'unchanged'}}, 'credit_ph': {'due_fees_collected': None, 'credit': {'grams': 1000, 'other': None}}, 'compute_ph': {'type_': 'skipped', 'reason': {'type_': 'no_gas'}}, 'action': None, 'aborted': True, 'bounce': {'type_': 'nofunds', 'msg_size': {'cells': None, 'bits': None}, 'req_fwd_fees': 1000000}, 'destroyed': False}}, {'account_addr': '6f5bc67986e06430961d9df00433926a4cd92e597ddd8aa6043645ac20bd1782', 'lt': 39515024000003, 'prev_trans_hash': b'>y\xa3L\xd9\x15\x92\xc0P\x93\x8a\x86D`H\xa0\x87Z}S\xb7\xc1h\x97\x1cL\xe3\xf7\xb1\x1f\xa4\x8e', 'prev_trans_lt': 39514911000001, 'now': 1690098531, 'outmsg_cnt': 0, 'orig_status': {'type_': 'active'}, 'end_status': {'type_': 'active'}, 'in_msg': {'info': {'ihr_disabled': True, 'bounce': True, 'bounced': False, 'src': Address<EQAPYSNXK9Ha7o8Z2cnROAYC22-IMzczCNIX7LsU39YZH8bP>, 'dest': Address<EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG>, 'value': {'grams': 1000, 'other': None}, 'value_coins': 1000, 'ihr_fee': 0, 'fwd_fee': 733339, 'created_lt': 39515024000002, 'created_at': 1690098531}, 'init': None, 'body': <Cell 0[] -> 0 refs>}, 'out_msgs': None, 'total_fees': {'grams': 91, 'other': None}, 'state_update': {'old_hash': b'\x03}\xbb\x93v\x00\xa7\xc7w\x96\x07\x14\x9a\xafo\xb0\xc3\x16n)\xc4\x02i\x99s\xef\x1f\xf0\xb2\xb6\xd77', 'new_hash': b'\xd6U\xcc\x0bD\xf2\xaeh\xcf\xe8\xb7I\xa8v\x1a9\xee\x87\x12\xa0\xdb#\xe4\xc3\xa5\xf3\xf5\xae&\x01\xc7\xa7'}, 'description': {'type_': 'ordinary', 'credit_first': False, 'storage_ph': {'storage_fees_collected': 91, 'storage_fees_due': None, 'status_change': {'type_': 'unchanged'}}, 'credit_ph': {'due_fees_collected': None, 'credit': {'grams': 1000, 'other': None}}, 'compute_ph': {'type_': 'skipped', 'reason': {'type_': 'no_gas'}}, 'action': None, 'aborted': True, 'bounce': {'type_': 'nofunds', 'msg_size': {'cells': None, 'bits': None}, 'req_fwd_fees': 1000000}, 'destroyed': False}}, {'account_addr': '6f5bc67986e06430961d9df00433926a4cd92e597ddd8aa6043645ac20bd1782', 'lt': 39514911000001, 'prev_trans_hash': b'\xdc#q\x05\x98\x7f\x90\xa8\xde\x85\xf5\xab\x0bqB\xb9\xae\xb1\xe9:\x8b;t\xf4\\\xa1\xda\xc1V\xa1B\xa7', 'prev_trans_lt': 39496961000001, 'now': 1690098174, 'outmsg_cnt': 1, 'orig_status': {'type_': 'active'}, 'end_status': {'type_': 'active'}, 'in_msg': {'info': {'src': None, 'dest': Address<EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG>, 'import_fee': 0}, 'init': None, 'body': <Cell 648[0317AED6DDEFC03BD811F8EAD1DB34F4FA74E5187B864CADF0C5849E36352CDF995D732967AD0EB474DB41166E1E51FB6D337BA6A0F9C261B4498FA1E37CAE0E29A9A31764BCDA33000000F10000000003] -> 1 refs>}, 'out_msgs': [{'info': {'ihr_disabled': True, 'bounce': False, 'bounced': False, 'src': Address<EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG>, 'dest': Address<EQAPYSNXK9Ha7o8Z2cnROAYC22-IMzczCNIX7LsU39YZH8bP>, 'value': {'grams': 45840000, 'other': None}, 'value_coins': 45840000, 'ihr_fee': 0, 'fwd_fee': 2773355, 'created_lt': 39514911000002, 'created_at': 1690098174}, 'init': {'split_depth': None, 'special': None, 'code': <Cell 80[FF00F4A413F4BCF2C80B] -> 1 refs>, 'data': <Cell 353[29A9A31700000000000000005E014E37FFE03A0AB54E904F3C2F87001114C084B0D0F3E3BEC934BDDEB655D400] -> 0 refs>, 'library': None}, 'body': <Cell 0[] -> 0 refs>}], 'total_fees': {'grams': 10134337, 'other': None}, 'state_update': {'old_hash': b'\xfe\xb4\x8a\x18!\xb4\x82\x8cg\x8aXfkI|\xcb\xa9i\xcaEh\x9c%q\x14M\xd3\xe5\xbf\xb2\xe0E', 'new_hash': b'\x03}\xbb\x93v\x00\xa7\xc7w\x96\x07\x14\x9a\xafo\xb0\xc3\x16n)\xc4\x02i\x99s\xef\x1f\xf0\xb2\xb6\xd77'}, 'description': {'type_': 'ordinary', 'credit_first': True, 'storage_ph': {'storage_fees_collected': 14692, 'storage_fees_due': None, 'status_change': {'type_': 'unchanged'}}, 'credit_ph': None, 'compute_ph': {'type_': 'vm', 'success': True, 'msg_state_used': False, 'account_activated': False, 'gas_fees': 3308000, 'gas_used': 3308, 'gas_limit': None, 'gas_credit': 10000, 'mode': 0, 'exit_code': 0, 'exit_arg': None, 'vm_steps': 68, 'vm_init_state_hash': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'vm_final_state_hash': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'}, 'action': {'success': True, 'valid': True, 'no_funds': False, 'status_change': {'type_': 'unchanged'}, 'total_fwd_fees': 4160000, 'total_action_fees': 1386645, 'result_code': 0, 'result_arg': None, 'tot_actions': 1, 'spec_actions': 0, 'skipped_actions': 0, 'msgs_created': 1, 'action_list_hash': b'd\xeb\xc4\x9ax*\xe5\x8ds\x03\xd6p\xd1\xb5Z\xd6s{\x8da\x81\x8e\x9b$\x91\x96[yLg\xe6&', 'tot_msg_size': {'cells': 13, 'bits': 2666}}, 'aborted': False, 'bounce': None, 'destroyed': False}}]

    transaction = trs[2]
    print(transaction.in_msg.info)  # {'ihr_disabled': True, 'bounce': True, 'bounced': False, 'src': Address<EQAPYSNXK9Ha7o8Z2cnROAYC22-IMzczCNIX7LsU39YZH8bP>, 'dest': Address<EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG>, 'value': {'grams': 1000, 'other': None}, 'value_coins': 1000, 'ihr_fee': 0, 'fwd_fee': 733339, 'created_lt': 39515024000003, 'created_at': 1690098531}
    body = transaction.in_msg.body
    print([body.begin_parse()])  # [<Slice 648[0317AED6DDEFC03BD811F8EAD1DB34F4FA74E5187B864CADF0C5849E36352CDF995D732967AD0EB474DB41166E1E51FB6D337BA6A0F9C261B4498FA1E37CAE0E29A9A31764BCDA33000000F10000000003] -> 1 refs>]

    await client.close()


if __name__ == '__main__':
    asyncio.run(main())

Blocks parsing

import asyncio

from pytoniq.liteclient import LiteClient
from pytoniq.tlb import Block, ValueFlow, ShardAccounts
from pytoniq.tl import BlockIdExt


async def parse_block(client: LiteClient, block: BlockIdExt):
    full_block = await client.raw_get_block(block)
    value_flow: ValueFlow = full_block.value_flow
    print(value_flow.fees_collected.grams)  # 1007000010
    accounts: ShardAccounts = full_block.state_update.old.shard_state_unsplit.accounts
    print(accounts)  # ({40756874397635192262439020188088563828720515972064165042579090230945048213995: {'account': {'addr': Address<EQBaG5LL_CsF2hOq0D-nk71YcihyR71_1o33FnlG5cS56590>, 'storage_stat': {'used': {'cells': 22, 'bits': 5697, 'public_cells': None}, 'last_paid': 1690187357, 'due_payment': None}, 'storage': {'last_trans_lt': 39542571000003, 'balance': {'grams': 62352028502, 'other': None}, 'state': {'type_': 'account_active', 'state_init': {'split_depth': None, 'special': None, 'code': <Cell 288[0101FEB5FF6820E2FF0D9483E7E0D62C817D846789FB4AE580C878866D959DABD5C00007] -> 0 refs>, 'data': <Cell 321[000023E429A9A317B28A8042597CD3F1591A8B3A0EE7DAEF53E8FA7D5378A618AA80BE1EB48FC8E700] -> 0 refs>, 'library': None}}}}, 'last_trans_hash': b'\xfe}o\x83\xaf\x7f\xcf\x9e .\xc6\x0b\x96\x9el\xae8\xa6\xa9N[O\x89\xb8\xd3\xbaf\x89\xdf.\xdb\xd4', 'last_trans_lt': 39542571000001, 'cell': <Cell 320[FE7D6F83AF7FCF9E202EC60B969E6CAE38A6A94E5B4F89B8D3BA6689DF2EDBD4000023F6B8E5E0C1] -> 1 refs>}}, [{'split_depth': 0, 'balance': {'grams': 5553445990447918, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 5553446978130918, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 5553447242093167, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 5553449597627584, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 5553449680120571, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 5553502425603666, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 5553551498198270, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 5554171371732038, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 5554810996626740, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 5556695368115041, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 5570820341996106, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 5582868370124598, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 5668324449113770, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 5983054304100620, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 6643915352221766, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 99915737789528586, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 198985701626791490, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 379795173339356597, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 62352028502, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 62353858158, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 62451366404, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 64501434435, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 115078782628, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 132264475468, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 413217320912, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 431027638506, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 465652010665, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 855472014247, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 12697170876788, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 23277573167204, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 65993263389943, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 1628994778449415, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 2334912485572297, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 4383884219022332, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 5493159230272353, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 31059031289819148, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 126234268026871666, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 506029441366228263, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 719987176953810690, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 1802443900690706273, 'other': None}}, {'split_depth': 0, 'balance': {'grams': 2725693542936016491, 'other': None}}])


async def main():
    client = LiteClient.from_mainnet_config(ls_i=0, trust_level=2)

    await client.connect()

    old_blk = client.last_shard_blocks[0]  # last basechain block
    await parse_block(client, old_blk)
    while True:
        while client.last_shard_blocks[0] == old_blk:
            await asyncio.sleep(0)
            continue
        old_blk = client.last_shard_blocks[0]
        await parse_block(client, old_blk)


if __name__ == '__main__':
    asyncio.run(main())

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytoniq-0.0.6.tar.gz (102.8 kB view details)

Uploaded Source

Built Distribution

pytoniq-0.0.6-py3-none-any.whl (112.8 kB view details)

Uploaded Python 3

File details

Details for the file pytoniq-0.0.6.tar.gz.

File metadata

  • Download URL: pytoniq-0.0.6.tar.gz
  • Upload date:
  • Size: 102.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.8.5

File hashes

Hashes for pytoniq-0.0.6.tar.gz
Algorithm Hash digest
SHA256 859e56c6202e7eb6332fef765254c69befc2a552e5ba7637473dc1ae9bf75073
MD5 c04f1973cf9eda9020d8bc91782c28fc
BLAKE2b-256 8b984c59b0cbb41b99cda9d0b88433df9453df912c02fa5966c8934b866fc7f6

See more details on using hashes here.

File details

Details for the file pytoniq-0.0.6-py3-none-any.whl.

File metadata

  • Download URL: pytoniq-0.0.6-py3-none-any.whl
  • Upload date:
  • Size: 112.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.8.5

File hashes

Hashes for pytoniq-0.0.6-py3-none-any.whl
Algorithm Hash digest
SHA256 6e963c2652203d08e88e7fca65ebdcb7a32509827692ab9a9ab1ad05965eb77f
MD5 7dab718efa8ddaa8b813b30c59668652
BLAKE2b-256 c9771ce75d26112a9b42f82d0dfdec34ee9cc26242ef2ae36b29e606a2345f5e

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page