Service API documentation - SkycoinProject/skywire GitHub Wiki

API documentation

Below, there is documentation for the API structure and enpoints for the Skywire services as well as the Skywire node. There is a separate documentation specifically for the Application API on the node.

Messaging Discovery

Endpoints

Only 3 endpoints need to be defined; Get Entry, Post Entry, and Get Available Servers.

GET Entry

Obtains a messaging node's entry.

GET {domain}/discovery/entries/{public_key}

REQUEST

Header:

Accept: application/json

RESPONSE

Possible Status Codes:

  • Success (200) - Successfully updated record.
    • Header:
      Content-Type: application/json
      
    • Body:

      JSON-encoded entry.

  • Not Found (404) - Entry of public key is not found.
  • Unauthorized (401) - invalid signature.
  • Internal Server Error (500) - something unexpected happened.
POST Entry

Posts an entry and replaces the current entry if valid.

POST {domain}/discovery/entries

REQUEST

Header:

Content-Type: application/json

Body:

JSON-encoded, signed Entry.

RESPONSE

Possible Response Codes:

  • Success (200) - Successfully registered record.
  • Unauthorized (401) - invalid signature.
  • Internal Server Error (500) - something unexpected happened.
GET Available Servers

Obtains a subset of available server entries.

GET {domain}/discovery/available_servers

REQUEST

Header:

Accept: application/json

RESPONSE

Possible Status Codes:

  • Success (200) - Got results.
    • Header:
      Content-Type: application/json
      
    • Body:

      JSON-encoded []Entry.

  • Not Found (404) - No results.
  • Forbidden (403) - When access is forbidden.
  • Internal Server Error (500) - Something unexpected happened.

Transport Discovery

There is further documentation available on the Transport Discovery

Security Procedures

Incrementing Security Nonce:

An Incrementing Security Nonce is represented by a uint64 value.

To avoid replay attacks and unauthorized access, each public key of a Skywire Node is assigned an Incrementing Security Nonce, and is expected to sign it with the rest of the body, and include the signature result in the http header. The Incrementing Security Nonce should increment every time an" endpoint is called (except for the endpoint that obtains the next expected incrementing security nonce). An Incrementing Security Nonce is not operation-specific, and increments every time any endpoint is called by the given Skywire Node.

The Transport Discovery should store a table of expected next Incrementing Security Nonce for each public key of a Skywire Node. There is an endpoint GET /security/nonces/{public-key} that provides the next expected Incrementing Security Nonce for a given Node public key. This endpoint should be publicly accessible, but nevertheless, the Skywire Nodes themselves should keep a copy of their next expected Incrementing Security Nonce.

The only times an Incrementing Security Nonce should not increment is when:

  • An invalid request is submitted (missing/extra fields, invalid signature).
  • An internal server error occurs.

Initially, the expected Incrementing Security Nonce should be 0. When it is this value, the Transport Discovery should not have an entry for it.

Each operation should contain the following extra header entries:

  • SW-Public - Specifies the public key of the Skywire Node performing this operation.
  • SW-Nonce - Specifies the incrementing nonce provided by this operation.
  • SW-Sig - Specifies the hex-representation of the signature of the hash result of the concatenation of the Incrementing Security Nonce + Body of the request.

If these values are not valid, the Transport Discovery rejects the request.

Endpoint Definitions

The following is a summary of all the Transport Discovery endpoints.

  • GET /security/nonces/edge:<public-key>
  • GET /transports/id:<transport-id>
  • GET /transports/edge:<public-key>
  • POST /transports
  • POST /statuses

All endpoints should include an Accept: application/json field and the response header should include an Content-Type: application/json field.

All requests (except for obtaining the next expected incrementing nonce) should include the following fields.

Accept: application/json
Content-Type: application/json
SW-Public: <public-key>
SW-Nonce: <nonce>
SW-Sig: <signature>
GET Incrementing Security Nonce

Obtains the next expected incrementing nonce for a given edge's public key.

Request:

GET /security/nonces/<public-key>

Responses:

  • 200 OK (Success).
    {
        "edge": "<public-key>",
        "next_nonce": 0
    }
  • 400 Bad Request (Malformed request).
  • 500 Internal Server Error (Server error).
GET Transport Entry via Transport ID

Obtains a Transport via a given Transport ID.

Should only return a single "transport" result.

Request:

GET /transports/id:<transport-id>

Responses:

  • 200 OK (Success).
    {
        "entry": {
            "id": "<transport-id>",
            "edges": [
                "<public-key-1>",
                "<public-key-2>"
            ],
            "type": "<transport-type>"
        },
        "is_up": true,
        "registered": 0
    }
  • 400 Bad Request (Malformed request).
  • 500 Internal Server Error (Server error).
GET Transport(s) via Edge Public Key

Obtains Transport(s) via a given Transport Edge public key.

Request:

GET /transports/edge:<public-key>

Responses:

  • 200 OK (Success).
    [
        {
            "entry": {
                "t_id": "<transport-id-1>",
                "edges": [
                    "<public-key-1>",
                    "<public-key-2>"
                ],
                "type": "<transport-type>",
                "public": true
            },
            "is_up": true,
            "registered": 0
        },
        {
            "entry": {
                "t_id": "<transport-id-2>",
                "edges": [
                    "<public-key-1>",
                    "<public-key-2>"
                ],
                "type": "<transport-type>",
                "public": true
            },
            "is_up": false,
            "registered": 0
        }
    ]
  • 400 Bad Request (Malformed request).
  • 500 Internal Server Error (Server error).
POST Register Transport(s)

Registers one or multiple Transports.

Request:

POST /transports
[
    {
        "entry": {
            "id": "<transport-id-1>",
            "edges": [
                "<public-key-1>",
                "<public-key-2>"
            ],
            "type": "<transport-type-1>",
            "public": true
        },
        "signatures": [
            "<signature-1>",
            "<signature-2>"
        ]
    },
    {
        "entry": {
            "id": "<transport-id-2>",
            "edges": [
                "<public-key-1>",
                "<public-key-3>"
            ],
            "type": "<transport-type-2>",
            "public": true
        },
        "signatures": [
            "<signature-1>",
            "<signature-3>"
        ]
    }
]    

Responses:

  • 200 OK (Success).
    [
        {
            "entry": {
                "id": "<transport-id-1>",
                "edges": [
                    "<public-key-1>",
                    "<public-key-2>"
                ],
                "type": "<transport-type-1>",
                "public": true
            },
            "signatures": [
                "<signature-1>",
                "<signature-2>"
            ],
            "registered": 0
        },
        {
            "entry": {
                "id": "<transport-id-2>",
                "edges": [
                    "<public-key-1>",
                    "<public-key-3>"
                ],
                "type": "<transport-type-2>",
                "public": true
            },
            "signatures": [
                "<signature-1>",
                "<signature-3>"
            ],
            "registered": 0
        }
    ]
  • 400 Bad Request (Malformed request).
  • 401 Unauthorized (Invalid signature/nonce).
  • 408 Request Timeout (Timed out).
  • 500 Internal Server Error (Server error).
POST Status(es)

Submits one or multiple Transport Status(es) from the perspective of the submitting node. The returned result is the final Transport Status(es) determined by the Transport Discovery that is generated using the submitted Transport Status(es) of the two edges.

When a Transport is registered, it is considered to be up. Then after, every time a node's Status is submitted, the Transport Discovery alters the final state Status with the following rules:

  • If there is only one edge's Status submitted, the final status is of that of the submitted Status.
  • If there are two Statuses submitted and they both agree, final Status will also be the same.
  • If the two submitted Statuses disagree, then the final Status is always Down.

Request:

POST /statuses
[
    {
        "id": "<transport-id-1>",
        "is_up": true
    },
    {
        "id": "<transport-id-2>",
        "is_up": true
    }
]

Responses:

  • 200 OK (Success).
    [
        {
            "id": "<transport-id-1>",
            "is_up": true,
            "updated": 0
        },
        {
            "id": "<transport-id-2>",
            "is_up": false,
            "updated": 0
        }
    ]
  • 400 Bad Request (Malformed request).
  • 401 Unauthorized (Invalid signature/nonce).
  • 408 Request Timeout (Timed out).
  • 500 Internal Server Error (Server error).

Route Finder

There is further documentation available on the Route Finder

The Route Finder only accesses the Transport database already defined in the Transport Discovery specification.

Endpoint Definitions

All endpoint calls should include an Accept: application/json field in the request header, and the response header should include an Content-Type: application/json field.

GET Routes available for the defined start and end key

Obtains the routes available for a specific start and end public key. Optionally with custom min and max hop parameters.

Note that each transport is to be represented by the transport.Entry structure.

Request:

GET /routes
{
    "src_pk": "<src-pk>",
    "dst_pk": "<dst-pk>",
    "min_hops": 0,
    "max_hops": 0,
}

Responses:

  • 200 OK (Success).
    {
        "routes": [
            {
                "transports": [
                    {
                        "tid": "<tid>",
                        "edges": ["<initiator-pk>", "<responder-pk>"],
                        "type": "<type>",
                        "public": true,
                    }
                ]
            }
        ]
    }
  • 400 Bad Request (Malformed request).
  • 500 Internal Server Error (Server error).
⚠️ **GitHub.com Fallback** ⚠️