Skip to content
Open
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
21 changes: 14 additions & 7 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { createKeyv } from '@keyv/redis'

export function createListsKeyv(namespace?: string) {
export function createKeyvClient(namespace?: string) {
const redisUrl = process.env.REST_CACHE_REDIS_URL || 'redis://localhost:6379'
return createKeyv(redisUrl, {
namespace,
})
}

28 changes: 16 additions & 12 deletions packages/web/app/api/rest/list/refresh.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { createKeyvClient } from '../cache'
import { getVaultsList } from './db'
import { createListsKeyv } from './redis'

async function refresh(): Promise<void> {
console.time('refresh')
const keyv = createKeyvClient('list:vaults')

const keyv = createListsKeyv('list:vaults')
async function refresh(): Promise<void> {
console.time('refresh list:vaults')

const vaults = await getVaultsList()

Expand All @@ -17,24 +17,28 @@ async function refresh(): Promise<void> {
}, {} as Record<number, typeof vaults>)

const chainIds = Object.keys(vaultsByChain).map(Number)
for (const chainId of chainIds) {
const chainVaults = vaultsByChain[chainId]
await keyv.set(String(chainId), JSON.stringify(chainVaults))
}
const entries = chainIds.map((chainId) => ({
key: String(chainId),
value: vaultsByChain[chainId],
}))

entries.push({ key: 'all', value: vaults })

await keyv.set('all', JSON.stringify(vaults))
await keyv.setMany(entries)

console.log(`✓ Completed: ${vaults.length} vaults cached across ${chainIds.length} chains`)
console.timeEnd('refresh')
console.timeEnd('refresh list:vaults')
}

if (require.main === module) {
refresh()
.then(() => {
.then(async () => {
await keyv.disconnect()
process.exit(0)
})
.catch(err => {
.catch(async (err) => {
console.error(err)
await keyv.disconnect()
process.exit(1)
})
}
21 changes: 6 additions & 15 deletions packages/web/app/api/rest/list/vaults/[chainId]/route.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import { NextResponse } from 'next/server'
import { createListsKeyv } from '../../redis'

import { createKeyvClient } from '../../../cache'
import type { VaultListItem } from '../../db'

const keyv = createKeyvClient('list:vaults')

export const runtime = 'nodejs'

const corsHeaders = {
'access-control-allow-origin': '*',
'access-control-allow-methods': 'GET,OPTIONS',
}

const listsKeyv = createListsKeyv('list:vaults')

type RouteParams = {
chainId?: string | string[]
}
Expand All @@ -30,26 +29,18 @@ export async function GET(
return new NextResponse('Invalid chainId', { status: 400, headers: corsHeaders })
}

let cached
let vaults: VaultListItem[] | undefined
try {
cached = await listsKeyv.get(String(chainId))
vaults = await keyv.get(String(chainId)) as VaultListItem[] | undefined
} catch (err) {
console.error(`Redis read failed for chainId ${chainId}:`, err)
throw err
}

if (!cached) {
if (!vaults) {
return new NextResponse('Not found', { status: 404, headers: corsHeaders })
}

let vaults: VaultListItem[]
try {
vaults = JSON.parse(cached as string)
} catch (e) {
console.error(`Failed to parse vault list for chain ${chainId}:`, e)
return new NextResponse('Internal Server Error', { status: 500, headers: corsHeaders })
}

const filtered = origin
? vaults.filter(v => v.origin === origin)
: vaults
Expand Down
18 changes: 5 additions & 13 deletions packages/web/app/api/rest/list/vaults/route.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,27 @@
import { NextResponse } from 'next/server'
import { createListsKeyv } from '../redis'
import { createKeyvClient } from '../../cache'
import type { VaultListItem } from '../db'

const keyv = createKeyvClient('list:vaults')

export const runtime = 'nodejs'

const corsHeaders = {
'access-control-allow-origin': '*',
'access-control-allow-methods': 'GET,OPTIONS',
}

const listsKeyv = createListsKeyv('list:vaults')

export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const origin = searchParams.get('origin')

try {
const cached = await listsKeyv.get('all')
const allVaults = await keyv.get('all') as VaultListItem[] | undefined

if (!cached) {
if (!allVaults) {
return new NextResponse('Not found', { status: 404, headers: corsHeaders })
}

let allVaults: VaultListItem[]
try {
allVaults = JSON.parse(cached as string)
} catch (e) {
console.error('Failed to parse vault list from Redis:', e)
return new NextResponse('Internal Server Error', { status: 500, headers: corsHeaders })
}

const filtered = origin
? allVaults.filter(v => v.origin === origin)
: allVaults
Expand Down
43 changes: 18 additions & 25 deletions packages/web/app/api/rest/reports/[chainId]/[address]/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import { NextRequest, NextResponse } from 'next/server'
import { createReportsKeyv, getReportKey} from '../../redis'
import { createKeyvClient } from '../../../cache'
import { VaultReport } from '../../db'
import { getReportKey } from '../../redis'

const keyv = createKeyvClient()

const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, OPTIONS',
}

export async function GET(
request: NextRequest,
Expand All @@ -17,43 +25,28 @@ export async function GET(
)
}

const keyv = createReportsKeyv()
const key = getReportKey(chainId, address)
const data = await keyv.get(key) as VaultReport[] | undefined

const cached = await keyv.get(key)

if (!cached) {
if (!data) {
return NextResponse.json(
{ error: 'Not found' },
{ status: 404 }
)
}

let data
try {
data = typeof cached === 'string' ? JSON.parse(cached) : cached

return NextResponse.json(data, {
headers: {
'Cache-Control': 'public, max-age=900, s-maxage=900, stale-while-revalidate=600',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, OPTIONS'
}
})
} catch (e) {
console.error('Failed to parse cached report', e)
return NextResponse.json(
{ error: 'Internal Server Error' },
{ status: 500 }
)
}
return NextResponse.json(data, {
headers: {
'Cache-Control': 'public, max-age=900, s-maxage=900, stale-while-revalidate=600',
...corsHeaders,
}
})
}

export async function OPTIONS() {
return new NextResponse(null, {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, OPTIONS',
...corsHeaders,
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
},
})
Expand Down
7 changes: 0 additions & 7 deletions packages/web/app/api/rest/reports/redis.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
import { createKeyv } from '@keyv/redis'

export function createReportsKeyv() {
const redisUrl = process.env.REST_CACHE_REDIS_URL || 'redis://localhost:6379'
return createKeyv(redisUrl)
}

export function getReportKey(
chainId: number,
address: string,
Expand Down
Loading