Skip to content

Commit

Permalink
Feat/PDI-2301 moore-hk (#3165)
Browse files Browse the repository at this point in the history
* PDI-2301 moore-hk adapter for trueusd PoR

* add changeset

* cleanup

* review fixes

* update readme
  • Loading branch information
mmcallister-cll authored Feb 5, 2024
1 parent 134ce71 commit 5bb4038
Show file tree
Hide file tree
Showing 19 changed files with 490 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/eight-eggs-perform.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@chainlink/moore-hk-adapter': major
---

moore-hk initial EA release
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.
54 changes: 54 additions & 0 deletions packages/sources/moore-hk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# MOORE-HK

![0.0.0](https://img.shields.io/github/package-json/v/smartcontractkit/external-adapters-js?filename=packages/sources/moore-hk/package.json) ![v3](https://img.shields.io/badge/framework%20version-v3-blueviolet)

This document was generated automatically. Please see [README Generator](../../scripts#readme-generator) for more info.

## Environment Variables

| Required? | Name | Description | Type | Options | Default |
| :-------: | :----------: | :-----------------------------------: | :----: | :-----: | :-----------------------------------------------: |
| | API_ENDPOINT | An API endpoint for the Data Provider | string | | `https://api.real-time-reserves.verinumus.io/v1/` |

---

## Data Provider Rate Limits

| Name | Requests/credits per second | Requests/credits per minute | Requests/credits per hour | Note |
| :-----: | :-------------------------: | :-------------------------: | :-----------------------: | :--: |
| default | | 6 | | |

---

## Input Parameters

| Required? | Name | Description | Type | Options | Default |
| :-------: | :------: | :-----------------: | :----: | :--------------------------: | :-------: |
| | endpoint | The endpoint to use | string | [trueusd](#trueusd-endpoint) | `trueusd` |

## Trueusd Endpoint

`trueusd` is the only supported name for this endpoint.

### Input Params

| Required? | Name | Aliases | Description | Type | Options | Default | Depends On | Not Valid With |
| :-------: | :---: | :-----: | :------------------------------------------------------: | :----: | :-----: | :----------: | :--------: | :------------: |
| | field | | The object-path string to parse a single `result` value. | string | | `totalTrust` | | |

### Example

Request:

```json
{
"data": {
"endpoint": "trueusd",
"field": "totalTrust"
}
}
```

---

MIT License
40 changes: 40 additions & 0 deletions packages/sources/moore-hk/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "@chainlink/moore-hk-adapter",
"version": "0.0.0",
"description": "Chainlink moore-hk adapter.",
"keywords": [
"Chainlink",
"LINK",
"blockchain",
"oracle",
"moore-hk"
],
"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.11.68",
"nock": "13.2.9",
"typescript": "5.0.4"
},
"dependencies": {
"@chainlink/external-adapter-framework": "0.33.2",
"tslib": "2.4.1"
}
}
9 changes: 9 additions & 0 deletions packages/sources/moore-hk/src/config/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { AdapterConfig } from '@chainlink/external-adapter-framework/config'

export const config = new AdapterConfig({
API_ENDPOINT: {
description: 'An API endpoint for the Data Provider',
type: 'string',
default: 'https://api.real-time-reserves.verinumus.io/v1/',
},
})
1 change: 1 addition & 0 deletions packages/sources/moore-hk/src/endpoint/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { endpoint as trueusd } from './trueusd'
32 changes: 32 additions & 0 deletions packages/sources/moore-hk/src/endpoint/trueusd.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { AdapterEndpoint } from '@chainlink/external-adapter-framework/adapter'
import { InputParameters } from '@chainlink/external-adapter-framework/validation'
import { SingleNumberResultResponse } from '@chainlink/external-adapter-framework/util'
import { config } from '../config'
import { httpTransport } from '../transport/trueusd'

export const inputParameters = new InputParameters(
{
field: {
default: 'totalTrust',
description: 'The object-path string to parse a single `result` value.',
type: 'string',
},
},
[
{
field: 'totalTrust',
},
],
)

export type BaseEndpointTypes = {
Parameters: typeof inputParameters.definition
Response: SingleNumberResultResponse
Settings: typeof config.settings
}

export const endpoint = new AdapterEndpoint({
name: 'trueusd',
transport: httpTransport,
inputParameters,
})
20 changes: 20 additions & 0 deletions packages/sources/moore-hk/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { expose, ServerInstance } from '@chainlink/external-adapter-framework'
import { Adapter } from '@chainlink/external-adapter-framework/adapter'
import { config } from './config'
import { trueusd } from './endpoint'

export const adapter = new Adapter({
defaultEndpoint: trueusd.name,
name: 'MOORE-HK',
config,
endpoints: [trueusd],
rateLimiting: {
tiers: {
default: {
rateLimit1m: 6,
},
},
},
})

export const server = (): Promise<ServerInstance | undefined> => expose(adapter)
83 changes: 83 additions & 0 deletions packages/sources/moore-hk/src/transport/trueusd.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { HttpTransport } from '@chainlink/external-adapter-framework/transports'
import { BaseEndpointTypes } from '../endpoint/trueusd'

interface ResponseSchema {
accountName: string
totalTrust: number
totalToken: number
updatedAt: string
token: {
tokenName: string
totalTokenByChain: number
}[]
ripcord: boolean
ripcordDetails: string[]
}

export type HttpTransportTypes = BaseEndpointTypes & {
Provider: {
RequestBody: never
ResponseBody: ResponseSchema
}
}

export const httpTransport = new HttpTransport<HttpTransportTypes>({
prepareRequests: (params, config) => {
return params.map((param) => {
return {
params: [param],
request: {
baseURL: config.API_ENDPOINT,
url: '/chainlink/proof-of-reserves/TrueUSD',
},
}
})
},
parseResponse: (params, response) => {
return params.map((param) => {
// Return error if ripcord indicator true
const providerIndicatedTimeUnixMs = new Date(response.data.updatedAt).getTime()
if (response.data.ripcord) {
const message = `Ripcord indicator true. Details: ${response.data.ripcordDetails.join(
', ',
)}`
return {
params: param,
response: {
errorMessage: message,
statusCode: 502,
timestamps: {
providerIndicatedTimeUnixMs,
},
},
}
}

const resultPath = param.field || ''
const result = response.data[resultPath as keyof typeof response.data]

if (isNaN(result as number)) {
return {
params: param,
response: {
errorMessage: `Value for '${resultPath}' is not a number.`,
statusCode: 502,
},
}
}

return {
params: param,
response: {
result: result as number,
data: {
result: result as number,
},
timestamps: {
providerIndicatedTimeUnixMs,
},
},
}
})
},
})
5 changes: 5 additions & 0 deletions packages/sources/moore-hk/test-payload.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"requests": [{
"field": "totalTrust"
}]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`execute trueusd endpoint should return 502 when field dne 1`] = `
{
"errorMessage": "Value for 'invalidField' is not a number.",
"statusCode": 502,
"timestamps": {
"providerDataReceivedUnixMs": 978347471111,
"providerDataRequestedUnixMs": 978347471111,
},
}
`;

exports[`execute trueusd endpoint should return 502 when ripcord: true 1`] = `
{
"errorMessage": "Ripcord indicator true. Details: Details1, Details2",
"statusCode": 502,
"timestamps": {
"providerDataReceivedUnixMs": 978347471111,
"providerDataRequestedUnixMs": 978347471111,
"providerIndicatedTimeUnixMs": 1706162197155,
},
}
`;

exports[`execute trueusd endpoint should return success 1`] = `
{
"data": {
"result": 1888313215.57,
},
"result": 1888313215.57,
"statusCode": 200,
"timestamps": {
"providerDataReceivedUnixMs": 978347471111,
"providerDataRequestedUnixMs": 978347471111,
"providerIndicatedTimeUnixMs": 1706162197155,
},
}
`;
Loading

0 comments on commit 5bb4038

Please sign in to comment.