Skip to content

Commit

Permalink
refactor: migrate to etherscan v2 api
Browse files Browse the repository at this point in the history
  • Loading branch information
dev2-nomo committed Nov 7, 2024
1 parent a2aced1 commit a8ff97e
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 98 deletions.
21 changes: 12 additions & 9 deletions lib/src/crypto/evm/repositories/etherscan/etherscan_explorer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ class EtherscanExplorer extends EtherscanRepository {

EtherscanExplorer(super.base, super.apiKeys, this.currency);

String get gasOracleEndpoint => "$base?module=gastracker&action=gasoracle";
@override
String get base => "${super.base}?chainid=${currency.chainID}";

String buildBalanceEndpoint(String address) =>
"$base?module=account&action=balance&address=$address"
"$base&module=account&action=balance&address=$address"
.addOptionalParameter('tag', 'latest');

String buildTokenBalanceEndpoint(String address, String contractAddress) =>
"$base?module=account&action=tokenbalance&address=$address&contractaddress=$contractAddress"
"$base&module=account&action=tokenbalance&address=$address&contractaddress=$contractAddress"
.addOptionalParameter('tag', 'latest');

String buildTransactionEndpoint({
Expand All @@ -30,7 +31,7 @@ class EtherscanExplorer extends EtherscanRepository {
int? offset,
Sorting? sorting,
}) =>
"$base?module=account&action=txlist&address=$address"
"$base&module=account&action=txlist&address=$address"
.addOptionalParameter('startblock', startblock)
.addOptionalParameter('endblock', endblock)
.addOptionalParameter('page', page)
Expand All @@ -46,7 +47,7 @@ class EtherscanExplorer extends EtherscanRepository {
int? offset,
Sorting? sorting,
}) =>
"$base?module=account&action=tokentx&address=$address&contractaddress=$contractAddress"
"$base&module=account&action=tokentx&address=$address&contractaddress=$contractAddress"
.addOptionalParameter('startblock', startblock)
.addOptionalParameter('endblock', endblock)
.addOptionalParameter('page', page)
Expand All @@ -62,7 +63,7 @@ class EtherscanExplorer extends EtherscanRepository {
int? offset,
Sorting? sorting,
}) =>
"$base?module=account&action=tokennfttx&address=$address"
"$base&module=account&action=tokennfttx&address=$address"
.addOptionalParameter('contractaddress', contractAddress)
.addOptionalParameter('startblock', startblock)
.addOptionalParameter('endblock', endblock)
Expand Down Expand Up @@ -221,6 +222,8 @@ class EtherscanExplorer extends EtherscanRepository {
/// Fetch Gas Prices
///
Future<EvmNetworkFees> fetchGasPrice() async {
final gasOracleEndpoint = "${base}&module=gastracker&action=gasoracle";

final result = await fetchEtherscanWithRatelimitRetries(gasOracleEndpoint);
if (result is! Json) {
throw Exception("Failed to fetch gas price");
Expand All @@ -232,7 +235,7 @@ class EtherscanExplorer extends EtherscanRepository {

Future<int?> fetchEstimatedTime(int gasPrice) async {
final endpoint =
"$base?module=gastracker&action=gasestimate&gasprice=$gasPrice";
"$base&module=gastracker&action=gasestimate&gasprice=$gasPrice";
final result = await fetchEtherscanWithRatelimitRetries(endpoint);
if (result is! String) {
throw Exception("Failed to fetch gas price");
Expand Down Expand Up @@ -280,7 +283,7 @@ class ZeniqScanExplorer extends EtherscanExplorer {
int? offset,
Sorting? sorting,
}) {
return "$base?module=account&action=txlist&address=$address"
return "$base&module=account&action=txlist&address=$address"
.addOptionalParameter('start_block', startblock)
.addOptionalParameter('end_block', endblock)
.addOptionalParameter('page', page)
Expand All @@ -298,7 +301,7 @@ class ZeniqScanExplorer extends EtherscanExplorer {
int? offset,
Sorting? sorting,
}) {
return "$base?module=account&action=tokentx&address=$address&contractaddress=$contractAddress"
return "$base&module=account&action=tokentx&address=$address&contractaddress=$contractAddress"
.addOptionalParameter('start_block', startblock)
.addOptionalParameter('end_block', endblock)
.addOptionalParameter('page', page)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class EtherscanRepository {
String action = queryParams['action']!;

// Construct the base endpoint
return '$baseUrl?module=$module&action=$action';
return '$baseUrl&module=$module&action=$action';
} else {
// If 'module' or 'action' is missing, return the original URL
return fullUrl;
Expand Down
31 changes: 1 addition & 30 deletions lib/src/domain/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -198,44 +198,15 @@ const spoilEVM = "0x1464935f48CA992D1a0bEAA2358471D7Cb6374E5";
///
/// EVM
///
const bnbScanBaseEndpoint = "https://api.bscscan.com/api";
const etherscanBaseEndpoint = "https://api.etherscan.io/api";
const polygonScanBaseEndpoint = "https://api.polygonscan.com/api";
const etherscanBaseEndpoint = "https://api.etherscan.io/v2/api";
const zeniqScanEnpoint = "https://zeniqscan.com/api";
const zeniqSmartRPCEndpoint = "https://api.zeniq.network";

///
/// Arbitrum
///
const arbitrumScanBaseEndpoint = "https://api.arbiscan.io/api";
const arbitrumTestWallet = "0xA7Fa4bB0bba164F999E8C7B83C9da96A3bE44616";

///
/// Moonbeam
///
const moonbeamScanBaseEndpoint = "https://api-moonbeam.moonscan.io/api";

///
/// Base
///
const baseScanEndpoint = "https://api.basescan.org/api";

///
/// Avalanche
///
const avalancheAPIEndpoint =
"https://api.routescan.io/v2/network/mainnet/evm/43114/etherscan/api";

///
/// Optimism
///
const optimismScanEndpoint = "https://api-optimistic.etherscan.io/api";

///
///ZKSync
///
const zksyncAPIEndpoint = "https://api-era.zksync.network/api";

///
/// Staking
///
Expand Down
97 changes: 48 additions & 49 deletions test/ci/evm/evm_explorer_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -102,51 +102,51 @@ void main() {
print('ERC721: $erc721');
});

// test('Test BinanceChain BnbScan Fetching', () async {
// ///
// /// Balances
// ///
test('Test BinanceChain BnbScan Fetching', () async {
///
/// Balances
///
// final balance = await bscscan.fetchBalance(
// address: rejectEVM,
// );
final balance = await bscscan.fetchBalance(
address: rejectEVM,
);

// print('BNB Balance: $balance');
print('BNB Balance: $balance');

// final zeniqBSCBalance = await bscscan.fetchTokenBalance(
// address: rejectEVM, contractAddress: zeniqBSCToken.contractAddress);
final zeniqBSCBalance = await bscscan.fetchTokenBalance(
address: rejectEVM, contractAddress: zeniqBSCToken.contractAddress);

// print('Zeniq BSC Balance: $zeniqBSCBalance');
print('Zeniq BSC Balance: $zeniqBSCBalance');

// ///
// /// Transactions
// ///
///
/// Transactions
///
// final transactions = await bscscan.fetchTransactions(
// address: rejectEVM,
// );
final transactions = await bscscan.fetchTransactions(
address: rejectEVM,
);

// expect(transactions, isNotEmpty);
expect(transactions, isNotEmpty);

// print('BNB Transactions: $transactions');
print('BNB Transactions: $transactions');

// final zeniqBSCTokenTransactions = await bscscan.fetchERC20Transactions(
// address: rejectEVM,
// contractAddress: zeniqBSCToken.contractAddress,
// );
final zeniqBSCTokenTransactions = await bscscan.fetchERC20Transactions(
address: rejectEVM,
contractAddress: zeniqBSCToken.contractAddress,
);

// expect(zeniqBSCTokenTransactions, isNotEmpty);
expect(zeniqBSCTokenTransactions, isNotEmpty);

// print('Zeniq BSC Transactions: $zeniqBSCTokenTransactions');
print('Zeniq BSC Transactions: $zeniqBSCTokenTransactions');

// ///
// /// ERC721
// ///
///
/// ERC721
///
// final erc721 = await bscscan.fetchERC721Transactions(address: rejectEVM);
final erc721 = await bscscan.fetchERC721Transactions(address: rejectEVM);

// print('ERC721: $erc721');
// });
print('ERC721: $erc721');
});

test('GasFees Test', () async {
final result = await etherscan.fetchGasPrice();
Expand Down Expand Up @@ -201,30 +201,29 @@ void main() {
expect(tokenTransactions.length, greaterThanOrEqualTo(4));
});

// TODO: Need Api Key
// test('Test Base Fetching', () async {
// final balance = await basescan.fetchBalance(address: arbitrumTestWallet);
test('Test Base Fetching', () async {
final balance = await basescan.fetchBalance(address: arbitrumTestWallet);

// expect(balance, greaterThanOrEqualTo(BigInt.zero));
expect(balance, greaterThanOrEqualTo(BigInt.zero));

// final transactions = await basescan.fetchTransactions(
// address: arbitrumTestWallet,
// );
final transactions = await basescan.fetchTransactions(
address: arbitrumTestWallet,
);

// expect(transactions, isNotEmpty);
expect(transactions, isNotEmpty);

// final erc20Transactions = await basescan.fetchERC20Transactions(
// address: arbitrumTestWallet,
// contractAddress: mathToken.contractAddress,
// );
final erc20Transactions = await basescan.fetchERC20Transactions(
address: arbitrumTestWallet,
contractAddress: mathToken.contractAddress,
);

// expect(erc20Transactions, isNotEmpty);
expect(erc20Transactions, isNotEmpty);

// final erc20balance = await basescan.fetchTokenBalance(
// address: arbitrumTestWallet,
// contractAddress: mathToken.contractAddress);
// expect(erc20balance, greaterThan(BigInt.zero));
// });
final erc20balance = await basescan.fetchTokenBalance(
address: arbitrumTestWallet,
contractAddress: mathToken.contractAddress);
expect(erc20balance, greaterThan(BigInt.zero));
});

test("Test MoonBeam Fetching", () async {
final balance =
Expand Down
25 changes: 16 additions & 9 deletions test/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,22 @@ final etherscan = EtherscanExplorer(
loadListFromEnv("ETHERSCAN_API_KEYS"),
ethNative,
);
final polygonscan = EtherscanExplorer(polygonScanBaseEndpoint, [], polygon);
final bscscan = EtherscanExplorer(bnbScanBaseEndpoint, [], binanceSmart);
final arbitrumscan =
EtherscanExplorer(arbitrumScanBaseEndpoint, [], ethArbitrum);
final moonbeamscan = EtherscanExplorer(moonbeamScanBaseEndpoint, [], moonbeam);
final basescan = EtherscanExplorer(baseScanEndpoint, [], ethBase);
final optimismscan = EtherscanExplorer(optimismScanEndpoint, [], ethOptimism);
final zksyncscan = EtherscanExplorer(zksyncAPIEndpoint, [], ethzkSync);
final avalancheScan = EtherscanExplorer(avalancheAPIEndpoint, [], avalanche);
final polygonscan = EtherscanExplorer(
etherscanBaseEndpoint, loadListFromEnv("ETHERSCAN_API_KEYS"), polygon);
final bscscan = EtherscanExplorer(
etherscanBaseEndpoint, loadListFromEnv("ETHERSCAN_API_KEYS"), binanceSmart);
final arbitrumscan = EtherscanExplorer(
etherscanBaseEndpoint, loadListFromEnv("ETHERSCAN_API_KEYS"), ethArbitrum);
final moonbeamscan = EtherscanExplorer(
etherscanBaseEndpoint, loadListFromEnv("ETHERSCAN_API_KEYS"), moonbeam);
final basescan = EtherscanExplorer(
etherscanBaseEndpoint, loadListFromEnv("ETHERSCAN_API_KEYS"), ethBase);
final optimismscan = EtherscanExplorer(
etherscanBaseEndpoint, loadListFromEnv("ETHERSCAN_API_KEYS"), ethOptimism);
final zksyncscan = EtherscanExplorer(
etherscanBaseEndpoint, loadListFromEnv("ETHERSCAN_API_KEYS"), ethzkSync);
final avalancheScan = EtherscanExplorer(
etherscanBaseEndpoint, loadListFromEnv("ETHERSCAN_API_KEYS"), avalanche);

///
/// Utils
Expand Down

0 comments on commit a8ff97e

Please sign in to comment.