Skip to content

Commit

Permalink
move sqlite deps out of client
Browse files Browse the repository at this point in the history
  • Loading branch information
ezynda3 committed Sep 18, 2024
1 parent 55429a3 commit 7dc942d
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 80 deletions.
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()'
}
85 changes: 11 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,6 +59,16 @@ 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,
Expand All @@ -85,72 +91,3 @@ export const getContractInformation = async (
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 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
}

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))
2 changes: 1 addition & 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 Down
6 changes: 1 addition & 5 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 Down

0 comments on commit 7dc942d

Please # to comment.