add sqlite to cache token metadata

This commit is contained in:
2026-05-14 20:49:54 +08:00
parent 92156f572d
commit cae5d4023f
15 changed files with 296 additions and 8 deletions
@@ -1,3 +1,6 @@
import { eq, and } from 'drizzle-orm'
import { db } from '../db'
import { tokenMetadata } from '../db/schema'
import { post } from './call'
import { getChainID, getURL } from './network'
@@ -9,6 +12,30 @@ export const getTokenMetadata = async (
const chainId = getChainID(chainid)
if (!chainId) return
const cached = db
.select()
.from(tokenMetadata)
.where(
and(
eq(tokenMetadata.chainId, chainId),
eq(tokenMetadata.contractAddress, tokenAddress.toLowerCase()),
),
)
.get()
if (cached) {
return {
jsonrpc: '2.0' as const,
id: 0,
result: {
name: cached.name ?? null,
symbol: cached.symbol,
decimals: cached.decimals ?? null,
logo: cached.logo ?? null,
},
}
}
const url = getURL({
chainId,
key,
@@ -26,5 +53,23 @@ export const getTokenMetadata = async (
params: [tokenAddress],
})
if (result?.result?.symbol) {
try {
await db
.insert(tokenMetadata)
.values({
name: result.result.name,
symbol: result.result.symbol,
decimals: result.result.decimals,
logo: result.result.logo,
contractAddress: tokenAddress.toLowerCase(),
chainId,
})
.onConflictDoNothing()
} catch (e) {
console.log('Failed to cache token metadata', e)
}
}
return result
}
@@ -35,6 +35,7 @@ export const getTransactionHistory = async (
const outRequest = post<{
transfers: Transaction[]
pageKey: string
}>(url, body(address, undefined))
const inRequest = post<{
+5
View File
@@ -0,0 +1,5 @@
import { drizzle } from 'drizzle-orm/bun-sqlite'
import { sqlite } from '../sqlite'
import { relations } from './relations'
export const db = drizzle({ client: sqlite, relations })
+4
View File
@@ -0,0 +1,4 @@
import { defineRelations } from 'drizzle-orm'
import * as schema from './schema'
export const relations = defineRelations(schema, () => ({}))
+19
View File
@@ -0,0 +1,19 @@
import { int, sqliteTable, text, uniqueIndex } from 'drizzle-orm/sqlite-core'
export const tokenMetadata = sqliteTable(
'token_metadata',
{
name: text(),
symbol: text().notNull(),
decimals: int(),
logo: text(),
contractAddress: text().notNull(),
chainId: text().notNull(),
},
(table) => ({
contractUnique: uniqueIndex('contract_unique').on(
table.chainId,
table.contractAddress,
),
}),
)
+19
View File
@@ -0,0 +1,19 @@
const env = Bun.env.ELECTROBUN_ENV as 'dev' | 'prod' | undefined
export const getENV = () => {
let appName
let dbFilename
if (env === 'prod') {
appName = 'koins'
dbFilename = 'koins.db'
} else {
appName = 'koins-dev'
dbFilename = 'koins-dev.db'
}
return {
env: env || 'dev',
appName,
dbFilename,
}
}
+16
View File
@@ -0,0 +1,16 @@
import { Database } from 'bun:sqlite'
import envPaths from 'env-paths'
import { join } from 'path'
import { mkdirSync } from 'fs'
import { getENV } from '../get-env'
const env = getENV()
const { data } = envPaths(env.appName, { suffix: '' })
mkdirSync(data, { recursive: true })
console.log(data)
export const sqlite = new Database(join(data, env.dbFilename), {
create: true,
})