@chainlink/external-adapter-framework 0.5.0 → 0.5.2

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 (192) hide show
  1. package/adapter/basic.d.ts +90 -0
  2. package/adapter/basic.js +325 -0
  3. package/adapter/basic.js.map +1 -0
  4. package/adapter/endpoint.d.ts +17 -0
  5. package/adapter/endpoint.js +20 -0
  6. package/adapter/endpoint.js.map +1 -0
  7. package/adapter/index.d.ts +4 -0
  8. package/adapter/index.js +21 -0
  9. package/adapter/index.js.map +1 -0
  10. package/adapter/price.d.ts +77 -0
  11. package/adapter/price.js +88 -0
  12. package/adapter/price.js.map +1 -0
  13. package/adapter/types.d.ts +124 -0
  14. package/adapter/types.js +3 -0
  15. package/adapter/types.js.map +1 -0
  16. package/background-executor.d.ts +9 -0
  17. package/background-executor.js +97 -0
  18. package/background-executor.js.map +1 -0
  19. package/cache/factory.d.ts +6 -0
  20. package/cache/factory.js +24 -0
  21. package/cache/factory.js.map +1 -0
  22. package/cache/index.d.ts +87 -0
  23. package/cache/index.js +133 -0
  24. package/cache/index.js.map +1 -0
  25. package/cache/local.d.ts +23 -0
  26. package/cache/local.js +84 -0
  27. package/cache/local.js.map +1 -0
  28. package/cache/metrics.d.ts +27 -0
  29. package/cache/metrics.js +121 -0
  30. package/cache/metrics.js.map +1 -0
  31. package/cache/redis.d.ts +16 -0
  32. package/cache/redis.js +101 -0
  33. package/cache/redis.js.map +1 -0
  34. package/config/index.d.ts +298 -0
  35. package/config/index.js +359 -0
  36. package/config/index.js.map +1 -0
  37. package/config/provider-limits.d.ts +27 -0
  38. package/config/provider-limits.js +75 -0
  39. package/config/provider-limits.js.map +1 -0
  40. package/examples/bank-frick/accounts.d.ts +45 -0
  41. package/examples/bank-frick/accounts.js +203 -0
  42. package/examples/bank-frick/accounts.js.map +1 -0
  43. package/examples/bank-frick/config/index.d.ts +17 -0
  44. package/examples/bank-frick/config/index.js +55 -0
  45. package/examples/bank-frick/config/index.js.map +1 -0
  46. package/examples/bank-frick/index.d.ts +2 -0
  47. package/examples/bank-frick/index.js +16 -0
  48. package/examples/bank-frick/index.js.map +1 -0
  49. package/examples/bank-frick/util.d.ts +4 -0
  50. package/examples/bank-frick/util.js +40 -0
  51. package/examples/bank-frick/util.js.map +1 -0
  52. package/examples/coingecko/src/config/index.d.ts +2 -0
  53. package/examples/coingecko/src/config/index.js +6 -0
  54. package/examples/coingecko/src/config/index.js.map +1 -0
  55. package/examples/coingecko/src/config/overrides.json +10825 -0
  56. package/examples/coingecko/src/crypto-utils.d.ts +62 -0
  57. package/examples/coingecko/src/crypto-utils.js +60 -0
  58. package/examples/coingecko/src/crypto-utils.js.map +1 -0
  59. package/examples/coingecko/src/endpoint/coins.d.ts +26 -0
  60. package/examples/coingecko/src/endpoint/coins.js +37 -0
  61. package/examples/coingecko/src/endpoint/coins.js.map +1 -0
  62. package/examples/coingecko/src/endpoint/crypto-marketcap.d.ts +3 -0
  63. package/examples/coingecko/src/endpoint/crypto-marketcap.js +30 -0
  64. package/examples/coingecko/src/endpoint/crypto-marketcap.js.map +1 -0
  65. package/examples/coingecko/src/endpoint/crypto-volume.d.ts +3 -0
  66. package/examples/coingecko/src/endpoint/crypto-volume.js +30 -0
  67. package/examples/coingecko/src/endpoint/crypto-volume.js.map +1 -0
  68. package/examples/coingecko/src/endpoint/crypto.d.ts +3 -0
  69. package/examples/coingecko/src/endpoint/crypto.js +28 -0
  70. package/examples/coingecko/src/endpoint/crypto.js.map +1 -0
  71. package/examples/coingecko/src/endpoint/dominance.d.ts +3 -0
  72. package/examples/coingecko/src/endpoint/dominance.js +28 -0
  73. package/examples/coingecko/src/endpoint/dominance.js.map +1 -0
  74. package/examples/coingecko/src/endpoint/global-marketcap.d.ts +3 -0
  75. package/examples/coingecko/src/endpoint/global-marketcap.js +28 -0
  76. package/examples/coingecko/src/endpoint/global-marketcap.js.map +1 -0
  77. package/examples/coingecko/src/endpoint/index.d.ts +6 -0
  78. package/examples/coingecko/src/endpoint/index.js +16 -0
  79. package/examples/coingecko/src/endpoint/index.js.map +1 -0
  80. package/examples/coingecko/src/global-utils.d.ts +42 -0
  81. package/examples/coingecko/src/global-utils.js +47 -0
  82. package/examples/coingecko/src/global-utils.js.map +1 -0
  83. package/examples/coingecko/src/index.d.ts +4 -0
  84. package/examples/coingecko/src/index.js +19 -0
  85. package/examples/coingecko/src/index.js.map +1 -0
  86. package/examples/cryptocompare/src/config/index.d.ts +2 -0
  87. package/examples/cryptocompare/src/config/index.js +6 -0
  88. package/examples/cryptocompare/src/config/index.js.map +1 -0
  89. package/examples/cryptocompare/src/endpoints/crypto.d.ts +40 -0
  90. package/examples/cryptocompare/src/endpoints/crypto.js +54 -0
  91. package/examples/cryptocompare/src/endpoints/crypto.js.map +1 -0
  92. package/examples/cryptocompare/src/endpoints/index.d.ts +1 -0
  93. package/examples/cryptocompare/src/endpoints/index.js +6 -0
  94. package/examples/cryptocompare/src/endpoints/index.js.map +1 -0
  95. package/examples/cryptocompare/src/index.d.ts +4 -0
  96. package/examples/cryptocompare/src/index.js +14 -0
  97. package/examples/cryptocompare/src/index.js.map +1 -0
  98. package/examples/genesis/config/index.d.ts +7 -0
  99. package/examples/genesis/config/index.js +11 -0
  100. package/examples/genesis/config/index.js.map +1 -0
  101. package/examples/genesis/index.d.ts +2 -0
  102. package/examples/genesis/index.js +13 -0
  103. package/examples/genesis/index.js.map +1 -0
  104. package/examples/genesis/sseStream.d.ts +27 -0
  105. package/examples/genesis/sseStream.js +149 -0
  106. package/examples/genesis/sseStream.js.map +1 -0
  107. package/index.d.ts +17 -0
  108. package/index.js +174 -0
  109. package/index.js.map +1 -0
  110. package/metrics/constants.d.ts +16 -0
  111. package/metrics/constants.js +26 -0
  112. package/metrics/constants.js.map +1 -0
  113. package/metrics/index.d.ts +19 -0
  114. package/metrics/index.js +139 -0
  115. package/metrics/index.js.map +1 -0
  116. package/metrics/util.d.ts +7 -0
  117. package/metrics/util.js +10 -0
  118. package/metrics/util.js.map +1 -0
  119. package/package.json +50 -42
  120. package/rate-limiting/background/fixed-frequency.d.ts +10 -0
  121. package/rate-limiting/background/fixed-frequency.js +36 -0
  122. package/rate-limiting/background/fixed-frequency.js.map +1 -0
  123. package/rate-limiting/index.d.ts +56 -0
  124. package/rate-limiting/index.js +86 -0
  125. package/rate-limiting/index.js.map +1 -0
  126. package/rate-limiting/metrics.d.ts +3 -0
  127. package/rate-limiting/metrics.js +45 -0
  128. package/rate-limiting/metrics.js.map +1 -0
  129. package/rate-limiting/request/simple-counting.d.ts +20 -0
  130. package/rate-limiting/request/simple-counting.js +63 -0
  131. package/rate-limiting/request/simple-counting.js.map +1 -0
  132. package/transports/batch-warming.d.ts +53 -0
  133. package/transports/batch-warming.js +136 -0
  134. package/transports/batch-warming.js.map +1 -0
  135. package/transports/index.d.ts +108 -0
  136. package/transports/index.js +56 -0
  137. package/transports/index.js.map +1 -0
  138. package/transports/metrics.d.ts +25 -0
  139. package/transports/metrics.js +122 -0
  140. package/transports/metrics.js.map +1 -0
  141. package/transports/rest.d.ts +68 -0
  142. package/transports/rest.js +131 -0
  143. package/transports/rest.js.map +1 -0
  144. package/transports/routing.d.ts +21 -0
  145. package/transports/routing.js +50 -0
  146. package/transports/routing.js.map +1 -0
  147. package/transports/sse.d.ts +61 -0
  148. package/transports/sse.js +97 -0
  149. package/transports/sse.js.map +1 -0
  150. package/transports/util.d.ts +9 -0
  151. package/transports/util.js +87 -0
  152. package/transports/util.js.map +1 -0
  153. package/transports/websocket.d.ts +95 -0
  154. package/transports/websocket.js +164 -0
  155. package/transports/websocket.js.map +1 -0
  156. package/util/censor/censor-list.d.ts +9 -0
  157. package/util/censor/censor-list.js +13 -0
  158. package/util/censor/censor-list.js.map +1 -0
  159. package/util/index.d.ts +13 -0
  160. package/util/index.js +38 -0
  161. package/util/index.js.map +1 -0
  162. package/util/logger.d.ts +49 -0
  163. package/util/logger.js +123 -0
  164. package/util/logger.js.map +1 -0
  165. package/util/request.d.ts +138 -0
  166. package/util/request.js +3 -0
  167. package/util/request.js.map +1 -0
  168. package/util/subscription-set/expiring-sorted-set.d.ts +21 -0
  169. package/util/subscription-set/expiring-sorted-set.js +36 -0
  170. package/util/subscription-set/expiring-sorted-set.js.map +1 -0
  171. package/util/subscription-set/redis-sorted-set.d.ts +9 -0
  172. package/util/subscription-set/redis-sorted-set.js +29 -0
  173. package/util/subscription-set/redis-sorted-set.js.map +1 -0
  174. package/util/subscription-set/subscription-set.d.ts +19 -0
  175. package/util/subscription-set/subscription-set.js +28 -0
  176. package/util/subscription-set/subscription-set.js.map +1 -0
  177. package/util/test-payload-loader.d.ts +26 -0
  178. package/util/test-payload-loader.js +85 -0
  179. package/util/test-payload-loader.js.map +1 -0
  180. package/validation/error.d.ts +48 -0
  181. package/validation/error.js +78 -0
  182. package/validation/error.js.map +1 -0
  183. package/validation/index.d.ts +5 -0
  184. package/validation/index.js +102 -0
  185. package/validation/index.js.map +1 -0
  186. package/validation/input-params.d.ts +14 -0
  187. package/validation/input-params.js +3 -0
  188. package/validation/input-params.js.map +1 -0
  189. package/validation/input-validator.d.ts +16 -0
  190. package/validation/input-validator.js +123 -0
  191. package/validation/input-validator.js.map +1 -0
  192. package/README.md +0 -102
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.endpoint = exports.transport = void 0;
4
+ const adapter_1 = require("../../../../adapter");
5
+ const websocket_1 = require("../../../../transports/websocket");
6
+ const util_1 = require("../../../../util");
7
+ const config_1 = require("../config");
8
+ const logger = (0, util_1.makeLogger)('CryptoCompareCryptoEndpoint');
9
+ exports.transport = new websocket_1.WebSocketTransport({
10
+ url: (context) => `${config_1.DEFAULT_WS_API_ENDPOINT}?api_key=${context.adapterConfig.API_KEY}`,
11
+ handlers: {
12
+ open(connection) {
13
+ return new Promise((resolve, reject) => {
14
+ // Set up listener
15
+ connection.on('message', (data) => {
16
+ const parsed = JSON.parse(data.toString());
17
+ if (parsed.MESSAGE === 'STREAMERWELCOME') {
18
+ logger.info('Got logged in response, connection is ready');
19
+ resolve();
20
+ }
21
+ else {
22
+ reject(new Error('Unexpected message after WS connection open'));
23
+ }
24
+ });
25
+ });
26
+ },
27
+ message(message) {
28
+ logger.trace(message, 'Got response from websocket');
29
+ if (message.TYPE === '5') {
30
+ return [
31
+ { params: { base: message.FROMSYMBOL, quote: message.TOSYMBOL }, value: message.PRICE },
32
+ ];
33
+ }
34
+ if (message.MESSAGE === 'INVALID_SUB') {
35
+ logger.error(message, 'asset not supported by data provider');
36
+ return;
37
+ }
38
+ },
39
+ },
40
+ builders: {
41
+ subscribeMessage: (params) => {
42
+ return { action: 'SubAdd', subs: [`5~CCCAGG~${`${params.base}~${params.quote}`}`] };
43
+ },
44
+ unsubscribeMessage: (params) => {
45
+ return { action: 'SubRemove', subs: [`5~CCCAGG~${`${params.base}~${params.quote}`}`] };
46
+ },
47
+ },
48
+ });
49
+ exports.endpoint = new adapter_1.PriceEndpoint({
50
+ name: 'crypto',
51
+ transport: exports.transport,
52
+ inputParameters: adapter_1.priceEndpointInputParameters,
53
+ });
54
+ //# sourceMappingURL=crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../../../../../src/examples/cryptocompare/src/endpoints/crypto.ts"],"names":[],"mappings":";;;AACA,iDAAiF;AAEjF,gEAAqE;AACrE,2CAAyF;AACzF,sCAAmD;AAuCnD,MAAM,MAAM,GAAG,IAAA,iBAAU,EAAC,6BAA6B,CAAC,CAAA;AAE3C,QAAA,SAAS,GAAG,IAAI,8BAAkB,CAAsB;IACnE,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,gCAAuB,YAAY,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE;IACvF,QAAQ,EAAE;QACR,IAAI,CAAC,UAAqB;YACxB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACrC,kBAAkB;gBAClB,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAa,EAAE,EAAE;oBACzC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAA;oBAC1C,IAAI,MAAM,CAAC,OAAO,KAAK,iBAAiB,EAAE;wBACxC,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAA;wBAC1D,OAAO,EAAE,CAAA;qBACV;yBAAM;wBACL,MAAM,CAAC,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC,CAAA;qBACjE;gBACH,CAAC,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,OAAO,CAAC,OAAgB;YACtB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,6BAA6B,CAAC,CAAA;YACpD,IAAI,OAAO,CAAC,IAAI,KAAK,GAAG,EAAE;gBACxB,OAAO;oBACL,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE;iBACxF,CAAA;aACF;YACD,IAAI,OAAO,CAAC,OAAO,KAAK,aAAa,EAAE;gBACrC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,sCAAsC,CAAC,CAAA;gBAC7D,OAAM;aACP;QACH,CAAC;KACF;IACD,QAAQ,EAAE;QACR,gBAAgB,EAAE,CAAC,MAA4B,EAAE,EAAE;YACjD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,YAAY,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,CAAA;QACrF,CAAC;QACD,kBAAkB,EAAE,CAAC,MAA4B,EAAE,EAAE;YACnD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,YAAY,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,CAAA;QACxF,CAAC;KACF;CACF,CAAC,CAAA;AAEW,QAAA,QAAQ,GAAG,IAAI,uBAAa,CAAC;IACxC,IAAI,EAAE,QAAQ;IACd,SAAS,EAAT,iBAAS;IACT,eAAe,EAAE,sCAA4B;CAC9C,CAAC,CAAA"}
@@ -0,0 +1 @@
1
+ export { endpoint as cryptoEndpoint } from './crypto';
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cryptoEndpoint = void 0;
4
+ var crypto_1 = require("./crypto");
5
+ Object.defineProperty(exports, "cryptoEndpoint", { enumerable: true, get: function () { return crypto_1.endpoint; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/examples/cryptocompare/src/endpoints/index.ts"],"names":[],"mappings":";;;AAAA,mCAAqD;AAA5C,wGAAA,QAAQ,OAAkB"}
@@ -0,0 +1,4 @@
1
+ /// <reference types="node" />
2
+ import { PriceAdapter } from '../../../../src/adapter';
3
+ export declare const adapter: PriceAdapter<import("../../../config").SettingsMap>;
4
+ export declare const server: () => Promise<import("fastify/types/instance").FastifyInstance<import("fastify").RawServerDefault, import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>, import("fastify").FastifyBaseLogger, import("fastify").FastifyTypeProviderDefault> | undefined>;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.server = exports.adapter = void 0;
4
+ const __1 = require("../../..");
5
+ const adapter_1 = require("../../../../src/adapter");
6
+ const endpoints_1 = require("./endpoints");
7
+ exports.adapter = new adapter_1.PriceAdapter({
8
+ name: 'CRYPTOCOMPARE',
9
+ defaultEndpoint: 'crypto',
10
+ endpoints: [endpoints_1.cryptoEndpoint],
11
+ });
12
+ const server = () => (0, __1.expose)(exports.adapter);
13
+ exports.server = server;
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/examples/cryptocompare/src/index.ts"],"names":[],"mappings":";;;AAAA,gCAAiC;AACjC,qDAAsD;AACtD,2CAA4C;AAE/B,QAAA,OAAO,GAAG,IAAI,sBAAY,CAAC;IACtC,IAAI,EAAE,eAAe;IACrB,eAAe,EAAE,QAAQ;IACzB,SAAS,EAAE,CAAC,0BAAc,CAAC;CAC5B,CAAC,CAAA;AAEK,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,IAAA,UAAM,EAAC,eAAO,CAAC,CAAA;AAA9B,QAAA,MAAM,UAAwB"}
@@ -0,0 +1,7 @@
1
+ export declare const customSettings: {
2
+ readonly API_SECRET: {
3
+ readonly description: "API secret";
4
+ readonly type: "string";
5
+ readonly required: true;
6
+ };
7
+ };
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.customSettings = void 0;
4
+ exports.customSettings = {
5
+ API_SECRET: {
6
+ description: 'API secret',
7
+ type: 'string',
8
+ required: true,
9
+ },
10
+ };
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/examples/genesis/config/index.ts"],"names":[],"mappings":";;;AAAa,QAAA,cAAc,GAAG;IAC5B,UAAU,EAAE;QACV,WAAW,EAAE,YAAY;QACzB,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,IAAI;KACf;CACO,CAAA"}
@@ -0,0 +1,2 @@
1
+ import { Adapter } from '../../adapter';
2
+ export declare const adapter: Adapter<import("../../config").SettingsMap>;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.adapter = void 0;
4
+ const adapter_1 = require("../../adapter");
5
+ const sseStream_1 = require("./sseStream");
6
+ const config_1 = require("./config");
7
+ exports.adapter = new adapter_1.Adapter({
8
+ name: 'GENESIS',
9
+ defaultEndpoint: sseStream_1.sseEndpoint.name,
10
+ endpoints: [sseStream_1.sseEndpoint],
11
+ customSettings: config_1.customSettings,
12
+ });
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/examples/genesis/index.ts"],"names":[],"mappings":";;;AAAA,2CAAuC;AACvC,2CAAyC;AACzC,qCAAyC;AAE5B,QAAA,OAAO,GAAG,IAAI,iBAAO,CAAC;IACjC,IAAI,EAAE,SAAS;IACf,eAAe,EAAE,uBAAW,CAAC,IAAI;IACjC,SAAS,EAAE,CAAC,uBAAW,CAAC;IACxB,cAAc,EAAd,uBAAc;CACf,CAAC,CAAA"}
@@ -0,0 +1,27 @@
1
+ import { AdapterEndpoint } from '../../adapter';
2
+ import { SSETransport } from '../../transports';
3
+ import { SingleNumberResultResponse } from '../../util';
4
+ import { InputParameters } from '../../validation';
5
+ import { SettingsMap } from '../../config';
6
+ interface AdapterRequestParams {
7
+ base: string;
8
+ quote: string;
9
+ }
10
+ export declare const inputParameters: InputParameters;
11
+ declare type Price = number;
12
+ declare type Quantity = number;
13
+ export declare type Entry = ['BUY' | 'SELL' | '', Price, Quantity];
14
+ declare type StreamEndpointTypes = {
15
+ Request: {
16
+ Params: AdapterRequestParams;
17
+ };
18
+ Response: SingleNumberResultResponse;
19
+ CustomSettings: SettingsMap;
20
+ Provider: {
21
+ RequestBody: never;
22
+ };
23
+ };
24
+ export declare const sseTransport: SSETransport<StreamEndpointTypes>;
25
+ export declare const calculateQWAPprice: (entries: Entry[]) => number | undefined;
26
+ export declare const sseEndpoint: AdapterEndpoint<StreamEndpointTypes>;
27
+ export {};
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.sseEndpoint = exports.calculateQWAPprice = exports.sseTransport = exports.inputParameters = void 0;
7
+ const crypto_1 = __importDefault(require("crypto"));
8
+ const adapter_1 = require("../../adapter");
9
+ const transports_1 = require("../../transports");
10
+ const util_1 = require("../../util");
11
+ const DEFAULT_ENDPOINT = 'https://api.genesistrading.com';
12
+ exports.inputParameters = {
13
+ base: {
14
+ aliases: ['from', 'coin'],
15
+ description: 'The symbol of the currency to query',
16
+ required: true,
17
+ },
18
+ quote: {
19
+ aliases: ['to', 'market'],
20
+ description: 'The symbol of the currency to convert to',
21
+ required: true,
22
+ },
23
+ };
24
+ const logger = (0, util_1.makeLogger)('GenesisSSETransport');
25
+ exports.sseTransport = new transports_1.SSETransport({
26
+ prepareSSEConnectionConfig: (params, context) => {
27
+ const payload = 'null';
28
+ const url = prepareRequestUrl(context.adapterConfig, 'sseStream', payload);
29
+ logger.debug('SSE Connection URL: ', url);
30
+ return { url };
31
+ },
32
+ prepareKeepAliveRequest: (context) => {
33
+ const payload = 'null';
34
+ const url = prepareRequestUrl(context.adapterConfig, 'ping', payload);
35
+ const axiosRequestConfig = {
36
+ method: 'POST',
37
+ url,
38
+ };
39
+ logger.debug('Keep Alive URL: ', url);
40
+ return axiosRequestConfig;
41
+ },
42
+ prepareSubscriptionRequest: (params, context) => {
43
+ const requestedSymbols = params.map((p) => {
44
+ return `${p.base.toUpperCase()}-${p.quote.toUpperCase()}`;
45
+ });
46
+ const payloadObj = {
47
+ Action: 'SUBSCRIBE',
48
+ Symbols: requestedSymbols,
49
+ };
50
+ const url = prepareRequestUrl(context.adapterConfig, 'marketDataRequest', JSON.stringify(payloadObj));
51
+ logger.debug('Subscribe URL: ', url);
52
+ const axiosConfig = {
53
+ method: 'POST',
54
+ url,
55
+ };
56
+ return axiosConfig;
57
+ },
58
+ prepareUnsubscriptionRequest: (params, context) => {
59
+ const requestedSymbols = params.map((p) => {
60
+ return `${p.base.toUpperCase()}-${p.quote.toUpperCase()}`;
61
+ });
62
+ const payloadObj = {
63
+ Action: 'UNSUBSCRIBE',
64
+ Symbols: requestedSymbols,
65
+ };
66
+ const url = prepareRequestUrl(context.adapterConfig, 'marketDataRequest', JSON.stringify(payloadObj));
67
+ logger.debug('Unsubscribe URL: ', url);
68
+ const axiosConfig = {
69
+ method: 'POST',
70
+ url,
71
+ };
72
+ return axiosConfig;
73
+ },
74
+ eventListeners: [
75
+ {
76
+ type: 'L2Update',
77
+ parseResponse: (evt) => {
78
+ let providerData = {};
79
+ try {
80
+ // To parse, add the formatting to interperate as a JSON array.
81
+ providerData = JSON.parse(evt.data);
82
+ }
83
+ catch (error) {
84
+ logger.error(error, `Error parsing JSON from data provider`);
85
+ }
86
+ const entries = providerData.Changes.map((e) => e.Entry);
87
+ const value = (0, exports.calculateQWAPprice)(entries);
88
+ if (value) {
89
+ const [base, quote] = providerData.Symbol.split('-');
90
+ return [
91
+ {
92
+ params: { base, quote },
93
+ value,
94
+ },
95
+ ];
96
+ }
97
+ return [];
98
+ },
99
+ },
100
+ ],
101
+ });
102
+ const calculateQWAPprice = (entries) => {
103
+ const meanPriceByQuantity = {};
104
+ // Group orders by quantity
105
+ let totalQuantity = 0;
106
+ entries.forEach((e) => {
107
+ if (e[2] === 0) {
108
+ return;
109
+ }
110
+ if (!meanPriceByQuantity[e[2].toString()]) {
111
+ meanPriceByQuantity[e[2].toString()] = [e[1], NaN];
112
+ }
113
+ else {
114
+ const meanPrice = (e[1] + meanPriceByQuantity[e[2].toString()][0]) / 2;
115
+ meanPriceByQuantity[e[2].toString()] = [meanPrice, meanPrice * e[2]];
116
+ totalQuantity += e[2];
117
+ }
118
+ });
119
+ if (Object.keys(meanPriceByQuantity).length === 0) {
120
+ return;
121
+ }
122
+ const priceTimesQuantitySum = Object.values(meanPriceByQuantity).reduce((e1, e2) => [
123
+ NaN,
124
+ e1[1] + e2[1],
125
+ ])[1];
126
+ // Return a sum of all the products divided by the total quantity
127
+ return priceTimesQuantitySum / totalQuantity;
128
+ };
129
+ exports.calculateQWAPprice = calculateQWAPprice;
130
+ const prepareRequestUrl = (config, endpoint, payload) => {
131
+ const apiKey = config.API_KEY;
132
+ if (!apiKey) {
133
+ logger.error(new Error('API_KEY not set'), 'Set the API_KEY configuration variable to a valid Genesis API key');
134
+ }
135
+ const apiSecret = config.API_SECRET;
136
+ const nonce = (BigInt(Date.now()) * BigInt('1000000')).toString();
137
+ const hash = crypto_1.default.createHmac('sha384', Buffer.from(apiSecret ?? ''));
138
+ const data = hash.update(Buffer.from(apiKey + payload + nonce));
139
+ const sig = data.digest().toString('hex');
140
+ const baseUrl = config.API_ENDPOINT ?? DEFAULT_ENDPOINT;
141
+ const subDir = `${endpoint}?APIKEY=${apiKey}&PAYLOAD=${payload}&NONCE=${nonce}&SIGNATURE=${sig}`;
142
+ return new URL(subDir, baseUrl).toString();
143
+ };
144
+ exports.sseEndpoint = new adapter_1.AdapterEndpoint({
145
+ name: 'sseStream',
146
+ transport: exports.sseTransport,
147
+ inputParameters: exports.inputParameters,
148
+ });
149
+ //# sourceMappingURL=sseStream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sseStream.js","sourceRoot":"","sources":["../../../../src/examples/genesis/sseStream.ts"],"names":[],"mappings":"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"}
package/index.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * `prom-client` is shared between v2 and v3 when both are dependencies, resulting in metric collision errors
3
+ * Clearing metrics on import will wipe v2's existing register so we can replace them with v3's metrics
4
+ * METRICS_ENABLED=false is used to trigger this behavior because generators in the monorepo (where v2 and v3 are dependencies) tend to set it to false.
5
+ */
6
+ import { FastifyInstance } from 'fastify';
7
+ import { Adapter, AdapterDependencies } from './adapter';
8
+ export { FastifyInstance as ServerInstance };
9
+ /**
10
+ * Main function for the framework.
11
+ * Initializes config and dependencies, uses those to initialize Transports, and starts listening for requests.
12
+ *
13
+ * @param adapter - an object describing an External Adapter
14
+ * @param dependencies - an optional object with adapter dependencies to inject
15
+ * @returns a Promise that resolves to the http.Server listening for connections
16
+ */
17
+ export declare const expose: (adapter: Adapter, dependencies?: Partial<AdapterDependencies>) => Promise<FastifyInstance | undefined>;
package/index.js ADDED
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ /**
3
+ * `prom-client` is shared between v2 and v3 when both are dependencies, resulting in metric collision errors
4
+ * Clearing metrics on import will wipe v2's existing register so we can replace them with v3's metrics
5
+ * METRICS_ENABLED=false is used to trigger this behavior because generators in the monorepo (where v2 and v3 are dependencies) tend to set it to false.
6
+ */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || function (mod) {
24
+ if (mod && mod.__esModule) return mod;
25
+ var result = {};
26
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
27
+ __setModuleDefault(result, mod);
28
+ return result;
29
+ };
30
+ var __importDefault = (this && this.__importDefault) || function (mod) {
31
+ return (mod && mod.__esModule) ? mod : { "default": mod };
32
+ };
33
+ Object.defineProperty(exports, "__esModule", { value: true });
34
+ exports.expose = void 0;
35
+ const client = __importStar(require("prom-client"));
36
+ // , so when it's false, we can clear any metrics before reg
37
+ if (process.env['METRICS_ENABLED'] === 'false') {
38
+ client.register.clear();
39
+ }
40
+ const fastify_1 = __importDefault(require("fastify"));
41
+ const path_1 = require("path");
42
+ const adapter_1 = require("./adapter");
43
+ const background_executor_1 = require("./background-executor");
44
+ const metrics_1 = require("./metrics");
45
+ const util_1 = require("./util");
46
+ const test_payload_loader_1 = require("./util/test-payload-loader");
47
+ const validation_1 = require("./validation");
48
+ const logger = (0, util_1.makeLogger)('Main');
49
+ const VERSION = process.env['npm_package_version'];
50
+ /**
51
+ * Main function for the framework.
52
+ * Initializes config and dependencies, uses those to initialize Transports, and starts listening for requests.
53
+ *
54
+ * @param adapter - an object describing an External Adapter
55
+ * @param dependencies - an optional object with adapter dependencies to inject
56
+ * @returns a Promise that resolves to the http.Server listening for connections
57
+ */
58
+ const expose = async (adapter, dependencies) => {
59
+ if (!(adapter instanceof adapter_1.Adapter)) {
60
+ throw new Error('The adapter has not been initialized as an instance of the Adapter class, exiting.');
61
+ }
62
+ // Initialize adapter (create dependencies, inject them, build endpoint map, etc.)
63
+ await adapter.initialize(dependencies);
64
+ let api = undefined;
65
+ if (adapter.config.METRICS_ENABLED && adapter.config.EXPERIMENTAL_METRICS_ENABLED) {
66
+ (0, metrics_1.setupMetricsServer)(adapter.name, adapter.config);
67
+ }
68
+ // Optional Promise to indicate that the API is shutting down (for us to close background executors)
69
+ let apiShutdownPromise;
70
+ if (adapter.config.EA_MODE === 'reader' || adapter.config.EA_MODE === 'reader-writer') {
71
+ // Main REST API server to handle incoming requests
72
+ api = await buildRestApi(adapter);
73
+ // Add a hook on close to use on the background execution loop to stop it
74
+ apiShutdownPromise = new Promise((resolve) => {
75
+ api?.addHook('onClose', async () => resolve());
76
+ });
77
+ // Start listening for incoming requests
78
+ try {
79
+ await api.listen({
80
+ port: adapter.config.EA_PORT,
81
+ host: adapter.config.EA_HOST,
82
+ });
83
+ }
84
+ catch (err) {
85
+ logger.fatal(`There was an error when starting the EA server: ${err}`);
86
+ process.exit();
87
+ }
88
+ logger.info(`Listening on port ${api.server.address().port}`);
89
+ }
90
+ else {
91
+ logger.info('REST API is disabled; this instance will not process incoming requests.');
92
+ }
93
+ if (adapter.config.EA_MODE === 'writer' || adapter.config.EA_MODE === 'reader-writer') {
94
+ // Start background loop that will take care of calling any async Transports
95
+ logger.info('Starting background execution loop');
96
+ (0, background_executor_1.callBackgroundExecutes)(adapter, apiShutdownPromise);
97
+ }
98
+ else {
99
+ logger.info('Background executor is disabled; this instance will not perform async background executes.');
100
+ }
101
+ return api;
102
+ };
103
+ exports.expose = expose;
104
+ async function buildRestApi(adapter) {
105
+ const app = (0, fastify_1.default)();
106
+ // Add healthcheck endpoint before middlewares to bypass them
107
+ app.get((0, path_1.join)(adapter.config.BASE_URL, 'health'), (req, res) => {
108
+ res.status(200).send({ message: 'OK', version: VERSION });
109
+ });
110
+ // Use global error handling
111
+ app.setErrorHandler(validation_1.errorCatchingMiddleware);
112
+ // Always reply with json content
113
+ app.addHook('preHandler', (_, reply, done) => {
114
+ reply.headers({ 'content-type': 'application/json; charset=utf-8' });
115
+ done();
116
+ });
117
+ app.register(async (router) => {
118
+ // Set up "middlewares" (hooks in fastify)
119
+ router.addHook('preHandler', (0, validation_1.validatorMiddleware)(adapter));
120
+ if (adapter.config['CORRELATION_ID_ENABLED']) {
121
+ router.addHook('onRequest', util_1.loggingContextMiddleware);
122
+ }
123
+ router.route({
124
+ url: adapter.config.BASE_URL,
125
+ method: 'POST',
126
+ handler: async (req, reply) => reply.send(await adapter.handleRequest(req, reply)),
127
+ });
128
+ if (adapter.config.METRICS_ENABLED && adapter.config.EXPERIMENTAL_METRICS_ENABLED) {
129
+ router.addHook('onResponse', metrics_1.buildMetricsMiddleware);
130
+ }
131
+ });
132
+ // Add smoke endpoint after middleware which are needed for tests
133
+ buildSmokeEndpoint(app, adapter.config);
134
+ return app;
135
+ }
136
+ /**
137
+ * Adds the /smoke endpoint to the API for smoke testing the adapter
138
+ *
139
+ * @param app - the Fastify instance
140
+ * @param config - the initialized adapter config
141
+ */
142
+ function buildSmokeEndpoint(app, config) {
143
+ app.get((0, path_1.join)(config.BASE_URL, 'smoke'), async (_, res) => {
144
+ const testPayload = (0, test_payload_loader_1.loadTestPayload)(config.SMOKE_TEST_PAYLOAD_FILE_NAME);
145
+ if (testPayload.isDefault) {
146
+ return res.status(200).send('OK');
147
+ }
148
+ const errors = [];
149
+ for (const index in testPayload.requests) {
150
+ try {
151
+ const request = { id: index, data: testPayload.requests[index] };
152
+ // Use Fastify's app inject to pass smoke requests internally
153
+ const response = await app.inject({
154
+ method: 'POST',
155
+ url: '/',
156
+ payload: request,
157
+ });
158
+ const parsedResponse = JSON.parse(response.body);
159
+ // Throw error if not 2xx status code
160
+ if (parsedResponse.statusCode < 200 || parsedResponse.statusCode > 299) {
161
+ throw Error('Smoke test request failed');
162
+ }
163
+ }
164
+ catch (e) {
165
+ errors.push(e);
166
+ }
167
+ }
168
+ if (errors.length > 0) {
169
+ return res.status(500).send(errors);
170
+ }
171
+ return res.status(200).send('OK');
172
+ });
173
+ }
174
+ //# sourceMappingURL=index.js.map
package/index.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export declare enum HttpRequestType {
2
+ CACHE_HIT = "cacheHit",
3
+ DATA_PROVIDER_HIT = "dataProviderHit",
4
+ ADAPTER_ERROR = "adapterError",
5
+ INPUT_ERROR = "inputError",
6
+ RATE_LIMIT_ERROR = "rateLimitError",
7
+ DP_ERROR = "dataProviderError",
8
+ TIMEOUT_ERROR = "timeoutError",
9
+ CONNECTION_ERROR = "connectionError",
10
+ CUSTOM_ERROR = "customError"
11
+ }
12
+ /**
13
+ * Maxiumum number of characters that a feedId can contain.
14
+ */
15
+ export declare const MAX_FEED_ID_LENGTH = 300;
16
+ export declare const requestDurationBuckets: number[];
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.requestDurationBuckets = exports.MAX_FEED_ID_LENGTH = exports.HttpRequestType = void 0;
4
+ var HttpRequestType;
5
+ (function (HttpRequestType) {
6
+ HttpRequestType["CACHE_HIT"] = "cacheHit";
7
+ HttpRequestType["DATA_PROVIDER_HIT"] = "dataProviderHit";
8
+ HttpRequestType["ADAPTER_ERROR"] = "adapterError";
9
+ HttpRequestType["INPUT_ERROR"] = "inputError";
10
+ HttpRequestType["RATE_LIMIT_ERROR"] = "rateLimitError";
11
+ // BURST_LIMIT_ERROR = 'burstLimitError',
12
+ // BACKOFF_ERROR = 'backoffError',
13
+ HttpRequestType["DP_ERROR"] = "dataProviderError";
14
+ HttpRequestType["TIMEOUT_ERROR"] = "timeoutError";
15
+ HttpRequestType["CONNECTION_ERROR"] = "connectionError";
16
+ // RES_EMPTY_ERROR = 'responseEmptyError',
17
+ // RES_INVALID_ERROR = 'responseInvalidError',
18
+ HttpRequestType["CUSTOM_ERROR"] = "customError";
19
+ })(HttpRequestType = exports.HttpRequestType || (exports.HttpRequestType = {}));
20
+ /**
21
+ * Maxiumum number of characters that a feedId can contain.
22
+ */
23
+ exports.MAX_FEED_ID_LENGTH = 300;
24
+ // We should tune these as we collect data, this is the default bucket distribution that prom comes with
25
+ exports.requestDurationBuckets = [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10];
26
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/metrics/constants.ts"],"names":[],"mappings":";;;AAAA,IAAY,eAcX;AAdD,WAAY,eAAe;IACzB,yCAAsB,CAAA;IACtB,wDAAqC,CAAA;IACrC,iDAA8B,CAAA;IAC9B,6CAA0B,CAAA;IAC1B,sDAAmC,CAAA;IACnC,yCAAyC;IACzC,kCAAkC;IAClC,iDAA8B,CAAA;IAC9B,iDAA8B,CAAA;IAC9B,uDAAoC,CAAA;IACpC,0CAA0C;IAC1C,8CAA8C;IAC9C,+CAA4B,CAAA;AAC9B,CAAC,EAdW,eAAe,GAAf,uBAAe,KAAf,uBAAe,QAc1B;AAED;;GAEG;AACU,QAAA,kBAAkB,GAAG,GAAG,CAAA;AAErC,wGAAwG;AAC3F,QAAA,sBAAsB,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAA"}
@@ -0,0 +1,19 @@
1
+ import * as client from 'prom-client';
2
+ import { AdapterRequest } from '../util';
3
+ import { AdapterConfig } from '../config';
4
+ import { FastifyReply, HookHandlerDoneFunction } from 'fastify';
5
+ import { AdapterError } from '../validation/error';
6
+ export declare function setupMetricsServer(name: string, config: AdapterConfig): void;
7
+ export declare const setupMetrics: (name: string, config: AdapterConfig) => void;
8
+ /**
9
+ * Builds metrics middleware that records end to end EA response times
10
+ * and count of requests
11
+ *
12
+ * @returns the cache middleware function
13
+ */
14
+ export declare const buildMetricsMiddleware: (req: AdapterRequest, res: FastifyReply, done: HookHandlerDoneFunction) => void;
15
+ export declare const buildHttpRequestMetricsLabel: (feedId: string, error?: AdapterError | Error, cacheHit?: boolean) => Partial<Record<"type" | "method" | "feed_id" | "status_code" | "provider_status_code" | "retry" | "is_cache_warming", string | number>>;
16
+ export declare const httpRequestsTotal: client.Counter<"type" | "method" | "feed_id" | "status_code" | "provider_status_code" | "retry" | "is_cache_warming">;
17
+ export declare const httpRequestDurationSeconds: client.Histogram<string>;
18
+ export declare const bgExecuteTotal: client.Counter<"endpoint">;
19
+ export declare const bgExecuteDurationSeconds: client.Gauge<"endpoint">;