Skip to content

Commit 26529ba

Browse files
authored
Fix "onchain score" component by updating to Etherscan API V2 (#2684)
* update to use etherscan v2 api * remove deprecation warning * fix lint errors * actually fix lints * simplify type definitions
1 parent ea2f47c commit 26529ba

File tree

2 files changed

+20
-14
lines changed
  • apps/web
    • app/(basenames)/api/proxy
    • src/components/Basenames/UsernameProfileSectionHeatmap

2 files changed

+20
-14
lines changed

apps/web/app/(basenames)/api/proxy/route.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { NextRequest, NextResponse } from 'next/server';
22
import { isAddress } from 'viem';
33

44
const ETHERSCAN_API_KEY = process.env.ETHERSCAN_API_KEY;
5-
const BASESCAN_API_KEY = process.env.BASESCAN_API_KEY;
65
const TALENT_PROTOCOL_API_KEY = process.env.TALENT_PROTOCOL_API_KEY;
76

87
export async function GET(req: NextRequest) {
@@ -19,16 +18,16 @@ export async function GET(req: NextRequest) {
1918
try {
2019
switch (apiType) {
2120
case 'etherscan':
22-
apiUrl = `https://api.etherscan.io/api?address=${address}&apikey=${ETHERSCAN_API_KEY}&module=account&action=txlist`;
21+
apiUrl = `https://api.etherscan.io/v2/api?module=account&action=txlist&address=${address}&chainid=1&apikey=${ETHERSCAN_API_KEY}`;
2322
break;
2423
case 'base-sepolia':
25-
apiUrl = `https://api-sepolia.basescan.org/api?address=${address}&apikey=${BASESCAN_API_KEY}&module=account&action=txlistinternal`;
24+
apiUrl = `https://api.etherscan.io/v2/api?module=account&action=txlistinternal&address=${address}&chainid=84532&apikey=${ETHERSCAN_API_KEY}`;
2625
break;
2726
case 'basescan':
28-
apiUrl = `https://api.basescan.org/api?address=${address}&apikey=${BASESCAN_API_KEY}&module=account&action=txlist`;
27+
apiUrl = `https://api.etherscan.io/v2/api?module=account&action=txlist&address=${address}&chainid=8453&apikey=${ETHERSCAN_API_KEY}`;
2928
break;
3029
case 'basescan-internal':
31-
apiUrl = `https://api.basescan.org/api?address=${address}&apikey=${BASESCAN_API_KEY}&module=account&action=txlistinternal`;
30+
apiUrl = `https://api.etherscan.io/v2/api?module=account&action=txlistinternal&address=${address}&chainid=8453&apikey=${ETHERSCAN_API_KEY}`;
3231
break;
3332
default:
3433
return NextResponse.json({ error: 'Invalid apiType parameter' }, { status: 400 });
@@ -49,7 +48,6 @@ export async function GET(req: NextRequest) {
4948
} else {
5049
responseData = await externalResponse.text();
5150
}
52-
5351
if (externalResponse.ok) {
5452
return NextResponse.json({ data: responseData });
5553
} else {

apps/web/src/components/Basenames/UsernameProfileSectionHeatmap/index.tsx

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -162,25 +162,32 @@ export default function UsernameProfileSectionHeatmap() {
162162
};
163163
};
164164

165+
type EtherscanApiResponse = {
166+
status: '1' | '0';
167+
message: string;
168+
result: unknown;
169+
};
170+
165171
const fetchTransactions = useCallback(
166172
async (apiUrl: string, retryCount = 3): Promise<Transaction[]> => {
167173
try {
168174
const response = await fetch(apiUrl);
169-
const json = (await response.json()) as {
170-
data: { result: Transaction[]; status: '1' | '0'; message: string };
171-
};
175+
const json = (await response.json()) as { data: EtherscanApiResponse };
176+
const data = json.data;
177+
178+
if (data.status === '1' && Array.isArray(data.result)) {
179+
return data.result as Transaction[];
180+
}
172181

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

0 commit comments

Comments
 (0)