Skip to content
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

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/hip-cows-serve.md
droconnel22 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@chainlink/peregrine-fund-admin-adapter': patch
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'@chainlink/peregrine-fund-admin-adapter': patch
'@chainlink/peregrine-fund-admin-adapter': major

---

Peregrine Fund Admin Init
20 changes: 20 additions & 0 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Empty file.
3 changes: 3 additions & 0 deletions packages/sources/peregrine-fund-admin/README.md
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`.
40 changes: 40 additions & 0 deletions packages/sources/peregrine-fund-admin/package.json
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"
}
}
29 changes: 29 additions & 0 deletions packages/sources/peregrine-fund-admin/src/config/index.d.ts
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.

37 changes: 37 additions & 0 deletions packages/sources/peregrine-fund-admin/src/config/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 31 additions & 0 deletions packages/sources/peregrine-fund-admin/src/config/index.ts
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: {
droconnel22 marked this conversation as resolved.
Show resolved Hide resolved
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',
droconnel22 marked this conversation as resolved.
Show resolved Hide resolved
default: DEFAULT_RESERVE_URL_VALUE,
},
})
2 changes: 2 additions & 0 deletions packages/sources/peregrine-fund-admin/src/endpoint/index.ts
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'
51 changes: 51 additions & 0 deletions packages/sources/peregrine-fund-admin/src/endpoint/nav.ts
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
droconnel22 marked this conversation as resolved.
Show resolved Hide resolved
name: 'nav',
// Transport handles incoming requests, data processing and communication for this endpoint
transport: httpTransport,
//input params,
inputParameters,
})
35 changes: 35 additions & 0 deletions packages/sources/peregrine-fund-admin/src/endpoint/reserve.ts
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
droconnel22 marked this conversation as resolved.
Show resolved Hide resolved
name: 'reserve',
// Supported input parameters for this endpoint
inputParameters,
// Transport handles incoming requests, data processing and communication for this endpoint
transport: httpTransport,
})
17 changes: 17 additions & 0 deletions packages/sources/peregrine-fund-admin/src/index.ts
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.
droconnel22 marked this conversation as resolved.
Show resolved Hide resolved
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)
86 changes: 86 additions & 0 deletions packages/sources/peregrine-fund-admin/src/transport/nav.ts
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),
droconnel22 marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
result: Number(response.data.equityNav),
result: Number(equityNav),

data: {
result: Number(response.data.equityNav),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
result: Number(response.data.equityNav),
result: Number(equityNav),

timestamps: {
providerIndicatedTimeUnixMs: Number(response.data.updateDateTime) * 1000,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updateDateTime returns a formatted string, not a number that can be cast. Please use a proper conversion here.

},
},
},
}
} else {
return {
params: param,
response: {
errorMessage: `The data provider didn't return any value for asset id: ${param}`,
statusCode: 502,
},
}
}
})
},
})
Loading
Loading