feat: Migrate to EtherScan v2 API for supported EVM chains (#2264)

David Adegoke committed May 22, 2025 at 22:32 UTC 1aac17676de86b68f4c00b1a4ba05b58b65c1dff
3 files changed +18 -12
cw_ethereum/lib/ethereum_client.dart
+4 -2
@@ -19,7 +19,8 @@ class EthereumClient extends EVMChainClient {
19 Future<List<EVMChainTransactionModel>> fetchTransactions(String address,
20 {String? contractAddress}) async {
21 try {
22 - final response = await httpClient.get(Uri.https("api.etherscan.io", "/api", {
22 + final response = await httpClient.get(Uri.https("api.etherscan.io", "/v2/api", {
23 + "chainid": "$chainId",
24 "module": "account",
25 "action": contractAddress != null ? "tokentx" : "txlist",
26 if (contractAddress != null) "contractaddress": contractAddress,
@@ -50,7 +51,8 @@ class EthereumClient extends EVMChainClient {
51 @override
52 Future<List<EVMChainTransactionModel>> fetchInternalTransactions(String address) async {
53 try {
53 - final response = await httpClient.get(Uri.https("api.etherscan.io", "/api", {
54 + final response = await httpClient.get(Uri.https("api.etherscan.io", "/v2/api", {
55 + "chainid": "$chainId",
56 "module": "account",
57 "action": "txlistinternal",
58 "address": address,
cw_polygon/lib/polygon_client.dart
+6 -4
@@ -40,12 +40,13 @@ class PolygonClient extends EVMChainClient {
40 Future<List<EVMChainTransactionModel>> fetchTransactions(String address,
41 {String? contractAddress}) async {
42 try {
43 - final response = await httpClient.get(Uri.https("api.polygonscan.com", "/api", {
43 + final response = await httpClient.get(Uri.https("api.etherscan.io", "/v2/api", {
44 + "chainid": "$chainId",
45 "module": "account",
46 "action": contractAddress != null ? "tokentx" : "txlist",
47 if (contractAddress != null) "contractaddress": contractAddress,
48 "address": address,
48 - "apikey": secrets.polygonScanApiKey,
49 + "apikey": secrets.etherScanApiKey,
50 }));
51
52 final jsonResponse = json.decode(response.body) as Map<String, dynamic>;
@@ -67,11 +68,12 @@ class PolygonClient extends EVMChainClient {
68 @override
69 Future<List<EVMChainTransactionModel>> fetchInternalTransactions(String address) async {
70 try {
70 - final response = await httpClient.get(Uri.https("api.polygonscan.io", "/api", {
71 + final response = await httpClient.get(Uri.https("api.etherscan.io", "/v2/api", {
72 + "chainid": "$chainId",
73 "module": "account",
74 "action": "txlistinternal",
75 "address": address,
74 - "apikey": secrets.polygonScanApiKey,
76 + "apikey": secrets.etherScanApiKey,
77 }));
78
79 final jsonResponse = json.decode(response.body) as Map<String, dynamic>;
lib/view_model/dashboard/home_settings_view_model.dart
+8 -6
@@ -297,13 +297,14 @@ abstract class HomeSettingsViewModelBase with Store {
297 required bool isEthereum,
298 }) async {
299 final uri = Uri.https(
300 - isEthereum ? "api.etherscan.io" : "api.polygonscan.com",
301 - "/api",
300 + "api.etherscan.io",
301 + "/v2/api",
302 {
303 + "chainid": isEthereum ? "1" : "137",
304 "module": "token",
305 "action": "tokeninfo",
306 "contractaddress": contractAddress,
306 - "apikey": isEthereum ? secrets.etherScanApiKey : secrets.polygonScanApiKey,
307 + "apikey": secrets.etherScanApiKey,
308 },
309 );
310
@@ -338,13 +339,14 @@ abstract class HomeSettingsViewModelBase with Store {
339 required bool isEthereum,
340 }) async {
341 final uri = Uri.https(
341 - isEthereum ? "api.etherscan.io" : "api.polygonscan.com",
342 - "/api",
342 + "api.etherscan.io",
343 + "/v2/api",
344 {
345 + "chainid": isEthereum ? "1" : "137",
346 "module": "contract",
347 "action": "getsourcecode",
348 "address": contractAddress,
347 - "apikey": isEthereum ? secrets.etherScanApiKey : secrets.polygonScanApiKey,
349 + "apikey": secrets.etherScanApiKey,
350 },
351 );
352