A Node.js
API to support communication to the Substrate-based dscp-node
(via polkadot-js/api
) and an IPFS
node.
First, ensure you're running the correct version of npm
, then install dependencies using:
npm install
The API requires instances of dscp-node
and IPFS
.
To bring them up locally:
Clone dscp-node and follow the README to setup and build a local node. Then run the following in its root directory:
./target/release/dscp-node --dev
To install and run IPFS
on macOS
brew install ipfs
ipfs daemon
Return to the root directory of this repository. Run the application in development mode:
npm run dev
Run tests:
npm run test:integration
dscp-api
uses an Auth0 Machine to Machine API to issue a JSON Web Token for authentication on its endpoints. You will need to create your own Auth0 API, which can be done for free, and set the appropriate environment variables (those prefixed with AUTH
). Follow the start of this tutorial to create an API. Go here and here to see where the environment variables are used.
The following environment variables are used by dcsp-api
and can be configured. Entries marked as required
are needed when running dscp-api
in production mode.
variable | required | default | description |
---|---|---|---|
PORT | N | 3001 |
The port for the API to listen on |
API_HOST | Y | - | The hostname of the dscp-node the API should connect to |
API_PORT | N | 9944 |
The port of the dscp-node the API should connect to |
LOG_LEVEL | N | info |
Logging level. Valid values are [trace , debug , info , warn , error , fatal ] |
USER_URI | Y | - | The Substrate URI representing the private key to use when making dscp-node transactions |
IPFS_HOST | Y | - | Hostname of the IPFS node to use for metadata storage |
IPFS_PORT | N | 15001 |
Port of the IPFS node to use for metadata storage |
METADATA_KEY_LENGTH | N | 32 |
Fixed length of metadata keys |
METADATA_VALUE_LITERAL_LENGTH | N | 32 |
Fixed length of metadata LITERAL values |
API_VERSION | N | package.json version |
API version |
API_MAJOR_VERSION | N | v3 |
API major version |
FILE_UPLOAD_MAX_SIZE | N | 200 * 1024 * 1024 |
The Maximum file upload size (bytes) |
SUBSTRATE_STATUS_POLL_PERIOD_MS | N | 10 * 1000 |
Number of ms between calls to check dscp-node status |
SUBSTRATE_STATUS_TIMEOUT_MS | N | 2 * 1000 |
Number of ms to wait for response to dscp-node health requests |
IPFS_STATUS_POLL_PERIOD_MS | N | 10 * 1000 |
Number of ms between calls to check ipfs status |
IPFS_STATUS_TIMEOUT_MS | N | 2 * 1000 |
Number of ms to wait for response to ipfs health requests |
AUTH_TYPE | N | NONE |
Authentication type for routes on the service. Valid values: [NONE , JWT , EXTERNAL ] |
The following environment variables are additionally used when AUTH_TYPE : 'JWT'
variable | required | default | description |
---|---|---|---|
AUTH_JWKS_URI | N | https://inteli.eu.auth0.com/.well-known/jwks.json |
JSON Web Key Set containing public keys used by the Auth0 API |
AUTH_AUDIENCE | N | inteli-dev |
Identifier of the Auth0 API |
AUTH_ISSUER | N | https://inteli.eu.auth0.com/ |
Domain of the Auth0 API ` |
Having ensured dependencies are installed and running + the relevant environment variables are set, the API can be started in production mode with:
npm start
If AUTH_TYPE
env is set to JWT
, the rest of the endpoints in dscp-api
require authentication in the form of a header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
:
Gets the item identified by id
. Item id
s are returned by POST /run-process. This will return a JSON response (Content-Type
application/json
) of the form:
{
"id": 42, // Number
"original_id": 20, // Number
"roles": {"Owner": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"}, // Object
"creator": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", // String
"created_at": 4321, // Number
"destroyed_at": 4999, || null, // Nullable<Number>
"parents": [40, 41], // Array<Number>
"children": [43, 44] || null // Nullable<Array<Number>>
"timestamp": "2022-02-09T10:30:12.003Z" // Date (ISO)
"metadata_keys": ["metadataKey1", ..."metadataKeyN"] // Array<String>
}
Gets the metadata value matching the metadataKey
for the item identified by id
. Item id
s are returned by POST /run-process. If the value is a string, it will be returned with a Content-Type
of text/plain
. If the value is a file, it will be returned with a Content-Type
of application/octet-stream
. The original filename
is returned in the Content-Disposition
header.
This endpoint governs the creation and destruction of all tokens in the system. The endpoint takes a body
of a multi-part form constructed with a request
field. The request
field should be a JSON object with the following format:
{
"inputs": [40, 41] // Array<Number>,
"outputs": [{ // Array<Output>
"roles": {
"Owner": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
..."some_other_role_key": "some_account_id"
},
"metadata": {
"some_file": { "type": "FILE", "value": "some_file.txt"},
"some_literal": {"type": "LITERAL", "value": "some_value"},
"some_token_id": {"type": "TOKEN_ID", "value": "42"},
..."metadataKeyN": {"type": "LITERAL", "value", "some_other_value"}
},
}]
}
The inputs
field is an array of token id
s that identifies the tokens to be consumed by running this process. To create tokens without destroying any inputs simply pass an empty array. To destroy a token, the AccountId
from the USER_URI
of the sender must match the AccountId
associated with the default (Owner
) role for that token.
The outputs
field is an array of objects that describe tokens to be created by running this process. To destroy tokens without creating any new ones simply pass an empty array. Each output must reference a roles
object containing a (key, value) pair for each role associated with the new token. The value is the AccountId
for the role. At minimum, a token requires the default Owner
role to be set. The following role keys are accepted:
[
"Owner",
"Customer",
"AdditiveManufacturer",
"Laboratory",
"Buyer",
"Supplier",
"Reviewer",
"Optimiser",
"MemberA",
"MemberB"
]
Each output must also reference a metadata
object containing a (key, value) pair for each metadata item associated with the new token. The following metadata value types are accepted:
["FILE", "LITERAL", "TOKEN_ID", "NONE"]
The key identifies the metadata item, and the value is either a string value, or for files, a file path. Each file path must match a corresponding file attached to the request.
The response of this API will be JSON (Content-Type
application/json
) of the following form
[42, 43]
Each element of the array contains the id
of the output
that was described in the corresponding index of the outputs
array.
Gets the id
of the last item created by POST /run-process. This will return a JSON response (Content-Type
application/json
) of the form:
{
"id": 5, // Number
}
Each element returned represents a member and their corresponding address in the following format:
[
{
"address": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"
}
]