-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
119 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { NET_FLOW_KEY } from "@/app/api/stats/constants" | ||
import { kv } from "@vercel/kv" | ||
import { NextRequest } from "next/server" | ||
|
||
export interface NetFlowResponse { | ||
netFlow: number | ||
timestamp: number | ||
} | ||
|
||
export const runtime = "edge" | ||
export const dynamic = "force-dynamic" | ||
|
||
export async function GET(req: NextRequest) { | ||
try { | ||
const data = await kv.get<NetFlowResponse>(NET_FLOW_KEY) | ||
if (data) { | ||
return new Response(JSON.stringify(data), { | ||
headers: { "Content-Type": "application/json" }, | ||
}) | ||
} | ||
return new Response(JSON.stringify({ error: "Net flow data not available" }), { | ||
status: 404, | ||
headers: { "Content-Type": "application/json" }, | ||
}) | ||
} catch (error) { | ||
return new Response(JSON.stringify({ error: "Failed to retrieve net flow data" }), { | ||
status: 500, | ||
headers: { "Content-Type": "application/json" }, | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { INFLOWS_KEY, INFLOWS_SET_KEY, NET_FLOW_KEY } from "@/app/api/stats/constants" | ||
import { NetFlowResponse } from "@/app/api/stats/net-flow/route" | ||
import { getAllSetMembers } from "@/app/lib/kv-utils" | ||
import { kv } from "@vercel/kv" | ||
|
||
const TWENTY_FOUR_HOURS = 24 * 60 * 60 * 1000 // 24 hours in milliseconds | ||
|
||
export async function GET() { | ||
console.log("Starting net flow calculation cron job") | ||
try { | ||
const now = Date.now() | ||
const twentyFourHoursAgo = now - TWENTY_FOUR_HOURS | ||
console.log(`Calculating net flow from ${new Date(twentyFourHoursAgo).toISOString()} to ${new Date(now).toISOString()}`) | ||
|
||
const transactionHashes = await getAllSetMembers(kv, INFLOWS_SET_KEY) | ||
console.log(`Retrieved ${transactionHashes.length} transaction hashes`) | ||
|
||
const pipeline = kv.pipeline() | ||
transactionHashes.forEach(hash => pipeline.get(`${INFLOWS_KEY}:${hash}`)) | ||
const data = await pipeline.exec() | ||
console.log(`Fetched data for ${data.length} transactions`) | ||
|
||
let netFlow = 0 | ||
let validTransactions = 0 | ||
let skippedTransactions = 0 | ||
|
||
data.forEach(item => { | ||
if (item && typeof item === "object" && "timestamp" in item && "amount" in item) { | ||
const transfer = item as { timestamp: number; amount: number; isWithdrawal: boolean } | ||
if (transfer.timestamp >= twentyFourHoursAgo) { | ||
netFlow += transfer.isWithdrawal ? -transfer.amount : transfer.amount | ||
validTransactions++ | ||
} else { | ||
skippedTransactions++ | ||
} | ||
} | ||
}) | ||
|
||
console.log(`Processed ${validTransactions} valid transactions, skipped ${skippedTransactions} outdated transactions`) | ||
console.log(`Calculated net flow: ${netFlow}`) | ||
|
||
const response: NetFlowResponse = { | ||
netFlow, | ||
timestamp: now, | ||
} | ||
|
||
await kv.set(NET_FLOW_KEY, response) | ||
console.log("Net flow data updated successfully") | ||
|
||
return new Response(JSON.stringify({ message: "Net flow data updated successfully" }), { | ||
status: 200, | ||
headers: { "Content-Type": "application/json" }, | ||
}) | ||
} catch (error) { | ||
console.error("Error updating net flow data:", error) | ||
return new Response(JSON.stringify({ error: "Failed to update net flow data" }), { | ||
status: 500, | ||
headers: { "Content-Type": "application/json" }, | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { NetFlowResponse } from '@/app/api/stats/net-flow/route' | ||
import { useQuery } from '@tanstack/react-query' | ||
|
||
async function fetchNetFlow(): Promise<NetFlowResponse> { | ||
const response = await fetch('/api/stats/net-flow') | ||
if (!response.ok) { | ||
throw new Error('Failed to fetch net flow data') | ||
} | ||
return response.json() | ||
} | ||
|
||
export function useNetFlow() { | ||
return useQuery<NetFlowResponse, Error>({ | ||
queryKey: ['stats', 'netFlow'], | ||
queryFn: fetchNetFlow, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters