Skip to content

serge-medvedev/tonos-client-lua

Repository files navigation

LuaRocks Testing

Lua bindings to EVER SDK's Core Client Library

Why Lua?

  • Nginx and Apache HTTP Server can use Lua for configuration
  • HAProxy can be extended using Lua
  • Redis uses Lua for its "stored procedures"
  • In science, Foldit uses Lua for user scripts
  • In game development, Lua is the most popular scripting language...
  • ... and more

These are opportunities for a great many possible use cases.

Usage

Prerequisites

  • lua 5.1
  • luarocks 3
  • libton_client.so and tonclient.h are accessible somewhere at well-known locations
    $ wget https://raw.githubusercontent.com/tonlabs/EVER-SDK/1.45.0/ton_client/client/tonclient.h -O /usr/include/tonclient.h \
      && wget http://sdkbinaries-ws.tonlabs.io/tonclient_1_45_0_linux.gz -O /usr/lib/libton_client.so.gz \
      && gunzip /usr/lib/libton_client.so.gz

Example

$ luarocks install tonos-client
local lib = require("tonos.client")
local context, client = lib.context, lib.client
local ctx = context.create('{"network":{"endpoints":["eri01.net.everos.dev"]}}')
local result = client.version(ctx).await()

print(result.version)

Refer to examples directory for more code snippets and demos.

Features

The bindings code itself is auto-generated, so the main focus is made on uniformity and consistency of user experience. To avoid callback hell, the implementation abstracts away asynchronous machinery by utilizing a few low-level tricks behind generator-like constructs and Lua's generic for loop.

For example, when we need to monitor all the events initiated by processing.process_message, we write the following code:

for request_id, params_json, response_type, finished
    in processing.process_message(context, params) do

    local response = json.decode(params_json)

    -- work with decoded response

    if response_type == 1 then
        -- handle error if any
    end

    if finished then
        -- do something special at the end of a stream
    end
end

If we're not interested in events generated by the request and just want it to do the job, we might do this:

processing.process_message(context, params).await()

A call like that will block until request is finished.

NOTE: there's a negative test for crypto.factorize which provides an example of dealing with error objects

Under the hood there are coroutines, being initiated and resumed on the Lua-side and yielding on the C-side when new data, received via callback function, appears in the queue. When all the events are fetched on the Lua-side, request-related resources are automatically and safely freed on the C-side.

Such design allows interesting co-operative multitasking approaches to be utilized (see debot tests for example).

Building

The simplest way to build the library and run the tests is by having Docker installed.

When ready, build the image:

$ docker build -t tonos-client-lua .

Testing

The library has over 60 tests.

There are four categories of them:

  • fast & slow
  • free & paid

And it's also good to know that:

  • all fast tests are free and all paid tests are slow
  • all free tests are being run automatically as a Docker image build step
  • some tests depend on either DevNet or MainNet accessibility

The paid tests are those which require account funding, e.g. for successful contract deployment. To run them, you need to:

When ready, do the following:

$ docker run --rm tonos-client-lua busted --run=paid

NOTE: replace "paid" with another name to run specific category of tests. Get rid of "--run" argument to run the whole test suite.