Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
2213000
Merge pull request #745 from AlphadayHQ/dependabot/npm_and_yarn/ajv-6…
dependabot[bot] Jun 17, 2026
a5ec650
chore(deps): bump @isaacs/brace-expansion from 5.0.0 to 5.0.1 (#744)
dependabot[bot] Jun 17, 2026
e457a7d
Merge pull request #750 from AlphadayHQ/dependabot/npm_and_yarn/immut…
dependabot[bot] Jun 17, 2026
c45bf27
Merge pull request #760 from AlphadayHQ/dependabot/npm_and_yarn/brace…
dependabot[bot] Jun 17, 2026
02fe42e
chore(deps): bump flatted from 3.3.3 to 3.4.2 (#753)
dependabot[bot] Jun 17, 2026
83b9b6d
Merge pull request #752 from AlphadayHQ/dependabot/npm_and_yarn/h3-1.…
dependabot[bot] Jun 17, 2026
e780680
chore(deps): bump fast-uri from 3.1.0 to 3.1.2 (#774)
dependabot[bot] Jun 17, 2026
f2808d9
chore(deps): bump defu from 6.1.4 to 6.1.6 (#764)
dependabot[bot] Jun 17, 2026
e0e0ec3
chore(deps): bump path-to-regexp from 0.1.12 to 0.1.13 (#763)
dependabot[bot] Jun 17, 2026
7268c33
chore(deps): bump shell-quote from 1.8.3 to 1.8.4 (#784)
dependabot[bot] Jun 17, 2026
9a62bba
chore(deps): bump tmp from 0.2.5 to 0.2.7 (#781)
dependabot[bot] Jun 17, 2026
8ff5ace
chore(deps): bump protobufjs from 6.11.4 to 6.11.6 (#777)
dependabot[bot] Jun 17, 2026
54cb6df
chore(deps-dev): bump vite from 8.0.12 to 8.0.16 (#790)
dependabot[bot] Jun 17, 2026
c9fc9eb
chore(deps): bump @babel/core from 7.28.5 to 7.29.7 (#791)
dependabot[bot] Jun 17, 2026
55499c0
chore(deps): bump dompurify from 3.2.4 to 3.4.9 (#789)
dependabot[bot] Jun 18, 2026
8a2a863
chore(deps): bump @babel/plugin-transform-modules-systemjs from 7.28.…
dependabot[bot] Jun 18, 2026
433ce1b
chore(deps): bump yaml from 1.10.2 to 1.10.3 (#755)
dependabot[bot] Jun 18, 2026
02519cc
chore(deps-dev): bump svgo from 3.2.0 to 3.3.3 (#748)
dependabot[bot] Jun 18, 2026
6ecdebe
chore(deps-dev): bump happy-dom from 20.0.11 to 20.8.9 (#762)
dependabot[bot] Jun 18, 2026
e84a209
chore(deps-dev): bump svgo from 3.2.0 to 3.3.3 in /packages/frontend …
dependabot[bot] Jun 18, 2026
8f7114f
chore(deps): bump @protobufjs/utf8 from 1.1.0 to 1.1.1 (#776)
dependabot[bot] Jun 18, 2026
50ae340
chore(deps): bump uuid from 9.0.0 to 14.0.0 (#778)
dependabot[bot] Jun 18, 2026
d45ade7
chore(deps): bump dompurify from 3.4.9 to 3.4.11 (#792)
dependabot[bot] Jun 18, 2026
d3cf881
fix: Bump Deploy ScriptsNode To 22 (#787)
Xavier-Charles Jun 18, 2026
1c43f96
chore(deps): bump react-quick-pinch-zoom from 5.1.0 to 5.1.1 (#797)
dependabot[bot] Jun 22, 2026
689a336
fix: Google-ga4 Imports (#798)
Xavier-Charles Jul 13, 2026
6bc6be1
enhance: Allow Shorts in Video and Media Widgets (#801)
Xavier-Charles Jul 13, 2026
ec551f2
feat: Revenue And Fees Widget (#802)
Xavier-Charles Jul 13, 2026
9f9292c
feat: Top Liquidity Providers Widgets (#803)
Xavier-Charles Jul 13, 2026
378f67c
fix(textUtils): Emit Auto-link target/rel via Mdast (#794)
Xavier-Charles Jul 13, 2026
d9b38ff
chore(deps): bump websocket-driver from 0.7.4 to 0.7.5 (#804)
dependabot[bot] Aug 19, 2026
60db4d7
chore(deps): bump immutable from 4.3.8 to 4.3.9 (#814)
dependabot[bot] Aug 19, 2026
235536e
chore(deps): bump shell-quote from 1.8.4 to 1.10.0 (#815)
dependabot[bot] Aug 19, 2026
5940710
chore(deps): bump body-parser from 1.20.4 to 1.20.6 (#816)
dependabot[bot] Aug 19, 2026
53f2f49
chore(deps): bump brace-expansion from 1.1.13 to 1.1.18 (#819)
dependabot[bot] Aug 19, 2026
676a97c
chore(deps): bump fast-uri from 3.1.2 to 3.1.5 (#820)
dependabot[bot] Aug 19, 2026
f2250a3
chore(deps): bump dompurify from 3.4.11 to 3.4.13 (#822)
dependabot[bot] Aug 19, 2026
aef2cc1
chore: Update Deploy Scripts (#826)
Xavier-Charles Aug 19, 2026
50a47e8
chore(deps-dev): bump @typescript-eslint/eslint-plugin from 5.54.0 to…
dependabot[bot] Aug 20, 2026
c514817
chore(deps): bump unist-util-visit from 5.0.0 to 5.1.0 (#800)
dependabot[bot] Aug 20, 2026
8658c36
chore(deps-dev): bump svgo from 3.3.3 to 3.3.4 (#808)
dependabot[bot] Aug 20, 2026
452f263
chore(deps-dev): bump postcss from 8.4.47 to 8.5.23 (#824)
dependabot[bot] Aug 20, 2026
ca5a042
feat: Developer Activity (#805)
Xavier-Charles Aug 20, 2026
e461192
feat: Security Exploits Widget (#806)
Xavier-Charles Aug 20, 2026
9079c3e
chore: Version Bump 4.2.0 (#827)
Xavier-Charles Aug 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/basic-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-node@v3
with:
node-version: "18.15.0"
node-version: "22.12.0"
cache: "yarn"
cache-dependency-path: |
yarn.lock
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/deploy-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:

- uses: actions/setup-node@v3
with:
node-version: "20.11.0"
node-version: "22.12.0"
cache: "yarn"
cache-dependency-path: |
yarn.lock
Expand Down Expand Up @@ -94,7 +94,7 @@ jobs:
- name: deploy
uses: kefranabg/s3-sync-action@master # https://github.com/kefranabg/s3-sync-action
with:
args: --acl public-read --follow-symlinks --delete
args: --follow-symlinks --delete
env:
AWS_ACCESS_KEY_ID: ${{ secrets.DEPLOYER__AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.DEPLOYER__SECRET_ACCESS_KEY }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/deploy-epsilon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:

- uses: actions/setup-node@v3
with:
node-version: "18.15.0"
node-version: "22.12.0"
cache: "yarn"
cache-dependency-path: |
yarn.lock
Expand Down Expand Up @@ -83,7 +83,7 @@ jobs:
- name: deploy
uses: kefranabg/s3-sync-action@master # https://github.com/kefranabg/s3-sync-action
with:
args: --acl public-read --follow-symlinks
args: --follow-symlinks
env:
AWS_ACCESS_KEY_ID: ${{ secrets.DEPLOYER__AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.DEPLOYER__SECRET_ACCESS_KEY }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/deploy-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:

- uses: actions/setup-node@v3
with:
node-version: "20.11.0"
node-version: "22.12.0"
cache: "yarn"
cache-dependency-path: |
yarn.lock
Expand Down Expand Up @@ -98,7 +98,7 @@ jobs:
- name: deploy
uses: kefranabg/s3-sync-action@master # https://github.com/kefranabg/s3-sync-action
with:
args: --acl public-read --follow-symlinks --delete
args: --follow-symlinks --delete
env:
AWS_ACCESS_KEY_ID: ${{ secrets.DEPLOYER__AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.DEPLOYER__SECRET_ACCESS_KEY }}
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"@types/cypress-cucumber-preprocessor": "4.0.5",
"@types/react": "18.2.25",
"@types/react-dom": "18.2.6",
"@typescript-eslint/eslint-plugin": "5.54.0",
"@typescript-eslint/eslint-plugin": "5.62.0",
"@typescript-eslint/parser": "5.62.0",
"@vitejs/plugin-react": "6.0.1",
"autoprefixer": "10.4.21",
Expand All @@ -47,7 +47,7 @@
"husky": "8.0.3",
"prettier": "3.5.3",
"typescript": "5.9.3",
"vite": "8.0.12",
"vite": "8.0.16",
"vite-tsconfig-paths": "6.1.1",
"vitest": "4.1.5"
},
Expand Down
12 changes: 6 additions & 6 deletions packages/frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@alphaday/frontend",
"private": true,
"version": "4.1.0",
"version": "4.1.1",
"type": "module",
"scripts": {
"prepare": "export VITE_COMMIT=$(git rev-parse --short HEAD)",
Expand All @@ -25,7 +25,7 @@
"@web3modal/ethereum": "2.7.1",
"@web3modal/react": "2.7.0",
"chroma-js": "3.1.2",
"dompurify": "3.2.4",
"dompurify": "3.4.13",
"es6-error": "4.1.1",
"firebase": "10.0.0",
"html2canvas": "1.4.1",
Expand Down Expand Up @@ -53,8 +53,8 @@
"redux-persist": "6.0.0",
"remark-breaks": "4.0.0",
"sharp": "0.32.6",
"unist-util-visit": "5.0.0",
"uuid": "9.0.0",
"unist-util-visit": "5.1.0",
"uuid": "14.0.0",
"viem": "1.2.5",
"wagmi": "1.3.9",
"web3": "1.9.0",
Expand All @@ -76,10 +76,10 @@
"@vitejs/plugin-legacy": "8.0.1",
"cypress": "12.17.4",
"dotenv": "16.4.5",
"happy-dom": "20.0.11",
"happy-dom": "20.8.9",
"react-test-renderer": "18.2.0",
"sharp": "0.32.6",
"svgo": "3.2.0",
"svgo": "3.3.4",
"terser": "5.39.2",
"vite-plugin-image-optimizer": "2.0.3",
"vite-plugin-optimize-css-modules": "1.4.0",
Expand Down
4 changes: 3 additions & 1 deletion packages/frontend/src/api/hooks/useCustomAnalytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ export const useCustomAnalytics = () => {

const logButtonClicked = (payload: TButtonClickEventPayload) => {
const key = EActivityLogEventTypes.ButtonClicked;
logEvent(analytics, key, payload);
if (analytics) {
logEvent(analytics, key, payload);
}
logButtonClickedActivity(payload.buttonName, payload.data);
Logger.debug("logButtonClicked", key, payload);
};
Expand Down
13 changes: 12 additions & 1 deletion packages/frontend/src/api/hooks/useGATracker.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import { useEffect } from "react";
import ReactGA from "react-ga4";
import ReactGADefault from "react-ga4";
import { useLocation } from "react-router-dom";
import { useCookieChoice } from "src/api/hooks";
import { Logger } from "src/api/utils/logging";
import CONFIG from "src/config";

// react-ga4 ships as CommonJS. Vite's dev pre-bundler (esbuild) resolves the
// default-import interop correctly, but the production Rollup build double-wraps
// the default export, leaving `ReactGA.initialize` undefined. Unwrap the extra
// `default` layer when present so it works under both bundlers.
const ReactGA =
typeof (ReactGADefault as { initialize?: unknown }).initialize ===
"function"
? ReactGADefault
: (ReactGADefault as unknown as { default: typeof ReactGADefault })
.default;

let isInitialized = false;

export const useGaTracker = (): void => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import queryString from "query-string";
import { TDeveloperActivitySnapshot } from "src/api/types";
import { Logger } from "src/api/utils/logging";
import CONFIG from "../../../config/config";
import { alphadayApi } from "../alphadayApi";
import {
TGetDeveloperActivityRequest,
TGetDeveloperActivityRawResponse,
TGetDeveloperActivityResponse,
} from "./types";

const { COINS } = CONFIG.API.DEFAULT.ROUTES;

const developerActivityApi = alphadayApi.injectEndpoints({
endpoints: (builder) => ({
getDeveloperActivity: builder.query<
TGetDeveloperActivityResponse,
TGetDeveloperActivityRequest
>({
query: ({ coin, limit }) => {
const params = queryString.stringify(
{ limit },
{ skipNull: true, skipEmptyString: true }
);
const path = `${String(COINS.BASE)}${String(
COINS.DEVELOPER_ACTIVITY(coin)
)}${params ? `?${params}` : ""}`;
Logger.debug("getDeveloperActivity: querying", path);
return path;
},
transformResponse: (
r: TGetDeveloperActivityRawResponse
): TGetDeveloperActivityResponse => {
try {
const snapshots: TDeveloperActivitySnapshot[] = r
.map((s) => ({
id: s.id,
coin: s.coin,
commitsLast4Weeks: s.commits_last_4_weeks,
contributorsCount: s.contributors_count,
openIssues: s.open_issues,
stars: s.stars,
forks: s.forks,
date: s.date,
}))
// The endpoint returns snapshots newest-first; sort
// oldest-first so the data is ready to plot on a time
// axis and the latest snapshot is the last element.
.sort(
(a, b) =>
new Date(a.date).getTime() -
new Date(b.date).getTime()
);
return { snapshots };
} catch (error) {
Logger.error(
"getDeveloperActivity::transformResponse: error while parsing response:",
error
);
return { snapshots: [] };
}
},
}),
}),
overrideExisting: false,
});

export const { useGetDeveloperActivityQuery } = developerActivityApi;
31 changes: 31 additions & 0 deletions packages/frontend/src/api/services/developerActivity/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { TDeveloperActivityData } from "src/api/types";

/**
* Primitive types
*/

export type TRemoteDeveloperActivitySnapshot = {
id: number;
coin: string;
commits_last_4_weeks: number;
contributors_count: number;
open_issues: number;
stars: number;
forks: number;
date: string;
};

/**
* Queries
*/

export type TGetDeveloperActivityRequest = {
// coin slug (case insensitive) — required path param
coin: string;
limit?: number | undefined;
};

export type TGetDeveloperActivityRawResponse =
TRemoteDeveloperActivitySnapshot[];

export type TGetDeveloperActivityResponse = TDeveloperActivityData;
101 changes: 101 additions & 0 deletions packages/frontend/src/api/services/exploits/exploitsEndpoints.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import queryString from "query-string";
import { Logger } from "src/api/utils/logging";
import CONFIG from "../../../config/config";
import { alphadayApi } from "../alphadayApi";
import {
TGetExploitsRequest,
TGetExploitsRawResponse,
TGetExploitsResponse,
} from "./types";

const { EXPLOITS } = CONFIG.API.DEFAULT.ROUTES;

const parseAmount = (amount: string | null): number | null => {
if (amount === null) return null;
const parsed = parseFloat(amount);
return Number.isNaN(parsed) ? null : parsed;
};

const exploitsApi = alphadayApi.injectEndpoints({
endpoints: (builder) => ({
getExploits: builder.query<TGetExploitsResponse, TGetExploitsRequest>({
query: (req) => {
const params: string = queryString.stringify({
...req,
limit: req.limit ?? 30,
});
const path = `${String(EXPLOITS.BASE)}${String(
EXPLOITS.DEFAULT
)}?${params}`;
Logger.debug("getExploits: querying", path);
return path;
},
transformResponse: (
r: TGetExploitsRawResponse,
_meta,
_arg
): TGetExploitsResponse => {
Logger.debug("[EXPLOITS] transformResponse: raw response =", r);
Logger.debug(
"[EXPLOITS] transformResponse: typeof r =",
typeof r,
"| keys =",
r && typeof r === "object" ? Object.keys(r) : "n/a",
"| results isArray =",
Array.isArray(r?.results),
"| results length =",
r?.results?.length
);
try {
const facadeData = r.results
.filter(
(item, index, self) =>
self.findIndex(
(innerItem) => innerItem.id === item.id
) === index
)
.map((data) => ({
id: data.id,
hash: data.hash,
title: data.title,
url: data.url,
image: data.image,
shortDescription: data.short_description,
description: data.description,
protocol: data.protocol,
amountUsd: parseAmount(data.amount_usd),
chain: data.chain,
attackType: data.attack_type?.name ?? null,
date: data.date,
source: data.source,
tags: data.tags ?? [],
}));
Logger.debug(
"[EXPLOITS] transformResponse: mapped facade length =",
facadeData.length,
"| first item =",
facadeData[0]
);
return {
...r,
results: facadeData,
};
} catch (error) {
Logger.error(
"[EXPLOITS] transformResponse: FAILED to parse response — returning empty list. error =",
error,
"| raw response was =",
r
);
return {
...r,
results: [],
};
}
},
}),
}),
overrideExisting: false,
});

export const { useGetExploitsQuery } = exploitsApi;
Loading
Loading