Skip to content

IPC 2.0 RPC gateway

cryptocode edited this page Jan 23, 2020 · 12 revisions

The RPC gateway automatically translates between Flatbuffers- and JSON messages over HTTP. The request and response is standard JSON.

The examples below assumes the node is compiled with TLS support. If not, replace https with http. If using TLS with a self-signed certificate, add --insecure to curl commands.

Making calls without a message envelope

A message envelope is a way to tell the server which message type is sent, as well as other information such as credentials.

For HTTP clients, it's convenient to send messages without an envelope. They do so by appending the message name (using uppercase CamelCase) to the path:

POST to https://www.example.com:7076/api/v2/AccountWeight

{
    "account": "nano_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3"
}

The RPC 1.0 "action" field is thus not necessary.

The response message is always wrapped in an envelope. JSON clients use the "message" property to access the message:

{
    "time": 1579736914615,
    "message_type": "AccountWeightResponse",
    "message": {
        "voting_weight": "668657804547735335568510480612620716"
    }
}

The message_type is always Error if a call fails:

{
    "time": 1579737134595,
    "message_type": "Error",
    "message": {
        "code": 3,
        "message": "Access denied"
    }
}

The "time" property is milliseconds since unix epoch when the message was produced on the server.

Relation to the WebSocket response structure

The "message" and "time" properties of the response envelope is exactly the same as in WebSockets (https://docs.nano.org/integration-guides/advanced/#websocket-support) Instead of "message_type", WebSockets use "topic". This structure should help simplify clients using both HTTP and WebSockets.

Headers

When calling without an envelope, credentials and a correlation id can still be set using an HTTP header:

curl --header "Nano-Api-Key:mywalletuser" ...

The correlation header is Nano-Correlation-Id, which can be an arbitrary string. This is usually not useful for request/response JSON clients, but may be valuable if responses from RPCs and WebSocket subscriptions are dealt with in a common message handler on the client.

Making calls with message envelopes

If the message name is missing from the path, an envelope will be expected which tells the node about the message type.

POST to https://www.example.com:7076/api/v2

{ 
    "message_type" : "AccountWeight", 
    "message": {
        "account": "nano_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3"
    }
}

The above is similar to using the "action" property in RPC 1.0. The main difference is that the message itself is always placed in a "message" property.

The envelope allows additional information to be sent, such as credentials:

POST to https://www.example.com:7076/api/v2

{ 
    "credentials": "mywalletuser",  
    "message_type" : "AccountWeight", 
    "message": {
        "account": "nano_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3"
    }
}

Large requests

While somewhat less convenient, the envelope approach is desirable for very large requests, because the node doesn't need to copy the message into an envelope.

Flatbuffers mapping

Here's the corresponding message definitions for the AccountWeight request and response types:

/** Returns the voting weight for the given account */
table AccountWeight {
    /** A nano_ address */
    account: string (required);
}

/** Response to AccountWeight */
table AccountWeightResponse {
    /** Voting weight as a decimal number*/
    voting_weight: string (required);
}

Parsing errors

Any problems with the JSON request will be reported with error details:

{
    "message_type": "Error",
    "message": {
        "code": 1,
        "message": "Invalid message format: 3: 2: error: required field is missing: account in AccountWeight"
    }
}