Skip to content

Commit 543a1f0

Browse files
authored
Create Tiingo state adapter (#3466)
1 parent 0be944b commit 543a1f0

File tree

19 files changed

+453
-0
lines changed

19 files changed

+453
-0
lines changed

.changeset/slow-cycles-perform.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@chainlink/tiingo-state-adapter': minor
3+
---
4+
5+
Add adapter for Tiingo state.

.pnp.cjs

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/sources/tiingo-state/CHANGELOG.md

Whitespace-only changes.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# TIINGO_STATE
2+
3+
![0.0.1](https://img.shields.io/github/package-json/v/smartcontractkit/external-adapters-js?filename=packages/sources/tiingo-state/package.json) ![v3](https://img.shields.io/badge/framework%20version-v3-blueviolet)
4+
5+
This document was generated automatically. Please see [README Generator](../../scripts#readme-generator) for more info.
6+
7+
## Environment Variables
8+
9+
| Required? | Name | Description | Type | Options | Default |
10+
| :-------: | :-------------: | :---------------------------: | :----: | :-----: | :--------------------: |
11+
| | WS_API_ENDPOINT | websocket endpoint for tiingo | string | | `wss://api.tiingo.com` |
12+
|| API_KEY | API key for tiingo | string | | |
13+
14+
---
15+
16+
## Data Provider Rate Limits
17+
18+
There are no rate limits for this adapter.
19+
20+
---
21+
22+
## Input Parameters
23+
24+
| Required? | Name | Description | Type | Options | Default |
25+
| :-------: | :------: | :-----------------: | :----: | :---------------------------------------------------------------------------: | :-----: |
26+
| | endpoint | The endpoint to use | string | [crypto](#price-endpoint), [price](#price-endpoint), [state](#price-endpoint) | `price` |
27+
28+
## Price Endpoint
29+
30+
Supported names for this endpoint are: `crypto`, `price`, `state`.
31+
32+
### Input Params
33+
34+
| Required? | Name | Aliases | Description | Type | Options | Default | Depends On | Not Valid With |
35+
| :-------: | :---: | :------------: | :--------------------------------------------: | :----: | :-----: | :-----: | :--------: | :------------: |
36+
|| base | `coin`, `from` | The symbol of symbols of the currency to query | string | | | | |
37+
|| quote | `market`, `to` | The symbol of the currency to convert to | string | | | | |
38+
39+
### Example
40+
41+
Request:
42+
43+
```json
44+
{
45+
"data": {
46+
"endpoint": "price",
47+
"base": "wstETH",
48+
"quote": "ETH"
49+
}
50+
}
51+
```
52+
53+
---
54+
55+
MIT License
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"name": "@chainlink/tiingo-state-adapter",
3+
"version": "0.0.1",
4+
"description": "Chainlink tiingo-state adapter.",
5+
"keywords": [
6+
"Chainlink",
7+
"LINK",
8+
"blockchain",
9+
"oracle",
10+
"tiingo-state"
11+
],
12+
"main": "dist/index.js",
13+
"types": "dist/index.d.ts",
14+
"files": [
15+
"dist"
16+
],
17+
"repository": {
18+
"url": "https://github.com/smartcontractkit/external-adapters-js",
19+
"type": "git"
20+
},
21+
"license": "MIT",
22+
"scripts": {
23+
"clean": "rm -rf dist && rm -f tsconfig.tsbuildinfo",
24+
"prepack": "yarn build",
25+
"build": "tsc -b",
26+
"server": "node -e 'require(\"./index.js\").server()'",
27+
"server:dist": "node -e 'require(\"./dist/index.js\").server()'",
28+
"start": "yarn server:dist"
29+
},
30+
"devDependencies": {
31+
"@sinonjs/fake-timers": "9.1.2",
32+
"@types/jest": "27.5.2",
33+
"@types/node": "16.11.68",
34+
"@types/sinonjs__fake-timers": "8.1.5",
35+
"nock": "13.5.4",
36+
"typescript": "5.0.4"
37+
},
38+
"dependencies": {
39+
"@chainlink/external-adapter-framework": "1.4.0",
40+
"tslib": "2.4.1"
41+
}
42+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { AdapterConfig } from '@chainlink/external-adapter-framework/config'
2+
3+
export const config = new AdapterConfig(
4+
{
5+
WS_API_ENDPOINT: {
6+
description: 'websocket endpoint for tiingo',
7+
default: 'wss://api.tiingo.com',
8+
type: 'string',
9+
},
10+
API_KEY: {
11+
description: 'API key for tiingo',
12+
type: 'string',
13+
required: true,
14+
sensitive: true,
15+
},
16+
},
17+
{
18+
envDefaultOverrides: {
19+
CACHE_MAX_AGE: 150_000, // see known issues in readme
20+
WS_SUBSCRIPTION_TTL: 180_000,
21+
},
22+
},
23+
)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { endpoint as price } from './price'
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import {
2+
PriceEndpoint,
3+
priceEndpointInputParametersDefinition,
4+
} from '@chainlink/external-adapter-framework/adapter'
5+
import { InputParameters } from '@chainlink/external-adapter-framework/validation'
6+
import { SingleNumberResultResponse } from '@chainlink/external-adapter-framework/util'
7+
import { TransportRoutes } from '@chainlink/external-adapter-framework/transports'
8+
import { wsTransport } from '../transport/price'
9+
import { config } from '../config'
10+
11+
export const inputParameters = new InputParameters(priceEndpointInputParametersDefinition, [
12+
{
13+
base: 'wstETH',
14+
quote: 'ETH',
15+
},
16+
])
17+
18+
export type BaseCryptoEndpointTypes = {
19+
Parameters: typeof inputParameters.definition
20+
Settings: typeof config.settings
21+
Response: SingleNumberResultResponse
22+
}
23+
24+
export const endpoint = new PriceEndpoint({
25+
name: 'price',
26+
aliases: ['crypto', 'state'],
27+
transportRoutes: new TransportRoutes<BaseCryptoEndpointTypes>().register('ws', wsTransport),
28+
defaultTransport: 'ws',
29+
inputParameters: inputParameters,
30+
})
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { expose, ServerInstance } from '@chainlink/external-adapter-framework'
2+
import { Adapter } from '@chainlink/external-adapter-framework/adapter'
3+
import { config } from './config'
4+
import { price } from './endpoint'
5+
6+
export const adapter = new Adapter({
7+
defaultEndpoint: price.name,
8+
name: 'TIINGO_STATE',
9+
config,
10+
endpoints: [price],
11+
})
12+
13+
export const server = (): Promise<ServerInstance | undefined> => expose(adapter)
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { WebSocketTransport } from '@chainlink/external-adapter-framework/transports'
2+
import { BaseCryptoEndpointTypes } from '../endpoint/price'
3+
4+
interface Message {
5+
service: string
6+
messageType: string
7+
data: [string, string, string, string, number]
8+
}
9+
10+
const tickerIndex = 1
11+
const dateIndex = 2
12+
const priceIndex = 4
13+
14+
type WsTransportTypes = BaseCryptoEndpointTypes & {
15+
Provider: {
16+
WsMessage: Message
17+
}
18+
}
19+
20+
export const wsTransport = new WebSocketTransport<WsTransportTypes>({
21+
url: (context) => {
22+
return `${context.adapterSettings.WS_API_ENDPOINT}/crypto-synth-state`
23+
},
24+
handlers: {
25+
message(message) {
26+
if (!message?.data?.length || message.messageType !== 'A' || !message.data[priceIndex]) {
27+
return []
28+
}
29+
const [base, quote] = message.data[tickerIndex].split('/')
30+
return [
31+
{
32+
params: { base, quote },
33+
response: {
34+
data: {
35+
result: message.data[priceIndex],
36+
},
37+
result: message.data[priceIndex],
38+
timestamps: {
39+
providerIndicatedTimeUnixMs: new Date(message.data[dateIndex]).getTime(),
40+
},
41+
},
42+
},
43+
]
44+
},
45+
},
46+
47+
builders: {
48+
subscribeMessage: (params, context) => {
49+
return {
50+
eventName: 'subscribe',
51+
authorization: context.adapterSettings.API_KEY,
52+
eventData: { thresholdLevel: 8, tickers: [`${params.base}/${params.quote}`] },
53+
}
54+
},
55+
unsubscribeMessage: (params, context) => {
56+
return {
57+
eventName: 'unsubscribe',
58+
authorization: context.adapterSettings.API_KEY,
59+
eventData: { thresholdLevel: 8, tickers: [`${params.base}/${params.quote}`] },
60+
}
61+
},
62+
},
63+
})

0 commit comments

Comments
 (0)