add utils package + move get tokens to lib folder
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
"build:stable": "vite build && electrobun build --env=stable"
|
||||
},
|
||||
"dependencies": {
|
||||
"@koins/utils": "workspace:*",
|
||||
"@alchemy/wallet-apis": "^5.0.0-beta.28",
|
||||
"electrobun": "^1.18.1",
|
||||
"ethers": "^6.16.0",
|
||||
|
||||
@@ -8,6 +8,8 @@ import {
|
||||
Utils,
|
||||
} from 'electrobun/bun'
|
||||
import { inspect } from 'util'
|
||||
import { getTokenMetadata, getTokensBalances } from './lib/alchemy'
|
||||
import { tryCatch } from '@koins/utils'
|
||||
|
||||
const DEV_SERVER_PORT = 5173
|
||||
const DEV_SERVER_URL = `http://localhost:${DEV_SERVER_PORT}`
|
||||
@@ -196,46 +198,33 @@ async function fetchAlchemyTokenBalances(
|
||||
chainid: string,
|
||||
address: string,
|
||||
): Promise<TokenBalanceResult[]> {
|
||||
const network = ALCHEMY_NETWORKS[chainid]
|
||||
if (!network) return []
|
||||
const url = `https://${network}.g.alchemy.com/v2/${key}`
|
||||
|
||||
const post = (body: any) =>
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body),
|
||||
}).then((r) => r.json())
|
||||
|
||||
const balRes = await post({
|
||||
jsonrpc: '2.0',
|
||||
id: 0,
|
||||
method: 'alchemy_getTokenBalances',
|
||||
params: [address, 'erc20'],
|
||||
})
|
||||
// console.log(inspect(balRes, { depth: null }))
|
||||
|
||||
const tokens: any[] = balRes.result?.tokenBalances ?? []
|
||||
const nonZero = tokens.filter(
|
||||
(t: any) => t.tokenBalance !== '0x0' && !t.error,
|
||||
const [balRes, balResError] = await tryCatch(
|
||||
getTokensBalances(key, chainid, address),
|
||||
)
|
||||
|
||||
if (balResError) {
|
||||
console.log('Get Tokens Balance', balResError)
|
||||
return []
|
||||
}
|
||||
|
||||
if (!balRes) return []
|
||||
|
||||
const tokens = balRes.result?.tokenBalances ?? []
|
||||
const nonZero = tokens.filter((t) => t.tokenBalance !== '0x0')
|
||||
|
||||
const metas = await Promise.allSettled(
|
||||
nonZero.map((t: any) =>
|
||||
post({
|
||||
jsonrpc: '2.0',
|
||||
id: 0,
|
||||
method: 'alchemy_getTokenMetadata',
|
||||
params: [t.contractAddress],
|
||||
}),
|
||||
nonZero.map((t) =>
|
||||
getTokenMetadata(key, chainid, t.contractAddress),
|
||||
),
|
||||
)
|
||||
console.log(inspect(metas, { depth: null }))
|
||||
if (!metas) return []
|
||||
|
||||
return nonZero
|
||||
.map((t: any, i: number) => {
|
||||
const meta =
|
||||
metas[i].status === 'fulfilled' ? metas[i].value.result : null
|
||||
metas[i].status === 'fulfilled' && metas[i].value
|
||||
? metas[i].value.result
|
||||
: null
|
||||
return {
|
||||
symbol: meta?.symbol ?? 'Unknown',
|
||||
decimals: meta?.decimals ?? 0,
|
||||
@@ -371,13 +360,17 @@ const rpc = BrowserView.defineRPC<RPC>({
|
||||
name: 'alchemy_key',
|
||||
})
|
||||
if (!key) return []
|
||||
const result = await fetchAlchemyTokenBalances(
|
||||
key,
|
||||
chainid,
|
||||
address,
|
||||
)
|
||||
// console.log(inspect(result, { depth: null }))
|
||||
return result
|
||||
try {
|
||||
const result = await fetchAlchemyTokenBalances(
|
||||
key,
|
||||
chainid,
|
||||
address,
|
||||
)
|
||||
return result
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
return []
|
||||
}
|
||||
},
|
||||
},
|
||||
messages: {},
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { tryCatch } from '@koins/utils'
|
||||
|
||||
export const post = async <T>(
|
||||
url: string,
|
||||
body: any,
|
||||
): Promise<{ jsonrpc: '2.0'; id: number; result: T }> => {
|
||||
const [response, error] = await tryCatch(
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body),
|
||||
}),
|
||||
)
|
||||
|
||||
if (error) {
|
||||
console.log(error)
|
||||
throw error
|
||||
}
|
||||
|
||||
console.log('data', await response.text())
|
||||
|
||||
const [data, dataError] = await tryCatch(response.json())
|
||||
|
||||
if (dataError) {
|
||||
console.log(dataError)
|
||||
throw dataError
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { post } from './call'
|
||||
import { getChainID, getURL } from './network'
|
||||
import { inspect } from 'util'
|
||||
|
||||
export const getTokensBalances = async (
|
||||
key: string,
|
||||
chainid: string,
|
||||
address: string,
|
||||
) => {
|
||||
const chainId = getChainID(chainid)
|
||||
if (!chainId) return
|
||||
|
||||
const url = getURL({
|
||||
chainId,
|
||||
key,
|
||||
})
|
||||
|
||||
const balRes = await post<{
|
||||
address: `0x${string}`
|
||||
tokenBalances: {
|
||||
contractAddress: `0x${string}`
|
||||
tokenBalance: string
|
||||
}[]
|
||||
}>(url, {
|
||||
jsonrpc: '2.0',
|
||||
id: 0,
|
||||
method: 'alchemy_getTokenBalances',
|
||||
params: [address, 'erc20'],
|
||||
})
|
||||
|
||||
console.log(inspect(balRes, { depth: null, colors: true }))
|
||||
|
||||
return balRes
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { post } from './call'
|
||||
import { getChainID, getURL } from './network'
|
||||
|
||||
export const getTokenMetadata = async (
|
||||
key: string,
|
||||
chainid: string,
|
||||
tokenAddress: string,
|
||||
) => {
|
||||
const chainId = getChainID(chainid)
|
||||
if (!chainId) return
|
||||
|
||||
const url = getURL({
|
||||
chainId,
|
||||
key,
|
||||
})
|
||||
|
||||
const result = await post<{
|
||||
name: string | null
|
||||
symbol: string | null
|
||||
decimals: number | null
|
||||
logo: string | null
|
||||
}>(url, {
|
||||
jsonrpc: '2.0',
|
||||
id: 0,
|
||||
method: 'alchemy_getTokenMetadata',
|
||||
params: [tokenAddress],
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from './get-token-balances'
|
||||
export * from './get-token-metadata'
|
||||
export * from './types'
|
||||
@@ -0,0 +1,31 @@
|
||||
export const ALCHEMY_NETWORKS = {
|
||||
'1': 'eth-mainnet',
|
||||
'137': 'polygon-mainnet',
|
||||
'56': 'bnb-mainnet',
|
||||
} as const
|
||||
|
||||
export type ChainID = keyof typeof ALCHEMY_NETWORKS
|
||||
|
||||
export const CHAIN_ID = Object.keys(
|
||||
ALCHEMY_NETWORKS,
|
||||
) as Array<ChainID>
|
||||
|
||||
export const getChainID = (id: string) => {
|
||||
if (CHAIN_ID.includes(id as ChainID)) {
|
||||
return id as ChainID
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export const getURL = ({
|
||||
key,
|
||||
chainId,
|
||||
}: {
|
||||
chainId: ChainID
|
||||
key: string
|
||||
}) => {
|
||||
const network = ALCHEMY_NETWORKS[chainId]
|
||||
const url = `https://${network}.g.alchemy.com/v2/${key}`
|
||||
|
||||
return url
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export type Token = {}
|
||||
|
||||
export type TokenBalance = {}
|
||||
Reference in New Issue
Block a user