packages/synapse-interface/utils/actions/getErc20TokenTransfers.ts
import { createPublicClient, http, Address, Log, Chain } from 'viem'
/**
* Wrapper function around getErc20TokenTransferLogs() and transformTransferLogsToData()
*
* @param tokenAddress token to query transfer logs
* @param fromAddress transfer from address
* @param toAddress transfer to address
* @param startBlock block to start query logs
* @param toBlock block to stop query logs
* @param chain viem Chain where token resides
* @returns Will return raw logs and parsed logs
*/
export const getErc20TokenTransfers = async (
tokenAddress: Address,
fromAddress: Address,
toAddress: Address,
chain: Chain,
startBlock: bigint,
toBlock?: bigint
) => {
if (!tokenAddress || !fromAddress || !toAddress) {
console.error('Invalid address')
return null
}
if (!startBlock && typeof startBlock !== 'bigint') {
console.error('Invalid start block')
return null
}
if (!chain) {
console.error('Invalid Viem Chain')
return null
}
const logs = await getErc20TokenTransferLogs(
tokenAddress,
fromAddress,
toAddress,
chain,
startBlock,
toBlock
)
const data = transformTransferLogsToData(logs)
return {
logs,
data,
}
}
const getErc20TokenTransferLogs = async (
tokenAddress: Address,
fromAddress: Address,
toAddress: Address,
chain: Chain,
startBlock: bigint,
toBlock?: bigint
) => {
/** Create public client to access logs while connected to any chain */
const publicClient = createPublicClient({
chain,
transport: http(),
})
const logs: Log[] = await publicClient.getLogs({
address: tokenAddress,
event: {
type: 'event',
name: 'Transfer',
inputs: [
{ type: 'address', indexed: true, name: 'from' },
{ type: 'address', indexed: true, name: 'to' },
{ type: 'uint256', indexed: false, name: 'value' },
],
},
args: {
from: fromAddress,
to: toAddress,
},
fromBlock: startBlock,
toBlock: toBlock ?? null,
})
return logs
}
const transformTransferLogsToData = (logs: any[]) => {
return logs.map((log) => {
return {
tokenAddress: log.address,
fromAddress: log?.args?.from,
toAddress: log?.args?.to,
transferValue: log?.args?.value,
blockNumber: log.blockNumber,
transactionHash: log.transactionHash,
}
})
}