From be7e4f7404d48c56c8b4dfe711adb618a101d42e Mon Sep 17 00:00:00 2001 From: Anni Piragauta Date: Fri, 6 Feb 2026 11:42:13 -0500 Subject: [PATCH] feat: Add sentry to capture errors for 2wp-api --- .env.test | 3 + package-lock.json | 870 +++++++++++++++++- package.json | 1 + src/controllers/addresses-info.controller.ts | 6 +- src/controllers/api-information.controller.ts | 2 +- src/controllers/broadcast.controller.ts | 2 + src/controllers/health-check.controller.ts | 39 +- .../pegin-configuration.controller.ts | 2 + src/controllers/tx.controller.ts | 2 + src/controllers/utxo.controller.ts | 2 + src/index.ts | 1 + src/instrument.ts | 12 + src/services/bridge.service.ts | 6 +- src/services/pegin-status/bitcoin.service.ts | 4 + .../pegin-status/pegin-status.service.ts | 18 +- src/services/pegout-data.processor.ts | 6 +- .../pegout-status/pegout-status.service.ts | 4 +- src/services/rsk-chain-sync.service.ts | 6 +- src/services/rsk-node.service.ts | 11 +- src/services/sync-status-mongo.service.ts | 3 +- src/utils/bridge-utils.ts | 4 +- src/utils/btc-utils.ts | 6 +- src/utils/hex-utils.ts | 16 +- 23 files changed, 961 insertions(+), 65 deletions(-) create mode 100644 src/instrument.ts diff --git a/.env.test b/.env.test index 4b0ab983..aac02cff 100644 --- a/.env.test +++ b/.env.test @@ -43,3 +43,6 @@ MAX_FEE_AMOUNT_ALLOWED=5000000 #Dust value (Satoshi) BURN_DUST_VALUE=2000 + +SENTRY_DSN= +SENTRY_ENV= diff --git a/package-lock.json b/package-lock.json index 970e7c77..89586401 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "@rsksmart/bridge-state-data-parser": "^2.0.0", "@rsksmart/bridge-transaction-parser": "^2.0.0", "@rsksmart/rsk-precompiled-abis": "^8.0.0-REED", + "@sentry/node": "^10.38.0", "big.js": "^6.1.1", "bitcoinjs-lib": "^6.0.1", "bs58": "^5.0.0", @@ -81,6 +82,23 @@ "node": ">=6.0.0" } }, + "node_modules/@apm-js-collab/code-transformer": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/@apm-js-collab/code-transformer/-/code-transformer-0.8.2.tgz", + "integrity": "sha512-YRjJjNq5KFSjDUoqu5pFUWrrsvGOxl6c3bu+uMFc9HNNptZ2rNU/TI2nLw4jnhQNtka972Ee2m3uqbvDQtPeCA==", + "license": "Apache-2.0" + }, + "node_modules/@apm-js-collab/tracing-hooks": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@apm-js-collab/tracing-hooks/-/tracing-hooks-0.3.1.tgz", + "integrity": "sha512-Vu1CbmPURlN5fTboVuKMoJjbO5qcq9fA5YXpskx3dXe/zTBvjODFoerw+69rVBlRLrJpwPqSDqEuJDEKIrTldw==", + "license": "Apache-2.0", + "dependencies": { + "@apm-js-collab/code-transformer": "^0.8.0", + "debug": "^4.4.1", + "module-details-from-path": "^1.0.4" + } + }, "node_modules/@babel/code-frame": { "version": "7.26.2", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", @@ -1326,6 +1344,504 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.0.tgz", "integrity": "sha512-zI22/pJW2wUZOVyguFaUL1HABdmSVxpXrzIqkjsHmyUjNhPoWM1CKfvVuXfetHhIok4RY573cqS0mZ1SJEnoTg==" }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/api-logs": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.211.0.tgz", + "integrity": "sha512-swFdZq8MCdmdR22jTVGQDhwqDzcI4M10nhjXkLr1EsIzXgZBqm4ZlmmcWsg3TSNf+3mzgOiqveXmBLZuDi2Lgg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/context-async-hooks": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.5.0.tgz", + "integrity": "sha512-uOXpVX0ZjO7heSVjhheW2XEPrhQAWr2BScDPoZ9UDycl5iuHG+Usyc3AIfG6kZeC1GyLpMInpQ6X5+9n69yOFw==", + "license": "Apache-2.0", + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.211.0.tgz", + "integrity": "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.211.0", + "import-in-the-middle": "^2.0.0", + "require-in-the-middle": "^8.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-amqplib": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-amqplib/-/instrumentation-amqplib-0.58.0.tgz", + "integrity": "sha512-fjpQtH18J6GxzUZ+cwNhWUpb71u+DzT7rFkg5pLssDGaEber91Y2WNGdpVpwGivfEluMlNMZumzjEqfg8DeKXQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-connect": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.54.0.tgz", + "integrity": "sha512-43RmbhUhqt3uuPnc16cX6NsxEASEtn8z/cYV8Zpt6EP4p2h9s4FNuJ4Q9BbEQ2C0YlCCB/2crO1ruVz/hWt8fA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/connect": "3.4.38" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-dataloader": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dataloader/-/instrumentation-dataloader-0.28.0.tgz", + "integrity": "sha512-ExXGBp0sUj8yhm6Znhf9jmuOaGDsYfDES3gswZnKr4MCqoBWQdEFn6EoDdt5u+RdbxQER+t43FoUihEfTSqsjA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-express": { + "version": "0.59.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.59.0.tgz", + "integrity": "sha512-pMKV/qnHiW/Q6pmbKkxt0eIhuNEtvJ7sUAyee192HErlr+a1Jx+FZ3WjfmzhQL1geewyGEiPGkmjjAgNY8TgDA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fs": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.30.0.tgz", + "integrity": "sha512-n3Cf8YhG7reaj5dncGlRIU7iT40bxPOjsBEA5Bc1a1g6e9Qvb+JFJ7SEiMlPbUw4PBmxE3h40ltE8LZ3zVt6OA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-generic-pool": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.54.0.tgz", + "integrity": "sha512-8dXMBzzmEdXfH/wjuRvcJnUFeWzZHUnExkmFJ2uPfa31wmpyBCMxO59yr8f/OXXgSogNgi/uPo9KW9H7LMIZ+g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-graphql": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.58.0.tgz", + "integrity": "sha512-+yWVVY7fxOs3j2RixCbvue8vUuJ1inHxN2q1sduqDB0Wnkr4vOzVKRYl/Zy7B31/dcPS72D9lo/kltdOTBM3bQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-hapi": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.57.0.tgz", + "integrity": "sha512-Os4THbvls8cTQTVA8ApLfZZztuuqGEeqog0XUnyRW7QVF0d/vOVBEcBCk1pazPFmllXGEdNbbat8e2fYIWdFbw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-http": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.211.0.tgz", + "integrity": "sha512-n0IaQ6oVll9PP84SjbOCwDjaJasWRHi6BLsbMLiT6tNj7QbVOkuA5sk/EfZczwI0j5uTKl1awQPivO/ldVtsqA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.0", + "@opentelemetry/instrumentation": "0.211.0", + "@opentelemetry/semantic-conventions": "^1.29.0", + "forwarded-parse": "2.1.2" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-ioredis": { + "version": "0.59.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.59.0.tgz", + "integrity": "sha512-875UxzBHWkW+P4Y45SoFM2AR8f8TzBMD8eO7QXGCyFSCUMP5s9vtt/BS8b/r2kqLyaRPK6mLbdnZznK3XzQWvw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/redis-common": "^0.38.2", + "@opentelemetry/semantic-conventions": "^1.33.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-kafkajs": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.20.0.tgz", + "integrity": "sha512-yJXOuWZROzj7WmYCUiyT27tIfqBrVtl1/TwVbQyWPz7rL0r1Lu7kWjD0PiVeTCIL6CrIZ7M2s8eBxsTAOxbNvw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.30.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-knex": { + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.55.0.tgz", + "integrity": "sha512-FtTL5DUx5Ka/8VK6P1VwnlUXPa3nrb7REvm5ddLUIeXXq4tb9pKd+/ThB1xM/IjefkRSN3z8a5t7epYw1JLBJQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-koa": { + "version": "0.59.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.59.0.tgz", + "integrity": "sha512-K9o2skADV20Skdu5tG2bogPKiSpXh4KxfLjz6FuqIVvDJNibwSdu5UvyyBzRVp1rQMV6UmoIk6d3PyPtJbaGSg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.36.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0" + } + }, + "node_modules/@opentelemetry/instrumentation-lru-memoizer": { + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.55.0.tgz", + "integrity": "sha512-FDBfT7yDGcspN0Cxbu/k8A0Pp1Jhv/m7BMTzXGpcb8ENl3tDj/51U65R5lWzUH15GaZA15HQ5A5wtafklxYj7g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongodb": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.64.0.tgz", + "integrity": "sha512-pFlCJjweTqVp7B220mCvCld1c1eYKZfQt1p3bxSbcReypKLJTwat+wbL2YZoX9jPi5X2O8tTKFEOahO5ehQGsA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongoose": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.57.0.tgz", + "integrity": "sha512-MthiekrU/BAJc5JZoZeJmo0OTX6ycJMiP6sMOSRTkvz5BrPMYDqaJos0OgsLPL/HpcgHP7eo5pduETuLguOqcg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.57.0.tgz", + "integrity": "sha512-HFS/+FcZ6Q7piM7Il7CzQ4VHhJvGMJWjx7EgCkP5AnTntSN5rb5Xi3TkYJHBKeR27A0QqPlGaCITi93fUDs++Q==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.0", + "@types/mysql": "2.15.27" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql2": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.57.0.tgz", + "integrity": "sha512-nHSrYAwF7+aV1E1V9yOOP9TchOodb6fjn4gFvdrdQXiRE7cMuffyLLbCZlZd4wsspBzVwOXX8mpURdRserAhNA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.0", + "@opentelemetry/sql-common": "^0.41.2" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pg": { + "version": "0.63.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.63.0.tgz", + "integrity": "sha512-dKm/ODNN3GgIQVlbD6ZPxwRc3kleLf95hrRWXM+l8wYo+vSeXtEpQPT53afEf6VFWDVzJK55VGn8KMLtSve/cg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.34.0", + "@opentelemetry/sql-common": "^0.41.2", + "@types/pg": "8.15.6", + "@types/pg-pool": "2.0.7" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-redis": { + "version": "0.59.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis/-/instrumentation-redis-0.59.0.tgz", + "integrity": "sha512-JKv1KDDYA2chJ1PC3pLP+Q9ISMQk6h5ey+99mB57/ARk0vQPGZTTEb4h4/JlcEpy7AYT8HIGv7X6l+br03Neeg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/redis-common": "^0.38.2", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-tedious": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.30.0.tgz", + "integrity": "sha512-bZy9Q8jFdycKQ2pAsyuHYUHNmCxCOGdG6eg1Mn75RvQDccq832sU5OWOBnc12EFUELI6icJkhR7+EQKMBam2GA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.0", + "@types/tedious": "^4.0.14" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-undici": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.21.0.tgz", + "integrity": "sha512-gok0LPUOTz2FQ1YJMZzaHcOzDFyT64XJ8M9rNkugk923/p6lDGms/cRW1cqgqp6N6qcd6K6YdVHwPEhnx9BWbw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.24.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.7.0" + } + }, + "node_modules/@opentelemetry/redis-common": { + "version": "0.38.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.38.2.tgz", + "integrity": "sha512-1BCcU93iwSRZvDAgwUxC/DV4T/406SkMfxGqu5ojc3AvNI+I9GhV7v0J1HljsczuuhcnFLYqD5VmwVXfCGHzxA==", + "license": "Apache-2.0", + "engines": { + "node": "^18.19.0 || >=20.6.0" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.0.tgz", + "integrity": "sha512-F8W52ApePshpoSrfsSk1H2yJn9aKjCrbpQF1M9Qii0GHzbfVeFUB+rc3X4aggyZD8x9Gu3Slua+s6krmq6Dt8g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.5.0.tgz", + "integrity": "sha512-VzRf8LzotASEyNDUxTdaJ9IRJ1/h692WyArDBInf5puLCjxbICD6XkHgpuudis56EndyS7LYFmtTMny6UABNdQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.0", + "@opentelemetry/resources": "2.5.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.39.0.tgz", + "integrity": "sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sql-common": { + "version": "0.41.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.41.2.tgz", + "integrity": "sha512-4mhWm3Z8z+i508zQJ7r6Xi7y4mmoJpdvH0fZPFRkWrdp5fq7hhZ2HhYokEOLkfqSMgPR4Z9EyB3DBkbKGOqZiQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0" + } + }, "node_modules/@paralleldrive/cuid2": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.2.2.tgz", @@ -1390,6 +1906,47 @@ "node": "*" } }, + "node_modules/@prisma/instrumentation": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@prisma/instrumentation/-/instrumentation-7.2.0.tgz", + "integrity": "sha512-Rh9Z4x5kEj1OdARd7U18AtVrnL6rmLSI0qYShaB4W7Wx5BKbgzndWF+QnuzMb7GLfVdlT5aYCXoPQVYuYtVu0g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.207.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.8" + } + }, + "node_modules/@prisma/instrumentation/node_modules/@opentelemetry/api-logs": { + "version": "0.207.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.207.0.tgz", + "integrity": "sha512-lAb0jQRVyleQQGiuuvCOTDVspc14nx6XJjP4FspJ1sNARo3Regq4ZZbrc3rN4b1TYSuUCvgH+UXUPug4SLOqEQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@prisma/instrumentation/node_modules/@opentelemetry/instrumentation": { + "version": "0.207.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.207.0.tgz", + "integrity": "sha512-y6eeli9+TLKnznrR8AZlQMSJT7wILpXH+6EYq5Vf/4Ao+huI7EedxQHwRgVUOMLFbe7VFDvHJrX9/f4lcwnJsA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.207.0", + "import-in-the-middle": "^2.0.0", + "require-in-the-middle": "^8.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, "node_modules/@rsksmart/bridge-state-data-parser": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@rsksmart/bridge-state-data-parser/-/bridge-state-data-parser-2.0.0.tgz", @@ -1432,6 +1989,128 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/@sentry/core": { + "version": "10.38.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.38.0.tgz", + "integrity": "sha512-1pubWDZE5y5HZEPMAZERP4fVl2NH3Ihp1A+vMoVkb3Qc66Diqj1WierAnStlZP7tCx0TBa0dK85GTW/ZFYyB9g==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/node": { + "version": "10.38.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-10.38.0.tgz", + "integrity": "sha512-wriyDtWDAoatn8EhOj0U4PJR1WufiijTsCGALqakOHbFiadtBJANLe6aSkXoXT4tegw59cz1wY4NlzHjYksaPw==", + "license": "MIT", + "dependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^2.5.0", + "@opentelemetry/core": "^2.5.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/instrumentation-amqplib": "0.58.0", + "@opentelemetry/instrumentation-connect": "0.54.0", + "@opentelemetry/instrumentation-dataloader": "0.28.0", + "@opentelemetry/instrumentation-express": "0.59.0", + "@opentelemetry/instrumentation-fs": "0.30.0", + "@opentelemetry/instrumentation-generic-pool": "0.54.0", + "@opentelemetry/instrumentation-graphql": "0.58.0", + "@opentelemetry/instrumentation-hapi": "0.57.0", + "@opentelemetry/instrumentation-http": "0.211.0", + "@opentelemetry/instrumentation-ioredis": "0.59.0", + "@opentelemetry/instrumentation-kafkajs": "0.20.0", + "@opentelemetry/instrumentation-knex": "0.55.0", + "@opentelemetry/instrumentation-koa": "0.59.0", + "@opentelemetry/instrumentation-lru-memoizer": "0.55.0", + "@opentelemetry/instrumentation-mongodb": "0.64.0", + "@opentelemetry/instrumentation-mongoose": "0.57.0", + "@opentelemetry/instrumentation-mysql": "0.57.0", + "@opentelemetry/instrumentation-mysql2": "0.57.0", + "@opentelemetry/instrumentation-pg": "0.63.0", + "@opentelemetry/instrumentation-redis": "0.59.0", + "@opentelemetry/instrumentation-tedious": "0.30.0", + "@opentelemetry/instrumentation-undici": "0.21.0", + "@opentelemetry/resources": "^2.5.0", + "@opentelemetry/sdk-trace-base": "^2.5.0", + "@opentelemetry/semantic-conventions": "^1.39.0", + "@prisma/instrumentation": "7.2.0", + "@sentry/core": "10.38.0", + "@sentry/node-core": "10.38.0", + "@sentry/opentelemetry": "10.38.0", + "import-in-the-middle": "^2.0.6", + "minimatch": "^9.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/node-core": { + "version": "10.38.0", + "resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-10.38.0.tgz", + "integrity": "sha512-ErXtpedrY1HghgwM6AliilZPcUCoNNP1NThdO4YpeMq04wMX9/GMmFCu46TnCcg6b7IFIOSr2S4yD086PxLlHQ==", + "license": "MIT", + "dependencies": { + "@apm-js-collab/tracing-hooks": "^0.3.1", + "@sentry/core": "10.38.0", + "@sentry/opentelemetry": "10.38.0", + "import-in-the-middle": "^2.0.6" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.1.0", + "@opentelemetry/core": "^1.30.1 || ^2.1.0", + "@opentelemetry/instrumentation": ">=0.57.1 <1", + "@opentelemetry/resources": "^1.30.1 || ^2.1.0", + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0", + "@opentelemetry/semantic-conventions": "^1.39.0" + } + }, + "node_modules/@sentry/node/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@sentry/node/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@sentry/opentelemetry": { + "version": "10.38.0", + "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-10.38.0.tgz", + "integrity": "sha512-YPVhWfYmC7nD3EJqEHGtjp4fp5LwtAbE5rt9egQ4hqJlYFvr8YEz9sdoqSZxO0cZzgs2v97HFl/nmWAXe52G2Q==", + "license": "MIT", + "dependencies": { + "@sentry/core": "10.38.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.1.0", + "@opentelemetry/core": "^1.30.1 || ^2.1.0", + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0", + "@opentelemetry/semantic-conventions": "^1.39.0" + } + }, "node_modules/@sinonjs/commons": { "version": "1.8.6", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", @@ -1500,9 +2179,10 @@ } }, "node_modules/@types/connect": { - "version": "3.4.36", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.36.tgz", - "integrity": "sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==", + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -1622,6 +2302,15 @@ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.32.tgz", "integrity": "sha512-xPSg0jm4mqgEkNhowKgZFBNtwoEwF6gJ4Dhww+GFpm3IgtNseHQZ5IqdNwnquZEoANxyDAKDRAdVo4Z72VvD/g==" }, + "node_modules/@types/mysql": { + "version": "2.15.27", + "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.27.tgz", + "integrity": "sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/nock": { "version": "10.0.3", "resolved": "https://registry.npmjs.org/@types/nock/-/nock-10.0.3.tgz", @@ -1653,6 +2342,26 @@ "@types/node": "*" } }, + "node_modules/@types/pg": { + "version": "8.15.6", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.15.6.tgz", + "integrity": "sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" + } + }, + "node_modules/@types/pg-pool": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/pg-pool/-/pg-pool-2.0.7.tgz", + "integrity": "sha512-U4CwmGVQcbEuqpyju8/ptOKg6gEC+Tqsvj2xS9o1g71bUh8twxnC6ZL5rZKCsGN0iyH0CwgUyc9VR5owNQF9Ng==", + "license": "MIT", + "dependencies": { + "@types/pg": "*" + } + }, "node_modules/@types/qs": { "version": "6.9.8", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz", @@ -1757,6 +2466,15 @@ "@types/superagent": "*" } }, + "node_modules/@types/tedious": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/@types/tedious/-/tedious-4.0.14.tgz", + "integrity": "sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/type-is": { "version": "1.6.4", "resolved": "https://registry.npmjs.org/@types/type-is/-/type-is-1.6.4.tgz", @@ -2012,10 +2730,10 @@ } }, "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "dev": true, + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -2023,6 +2741,15 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -2914,6 +3641,12 @@ "node": ">= 0.10" } }, + "node_modules/cjs-module-lexer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", + "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", + "license": "MIT" + }, "node_modules/cldrjs": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/cldrjs/-/cldrjs-0.5.5.tgz", @@ -3194,9 +3927,10 @@ } }, "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -4559,6 +5293,12 @@ "node": ">= 0.6" } }, + "node_modules/forwarded-parse": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/forwarded-parse/-/forwarded-parse-2.1.2.tgz", + "integrity": "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==", + "license": "MIT" + }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -5249,6 +5989,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-in-the-middle": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-2.0.6.tgz", + "integrity": "sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw==", + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.15.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^2.2.0", + "module-details-from-path": "^1.0.4" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -6594,6 +7346,12 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/module-details-from-path": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", + "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==", + "license": "MIT" + }, "node_modules/mongodb": { "version": "5.9.2", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.9.2.tgz", @@ -7867,6 +8625,37 @@ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.11.0.tgz", + "integrity": "sha512-pfsxk2M9M3BuGgDOfuy37VNRRX3jmKgMjcvAcWqNDpZSf4cUmv8HSOl5ViRQFsfARFn0KuUQTgLxVMbNq5NW3g==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -7957,6 +8746,45 @@ "node": ">= 0.4" } }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/postman-request": { "version": "2.88.1-postman.40", "resolved": "https://registry.npmjs.org/postman-request/-/postman-request-2.88.1-postman.40.tgz", @@ -8286,6 +9114,19 @@ "node": ">=0.10.0" } }, + "node_modules/require-in-the-middle": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-8.0.1.tgz", + "integrity": "sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3" + }, + "engines": { + "node": ">=9.3.0 || >=8.10.0 <9.0.0" + } + }, "node_modules/require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -11474,6 +12315,15 @@ "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==" }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index 9faec4e5..60723601 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "@rsksmart/bridge-state-data-parser": "^2.0.0", "@rsksmart/bridge-transaction-parser": "^2.0.0", "@rsksmart/rsk-precompiled-abis": "^8.0.0-REED", + "@sentry/node": "^10.38.0", "big.js": "^6.1.1", "bitcoinjs-lib": "^6.0.1", "bs58": "^5.0.0", diff --git a/src/controllers/addresses-info.controller.ts b/src/controllers/addresses-info.controller.ts index a46c0480..5648fd5c 100644 --- a/src/controllers/addresses-info.controller.ts +++ b/src/controllers/addresses-info.controller.ts @@ -1,5 +1,6 @@ import {getModelSchemaRef, post, requestBody, response} from '@loopback/rest'; import {inject} from '@loopback/core'; +import * as Sentry from "@sentry/node"; import {AddressList} from '../models'; import {AddressInfoResponse} from '../models/adddress-info-response.model'; import {ServicesBindings} from '../dependency-injection-bindings'; @@ -52,7 +53,10 @@ export class AddressesInfoController { addressesInfo, })); }) - .catch(reject); + .catch((error) => { + Sentry.captureException(error); + return reject(error); + }); }); } } diff --git a/src/controllers/api-information.controller.ts b/src/controllers/api-information.controller.ts index bcf03b02..0470c536 100644 --- a/src/controllers/api-information.controller.ts +++ b/src/controllers/api-information.controller.ts @@ -24,7 +24,7 @@ export class ApiInformationController { }, }) getApiInformation():ApiInformation { - const version = packageJson.version; + const {version} = packageJson; this.logger.debug(`[getApiInformation] current version : ${version}`); const apiInfo = new ApiInformation(); apiInfo.version = version; diff --git a/src/controllers/broadcast.controller.ts b/src/controllers/broadcast.controller.ts index 243c7d41..473ad4b7 100644 --- a/src/controllers/broadcast.controller.ts +++ b/src/controllers/broadcast.controller.ts @@ -1,6 +1,7 @@ import {inject} from '@loopback/core'; import {getModelSchemaRef, post} from '@loopback/rest'; import {getLogger, Logger} from 'log4js'; +import * as Sentry from "@sentry/node"; import {BroadcastRequest, BroadcastResponse} from '../models'; import {Broadcast} from '../services'; @@ -60,6 +61,7 @@ export class BroadcastController { }) .catch((reason) => { this.logger.warn(`[sendTx] Something went wrong. error: ${reason}`); + Sentry.captureException(reason); return reject(reason); }); }); diff --git a/src/controllers/health-check.controller.ts b/src/controllers/health-check.controller.ts index 8cee894d..bd12bad2 100644 --- a/src/controllers/health-check.controller.ts +++ b/src/controllers/health-check.controller.ts @@ -1,6 +1,7 @@ import { RestBindings, get, getModelSchemaRef, Response } from '@loopback/rest'; import { getLogger, Logger } from 'log4js'; import { inject } from '@loopback/core'; +import * as Sentry from "@sentry/node"; import { BitcoinService, BridgeService } from '../services'; import { ServicesBindings } from "../dependency-injection-bindings"; import { HealthInformation } from '../models/health-information.model'; @@ -50,16 +51,16 @@ export class HealthCheckController { }, }) async health(): Promise { - const version = packageJson.version; + const {version} = packageJson; this.logger.debug(`[healthCheckController] current version : ${version}`); const health = new HealthInformation(); health.up = true; health.apiVersion = version; - let dataBase: HealthInformationChecks = await this.getDataBaseInfo(health); - let blockBook: BlockBoock = await this.getBlockBookInfo(health); - let rskNode: HealthInformationChecks = await this.getRskNodeInfo(health); - let bridgeService: HealthInformationChecks = await this.getBridgeInfo(health); + const dataBase: HealthInformationChecks = await this.getDataBaseInfo(health); + const blockBook: BlockBoock = await this.getBlockBookInfo(health); + const rskNode: HealthInformationChecks = await this.getRskNodeInfo(health); + const bridgeService: HealthInformationChecks = await this.getBridgeInfo(health); health.dataBase = dataBase; health.blockBook = blockBook; @@ -74,17 +75,18 @@ export class HealthCheckController { } private async getBridgeInfo(health: HealthInformation): Promise { - let bridgeService = new Federation(); + const bridgeService = new Federation(); return this.bridgeService.getFederationAddress().then((address: any) => { if(address) { bridgeService.up = true; bridgeService.federationAddress = address; return bridgeService; - } else { + } throw new Error("Error searching Bridge State"); - } + }).catch((e) => { this.logger.error(`[healthCheckController-BridgeError] error : ${e}`); + Sentry.captureException(e); bridgeService.up = false; health.up = false; return bridgeService; @@ -92,7 +94,7 @@ export class HealthCheckController { } private async getBlockBookInfo(health: HealthInformation): Promise { - let blockBook = new BlockBoock(); + const blockBook = new BlockBoock(); return this.bitcoinService.getLastBlock().then((info: LastBlockInfo) => { if (info) { blockBook.up = true; @@ -102,11 +104,12 @@ export class HealthCheckController { blockBook.syncing = info.inSync; blockBook.chain = info.chain; return blockBook; - } else { + } throw new Error("Error searching BTC Block Number"); - } + }).catch((e) => { this.logger.error(`[healthCheckController-BlockBook] error : ${e}`); + Sentry.captureException(e); blockBook.up = false; health.up = false; return blockBook; @@ -114,17 +117,18 @@ export class HealthCheckController { } private async getRskNodeInfo(health: HealthInformation): Promise { - let rskNode = this.createNewType(); + const rskNode = this.createNewType(); return this.rskNodeService.getBlockNumber().then((blockNumber:number) => { if(blockNumber) { rskNode.up = true; rskNode.lastRskBlockNumber = blockNumber; return rskNode; - } else { + } throw new Error("Error searching block number"); - } + }).catch((e) => { this.logger.error(`[healthCheckController-RskNodeInfoError] error : ${e}`); + Sentry.captureException(e); rskNode.up = false; health.up = false; return rskNode; @@ -132,18 +136,19 @@ export class HealthCheckController { } private async getDataBaseInfo(health: HealthInformation): Promise { - let dataBase = this.createNewType(); + const dataBase = this.createNewType(); return this.syncStorageService.getBestBlock().then((syncStatusModel: SyncStatusModel | undefined) => { if(syncStatusModel) { dataBase.lastRskBlockNumber = syncStatusModel.rskBlockHeight; dataBase.lastRskBlockHash = syncStatusModel.rskBlockHash; dataBase.up = true; return dataBase; - } else { + } throw new Error("[healthCheckController-DataBaseError] - Block info not found"); - } + }).catch((e) => { this.logger.error(`[healthCheckController-DataBaseError] error : ${e}`); + Sentry.captureException(e); health.up = false; dataBase.up = false; return dataBase; diff --git a/src/controllers/pegin-configuration.controller.ts b/src/controllers/pegin-configuration.controller.ts index c084ddcf..e1c870fd 100644 --- a/src/controllers/pegin-configuration.controller.ts +++ b/src/controllers/pegin-configuration.controller.ts @@ -1,6 +1,7 @@ import {repository} from '@loopback/repository'; import {get, getModelSchemaRef} from '@loopback/rest'; import {getLogger, Logger} from 'log4js'; +import * as Sentry from "@sentry/node"; import {PeginConfiguration} from '../models'; import {PeginConfigurationRepository} from '../repositories'; import {BridgeService} from '../services'; @@ -53,6 +54,7 @@ export class PeginConfigurationController { }) .catch((e) => { this.logger.warn(`[get] Got an error: ${e}`); + Sentry.captureException(e); reject(e); }); }); diff --git a/src/controllers/tx.controller.ts b/src/controllers/tx.controller.ts index 8757cc55..e8cda09d 100644 --- a/src/controllers/tx.controller.ts +++ b/src/controllers/tx.controller.ts @@ -1,6 +1,7 @@ import {inject} from '@loopback/core'; import {get, getModelSchemaRef} from '@loopback/rest'; import {getLogger, Logger} from 'log4js'; +import * as Sentry from "@sentry/node"; import {Tx} from '../models'; import {TxService} from '../services'; @@ -47,6 +48,7 @@ export class TxController { }) .catch((reason) => { this.logger.warn(`[getTx] Got an error: ${reason}`); + Sentry.captureException(reason); return reject(reason); }); }); diff --git a/src/controllers/utxo.controller.ts b/src/controllers/utxo.controller.ts index 803d8bb9..adaa6cfe 100644 --- a/src/controllers/utxo.controller.ts +++ b/src/controllers/utxo.controller.ts @@ -1,6 +1,7 @@ import {inject} from '@loopback/core'; import {getModelSchemaRef, post, requestBody, response} from '@loopback/rest'; import {getLogger, Logger} from 'log4js'; +import * as Sentry from "@sentry/node"; import {ServicesBindings} from '../dependency-injection-bindings'; import {AddressList, Utxo} from '../models'; import {UtxoResponse} from '../models/utxo-response.model'; @@ -59,6 +60,7 @@ export class UtxoController { }) .catch(reason => { this.logger.warn(`[getUtxos] Got an error: ${reason}`); + Sentry.captureException(reason); reject(reason); }); }); diff --git a/src/index.ts b/src/index.ts index f4d01077..be00b450 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,6 +3,7 @@ import {configure, getLogger} from 'log4js'; import {ApplicationConfig, TwpapiApplication} from './application'; import {DaemonRunner} from './daemon-runner'; import { ENVIRONMENT_PRODUCTION } from './constants'; +import './instrument'; export * from './application'; diff --git a/src/instrument.ts b/src/instrument.ts new file mode 100644 index 00000000..a02024da --- /dev/null +++ b/src/instrument.ts @@ -0,0 +1,12 @@ +const Sentry = require("@sentry/node"); + +const dsn = process.env.SENTRY_DSN; +if (!dsn) { + throw new Error('SENTRY_DSN is not set'); +} + +Sentry.init({ + dsn, + environment: process.env.SENTRY_ENV || 'staging-testnet', + sendDefaultPii: true, +}); diff --git a/src/services/bridge.service.ts b/src/services/bridge.service.ts index 7a3304ea..21a1b094 100644 --- a/src/services/bridge.service.ts +++ b/src/services/bridge.service.ts @@ -1,5 +1,6 @@ import * as precompiledAbis from '@rsksmart/rsk-precompiled-abis'; import {getLogger, Logger} from 'log4js'; +import * as Sentry from "@sentry/node"; import {ethers} from 'ethers'; import BridgeTransactionParser, {Transaction} from '@rsksmart/bridge-transaction-parser'; import { getBridgeState, BridgeState } from '@rsksmart/bridge-state-data-parser'; @@ -33,6 +34,7 @@ export class BridgeService { }) .catch((reason: any) => { this.logger.warn(`[getFederationAddress] Got an error: ${reason}`); + Sentry.captureException(reason); reject(reason); }); }); @@ -108,11 +110,11 @@ export class BridgeService { } public async getBridgeTransactionByHash(txHash: string): Promise { - return await this.bridgeTransactionParser.getBridgeTransactionByTxHash(txHash); + return this.bridgeTransactionParser.getBridgeTransactionByTxHash(txHash); } public async getBridgeState(defaultBlock: string | number = 'latest'): Promise { - return await getBridgeState(this.host, defaultBlock); + return getBridgeState(this.host, defaultBlock); } } diff --git a/src/services/pegin-status/bitcoin.service.ts b/src/services/pegin-status/bitcoin.service.ts index a8a8a3bb..6cefe788 100644 --- a/src/services/pegin-status/bitcoin.service.ts +++ b/src/services/pegin-status/bitcoin.service.ts @@ -1,5 +1,6 @@ import {inject} from '@loopback/core'; import {getLogger, Logger} from 'log4js'; +import * as Sentry from "@sentry/node"; import {AddressService, TxV2Service} from '..'; import {ServicesBindings} from '../../dependency-injection-bindings'; import {BitcoinAddress} from '../../models/bitcoin-address.model'; @@ -48,6 +49,7 @@ export class BitcoinService { }) .catch(reason => { this.logger.warn(`[getTx] Got an error: ${reason}`); + Sentry.captureException(reason); reject(`Error getting tx ${txId}`); }); }); @@ -74,6 +76,7 @@ export class BitcoinService { resolve(responseAddress); }) .catch(() => { + Sentry.captureException(`Error getting address ${address}`); reject(`Error getting address ${address}`); }); }); @@ -95,6 +98,7 @@ export class BitcoinService { resolve(lastBlockInfo); }) .catch((e) => { + Sentry.captureException(`Error getting last block ${e}`); reject(`Error getting last block ${e}`); }); }); diff --git a/src/services/pegin-status/pegin-status.service.ts b/src/services/pegin-status/pegin-status.service.ts index 1bf0f4a2..d695f510 100644 --- a/src/services/pegin-status/pegin-status.service.ts +++ b/src/services/pegin-status/pegin-status.service.ts @@ -1,5 +1,6 @@ import {inject} from '@loopback/core'; import {getLogger, Logger} from 'log4js'; +import * as Sentry from "@sentry/node"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore import peginAddressVerifier from 'pegin-address-verificator'; @@ -56,26 +57,27 @@ export class PeginStatusService { peginStatusInfo.setRskPeginStatus(rskStatus); this.logger.debug(`Tx: ${btcTxId} includes rsk info. RskAddress: ${rskStatus.recipientAddress} Pegin status: ${peginStatusInfo.status}`); return peginStatusInfo; - } else { + } const peginRskInfo = new RskPeginStatus(); peginRskInfo.recipientAddress = this.destinationAddress; peginStatusInfo.status = Status.NOT_IN_RSK_YET; this.logger.debug(`Tx: ${btcTxId} not in RSK yet. Pegin status: ${peginStatusInfo.status}`); peginStatusInfo.setRskPeginStatus(peginRskInfo); return peginStatusInfo; - } + }); - } else { + } const peginRskInfo = new RskPeginStatus(); peginRskInfo.recipientAddress = this.destinationAddress; peginStatusInfo.status = Status.WAITING_CONFIRMATIONS; this.logger.debug(`Tx: ${btcTxId} waiting confirmations. Pegin status: ${peginStatusInfo.status}`); peginStatusInfo.setRskPeginStatus(peginRskInfo); return peginStatusInfo; - } + }) .catch((e) => { this.logger.warn(`TxId:${btcTxId} Unexpected error trying to obtain information. Error: ${e}`); + Sentry.captureException(e); return new PeginStatusError(btcTxId); }) }; @@ -109,7 +111,7 @@ export class PeginStatusService { if (!this.canBeAPeginSender(btcTx)) { throw new Error(`Is not a pegin. Tx was not processed in Bitcoin network.`); } - const vout = btcTx.vout; + const {vout} = btcTx; const fedDestinationAddress = await this.getTxDestinationFedAddress(vout); if (!fedDestinationAddress) { throw new Error('Is not a pegin. Tx was not sent to valid Federation address.'); @@ -244,11 +246,11 @@ export class PeginStatusService { if (data.length === 96 || data.length === 54) { //Contain refund address this.logger.debug(`Tx contains OPT_RETURN value: ${txId}`); return (true); - } else { + } const errorMessage = `Can not parse OP_RETURN parameter. Invalid transaction: ${txId}`; this.logger.warn(errorMessage); return false; //RSK will return invalid - } + } return (false); } @@ -257,7 +259,7 @@ export class PeginStatusService { try { if (peginAddressVerifier.canPegIn(peginAddressVerifier.getAddressInformation(btcTx.vin[0].addresses[0]))) { return true; - } else if (this.getxDestinationRskAddress(btcTx).length > 0) { + } if (this.getxDestinationRskAddress(btcTx).length > 0) { return true; } } catch { diff --git a/src/services/pegout-data.processor.ts b/src/services/pegout-data.processor.ts index 2030a052..9c6c5338 100644 --- a/src/services/pegout-data.processor.ts +++ b/src/services/pegout-data.processor.ts @@ -45,7 +45,7 @@ export class PegoutDataProcessor implements FilteredBridgeTransactionProcessor { async process(extendedBridgeTx: ExtendedBridgeTx): Promise { try { this.logger.debug(`[process] Got tx ${extendedBridgeTx.txHash}`); - const events: BridgeEvent[] = extendedBridgeTx.events; + const {events} = extendedBridgeTx; if (!this.isMethodAccepted(extendedBridgeTx)) { return this.logger.warn('[process] Received a method not accepted'); @@ -136,7 +136,7 @@ export class PegoutDataProcessor implements FilteredBridgeTransactionProcessor { } const batchPegoutCreationTx = releaseBTCEvent.arguments.releaseRskTxHash; - for(let output of parsedBtcTransaction.outs) { + for(const output of parsedBtcTransaction.outs) { const address = bitcoin.address.fromOutputScript(output.script, btcNetwork); const dbPegout = await this.pegoutStatusDataService.getPegoutByRecipientAndCreationTx(address, batchPegoutCreationTx); @@ -279,7 +279,7 @@ export class PegoutDataProcessor implements FilteredBridgeTransactionProcessor { private async changePegoutsToWaitingForSignatures(dbPegoutsWaitingForConfirmations: PegoutStatusDbDataModel[], extendedBridgeTx: ExtendedBridgeTx) { let index = 0; - for (let oldStatus of dbPegoutsWaitingForConfirmations) { + for (const oldStatus of dbPegoutsWaitingForConfirmations) { const newStatus = PegoutStatusDbDataModel.clonePegoutStatusInstance(oldStatus); newStatus.setRskTxInformation(extendedBridgeTx); newStatus.rskTxHash = `${extendedBridgeTx.txHash}__${index}`; diff --git a/src/services/pegout-status/pegout-status.service.ts b/src/services/pegout-status/pegout-status.service.ts index 352143a0..ff46cc66 100644 --- a/src/services/pegout-status/pegout-status.service.ts +++ b/src/services/pegout-status/pegout-status.service.ts @@ -1,5 +1,6 @@ import {getLogger, Logger} from "log4js"; import {inject} from "@loopback/core"; +import * as Sentry from "@sentry/node"; import Web3 from 'web3'; import {BridgeEvent, Transaction} from '@rsksmart/bridge-transaction-parser'; import {ServicesBindings} from "../../dependency-injection-bindings"; @@ -74,6 +75,7 @@ export class PegoutStatusService { }) .catch((e) => { this.logger.warn(`TxId:${rskTxHash} Unexpected error trying to obtain information. Error: ${e}`); + Sentry.captureException(e); reject(e); }); }); @@ -81,7 +83,7 @@ export class PegoutStatusService { private async processTransaction(extendedBridgeTx: ExtendedBridgeTx): Promise { const pegoutStatus: PegoutStatusAppDataModel = new PegoutStatusAppDataModel(); - const events = extendedBridgeTx.events; + const {events} = extendedBridgeTx; if(this.hasReleaseRequestReceivedEvent(events)) { return PegoutStatusBuilder.fillRequestReceivedStatus(extendedBridgeTx); diff --git a/src/services/rsk-chain-sync.service.ts b/src/services/rsk-chain-sync.service.ts index 128d4318..73d85a22 100644 --- a/src/services/rsk-chain-sync.service.ts +++ b/src/services/rsk-chain-sync.service.ts @@ -97,8 +97,7 @@ export class RskChainSyncService { if (!this.started) { p.then(() => this.start()); } - return p.then(() => { - return this.syncStorageService.getBestBlock().then(result => { + return p.then(() => this.syncStorageService.getBestBlock().then(result => { if (!result) { this.logger.debug( 'No sync data on storage! starting from default height', @@ -109,8 +108,7 @@ export class RskChainSyncService { return syncStatusModel; } return result; - }); - }); + })); } public async sync(): Promise { diff --git a/src/services/rsk-node.service.ts b/src/services/rsk-node.service.ts index 38e0933b..0871d7db 100644 --- a/src/services/rsk-node.service.ts +++ b/src/services/rsk-node.service.ts @@ -1,5 +1,6 @@ import BridgeTransactionParser, { Transaction } from '@rsksmart/bridge-transaction-parser'; import Web3, { Block } from 'web3'; +import * as Sentry from "@sentry/node"; import { ethers } from 'ethers'; import { RskTransaction } from '../models/rsk/rsk-transaction.model'; import * as constants from '../constants'; @@ -53,12 +54,18 @@ export class RskNodeService { return resolve(rskTx); } }) - .catch((reason) => reject(reason)); + .catch((reason) => { + Sentry.captureException(reason); + return reject(reason); + }); } else { return resolve(rskTx); } }) - .catch((reason) => reject(reason)); + .catch((reason) => { + Sentry.captureException(reason); + return reject(reason); + }); }); } } diff --git a/src/services/sync-status-mongo.service.ts b/src/services/sync-status-mongo.service.ts index 4715e2dd..73183937 100644 --- a/src/services/sync-status-mongo.service.ts +++ b/src/services/sync-status-mongo.service.ts @@ -1,10 +1,10 @@ /* eslint-disable @typescript-eslint/no-floating-promises */ import {getLogger, Logger} from 'log4js'; import mongoose from 'mongoose'; +import * as Sentry from "@sentry/node"; import {SyncStatusModel} from '../models/rsk/sync-status.model'; import {MongoDbDataService} from './mongodb-data.service'; import {SyncStatusDataService} from './sync-status-data.service'; - /* - THESE MODEL INTERFACES AND CLASSES ARE REQUIRED FOR MONGO BUT WE DON'T WANT THEM EXPOSED OUT OF THIS LAYER */ @@ -51,6 +51,7 @@ export class SyncStatusMongoService extends MongoDbDataService (result[0])) .catch((reason) => { this.logger.warn(`[getBestBlock] Got an error: ${reason}`); + Sentry.captureException(reason); return undefined; }); } diff --git a/src/utils/bridge-utils.ts b/src/utils/bridge-utils.ts index 2e8b35ce..dffe2719 100644 --- a/src/utils/bridge-utils.ts +++ b/src/utils/bridge-utils.ts @@ -40,13 +40,13 @@ export function getBridgeSignature(methodOrEvent: BRIDGE_METHODS | BRIDGE_EVENTS if (event) { return event.topicHash; } - throw new Error(methodOrEvent + " does not exist in Bridge abi"); + throw new Error(`${methodOrEvent } does not exist in Bridge abi`); } export function getBridgeMethodABI(method: BRIDGE_METHODS): any { const abi = precompiledAbis.bridge.abi.find((m: any) => m.name === method); if (!abi) { - throw new Error(method + " does not exist in Bridge abi"); + throw new Error(`${method } does not exist in Bridge abi`); } return abi; } diff --git a/src/utils/btc-utils.ts b/src/utils/btc-utils.ts index 26a4f54d..fb55037a 100644 --- a/src/utils/btc-utils.ts +++ b/src/utils/btc-utils.ts @@ -61,7 +61,7 @@ export class BtcAddressUtils { } public getBtcAddressFromHash(hash160: string): string { - let hash = remove0x(hash160); + const hash = remove0x(hash160); try{ // Since Fingerroot the "release_request_received" event changed and now the btcDestinationAddress is a proper Base58 address // Check if the length of the data is different than 40, then it should be an address, otherwise treat it as a hash160 @@ -94,13 +94,13 @@ export class BtcAddressUtils { if (netName == 'mainnet') { if (type == 'P2PKH') { return '00'; - } else if (type == 'P2SH') { + } if (type == 'P2SH') { return '05'; } } else if (netName == 'testnet') { if (type == 'P2PKH') { return '6F'; - } else if (type == 'P2SH') { + } if (type == 'P2SH') { return 'C4'; } } diff --git a/src/utils/hex-utils.ts b/src/utils/hex-utils.ts index 7403b64a..3c431fb5 100644 --- a/src/utils/hex-utils.ts +++ b/src/utils/hex-utils.ts @@ -1,18 +1,14 @@ -export const ensure0x = (value: string) => { - return value.startsWith('0x') ? value : '0x' + value; -}; +export const ensure0x = (value: string) => value.startsWith('0x') ? value : `0x${ value}`; -export const remove0x = (value: string) => { - return !value.startsWith('0x') ? value : value.substring(2); -} +export const remove0x = (value: string) => !value.startsWith('0x') ? value : value.substring(2) export const ensureRskHashLength = (hash: string) => { - const length = hash.length; + const {length} = hash; if(length === 64) { return hash; - } else if (length === 63) { - return '0' + hash; - } else if (length === 66) { + } if (length === 63) { + return `0${ hash}`; + } if (length === 66) { return remove0x(hash); } }