Skip to content
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
10 changes: 4 additions & 6 deletions apps/web/app/(basenames)/api/proxy/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { NextRequest, NextResponse } from 'next/server';
import { isAddress } from 'viem';

const ETHERSCAN_API_KEY = process.env.ETHERSCAN_API_KEY;
const BASESCAN_API_KEY = process.env.BASESCAN_API_KEY;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all uses ETHERSCAN API key now

const TALENT_PROTOCOL_API_KEY = process.env.TALENT_PROTOCOL_API_KEY;

export async function GET(req: NextRequest) {
Expand All @@ -19,16 +18,16 @@ export async function GET(req: NextRequest) {
try {
switch (apiType) {
case 'etherscan':
apiUrl = `https://api.etherscan.io/api?address=${address}&apikey=${ETHERSCAN_API_KEY}&module=account&action=txlist`;
apiUrl = `https://api.etherscan.io/v2/api?module=account&action=txlist&address=${address}&chainid=1&apikey=${ETHERSCAN_API_KEY}`;
break;
case 'base-sepolia':
apiUrl = `https://api-sepolia.basescan.org/api?address=${address}&apikey=${BASESCAN_API_KEY}&module=account&action=txlistinternal`;
apiUrl = `https://api.etherscan.io/v2/api?module=account&action=txlistinternal&address=${address}&chainid=84532&apikey=${ETHERSCAN_API_KEY}`;
break;
case 'basescan':
apiUrl = `https://api.basescan.org/api?address=${address}&apikey=${BASESCAN_API_KEY}&module=account&action=txlist`;
apiUrl = `https://api.etherscan.io/v2/api?module=account&action=txlist&address=${address}&chainid=8453&apikey=${ETHERSCAN_API_KEY}`;
break;
case 'basescan-internal':
apiUrl = `https://api.basescan.org/api?address=${address}&apikey=${BASESCAN_API_KEY}&module=account&action=txlistinternal`;
apiUrl = `https://api.etherscan.io/v2/api?module=account&action=txlistinternal&address=${address}&chainid=8453&apikey=${ETHERSCAN_API_KEY}`;
break;
default:
return NextResponse.json({ error: 'Invalid apiType parameter' }, { status: 400 });
Expand All @@ -49,7 +48,6 @@ export async function GET(req: NextRequest) {
} else {
responseData = await externalResponse.text();
}

if (externalResponse.ok) {
return NextResponse.json({ data: responseData });
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,25 +162,32 @@ export default function UsernameProfileSectionHeatmap() {
};
};

type EtherscanApiResponse = {
status: '1' | '0';
message: string;
result: unknown;
};

const fetchTransactions = useCallback(
async (apiUrl: string, retryCount = 3): Promise<Transaction[]> => {
try {
const response = await fetch(apiUrl);
const json = (await response.json()) as {
data: { result: Transaction[]; status: '1' | '0'; message: string };
};
const json = (await response.json()) as { data: EtherscanApiResponse };
const data = json.data;

if (data.status === '1' && Array.isArray(data.result)) {
return data.result as Transaction[];
}

if (json.data?.status === '1' && Array.isArray(json.data.result)) {
return json.data.result;
} else if (json.data?.status === '0' && json.data.message === 'No transactions found') {
if (data.status === '0' && data.message === 'No transactions found') {
return []; // Return an empty array for no transactions
} else if (json.data?.status === '0' && json.data.message === 'Exception') {
} else if (data.status === '0' && data.message === 'Exception') {
if (retryCount > 0) {
console.log(`API returned an exception. Retrying... (${retryCount} attempts left)`);
await new Promise((resolve) => setTimeout(resolve, 2000));
return await fetchTransactions(apiUrl, retryCount - 1);
} else {
throw new Error(`API Error: ${json.data.message}`);
throw new Error(`API Error: ${data.message}`);
}
} else {
console.error('Unexpected API response structure:', json);
Expand Down Expand Up @@ -444,6 +451,7 @@ export default function UsernameProfileSectionHeatmap() {
style={{ direction: 'rtl' }}
className="w-full max-w-full overflow-x-auto overflow-y-hidden whitespace-nowrap"
>
{/* @ts-expect-error react-calendar-heatmap has incompatible JSX types in our setup; runtime is fine */}
<CalendarHeatmap
startDate={new Date(new Date().setFullYear(new Date().getFullYear() - 1))}
endDate={new Date()}
Expand Down