@dhedge/backend-flatcoin-core 0.1.26 → 0.1.27

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.
@@ -0,0 +1,16 @@
1
+ import { Logger } from '@nestjs/common';
2
+ import { EvmPriceServiceConnection } from '@pythnetwork/pyth-evm-js';
3
+ import { BigNumber } from 'ethers';
4
+ export declare class AppPriceService {
5
+ private readonly connection;
6
+ private readonly logger;
7
+ private readonly priceIds;
8
+ constructor(connection: EvmPriceServiceConnection, logger: Logger);
9
+ getPriceUpdates(): Promise<string[]>;
10
+ getPrice(): Promise<BigNumber>;
11
+ getPriceByTimestamp(timestamp: number): Promise<BigNumber>;
12
+ getPriceUpdatesWithRetry(maxRetries: number, timeoutMillis: number): Promise<string[]>;
13
+ getPriceWithRetry(maxRetries: number, timeoutMillis: number): Promise<BigNumber>;
14
+ getPriceByTimestampWithRetry(timestamp: number, maxRetries: number, timeoutMillis: number): Promise<BigNumber>;
15
+ retry<T>(func: () => Promise<T>, maxRetries: number, timeoutMillis: number): Promise<T>;
16
+ }
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.AppPriceService = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const pyth_evm_js_1 = require("@pythnetwork/pyth-evm-js");
15
+ const ethers_1 = require("ethers");
16
+ let AppPriceService = class AppPriceService {
17
+ constructor(connection, logger) {
18
+ this.connection = connection;
19
+ this.logger = logger;
20
+ if (process.env.PYTH_NETWORK_ETH_USD_PRICE_ID) {
21
+ this.priceIds = [process.env.PYTH_NETWORK_ETH_USD_PRICE_ID];
22
+ }
23
+ else {
24
+ throw new Error('env property PYTH_NETWORK_ETH_USD_PRICE_ID is not configured');
25
+ }
26
+ }
27
+ async getPriceUpdates() {
28
+ // In order to use Pyth prices in your protocol you need to submit the price update data to Pyth contract in your target
29
+ // chain. `getPriceFeedsUpdateData` creates the update data which can be submitted to your contract. Then your contract should
30
+ // call the Pyth Contract with this data.
31
+ const priceUpdates = await this.connection.getPriceFeedsUpdateData(this.priceIds);
32
+ if (!priceUpdates) {
33
+ throw new Error('failed to get PriceFeedsUpdateData');
34
+ }
35
+ return priceUpdates;
36
+ }
37
+ async getPrice() {
38
+ const priceFeeds = await this.connection.getLatestPriceFeeds(this.priceIds);
39
+ if (!priceFeeds) {
40
+ throw new Error('failed to get LatestPriceFeeds');
41
+ }
42
+ return ethers_1.BigNumber.from(priceFeeds[0].getPriceUnchecked().price).mul(ethers_1.BigNumber.from(10).pow(10));
43
+ }
44
+ async getPriceByTimestamp(timestamp) {
45
+ const priceFeed = await this.connection.getPriceFeed(this.priceIds[0], timestamp);
46
+ return ethers_1.BigNumber.from(priceFeed.getPriceUnchecked().price).mul(ethers_1.BigNumber.from(10).pow(10));
47
+ }
48
+ async getPriceUpdatesWithRetry(maxRetries, timeoutMillis) {
49
+ return this.retry(this.getPriceUpdates.bind(this), maxRetries, timeoutMillis);
50
+ }
51
+ async getPriceWithRetry(maxRetries, timeoutMillis) {
52
+ return this.retry(this.getPrice.bind(this), maxRetries, timeoutMillis);
53
+ }
54
+ async getPriceByTimestampWithRetry(timestamp, maxRetries, timeoutMillis) {
55
+ return this.retry(() => this.getPriceByTimestamp.bind(this)(timestamp), maxRetries, timeoutMillis);
56
+ }
57
+ async retry(func, maxRetries, timeoutMillis) {
58
+ for (let retries = 0; retries < maxRetries; retries++) {
59
+ try {
60
+ return await func();
61
+ }
62
+ catch (err) {
63
+ this.logger.error(`Error querying ${func.name} (retries: ${retries}): ${err.message}`);
64
+ // delay before the next retry
65
+ await new Promise((resolve) => setTimeout(resolve, timeoutMillis)); // 1-second delay
66
+ }
67
+ }
68
+ throw new Error(`Max retry attempts reached`);
69
+ }
70
+ };
71
+ exports.AppPriceService = AppPriceService;
72
+ exports.AppPriceService = AppPriceService = __decorate([
73
+ (0, common_1.Injectable)(),
74
+ __metadata("design:paramtypes", [pyth_evm_js_1.EvmPriceServiceConnection, common_1.Logger])
75
+ ], AppPriceService);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhedge/backend-flatcoin-core",
3
- "version": "0.1.26",
3
+ "version": "0.1.27",
4
4
  "description": "Backend Flatcoin Core",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -15,19 +15,23 @@
15
15
  "/dist"
16
16
  ],
17
17
  "dependencies": {
18
- "@nestjs/core": "^9.0.0",
19
18
  "@nestjs/common": "^9.0.0",
19
+ "@nestjs/core": "^9.0.0",
20
20
  "@nestjs/graphql": "^12.0.9",
21
21
  "@nestjs/typeorm": "^9.0.0",
22
- "typeorm": "^0.3.17",
22
+ "@pythnetwork/pyth-evm-js": "^1.25.0",
23
23
  "ethers": "5.7.2",
24
24
  "nest-winston": "1.9.3",
25
+ "typeorm": "^0.3.17",
25
26
  "winston": "3.10.0"
26
27
  },
27
28
  "devDependencies": {
29
+ "@nestjs/testing": "^9.4.3",
28
30
  "@swc/core": "^1.3.90",
29
31
  "@types/dedent": "^0.7.0",
30
32
  "@types/fs-extra": "^11.0.1",
33
+ "@types/jest": "29.5.1",
34
+ "@types/supertest": "^2.0.11",
31
35
  "@typescript-eslint/eslint-plugin": "^5.0.0",
32
36
  "@typescript-eslint/parser": "^5.0.0",
33
37
  "dedent": "^0.7.0",
@@ -36,9 +40,11 @@
36
40
  "eslint-plugin-prettier": "^4.0.0",
37
41
  "execa": "^7.1.1",
38
42
  "fs-extra": "^11.1.1",
43
+ "jest": "29.5.0",
39
44
  "prettier": "^2.3.2",
40
- "typescript": "^5.0.0",
41
- "rimraf": "5.0.5"
45
+ "rimraf": "5.0.5",
46
+ "ts-jest": "29.1.0",
47
+ "typescript": "^5.0.0"
42
48
  },
43
49
  "repository": {
44
50
  "type": "git",
@@ -53,6 +59,29 @@
53
59
  "precommit": "npm run lint && npm run typecheck && npm run test",
54
60
  "prepublish:npm": "npm run build",
55
61
  "publish:npm": "npm publish --access=restricted",
56
- "test": "vitest run --coverage"
62
+ "test": "jest --runInBand --detectOpenHandles --forceExit",
63
+ "test:watch": "jest --watch",
64
+ "test:cov": "jest --coverage",
65
+ "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
66
+ "test:e2e": "jest --config ./test/jest-e2e.json"
67
+ },
68
+ "jest": {
69
+ "moduleFileExtensions": [
70
+ "js",
71
+ "json",
72
+ "ts"
73
+ ],
74
+ "rootDir": "./",
75
+ "testRegex": ".*\\.spec\\.ts$",
76
+ "transform": {
77
+ "^.+\\.(t|j)s$": "ts-jest"
78
+ },
79
+ "collectCoverageFrom": [
80
+ "**/*.ts",
81
+ "!**/node_modules/**",
82
+ "!**/dist/**"
83
+ ],
84
+ "coverageDirectory": "../coverage",
85
+ "testEnvironment": "node"
57
86
  }
58
87
  }