diff --git a/.github/workflows/app-preview.yaml b/.github/workflows/app-preview.yaml index 9da150e5..28b81236 100644 --- a/.github/workflows/app-preview.yaml +++ b/.github/workflows/app-preview.yaml @@ -26,6 +26,8 @@ jobs: - run: pnpm install --prefer-offline - run: pnpm build + env: + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} - name: Deploy id: deploy diff --git a/deployables/app/app/entry.client.tsx b/deployables/app/app/entry.client.tsx new file mode 100644 index 00000000..e0e52b0b --- /dev/null +++ b/deployables/app/app/entry.client.tsx @@ -0,0 +1,25 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import { HydratedRouter } from 'react-router/dom' +import './app.css' + +import * as Sentry from '@sentry/react' + +Sentry.init({ + dsn: 'https://23cb3bbf49ea43ed9bbaf41199c40d1c@o4508675621912576.ingest.us.sentry.io/4508676926078976', + integrations: [Sentry.browserTracingIntegration()], + // Tracing + tracesSampleRate: 1.0, // Capture 100% of the transactions + // Set 'tracePropagationTargets' to control for which URLs distributed tracing should be enabled + tracePropagationTargets: [ + 'localhost', + /^https:\/\/app\.pilot\.gnosisguild\.org/, + ], +}) + +ReactDOM.hydrateRoot( + document, + + + , +) diff --git a/deployables/app/app/root.tsx b/deployables/app/app/root.tsx index 1791388c..37fdd293 100644 --- a/deployables/app/app/root.tsx +++ b/deployables/app/app/root.tsx @@ -7,7 +7,6 @@ import { ScrollRestoration, } from 'react-router' import type { Route } from './+types/root' -import './app.css' export function Layout({ children }: { children: React.ReactNode }) { return ( diff --git a/deployables/app/app/routes/edit-route.$data.tsx b/deployables/app/app/routes/edit-route.$data.tsx index 3898855c..9121a79d 100644 --- a/deployables/app/app/routes/edit-route.$data.tsx +++ b/deployables/app/app/routes/edit-route.$data.tsx @@ -79,7 +79,7 @@ export const action = async ({ request, params }: Route.ActionArgs) => { multisend: await getMultisend(route, module), }) - return editRoute(request.url, updatedRoute) + return editRoute(updatedRoute) } export const clientAction = async ({ @@ -107,26 +107,25 @@ export const clientAction = async ({ { type: CompanionAppMessageType.SAVE_ROUTE, data: route }, '*', ) - // chrome.runtime.sendMessage('', route) - return editRoute(request.url, route) + return editRoute(route) } case Intent.UpdateChain: { const route = parseRouteData(params.data) const chainId = verifyChainId(getInt(data, 'chainId')) - return editRoute(request.url, updateChainId(route, chainId)) + return editRoute(updateChainId(route, chainId)) } case Intent.UpdateAvatar: { const route = parseRouteData(params.data) const avatar = getHexString(data, 'avatar') - return editRoute(request.url, updateAvatar(route, { safe: avatar })) + return editRoute(updateAvatar(route, { safe: avatar })) } case Intent.RemoveAvatar: { const route = parseRouteData(params.data) - return editRoute(request.url, removeAvatar(route)) + return editRoute(removeAvatar(route)) } case Intent.ConnectWallet: { const route = parseRouteData(params.data) @@ -136,7 +135,6 @@ export const clientAction = async ({ const providerType = verifyProviderType(getInt(data, 'providerType')) return editRoute( - request.url, updatePilotAddress( updateChainId(updateProviderType(route, providerType), chainId), account, @@ -146,7 +144,7 @@ export const clientAction = async ({ case Intent.DisconnectWallet: { const route = parseRouteData(params.data) - return editRoute(request.url, updatePilotAddress(route, ZERO_ADDRESS)) + return editRoute(updatePilotAddress(route, ZERO_ADDRESS)) } default: return serverAction() diff --git a/deployables/app/app/routes/new-route.ts b/deployables/app/app/routes/new-route.ts index b4032b55..12cd7184 100644 --- a/deployables/app/app/routes/new-route.ts +++ b/deployables/app/app/routes/new-route.ts @@ -1,6 +1,4 @@ import { editRoute } from '@/utils' import { createBlankRoute } from '@zodiac/modules' -import type { Route } from './+types/new-route' -export const loader = ({ request }: Route.LoaderArgs) => - editRoute(request.url, createBlankRoute()) +export const loader = () => editRoute(createBlankRoute()) diff --git a/deployables/app/app/utils/editRoute.ts b/deployables/app/app/utils/editRoute.ts index e3c23c30..c94b5299 100644 --- a/deployables/app/app/utils/editRoute.ts +++ b/deployables/app/app/utils/editRoute.ts @@ -1,9 +1,5 @@ import type { ExecutionRoute } from '@zodiac/schema' +import { redirect } from 'react-router' -export const editRoute = (currentUrl: string, route: ExecutionRoute) => { - const url = new URL(currentUrl) - - return Response.redirect( - new URL(`/edit-route/${btoa(JSON.stringify(route))}`, url.origin), - ) -} +export const editRoute = (route: ExecutionRoute) => + redirect(`/edit-route/${btoa(JSON.stringify(route))}`) diff --git a/deployables/app/package.json b/deployables/app/package.json index 19417134..192e8104 100644 --- a/deployables/app/package.json +++ b/deployables/app/package.json @@ -16,6 +16,7 @@ "@epic-web/invariant": "^1.0.0", "@react-router/node": "^7.1.1", "@react-router/serve": "^7.1.1", + "@sentry/react": "^8.50.0", "@tanstack/react-query": "^5.56.2", "@zodiac/chains": "workspace:*", "@zodiac/form-data": "workspace:*", @@ -42,6 +43,7 @@ "@hiogawa/vite-node-miniflare": "0.1.1", "@playwright/test": "^1.48.1", "@react-router/dev": "^7.1.1", + "@sentry/vite-plugin": "^3.0.0", "@testing-library/jest-dom": "^6.4.6", "@testing-library/react": "^16.0.1", "@testing-library/user-event": "14.6.0", diff --git a/deployables/app/vite.config.ts b/deployables/app/vite.config.ts index 3cff78d5..4e99edc3 100644 --- a/deployables/app/vite.config.ts +++ b/deployables/app/vite.config.ts @@ -1,5 +1,6 @@ import { reactRouter } from '@react-router/dev/vite' import { cloudflareDevProxy } from '@react-router/dev/vite/cloudflare' +import { sentryVitePlugin } from '@sentry/vite-plugin' import autoprefixer from 'autoprefixer' import tailwindcss from 'tailwindcss' import { defineConfig } from 'vite' @@ -12,6 +13,7 @@ export default defineConfig(({ isSsrBuild }) => ({ input: './workers/app.ts', } : undefined, + sourcemap: true, }, server: { port: 3040, @@ -26,7 +28,6 @@ export default defineConfig(({ isSsrBuild }) => ({ }, ssr: { target: 'webworker', - // noExternal: true, resolve: { conditions: ['workerd', 'browser'], }, @@ -42,5 +43,14 @@ export default defineConfig(({ isSsrBuild }) => ({ }, noExternal: ['@gnosis.pm/zodiac', 'evm-proxy-detection'], }, - plugins: [cloudflareDevProxy(), reactRouter(), tsconfigPaths()], + plugins: [ + cloudflareDevProxy(), + reactRouter(), + tsconfigPaths(), + sentryVitePlugin({ + authToken: process.env.SENTRY_AUTH_TOKEN, + org: 'gnosis-guild', + project: 'pilot-companion-app', + }), + ], })) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 299955d3..5286619e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -85,6 +85,9 @@ importers: '@react-router/serve': specifier: ^7.1.1 version: 7.1.3(react-router@7.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(typescript@5.7.3) + '@sentry/react': + specifier: ^8.50.0 + version: 8.50.0(react@19.0.0) '@tanstack/react-query': specifier: ^5.56.2 version: 5.64.2(react@19.0.0) @@ -158,6 +161,9 @@ importers: '@react-router/dev': specifier: ^7.1.1 version: 7.1.3(@react-router/serve@7.1.3(react-router@7.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(typescript@5.7.3))(@types/node@22.10.7)(babel-plugin-macros@3.1.0)(jiti@2.4.1)(less@4.2.1)(lightningcss@1.28.2)(react-router@7.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(sass@1.82.0)(stylus@0.62.0)(typescript@5.7.3)(vite@6.0.10(@types/node@22.10.7)(jiti@2.4.1)(less@4.2.1)(lightningcss@1.28.2)(sass@1.82.0)(stylus@0.62.0)(yaml@2.7.0))(wrangler@3.103.2(@cloudflare/workers-types@4.20250109.0)(bufferutil@4.0.9)(utf-8-validate@5.0.10))(yaml@2.7.0) + '@sentry/vite-plugin': + specifier: ^3.0.0 + version: 3.0.0 '@testing-library/jest-dom': specifier: ^6.4.6 version: 6.6.3 @@ -3027,6 +3033,16 @@ packages: resolution: {integrity: sha512-8Ga7gMjlmZrTBq6CIxa1fcFZtvxLSb40qsYAjxFH2njoAr5PplfnYRD0H2i/AhdOld2dsJNanuv65OW2DZTdiQ==} engines: {node: '>= 14'} + '@sentry/react@8.50.0': + resolution: {integrity: sha512-qkDW5dieROPDf0uk1usXib/SLZTEveN5jvKgBFd+HKWz5JNu+M7L53t9KdZ7ryn4T68utI/LWs4qR3QhmXzUbQ==} + engines: {node: '>=14.18'} + peerDependencies: + react: ^16.14.0 || 17.x || 18.x || 19.x + + '@sentry/vite-plugin@3.0.0': + resolution: {integrity: sha512-E2elyHjP3Wqnk2uXr9C17jHRQBKX8jEOpzOnEOiXYDI2FBfehs9ttj9yX1I7H8ofCiqO2EsTu5r2a0C26ZWi+w==} + engines: {node: '>= 14'} + '@shazow/whatsabi@0.19.0': resolution: {integrity: sha512-18LfRRaTrn58mFUgCFvShiYqVuiDkx8TJWHzVcpaQu5O8+H8u9Pe+I3xlZeUTrGq6XQepPF7C8Uf9Sv7o26j0Q==} peerDependencies: @@ -6089,9 +6105,6 @@ packages: engines: {node: '>=10'} hasBin: true - mlly@1.7.3: - resolution: {integrity: sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A==} - mlly@1.7.4: resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} @@ -10785,6 +10798,21 @@ snapshots: - encoding - supports-color + '@sentry/react@8.50.0(react@19.0.0)': + dependencies: + '@sentry/browser': 8.50.0 + '@sentry/core': 8.50.0 + hoist-non-react-statics: 3.3.2 + react: 19.0.0 + + '@sentry/vite-plugin@3.0.0': + dependencies: + '@sentry/bundler-plugin-core': 3.0.0 + unplugin: 1.0.1 + transitivePeerDependencies: + - encoding + - supports-color + '@shazow/whatsabi@0.19.0(@noble/hashes@1.7.1)(typescript@5.7.3)(zod@3.24.1)': dependencies: '@noble/hashes': 1.7.1 @@ -11183,12 +11211,12 @@ snapshots: '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.0) '@vanilla-extract/babel-plugin-debug-ids': 1.2.0 '@vanilla-extract/css': 1.17.0(babel-plugin-macros@3.1.0) - esbuild: 0.17.6 + esbuild: 0.17.19 eval: 0.1.8 find-up: 5.0.0 javascript-stringify: 2.1.0 lodash: 4.17.21 - mlly: 1.7.3 + mlly: 1.7.4 outdent: 0.8.0 vite: 5.4.13(@types/node@22.10.7)(less@4.2.1)(lightningcss@1.28.2)(sass@1.82.0)(stylus@0.62.0) vite-node: 1.6.0(@types/node@22.10.7)(less@4.2.1)(lightningcss@1.28.2)(sass@1.82.0)(stylus@0.62.0) @@ -15136,13 +15164,6 @@ snapshots: mkdirp@1.0.4: {} - mlly@1.7.3: - dependencies: - acorn: 8.14.0 - pathe: 1.1.2 - pkg-types: 1.3.1 - ufo: 1.5.4 - mlly@1.7.4: dependencies: acorn: 8.14.0