{"id":27732756,"url":"https://github.com/yungwine/tontools","last_synced_at":"2025-04-28T11:42:24.518Z","repository":{"id":64055387,"uuid":"569718941","full_name":"yungwine/TonTools","owner":"yungwine","description":"High-level OOP Python library to interact with TON Blockchain","archived":false,"fork":false,"pushed_at":"2024-07-24T12:28:18.000Z","size":77,"stargazers_count":97,"open_issues_count":11,"forks_count":21,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-07-31T20:39:57.472Z","etag":null,"topics":["hack-ton-berfest","hacktoberfest"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yungwine.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-23T13:11:50.000Z","updated_at":"2024-07-31T15:35:58.000Z","dependencies_parsed_at":"2023-01-29T03:01:10.130Z","dependency_job_id":"315c011a-9cb7-41ac-9fda-5642159c39a5","html_url":"https://github.com/yungwine/TonTools","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yungwine%2FTonTools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yungwine%2FTonTools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yungwine%2FTonTools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yungwine%2FTonTools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yungwine","download_url":"https://codeload.github.com/yungwine/TonTools/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251307002,"owners_count":21568376,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hack-ton-berfest","hacktoberfest"],"created_at":"2025-04-28T11:42:23.365Z","updated_at":"2025-04-28T11:42:24.501Z","avatar_url":"https://github.com/yungwine.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TonTools\n\n__TonTools__ is a _high-level_ OOP library for Python, which can be used to interact with [TON Blockchain](https://ton.org).\n\nIf you have any questions join Python - TON [developers chat](https://t.me/pythonnton).\n\n[comment]: \u003c\u003e ([![PyPI version]\u0026#40;https://badge.fury.io/py/tontools.svg\u0026#41;]\u0026#40;https://badge.fury.io/py/tontools\u0026#41;)\n\n[![PyPI version](https://badge.fury.io/py/tontools.svg)](https://badge.fury.io/py/tontools) ![](https://pepy.tech/badge/tontools) [![Downloads](https://static.pepy.tech/badge/tontools/month)](https://pepy.tech/project/tontools) [![](https://img.shields.io/badge/%F0%9F%92%8E-TON-grey)](https://ton.org)\n## How to install:\n\n```bash\npip install tontools\n```\n## Possibilities\nWith __TonTools__ you can:\n* Scan custom Contracts and run get methods\n* Create, deploy and scan wallets\n* Scan NFT Collections, Items, Sale contracts\n* Scan Jettons, Jetton Wallets\n* Transfer Tons, Jettons, NFTs\n* Scan Transactions in raw or User-Friendly forms\n* And so much more...\n## Examples\nYou can find them in `examples/` directory.\n\n## Donations\n__TON__ - EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG\n\n## Providers\n\n__TonTools__ gets data from blockchain using Providers: [TonCenterClient](https://toncenter.com/api/v2/), [LsClient](https://ton.org/docs/participate/nodes/node-types),\n[DtonClient](https://docs.dton.io/dton/) and [TonApiClient](https://tonapi.io/swagger-ui) \n\nMost provider methods are the same, but there are some differences.\n\n### TonCenterClient\n\n[TonCenter](https://toncenter.com/api/v2/) is an Api which uses [lite servers](https://ton.org/docs/participate/nodes/node-types)\n\nTo initialize TonCenterClient: \n```python\nclient = TonCenterClient(base_url='http://127.0.0.1:80/')\nor\nclient = TonCenterClient(api_key)\n```\nNotice that TonCenter has Limit 10 RPS with Api Key, so It's highly recommend to use [Local TonCenter](https://github.com/toncenter/ton-http-api) \nand specify your host in `base_url` parameter or use the [Orbs Ton Access](https://www.orbs.com/ton-access/): \n\n```python\nclient = TonCenterClient(orbs_access=True,\n                         testnet=True)\n\ncontract = Contract('EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG', client)\nprint((await contract.get_transactions(limit=10))[-1].out_msgs[0].destination)  # kQCdaMggjCXoW867yRXilPw2bu8Av9dSBlGGCdDPIGNLKM8N\n```\n\n### LsClient\n\n**LsClient** gets data from blockhain using [lite servers](https://ton.org/docs/participate/nodes/node-types) (based on [pytonlib](https://github.com/psylopunk/pytonlib))\n\nTo initialize LsClient: \n```python\nclient = LsClient(ls_index=2, default_timeout=30, addresses_form='user_friendly')\nawait client.init_tonlib()\n```\n*LsClient* is some more advanced, for e.g. you may need to compile binaries to use it.\n\n### DtonClient\n[Dton](https://docs.dton.io/dton) is a high level indexing GraphQL Api. \n\nTo initialize DtonClient:\n```python\nclient = DtonClient(\n    key: str = None,  # dton api key\n    addresses_form='user_friendly',  # addresses_form could be 'raw' or 'user_friendly'\n    testnet=False,  # if testnet, all addresses will be in testnet form and base url will start with https://testnet.dton.io/\n    private_graphql=False  # you can use private_graphql if you have an api key\n)\n```\n**_Note:_** Dton currently doesn't support sending messages to blockchain, so you can't, for example, transfer toncoins using this provider\n\n\n### TonApiClient - currently v1\n\n**_Note:_** in future TonApiClient will be overwritten to use v2 methods\nand current TonApiClient will be renamed into TonApiClientV1, because tonapi v1 endpoints\nsoon will become unsupported\n\n[TonApi](https://tonapi.io/swagger-ui) is a high level indexing Api. \n\nTo initialize TonApiClient: \n```python\nclient = TonApiClient(api_key, addresses_form)\n```\n`TonApiClient` hasn't `run_get_method` method, but it fast (cause of indexator), so \nyou should use it if you want to scan a lot of _transactions_ and _contracts_  \n\n\n\n\n\n## Contracts\nAll _Contracts_ are inherited from the base class **Contract**, which has \n`.get_transactions(), .run_get_method(), .get_balance(), .get_state()` methods.\nSo you can use them with any type of **Contract**:\n```python\nclient = TonCenterClient(base_url='http://127.0.0.1:80/')\n\nitem = NftItem('EQDzyRLwjasHwP-y5c9rtoVi2iqriu-sbL3080FlCc-XyUG4', provider=client)\nawait item.update()\n\nowner = Wallet(provider=client, address=item.sale.owner)\ntransactions = await owner.get_transactions(limit=2)\n\nprint(transactions[0], transactions[1])\n# Transaction({\"type\": \"out\", \"utime\": 1677531709, \"hash\": \"h+lVX0qK4T76QtRqC0FWWGhLptgPLM4MjSEbgKODcFc=\", \"value\": 2500.0, \"from\": \"EQBZVBXBpirFPOQ5Wmgi5Es2hDCRAfiT3i5JRy_gVsJOlpZv\", \"to\": \"EQBfAN7LfaUYgXZNw5Wc7GBgkEX2yhuJ5ka95J1JJwXXf4a8\", \"comment\": \"6017835\"}) Transaction({\"type\": \"in\", \"utime\": 1677413260, \"hash\": \"erk0nLWW9W3m9boFM+/9v0YSeRz1jJvpyiRQYEgN5AE=\", \"value\": 1e-09, \"from\": \"EQCPGzW1dJURRybL41Q3KYfzX4fZdQUeY8-7-TKyeR7f-7cU\", \"to\": \"EQBZVBXBpirFPOQ5Wmgi5Es2hDCRAfiT3i5JRy_gVsJOlpZv\", \"comment\": \"\"})\n\nprint(await item.sale.get_balance()) # 75730000\n\n```\nYou can init object of some Contract just specifying `address` and `provider`,\nbut to get full data of this object you should call `await object.update()`\n\n### NFT Contracts\n\nThere are `NftItem, NftCollection and NftItemSale` classes.\n```python\nitem = NftItem('EQDzyRLwjasHwP-y5c9rtoVi2iqriu-sbL3080FlCc-XyUG4', provider=client)\nawait item.update()\n\ncollection = item.collection\nawait collection.update()\n\nprint(collection.metadata) #  {\"name\": \"Whales Club\", \"description\": \"Collection limited to 10000 utility-enabled NFTs, where the token is your membership to the Whales Club. Join the club and participate in weekly Ambra token giveaways, have access to the most profitable Ton Whales decentralized staking pools and many other useful club privileges.\", \"external_link\": \"https://tonwhales.com/club\", \"external_url\": \"https://tonwhales.com/club\", \"image\": \"ipfs://QmZc5PwuyVKSV4urDTArqfDbkGVjkKs6q4dBk8kpPt1bqD/logo.gif\", \"social_links\": [\"https://t.me/tonwhalesnft\", \"https://t.me/tonwhalesnften\", \"https://twitter.com/whalescorp\"], \"cover_image\": \"ipfs://QmZc5PwuyVKSV4urDTArqfDbkGVjkKs6q4dBk8kpPt1bqD/cover.gif\"}\nitems = await collection.get_collection_items()\nprint(len(items), items[0])  # 1621 NftItem({\"address\": \"EQD6ufFjSIUJSkbVuV7w00ORT8UvoMLQ9RDZ1lJ8sYh3cOIx\"})\n\nsale = item.sale\nprint(sale.price_value, sale.owner) #  200000000000 EQBZVBXBpirFPOQ5Wmgi5Es2hDCRAfiT3i5JRy_gVsJOlpZv\n```\n\n### Jetton Contracts\nThere are `Jetton and JettonWallet` classes.\n```python\nclient = LsClient(ls_index=2, default_timeout=30)\nawait client.init_tonlib()\n\njetton = Jetton('EQBl3gg6AAdjgjO2ZoNU5Q5EzUIl8XMNZrix8Z5dJmkHUfxI', provider=client)\nprint(jetton)  # Jetton({\"address\": \"EQBl3gg6AAdjgjO2ZoNU5Q5EzUIl8XMNZrix8Z5dJmkHUfxI\"})\n\nawait jetton.update()\nprint(jetton)  # Jetton({\"supply\": 4600000000000000000, \"address\": \"EQBl3gg6AAdjgjO2ZoNU5Q5EzUIl8XMNZrix8Z5dJmkHUfxI\", \"decimals\": 9, \"symbol\": \"LAVE\", \"name\": \"Lavandos\", \"description\": \"This is a universal token for use in all areas of the decentralized Internet in the TON blockchain, web3, Telegram bots, TON sites. Issue of 4.6 billion coins. Telegram channels: Englishversion: @lave_eng \\u0420\\u0443\\u0441\\u0441\\u043a\\u043e\\u044f\\u0437\\u044b\\u0447\\u043d\\u0430\\u044f \\u0432\\u0435\\u0440\\u0441\\u0438\\u044f: @lavet\", \"image\": \"https://i.ibb.co/Bj5KqK4/IMG-20221213-115545-207.png\", \"token_supply\": 4600000000.0})\n\njetton_wallet = await jetton.get_jetton_wallet('EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG')  # for TonCenterClient and LsClient\nprint(jetton_wallet)  # JettonWallet({\"address\": \"EQDgCBnCncRp4jOi3CMeLn-b71gymAX3W28YZT3Dn0a2dKj-\"})\n\nawait jetton_wallet.update()\nprint(jetton_wallet)  # JettonWallet({\"address\": \"EQDgCBnCncRp4jOi3CMeLn-b71gymAX3W28YZT3Dn0a2dKj-\", \"balance\": 10000000000000, \"owner\": \"EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG\", \"jetton_master_address\": \"EQBl3gg6AAdjgjO2ZoNU5Q5EzUIl8XMNZrix8Z5dJmkHUfxI\"})\n\nmy_wallet_mnemonics = []\nmy_wallet = Wallet(provider=client, mnemonics=my_wallet_mnemonics, version='v4r2')\nawait my_wallet.transfer_jetton(destination_address='address', jetton_master_address=jetton.address, jettons_amount=1000, fee=0.15)  # for TonCenterClient and LsClient\nawait my_wallet.transfer_jetton_by_jetton_wallet(destination_address='address', jetton_wallet='your jetton wallet address', jettons_amount=1000, fee=0.1)  # for all clients\n```\n\n\n### Wallet contracts\nCurrently there is only `Wallet` class (will add HighLoadWallet and MultiSigWallet in future versions).\n\nYou can create new wallet just calling `Wallet(provider, wallet_version)`, check existing wallet `Wallet(provider, address)` or enter wallet `Wallet(provider, mnemonics, wallet_version)`\n```python\nclient = LsClient(ls_index=2, default_timeout=20)\nawait client.init_tonlib()\n\nmy_wallet_mnemonics = []\nmy_wallet = Wallet(provider=client, mnemonics=my_wallet_mnemonics, version='v4r2')\nmy_wallet_nano_balance = await my_wallet.get_balance()\n\nnew_wallet = Wallet(provider=client)\nprint(new_wallet.address, new_wallet.mnemonics, my_wallet_nano_balance)  # EQBcMK8CBrZKfSYdvT8FDVo1TxZV_d3Lz-xPyGp8c7mUacko ['federal', 'memory', 'scare', 'exact', 'extend', 'rain', 'private', 'ribbon', 'inspire', 'capital', 'arrow', 'glimpse', 'toy', 'double', 'man', 'speak', 'imitate', 'hint', 'dinner', 'oblige', 'rather', 'answer', 'unfold', 'small'] 496348289\n\nnon_bounceable_new_wallet_address = Address(new_wallet.address).to_string(True, True, False)\nawait my_wallet.transfer_ton(destination_address=non_bounceable_new_wallet_address, amount=0.02, message='just random comment')\nawait new_wallet.deploy()\n\nprint(await new_wallet.get_state())  # active\n```\n\n### Transactions\nClass `Transaction` has `.to_dict()` and `.to_dict_user_friendly()` methods.\nThe first one returns full data of transaction, and the second one only user-friendly data of transaction\n\n*status* - True if computation and action phases have returned zero code.\n```python\nclient = TonApiClient()\nwallet = Wallet(provider=client, address='EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG')\ntrs = await wallet.get_transactions(limit=1) \nprint(trs[0].to_dict())  # {'utime': 1677658702, 'fee': 7384081, 'data': 'a lot of bytes :)', 'hash': 'skqFysIHksJDkH8Sy4UAKmQSuW95WGS6V/XD/QaJCdE=', 'in_msg': {'created_lt': 35690250000001, 'source': '', 'destination': 'EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG', 'value': 0, 'msg_data': 'a lot of bytes :'}, 'out_msgs': [{'created_lt': 35690250000002, 'source': 'EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG', 'destination': 'EQDgCBnCncRp4jOi3CMeLn-b71gymAX3W28YZT3Dn0a2dKj-', 'value': 100000000, 'msg_data': 'te6ccgEBAQEAVwAAqg+KfqUAAAAAAAAAAF6NSlEACADvv6jNfMa6nPxbbgyeiO7riR4Cq0JAynas1pLFqNpq9wAd9/UZr5jXU5+LbcGT0R3dcSPAVWhIGU7VmtJYtRtNXsA='}]}\nprint(trs[0].to_dict_user_friendly())  # {'type': 'out', 'utime': 1677658702, 'status': True, 'hash': 'skqFysIHksJDkH8Sy4UAKmQSuW95WGS6V/XD/QaJCdE=', 'value': 0.1, 'from': 'EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG', 'to': 'EQDgCBnCncRp4jOi3CMeLn-b71gymAX3W28YZT3Dn0a2dKj-', 'comment': ''}\n```\n_Note:_ `.to_dict_user_friendly()` works good with many recipients in one transaction\n#### Messages\nYou can check the type of message using `.try_detect_type()` method.\n```python\nclient = TonCenterClient()\n\ncontract = Contract('EQB5DER03H1uhKGX6BJh_IWa_zV9MzvH2lcy6t30tZ9k4RSL', client)\nprint((await contract.get_transactions())[-1].in_msg.try_detect_type())  # JettonTransferNotificationMessage\n\ncontract = Contract('EQB5QP6tAVlWBXKhMN9TynyusIR8_oTuN10NozaOfpFzAXDj', client)\nprint((await contract.get_transactions())[-1].in_msg.try_detect_type())  # JettonInternalTransferMessage\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyungwine%2Ftontools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyungwine%2Ftontools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyungwine%2Ftontools/lists"}