@windingtree/wt-read-api

0.15.0 • Public • Published

JavaScript Style Guide Greenkeeper badge

WT Read API

API written in nodejs to fetch information from the Winding Tree platform. This API supports only the Winding Tree data model.

Requirements

  • Nodejs >=10

Development

In order to install and run tests, we must:

git clone git@github.com:windingtree/wt-read-api.git
cd wt-read-api
nvm install
npm install
npm run resolve-swagger-references
npm test

Running in dev mode

With all the dependencies installed, you can start the dev server. First step is starting Ganache (local Ethereum network node). You can skip this step if you have a different network already running.

npm run dev-net

If you need to interact (for example add some testing hotels) with the running dev-net in any way, you can use the Winding Tree demo wallet protected by password windingtree. It is initialized with enough ether. For sample interaction scripts, check out our Developer guides.

!!!NEVER USE THIS WALLET FOR ANYTHING IN PRODUCTION!!! Anyone has access to it.

{"version":3,"id":"7fe84016-4686-4622-97c9-dc7b47f5f5c6","address":"d037ab9025d43f60a31b32a82e10936f07484246","crypto":{"ciphertext":"ef9dcce915eeb0c4f7aa2bb16b9ae6ce5a4444b4ed8be45d94e6b7fe7f4f9b47","cipherparams":{"iv":"31b12ef1d308ea1edacc4ab00de80d55"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"d06ccd5d9c5d75e1a66a81d2076628f5716a3161ca204d92d04a42c057562541","n":8192,"r":8,"p":1},"mac":"2c30bc373c19c5b41385b85ffde14b9ea9f0f609c7812a10fdcb0a565034d9db"}};

Now we can run our dev server.

npm run dev

When using a dev config, we internally run a script to deploy contracts. It is not immediate, so you might experience some errors in a first few seconds. And that's the reason why it is not used in the same manner in tests.

You can then visit http://localhost:3000/docs/ to interact with the live server. An OAS description is published there.

You can tweak with the configuration in src/config/.

Running this server

Docker

You can run the whole API in a docker container, and you can control which config will be used by passing an appropriate value to WT_CONFIG variable at runtime.

$ docker build -t windingtree/wt-read-api .
$ docker run -p 8080:3000 -e ETH_NETWORK_PROVIDER=address_to_node -e WT_CONFIG=playground windingtree/wt-read-api

After that you can access the wt-read-api on local port 8080. This deployment is using a Ropsten configuration that can be found in src/config/playground.js.

NPM

You can install and run this from NPM as well:

$ npm install -g @windingtree/wt-read-api
$ ETH_NETWORK_PROVIDER=address_to_node WT_CONFIG=playground wt-read-api

Probably the easiest way of getting an Ethereum Node API is to register with Infura.

Running in production

You can customize the behaviour of the instance by many environment variables which get applied if you run the API with WT_CONFIG=envvar. These are:

  • WT_CONFIG - Which config will be used. Defaults to dev.
  • WT_SEGMENTS - Which segments will be enabled. Defaults to hotels,airlines.
  • ADAPTER_IN_MEMORY - Enables in memory off-chain data adapter. Defaults to false.
  • ADAPTER_SWARM - Enables Swarm off-chain data adapter. Defaults to true.
  • ADAPTER_SWARM_GATEWAY - Address of a Swarm HTTP Gateway, for example https://swarm.windingtree.com or https://swarm-gateways.net
  • ADAPTER_SWARM_READ_TIMEOUT - Read timeout in milliseconds for Swarm, defaults to 1000
  • ADAPTER_HTTPS - Enables HTTP off-chain data adapter. Defaults to true.
  • WT_ENTRYPOINT_ADDRESS - On chain address of Entrypoint
  • PORT - HTTP Port where the API will listen, defaults to 3000.
  • BASE_URL - Base URL of this API instance, for example https://playground-api.windingtree.com
  • ETH_NETWORK_NAME - Name of Ethereum network for informational purposes, for example ropsten or mainnet
  • ETH_NETWORK_PROVIDER - Address of Ethereum node, for example https://ropsten.infura.io/v3/my-project-id
  • TRUST_CLUES_CHECK - If trust clues should be evaluated for hotels. This may affect which data will be returned by the API. Defaults to true.
  • TRUST_CLUES_CURATED_LIST_ADDRESS - ETH Address of an instance of Curated List Trust clue if used as a trust clue.
  • TRUST_CLUES_LIF_DEPOSIT_ADDRESS - ETH Address of an instance of Líf Deposit Trust clue if used as a trust clue. A local instance is automatically deployed if a dev config is used.
  • ORG_JSON_HASH_CHECK - If hash of ORG.JSON file should be checked. This confirms the content has not been modified. Defaults to true.

For example the playground configuration can be emulated with the following command (the actual values will differ, check src/config/playground.js for current ones):

docker run -p 8080:3000 \
  -e WT_CONFIG=envvar \
  -e WT_SEGMENTS=hotels,airlines \
  -e WT_ENTRYPOINT_ADDRESS=0xa268937c2573e2AB274BF6d96e88FfE0827F0D4D \
  -e ADAPTER_SWARM_GATEWAY=https://swarm.windingtree.com \
  -e ADAPTER_SWARM=1 \
  -e ADAPTER_HTTPS=1 \
  -e ETH_NETWORK_NAME=ropsten \
  -e ETH_NETWORK_PROVIDER=https://ropsten.infura.io/v3/my-project-id \
  -e TRUST_CLUES_CHECK=0 \
  -e ORG_JSON_HASH_CHECK=0 \
  windingtree/wt-read-api

Trust levels

You can control which hotels are passed from the Directory to your API instance clients by the following:

  • ORG.JSON hash validation - ORG.IDs with invalid orgJsonHash will not pass through the API
  • Trust clues configuration - ORG.IDs without required trust clues will not pass through the API. If trust clues are on, hotel's guarantee is also checked for validity

Examples

See API definition for full details or in a more readable form here.

Hotels

Get list of hotels

Calling GET /hotels will retrieve an array of hotels. By default fields are id, name and location, which means that at least some off-chain stored data is retrieved.

You can use a query attribute fields to specify which fields you want to be included in the response. Hotel ID is included by default in every request. Ex. GET /hotels?fields=name. You can also choose to include only ids (e. g. GET /hotels?fields=id) which will not fetch any off-chain data, so the response will be much faster.

items: [
  ...
  {
    id: '0x585c0771Fe960f99aBdba8dc77e5d31Be2Ada74d',
    name: 'WT Hotel'
  },
  ...
]

If an error is produced for a hotel, the response will look like this

items: [
  {
    id: '0x417C3DDae54aB2f5BCd8d5A1750487a1f765a94a',
    name: 'WT Hotel'
  }
],
warnings: [],
errors: [
  {
    error: 'Unsupported data storage type: ipfs',
    originalError: 'Unsupported data storage type: ipfs',
    data: { id: '0x585c0771Fe960f99aBdba8dc77e5d31Be2Ada74d' }
  }
]

Get a hotel

Request to /hotels/:address can fetch off-chain data in a single request. By default, included fields are id, location, name, description, contacts, address, currency, images, amenities, updatedAt.

id: "0x417C3DDae54aB2f5BCd8d5A1750487a1f765a94a",
location: { "latitude": 35.89421911, "longitude": 139.94637467 },
name: "Winding Tree Hotel",
dataFormatVersion: "0.6.0",
description: "string",
contacts:
 {
  general:
    {
      email: "joseph.urban@example.com",
      phone: 44123456789,
      url: "string",
      ethereum: "string",
      additionalContacts: []
    }
  },
roomTypes: [
  {
    id: "room-type-1111",
    name: "Room with windows",
    description: "some fancy room type description",
    totalQuantity: 0,
    occupancy: {
      min: 1,
      max: 3
    },
    amenities: [
      "tv"
    ],
    images: [
      "https://example.com/room-image.jpg"
    ],
    updatedAt: "2018-06-19T13:19:58.190Z"
  }
],
address:
 {
   road: "string",
   houseNumber: "string",
   postcode: "string",
   city: "string",
   countryCode: "US"
 },
currency: "string",
images: [ "string" ],
amenities: [ "free wi-fi" ],
updatedAt: "2018-06-19T13:19:58.190Z"

Airlines

The airline endpoints work basically the same way as hotels. The default fields for airline list (/airlines) are id, name and code. You can use a query parameter fields to specify fields to be included in the response. See the airline data specification and endpoint specification for full list.

Get a list of airlines

A simple GET /airlines may return:

items: [
  {
    name: 'Mazurka Airlines',
    code: 'MA',
    id: '0xa8c4cbB500da540D9fEd05BE7Bef0f0f5df3e2cc'
  }, {
    name: 'Falco Airlines',
    code: 'FA',
    id: '0x972422ce30AAC491Fa24a5287C40eAf85b0b9dC4'
  },
],
...

Or in case an error occurs while fetching upstream data:

items: [
  {
    name: 'Mazurka Airlines',
    code: 'MA',
    id: '0xa8c4cbB500da540D9fEd05BE7Bef0f0f5df3e2cc'
  }
],
warnings: [],
errors: [
  {
    error: 'Cannot access on-chain data, maybe the deployed smart contract is broken',
    originalError: 'VM Exception while processing transaction: revert',
    data: {
        id: '0x972422ce30AAC491Fa24a5287C40eAf85b0b9dC4'
    }
  }
]

Get an airline

Request to /airlines/:address can fetch off-chain data in a single request. By default, included fields are id, name, description, contacts, currency, updatedAt.

name: 'Mazurka Airlines',
description: 'Small but flexible',
dataFormatVersion: "0.6.0",
contacts: {
  general: {
    email: 'info@airline-mazurka.com',
    phone: '004078965423',
    url: 'https://www.airline-mazurka.com'
  }
},
currency: 'EUR',
updatedAt: '2019-02-01 10:00:00',
id: '0x0f7aDd75c09E2F8F5e4444fcde917267257471bD'

Get a flight

Use GET at /airlines/:address/flights/:id. Use fields query param to get instances data as well.

id: "IeKeix6G",
origin: "PRG",
destination: "LAX",
segments: [
  {
    id: "segment1",
    departureAirport: "PRG",
    arrivalAirport: "CDG"
  },
  {
    id: "segment2",
    departureAirport: "CDG",
    arrivalAirport: "LAX"
  }
]

Get a flight instance

Use GET at /airlines/:address/flights/:flightId/instances/:instanceId.

id: 'IeKeix6G-1',
departureDateTime: '2018-12-10 12:00:00',
bookingClasses: [
  { id: 'economy', availabilityCount: 100 },
  { id: 'business', availabilityCount: 20 }
]
segments: {
  segment1: {
    departureDateTime: "2018-12-10 12:00:00",
    arrivalDateTime: "2018-12-10 15:00:00"
  },
  segment2: {
    departureDateTime: "2018-12-10 20:00:00",
    arrivalDateTime: "2018-12-11 02:00:00"
  }
}

Publicly available instances

For currently available public instances of wt-read-api, please see this page.

Data validation

This API serves upstream data and has no control over the content. To ensure basic semantic compatibility, data is validated against model definition and returned as an error when validation fails. (Detail endpoints will return 422 HTTP code, lists will contain the data in errors array.)

In case the validation succeeds but the declared data format version is different than the version supported by the API, it is returned with a warning. This usually means there was a non-breaking change in the data format but may have consequences in case of a semantic change. (Warnings are returned in x-data-validation-warning header for detail endpoints, warnings array for a list.)

Package Sidebar

Install

npm i @windingtree/wt-read-api

Weekly Downloads

1

Version

0.15.0

License

Apache-2.0

Unpacked Size

270 kB

Total Files

45

Last publish

Collaborators

  • kostysh
  • kvakes
  • tomashq