From 80f8dd3fd7e1852f4e31cfa10f273abb517f97c8 Mon Sep 17 00:00:00 2001 From: baha Date: Wed, 1 Oct 2025 23:26:30 +0300 Subject: [PATCH] feat: add sentry monitoring --- .env.sample | 2 + package-lock.json | 184 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 4 +- src/App.tsx | 21 ++++-- src/index.tsx | 19 +++++ src/vite-env.d.ts | 2 + vite.config.ts | 2 + 7 files changed, 228 insertions(+), 6 deletions(-) diff --git a/.env.sample b/.env.sample index 63b0d53..8d1c8ca 100644 --- a/.env.sample +++ b/.env.sample @@ -2,3 +2,5 @@ VITE_BASE_SIGNING_URL= VITE_BTC_DEFAULT_FEE_RATE= VITE_BTC_TX_BASE_URL= VITE_BTC_TESTNET= +VITE_SENTRY_DSN= +VITE_SENTRY_ENVIRONMENT= diff --git a/package-lock.json b/package-lock.json index 143a7b9..1a93c36 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@fortawesome/free-brands-svg-icons": "^6.2.0", "@fortawesome/free-solid-svg-icons": "^6.2.0", "@fortawesome/react-fontawesome": "^0.2.0", + "@sentry/react": "^10.17.0", "@solana/web3.js": "^1.63.1", "antd": "^4.21.3", "bech32": "^2.0.0", @@ -1758,6 +1759,98 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/@sentry-internal/browser-utils": { + "version": "10.17.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-10.17.0.tgz", + "integrity": "sha512-jXC7dtItZYNGP+K9Lo+3MWaWaGVI6uDIPGB9BAZkZntc/1lGfhMPm7Fo2qb1N1bUP0vOTJ2TmSUA8GNxyxgekQ==", + "license": "MIT", + "dependencies": { + "@sentry/core": "10.17.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry-internal/feedback": { + "version": "10.17.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-10.17.0.tgz", + "integrity": "sha512-KIIF/dDQqYENbx4vn6B0evy/qx1QtEZsSZRvXNX6tUm14CCyrZeDymBMyEzu8RQ5PeZXibbPEkz7xOXiG3q+eQ==", + "license": "MIT", + "dependencies": { + "@sentry/core": "10.17.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry-internal/replay": { + "version": "10.17.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-10.17.0.tgz", + "integrity": "sha512-9kirOPp3wbf+TMyHmA8iStKAysklZPcrPlB0v2zh0qRj1zNFY0xAD2WSgxuCvD9rEo5qKhmAKcaT7Ujin64uSw==", + "license": "MIT", + "dependencies": { + "@sentry-internal/browser-utils": "10.17.0", + "@sentry/core": "10.17.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry-internal/replay-canvas": { + "version": "10.17.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-10.17.0.tgz", + "integrity": "sha512-GXKZIraXrboP03+XS+KwkkKVJO+cSlM0HrfjePSfFqiNbbnjRhOLekoLuDvvH/ZEXPUoUJD1We5IPBg+sZZQfQ==", + "license": "MIT", + "dependencies": { + "@sentry-internal/replay": "10.17.0", + "@sentry/core": "10.17.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/browser": { + "version": "10.17.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-10.17.0.tgz", + "integrity": "sha512-X4OiGECzkp6tIyAKXB/9beBC2oX1xKOEkDo4v/phIKGPzrmQ4o55j2a6/V20jSfSN7w+kfZ56ILE71SzC9w1aQ==", + "license": "MIT", + "dependencies": { + "@sentry-internal/browser-utils": "10.17.0", + "@sentry-internal/feedback": "10.17.0", + "@sentry-internal/replay": "10.17.0", + "@sentry-internal/replay-canvas": "10.17.0", + "@sentry/core": "10.17.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/core": { + "version": "10.17.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.17.0.tgz", + "integrity": "sha512-UVIvxSzS0n5QbIDPyFf0WX9I77Of1bcr6a0sCEKfjhJGmGQ8mFWoWgR2gF4wcPw60XUrzbryCr79eOsIHLQ5cw==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/react": { + "version": "10.17.0", + "resolved": "https://registry.npmjs.org/@sentry/react/-/react-10.17.0.tgz", + "integrity": "sha512-vSJ1+HruWBoQtWlK8r/SSTUyA6cQ2Xc+NNRzIdsVHWUCSo/lAA4UvxqLXyIkEtftqS1+N/+WrMOCf09XuHWpqg==", + "license": "MIT", + "dependencies": { + "@sentry/browser": "10.17.0", + "@sentry/core": "10.17.0", + "hoist-non-react-statics": "^3.3.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react": "^16.14.0 || 17.x || 18.x || 19.x" + } + }, "node_modules/@sinclair/typebox": { "version": "0.24.51", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", @@ -5522,6 +5615,21 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, "node_modules/homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -12310,6 +12418,67 @@ } } }, + "@sentry-internal/browser-utils": { + "version": "10.17.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-10.17.0.tgz", + "integrity": "sha512-jXC7dtItZYNGP+K9Lo+3MWaWaGVI6uDIPGB9BAZkZntc/1lGfhMPm7Fo2qb1N1bUP0vOTJ2TmSUA8GNxyxgekQ==", + "requires": { + "@sentry/core": "10.17.0" + } + }, + "@sentry-internal/feedback": { + "version": "10.17.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-10.17.0.tgz", + "integrity": "sha512-KIIF/dDQqYENbx4vn6B0evy/qx1QtEZsSZRvXNX6tUm14CCyrZeDymBMyEzu8RQ5PeZXibbPEkz7xOXiG3q+eQ==", + "requires": { + "@sentry/core": "10.17.0" + } + }, + "@sentry-internal/replay": { + "version": "10.17.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-10.17.0.tgz", + "integrity": "sha512-9kirOPp3wbf+TMyHmA8iStKAysklZPcrPlB0v2zh0qRj1zNFY0xAD2WSgxuCvD9rEo5qKhmAKcaT7Ujin64uSw==", + "requires": { + "@sentry-internal/browser-utils": "10.17.0", + "@sentry/core": "10.17.0" + } + }, + "@sentry-internal/replay-canvas": { + "version": "10.17.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-10.17.0.tgz", + "integrity": "sha512-GXKZIraXrboP03+XS+KwkkKVJO+cSlM0HrfjePSfFqiNbbnjRhOLekoLuDvvH/ZEXPUoUJD1We5IPBg+sZZQfQ==", + "requires": { + "@sentry-internal/replay": "10.17.0", + "@sentry/core": "10.17.0" + } + }, + "@sentry/browser": { + "version": "10.17.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-10.17.0.tgz", + "integrity": "sha512-X4OiGECzkp6tIyAKXB/9beBC2oX1xKOEkDo4v/phIKGPzrmQ4o55j2a6/V20jSfSN7w+kfZ56ILE71SzC9w1aQ==", + "requires": { + "@sentry-internal/browser-utils": "10.17.0", + "@sentry-internal/feedback": "10.17.0", + "@sentry-internal/replay": "10.17.0", + "@sentry-internal/replay-canvas": "10.17.0", + "@sentry/core": "10.17.0" + } + }, + "@sentry/core": { + "version": "10.17.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.17.0.tgz", + "integrity": "sha512-UVIvxSzS0n5QbIDPyFf0WX9I77Of1bcr6a0sCEKfjhJGmGQ8mFWoWgR2gF4wcPw60XUrzbryCr79eOsIHLQ5cw==" + }, + "@sentry/react": { + "version": "10.17.0", + "resolved": "https://registry.npmjs.org/@sentry/react/-/react-10.17.0.tgz", + "integrity": "sha512-vSJ1+HruWBoQtWlK8r/SSTUyA6cQ2Xc+NNRzIdsVHWUCSo/lAA4UvxqLXyIkEtftqS1+N/+WrMOCf09XuHWpqg==", + "requires": { + "@sentry/browser": "10.17.0", + "@sentry/core": "10.17.0", + "hoist-non-react-statics": "^3.3.2" + } + }, "@sinclair/typebox": { "version": "0.24.51", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", @@ -15332,6 +15501,21 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, "homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", diff --git a/package.json b/package.json index 41f98d5..02bd0d6 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "@fortawesome/free-brands-svg-icons": "^6.2.0", "@fortawesome/free-solid-svg-icons": "^6.2.0", "@fortawesome/react-fontawesome": "^0.2.0", + "@sentry/react": "^10.17.0", "@solana/web3.js": "^1.63.1", "antd": "^4.21.3", "bech32": "^2.0.0", @@ -66,5 +67,6 @@ }, "msw": { "workerDirectory": "public" - } + }, + "packageManager": "pnpm@10.17.1+sha512.17c560fca4867ae9473a3899ad84a88334914f379be46d455cbf92e5cf4b39d34985d452d2583baf19967fa76cb5c17bc9e245529d0b98745721aa7200ecaf7a" } diff --git a/src/App.tsx b/src/App.tsx index 18f2f43..91d398a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,5 @@ import React from "react"; +import * as Sentry from "@sentry/react"; import "antd/dist/antd.dark.min.css"; import "./styles.css"; import { Main } from "./components"; @@ -6,11 +7,21 @@ import { AppContextProvider } from "./store/AppContext"; function App() { return ( -
- -
- -
+ ( +
+

Something went wrong

+

{error instanceof Error ? error.message : "An unexpected error occurred"}

+ +
+ )} + > +
+ +
+ +
+
); } diff --git a/src/index.tsx b/src/index.tsx index 3fd3a69..261c445 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,7 +1,26 @@ import React from "react"; import ReactDOM from "react-dom/client"; +import * as Sentry from "@sentry/react"; import App from "./App"; +// Initialize Sentry if DSN is provided +if (SENTRY_DSN) { + Sentry.init({ + dsn: SENTRY_DSN, + environment: SENTRY_ENVIRONMENT || "production", + integrations: [ + Sentry.browserTracingIntegration(), + Sentry.replayIntegration(), + ], + // Performance Monitoring + tracesSampleRate: 1.0, + // Session Replay + replaysSessionSampleRate: 0.1, + replaysOnErrorSampleRate: 1.0, + release: APP_VERSION, + }); +} + ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index fe15b4f..c57b29c 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -1,3 +1,5 @@ /// declare const APP_VERSION: string; +declare const SENTRY_DSN: string; +declare const SENTRY_ENVIRONMENT: string; diff --git a/vite.config.ts b/vite.config.ts index 1222da1..8fd54c5 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -11,6 +11,8 @@ export default defineConfig(({ mode }) => ({ BTC_DEFAULT_FEE_RATE: JSON.stringify(process.env.VITE_BTC_DEFAULT_FEE_RATE), BTC_TX_BASE_URL: JSON.stringify(process.env.VITE_BTC_TX_BASE_URL), BTC_TESTNET: JSON.stringify(process.env.VITE_BTC_TESTNET), + SENTRY_DSN: JSON.stringify(process.env.VITE_SENTRY_DSN), + SENTRY_ENVIRONMENT: JSON.stringify(process.env.VITE_SENTRY_ENVIRONMENT), "process.env": {}, }, server: {