@chainlink/external-adapter-framework 0.0.14 → 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 (292) hide show
  1. package/.c8rc.json +3 -0
  2. package/.eslintignore +10 -0
  3. package/.eslintrc.js +96 -0
  4. package/.github/README.MD +42 -0
  5. package/.github/actions/setup/action.yaml +13 -0
  6. package/.github/workflows/label.yaml +39 -0
  7. package/.github/workflows/main.yaml +39 -0
  8. package/.github/workflows/publish.yaml +17 -0
  9. package/.prettierignore +13 -0
  10. package/.yarnrc +0 -0
  11. package/README.md +103 -0
  12. package/dist/examples/coingecko/test/e2e/adapter.test.ts.js +82953 -0
  13. package/dist/examples/coingecko/test/integration/adapter.test.ts.js +91672 -0
  14. package/dist/main.js +72703 -0
  15. package/docker-compose.yaml +35 -0
  16. package/env.sh +54 -0
  17. package/env2.sh +55 -0
  18. package/jest.config.js +5 -0
  19. package/package.json +14 -3
  20. package/publish.sh +0 -0
  21. package/src/adapter.ts +263 -0
  22. package/src/background-executor.ts +52 -0
  23. package/src/cache/factory.ts +26 -0
  24. package/src/cache/index.ts +258 -0
  25. package/src/cache/local.ts +73 -0
  26. package/src/cache/metrics.ts +112 -0
  27. package/src/cache/redis.ts +93 -0
  28. package/src/config/index.ts +517 -0
  29. package/src/config/provider-limits.ts +127 -0
  30. package/src/examples/bank-frick/README.MD +10 -0
  31. package/src/examples/bank-frick/accounts.ts +246 -0
  32. package/src/examples/bank-frick/config/index.ts +53 -0
  33. package/src/examples/bank-frick/index.ts +13 -0
  34. package/src/examples/bank-frick/types.d.ts +38 -0
  35. package/src/examples/bank-frick/util.ts +55 -0
  36. package/src/examples/coingecko/src/config/index.ts +12 -0
  37. package/src/examples/coingecko/src/config/overrides.json +10826 -0
  38. package/src/examples/coingecko/src/cryptoUtils.ts +88 -0
  39. package/src/examples/coingecko/src/endpoint/coins.ts +54 -0
  40. package/src/examples/coingecko/src/endpoint/crypto-marketcap.ts +66 -0
  41. package/src/examples/coingecko/src/endpoint/crypto-volume.ts +66 -0
  42. package/src/examples/coingecko/src/endpoint/crypto.ts +63 -0
  43. package/src/examples/coingecko/src/endpoint/dominance.ts +40 -0
  44. package/src/examples/coingecko/src/endpoint/global-marketcap.ts +40 -0
  45. package/src/examples/coingecko/src/endpoint/index.ts +6 -0
  46. package/src/examples/coingecko/src/globalUtils.ts +78 -0
  47. package/src/examples/coingecko/src/index.ts +17 -0
  48. package/src/examples/coingecko/test/e2e/adapter.test.ts +278 -0
  49. package/src/examples/coingecko/test/integration/__snapshots__/adapter.test.ts.snap +15 -0
  50. package/src/examples/coingecko/test/integration/adapter.test.ts +281 -0
  51. package/src/examples/coingecko/test/integration/capturedRequests.json +1 -0
  52. package/src/examples/coingecko/test/integration/fixtures.ts +42 -0
  53. package/src/examples/coingecko-old/batch-warming.ts +79 -0
  54. package/src/examples/coingecko-old/index.ts +9 -0
  55. package/src/examples/coingecko-old/rest.ts +77 -0
  56. package/src/examples/ncfx/config/index.ts +12 -0
  57. package/src/examples/ncfx/index.ts +9 -0
  58. package/src/examples/ncfx/websocket.ts +99 -0
  59. package/src/index.ts +149 -0
  60. package/src/metrics/constants.ts +23 -0
  61. package/src/metrics/index.ts +115 -0
  62. package/src/metrics/util.ts +18 -0
  63. package/src/rate-limiting/background/fixed-frequency.ts +45 -0
  64. package/src/rate-limiting/index.ts +100 -0
  65. package/src/rate-limiting/metrics.ts +18 -0
  66. package/src/rate-limiting/request/simple-counting.ts +76 -0
  67. package/src/transports/batch-warming.ts +127 -0
  68. package/src/transports/index.ts +152 -0
  69. package/src/transports/metrics.ts +95 -0
  70. package/src/transports/rest.ts +168 -0
  71. package/src/transports/util.ts +63 -0
  72. package/src/transports/websocket.ts +245 -0
  73. package/src/util/index.ts +23 -0
  74. package/src/util/logger.ts +69 -0
  75. package/src/util/recordRequests.ts +47 -0
  76. package/src/util/request.ts +117 -0
  77. package/src/util/subscription-set/expiring-sorted-set.ts +54 -0
  78. package/src/util/subscription-set/subscription-set.ts +35 -0
  79. package/src/util/test-payload-loader.ts +87 -0
  80. package/src/validation/error.ts +116 -0
  81. package/src/validation/index.ts +110 -0
  82. package/src/validation/input-params.ts +45 -0
  83. package/src/validation/override-functions.ts +44 -0
  84. package/src/validation/overrideFunctions.ts +44 -0
  85. package/src/validation/preset-tokens.json +23 -0
  86. package/src/validation/validator.ts +384 -0
  87. package/test/adapter.test.ts +27 -0
  88. package/test/background-executor.test.ts +108 -0
  89. package/test/cache/cache-key.test.ts +114 -0
  90. package/test/cache/helper.ts +100 -0
  91. package/test/cache/local.test.ts +54 -0
  92. package/test/cache/redis.test.ts +89 -0
  93. package/test/correlation.test.ts +114 -0
  94. package/test/index.test.ts +37 -0
  95. package/test/metrics/feed-id.test.ts +38 -0
  96. package/test/metrics/helper.ts +14 -0
  97. package/test/metrics/labels.test.ts +36 -0
  98. package/test/metrics/metrics.test.ts +267 -0
  99. package/test/metrics/redis-metrics.test.ts +113 -0
  100. package/test/metrics/warmer-metrics.test.ts +193 -0
  101. package/test/metrics/ws-metrics.test.ts +225 -0
  102. package/test/rate-limit-config.test.ts +242 -0
  103. package/test/smoke/smoke.test.ts +166 -0
  104. package/test/smoke/test-payload-fail.json +3 -0
  105. package/test/smoke/test-payload.js +22 -0
  106. package/test/smoke/test-payload.json +7 -0
  107. package/test/transports/batch.test.ts +466 -0
  108. package/test/transports/rest.test.ts +242 -0
  109. package/test/transports/websocket.test.ts +183 -0
  110. package/test/tsconfig.json +5 -0
  111. package/test/util.ts +77 -0
  112. package/test/validation.test.ts +178 -0
  113. package/test.sh +20 -0
  114. package/test2.sh +2 -0
  115. package/tsconfig.json +28 -0
  116. package/typedoc.json +6 -0
  117. package/webpack.config.js +57 -0
  118. package/yarn-error.log +3778 -0
  119. package/adapter.d.ts +0 -107
  120. package/adapter.js +0 -115
  121. package/background-executor.d.ts +0 -11
  122. package/background-executor.js +0 -45
  123. package/cache/factory.d.ts +0 -6
  124. package/cache/factory.js +0 -55
  125. package/cache/index.d.ts +0 -94
  126. package/cache/index.js +0 -173
  127. package/cache/local.d.ts +0 -23
  128. package/cache/local.js +0 -83
  129. package/cache/metrics.d.ts +0 -27
  130. package/cache/metrics.js +0 -120
  131. package/cache/redis.d.ts +0 -16
  132. package/cache/redis.js +0 -100
  133. package/chainlink-external-adapter-framework-0.0.6.tgz +0 -0
  134. package/config/index.d.ts +0 -209
  135. package/config/index.js +0 -380
  136. package/config/provider-limits.d.ts +0 -31
  137. package/config/provider-limits.js +0 -79
  138. package/examples/bank-frick/accounts.d.ts +0 -39
  139. package/examples/bank-frick/accounts.js +0 -191
  140. package/examples/bank-frick/config/index.d.ts +0 -4
  141. package/examples/bank-frick/config/index.js +0 -54
  142. package/examples/bank-frick/index.d.ts +0 -2
  143. package/examples/bank-frick/index.js +0 -14
  144. package/examples/bank-frick/util.d.ts +0 -4
  145. package/examples/bank-frick/util.js +0 -39
  146. package/examples/coingecko/batch-warming.d.ts +0 -2
  147. package/examples/coingecko/batch-warming.js +0 -52
  148. package/examples/coingecko/index.d.ts +0 -2
  149. package/examples/coingecko/index.js +0 -10
  150. package/examples/coingecko/rest.d.ts +0 -2
  151. package/examples/coingecko/rest.js +0 -50
  152. package/examples/ncfx/config/index.d.ts +0 -12
  153. package/examples/ncfx/config/index.js +0 -15
  154. package/examples/ncfx/index.d.ts +0 -2
  155. package/examples/ncfx/index.js +0 -10
  156. package/examples/ncfx/websocket.d.ts +0 -36
  157. package/examples/ncfx/websocket.js +0 -72
  158. package/index.d.ts +0 -11
  159. package/index.js +0 -133
  160. package/metrics/constants.d.ts +0 -16
  161. package/metrics/constants.js +0 -25
  162. package/metrics/index.d.ts +0 -15
  163. package/metrics/index.js +0 -122
  164. package/metrics/util.d.ts +0 -7
  165. package/metrics/util.js +0 -9
  166. package/package/adapter.d.ts +0 -88
  167. package/package/adapter.js +0 -112
  168. package/package/background-executor.d.ts +0 -11
  169. package/package/background-executor.js +0 -45
  170. package/package/cache/factory.d.ts +0 -6
  171. package/package/cache/factory.js +0 -57
  172. package/package/cache/index.d.ts +0 -90
  173. package/package/cache/index.js +0 -169
  174. package/package/cache/local.d.ts +0 -23
  175. package/package/cache/local.js +0 -83
  176. package/package/cache/metrics.d.ts +0 -27
  177. package/package/cache/metrics.js +0 -120
  178. package/package/cache/redis.d.ts +0 -16
  179. package/package/cache/redis.js +0 -100
  180. package/package/config/index.d.ts +0 -195
  181. package/package/config/index.js +0 -365
  182. package/package/config/provider-limits.d.ts +0 -31
  183. package/package/config/provider-limits.js +0 -76
  184. package/package/examples/coingecko/batch-warming.d.ts +0 -2
  185. package/package/examples/coingecko/batch-warming.js +0 -52
  186. package/package/examples/coingecko/index.d.ts +0 -2
  187. package/package/examples/coingecko/index.js +0 -10
  188. package/package/examples/coingecko/rest.d.ts +0 -2
  189. package/package/examples/coingecko/rest.js +0 -50
  190. package/package/examples/ncfx/config/index.d.ts +0 -12
  191. package/package/examples/ncfx/config/index.js +0 -15
  192. package/package/examples/ncfx/index.d.ts +0 -2
  193. package/package/examples/ncfx/index.js +0 -10
  194. package/package/examples/ncfx/websocket.d.ts +0 -36
  195. package/package/examples/ncfx/websocket.js +0 -72
  196. package/package/index.d.ts +0 -12
  197. package/package/index.js +0 -92
  198. package/package/metrics/constants.d.ts +0 -16
  199. package/package/metrics/constants.js +0 -25
  200. package/package/metrics/index.d.ts +0 -15
  201. package/package/metrics/index.js +0 -123
  202. package/package/metrics/util.d.ts +0 -3
  203. package/package/metrics/util.js +0 -9
  204. package/package/package.json +0 -72
  205. package/package/rate-limiting/background/fixed-frequency.d.ts +0 -10
  206. package/package/rate-limiting/background/fixed-frequency.js +0 -37
  207. package/package/rate-limiting/index.d.ts +0 -54
  208. package/package/rate-limiting/index.js +0 -63
  209. package/package/rate-limiting/metrics.d.ts +0 -3
  210. package/package/rate-limiting/metrics.js +0 -44
  211. package/package/rate-limiting/request/simple-counting.d.ts +0 -20
  212. package/package/rate-limiting/request/simple-counting.js +0 -62
  213. package/package/test.d.ts +0 -1
  214. package/package/test.js +0 -6
  215. package/package/transports/batch-warming.d.ts +0 -34
  216. package/package/transports/batch-warming.js +0 -101
  217. package/package/transports/index.d.ts +0 -87
  218. package/package/transports/index.js +0 -87
  219. package/package/transports/metrics.d.ts +0 -21
  220. package/package/transports/metrics.js +0 -105
  221. package/package/transports/rest.d.ts +0 -43
  222. package/package/transports/rest.js +0 -129
  223. package/package/transports/util.d.ts +0 -8
  224. package/package/transports/util.js +0 -85
  225. package/package/transports/websocket.d.ts +0 -80
  226. package/package/transports/websocket.js +0 -169
  227. package/package/util/expiring-sorted-set.d.ts +0 -21
  228. package/package/util/expiring-sorted-set.js +0 -47
  229. package/package/util/index.d.ts +0 -11
  230. package/package/util/index.js +0 -35
  231. package/package/util/logger.d.ts +0 -42
  232. package/package/util/logger.js +0 -62
  233. package/package/util/request.d.ts +0 -55
  234. package/package/util/request.js +0 -2
  235. package/package/validation/error.d.ts +0 -50
  236. package/package/validation/error.js +0 -79
  237. package/package/validation/index.d.ts +0 -5
  238. package/package/validation/index.js +0 -86
  239. package/package/validation/input-params.d.ts +0 -15
  240. package/package/validation/input-params.js +0 -30
  241. package/package/validation/override-functions.d.ts +0 -3
  242. package/package/validation/override-functions.js +0 -40
  243. package/package/validation/preset-tokens.json +0 -23
  244. package/package/validation/validator.d.ts +0 -47
  245. package/package/validation/validator.js +0 -303
  246. package/rate-limiting/background/fixed-frequency.d.ts +0 -10
  247. package/rate-limiting/background/fixed-frequency.js +0 -35
  248. package/rate-limiting/index.d.ts +0 -54
  249. package/rate-limiting/index.js +0 -63
  250. package/rate-limiting/metrics.d.ts +0 -3
  251. package/rate-limiting/metrics.js +0 -44
  252. package/rate-limiting/request/simple-counting.d.ts +0 -20
  253. package/rate-limiting/request/simple-counting.js +0 -62
  254. package/test.d.ts +0 -1
  255. package/test.js +0 -6
  256. package/transports/batch-warming.d.ts +0 -35
  257. package/transports/batch-warming.js +0 -101
  258. package/transports/index.d.ts +0 -70
  259. package/transports/index.js +0 -87
  260. package/transports/metrics.d.ts +0 -21
  261. package/transports/metrics.js +0 -105
  262. package/transports/rest.d.ts +0 -44
  263. package/transports/rest.js +0 -131
  264. package/transports/util.d.ts +0 -8
  265. package/transports/util.js +0 -85
  266. package/transports/websocket.d.ts +0 -81
  267. package/transports/websocket.js +0 -168
  268. package/util/expiring-sorted-set.d.ts +0 -21
  269. package/util/expiring-sorted-set.js +0 -47
  270. package/util/index.d.ts +0 -12
  271. package/util/index.js +0 -35
  272. package/util/logger.d.ts +0 -42
  273. package/util/logger.js +0 -62
  274. package/util/request.d.ts +0 -57
  275. package/util/request.js +0 -2
  276. package/util/subscription-set/expiring-sorted-set.d.ts +0 -22
  277. package/util/subscription-set/expiring-sorted-set.js +0 -47
  278. package/util/subscription-set/subscription-set.d.ts +0 -18
  279. package/util/subscription-set/subscription-set.js +0 -19
  280. package/util/test-payload-loader.d.ts +0 -25
  281. package/util/test-payload-loader.js +0 -83
  282. package/validation/error.d.ts +0 -50
  283. package/validation/error.js +0 -79
  284. package/validation/index.d.ts +0 -5
  285. package/validation/index.js +0 -91
  286. package/validation/input-params.d.ts +0 -15
  287. package/validation/input-params.js +0 -30
  288. package/validation/override-functions.d.ts +0 -3
  289. package/validation/override-functions.js +0 -40
  290. package/validation/preset-tokens.json +0 -23
  291. package/validation/validator.d.ts +0 -47
  292. package/validation/validator.js +0 -303
@@ -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
+ }