Skip to content

Commit 6557927

Browse files
Merge branch 'main' into feat/OPDATA-2382-ondo
2 parents 8815eaf + ac63074 commit 6557927

File tree

21 files changed

+600
-0
lines changed

21 files changed

+600
-0
lines changed

.changeset/proud-masks-film.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@chainlink/gmci-adapter': major
3+
---
4+
5+
Version 1.0.0 of GMCI EA

.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/gmci/CHANGELOG.md

Whitespace-only changes.

packages/sources/gmci/README.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# GMCI
2+
3+
![0.0.0](https://img.shields.io/github/package-json/v/smartcontractkit/external-adapters-js?filename=packages/sources/gmci/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+
|| API_KEY | An API key for Data Provider | string | | |
12+
| | WS_API_ENDPOINT | WS endpoint for GMCI Data Provider | 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 | [price](#price-endpoint) | `price` |
27+
28+
## Price Endpoint
29+
30+
`price` is the only supported name for this endpoint.
31+
32+
### Input Params
33+
34+
| Required? | Name | Aliases | Description | Type | Options | Default | Depends On | Not Valid With |
35+
| :-------: | :----: | :-----: | :---------: | :----: | :-----: | :-----: | :--------: | :------------: |
36+
|| symbol | | Index name | string | | | | |
37+
38+
### Example
39+
40+
Request:
41+
42+
```json
43+
{
44+
"data": {
45+
"endpoint": "price",
46+
"symbol": "GMCI30"
47+
}
48+
}
49+
```
50+
51+
---
52+
53+
MIT License

packages/sources/gmci/package.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"name": "@chainlink/gmci-adapter",
3+
"version": "0.0.0",
4+
"description": "Chainlink gmci adapter.",
5+
"keywords": [
6+
"Chainlink",
7+
"LINK",
8+
"blockchain",
9+
"oracle",
10+
"gmci"
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": "29.5.14",
33+
"@types/node": "22.14.1",
34+
"@types/sinonjs__fake-timers": "8.1.5",
35+
"nock": "13.5.6",
36+
"typescript": "5.8.3"
37+
},
38+
"dependencies": {
39+
"@chainlink/external-adapter-framework": "2.6.0",
40+
"tslib": "2.4.1"
41+
}
42+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { AdapterConfig } from '@chainlink/external-adapter-framework/config'
2+
3+
export const config = new AdapterConfig({
4+
API_KEY: {
5+
description: 'An API key for Data Provider',
6+
type: 'string',
7+
required: true,
8+
sensitive: true,
9+
},
10+
WS_API_ENDPOINT: {
11+
description: 'WS endpoint for GMCI Data Provider',
12+
type: 'string',
13+
required: true,
14+
},
15+
})
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: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { AdapterEndpoint } from '@chainlink/external-adapter-framework/adapter'
2+
import { InputParameters } from '@chainlink/external-adapter-framework/validation'
3+
import { config } from '../config'
4+
import { transport } from '../transport/price'
5+
6+
export const inputParameters = new InputParameters(
7+
{
8+
symbol: {
9+
required: true,
10+
type: 'string',
11+
description: 'Index name',
12+
},
13+
},
14+
[
15+
{
16+
symbol: 'GMCI30',
17+
},
18+
],
19+
)
20+
21+
export type GMCIResultResponse = {
22+
Result: number
23+
Data: {
24+
symbol: string
25+
result: number
26+
}
27+
}
28+
29+
export type BaseEndpointTypes = {
30+
Parameters: typeof inputParameters.definition
31+
Response: GMCIResultResponse
32+
Settings: typeof config.settings
33+
}
34+
35+
export const endpoint = new AdapterEndpoint({
36+
name: 'price',
37+
aliases: [],
38+
transport: transport,
39+
inputParameters,
40+
})

packages/sources/gmci/src/index.ts

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: 'GMCI',
9+
config,
10+
endpoints: [price],
11+
})
12+
13+
export const server = (): Promise<ServerInstance | undefined> => expose(adapter)
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import { EndpointContext } from '@chainlink/external-adapter-framework/adapter'
2+
import {
3+
WebSocketTransport,
4+
WebSocketTransportConfig,
5+
} from '@chainlink/external-adapter-framework/transports'
6+
import { makeLogger } from '@chainlink/external-adapter-framework/util'
7+
import { BaseEndpointTypes } from '../endpoint/price'
8+
import { convertTimetoUnixMs } from './util'
9+
10+
export interface PriceMessage {
11+
last_updated: string
12+
price: number
13+
symbol: string
14+
}
15+
16+
export interface RebalanceMessage {
17+
end_time: string
18+
start_time: string
19+
status: string
20+
symbol: string
21+
}
22+
23+
interface WsPriceResponse {
24+
success: boolean
25+
data: Array<PriceMessage>
26+
topic: 'price'
27+
}
28+
29+
interface WsRebalanceResponse {
30+
success: boolean
31+
data: Array<RebalanceMessage>
32+
topic: 'rebalance_status'
33+
}
34+
35+
export type WsResponse = WsPriceResponse | WsRebalanceResponse
36+
37+
export type WsTransportTypes = BaseEndpointTypes & {
38+
Provider: {
39+
WsMessage: WsResponse
40+
}
41+
}
42+
43+
const logger = makeLogger('GmciTransport')
44+
45+
export const options: WebSocketTransportConfig<WsTransportTypes> = {
46+
url: (context: EndpointContext<WsTransportTypes>) => context.adapterSettings.WS_API_ENDPOINT,
47+
options: async (context: EndpointContext<WsTransportTypes>) => ({
48+
headers: {
49+
'X-GMCI-API-KEY': context.adapterSettings.API_KEY,
50+
},
51+
}),
52+
53+
handlers: {
54+
message(message: WsResponse) {
55+
if (message.success === false) {
56+
logger.info(message)
57+
return
58+
}
59+
60+
const results = []
61+
62+
if (message.topic === 'price') {
63+
for (const item of message.data) {
64+
results.push({
65+
params: { symbol: item.symbol },
66+
response: {
67+
result: item.price,
68+
data: {
69+
result: item.price,
70+
symbol: item.symbol,
71+
},
72+
timestamps: {
73+
providerIndicatedTimeUnixMs: convertTimetoUnixMs(item.last_updated),
74+
},
75+
},
76+
})
77+
}
78+
}
79+
return results
80+
},
81+
},
82+
83+
builders: {
84+
subscribeMessage: (params) => {
85+
return {
86+
op: 'subscribe',
87+
args: [`price.${params.symbol}`.toLowerCase()],
88+
}
89+
},
90+
91+
unsubscribeMessage: (params) => {
92+
return {
93+
op: 'unsubscribe',
94+
args: [`price.${params.symbol}`.toLowerCase()],
95+
}
96+
},
97+
},
98+
}
99+
100+
export const transport = new WebSocketTransport(options)

0 commit comments

Comments
 (0)