Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add event based interpreters #103

Merged
merged 5 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/breezy-jokes-jump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@3loop/transaction-decoder': minor
---

Add human redable signature to decoded transaciton events
5 changes: 5 additions & 0 deletions .changeset/gorgeous-planes-decide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@3loop/transaction-interpreter': minor
---

Add option to specify interpreters based on event signature. Add new event-based interpreter.
38 changes: 37 additions & 1 deletion apps/web/src/app/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,81 +6,115 @@ export const EXAMPLE_TXS = {
name: 'Repay',
hash: '0xc0bd04d7e94542e58709f51879f64946ff4a744e1c37f5f920cea3d478e115d7',
chainID: 1,
interpreter: 'aave',
},
{
name: 'Deposit',
hash: '0xe61092c0ce50d7cf7c43a060c3ca023f16f99729ccae7a6d011e408d93d6f93f',
chainID: 1,
interpreter: 'aave',
},
{
name: 'Borrow',
hash: '0x1fc39eea9247cd9aa9d311bf83666afa6c9b30d66515d313e4d04dcb07a73a8f',
chainID: 1,
interpreter: 'aave',
},
{
name: 'Withdraw',
hash: '0xf42e5d28e2fea319cf3675c57c57849ad5d178f17f8a17c94c7607321cf1b959',
chainID: 1,
interpreter: 'aave',
},
],
'NFTS BLUR': [
{
name: 'Sell',
hash: '0xb5c56b4213325cb3fba274d0467b40ab28d9d475ba4a652b46943251c3c0d697',
chainID: 1,
interpreter: 'blur',
},
{
name: 'Buy',
hash: '0x9ed41e3d626605673c282dc8a0f7429e7abcab112d6529b0c77ee43954202cab',
chainID: 1,
interpreter: 'blur',
},
],
'Account Abstraction': [
{
name: 'handleOps',
hash: '0xcc1f4e40e1186503bb19b5716c8527947ab4c7e972b79d3d64ad8a015cf10ff8',
chainID: 1,
interpreter: 'aa',
},
],
'Swap Transactions': [
{
name: '1inch',
hash: '0x8e36953374f7b71fe4c20898c8ade628cf71d5d0303ec8ad368b254629db2985',
chainID: 1,
interpreter: '1inch',
},
{
name: 'Kyberswap',
hash: '0xfe429c6acf3c372270374122fe922282311bea31e09419f7fb167c6d8912372d',
chainID: 1,
interpreter: 'kyberswap',
},
{
name: 'Metamask Router',
hash: '0xcb2b8448a1f5dc7a29dc4ab3e79051e7460a4602b82ee5af2b3202c2e8b614de',
chainID: 1,
interpreter: 'metamaskRouter',
},
{
name: 'OKX',
hash: '0xf30013e82cd1197cb867f89ac33480699827282ca19ff49f0810a75e138ec869',
chainID: 1,
interpreter: 'okx',
},
],
'Bridge Transactions': [
{
name: 'Hop Protocol',
hash: '0x7a7f39aee8c68f9be272b093f613280a8122291923edba83cc3f1f1754a70ecd',
chainID: 1,
interpreter: 'hop-protocol',
},
],
'Friend.Tech (Base mainnet)': [
{
name: 'Sell',
hash: '0x9e18a3ab3faed1b13412e5cca532e083761410bb58e0423a5cd865a18a8e49a3',
chainID: 8453,
interpreter: 'friend-tech',
},
{
name: 'Buy',
hash: '0x24067751e1bb553b8f5ccd6958edc3fa27489f9836bc0cd477383b143825dca5',
chainID: 8453,
interpreter: 'friend-tech',
},
],
'Moxie (Base mainnet)': [
{
name: 'Sell',
hash: '0x0f2540f5936228704cf94348085fb16fde87bfb554a76f0234dc8d5a804b0a7b',
chainID: 8453,
interpreter: 'moxie',
},
{
name: 'Buy',
hash: '0xc355f63566a9407d9a610b13f5e4e7fc64ce526f34503af18666904b63e0556f',
chainID: 8453,
interpreter: 'moxie',
},
{
name: 'Burn',
hash: '0x88833e8e873c09b3def62c2fe82f5ac3a20cdb936acce5ba27a5e4ab20417831',
chainID: 8453,
interpreter: 'moxie',
},
],
}
Expand All @@ -106,7 +140,7 @@ export const supportedChains: {
name: 'Base mainnet',
chainID: 8453,
rpcUrl: process.env.BASE_RPC_URL as string,
traceAPI: 'geth',
traceAPI: 'parity',
batchMaxCount: 1,
},
{
Expand Down Expand Up @@ -149,3 +183,5 @@ const generateNavItems = (transactions: any) => {
export const sidebarNavItems = Object.fromEntries(
Object.entries(EXAMPLE_TXS).map(([key, value]) => [key, generateNavItems(value)]),
)

export const INTERPRETER_REPO = 'https://github.com/3loop/loop-decoder/tree/main/packages/transaction-interpreter'
24 changes: 22 additions & 2 deletions apps/web/src/app/tx/[chainID]/[hash]/form.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client'
import * as React from 'react'
import { Label } from '@/components/ui/label'
import { DEFAULT_CHAIN_ID, sidebarNavItems } from '@/app/data'
import { DEFAULT_CHAIN_ID, sidebarNavItems, EXAMPLE_TXS, INTERPRETER_REPO } from '@/app/data'
import { useLocalStorage } from 'usehooks-ts'
import { SidebarNav } from '@/components/ui/sidebar-nav'
import { PlayIcon } from '@radix-ui/react-icons'
Expand Down Expand Up @@ -64,6 +64,16 @@ export default function DecodingForm({ decoded, currentHash, currentChainID }: F
}
}, [schema, decoded, result, onRun])

const interpreterSourceLink = React.useMemo(() => {
const matchingExample = Object.values(EXAMPLE_TXS)
.flatMap((categoryTxs) => categoryTxs)
.find((tx) => tx.hash.toLowerCase() === currentHash?.toLowerCase())

return matchingExample?.interpreter
? `${INTERPRETER_REPO}/interpreters/${matchingExample?.interpreter}.ts`
: INTERPRETER_REPO
}, [currentHash])

return (
<div className="grid h-full items-stretch gap-6 grid-cols-1 lg:grid-cols-[1fr_200px]">
<div className="md:order-1 flex flex-col space-y-4">
Expand Down Expand Up @@ -93,7 +103,17 @@ export default function DecodingForm({ decoded, currentHash, currentChainID }: F

<div className="grid gap-6 grid-cols-1 lg:grid-cols-2 h-full">
<div className="flex flex-col gap-2 lg:col-span-2 min-h-[40vh] lg:min-h-[initial]">
<Label>Interpretation:</Label>
<Label>
Interpretation:{' '}
<a
href={interpreterSourceLink}
target="_blank"
rel="noopener noreferrer"
className="text-xs text-blue-500 hover:underline"
>
(Source Code)
</a>
</Label>

<CodeBlock
language="javascript"
Expand Down
11 changes: 7 additions & 4 deletions apps/web/src/lib/contract-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@ export const AbiStoreLive = Layer.succeed(
AbiStore,
AbiStore.of({
strategies: {
default: [
default: [SourcifyStrategyResolver(), OpenchainStrategyResolver(), FourByteStrategyResolver()],
1: [
EtherscanStrategyResolver({
apikey: process.env.ETHERSCAN_API_KEY,
}),
SourcifyStrategyResolver(),
OpenchainStrategyResolver(),
FourByteStrategyResolver(),
],
8453: [
EtherscanStrategyResolver({
apikey: process.env.BASESCAN_API_KEY,
}),
],
169: [
BlockscoutStrategyResolver({
Expand Down
5 changes: 5 additions & 0 deletions packages/transaction-decoder/src/decoding/log-decode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { getAndCacheAbi } from '../abi-loader.js'
import { getAndCacheContractMeta } from '../contract-meta-loader.js'
import * as AbiDecoder from './abi-decode.js'
import { stringify } from '../helpers/stringify.js'
import { formatAbiItem } from 'viem/utils'

const decodedLog = (transaction: GetTransactionReturnType, logItem: Log) =>
Effect.gen(function* () {
Expand Down Expand Up @@ -85,11 +86,14 @@ const decodedLog = (transaction: GetTransactionReturnType, logItem: Log) =>
},
})

const textSignature = formatAbiItem(fragment)

const rawLog: RawDecodedLog = {
events: decodedParams.filter((x) => x != null) as DecodedLogEvent[],
name: eventName,
address,
logIndex: logItem.logIndex ?? -1,
signature: textSignature,
decoded: true,
}

Expand All @@ -115,6 +119,7 @@ const transformLog = (transaction: GetTransactionReturnType, log: RawDecodedLog)
decimals: contractData?.decimals || null,
chainID: Number(transaction.chainId),
contractType: contractData?.type ?? 'OTHER',
signature: log.signature,
event: {
eventName: log.name,
logIndex: log.logIndex,
Expand Down
1 change: 1 addition & 0 deletions packages/transaction-decoder/src/decoding/trace-decode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ export function augmentTraceLogs(
event: traceLogToEvent(log),
decimals: null,
chainID: Number(transaction.chainId),
signature: null,
}),
)
return [...interactionsWithoutNativeTransfers, ...nativeTransfers]
Expand Down
2 changes: 2 additions & 0 deletions packages/transaction-decoder/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export interface RawDecodedLog {
logIndex: number
events: DecodedLogEvent[]
decoded: boolean
signature: string
}

export type ContractType = 'ERC20' | 'ERC721' | 'ERC1155' | 'WETH' | 'OTHER' | string
Expand All @@ -69,6 +70,7 @@ export interface Interaction {
decimals: number | null
chainID: number
contractType: ContractType
signature: string | null
event: InteractionEvent
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"owner": "0x997162a6BEB886655d3e355B190fe0C8f0c37F0e",
},
},
"signature": "ApprovalForAll(address,address,bool)",
},
],
"methodCall": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"value": "10000000000000000",
},
},
"signature": null,
},
{
"chainID": 1,
Expand All @@ -88,6 +89,7 @@
"value": "5000000000000000",
},
},
"signature": null,
},
{
"chainID": 1,
Expand All @@ -106,6 +108,7 @@
"value": "5000000000000000",
},
},
"signature": null,
},
],
"methodCall": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
"tokenId": "9912",
},
},
"signature": "Approval(address,address,uint256)",
},
{
"chainID": 1,
Expand All @@ -106,6 +107,7 @@
"tokenId": "9912",
},
},
"signature": "Transfer(address,address,uint256)",
},
{
"chainID": 1,
Expand All @@ -123,6 +125,7 @@
"to": "0xde02FFFb824720E25674a604BaF2277f21c66a0F",
},
},
"signature": "Transfer(address,address,uint256)",
},
{
"chainID": 1,
Expand All @@ -140,6 +143,7 @@
"tokenIdListingIndexTrader": "3708519897897837542598287020838563106149287084151295037",
},
},
"signature": "Execution721Packed(bytes32,uint256,uint256)",
},
],
"methodCall": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"user": "0xbbDd1b3C87c211E482CdA98eA14fa8bF50022CA0",
},
},
"signature": "CancelTrade(address,bytes32,uint256,uint256)",
},
],
"methodCall": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"value": "2",
},
},
"signature": "TransferSingle(address,address,address,uint256,uint256)",
},
],
"methodCall": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
"wad": "1361017781386941",
},
},
"signature": "Transfer(address,address,uint256)",
},
{
"chainID": 1,
Expand All @@ -115,6 +116,7 @@
"reserve1": "179139477",
},
},
"signature": "Sync(uint112,uint112)",
},
{
"chainID": 1,
Expand All @@ -135,6 +137,7 @@
"to": "0x12D737470fB3ec6C3DeEC9b518100Bec9D520144",
},
},
"signature": "Swap(address,uint256,uint256,uint256,uint256,address)",
},
{
"chainID": 1,
Expand All @@ -151,6 +154,7 @@
"wad": "1361017781386941",
},
},
"signature": "Withdrawal(address,uint256)",
},
{
"chainID": 1,
Expand All @@ -169,6 +173,7 @@
"value": "1361017781386941",
},
},
"signature": null,
},
{
"chainID": 1,
Expand All @@ -187,6 +192,7 @@
"value": "396600581496154",
},
},
"signature": null,
},
{
"chainID": 1,
Expand All @@ -205,6 +211,7 @@
"value": "964417199890787",
},
},
"signature": null,
},
],
"methodCall": {
Expand Down
Loading
Loading