3.2. Websocket Calls & Notifications¶
Table of Contents
3.2.1. Prerequisites¶
This page assumes that you have a full node running and listening to port
8090, locally.
Примечание
If you also want to run a wallet, please pick reasonable different ports and make sure you do not try to call methods at the wallet that are only available to the blockchain API.
3.2.2. Call Format¶
In Graphene, Websocket calls are stateful and accessible via regular JSON formated websocket connection. The correct structure of the JSON call is
{
"id":1,
"method":"call",
"params":[
0,
"get_accounts",
[["1.2.0"]]
]
}
The parameters params have the following structure:
[API-identifier, Method-to-Call, Call-Parameters]
In the example above, we query the database API which carries the identifier 0 in our example (see more details below).
- Example Call with `wscat`
- The following will show the usage of websocket connections. We make use of the
wscat application available via npm:
npm install -g wscat
A non-restricted call against a full-node would take the form:
wscat -c ws://127.0.0.1:8090
> {"id":1, "method":"call", "params":[0,"get_accounts",[["1.2.0"]]]}
- Successful Calls
- The API will return a properly JSON formated response carrying the same
idas the request to distinguish subsequent calls.
{
"id":1,
"result": ..data..
}
- Errors
- In case of an error, the resulting answer will carry an
errorattribute and a detailed description:
{
"id": 0
"error": {
"data": {
"code": error-code,
"name": " .. name of exception .."
"message": " .. message of exception ..",
"stack": [ .. stack trace .. ],
},
"code": 1,
},
}
3.2.3. Requesting API access¶
The Graphene full node offers a wide range of APIs that can be accessed via websockets. The procedure works as follows:
- Login to the Full Node
- Request access to an API
- Obtain the API identifier
- Call methods of a specific API by providing the identifier
Find more available APIs: Blockchain API(s)
- Login
The first thing we need to do is to login:
> {"id":2,"method":"call","params":[1,"login",["",""]]} < {"id":2,"result":true}If you have restricted access then you may be required to put your
usernameandpaswordinto the quotes, accordingly. Furthermore, you should verify, that theresultgive positive confirmation about your login.
- Requesting Access to an API
Most data can be queried from the database-API to which we register with the following call:
> {"id":2,"method":"call","params":[1,"database",[]]}
- Obtain the API identifier
After requesting access, the full node will either deny access or return an identifier to be used in future calls:
< {"id":2,"result":2}The
resultwill be our identifier for the database API, in the following calledDATABASE_API_ID!
- Call methods of a specific API by providing the identifier
Now we can call any methods available to the
databaseAPI via:> {"id":1, "method":"call", "params":[DATABASE_API_ID,"get_accounts",[["1.2.0"]]]}
3.2.3.1. Database Notifications¶
In Graphene, the websocket connection is used for notifications when objects in the database change or a particular event (such as filled orders) occur.
We have the following subscriptions available:
set_subscribe_callback( int identifier, bool clear_filter ):- To simplify development a global subscription callback can be registered.
Every notification initiated by the full node will carry a particular
idas defined by the user with theidentifierparameter.
set_pending_transaction_callback(int identifier):- Notifications for incoming unconfirmed transactions.
set_block_applied_callback(blockid):- Gives a notification whenever the block
blockidis applied to the blockchain.
subscribe_to_market(int identifier, asset_id a, asset_id b)):- Subscribes to market changes in market
a:band sends notifications with ididentifier.
get_full_accounts(array account_ids, bool subscribe):- Returns the full account object for the accounts in array
account_idsand subscribes to changed to that account ifsubscribeis set toTrue.
Let’s first get a global scubscription callback to disctinguish our notifications from regular RPC calls:
> {"id":4,"method":"call","params":[DATABASE_API_ID,"set_subscribe_callback",[SUBSCRIPTION_ID, true]]}
This call above will register SUBSCRIPTION_ID as id for notifications.
Now, whenever you get an object from the witness (e.g. via get_objects) you will automatically subscribe to any future changes of that object.
After calling set_subscribe_callback the witness will start to send notices every time the object changes:
< {
"method": "notice"
"params": [
SUBSCRIPTION_ID,
[[
{ "id": "2.1.0", ... },
{ "id": ... },
{ "id": ... },
{ "id": ... }
]]
],
}
Example Session
Here is an example of a full session::
> {"method": "call", "params": [1, "login", ["", ""]], "id": 2}
< {"id":2,"result":true}
> {"method": "call", "params": [1, "database", []], "id": 3}
< {"id":3,"result":2}
> {"method": "call", "params": [1, "history", []], "id": 4}
< {"id":4,"result":3}
> {"method": "call", "params": [2, "set_subscribe_callback", [5, false]], "id": 6}
< {"id":6,"result":null}
> {"method": "call", "params": [2, "get_objects", [["2.1.0"]]], "id": 7}
(plenty of data coming in from this point on)