Skip to content

Commit a1a5b26

Browse files
authored
Glv adapter lwba (#3670)
* Refactor adapter to have price/lwba endoints * Add LWBA response verification in test
1 parent 5bb85b8 commit a1a5b26

File tree

10 files changed

+178
-6
lines changed

10 files changed

+178
-6
lines changed

.changeset/happy-moles-change.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@chainlink/glv-token-adapter': minor
3+
---
4+
5+
Add LWBA endpoint

packages/composites/glv-token/README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,29 @@ Request:
5959
}
6060
```
6161

62+
## Crypto-lwba Endpoint
63+
64+
Supported names for this endpoint are: `cryptolwba`.
65+
66+
### Input Params
67+
68+
| Required? | Name | Aliases | Description | Type | Options | Default | Depends On | Not Valid With |
69+
| :-------: | :--: | :-----: | :---------: | :----: | :-----: | :-----: | :--------: | :------------: |
70+
|| glv | | Glv address | string | | | | |
71+
72+
### Example
73+
74+
Request:
75+
76+
```json
77+
{
78+
"data": {
79+
"endpoint": "crypto-lwba",
80+
"glv": "0x528A5bac7E746C9A509A1f4F6dF58A03d44279F9"
81+
}
82+
}
83+
```
84+
6285
---
6386

6487
MIT License
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export { endpoint as price } from './price'
2+
export { endpoint as lwba } from './lwba'
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import {
2+
AdapterEndpoint,
3+
LwbaResponseDataFields,
4+
} from '@chainlink/external-adapter-framework/adapter'
5+
import { InputParameters } from '@chainlink/external-adapter-framework/validation'
6+
import { config } from '../config'
7+
import { glvLwbaTransport } from '../transport/lwba'
8+
9+
export const inputParameters = new InputParameters(
10+
{
11+
glv: {
12+
required: true,
13+
type: 'string',
14+
description: 'Glv address',
15+
},
16+
},
17+
[
18+
{
19+
glv: '0x528A5bac7E746C9A509A1f4F6dF58A03d44279F9',
20+
},
21+
],
22+
)
23+
24+
export type BaseEndpointTypesLwba = {
25+
Parameters: typeof inputParameters.definition
26+
Response: LwbaResponseDataFields & {
27+
Data: {
28+
sources: Record<string, string[]>
29+
}
30+
}
31+
Settings: typeof config.settings
32+
}
33+
34+
export const endpoint = new AdapterEndpoint({
35+
name: 'crypto-lwba',
36+
transport: glvLwbaTransport,
37+
inputParameters,
38+
})
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { expose, ServerInstance } from '@chainlink/external-adapter-framework'
22
import { Adapter } from '@chainlink/external-adapter-framework/adapter'
33
import { config } from './config'
4-
import { price } from './endpoint'
4+
import { lwba, price } from './endpoint'
55

66
export const adapter = new Adapter({
77
defaultEndpoint: price.name,
88
name: 'GLV_TOKEN',
99
config,
10-
endpoints: [price],
10+
endpoints: [price, lwba],
1111
})
1212

1313
export const server = (): Promise<ServerInstance | undefined> => expose(adapter)

packages/composites/glv-token/src/transport/base.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { AdapterResponse, makeLogger } from '@chainlink/external-adapter-framewo
1111
import { AdapterDataProviderError } from '@chainlink/external-adapter-framework/validation/error'
1212
import glvAbi from '../config/glvReaderAbi.json'
1313
import { BaseEndpointTypes, inputParameters } from '../endpoint/price'
14+
import { BaseEndpointTypesLwba } from '../endpoint/lwba'
1415
import {
1516
mapParameter,
1617
mapSymbol,
@@ -41,7 +42,7 @@ type RequestParams = typeof inputParameters.validated
4142
* `formatResponse()` to produce different output shapes.
4243
*/
4344
export abstract class BaseGlvTransport<
44-
T extends BaseEndpointTypes,
45+
T extends BaseEndpointTypes | BaseEndpointTypesLwba,
4546
> extends SubscriptionTransport<T> {
4647
abstract backgroundHandler(
4748
context: EndpointContext<T>,
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { BaseGlvTransport } from './base'
2+
import { EndpointContext } from '@chainlink/external-adapter-framework/adapter'
3+
import { TypeFromDefinition } from '@chainlink/external-adapter-framework/validation/input-params'
4+
import { AdapterResponse, sleep } from '@chainlink/external-adapter-framework/util'
5+
import { BaseEndpointTypesLwba } from '../endpoint/lwba'
6+
7+
export class GlvLwbaTransport extends BaseGlvTransport<BaseEndpointTypesLwba> {
8+
async backgroundHandler(
9+
context: EndpointContext<BaseEndpointTypesLwba>,
10+
entries: TypeFromDefinition<BaseEndpointTypesLwba['Parameters']>[],
11+
): Promise<void> {
12+
await Promise.all(entries.map(async (param) => this.handleRequest(param)))
13+
await sleep(context.adapterSettings.BACKGROUND_EXECUTE_MS)
14+
}
15+
16+
async handleRequest(
17+
param: TypeFromDefinition<BaseEndpointTypesLwba['Parameters']>,
18+
): Promise<void> {
19+
const response = await this._handleRequest(param).catch((e) => this.handleError(e))
20+
await this.responseCache.write(this.name, [{ params: param, response }])
21+
}
22+
23+
protected formatResponse(
24+
result: number,
25+
minimizedValue: number,
26+
maximizedValue: number,
27+
sources: Record<string, string[]>,
28+
timestamps: any,
29+
): AdapterResponse<BaseEndpointTypesLwba['Response']> {
30+
return {
31+
data: {
32+
mid: result,
33+
bid: minimizedValue,
34+
ask: maximizedValue,
35+
sources,
36+
},
37+
statusCode: 200,
38+
result: null,
39+
timestamps,
40+
}
41+
}
42+
}
43+
44+
export const glvLwbaTransport = new GlvLwbaTransport()
Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
{
2-
"requests": [{
3-
"glv": "0x528A5bac7E746C9A509A1f4F6dF58A03d44279F9"
4-
}]
2+
"requests": [
3+
{
4+
"glv": "0x528A5bac7E746C9A509A1f4F6dF58A03d44279F9"
5+
},
6+
{
7+
"endpoint": "price",
8+
"glv": "0x528A5bac7E746C9A509A1f4F6dF58A03d44279F9"
9+
},
10+
{
11+
"endpoint": "crypto-lwba",
12+
"glv": "0x528A5bac7E746C9A509A1f4F6dF58A03d44279F9"
13+
}
14+
]
515
}

packages/composites/glv-token/test/integration/__snapshots__/adapter.test.ts.snap

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,33 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`execute lwba endpoint should return success 1`] = `
4+
{
5+
"data": {
6+
"ask": 1.1473068612168396,
7+
"bid": 1.1470467994160611,
8+
"mid": 1.1471768303164502,
9+
"sources": {
10+
"ETH": [
11+
"tiingo",
12+
"coinmetrics",
13+
"ncfx",
14+
],
15+
"USDC": [
16+
"tiingo",
17+
"coinmetrics",
18+
"ncfx",
19+
],
20+
},
21+
},
22+
"result": null,
23+
"statusCode": 200,
24+
"timestamps": {
25+
"providerDataReceivedUnixMs": 978347471111,
26+
"providerDataRequestedUnixMs": 978347471111,
27+
},
28+
}
29+
`;
30+
331
exports[`execute price endpoint should return success 1`] = `
432
{
533
"data": {

packages/composites/glv-token/test/integration/adapter.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ import {
99
mockTiingoEAResponseSuccess,
1010
} from './fixtures'
1111
import { ethers } from 'ethers'
12+
import {
13+
LwbaResponseDataFields,
14+
validateLwbaResponse,
15+
} from '@chainlink/external-adapter-framework/adapter'
1216

1317
jest.mock('ethers', () => ({
1418
...jest.requireActual('ethers'),
@@ -116,4 +120,22 @@ describe('execute', () => {
116120
expect(response.json()).toMatchSnapshot()
117121
})
118122
})
123+
124+
describe('lwba endpoint', () => {
125+
it('should return success', async () => {
126+
const data = {
127+
endpoint: 'crypto-lwba',
128+
glv: '0x528A5bac7E746C9A509A1f4F6dF58A03d44279F9',
129+
}
130+
mockTiingoEAResponseSuccess('ETH')
131+
mockNCFXEAResponseSuccess('ETH')
132+
mockCoinmetricsEAResponseSuccess('ETH')
133+
const response = await testAdapter.request(data)
134+
expect(response.statusCode).toBe(200)
135+
expect(response.json()).toMatchSnapshot()
136+
const resJson = response.json()
137+
const resData = resJson.data as LwbaResponseDataFields['Data']
138+
validateLwbaResponse(resData.bid, resData.mid, resData.ask)
139+
})
140+
})
119141
})

0 commit comments

Comments
 (0)