Skip to content

Commit 1aa2e41

Browse files
DF-21398 OnRe NAV EA (#3911)
* DF-21398 OnRe NAV EA * update test-payload * add rateLimit * yarn lock file * .pnp.cjs file * yarn cache * fixing tests * update package versions * fix dependencies * Changes - Review 1 * fix test * fix date to include UTC time * Modify output; add ripcord * Review 20 June - Part 1 * Update test snapshot * OnRe EA - correct precision * Change Response Type * update snapshot * refactor * Update packages/sources/onre/src/endpoint/nav.ts --------- Co-authored-by: mmcallister-cll <139181225+mmcallister-cll@users.noreply.github.com>
1 parent f0ffa79 commit 1aa2e41

File tree

18 files changed

+483
-0
lines changed

18 files changed

+483
-0
lines changed

.changeset/cool-lamps-admire.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@chainlink/onre-adapter': major
3+
---
4+
5+
OnRe EA

.pnp.cjs

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

packages/sources/onre/CHANGELOG.md

Whitespace-only changes.

packages/sources/onre/README.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# ONRE
2+
3+
![0.0.0](https://img.shields.io/github/package-json/v/smartcontractkit/external-adapters-js?filename=packages/sources/onre/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_ENDPOINT | An API endpoint for OnRe | string | | `https://onre-api-prod.ew.r.appspot.com/nav` |
12+
13+
---
14+
15+
## Data Provider Rate Limits
16+
17+
| Name | Requests/credits per second | Requests/credits per minute | Requests/credits per hour | Note |
18+
| :-----: | :-------------------------: | :-------------------------: | :-----------------------: | :--: |
19+
| default | | 2 | | |
20+
21+
---
22+
23+
## Input Parameters
24+
25+
| Required? | Name | Description | Type | Options | Default |
26+
| :-------: | :------: | :-----------------: | :----: | :----------------------------------------------------------------------------------: | :--------: |
27+
| | endpoint | The endpoint to use | string | [nav](#reserves-endpoint), [por](#reserves-endpoint), [reserves](#reserves-endpoint) | `reserves` |
28+
29+
## Reserves Endpoint
30+
31+
Supported names for this endpoint are: `nav`, `por`, `reserves`.
32+
33+
### Input Params
34+
35+
| Required? | Name | Aliases | Description | Type | Options | Default | Depends On | Not Valid With |
36+
| :-------: | :---------: | :-----: | :----------------------: | :----: | :---------------: | :---------------: | :--------: | :------------: |
37+
|| fundId | | Fund id | number | | | | |
38+
| | reportValue | | Which value to report on | string | `net_asset_value` | `net_asset_value` | | |
39+
40+
### Example
41+
42+
Request:
43+
44+
```json
45+
{
46+
"data": {
47+
"endpoint": "reserves",
48+
"fundId": 1,
49+
"reportValue": "net_asset_value"
50+
}
51+
}
52+
```
53+
54+
---
55+
56+
MIT License

packages/sources/onre/package.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"name": "@chainlink/onre-adapter",
3+
"version": "0.0.0",
4+
"description": "Chainlink onre adapter.",
5+
"keywords": [
6+
"Chainlink",
7+
"LINK",
8+
"blockchain",
9+
"oracle",
10+
"onre"
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+
"@types/jest": "^29.5.14",
32+
"@types/node": "22.14.1",
33+
"nock": "13.5.6",
34+
"typescript": "5.8.3"
35+
},
36+
"dependencies": {
37+
"@chainlink/external-adapter-framework": "2.6.0",
38+
"tslib": "2.4.1"
39+
}
40+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { AdapterConfig } from '@chainlink/external-adapter-framework/config'
2+
3+
export const config = new AdapterConfig({
4+
API_ENDPOINT: {
5+
description: 'An API endpoint for OnRe',
6+
type: 'string',
7+
default: 'https://onre-api-prod.ew.r.appspot.com/nav',
8+
},
9+
})
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { endpoint as nav } from './nav'
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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 { httpTransport } from '../transport/nav'
5+
6+
export const NetAssetValue = 'net_asset_value'
7+
export const AssetsUnderManagement = 'assets_under_management'
8+
9+
export const inputParameters = new InputParameters(
10+
{
11+
fundId: {
12+
description: 'Fund id',
13+
type: 'number',
14+
required: true,
15+
},
16+
reportValue: {
17+
description: 'Which value to report on as top-level result',
18+
type: 'string',
19+
default: NetAssetValue,
20+
options: [NetAssetValue],
21+
},
22+
},
23+
[
24+
{
25+
fundId: 1,
26+
reportValue: NetAssetValue,
27+
},
28+
],
29+
)
30+
31+
export type NavResultResponse = {
32+
Result: number
33+
Data: {
34+
navPerShare: number
35+
navDate: string
36+
currency: string
37+
aum: string
38+
fundId: number
39+
}
40+
}
41+
42+
export type BaseEndpointTypes = {
43+
Parameters: typeof inputParameters.definition
44+
Response: NavResultResponse
45+
Settings: typeof config.settings
46+
}
47+
48+
export const endpoint = new AdapterEndpoint({
49+
name: 'reserves',
50+
aliases: ['nav'],
51+
transport: httpTransport,
52+
inputParameters,
53+
})

packages/sources/onre/src/index.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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 { nav } from './endpoint'
5+
6+
export const adapter = new Adapter({
7+
defaultEndpoint: nav.name,
8+
name: 'ONRE',
9+
config,
10+
endpoints: [nav],
11+
rateLimiting: {
12+
tiers: {
13+
default: {
14+
rateLimit1m: 2,
15+
},
16+
},
17+
},
18+
})
19+
20+
export const server = (): Promise<ServerInstance | undefined> => expose(adapter)
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import { HttpTransport } from '@chainlink/external-adapter-framework/transports'
2+
import { BaseEndpointTypes } from '../endpoint/nav'
3+
import { parseDateToTimestamp, sanityCheckData } from './utils'
4+
5+
interface FundNavData {
6+
net_asset_value_date: string
7+
net_asset_value: string
8+
assets_under_management: string
9+
fund_name: string
10+
fund_id: number
11+
}
12+
13+
type ProviderResponseSchema = FundNavData[]
14+
15+
export type FundNavDataWithTimestamp = Omit<FundNavData, 'net_asset_value_date'> & {
16+
net_asset_value_date: number
17+
}
18+
19+
export type HttpTransportTypes = BaseEndpointTypes & {
20+
Provider: {
21+
RequestBody: never
22+
ResponseBody: ProviderResponseSchema
23+
}
24+
}
25+
26+
export const httpTransport = new HttpTransport<HttpTransportTypes>({
27+
prepareRequests: (params, config) => {
28+
return params.map((param) => {
29+
return {
30+
params: [param],
31+
request: {
32+
baseURL: config.API_ENDPOINT,
33+
},
34+
}
35+
})
36+
},
37+
38+
parseResponse: (params, response) => {
39+
if (!response.data) {
40+
return params.map((param) => {
41+
return {
42+
params: param,
43+
response: {
44+
errorMessage: `The data provider didn't return any value for ${param}`,
45+
statusCode: 502,
46+
},
47+
}
48+
})
49+
}
50+
51+
return params.map((param) => {
52+
const filteredData = response.data.filter((item) => item.fund_id === param.fundId)
53+
if (filteredData.length === 0) {
54+
return {
55+
params: param,
56+
response: {
57+
errorMessage: `The data provider didn't return any value for fundId: ${param.fundId}`,
58+
statusCode: 502,
59+
},
60+
}
61+
}
62+
63+
const dataWithDateMs = filteredData.map((item) => {
64+
return {
65+
...item,
66+
net_asset_value_date: parseDateToTimestamp(item.net_asset_value_date),
67+
}
68+
})
69+
70+
const dataWithDateMsFiltered = dataWithDateMs.filter((item) =>
71+
Number.isFinite(item.net_asset_value_date),
72+
) as FundNavDataWithTimestamp[]
73+
const sortedData = dataWithDateMsFiltered.sort(
74+
(a, b) => b.net_asset_value_date - a.net_asset_value_date,
75+
)
76+
const latestData = sortedData[0]
77+
78+
if (!sanityCheckData(latestData)) {
79+
return {
80+
params: param,
81+
response: {
82+
errorMessage: `The data by data provider for ${param} is null in value`,
83+
statusCode: 502,
84+
},
85+
}
86+
}
87+
88+
const resultData = {
89+
navPerShare: Number(latestData.net_asset_value),
90+
navDate: String(latestData.net_asset_value_date),
91+
currency: 'USD',
92+
aum: latestData.assets_under_management,
93+
fundId: latestData.fund_id,
94+
}
95+
96+
const result = Number(latestData.net_asset_value)
97+
98+
return {
99+
params: param,
100+
response: {
101+
result: result,
102+
data: resultData,
103+
},
104+
}
105+
})
106+
},
107+
})

0 commit comments

Comments
 (0)