Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
32 changes: 32 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

permissions:
contents: read

jobs:
ci:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v6

- name: vite-plus setup
uses: voidzero-dev/setup-vp@v1
with:
node-version-file: ".node-version"
cache: true

- name: Run build
run: |
cp ./apps/web/.env.production.build ./apps/web/.env.production.local
vp run build

- name: Check formatting, linting and type checks.
run: vp check
8 changes: 4 additions & 4 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ name: Docker

on:
push:
branches: [ "main" ]
branches: ["main"]
# Publish semver tags as releases.
tags: [ 'stackspulse@*.*.*' ]
tags: ["stackspulse@*.*.*"]
pull_request:
branches: [ "main" ]
branches: ["main"]
workflow_dispatch:

concurrency:
Expand Down Expand Up @@ -63,7 +63,7 @@ jobs:
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

build-server:
runs-on: ubuntu-latest

Expand Down
31 changes: 18 additions & 13 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,33 @@ jobs:
permissions:
contents: write
pull-requests: write

steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Install pnpm
uses: pnpm/action-setup@v6

- name: Setup Node.js 22
uses: actions/setup-node@v4
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 22
node-version-file: ".node-version"
cache: "pnpm"

- name: Install dependencies
run: pnpm install
run: pnpm install --frozen-lockfile

- name: Create Release Pull Request
- name: Create Release Pull Request or Publish
id: changesets
uses: changesets/action@v1
uses: changesets/action@v2
with:
version: pnpm run version
publish: pnpm run release
commit: 'chore: release'
title: 'chore: create new release'
version-script: pnpm run version
publish-script: pnpm run release
commit-message: "chore: release"
pr-title: "chore: create new release"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Expand Down
1 change: 0 additions & 1 deletion .husky/pre-commit

This file was deleted.

1 change: 1 addition & 0 deletions .node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v24.19.0
5 changes: 1 addition & 4 deletions ansible/security/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,7 @@
state: present
mode: "0644"
loop:
- {
key: "Unattended-Upgrade::Automatic-Reboot",
value: "{{ security_autoupdate_reboot }}",
}
- { key: "Unattended-Upgrade::Automatic-Reboot", value: "{{ security_autoupdate_reboot }}" }
- {
key: "Unattended-Upgrade::Automatic-Reboot-Time",
value: "{{ security_autoupdate_reboot_time }}",
Expand Down
14 changes: 3 additions & 11 deletions apps/server/src/api/protocols/users/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Protocol } from "@stackspulse/protocols";

Check failure on line 1 in apps/server/src/api/protocols/users/index.ts

View workflow job for this annotation

GitHub Actions / quality

format

File content differs from formatting output
import type postgres from "postgres";
import { z } from "zod";
import { sql } from "~/db/db";
Expand Down Expand Up @@ -44,7 +44,7 @@

const stats: ProtocolUsersRouteResponse = result.map((stat) => ({
protocol_name: stat.protocol_name as Protocol,
unique_senders: Number.parseInt(stat.unique_senders),

Check notice on line 47 in apps/server/src/api/protocols/users/index.ts

View workflow job for this annotation

GitHub Actions / quality

lint/correctness/useParseIntRadix

Missing radix parameter
}));

return stats;
Expand All @@ -55,10 +55,7 @@
daysToSubtract?: number;
}

const getProtocolUsersDirect = async ({
limit,
daysToSubtract,
}: QueryParams) => {
const getProtocolUsersDirect = async ({ limit, daysToSubtract }: QueryParams) => {
let dateCondition = "";
if (daysToSubtract) {
dateCondition = `AND txs.block_time >= EXTRACT(EPOCH FROM (NOW() - INTERVAL '${daysToSubtract} days'))`;
Expand All @@ -85,10 +82,7 @@
return result;
};

const getProtocolUsersNested = async ({
limit,
daysToSubtract,
}: QueryParams) => {
const getProtocolUsersNested = async ({ limit, daysToSubtract }: QueryParams) => {
let dateCondition = "";
if (daysToSubtract) {
dateCondition = `AND txs.block_time >= EXTRACT(EPOCH FROM (NOW() - INTERVAL '${daysToSubtract} days'))`;
Expand Down Expand Up @@ -152,9 +146,7 @@

const queryEndTime = Date.now();
consola.debug(
`ProtocolUsersRoute: Query executed in ${formatElapsedTime(
queryEndTime - queryStartTime,
)}ms`,
`ProtocolUsersRoute: Query executed in ${formatElapsedTime(queryEndTime - queryStartTime)}ms`,
);

return result;
Expand Down
8 changes: 2 additions & 6 deletions apps/server/src/api/root/tweet-weekly-users/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,7 @@ export default defineEventHandler(async () => {
params.append("title", "Last 7 Days Unique Users");
params.append("data", JSON.stringify(dataNested));

const imageUrlNested = `${
env.WEB_URL
}/api/images/weekly-users?${params.toString()}`;
const imageUrlNested = `${env.WEB_URL}/api/images/weekly-users?${params.toString()}`;

let messageNested = "📈 Last 7 days unique users:\n\n";
for (const stat of statsNested) {
Expand All @@ -63,9 +61,7 @@ export default defineEventHandler(async () => {
params.set("title", "Last 7 Days Direct Unique Users");
params.set("data", JSON.stringify(dataDirect));

const imageUrlDirect = `${
env.WEB_URL
}/api/images/weekly-users?${params.toString()}`;
const imageUrlDirect = `${env.WEB_URL}/api/images/weekly-users?${params.toString()}`;

let messageDirect =
"📈 Last 7 days unique users that interacted directly with the protocols:\n\n";
Expand Down
5 changes: 1 addition & 4 deletions apps/server/src/api/tokens/transaction-volume.get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ type TokensTransactionVolumeRouteResponse = {
}[];

export default defineCachedEventHandler(async (event) => {
const query = await getValidatedQueryZod(
event,
tokensTransactionVolumeRouteSchema,
);
const query = await getValidatedQueryZod(event, tokensTransactionVolumeRouteSchema);

const result = await sql`
SELECT
Expand Down
8 changes: 2 additions & 6 deletions apps/server/src/api/transactions/index.get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,7 @@ LIMIT 50

const queryEndTime = Date.now();
consola.debug(
`TransactionsRoute: Query executed in ${formatElapsedTime(
queryEndTime - queryStartTime,
)}ms`,
`TransactionsRoute: Query executed in ${formatElapsedTime(queryEndTime - queryStartTime)}ms`,
);

const formattedResult = result.map((r) => ({
Expand All @@ -73,9 +71,7 @@ LIMIT 50

const transactionsWithDetails: TransactionsRouteResponse = formattedResult
.map((r) =>
data[r.tx_id].found === true
? { protocol: r.protocol, ...data[r.tx_id].result }
: null,
data[r.tx_id].found === true ? { protocol: r.protocol, ...data[r.tx_id].result } : null,
)
.filter((tx) => tx !== null);

Expand Down
5 changes: 1 addition & 4 deletions apps/server/src/api/transactions/unique-senders/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@
}[];

export default defineCachedEventHandler(async (event) => {
const query = await getValidatedQueryZod(
event,
transactionUniqueSendersRouteSchema,
);
const query = await getValidatedQueryZod(event, transactionUniqueSendersRouteSchema);

const queryStartTime = Date.now();
const result = await sql`
Expand Down Expand Up @@ -96,7 +93,7 @@
// format of the month is "2021-08-01 00:00:00+00"
// we want to output "2021-08"
month: row.month.slice(0, 7),
unique_senders: Number.parseInt(row.unique_senders),

Check notice on line 96 in apps/server/src/api/transactions/unique-senders/index.ts

View workflow job for this annotation

GitHub Actions / quality

lint/correctness/useParseIntRadix

Missing radix parameter
}));

return stats;
Expand Down
17 changes: 7 additions & 10 deletions apps/server/src/db/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,12 @@
table: TTable,
): PgUpdateSetSource<TTable> {
const columns = getTableColumns(table);
const conflictUpdateSet = Object.entries(columns).reduce(
(acc, [columnName, columnInfo]) => {
if (!columnInfo.default) {
// @ts-ignore
acc[columnName] = sql.raw(`excluded.${columnInfo.name}`);
}
return acc;
},
{},
) as PgUpdateSetSource<TTable>;
const conflictUpdateSet = Object.entries(columns).reduce((acc, [columnName, columnInfo]) => {
if (!columnInfo.default) {
// @ts-ignore

Check warning on line 14 in apps/server/src/db/utils.ts

View workflow job for this annotation

GitHub Actions / quality

lint/suspicious/noTsIgnore

Unsafe use of the @ts-ignore directive found in this comment.
acc[columnName] = sql.raw(`excluded.${columnInfo.name}`);
}
return acc;
}, {}) as PgUpdateSetSource<TTable>;
return conflictUpdateSet;
}
6 changes: 1 addition & 5 deletions apps/server/src/lib/consola.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,5 @@ import { createConsola } from "consola";
import { env } from "~/env";

export const consola = createConsola({
level: env.CONSOLA_LEVEL
? env.CONSOLA_LEVEL
: env.NODE_ENV === "development"
? 4
: 3,
level: env.CONSOLA_LEVEL ? env.CONSOLA_LEVEL : env.NODE_ENV === "development" ? 4 : 3,
});
8 changes: 2 additions & 6 deletions apps/web/src/app/Providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ const queryClient = new QueryClient({
},
});

export const Providers = ({
children,
}: Readonly<{ children: React.ReactNode }>) => {
return (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);
export const Providers = ({ children }: Readonly<{ children: React.ReactNode }>) => {
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;
};
9 changes: 4 additions & 5 deletions apps/web/src/app/about/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { appConfig } from "@/appConfig";
import { Container, Heading, Link, Text } from "@radix-ui/themes";
import type { Metadata } from "next";

Check failure on line 3 in apps/web/src/app/about/page.tsx

View workflow job for this annotation

GitHub Actions / quality

assist/source/organizeImports

Sort these imports.

export const metadata: Metadata = {
alternates: {
Expand All @@ -17,9 +17,8 @@

<div className="mt-5 space-y-2">
<Text as="p" size="3" color="gray">
This project aims to provide a real-time view of Stacks DeFi ecosystem
by aggregating public blockchain data and making it accessible through
an easy to use interface.
This project aims to provide a real-time view of Stacks DeFi ecosystem by aggregating
public blockchain data and making it accessible through an easy to use interface.
</Text>
<Text as="p" size="3" color="gray">
Give us a star on{" "}
Expand All @@ -42,8 +41,8 @@
Data
</Heading>
<Text as="p" size="3" color="gray">
Data is extracted from a self-hosted Stacks blockchain node and
aggregated using PostgreSQL.
Data is extracted from a self-hosted Stacks blockchain node and aggregated using
PostgreSQL.
</Text>
<Text as="p" size="3" color="gray">
Token prices and volume is provided by{" "}
Expand Down
10 changes: 2 additions & 8 deletions apps/web/src/app/api/images/weekly-users/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ export async function GET(req: NextRequest) {
});

if (!params.success) {
return Response.json(
{ success: false, message: "Invalid parameters" },
{ status: 400 },
);
return Response.json({ success: false, message: "Invalid parameters" }, { status: 400 });
}

const title = params.data.title;
Expand Down Expand Up @@ -83,10 +80,7 @@ export async function GET(req: NextRequest) {

<div tw="flex min-w-min text-right flex-col" style={{ gap: rowGap }}>
{data.map((item) => (
<div
key={item.name}
tw={cn("flex justify-end items-center", rowHeight)}
>
<div key={item.name} tw={cn("flex justify-end items-center", rowHeight)}>
{item.value.toLocaleString("en-US")}
</div>
))}
Expand Down
5 changes: 1 addition & 4 deletions apps/web/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ export default function RootLayout({
}>) {
return (
<html lang="en">
<body
suppressHydrationWarning
className={`${font.variable} font-sans antialiased`}
>
<body suppressHydrationWarning className={`${font.variable} font-sans antialiased`}>
<Providers>
<Theme appearance="dark" accentColor="orange" grayColor="sand">
<Header />
Expand Down
13 changes: 5 additions & 8 deletions apps/web/src/app/tokens/[token]/opengraph-image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,13 @@
}

export default async function Image({ params }: PageProps) {
const metadata = await tokenMetadataClient.GET(
"/metadata/v1/ft/{principal}",
{
params: {
path: {
principal: params.token,
},
const metadata = await tokenMetadataClient.GET("/metadata/v1/ft/{principal}", {
params: {
path: {
principal: params.token,
},
},
);
});
const tokenInfo = metadata?.data;
if (!tokenInfo) {
notFound();
Expand All @@ -52,17 +49,17 @@
>
<div tw="flex items-center">
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
tw="mr-4"
src={tokenInfo.image_thumbnail_uri || tokenInfo.image_uri}
alt={alt}
height={100}
width={100}
style={{
borderRadius: "50%",
border: "2px solid white",
}}
/>

Check warning on line 62 in apps/web/src/app/tokens/[token]/opengraph-image.tsx

View workflow job for this annotation

GitHub Actions / quality

lint/performance/noImgElement

Don't use <img> element.
{tokenInfo.symbol}
</div>
</div>,
Expand Down
26 changes: 10 additions & 16 deletions apps/web/src/app/tokens/[token]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,13 @@

export async function generateMetadata(props: PageProps): Promise<Metadata> {
const params = await props.params;
const metadata = await tokenMetadataClient.GET(
"/metadata/v1/ft/{principal}",
{
params: {
path: {
principal: params.token,
},
const metadata = await tokenMetadataClient.GET("/metadata/v1/ft/{principal}", {
params: {
path: {
principal: params.token,
},
},
);
});
const tokenInfo = metadata?.data;
if (!tokenInfo) {
notFound();
Expand All @@ -42,22 +39,19 @@

export default async function ProtocolPage(props: PageProps) {
const params = await props.params;
const metadata = await tokenMetadataClient.GET(
"/metadata/v1/ft/{principal}",
{
params: {
path: {
principal: params.token,
},
const metadata = await tokenMetadataClient.GET("/metadata/v1/ft/{principal}", {
params: {
path: {
principal: params.token,
},
},
);
});
const tokenInfo = metadata?.data;
if (!tokenInfo) {
notFound();
}

const token = tokenInfo.asset_identifier;

Check warning on line 54 in apps/web/src/app/tokens/[token]/page.tsx

View workflow job for this annotation

GitHub Actions / quality

lint/correctness/noUnusedVariables

This variable token is unused.

return (
<Container size="2" className="px-4 pt-10">
Expand Down
Loading
Loading