@chainlink/external-adapter-framework 0.0.12 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/.eslintignore +1 -0
  2. package/.github/README.MD +35 -10
  3. package/.github/workflows/label.yaml +39 -0
  4. package/.github/workflows/publish.yaml +0 -3
  5. package/dist/examples/coingecko/test/e2e/adapter.test.ts.js +82953 -0
  6. package/dist/examples/coingecko/test/integration/adapter.test.ts.js +91672 -0
  7. package/dist/main.js +72703 -0
  8. package/jest.config.js +5 -0
  9. package/package.json +14 -3
  10. package/src/config/provider-limits.ts +14 -17
  11. package/src/examples/coingecko/src/config/index.ts +12 -0
  12. package/src/examples/coingecko/src/config/overrides.json +10826 -0
  13. package/src/examples/coingecko/src/cryptoUtils.ts +88 -0
  14. package/src/examples/coingecko/src/endpoint/coins.ts +54 -0
  15. package/src/examples/coingecko/src/endpoint/crypto-marketcap.ts +66 -0
  16. package/src/examples/coingecko/src/endpoint/crypto-volume.ts +66 -0
  17. package/src/examples/coingecko/src/endpoint/crypto.ts +63 -0
  18. package/src/examples/coingecko/src/endpoint/dominance.ts +40 -0
  19. package/src/examples/coingecko/src/endpoint/global-marketcap.ts +40 -0
  20. package/src/examples/coingecko/src/endpoint/index.ts +6 -0
  21. package/src/examples/coingecko/src/globalUtils.ts +78 -0
  22. package/src/examples/coingecko/src/index.ts +17 -0
  23. package/src/examples/coingecko/test/e2e/adapter.test.ts +278 -0
  24. package/src/examples/coingecko/test/integration/__snapshots__/adapter.test.ts.snap +15 -0
  25. package/src/examples/coingecko/test/integration/adapter.test.ts +281 -0
  26. package/src/examples/coingecko/test/integration/capturedRequests.json +1 -0
  27. package/src/examples/coingecko/test/integration/fixtures.ts +42 -0
  28. package/src/examples/{coingecko → coingecko-old}/batch-warming.ts +1 -0
  29. package/src/examples/{coingecko → coingecko-old}/index.ts +0 -0
  30. package/src/examples/{coingecko → coingecko-old}/rest.ts +0 -0
  31. package/src/transports/batch-warming.ts +7 -2
  32. package/src/transports/rest.ts +5 -1
  33. package/src/util/index.ts +1 -0
  34. package/src/util/recordRequests.ts +47 -0
  35. package/src/validation/overrideFunctions.ts +44 -0
  36. package/test/metrics/warmer-metrics.test.ts +1 -0
  37. package/test/{smoke.test.ts → smoke/smoke.test.ts} +13 -13
  38. package/{test-payload-fail.json → test/smoke/test-payload-fail.json} +0 -0
  39. package/{test-payload.js → test/smoke/test-payload.js} +0 -0
  40. package/{test-payload.json → test/smoke/test-payload.json} +0 -0
  41. package/test/transports/batch.test.ts +1 -0
  42. package/tsconfig.json +4 -1
  43. package/webpack.config.js +39 -5
  44. package/yarn-error.log +3778 -0
  45. package/dist/src/adapter.d.ts +0 -135
  46. package/dist/src/adapter.js +0 -145
  47. package/dist/src/background-executor.d.ts +0 -11
  48. package/dist/src/background-executor.js +0 -45
  49. package/dist/src/cache/factory.d.ts +0 -6
  50. package/dist/src/cache/factory.js +0 -55
  51. package/dist/src/cache/index.d.ts +0 -94
  52. package/dist/src/cache/index.js +0 -173
  53. package/dist/src/cache/local.d.ts +0 -23
  54. package/dist/src/cache/local.js +0 -83
  55. package/dist/src/cache/metrics.d.ts +0 -27
  56. package/dist/src/cache/metrics.js +0 -120
  57. package/dist/src/cache/redis.d.ts +0 -16
  58. package/dist/src/cache/redis.js +0 -100
  59. package/dist/src/chainlink-external-adapter-framework-0.0.6.tgz +0 -0
  60. package/dist/src/config/index.d.ts +0 -214
  61. package/dist/src/config/index.js +0 -380
  62. package/dist/src/config/provider-limits.d.ts +0 -31
  63. package/dist/src/config/provider-limits.js +0 -75
  64. package/dist/src/examples/bank-frick/accounts.d.ts +0 -39
  65. package/dist/src/examples/bank-frick/accounts.js +0 -192
  66. package/dist/src/examples/bank-frick/config/index.d.ts +0 -4
  67. package/dist/src/examples/bank-frick/config/index.js +0 -54
  68. package/dist/src/examples/bank-frick/index.d.ts +0 -2
  69. package/dist/src/examples/bank-frick/index.js +0 -15
  70. package/dist/src/examples/bank-frick/util.d.ts +0 -4
  71. package/dist/src/examples/bank-frick/util.js +0 -39
  72. package/dist/src/examples/coingecko/batch-warming.d.ts +0 -7
  73. package/dist/src/examples/coingecko/batch-warming.js +0 -53
  74. package/dist/src/examples/coingecko/index.d.ts +0 -2
  75. package/dist/src/examples/coingecko/index.js +0 -11
  76. package/dist/src/examples/coingecko/rest.d.ts +0 -12
  77. package/dist/src/examples/coingecko/rest.js +0 -51
  78. package/dist/src/examples/ncfx/config/index.d.ts +0 -12
  79. package/dist/src/examples/ncfx/config/index.js +0 -15
  80. package/dist/src/examples/ncfx/index.d.ts +0 -13
  81. package/dist/src/examples/ncfx/index.js +0 -11
  82. package/dist/src/examples/ncfx/websocket.d.ts +0 -47
  83. package/dist/src/examples/ncfx/websocket.js +0 -73
  84. package/dist/src/index.d.ts +0 -11
  85. package/dist/src/index.js +0 -128
  86. package/dist/src/metrics/constants.d.ts +0 -16
  87. package/dist/src/metrics/constants.js +0 -25
  88. package/dist/src/metrics/index.d.ts +0 -15
  89. package/dist/src/metrics/index.js +0 -122
  90. package/dist/src/metrics/util.d.ts +0 -7
  91. package/dist/src/metrics/util.js +0 -9
  92. package/dist/src/package/adapter.d.ts +0 -88
  93. package/dist/src/package/adapter.js +0 -112
  94. package/dist/src/package/background-executor.d.ts +0 -11
  95. package/dist/src/package/background-executor.js +0 -45
  96. package/dist/src/package/cache/factory.d.ts +0 -6
  97. package/dist/src/package/cache/factory.js +0 -57
  98. package/dist/src/package/cache/index.d.ts +0 -90
  99. package/dist/src/package/cache/index.js +0 -169
  100. package/dist/src/package/cache/local.d.ts +0 -23
  101. package/dist/src/package/cache/local.js +0 -83
  102. package/dist/src/package/cache/metrics.d.ts +0 -27
  103. package/dist/src/package/cache/metrics.js +0 -120
  104. package/dist/src/package/cache/redis.d.ts +0 -16
  105. package/dist/src/package/cache/redis.js +0 -100
  106. package/dist/src/package/config/index.d.ts +0 -195
  107. package/dist/src/package/config/index.js +0 -365
  108. package/dist/src/package/config/provider-limits.d.ts +0 -31
  109. package/dist/src/package/config/provider-limits.js +0 -76
  110. package/dist/src/package/examples/coingecko/batch-warming.d.ts +0 -2
  111. package/dist/src/package/examples/coingecko/batch-warming.js +0 -52
  112. package/dist/src/package/examples/coingecko/index.d.ts +0 -2
  113. package/dist/src/package/examples/coingecko/index.js +0 -10
  114. package/dist/src/package/examples/coingecko/rest.d.ts +0 -2
  115. package/dist/src/package/examples/coingecko/rest.js +0 -50
  116. package/dist/src/package/examples/ncfx/config/index.d.ts +0 -12
  117. package/dist/src/package/examples/ncfx/config/index.js +0 -15
  118. package/dist/src/package/examples/ncfx/index.d.ts +0 -2
  119. package/dist/src/package/examples/ncfx/index.js +0 -10
  120. package/dist/src/package/examples/ncfx/websocket.d.ts +0 -36
  121. package/dist/src/package/examples/ncfx/websocket.js +0 -72
  122. package/dist/src/package/index.d.ts +0 -12
  123. package/dist/src/package/index.js +0 -92
  124. package/dist/src/package/metrics/constants.d.ts +0 -16
  125. package/dist/src/package/metrics/constants.js +0 -25
  126. package/dist/src/package/metrics/index.d.ts +0 -15
  127. package/dist/src/package/metrics/index.js +0 -123
  128. package/dist/src/package/metrics/util.d.ts +0 -3
  129. package/dist/src/package/metrics/util.js +0 -9
  130. package/dist/src/package/package.json +0 -72
  131. package/dist/src/package/rate-limiting/background/fixed-frequency.d.ts +0 -10
  132. package/dist/src/package/rate-limiting/background/fixed-frequency.js +0 -37
  133. package/dist/src/package/rate-limiting/index.d.ts +0 -54
  134. package/dist/src/package/rate-limiting/index.js +0 -63
  135. package/dist/src/package/rate-limiting/metrics.d.ts +0 -3
  136. package/dist/src/package/rate-limiting/metrics.js +0 -44
  137. package/dist/src/package/rate-limiting/request/simple-counting.d.ts +0 -20
  138. package/dist/src/package/rate-limiting/request/simple-counting.js +0 -62
  139. package/dist/src/package/test.d.ts +0 -1
  140. package/dist/src/package/test.js +0 -6
  141. package/dist/src/package/transports/batch-warming.d.ts +0 -34
  142. package/dist/src/package/transports/batch-warming.js +0 -101
  143. package/dist/src/package/transports/index.d.ts +0 -87
  144. package/dist/src/package/transports/index.js +0 -87
  145. package/dist/src/package/transports/metrics.d.ts +0 -21
  146. package/dist/src/package/transports/metrics.js +0 -105
  147. package/dist/src/package/transports/rest.d.ts +0 -43
  148. package/dist/src/package/transports/rest.js +0 -129
  149. package/dist/src/package/transports/util.d.ts +0 -8
  150. package/dist/src/package/transports/util.js +0 -85
  151. package/dist/src/package/transports/websocket.d.ts +0 -80
  152. package/dist/src/package/transports/websocket.js +0 -169
  153. package/dist/src/package/util/expiring-sorted-set.d.ts +0 -21
  154. package/dist/src/package/util/expiring-sorted-set.js +0 -47
  155. package/dist/src/package/util/index.d.ts +0 -11
  156. package/dist/src/package/util/index.js +0 -35
  157. package/dist/src/package/util/logger.d.ts +0 -42
  158. package/dist/src/package/util/logger.js +0 -62
  159. package/dist/src/package/util/request.d.ts +0 -55
  160. package/dist/src/package/util/request.js +0 -2
  161. package/dist/src/package/validation/error.d.ts +0 -50
  162. package/dist/src/package/validation/error.js +0 -79
  163. package/dist/src/package/validation/index.d.ts +0 -5
  164. package/dist/src/package/validation/index.js +0 -86
  165. package/dist/src/package/validation/input-params.d.ts +0 -15
  166. package/dist/src/package/validation/input-params.js +0 -30
  167. package/dist/src/package/validation/override-functions.d.ts +0 -3
  168. package/dist/src/package/validation/override-functions.js +0 -40
  169. package/dist/src/package/validation/preset-tokens.json +0 -23
  170. package/dist/src/package/validation/validator.d.ts +0 -47
  171. package/dist/src/package/validation/validator.js +0 -303
  172. package/dist/src/package.json +0 -72
  173. package/dist/src/rate-limiting/background/fixed-frequency.d.ts +0 -11
  174. package/dist/src/rate-limiting/background/fixed-frequency.js +0 -35
  175. package/dist/src/rate-limiting/index.d.ts +0 -55
  176. package/dist/src/rate-limiting/index.js +0 -63
  177. package/dist/src/rate-limiting/metrics.d.ts +0 -3
  178. package/dist/src/rate-limiting/metrics.js +0 -44
  179. package/dist/src/rate-limiting/request/simple-counting.d.ts +0 -21
  180. package/dist/src/rate-limiting/request/simple-counting.js +0 -62
  181. package/dist/src/test.d.ts +0 -1
  182. package/dist/src/test.js +0 -6
  183. package/dist/src/transports/batch-warming.d.ts +0 -35
  184. package/dist/src/transports/batch-warming.js +0 -101
  185. package/dist/src/transports/index.d.ts +0 -70
  186. package/dist/src/transports/index.js +0 -87
  187. package/dist/src/transports/metrics.d.ts +0 -22
  188. package/dist/src/transports/metrics.js +0 -105
  189. package/dist/src/transports/rest.d.ts +0 -44
  190. package/dist/src/transports/rest.js +0 -131
  191. package/dist/src/transports/util.d.ts +0 -8
  192. package/dist/src/transports/util.js +0 -85
  193. package/dist/src/transports/websocket.d.ts +0 -80
  194. package/dist/src/transports/websocket.js +0 -166
  195. package/dist/src/util/expiring-sorted-set.d.ts +0 -21
  196. package/dist/src/util/expiring-sorted-set.js +0 -47
  197. package/dist/src/util/index.d.ts +0 -12
  198. package/dist/src/util/index.js +0 -35
  199. package/dist/src/util/logger.d.ts +0 -42
  200. package/dist/src/util/logger.js +0 -62
  201. package/dist/src/util/request.d.ts +0 -57
  202. package/dist/src/util/request.js +0 -2
  203. package/dist/src/util/subscription-set/expiring-sorted-set.d.ts +0 -22
  204. package/dist/src/util/subscription-set/expiring-sorted-set.js +0 -47
  205. package/dist/src/util/subscription-set/subscription-set.d.ts +0 -18
  206. package/dist/src/util/subscription-set/subscription-set.js +0 -19
  207. package/dist/src/util/test-payload-loader.d.ts +0 -25
  208. package/dist/src/util/test-payload-loader.js +0 -83
  209. package/dist/src/validation/error.d.ts +0 -50
  210. package/dist/src/validation/error.js +0 -79
  211. package/dist/src/validation/index.d.ts +0 -5
  212. package/dist/src/validation/index.js +0 -91
  213. package/dist/src/validation/input-params.d.ts +0 -15
  214. package/dist/src/validation/input-params.js +0 -30
  215. package/dist/src/validation/override-functions.d.ts +0 -3
  216. package/dist/src/validation/override-functions.js +0 -40
  217. package/dist/src/validation/preset-tokens.json +0 -23
  218. package/dist/src/validation/validator.d.ts +0 -47
  219. package/dist/src/validation/validator.js +0 -303
  220. package/src/test.ts +0 -5
@@ -0,0 +1,88 @@
1
+ import { AxiosRequestConfig, AxiosResponse } from 'axios'
2
+ import { PRO_API_ENDPOINT, DEFAULT_API_ENDPOINT } from './config'
3
+ import { AdapterConfig } from '../../../config'
4
+ import { makeLogger } from '../../../util/logger'
5
+
6
+ type Overrides = Record<string, Record<string, string>>
7
+
8
+ export interface AdapterRequestParams {
9
+ coinid?: string
10
+ base?: string
11
+ quote: string
12
+ overrides?: Overrides
13
+ }
14
+
15
+ export interface ProviderRequestBody {
16
+ ids: string
17
+ vs_currencies: string
18
+ include_market_cap?: boolean
19
+ include_24hr_vol?: boolean
20
+ }
21
+
22
+ export interface ProviderResponseBody {
23
+ [base: string]: {
24
+ [quote: string]: number
25
+ }
26
+ }
27
+
28
+ interface ResultEntry {
29
+ value: number
30
+ params: {
31
+ quote: string
32
+ base?: string
33
+ coinid?: string
34
+ overrides?: Overrides
35
+ }
36
+ }
37
+
38
+ interface ResultEntryWithoutOverrides {
39
+ value: number
40
+ params: {
41
+ quote: string
42
+ base?: string
43
+ coinid?: string
44
+ }
45
+ }
46
+
47
+ export const buildBatchedRequestBody = (
48
+ params: AdapterRequestParams[],
49
+ config: AdapterConfig,
50
+ ): AxiosRequestConfig<ProviderRequestBody> => {
51
+ return {
52
+ baseURL: config.API_KEY ? PRO_API_ENDPOINT : DEFAULT_API_ENDPOINT,
53
+ url: '/simple/price',
54
+ method: 'GET',
55
+ params: {
56
+ ids: [...new Set(params.map((p) => p.coinid ?? p.base))].join(','),
57
+ vs_currencies: [...new Set(params.map((p) => p.quote))].join(','),
58
+ x_cg_pro_api_key: config.API_KEY,
59
+ },
60
+ }
61
+ }
62
+
63
+ const logger = makeLogger('CoinGecko Crypto Batched')
64
+
65
+ export const constructEntry = (
66
+ res: AxiosResponse<ProviderResponseBody>,
67
+ requestPayload: AdapterRequestParams,
68
+ resultPath: string,
69
+ ): ResultEntryWithoutOverrides | undefined => {
70
+ const coinId = requestPayload.coinid ?? (requestPayload.base as string)
71
+ const dataForCoin = res.data[coinId]
72
+ const dataForQuote = dataForCoin ? dataForCoin[resultPath] : undefined
73
+ if (!dataForQuote) {
74
+ logger.warn(`Data for "${requestPayload.quote}" not found for token "${coinId}".`)
75
+ return
76
+ }
77
+ const entry = {
78
+ params: requestPayload,
79
+ value: dataForQuote,
80
+ } as ResultEntry
81
+ if (requestPayload.coinid) {
82
+ entry.params.coinid = requestPayload.coinid
83
+ } else {
84
+ entry.params.base = requestPayload.base
85
+ }
86
+ delete entry.params.overrides
87
+ return entry
88
+ }
@@ -0,0 +1,54 @@
1
+ import { AxiosResponse, AxiosRequestConfig } from 'axios'
2
+ import { AdapterConfig } from '../../../../config'
3
+ import { AdapterEndpoint } from '../../../../../src/adapter'
4
+ import { RestTransport } from '../../../../../src/transports'
5
+ import { AdapterRequest, AdapterResponse } from '../../../../../src/util'
6
+ import { InputParameters } from '../../../../../src/validation'
7
+ import { DEFAULT_API_ENDPOINT, PRO_API_ENDPOINT, customSettings } from '../config'
8
+
9
+ export const inputParameters: InputParameters = {}
10
+
11
+ export interface AdapterRequestParams {
12
+ id: string
13
+ }
14
+
15
+ export interface CoinsResponse {
16
+ id: string
17
+ symbol: string
18
+ name: string
19
+ }
20
+
21
+ const restEndpointTransport = new RestTransport({
22
+ prepareRequest: (
23
+ _: AdapterRequest<AdapterRequestParams>,
24
+ config: AdapterConfig<typeof customSettings>,
25
+ ): AxiosRequestConfig<CoinsResponse> => {
26
+ const baseURL = config.API_KEY ? PRO_API_ENDPOINT : DEFAULT_API_ENDPOINT
27
+ const params = config.API_KEY ? { x_cg_pro_api_key: config.API_KEY } : undefined
28
+ return {
29
+ baseURL,
30
+ url: '/coins/list',
31
+ method: 'GET',
32
+ params,
33
+ }
34
+ },
35
+ parseResponse: (
36
+ req: AdapterRequest<AdapterRequestParams>,
37
+ res: AxiosResponse<CoinsResponse[]>,
38
+ ): AdapterResponse<CoinsResponse[]> => {
39
+ return {
40
+ data: res.data,
41
+ statusCode: 200,
42
+ result: res.data,
43
+ }
44
+ },
45
+ options: {
46
+ coalescing: true,
47
+ },
48
+ })
49
+
50
+ export const endpoint: AdapterEndpoint = {
51
+ name: 'coins',
52
+ transport: restEndpointTransport,
53
+ inputParameters,
54
+ }
@@ -0,0 +1,66 @@
1
+ import { AxiosRequestConfig, AxiosResponse } from 'axios'
2
+ import { AdapterEndpoint, AdapterContext } from '../../../../adapter'
3
+ import { BatchWarmingTransport } from '../../../../transports/batch-warming'
4
+ import { ProviderResult } from '../../../../util'
5
+ import { InputParameters } from '../../../../validation'
6
+ import { baseInputParameters } from '../../../../validation/input-params'
7
+ import {
8
+ AdapterRequestParams,
9
+ ProviderRequestBody,
10
+ buildBatchedRequestBody,
11
+ constructEntry,
12
+ ProviderResponseBody,
13
+ } from '../cryptoUtils'
14
+
15
+ export const inputParameters: InputParameters = {
16
+ overrides: baseInputParameters['overrides'],
17
+ coinid: {
18
+ description: 'The CoinGecko id or to query',
19
+ required: false,
20
+ },
21
+ base: {
22
+ aliases: ['from', 'coin'],
23
+ description: 'The symbol of symbols of the currency to query',
24
+ required: false,
25
+ },
26
+ quote: {
27
+ aliases: ['to', 'market'],
28
+ description: 'The symbol of the currency to convert to',
29
+ required: true,
30
+ },
31
+ }
32
+
33
+ const batchEndpointTransport = new BatchWarmingTransport({
34
+ prepareRequest: (
35
+ params: AdapterRequestParams[],
36
+ context: AdapterContext,
37
+ ): AxiosRequestConfig<ProviderRequestBody> => {
38
+ const requestBody = buildBatchedRequestBody(params, context.adapterConfig)
39
+ requestBody.params.include_market_cap = true
40
+ return requestBody
41
+ },
42
+ parseResponse: (
43
+ params: AdapterRequestParams[],
44
+ res: AxiosResponse<ProviderResponseBody>,
45
+ ): ProviderResult<AdapterRequestParams>[] => {
46
+ const entries = [] as ProviderResult<AdapterRequestParams>[]
47
+ for (const requestPayload of params) {
48
+ const entry = constructEntry(
49
+ res,
50
+ requestPayload,
51
+ `${requestPayload.quote.toLowerCase()}_market_cap`,
52
+ )
53
+ if (entry) {
54
+ entries.push(entry)
55
+ }
56
+ }
57
+ return entries
58
+ },
59
+ })
60
+
61
+ export const endpoint: AdapterEndpoint = {
62
+ name: 'marketcap',
63
+ aliases: ['crypto-marketcap'],
64
+ transport: batchEndpointTransport,
65
+ inputParameters,
66
+ }
@@ -0,0 +1,66 @@
1
+ import { AxiosRequestConfig, AxiosResponse } from 'axios'
2
+ import { AdapterEndpoint, AdapterContext } from '../../../../adapter'
3
+ import { BatchWarmingTransport } from '../../../../transports/batch-warming'
4
+ import { ProviderResult } from '../../../../util'
5
+ import { InputParameters } from '../../../../validation'
6
+ import { baseInputParameters } from '../../../../validation/input-params'
7
+ import {
8
+ AdapterRequestParams,
9
+ ProviderRequestBody,
10
+ buildBatchedRequestBody,
11
+ constructEntry,
12
+ ProviderResponseBody,
13
+ } from '../cryptoUtils'
14
+
15
+ export const inputParameters: InputParameters = {
16
+ overrides: baseInputParameters['overrides'],
17
+ coinid: {
18
+ description: 'The CoinGecko id or to query',
19
+ required: false,
20
+ },
21
+ base: {
22
+ aliases: ['from', 'coin'],
23
+ description: 'The symbol of symbols of the currency to query',
24
+ required: false,
25
+ },
26
+ quote: {
27
+ aliases: ['to', 'market'],
28
+ description: 'The symbol of the currency to convert to',
29
+ required: true,
30
+ },
31
+ }
32
+
33
+ const batchEndpointTransport = new BatchWarmingTransport({
34
+ prepareRequest: (
35
+ params: AdapterRequestParams[],
36
+ context: AdapterContext,
37
+ ): AxiosRequestConfig<ProviderRequestBody> => {
38
+ const requestBody = buildBatchedRequestBody(params, context.adapterConfig)
39
+ requestBody.params.include_24hr_vol = true
40
+ return requestBody
41
+ },
42
+ parseResponse: (
43
+ params: AdapterRequestParams[],
44
+ res: AxiosResponse<ProviderResponseBody>,
45
+ ): ProviderResult<AdapterRequestParams>[] => {
46
+ const entries = [] as ProviderResult<AdapterRequestParams>[]
47
+ for (const requestPayload of params) {
48
+ const entry = constructEntry(
49
+ res,
50
+ requestPayload,
51
+ `${requestPayload.quote.toLowerCase()}_24h_vol`,
52
+ )
53
+ if (entry) {
54
+ entries.push(entry)
55
+ }
56
+ }
57
+ return entries
58
+ },
59
+ })
60
+
61
+ export const endpoint: AdapterEndpoint = {
62
+ name: 'volume',
63
+ aliases: ['crypto-volume'],
64
+ transport: batchEndpointTransport,
65
+ inputParameters,
66
+ }
@@ -0,0 +1,63 @@
1
+ import { AxiosRequestConfig, AxiosResponse } from 'axios'
2
+ import { AdapterEndpoint, AdapterContext } from '../../../../adapter'
3
+ import { BatchWarmingTransport } from '../../../../transports/batch-warming'
4
+ import { ProviderResult } from '../../../../util'
5
+ import { InputParameters } from '../../../../validation'
6
+ import { baseInputParameters } from '../../../../validation/input-params'
7
+ import {
8
+ AdapterRequestParams,
9
+ ProviderRequestBody,
10
+ buildBatchedRequestBody,
11
+ constructEntry,
12
+ ProviderResponseBody,
13
+ } from '../cryptoUtils'
14
+
15
+ export const inputParameters: InputParameters = {
16
+ overrides: baseInputParameters['overrides'],
17
+ coinid: {
18
+ description: 'The CoinGecko id or to query',
19
+ required: false,
20
+ },
21
+ base: {
22
+ aliases: ['from', 'coin'],
23
+ description: 'The symbol of symbols of the currency to query',
24
+ required: false,
25
+ },
26
+ quote: {
27
+ aliases: ['to', 'market'],
28
+ description: 'The symbol of the currency to convert to',
29
+ required: true,
30
+ },
31
+ }
32
+
33
+ const batchEndpointTransport = new BatchWarmingTransport({
34
+ prepareRequest: (
35
+ params: AdapterRequestParams[],
36
+ context: AdapterContext,
37
+ ): AxiosRequestConfig<ProviderRequestBody> => {
38
+ return buildBatchedRequestBody(params, context.adapterConfig)
39
+ },
40
+ parseResponse: (
41
+ params: AdapterRequestParams[],
42
+ res: AxiosResponse<ProviderResponseBody>,
43
+ ): ProviderResult<AdapterRequestParams>[] => {
44
+ const entries = [] as ProviderResult<AdapterRequestParams>[]
45
+ for (const requestPayload of params) {
46
+ const entry = constructEntry(res, requestPayload, requestPayload.quote.toLowerCase())
47
+ // NOTE: the `entries` array is going to be shorter than the `params` array if one of the params has a bad token.
48
+ // Is that okay? I did this to avoid caching an invalid value for transient DP issues. Just want to make
49
+ // sure this works within the core framework
50
+ if (entry) {
51
+ entries.push(entry)
52
+ }
53
+ }
54
+ return entries
55
+ },
56
+ })
57
+
58
+ export const endpoint: AdapterEndpoint = {
59
+ name: 'crypto',
60
+ aliases: ['crypto-batched', 'batched', 'batch'],
61
+ transport: batchEndpointTransport,
62
+ inputParameters,
63
+ }
@@ -0,0 +1,40 @@
1
+ import { AxiosRequestConfig, AxiosResponse } from 'axios'
2
+ import { AdapterEndpoint, AdapterContext } from '../../../../adapter'
3
+ import { BatchWarmingTransport } from '../../../../transports/batch-warming'
4
+ import { ProviderResult } from '../../../../util'
5
+ import {
6
+ buildGlobalRequestBody,
7
+ AdapterRequestParams,
8
+ ProviderResponseBody,
9
+ constructEntry,
10
+ inputParameters,
11
+ } from '../globalUtils'
12
+
13
+ const batchEndpointTransport = new BatchWarmingTransport({
14
+ prepareRequest: (
15
+ params: AdapterRequestParams[],
16
+ context: AdapterContext,
17
+ ): AxiosRequestConfig<never> => {
18
+ return buildGlobalRequestBody(context.adapterConfig)
19
+ },
20
+ parseResponse: (
21
+ params: AdapterRequestParams[],
22
+ res: AxiosResponse<ProviderResponseBody>,
23
+ ): ProviderResult<AdapterRequestParams>[] => {
24
+ const entries = [] as ProviderResult<AdapterRequestParams>[]
25
+ for (const requestPayload of params) {
26
+ const entry = constructEntry(res, requestPayload, 'market_cap_percentage')
27
+ if (entry) {
28
+ entries.push(entry)
29
+ }
30
+ }
31
+ return entries
32
+ },
33
+ })
34
+
35
+ export const endpoint: AdapterEndpoint = {
36
+ name: 'dominance',
37
+ aliases: ['market_cap_percentage'],
38
+ transport: batchEndpointTransport,
39
+ inputParameters,
40
+ }
@@ -0,0 +1,40 @@
1
+ import { AxiosRequestConfig, AxiosResponse } from 'axios'
2
+ import { AdapterEndpoint, AdapterContext } from '../../../../adapter'
3
+ import { BatchWarmingTransport } from '../../../../transports/batch-warming'
4
+ import { ProviderResult } from '../../../../util'
5
+ import {
6
+ buildGlobalRequestBody,
7
+ AdapterRequestParams,
8
+ ProviderResponseBody,
9
+ constructEntry,
10
+ inputParameters,
11
+ } from '../globalUtils'
12
+
13
+ const batchEndpointTransport = new BatchWarmingTransport({
14
+ prepareRequest: (
15
+ params: AdapterRequestParams[],
16
+ context: AdapterContext,
17
+ ): AxiosRequestConfig<never> => {
18
+ return buildGlobalRequestBody(context.adapterConfig)
19
+ },
20
+ parseResponse: (
21
+ params: AdapterRequestParams[],
22
+ res: AxiosResponse<ProviderResponseBody>,
23
+ ): ProviderResult<AdapterRequestParams>[] => {
24
+ const entries = [] as ProviderResult<AdapterRequestParams>[]
25
+ for (const requestPayload of params) {
26
+ const entry = constructEntry(res, requestPayload, 'total_market_cap')
27
+ if (entry) {
28
+ entries.push(entry)
29
+ }
30
+ }
31
+ return entries
32
+ },
33
+ })
34
+
35
+ export const endpoint: AdapterEndpoint = {
36
+ name: 'globalmarketcap',
37
+ aliases: ['total_market_cap'],
38
+ transport: batchEndpointTransport,
39
+ inputParameters,
40
+ }
@@ -0,0 +1,6 @@
1
+ export { endpoint as coins } from './coins'
2
+ export { endpoint as crypto } from './crypto'
3
+ export { endpoint as cryptoMarketcap } from './crypto-marketcap'
4
+ export { endpoint as globalMarketcap } from './global-marketcap'
5
+ export { endpoint as dominance } from './dominance'
6
+ export { endpoint as cryptoVolume } from './crypto-volume'
@@ -0,0 +1,78 @@
1
+ import { AxiosRequestConfig, AxiosResponse } from 'axios'
2
+ import { PRO_API_ENDPOINT, DEFAULT_API_ENDPOINT } from './config'
3
+ import { AdapterConfig } from '../../../config'
4
+ import { makeLogger } from '../../../util/logger'
5
+ import { InputParameters } from '../../../validation'
6
+
7
+ const logger = makeLogger('CoinGecko Global Batched')
8
+
9
+ export const inputParameters: InputParameters = {
10
+ market: {
11
+ aliases: ['to', 'quote'],
12
+ description: 'The ticker of the coin to query',
13
+ required: true,
14
+ },
15
+ }
16
+
17
+ export interface AdapterRequestParams {
18
+ market: string
19
+ }
20
+
21
+ export interface ProviderResponseBody {
22
+ data: {
23
+ active_cryptocurrencies: number
24
+ upcoming_icos: number
25
+ ongoing_icos: number
26
+ ended_icos: number
27
+ markets: number
28
+ total_market_cap: Record<string, number>
29
+ total_volume: Record<string, number>
30
+ market_cap_percentage: Record<string, number>
31
+ market_cap_change_percentage_24h_usd: number
32
+ updated_at: number
33
+ }
34
+ }
35
+
36
+ interface ResultEntry {
37
+ value: number
38
+ params: AdapterRequestParams
39
+ }
40
+
41
+ export const buildGlobalRequestBody = (config: AdapterConfig): AxiosRequestConfig<never> => {
42
+ const apiKey = {
43
+ x_cg_pro_api_key: config.API_KEY,
44
+ }
45
+ return {
46
+ baseURL: config.API_KEY ? PRO_API_ENDPOINT : DEFAULT_API_ENDPOINT,
47
+ url: '/global',
48
+ method: 'GET',
49
+ params: apiKey,
50
+ }
51
+ }
52
+
53
+ export const constructEntry = (
54
+ res: AxiosResponse<ProviderResponseBody>,
55
+ requestPayload: AdapterRequestParams,
56
+ resultPath: 'total_market_cap' | 'market_cap_percentage',
57
+ ): ResultEntry | undefined => {
58
+ const resultData = res.data.data
59
+ if (!resultData) {
60
+ logger.warn(`Data not found".`)
61
+ return
62
+ }
63
+ const totalMarketcapData = resultData[resultPath]
64
+ if (!totalMarketcapData) {
65
+ logger.warn(`Data for "${resultPath}" not found".`)
66
+ return
67
+ }
68
+ const result = totalMarketcapData[requestPayload.market.toLowerCase()]
69
+ if (!result) {
70
+ logger.warn(`Data for "${requestPayload.market}" not found".`)
71
+ return
72
+ }
73
+ const entry = {
74
+ params: requestPayload,
75
+ value: result,
76
+ } as ResultEntry
77
+ return entry
78
+ }
@@ -0,0 +1,17 @@
1
+ import { Adapter } from '../../../../src/adapter'
2
+ import overrides from './config/overrides.json'
3
+ import {
4
+ coins,
5
+ crypto,
6
+ cryptoVolume,
7
+ cryptoMarketcap,
8
+ dominance,
9
+ globalMarketcap,
10
+ } from './endpoint'
11
+
12
+ export const adapter: Adapter = {
13
+ defaultEndpoint: 'crypto',
14
+ name: 'coingecko',
15
+ endpoints: [crypto, coins, cryptoMarketcap, cryptoVolume, dominance, globalMarketcap],
16
+ overrides: (overrides as Record<string, Record<string, string>>)['coingecko'],
17
+ }