Skip to content

Commit

Permalink
Various fixes (#29)
Browse files Browse the repository at this point in the history
* Update config stuff

* Add more logging

* move hooks to only run on the server

* move sqlite deps out of client

* use older version of bun...

* bump version
  • Loading branch information
ezynda3 authored Sep 18, 2024
1 parent fb05f40 commit d7edd31
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 91 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM oven/bun:1.1-slim
FROM oven/bun:1.1.20-slim

WORKDIR /app
COPY package.json package.json
Expand Down
Binary file modified bun.lockb
Binary file not shown.
File renamed without changes.
88 changes: 88 additions & 0 deletions src/lib/utils.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import type { Address } from 'viem'
import type { Contract } from './types'
import consola from 'consola'
import type { BunSQLiteDatabase } from 'drizzle-orm/bun-sqlite'
import { contracts } from '../schema'
import { and, eq } from 'drizzle-orm'

export const getContractInformation = async (
address: Address,
chainId: number,
): Promise<Contract> => {
try {
const response = await fetch(`https://anyabi.xyz/api/get-abi/${chainId}/${address}`)
if (!response.ok) {
consola.info('ABI not found.')
return { name: 'Unverified', address, abi: [] }
}
const contractData = await response.json()

return {
...contractData,
address,
}
} catch (e) {
consola.error(e)
consola.info('ABI not found.')
return { name: 'Unverified', address, abi: [] }
}
}

export const getCachedContractInformation = async (
address: Address,
chainId: number,
db: BunSQLiteDatabase,
): Promise<Contract> => {
try {
consola.info('Fetching contract information for', address, 'on chain', chainId)
consola.info('Checking for cached ABI...')
const result = await db
.select()
.from(contracts)
.where(and(eq(contracts.address, address), eq(contracts.chainId, chainId)))

if (result.length) {
consola.info('Found in db cache')
return {
name: result[0].name,
abi: [...JSON.parse(result[0].abi)],
address,
}
}
consola.info('Not found in cache. Fetching from anyabi.xyz...')
const contract = await getContractInformation(address, chainId)

// Don't cache unverified contracts
if (contract.name === 'Unverified') {
return contract
}

// Update the database
consola.info('Updating db cache...')
await db.insert(contracts).values({
id: `${chainId}:${address}`,
name: contract.name,
address,
abi: JSON.stringify(contract.abi),
chainId,
})

return contract
} catch (e) {
consola.error(e)
throw new Error('Failed to fetch contract information')
}
}

export const getFuncSigBySelector = async (selector: string): Promise<string> => {
const response = await fetch(
`https://api.openchain.xyz/signature-database/v1/lookup?function=${selector}&filter=true`,
)
const data = await response.json()

if (data && data.result && data.result.function && data.result.function[selector]) {
return data.result.function[selector][0].name
}

return 'unknown()'
}
91 changes: 17 additions & 74 deletions src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@ import { twMerge } from 'tailwind-merge'
import { cubicOut } from 'svelte/easing'
import type { TransitionConfig } from 'svelte/transition'
import { type Abi, type AbiFunction, type Address } from 'viem'
import type { Contract } from './types'
import toast from 'svelte-french-toast'
import Database from 'bun:sqlite'
import { drizzle, type BunSQLiteDatabase } from 'drizzle-orm/bun-sqlite'
import { contracts } from '../schema'
import { and, eq } from 'drizzle-orm'
import type { Contract } from './types'
import consola from 'consola'

export function cn(...inputs: ClassValue[]) {
Expand Down Expand Up @@ -63,13 +59,26 @@ export const flyAndScale = (
}
}

export const copyToClipboard = async (text: string) => {
await navigator.clipboard.writeText(text)
toast.success('Copied to clipboard!')
}

export const abiMethods = (abi: Abi): AbiFunction[] =>
abi.filter((i) => i.type === 'function') as AbiFunction[]

export const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))

export const getContractInformation = async (
address: Address,
chainId: number,
): Promise<Contract> => {
try {
const response = await fetch(`https://anyabi.xyz/api/get-abi/${chainId}/${address}`)
if (!response.ok) return { name: 'Unverified', address, abi: [] }
if (!response.ok) {
consola.info('ABI not found.')
return { name: 'Unverified', address, abi: [] }
}
const contractData = await response.json()

return {
Expand All @@ -78,73 +87,7 @@ export const getContractInformation = async (
}
} catch (e) {
consola.error(e)
throw new Error('Contract not found')
}
}

export const getCachedContractInformation = async (
address: Address,
chainId: number,
db: BunSQLiteDatabase,
): Promise<Contract> => {
try {
consola.info('Fetching contract information for', address, 'on chain', chainId)
const result = await db
.select()
.from(contracts)
.where(and(eq(contracts.address, address), eq(contracts.chainId, chainId)))

if (result.length) {
consola.info('Found in db cache')
return {
name: result[0].name,
abi: [...JSON.parse(result[0].abi)],
address,
}
}
const contract = await getContractInformation(address, chainId)

// Don't cache unverified contracts
if (contract.name === 'Unverified') {
return contract
}

// Update the database
consola.info('Updating db cache')
await db.insert(contracts).values({
id: `${chainId}:${address}`,
name: contract.name,
address,
abi: JSON.stringify(contract.abi),
chainId,
})

return contract
} catch (e) {
consola.error(e)
throw new Error('Contract not found')
}
}

export const copyToClipboard = async (text: string) => {
await navigator.clipboard.writeText(text)
toast.success('Copied to clipboard!')
}

export const getFuncSigBySelector = async (selector: string): Promise<string> => {
const response = await fetch(
`https://api.openchain.xyz/signature-database/v1/lookup?function=${selector}&filter=true`,
)
const data = await response.json()

if (data && data.result && data.result.function && data.result.function[selector]) {
return data.result.function[selector][0].name
consola.info('ABI not found.')
return { name: 'Unverified', address, abi: [] }
}

return 'unknown()'
}

export const abiMethods = (abi: Abi): AbiFunction[] =>
abi.filter((i) => i.type === 'function') as AbiFunction[]

export const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
4 changes: 3 additions & 1 deletion src/routes/diamond/[address]/+page.server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FacetData, Contract, Diamond } from '$lib/types'
import { getCachedContractInformation, getFuncSigBySelector } from '$lib/utils'
import { getCachedContractInformation, getFuncSigBySelector } from '$lib/utils.server'
import { error } from '@sveltejs/kit'
import type { PageServerLoad } from './$types'
import {
Expand All @@ -16,6 +16,7 @@ import { chainMap } from '$lib/chains'
import { type BunSQLiteDatabase } from 'drizzle-orm/bun-sqlite'
import { diamonds } from '../../../schema'
import { sql } from 'drizzle-orm'
import consola from 'consola'

export const load: PageServerLoad = async ({ params, url, locals }) => {
const { address } = params
Expand Down Expand Up @@ -54,6 +55,7 @@ export const load: PageServerLoad = async ({ params, url, locals }) => {
}

// Udate the database
consola.info('Updating stats...')
await locals.db
.insert(diamonds)
.values({
Expand Down
24 changes: 10 additions & 14 deletions src/routes/diamond/[address]/json/+server.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import type { FacetData, Contract, Diamond } from '$lib/types'
import {
getCachedContractInformation,
getContractInformation,
getFuncSigBySelector,
} from '$lib/utils'
import { getCachedContractInformation, getFuncSigBySelector } from '$lib/utils.server'
import { error, json } from '@sveltejs/kit'
import type { RequestHandler } from './$types'
import {
Expand All @@ -17,10 +13,10 @@ import {
} from 'viem'
import type { Chain } from 'viem/chains'
import { chainMap } from '$lib/chains'
import { drizzle, type BunSQLiteDatabase } from 'drizzle-orm/bun-sqlite'
import { Database } from 'bun:sqlite'
import { type BunSQLiteDatabase } from 'drizzle-orm/bun-sqlite'
import { diamonds } from '../../../../schema'
import { sql } from 'drizzle-orm'
import consola from 'consola'

export const GET: RequestHandler = async ({ params, url, locals }) => {
const { address } = params
Expand Down Expand Up @@ -59,9 +55,8 @@ export const GET: RequestHandler = async ({ params, url, locals }) => {
}

// Udate the database
const sqlite = new Database('./data/louper.db')
const db = drizzle(sqlite)
await db
consola.info('Updating stats...')
await locals.db
.insert(diamonds)
.values({
id: `${network}:${address}`,
Expand All @@ -76,14 +71,15 @@ export const GET: RequestHandler = async ({ params, url, locals }) => {
visits: sql`${diamonds.visits} + 1`,
},
})
consola.info('Stats updated.')

sqlite.close()

return json({
const response = {
chain: network,
diamond,
diamondAbi,
})
}

return json(response)
} catch (e) {
console.error(e)
throw error(400, { message: 'Unable to fetch diamond details' })
Expand Down
12 changes: 11 additions & 1 deletion vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,15 @@ import { defineConfig } from 'vite'
import { nodePolyfills } from 'vite-plugin-node-polyfills'

export default defineConfig({
plugins: [nodePolyfills(), sveltekit()],
plugins: [
nodePolyfills({
include: ['path', 'stream', 'util'],
globals: {
Buffer: true,
global: true,
process: true,
},
}),
sveltekit(),
],
})

0 comments on commit d7edd31

Please sign in to comment.