JSON Interface to TVM Client
JSON Interface to TVM Client
In addition to the native rust interface the core library has an alternative JSON RPC like interface.
The interaction with library is performed using an asynchronous request/response calls.
The library provides the request
function to receive requests. And the application provides response_handler
to receive responses from library related to requests.
This interface is offered for bindings – a small wrapping libraries which purpose is to directly use the tvm client library in languages others than Rust.
Counterparts:
Application – uses native language interface, provided by binding library.
Binding – provides native language interface to TVM client library. Uses JSON Interface to directly call TVM client library.
Library (or Core) – provides JSON Interface to all TVM client functionality.
Strings
Many library functions operates with strings. So there are a responsibility for string ownership and lifetimes.
There are two types related to strings:
tc_string_handle_t
– internal Rust string representation. Application or binding can't use this memory directly. There is thetc_read_string
function for this purpose. Application responsible for the releasing of string withrc_destroy_string
function.tc_string_data_t
– temporarily access string internal data.content
field points to theutf8
encoded content of the string and thelen
field contains the content size in bytes. Note that content IS NOT NULL TERMINATED.
String manipulation functions:
tc_read_string
– read string content provided by thestring
pointer. Returned value is the internal string data. Note that this data will be invalid after the string will be destroyed.tc_destroy_string
– destroys rust string provided bystring
pointer.
Contexts
All library functions requires context – the main library object that encapsulates configuration and state data.
Application can create many contexts and use them all together. For example – creates two contexts that configured to work with different blockchain networks.
Context related functions:
tc_create_context
– create context using providedconfig
with configuration json. Returned string is a JSON with the result or the error. Result is returned in form of{ "result": context }
wherecontext
is a number with context handle. Error is returned in form{ "error": { error fields } }
. Note:tc_create_context
doesn't store pointer passed inconfig
parameter. So it is safe to free this memory after the function returns. Important: application is responsible for freeing of the receiving string. Example:Config contains optional
binding
section with information about binding. It is good practice to provide this information into core library because core library includes this information into logs, errors etc. Providing binding information will help users and binding authors to determine possible error reason. The best way is to merge users config with binding information before callingtc_create_config
. Typical code snippet to merge binding info:tc_destroy_context
– closes and releases all recourses that was allocated and opened by library during serving functions related to provided context.
Request
When application requires to invoke some TVM client function it sends a function request to the library.
Where:
function_name
– function name requested.function_params_json
– function parameters encoded as a JSON string. If a function hasn't parameters then en empty string must be passed.request_id
orrequest_ptr
– application (or binding) defined request identifier or pointer. Usually binding allocates and stores some additional data with every request. This data will help in the future to properly route responses to the application.response_handler
– function that will receive responses related to this request.
This function returns nothing. The function execution result will be sent to the response_handler
.
Note: response_handler
can be called before the function returns.
Note: tc_request
doesn't store pointers passed in function_name
and function_params_json
parameters. So it is safe to free this memory after the function returns.
Request Id versus Request Pointer
TVM Client Library has two version of request context representation:
id
– Each request is identified byu32
integer value defined by application. In this case the application or binding usually uses global hash map to associate additional response dispatch information.pointer
– Each request is identified byvoid*
pointer defined by application. In this case the application or binding uses pointers to native objects with additional response dispatch information. For example a pointer to closure. Note, that library doesn't use this pointer and memory pointed to. It just stores this pointer and provides it back to application when library calls response handler.
Note pointer
supports is UNSTABLE feature yet and can be refined.
Responses
Application (or binding) defines function response_handler
that will receive the request responses.
The response includes the mandatory function result or error and optional additional data responses.
response_handler
– handles responses from the library. Note that an application can receive an unlimited count of responses related to single request. Parameters:
request_id
orrequest_ptr
– the request to which this response is addressed.params_json
– response parameters encoded into JSON string.response_type
– type of this response:RESULT = 0
, function result.ERROR = 1
, function execution error.NOP = 2
, no operation. In combination withfinished = true
signals that the request handling was finished.APP_REQUEST = 3
, request some data from application. See Application objectsAPP_NOTIFY = 4
, notify application with some data. See Application objectsRESERVED = 5..99
– reserved for protocol internal purposes. Application (or binding) must ignore this response. Nevertheless the binding must check thefinished
flag to release data, associated with request.CUSTOM >= 100
- additional function data related to request handling. Depends on the function.
finished
– is a signal to release all additional data associated with the request. It is last response for specified request_id.
Important:
Application MUST NOT store pointers passed in
params_json
and use it afterresponse_handler
has been returned, if an application requires this data after returning then it must creates an own copy.Application MUST NOT free memory of pointers passed in
params_json
.Response handler can be called before the
tc_request
returns. In this case the response handler will be called on the calling thread.Responses can be called on background thread created by library to serve asynchronous tasks. All responses, related to the same request will be called from the same thread in right sequence.
Bindings
Here we are look to the typical binding structure. In this example we will use the Type Script.
Declare high level function wrapper:
Define additional data allocated for each request:
Map library responses to high level handlers:
Map high level call to library request / response chain:
Implement high level function:
Application objects
SDK has some features that require interaction with client applications. Such features are for example, external signing interface - so-called "signing box", and debot. We call them Application objects
. Such an object can be represented as a set of functions which either return execution result (requests) or not (notifications).
Application object is implemented using a callback passed into tc_request
. For such case two response types are used: APP_REQUEST = 3
for requests that require some response from application and APP_NOTIFY = 4
for notifications with no response needed. When response type is 3
, params_json
parameter contains serialized structure ParamsOfAppRequest
Here request_data
is some data describing the request and app_request_id
is ID of the request, which should be used for request result resolving. After the request is processed application should call client.resolve_app_request
function passing app_request_id
used in the request and result of processing.
In case if response type is 4
, params_json
contains serialized notification data without any wrappers. Application processes notification in the way it needs. No response is needed for SDK.
How to work with Application Objects in binding generators
Find out how to work with Application Objects in binding generators in this specification.
Last updated