Skip to content
Open
Show file tree
Hide file tree
Changes from all 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/hungry-walls-admire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@chainlink/data-engine-adapter': minor
---

Add v11 schema
14 changes: 7 additions & 7 deletions .pnp.cjs

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

Binary file not shown.
2 changes: 1 addition & 1 deletion packages/sources/data-engine/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"typescript": "5.8.3"
},
"dependencies": {
"@chainlink/data-streams-sdk": "^1.0.4",
"@chainlink/data-streams-sdk": "1.2.0",
"@chainlink/external-adapter-framework": "2.8.0",
"tslib": "2.4.1"
}
Expand Down
45 changes: 45 additions & 0 deletions packages/sources/data-engine/src/endpoint/deutscheBoerseV11.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { AdapterEndpoint } from '@chainlink/external-adapter-framework/adapter'
import { InputParameters } from '@chainlink/external-adapter-framework/validation'
import { config } from '../config'
import { deutscheBoerseV11Transport } from '../transport/deutscheBoerseV11'

export const inputParameters = new InputParameters(
{
feedId: {
required: true,
type: 'string',
description: 'The feedId for Deutsche Boerse feed with v11 schema',
},
},
[
{
feedId: '0x0008707410e2c111fb0e80cab2fa004b215eea2d95b106e700243f9ebcc8fbd9',
},
],
)

export type BaseEndpointTypes = {
Parameters: typeof inputParameters.definition
Response: {
Result: null
Data: {
mid: string
lastSeenTimestampNs: string
bid: string
bidVolume: number
ask: string
askVolume: number
lastTradedPrice: string
Copy link
Collaborator

Choose a reason for hiding this comment

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

How does Streams / DE handle the feeds where lastTradedPrice is not available?
For example, spot (FX) feeds don't have lastTradedPrice. Would it cause any issues here or would they return a default?

marketStatus: number
decimals: number
}
}
Settings: typeof config.settings
}

export const endpoint = new AdapterEndpoint({
name: 'deutscheBoerse-v11',
aliases: [],
transport: deutscheBoerseV11Transport,
inputParameters,
})
1 change: 1 addition & 0 deletions packages/sources/data-engine/src/endpoint/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { endpoint as cryptoV3 } from './cryptoV3'
export { endpoint as deutscheBoerseV11 } from './deutscheBoerseV11'
export { endpoint as rwaV8 } from './rwaV8'
4 changes: 2 additions & 2 deletions packages/sources/data-engine/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { expose, ServerInstance } from '@chainlink/external-adapter-framework'
import { Adapter } from '@chainlink/external-adapter-framework/adapter'
import { config } from './config'
import { cryptoV3, rwaV8 } from './endpoint'
import { cryptoV3, deutscheBoerseV11, rwaV8 } from './endpoint'

export const adapter = new Adapter({
defaultEndpoint: cryptoV3.name,
name: 'DATA_ENGINE',
config,
endpoints: [cryptoV3, rwaV8],
endpoints: [cryptoV3, rwaV8, deutscheBoerseV11],
})

export const server = (): Promise<ServerInstance | undefined> => expose(adapter)
Expand Down
4 changes: 4 additions & 0 deletions packages/sources/data-engine/src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Requester } from '@chainlink/external-adapter-framework/util/requester'
import { AdapterError } from '@chainlink/external-adapter-framework/validation/error'

import { BaseEndpointTypes as CryptoV3Types } from './endpoint/cryptoV3'
import { BaseEndpointTypes as DeutscheBoerseV11Types } from './endpoint/deutscheBoerseV11'
import { BaseEndpointTypes as RwaV8Types } from './endpoint/rwaV8'

export const getCryptoPrice = async (feedId: string, url: string, requester: Requester) =>
Expand All @@ -11,6 +12,9 @@ export const getCryptoPrice = async (feedId: string, url: string, requester: Req
export const getRwaPrice = async (feedId: string, url: string, requester: Requester) =>
callEA<RwaV8Types['Response']['Data']>(feedId, 'rwa-v8', url, requester)

export const getDeutscheBoersePrice = async (feedId: string, url: string, requester: Requester) =>
callEA<DeutscheBoerseV11Types['Response']['Data']>(feedId, 'deutscheBoerse-v11', url, requester)

const callEA = async <T>(feedId: string, endpoint: string, url: string, requester: Requester) => {
const requestConfig = {
baseURL: url,
Expand Down
24 changes: 24 additions & 0 deletions packages/sources/data-engine/src/transport/deutscheBoerseV11.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { DecodedV11Report } from '@chainlink/data-streams-sdk'
import { BaseEndpointTypes } from '../endpoint/deutscheBoerseV11'
import { createDataEngineTransport, DECIMALS } from './wsTransportBase'

export const deutscheBoerseV11Transport = createDataEngineTransport<
BaseEndpointTypes,
DecodedV11Report
>({
schemaVersion: 'V11',
loggerName: 'deutscheBoerseV11Transport',
extractData: (decoded) => {
return {
mid: decoded.mid.toString(),
lastSeenTimestampNs: decoded.lastSeenTimestampNs.toString(),
bid: decoded.bid.toString(),
bidVolume: decoded.bidVolume,
ask: decoded.ask.toString(),
askVolume: decoded.askVolume,
lastTradedPrice: decoded.lastTradedPrice.toString(),
marketStatus: decoded.marketStatus,
decimals: DECIMALS,
}
},
})
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,28 @@ exports[`execute crypto-v3 endpoint should return success 1`] = `
}
`;

exports[`execute deutscheBoerse-v11 endpoint should return success 1`] = `
{
"data": {
"ask": "225350000000000000000",
"askVolume": 2426047410323587000,
"bid": "225300000000000000000",
"bidVolume": 2426047410323587000,
"decimals": 18,
"lastSeenTimestampNs": "1763378650248000000",
"lastTradedPrice": "221900000000000000000",
"marketStatus": 0,
"mid": "225325000000000000000",
},
"result": null,
"statusCode": 200,
"timestamps": {
"providerDataReceivedUnixMs": 3134,
"providerDataStreamEstablishedUnixMs": 3030,
},
}
`;

exports[`execute rwa-v8 endpoint should return success 1`] = `
{
"data": {
Expand Down
16 changes: 15 additions & 1 deletion packages/sources/data-engine/test/integration/adapter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ describe('execute', () => {
feedId: '0x0008',
}

const v11Data = {
endpoint: 'deutscheBoerse-v11',
feedId: '0x000b5',
}

beforeAll(async () => {
oldEnv = JSON.parse(JSON.stringify(process.env))
process.env.WS_API_ENDPOINT = wsEndpoint
Expand All @@ -41,7 +46,8 @@ describe('execute', () => {
// Send initial request to start background execute and wait for cache to be filled with results
await testAdapter.request(v3Data)
await testAdapter.request(v8Data)
await testAdapter.waitForCache(2)
await testAdapter.request(v11Data)
await testAdapter.waitForCache(3)
})

afterAll(async () => {
Expand All @@ -66,4 +72,12 @@ describe('execute', () => {
expect(response.json()).toMatchSnapshot()
})
})

describe('deutscheBoerse-v11 endpoint', () => {
it('should return success', async () => {
const response = await testAdapter.request(v11Data)
expect(response.statusCode).toBe(200)
expect(response.json()).toMatchSnapshot()
})
})
})
9 changes: 9 additions & 0 deletions packages/sources/data-engine/test/integration/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ export const mockWebSocketServer = (URL: string): MockWebsocketServer => {
},
}),
)
socket.send(
JSON.stringify({
report: {
feedID: '0x000b5',
fullReport:
'0x00094baebfda9b87680d8e59aa20a3e565126640ee7caeab3cd965e5568b17ee00000000000000000000000000000000000000000000000000000000016e6cb6000000000000000000000000000000000000000000000000000000040000000100000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000003a0010001010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000b5b1b8e542a6df9ba9dde5d1414d7ae63d62e57beb7f1467b8466780c336c000000000000000000000000000000000000000000000000000000006920dc1d000000000000000000000000000000000000000000000000000000006920dc1d0000000000000000000000000000000000000000000000000000692fbba7ee00000000000000000000000000000000000000000000000000005d6f4c28e02a0f000000000000000000000000000000000000000000000000000000006948691d00000000000000000000000000000000000000000000000c370335ad4ee480000000000000000000000000000000000000000000000000001878c78a248a320000000000000000000000000000000000000000000000000c36aa644f3782000000000000000000000000000000000000000000000000000821ab0d441498000000000000000000000000000000000000000000000000000c375c070b6647000000000000000000000000000000000000000000000000000821ab0d441498000000000000000000000000000000000000000000000000000c077b2a52cb2e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000678973865fd99c2db5792344b322b02fe756bf17fa9ff08956b0a11cc90cd220eb3d269d0fc7d00045ad61485770d97d6c792d34aa629d28ea3842d4a9eeb21d1cce4352e78d040458197361ec07f5c63570a52ac673b4f2e99b51dea48e5fdea662f30f90f154e0617712804d25ceb0b0bb89ad47e6d6530b797b2a52c6a4b77ae07ba227eed09c41426ba59606270efd8219fa1b09b40ffdd8a05dfa1dd755181cc6c0756e8160e3632876be343f048ab433167d64453235c4f95fad15d298c00000000000000000000000000000000000000000000000000000000000000064a8a69af25288efad814ddd0cb43eaef65ec54cbd02988034394d0c23f5d28d83e03741fb8f486723ab7443703f4e9b462b1011297fa345d4141827c52e68cd369a6808038ce21cc80da2b612c552110cadc0805e303b5a8247ba961476cec840ac48b4c47b052b550fc58ce6af88920b35dfaf6c5a0b58b9258490f601c84c46ccfc77960b1d3902747bc8b4817008e64376090ab2139a853fe7d07726f7f3814b275de57f7cdee746649355ac8b2db1d07acee309be9d1745916b815407d18',
},
}),
)
}, 100)
})

Expand Down
21 changes: 20 additions & 1 deletion packages/sources/data-engine/test/unit/lib.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getCryptoPrice, getRwaPrice } from '../../src/lib'
import { getCryptoPrice, getDeutscheBoersePrice, getRwaPrice } from '../../src/lib'

describe('lib.ts', () => {
it('getCryptoPrice - should return result', async () => {
Expand All @@ -19,6 +19,25 @@ describe('lib.ts', () => {
await expect(getRwaPrice('feed-2', 'ea-url', requester)).resolves.toEqual(data)
})

it('getDeutscheBoersePrice - should return result', async () => {
const requester = { request: jest.fn() } as any
const data = {
mid: '1',
lastSeenTimestampNs: '2',
bid: '3',
bidVolume: 4,
ask: '5',
askVolume: 6,
lastTradedPrice: '7',
marketStatus: 8,
decimals: 9,
}

requester.request.mockResolvedValueOnce({ response: { data: { result: null, data: data } } })

await expect(getDeutscheBoersePrice('feed-3', 'ea-url', requester)).resolves.toEqual(data)
})

it('should throw if empty', async () => {
const requester = { request: jest.fn() } as any

Expand Down
10 changes: 5 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3441,7 +3441,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@chainlink/data-engine-adapter@workspace:packages/sources/data-engine"
dependencies:
"@chainlink/data-streams-sdk": "npm:^1.0.4"
"@chainlink/data-streams-sdk": "npm:1.2.0"
"@chainlink/external-adapter-framework": "npm:2.8.0"
"@sinonjs/fake-timers": "npm:9.1.2"
"@types/jest": "npm:^29.5.14"
Expand All @@ -3453,9 +3453,9 @@ __metadata:
languageName: unknown
linkType: soft

"@chainlink/data-streams-sdk@npm:^1.0.4":
version: 1.0.4
resolution: "@chainlink/data-streams-sdk@npm:1.0.4"
"@chainlink/data-streams-sdk@npm:1.2.0":
version: 1.2.0
resolution: "@chainlink/data-streams-sdk@npm:1.2.0"
dependencies:
ethers: "npm:^6.15.0"
ws: "npm:^8.18.3"
Expand All @@ -3464,7 +3464,7 @@ __metadata:
peerDependenciesMeta:
dotenv:
optional: true
checksum: 10/32e33c3e87d646f0dc40957acf85f99f3a781c8cad28bd6cfb1aa778507a20894c74fe63f4a673bf43bee0ed6c1700c8eb6dd1189d89479e645d086299d35dcd
checksum: 10/6ee4c811874f97cce43cd77d9511a67163b08216313e89b7546a85bb51e63a25915eae1cc771224769a39c300de42bb4fa88726913d830ef0f2ec70a2d7f2aec
languageName: node
linkType: hard

Expand Down
Loading