Skip to content

Commit

Permalink
m^0 external adapter (#3505)
Browse files Browse the repository at this point in the history
* m^0 external adapter

* Remove input param

---------

Co-authored-by: Adam Stibal <stibala@users.noreply.github.com>
Co-authored-by: app-token-issuer-data-feeds[bot] <134377064+app-token-issuer-data-feeds[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Oct 25, 2024
1 parent 45d018f commit cae92f9
Show file tree
Hide file tree
Showing 25 changed files with 301 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/dull-lemons-exist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@chainlink/m0-adapter': patch
---

Initial version of the M^0 EA
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.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added .yarn/cache/fsevents-patch-19706e7e35-10.zip
Binary file not shown.
Binary file added .yarn/cache/fsevents-patch-afc6995412-10.zip
Binary file not shown.
Empty file.
3 changes: 3 additions & 0 deletions packages/sources/m0/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Chainlink External Adapter for m0

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 m0`.
40 changes: 40 additions & 0 deletions packages/sources/m0/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "@chainlink/m0-adapter",
"version": "0.0.0",
"description": "Chainlink m0 adapter.",
"keywords": [
"Chainlink",
"LINK",
"blockchain",
"oracle",
"m0"
],
"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.5.4"
},
"dependencies": {
"@chainlink/external-adapter-framework": "1.5.0",
"tslib": "2.4.1"
}
}
9 changes: 9 additions & 0 deletions packages/sources/m0/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 Data Provider',
type: 'string',
default: 'https://api.m0.xyz',
},
})
1 change: 1 addition & 0 deletions packages/sources/m0/src/endpoint/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { endpoint as nav } from './nav'
20 changes: 20 additions & 0 deletions packages/sources/m0/src/endpoint/nav.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { AdapterEndpoint } from '@chainlink/external-adapter-framework/adapter'
import { InputParameters } from '@chainlink/external-adapter-framework/validation'
import { EmptyInputParameters } from '@chainlink/external-adapter-framework/validation/input-params'
import { SingleNumberResultResponse } from '@chainlink/external-adapter-framework/util'
import { config } from '../config'
import { httpTransport } from '../transport/nav'

export const inputParameters = new InputParameters({}, [])

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

export const endpoint = new AdapterEndpoint({
name: 'reserves',
aliases: ['por', 'nav'],
transport: httpTransport,
})
21 changes: 21 additions & 0 deletions packages/sources/m0/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { expose, ServerInstance } from '@chainlink/external-adapter-framework'
import { Adapter } from '@chainlink/external-adapter-framework/adapter'
import { config } from './config'
import { nav } from './endpoint'

export const adapter = new Adapter({
defaultEndpoint: nav.name,
name: 'M0',
config,
endpoints: [nav],
rateLimiting: {
tiers: {
default: {
rateLimit1m: 1,
note: 'Considered unlimited tier, but setting reasonable limit',
},
},
},
})

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

export interface ResponseSchema {
totalCollateral: number
totalOwedM: number
collateralisation: number
}

export type HttpTransportTypes = BaseEndpointTypes & {
Provider: {
RequestBody: {
method: string
}
ResponseBody: ResponseSchema
}
}
export const httpTransport = new HttpTransport<HttpTransportTypes>({
prepareRequests: (params, config) => {
return params.map((param) => {
return {
params: [param],
request: {
baseURL: config.API_ENDPOINT,
url: '/api/dashboard-backend-api/api/rpc',
method: 'POST',
data: { method: 'navDetails' },
},
}
})
},
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) => {
// total collateral: eligible and non eligible treasuries and cash, in micro dollar denomination
const result = response.data['totalCollateral']
return {
params: param,
response: {
result,
data: {
result,
},
},
}
})
},
})
3 changes: 3 additions & 0 deletions packages/sources/m0/test-payload.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"requests": [{}]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`execute nav endpoint should return success 1`] = `
{
"data": {
"result": 54716821540000,
},
"result": 54716821540000,
"statusCode": 200,
"timestamps": {
"providerDataReceivedUnixMs": 978347471111,
"providerDataRequestedUnixMs": 978347471111,
},
}
`;
44 changes: 44 additions & 0 deletions packages/sources/m0/test/integration/adapter.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {
TestAdapter,
setEnvVariables,
} from '@chainlink/external-adapter-framework/util/testing-utils'
import * as nock from 'nock'
import { mockResponseSuccess } from './fixtures'

describe('execute', () => {
let spy: jest.SpyInstance
let testAdapter: TestAdapter
let oldEnv: NodeJS.ProcessEnv

beforeAll(async () => {
oldEnv = JSON.parse(JSON.stringify(process.env))
process.env.API_KEY = process.env.API_KEY ?? 'fake-api-key'

const mockDate = new Date('2001-01-01T11:11:11.111Z')
spy = jest.spyOn(Date, 'now').mockReturnValue(mockDate.getTime())

const adapter = (await import('./../../src')).adapter
adapter.rateLimiting = undefined
testAdapter = await TestAdapter.startWithMockedCache(adapter, {
testAdapter: {} as TestAdapter<never>,
})
})

afterAll(async () => {
setEnvVariables(oldEnv)
await testAdapter.api.close()
nock.restore()
nock.cleanAll()
spy.mockRestore()
})

describe('nav endpoint', () => {
it('should return success', async () => {
const data = {}
mockResponseSuccess()
const response = await testAdapter.request(data)
expect(response.statusCode).toBe(200)
expect(response.json()).toMatchSnapshot()
})
})
})
26 changes: 26 additions & 0 deletions packages/sources/m0/test/integration/fixtures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import nock from 'nock'

export const mockResponseSuccess = (): nock.Scope =>
nock('https://api.m0.xyz', {
encodedQueryParams: true,
})
.post('/api/dashboard-backend-api/api/rpc', { method: 'navDetails' })
.reply(
200,
() => ({
totalCollateral: 54716821540000,
totalOwedM: 42847433836220,
collateralisation: 0.7830760743407144,
}),
[
'Content-Type',
'application/json',
'Connection',
'close',
'Vary',
'Accept-Encoding',
'Vary',
'Origin',
],
)
.persist()
9 changes: 9 additions & 0 deletions packages/sources/m0/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src"
},
"include": ["src/**/*", "src/**/*.json"],
"exclude": ["dist", "**/*.spec.ts", "**/*.test.ts"]
}
7 changes: 7 additions & 0 deletions packages/sources/m0/tsconfig.test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"include": ["src/**/*", "**/test", "src/**/*.json"],
"compilerOptions": {
"noEmit": true
}
}
3 changes: 3 additions & 0 deletions packages/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,9 @@
{
"path": "./sources/lotus"
},
{
"path": "./sources/m0"
},
{
"path": "./sources/marketstack"
},
Expand Down
3 changes: 3 additions & 0 deletions packages/tsconfig.test.json
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,9 @@
{
"path": "./sources/lotus/tsconfig.test.json"
},
{
"path": "./sources/m0/tsconfig.test.json"
},
{
"path": "./sources/marketstack/tsconfig.test.json"
},
Expand Down
13 changes: 13 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5181,6 +5181,19 @@ __metadata:
languageName: unknown
linkType: soft

"@chainlink/m0-adapter@workspace:packages/sources/m0":
version: 0.0.0-use.local
resolution: "@chainlink/m0-adapter@workspace:packages/sources/m0"
dependencies:
"@chainlink/external-adapter-framework": "npm:1.5.0"
"@types/jest": "npm:27.5.2"
"@types/node": "npm:16.18.115"
nock: "npm:13.5.4"
tslib: "npm:2.4.1"
typescript: "npm:5.5.4"
languageName: unknown
linkType: soft

"@chainlink/market-closure-adapter@workspace:packages/composites/market-closure":
version: 0.0.0-use.local
resolution: "@chainlink/market-closure-adapter@workspace:packages/composites/market-closure"
Expand Down

0 comments on commit cae92f9

Please sign in to comment.