Skip to content

Commit

Permalink
Mac and windows support (#2)
Browse files Browse the repository at this point in the history
PyTONLib v0.0.4

- Added Intel Macs support
- Added Windows x64 support
- Updated Ubuntu binary
  • Loading branch information
kdimentionaltree authored May 6, 2022
1 parent 0b330b1 commit 32cc4c4
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 28 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -123,5 +123,5 @@ venv.bak/
.idea/
/private
.DS_Store

/RELEASE.md
/sandbox
39 changes: 32 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,20 @@ with the following restrictions:
## Installation

### From PyPi
Currently, the library works with Ubuntu OS. To install package run
```bash
pip install pytonlib
```
Currently, the library works for Windows, Mac and Linux only on Intel CPUs:

* (Windows) Install OpenSSL v1.1.1 for Win64 from [here](https://slproweb.com/products/Win32OpenSSL.html).
* Install Python 3 package: `pip3 install pytonlib`.

### Docker

Also, the library can be installed inside the Docker.
To deploy the example of service with Docker Compose run:
In this repo Compose file is provided to deploy the example of service with *pytonlib*:
```bash
docker-compose -f docker-compose.jupyter.yaml build
docker-compose -f docker-compose.jupyter.yaml up -d
```

This command runs Jupyter Notebook on port 3100 (http://localhost:3100).
Jupyter Notebook will be available on port 3100 (http://localhost:3100).

## Examples

Expand Down Expand Up @@ -64,3 +63,29 @@ shards = await client.get_shards(master_seqno=masterchain_info['last']['seqno'])
masterchain_info = await client.get_masterchain_info()
txs = await client.get_block_transactions(**masterchain_info['last'], count=10)
```

* Running async code from script:
```python
import requests
import asyncio

from pytonlib import TonlibClient


async def main():
loop = asyncio.get_running_loop()
ton_config = requests.get('https://newton-blockchain.github.io/global.config.json').json()

# init TonlibClient
client = TonlibClient(ls_index=0, # choose LiteServer index to connect
config=ton_config,
keystore='/tmp/ton_keystore',
loop=loop)

# init tonlibjson
await client.init(max_restarts=None)


if __name__ == '__main__':
asyncio.run(main())
```
27 changes: 14 additions & 13 deletions pytonlib/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ async def set_verbosity_level(self, level):
}
return await self.tonlib_wrapper.execute(request)

async def raw_get_transactions(self, account_address: str, from_transaction_lt: str, from_transaction_hash: str):
# tonlib methods
async def raw_get_transactions(self, account_address: str, from_transaction_lt: str, from_transaction_hash: str, *args, **kwargs):
"""
TL Spec:
raw.getTransactions account_address:accountAddress from_transaction_id:internal.transactionId = raw.Transactions;
Expand Down Expand Up @@ -158,7 +159,7 @@ async def raw_get_transactions(self, account_address: str, from_transaction_lt:
}
return await self.tonlib_wrapper.execute(request)

async def raw_get_account_state(self, address: str):
async def raw_get_account_state(self, address: str, *args, **kwargs):
"""
TL Spec:
raw.getAccountState account_address:accountAddress = raw.AccountState;
Expand All @@ -185,7 +186,7 @@ async def raw_get_account_state(self, address: str):

return await self.tonlib_wrapper.execute(request)

async def generic_get_account_state(self, address: str):
async def generic_get_account_state(self, address: str, *args, **kwargs):
# TODO: understand why this is not used
account_address = prepare_address(address)
request = {
Expand All @@ -196,7 +197,7 @@ async def generic_get_account_state(self, address: str):
}
return await self.tonlib_wrapper.execute(request)

async def _load_contract(self, address):
async def _load_contract(self, address, *args, **kwargs):
# TODO: understand why this is not used
account_address = prepare_address(address)
request = {
Expand All @@ -211,7 +212,7 @@ async def _load_contract(self, address):
self.loaded_contracts_num += 1
return result["id"]

async def raw_run_method(self, address, method, stack_data, output_layout=None):
async def raw_run_method(self, address, method, stack_data, output_layout=None, *args, **kwargs):
"""
For numeric data only
TL Spec:
Expand Down Expand Up @@ -254,7 +255,7 @@ async def raw_run_method(self, address, method, stack_data, output_layout=None):
r.pop('@type')
return r

async def raw_send_message(self, serialized_boc):
async def raw_send_message(self, serialized_boc, *args, **kwargs):
"""
raw.sendMessage body:bytes = Ok;
Expand All @@ -268,7 +269,7 @@ async def raw_send_message(self, serialized_boc):
}
return await self.tonlib_wrapper.execute(request)

async def _raw_create_query(self, destination, body, init_code=b'', init_data=b''):
async def _raw_create_query(self, destination, body, init_code=b'', init_data=b'', *args, **kwargs):
"""
raw.createQuery destination:accountAddress init_code:bytes init_data:bytes body:bytes = query.Info;
Expand Down Expand Up @@ -296,7 +297,7 @@ async def _raw_create_query(self, destination, body, init_code=b'', init_data=b'
raise TonLibWrongResult("raw.createQuery failed", result)
return result

async def _raw_send_query(self, query_info):
async def _raw_send_query(self, query_info, *args, **kwargs):
"""
query.send id:int53 = Ok;
"""
Expand All @@ -306,11 +307,11 @@ async def _raw_send_query(self, query_info):
}
return await self.tonlib_wrapper.execute(request)

async def raw_create_and_send_query(self, destination, body, init_code=b'', init_data=b''):
async def raw_create_and_send_query(self, destination, body, init_code=b'', init_data=b'', *args, **kwargs):
query_info = await self._raw_create_query(destination, body, init_code, init_data)
return self._raw_send_query(query_info)

async def raw_create_and_send_message(self, destination, body, initial_account_state=b''):
async def raw_create_and_send_message(self, destination, body, initial_account_state=b'', *args, **kwargs):
# Very close to raw_create_and_send_query, but StateInit should be generated outside
"""
raw.createAndSendMessage destination:accountAddress initial_account_state:bytes data:bytes = Ok;
Expand All @@ -331,7 +332,7 @@ async def raw_create_and_send_message(self, destination, body, initial_account_s
}
return await self.tonlib_wrapper.execute(request)

async def raw_estimate_fees(self, destination, body, init_code=b'', init_data=b'', ignore_chksig=True):
async def raw_estimate_fees(self, destination, body, init_code=b'', init_data=b'', ignore_chksig=True, *args, **kwargs):
query_info = await self._raw_create_query(destination, body, init_code, init_data)
request = {
'@type': 'query.estimateFees',
Expand All @@ -340,7 +341,7 @@ async def raw_estimate_fees(self, destination, body, init_code=b'', init_data=b'
}
return await self.tonlib_wrapper.execute(request)

async def raw_get_block_transactions(self, fullblock, count, after_tx):
async def raw_get_block_transactions(self, fullblock, count, after_tx, *args, **kwargs):
request = {
'@type': 'blocks.getTransactions',
'id': fullblock,
Expand All @@ -350,7 +351,7 @@ async def raw_get_block_transactions(self, fullblock, count, after_tx):
}
return await self.tonlib_wrapper.execute(request)

async def raw_get_block_transactions_ext(self, fullblock, count, after_tx):
async def raw_get_block_transactions_ext(self, fullblock, count, after_tx, *args, **kwargs):
request = {
'@type': 'blocks.getTransactionsExt',
'id': fullblock,
Expand Down
Binary file not shown.
File renamed without changes.
Binary file added pytonlib/distlib/windows/tonlibjson.amd64.dll
Binary file not shown.
13 changes: 9 additions & 4 deletions pytonlib/tonlibjson.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,15 @@

def get_tonlib_path():
arch_name = platform.system().lower()
machine = platform.machine().lower()
if arch_name == 'linux':
lib_name = 'libtonlibjson.so'
lib_name = f'libtonlibjson.{machine}.so'
elif arch_name == 'darwin':
lib_name = f'libtonlibjson.{machine}.dylib'
elif arch_name == 'windows':
lib_name = f'tonlibjson.{machine}.dll'
else:
raise RuntimeError('Platform could not be identified')
raise RuntimeError(f"Platform '{arch_name}({machine})' is not compatible yet")
return pkg_resources.resource_filename('pytonlib', f'distlib/{arch_name}/{lib_name}')


Expand Down Expand Up @@ -148,8 +153,8 @@ async def read_results(self):
logger.critical(f"Tonlib #{self.ls_index:03d} Stuck!")
asyncio.ensure_future(self.restart(), loop=self.loop)
await asyncio.sleep(2)
except Exception as e:
logger.critical(f"Tonlib #{self.ls_index:03d} crashed!")
except:
logger.critical(f"Tonlib #{self.ls_index:03d} crashed: {traceback.format_exc()}")
asyncio.ensure_future(self.restart(), loop=self.loop)
await asyncio.sleep(2)

Expand Down
6 changes: 4 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,17 @@
author='K-Dimentional Tree',
author_email='[email protected]',
name='pytonlib',
version='0.0.1',
version='0.0.4',
packages=find_packages('.', exclude=['tests']),
install_requires=[
'crc16==0.1.1',
'tvm_valuetypes==0.0.8',
'requests==2.27.1',
],
package_data={
'pytonlib': ['distlib/linux/*'],
'pytonlib': ['distlib/linux/*',
'distlib/darwin/*',
'distlib/windows/*',],
'pytonlib.utils': []
},
zip_safe=True,
Expand Down
17 changes: 16 additions & 1 deletion tests/pytonlib/test_tonlibclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def ls_index():
async def tonlib_client(tonlib_config, ton_keystore, ls_index):
loop = asyncio.get_running_loop()

client = TonlibClient(ls_index=0,
client = TonlibClient(ls_index=ls_index,
config=tonlib_config,
keystore=ton_keystore,
loop=loop,
Expand Down Expand Up @@ -72,3 +72,18 @@ async def test_get_transactions(tonlib_client: TonlibClient):

tx = await tonlib_client.get_transactions(**txs['transactions'][0], limit=1)
assert tx[0]['@type'] == 'raw.transaction'


def test_sync_code(tonlib_config, ton_keystore, ls_index):
async def main():
loop = asyncio.get_running_loop()

client = TonlibClient(ls_index=ls_index,
config=tonlib_config,
keystore=ton_keystore,
loop=loop,
verbosity_level=0)
await client.init()
return client

asyncio.run(main())

0 comments on commit 32cc4c4

Please sign in to comment.