fetchEtherscanWithRatelimitRetries<T> method
inherited
Implementation
Future<T> fetchEtherscanWithRatelimitRetries<T>(
String rawEndpoint, {
int maxRetries = 10,
}) async {
final baseEndpoint = getBaseEtherscanEndpoint(rawEndpoint);
bool maybeUseApiKey = false;
for (var i = 0; i < maxRetries; i++) {
String endpoint = rawEndpoint;
String? currentApiKey;
if (_needsApiKey(baseEndpoint)) {
maybeUseApiKey = false;
currentApiKey = _getRandomApiKey();
if (currentApiKey == null) {
Logger.logError("No available API keys");
throw Exception("No available API keys");
}
endpoint = "$rawEndpoint&apikey=$currentApiKey";
} else if (maybeUseApiKey) {
maybeUseApiKey = false;
currentApiKey = _getRandomApiKey();
if (currentApiKey != null) {
endpoint = "$rawEndpoint&apikey=$currentApiKey";
}
}
final response = await HTTPService.client.get(
Uri.parse(endpoint),
headers: _buildRequestHeaders(),
);
if (response.statusCode == 200) {
final body = jsonDecode(response.body);
int status = int.tryParse(body['status'] ?? '') ?? -1;
final result = body['result'];
if (status == 1) return result;
if (status == 0) {
final result_s = result is String ? result : 'empty';
if (result == null) {
continue;
}
if (result == "Missing/Invalid API Key") {
_setNeedsApiKey(baseEndpoint, true);
} else if (result_s.contains('Invalid API Key')) {
invalidApiKeys.add(currentApiKey!);
if (_getRandomApiKey() == null) {
await Future.delayed(noApiKeyRetryIntervall);
} else {
maybeUseApiKey = true; // Try again with an API key
}
} else if (result_s.contains("Max daily rate limit")) {
if (currentApiKey != null) {
_excludeApiKey(currentApiKey);
}
if (_getRandomApiKey() == null) {
await Future.delayed(noApiKeyRetryIntervall);
} else {
maybeUseApiKey = true; // Try again with an API key
}
} else if (result_s.contains('for higher rate limit')) {
if (_getRandomApiKey() == null) {
await Future.delayed(noApiKeyRetryIntervall);
} else {
maybeUseApiKey = true; // Try again with an API key
}
} else if (result_s.contains("Max calls per sec")) {
await Future.delayed(apiKeyRetryIntervall);
} else {
String message = body['message'];
if (message != "NOTOK") return result;
}
}
}
}
throw Exception("Failed to fetch $rawEndpoint after $maxRetries retries");
}