Skip to content

Commit b17c331

Browse files
author
Vernon Johnson
committed
wip: use insights to fetch wallet activity
1 parent 0b4045b commit b17c331

File tree

4 files changed

+130
-13
lines changed

4 files changed

+130
-13
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { DASHBOARD_THIRDWEB_CLIENT_ID } from "@/constants/env";
2+
3+
export interface Transaction {
4+
chain_id: number;
5+
hash: string;
6+
nonce: number;
7+
block_hash: string;
8+
block_number: number;
9+
block_timestamp: number;
10+
transaction_index: number;
11+
from_address: string;
12+
to_address: string | null;
13+
value: number;
14+
gas: number;
15+
gas_price: number | null;
16+
data: string | null;
17+
function_selector: string | null;
18+
max_fee_per_gas: number | null;
19+
max_priority_fee_per_gas: number | null;
20+
transaction_type: number | null;
21+
r: string | null;
22+
s: string | null;
23+
v: number | null;
24+
access_list_json: string | null;
25+
contract_address: string | null;
26+
gas_used: number | null;
27+
cumulative_gas_used: number | null;
28+
effective_gas_price: number | null;
29+
blob_gas_used: number | null;
30+
blob_gas_price: number | null;
31+
logs_bloom: string | null;
32+
status: boolean | null; // true for success, false for failure
33+
}
34+
35+
interface InsightsResponse {
36+
meta: {
37+
address: string;
38+
signature: string;
39+
page: number;
40+
total_items: number;
41+
total_pages: number;
42+
limit_per_chain: number;
43+
chain_ids: number[];
44+
};
45+
data: Transaction[];
46+
}
47+
48+
export async function fetchActivity(args: {
49+
chainId: number;
50+
address: string;
51+
page?: string;
52+
}): Promise<InsightsResponse> {
53+
const { chainId, address, page } = args;
54+
55+
const response = await fetch(
56+
`https://insight.thirdweb.com/v1/transactions?chain=${chainId}&filter_from_address=${address}&page=${page}&limit=10&sort_by=block_number&sort_order=desc`,
57+
{
58+
headers: {
59+
"x-client-id": DASHBOARD_THIRDWEB_CLIENT_ID,
60+
},
61+
},
62+
);
63+
64+
if (!response.ok) {
65+
throw new Error('Failed to fetch transaction history');
66+
}
67+
68+
const data: InsightsResponse = await response.json();
69+
return data;
70+
}

apps/dashboard/src/app/(dashboard)/hackweek/[chain_id]/[address]/components/ActivityOverview.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {} from "@radix-ui/react-tabs";
1313
import { useState } from "react";
1414

1515
interface Transaction {
16-
id: number;
16+
id: string;
1717
type: string;
1818
amount: string;
1919
to?: string;
@@ -86,9 +86,9 @@ export function ActivityOverview({
8686
<TableCell>{tx.type}</TableCell>
8787
<TableCell>{tx.amount}</TableCell>
8888
<TableCell>
89-
{tx.to && `To: ${tx.to}`}
90-
{tx.from && `From: ${tx.from}`}
91-
{tx.contract && `Contract: ${tx.contract}`}
89+
{tx.to && `To: ${tx.to} `}
90+
{tx.from && `From: ${tx.from} `}
91+
{tx.contract && `Contract: ${tx.contract} `}
9292
{tx.method && ` Method: ${tx.method}`}
9393
</TableCell>
9494
<TableCell>{tx.date}</TableCell>

apps/dashboard/src/app/(dashboard)/hackweek/[chain_id]/[address]/components/WalletDashboard.tsx

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"use client";
22
import type { ChainMetadata } from "thirdweb/chains";
33
import { useBalance } from "../hooks/getBalance";
4+
import { useGetActivity } from "../hooks/useGetActivity";
45
import { useGetERC20Tokens } from "../hooks/useGetERC20Tokens";
56
import { useGetNFTs } from "../hooks/useGetNFTs";
67
import { mockWalletData } from "../utils/mockData";
@@ -23,19 +24,21 @@ export function WalletDashboard(props: {
2324
const {
2425
tokens,
2526
isLoading: isLoadingERC20,
26-
error: errorERC20,
27+
// error: errorERC20,
2728
} = useGetERC20Tokens(props.chain.chainId, props.address);
28-
if (errorERC20) {
29-
console.error("Error fetching ERC20 tokens:", errorERC20);
30-
}
29+
// if (errorERC20) {
30+
// console.error("Error fetching ERC20 tokens:", errorERC20);
31+
// }
3132
const {
3233
nfts,
3334
isLoading: isLoadingNFTs,
34-
error: errorNFTs,
35+
// error: errorNFTs,
3536
} = useGetNFTs(props.chain.chainId, props.address);
36-
if (errorNFTs) {
37-
console.error("Error fetching NFTs:", errorNFTs);
38-
}
37+
// if (errorNFTs) {
38+
// console.error("Error fetching NFTs:", errorNFTs);
39+
// }
40+
41+
const { activity, isLoading: isLoadingActivity } = useGetActivity(props.chain.chainId, props.address)
3942

4043
return (
4144
<div className="grid gap-6">
@@ -45,7 +48,8 @@ export function WalletDashboard(props: {
4548
isLoading={isLoadingBalance}
4649
/>
4750
<ActivityOverview
48-
transactions={mockWalletData.transactions}
51+
transactions={activity}
52+
isLoading={isLoadingActivity}
4953
contracts={mockWalletData.contracts}
5054
/>
5155
<TokenHoldings
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { useEffect, useState } from "react";
2+
import { fetchActivity } from "../actions/fetchActivity";
3+
4+
interface ActivityItem {
5+
id: string;
6+
type: string;
7+
amount: string;
8+
to?: string;
9+
from?: string;
10+
contract?: string;
11+
method?: string;
12+
date: string;
13+
}
14+
15+
export function useGetActivity(chainId: number, address: string) {
16+
const [activity, setActivity] = useState<ActivityItem[]>([]);
17+
const [isLoading, setIsLoading] = useState(true);
18+
19+
useEffect(() => {
20+
(async () => {
21+
const response = await fetchActivity({ chainId, address, page: "0" });
22+
const activity = response.data.map((tx): ActivityItem => {
23+
let type = tx.to_address?.toLowerCase() === address.toLowerCase() ? "Receive" : "Send";
24+
if (tx.contract_address) {
25+
type = "Interact";
26+
}
27+
return {
28+
id: tx.hash,
29+
type,
30+
amount: `${tx.value / Math.pow(10, 18)} ETH`,
31+
to: tx.to_address || undefined,
32+
from: tx.from_address,
33+
contract: tx.contract_address || undefined,
34+
date: new Date(tx.block_timestamp * 1000).toLocaleString(),
35+
};
36+
})
37+
setActivity(activity);
38+
setIsLoading(false);
39+
})();
40+
}, [address, chainId]);
41+
42+
return { activity, isLoading };
43+
}

0 commit comments

Comments
 (0)