-
Notifications
You must be signed in to change notification settings - Fork 307
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Peregrine Data External Adapter Submission #3590
base: main
Are you sure you want to change the base?
Changes from 9 commits
e28136e
d1b0993
0b7838f
3a60293
199a8a3
82605d8
6898571
3cecc24
5a77e40
53d98b9
c15ec77
63dc9d6
b4fa6e2
909072c
732fd7f
481efb8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@chainlink/peregrine-fund-admin-adapter': patch | ||
--- | ||
|
||
Peregrine Fund Admin Init |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Chainlink External Adapter for peregrine-fund-admin | ||
|
||
This README will be generated automatically when code is merged to `main`. If you would like to generate a preview of the README, please run `yarn generate:readme peregrine-fund-admin`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
{ | ||
"name": "@chainlink/peregrine-fund-admin-adapter", | ||
"version": "0.0.1", | ||
"description": "Chainlink peregrine-fund-admin adapter.", | ||
"keywords": [ | ||
"Chainlink", | ||
"LINK", | ||
"blockchain", | ||
"oracle", | ||
"peregrine-fund-admin" | ||
], | ||
"main": "dist/index.js", | ||
"types": "dist/index.d.ts", | ||
"files": [ | ||
"dist" | ||
], | ||
"repository": { | ||
"url": "https://github.com/smartcontractkit/external-adapters-js", | ||
"type": "git" | ||
}, | ||
"license": "MIT", | ||
"scripts": { | ||
"clean": "rm -rf dist && rm -f tsconfig.tsbuildinfo", | ||
"prepack": "yarn build", | ||
"build": "tsc -b", | ||
"server": "node -e 'require(\"./index.js\").server()'", | ||
"server:dist": "node -e 'require(\"./dist/index.js\").server()'", | ||
"start": "yarn server:dist" | ||
}, | ||
"devDependencies": { | ||
"@types/jest": "27.5.2", | ||
"@types/node": "16.18.115", | ||
"nock": "13.5.4", | ||
"typescript": "5.6.3" | ||
}, | ||
"dependencies": { | ||
"@chainlink/external-adapter-framework": "1.7.1", | ||
droconnel22 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"tslib": "2.4.1" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { AdapterConfig } from '@chainlink/external-adapter-framework/config' | ||
droconnel22 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
export declare const DEFAULT_BASE_URL_VALUE = | ||
'https://fund-admin-data-adapter-v1-960005989691.europe-west2.run.app' | ||
export declare const DEFAULT_NAV_URL_VALUE = '/api/v1/nav/' | ||
export declare const DEFAULT_RESERVE_URL_VALUE = '/api/v1/reserve/' | ||
export declare const config: AdapterConfig<{ | ||
API_KEY: { | ||
description: string | ||
type: 'string' | ||
required: true | ||
sensitive: true | ||
} | ||
API_BASE_URL: { | ||
description: string | ||
type: 'string' | ||
default: string | ||
} | ||
API_NAV_ENDPOINT: { | ||
description: string | ||
type: 'string' | ||
default: string | ||
} | ||
API_RESERVE_ENDPOINT: { | ||
description: string | ||
type: 'string' | ||
default: string | ||
} | ||
}> | ||
//# sourceMappingURL=index.d.ts.map |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { AdapterConfig } from '@chainlink/external-adapter-framework/config' | ||
droconnel22 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
export const DEFAULT_BASE_URL_VALUE = | ||
'https://fund-admin-data-adapter-v1-960005989691.europe-west2.run.app' | ||
export const DEFAULT_NAV_URL_VALUE = '/api/v1/nav/' | ||
export const DEFAULT_RESERVE_URL_VALUE = '/api/v1/reserve/' | ||
droconnel22 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
export const config = new AdapterConfig({ | ||
API_KEY: { | ||
description: 'An API key for Data Provider', | ||
type: 'string', | ||
required: true, | ||
sensitive: true, | ||
}, | ||
API_BASE_URL: { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. might be what @mxiao-cll is mentioning below, but should there be default URLs here as there were in the original commit? |
||
description: 'Base URL to Fund Admin Server Endpoint', | ||
type: 'string', | ||
default: DEFAULT_BASE_URL_VALUE, | ||
}, | ||
API_NAV_ENDPOINT: { | ||
description: | ||
'An API endpoint for the latest Net Asset Value (NAV) calculation for a given asset', | ||
type: 'string', | ||
default: DEFAULT_NAV_URL_VALUE, | ||
}, | ||
API_RESERVE_ENDPOINT: { | ||
description: 'API Endpoint to get the latest Proof of Reserves for a given asset', | ||
type: 'string', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The values seems to be lost? |
||
default: DEFAULT_RESERVE_URL_VALUE, | ||
}, | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { endpoint as nav } from './nav' | ||
export { endpoint as reserve } from './reserve' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { AdapterEndpoint } from '@chainlink/external-adapter-framework/adapter' | ||
import { httpTransport } from '../transport/nav' | ||
import { InputParameters } from '@chainlink/external-adapter-framework/validation' | ||
import { SingleNumberResultResponse } from '@chainlink/external-adapter-framework/util' | ||
import { config } from '../config' | ||
|
||
export const inputParameters = new InputParameters( | ||
{ | ||
assetId: { | ||
required: true, | ||
type: 'string', | ||
description: 'The identifying number for the requested asset', | ||
}, | ||
}, | ||
[ | ||
{ | ||
assetId: '100', | ||
}, | ||
], | ||
) | ||
|
||
export interface ResponseSchema { | ||
droconnel22 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Id: string | null | ||
assetId: string | ||
seniorNAV: number | ||
juniorNav: number | ||
equityNav: number | ||
totalLiability: number | ||
totalAccounts: string | ||
totalCollateral: number | ||
collateral: number[] | ||
accounts: number[] | ||
updateTimestamp: string | ||
id: string | null | ||
} | ||
|
||
// Endpoints contain a type parameter that allows specifying relevant types of an endpoint, for example, request payload type, Adapter response type and Adapter configuration (environment variables) type | ||
export type BaseEndpointTypes = { | ||
Parameters: typeof inputParameters.definition | ||
Response: SingleNumberResultResponse | ||
Settings: typeof config.settings | ||
} | ||
|
||
export const endpoint = new AdapterEndpoint({ | ||
// Endpoint name | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can get rid of the comments in this object |
||
name: 'nav', | ||
// Transport handles incoming requests, data processing and communication for this endpoint | ||
transport: httpTransport, | ||
//input params, | ||
inputParameters, | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { AdapterEndpoint } from '@chainlink/external-adapter-framework/adapter' | ||
import { httpTransport } from '../transport/reserve' | ||
import { InputParameters } from '@chainlink/external-adapter-framework/validation' | ||
import { SingleNumberResultResponse } from '@chainlink/external-adapter-framework/util' | ||
import { config } from '../config' | ||
|
||
export const inputParameters = new InputParameters( | ||
{ | ||
assetId: { | ||
required: true, | ||
type: 'string', | ||
description: 'The identifying number for the requested asset', | ||
}, | ||
}, | ||
[ | ||
{ | ||
assetId: '100', | ||
}, | ||
], | ||
) | ||
|
||
export type BaseEndpointTypes = { | ||
Parameters: typeof inputParameters.definition | ||
Response: SingleNumberResultResponse | ||
Settings: typeof config.settings | ||
} | ||
|
||
export const endpoint = new AdapterEndpoint({ | ||
// Endpoint name | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. here too please |
||
name: 'reserve', | ||
// Supported input parameters for this endpoint | ||
inputParameters, | ||
// Transport handles incoming requests, data processing and communication for this endpoint | ||
transport: httpTransport, | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { expose, ServerInstance } from '@chainlink/external-adapter-framework' | ||
import { Adapter } from '@chainlink/external-adapter-framework/adapter' | ||
import { config } from './config' | ||
import { nav, reserve } from './endpoint' | ||
|
||
export const adapter = new Adapter({ | ||
//Requests will direct to this endpoint if the `endpoint` input parameter is not specified. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and here |
||
defaultEndpoint: nav.name, | ||
// Adapter name | ||
name: 'PEREGRINE_FUND_ADMIN', | ||
// Adapter configuration (environment variables) | ||
config, | ||
// List of supported endpoints | ||
endpoints: [nav, reserve], | ||
droconnel22 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}) | ||
|
||
export const server = (): Promise<ServerInstance | undefined> => expose(adapter) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import { HttpTransport } from '@chainlink/external-adapter-framework/transports' | ||
import { BaseEndpointTypes } from '../endpoint/nav' | ||
|
||
export interface ResponseSchema { | ||
equityNav: number | ||
seniorNAV: number | ||
juniorNav: number | ||
totalCollateral: number | ||
totalAccounts: number | ||
totalLiability: number | ||
updateDateTime: string | ||
assetId: string | ||
} | ||
|
||
export type HttpTransportTypes = BaseEndpointTypes & { | ||
Provider: { | ||
RequestBody: never | ||
ResponseBody: ResponseSchema | ||
} | ||
} | ||
|
||
// HttpTransport is used to fetch and process data from a Provider using HTTP(S) protocol. It usually needs two methods | ||
// `prepareRequests` and `parseResponse` | ||
export const httpTransport = new HttpTransport<HttpTransportTypes>({ | ||
// `prepareRequests` method receives request payloads sent to associated endpoint alongside adapter config(environment variables) | ||
// and should return 'request information' to the Data Provider. Use this method to construct one or many requests, and the framework | ||
// will send them to Data Provider | ||
prepareRequests: (params, config) => { | ||
return params.map((param) => { | ||
return { | ||
// `params` are parameters associated to this single request and will also be available in the 'parseResponse' method. | ||
params: [param], | ||
// `request` contains any valid axios request configuration | ||
request: { | ||
baseURL: config.API_BASE_URL, | ||
url: `${config.API_NAV_ENDPOINT}${param}`, | ||
headers: { | ||
X_API_KEY: config.API_KEY, | ||
}, | ||
}, | ||
} | ||
}) | ||
}, | ||
// `parseResponse` takes the 'params' specified in the `prepareRequests` and the 'response' from Data Provider and should return | ||
// an array of response objects to be stored in cache. Use this method to construct a list of response objects for every parameter in 'params' | ||
// and the framework will save them in cache and return to user | ||
parseResponse: (params, response) => { | ||
if (!response.data) { | ||
return params.map((param) => { | ||
return { | ||
params: param, | ||
response: { | ||
errorMessage: `The data provider didn't return any value`, | ||
statusCode: 502, | ||
}, | ||
} | ||
}) | ||
} | ||
|
||
return params.map((param) => { | ||
const equityNav = response.data.equityNav | ||
if (equityNav) { | ||
return { | ||
params: param, | ||
response: { | ||
result: Number(response.data.equityNav), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't follow the earlier discussion very closely but I think what you might be looking for here is something like the following: add to nav inputParameters trancheSelector: {
required: true,
type: 'string',
options: ['equityNav', 'seniorNAV', 'juniorNav'],
description: 'The tranche to use as result',
}, then here result: Number(response.data[param.trancheSelector]) plus necessary validation/verification where appropriate |
||
data: { | ||
result: Number(response.data.equityNav), | ||
timestamps: { | ||
providerIndicatedTimeUnixMs: Number(response.data.updateDateTime) * 1000, | ||
}, | ||
}, | ||
}, | ||
} | ||
} else { | ||
return { | ||
params: param, | ||
response: { | ||
errorMessage: `The data provider didn't return any value for asset id: ${param}`, | ||
statusCode: 502, | ||
}, | ||
} | ||
} | ||
}) | ||
}, | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just need 1 changeset for the PR, please mark it
major
instead ofpatch