-
Notifications
You must be signed in to change notification settings - Fork 1.7k
External Adapters
External adapters are how ChainLink allows for easy integration of custom computations and specialized APIs. External adapters are adapters that run as services which the core of the ChainLink node communicates with via a simple API.
External adapters are added to the Chainlink node first by creating a bridge type. Bridges define the task type's name and URL of the external adapter which will run that task type. When a task type is received that is not one of the core adapters, the node will search for a bridge type with that name, creating a bridge to your external adapter. Task type names are case insensitive.
Example JSON for creating a bridge type:
{ "name": "randomNumber", "url": "http://localhost:3000/randomNumber" }
Example JSON for running a bridge type:
{
"initiators": [{"type": "runLog"}],
"tasks": [{"type": "randomNumber"}]
}
The Copy adapter allows for the same functionality of the JSONParse adapter but for getting data from the external adapter's response.
For example, if an adapter returns JSON data like what is below:
{
"firstValue": "SomeValue",
"details": {
"close": "100",
"open": "110",
"current": "111"
},
"other": "GetData"
}
And you wanted the value in the field "open", you could have a spec like the one below, and the value at "open" will be passed on to the next adapter in the task pipeline.
{
"initiators": [
{ "type": "RunLog" }
],
"tasks": [
{ "type": "MyExternalAdapter" },
{ "type": "copy",
"copyPath": ["details", "open"] },
{ "type": "EthInt256" },
{ "type": "EthTx" }
]
}
Run the following command:
chainlink bridge '{"name":"randomNumber","url":"http://localhost:3000/randomNumber"}'
Or POST to /v2/bridge_types
:
curl -u chainlink:twochains -X POST -H 'Content-Type: application/json' -d '{"name":"randomNumber","url":"http://localhost:3000/randomNumber"}' http://localhost:6688/v2/bridge_types
"name"
should be unique to the local node, and "url"
should be the URL of your external adapter, whether local or on a separate machine.
Output should return the JSON given:
{"name":"randomnumber","url":"http://localhost:3000/randomNumber"}
And the node will log the following:
{"level":"info","ts":1518531822.179224,"caller":"web/router.go:50","msg":"Web request","method":"POST","status":200,"path":"/v2/bridge_types","query":"","body":"{\"name\":\"randomNumber\",\"url\":\"http://localhost:3000/randomNumber\"}","clientIP":"127.0.0.1","comment":"","servedAt":"2018/02/13 - 14:23:42","latency":"1.623398ms"}
When an external adapter receives a request from the Chainlink node, the JSON payload will include the JobRunID and a data object.
{"id":"278c97ffadb54a5bbb93cfec5f7b5503","data":{}}
Additional data may be specified in the spec to be utilized by the adapter. This can be useful for requesting data from a REST endpoint where the keys and values can be specified by the requester. For example, if the REST endpoint supports the following:
https://example.com/api/:parent/:child
Then the payload to the external adapter would need:
{"id":"278c97ffadb54a5bbb93cfec5f7b5503","data":{"parent":"myParentValue","child":"myChildValue"}}
The values for :parent
and :child
can be used within the adapter to dynamically build the URL for the request. This same concept can also be applied to URLs with query values. For example:
https://example.com/api/?parent=myParentValue&child=myChildValue
When the external adapter has a response payload, it will need to include it with the given JobRunID back to the node.
An example of the response data can look like:
{
"jobRunID": "278c97ffadb54a5bbb93cfec5f7b5503",
"data": {
"symbol": "ETH-USD",
"last": {
"price": 467.85,
"size": 0.01816561,
"timestamp": 1528926483463
}
},
"status": "completed",
"error": null,
"pending": false
}
You'll also notice some additional fields: status
, error
, and pending
. An external adapter may mark the JobRun as pending if the answer needs to be returned at a specified time, or when a desired result is found. The pending
field should also be set to true
if this is the case. When the external adapter calls back to the node to update the JobRun, this should be done with an HTTP PATCH request, see the REST API documentation page for details.