-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: #359: implement initial leaderboard request
- Loading branch information
Showing
6 changed files
with
119 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { LeaderboardPage } from '@/pages/leaderboard'; | ||
|
||
// Informs NextJs to not prerender the page in build time | ||
export const dynamic = 'force-dynamic'; | ||
|
||
export default LeaderboardPage; |
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,27 @@ | ||
import { sql } from 'kysely'; | ||
import { pindexerDb } from '@/shared/database/client'; | ||
|
||
export const queryLeaderboard = async (limit: number) => { | ||
const results = await pindexerDb | ||
.selectFrom('dex_ex_position_executions') | ||
.select((exp) => ([ | ||
// 'context_asset_end', | ||
// 'context_asset_start', | ||
// exp.fn.sum(exp.ref('delta_1'), exp.ref('lambda_1')).as('volume1'), | ||
'position_id', | ||
sql<string>`sum(${exp.ref('delta_1')} + ${exp.ref('lambda_1')})`.as('volume1'), | ||
sql<string>`sum(${exp.ref('delta_2')} + ${exp.ref('lambda_2')})`.as('volume2'), | ||
sql<string>`sum(${exp.ref('fee_1')})`.as('fees1'), | ||
sql<string>`sum(${exp.ref('fee_2')})`.as('fees2'), | ||
sql<number>`CAST(count(*) AS INTEGER)`.as('executionCount'), | ||
])) | ||
.groupBy(['position_id']) | ||
.orderBy('executionCount', 'desc') | ||
.limit(limit) | ||
.execute(); | ||
|
||
return results; | ||
}; | ||
|
||
type FromPromise<T> = T extends Promise<(infer U)[]> ? U : T; | ||
export type LeaderboardData = FromPromise<ReturnType<typeof queryLeaderboard>>; |
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 @@ | ||
export { LeaderboardPage } from './ui/page'; |
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,24 @@ | ||
'use server'; | ||
|
||
import { queryLeaderboard } from '../api/query-leaderboard'; | ||
import { LeaderboardTable } from './table'; | ||
import { serialize } from '@/shared/utils/serializer'; | ||
|
||
export interface LeaderboardPageProps { | ||
searchParams: Promise<{ | ||
limit?: string; | ||
}> | ||
} | ||
|
||
export const LeaderboardPage = async ({ searchParams }: LeaderboardPageProps) => { | ||
const { limit } = await searchParams; | ||
console.log('LOADING', limit); | ||
const data = await queryLeaderboard(limit ? parseInt(limit) : 30); | ||
|
||
return ( | ||
<section className='text-text-primary'> | ||
<h1>Leaderboard</h1> | ||
<LeaderboardTable data={serialize(data)} /> | ||
</section> | ||
); | ||
}; |
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,60 @@ | ||
'use client'; | ||
|
||
import cn from 'clsx'; | ||
import { TableCell } from '@penumbra-zone/ui/TableCell'; | ||
import type { LeaderboardData } from '../api/query-leaderboard'; | ||
import { useRouter, useSearchParams } from 'next/navigation'; | ||
import { PagePath } from '@/shared/const/pages'; | ||
import { Serialized, deserialize } from '@/shared/utils/serializer'; | ||
|
||
export interface LeaderboardTableProps { | ||
data: Serialized<LeaderboardData[]>; | ||
} | ||
|
||
export const LeaderboardTable = ({ data }: LeaderboardTableProps) => { | ||
const router = useRouter(); | ||
const searchParams = useSearchParams(); | ||
const positions = deserialize(data); | ||
|
||
const reload = () => { | ||
const search = new URLSearchParams(searchParams ?? undefined); | ||
search.set('limit', '5'); | ||
router.push(`${PagePath.LpLeaderboard}?${search.toString()}`); | ||
}; | ||
|
||
return ( | ||
<div className='grid grid-cols-4 pt-4 px-4 pb-0 h-auto overflow-auto'> | ||
<div className='grid col-span-4'> | ||
<button onClick={reload}>refresh</button> | ||
</div> | ||
<div className='grid grid-cols-subgrid col-span-4'> | ||
<TableCell heading>Time</TableCell> | ||
<TableCell heading>Executions</TableCell> | ||
<TableCell heading>Fees</TableCell> | ||
<TableCell heading>Volume</TableCell> | ||
</div> | ||
|
||
{positions.map((position, index) => ( | ||
<div | ||
key={index} | ||
className={cn( | ||
'relative grid grid-cols-subgrid col-span-4', | ||
)} | ||
> | ||
<TableCell numeric variant={index !== data.length - 1 ? 'cell' : 'lastCell'}> | ||
ABC | ||
</TableCell> | ||
<TableCell numeric variant={index !== data.length - 1 ? 'cell' : 'lastCell'}> | ||
{position.executionCount} | ||
</TableCell> | ||
<TableCell numeric variant={index !== data.length - 1 ? 'cell' : 'lastCell'}> | ||
{position.fees2} | ||
</TableCell> | ||
<TableCell numeric variant={index !== data.length - 1 ? 'cell' : 'lastCell'}> | ||
{position.volume1} | ||
</TableCell> | ||
</div> | ||
))} | ||
</div> | ||
); | ||
} |
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