diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ade62b1..5b0fb2a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,14 +14,6 @@ jobs: env: ETHSCAN_API_KEY: ${{ secrets.ETHSCAN_API_KEY }} - POLYSCAN_API_KEY: ${{ secrets.POLYSCAN_API_KEY }} - OPTSCAN_API_KEY: ${{ secrets.OPTSCAN_API_KEY }} - ARBSCAN_API_KEY: ${{ secrets.ARBSCAN_API_KEY }} - BASESCAN_API_KEY: ${{ secrets.BASESCAN_API_KEY }} - GNOSCAN_API_KEY: ${{ secrets.GNOSCAN_API_KEY }} - SCRSCAN_API_KEY: ${{ secrets.SCRSCAN_API_KEY }} - BSCSCAN_API_KEY: ${{ secrets.BSCSCAN_API_KEY }} - ZKSCAN_API_KEY: ${{ secrets.ZKSCAN_API_KEY }} QUORUM_PATH: "." ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} diff --git a/Quorum/apis/block_explorers/chains_api.py b/Quorum/apis/block_explorers/chains_api.py index 0e831d9..bfd6077 100644 --- a/Quorum/apis/block_explorers/chains_api.py +++ b/Quorum/apis/block_explorers/chains_api.py @@ -1,7 +1,6 @@ -from dataclasses import dataclass -import requests -from typing import Callable, Any import os +import requests +from typing import Any import json from eth_abi import encode @@ -10,20 +9,6 @@ from Quorum.utils.chain_enum import Chain from Quorum.apis.block_explorers.source_code import SourceCode - -@dataclass -class APIinfo: - """ - Data class for storing API base URL and a function to retrieve the API key. - - Attributes: - base_url (str): The base URL of the blockchain explorer API. - api_key (Callable[[], str]): A function to retrieve the API key for the explorer. - """ - base_url: str - api_key: Callable[[], str] - - class ChainAPI: """ A class to interact with blockchain explorer APIs for fetching contract ABIs, @@ -33,32 +18,22 @@ class ChainAPI: chain_mapping (dict): Maps Chain enum to APIinfo containing base URL and API key function. """ - # Maps Chain enums to their corresponding API base URL and API key retrieval function. - chain_mapping = { - Chain.ETH: APIinfo(base_url="https://api.etherscan.io/api", - api_key=lambda: os.getenv('ETHSCAN_API_KEY')), - Chain.ARB: APIinfo(base_url="https://api.arbiscan.io/api", - api_key=lambda: os.getenv('ARBSCAN_API_KEY')), - Chain.AVAX: APIinfo(base_url="https://api.routescan.io/v2/network/mainnet/evm/43114/etherscan/api", - api_key=lambda: os.getenv('AVAXSCAN_API_KEY', "FREE")), - Chain.BASE: APIinfo(base_url="https://api.basescan.org/api", - api_key=lambda: os.getenv('BASESCAN_API_KEY')), - Chain.BSC: APIinfo(base_url="https://api.bscscan.com/api", - api_key=lambda: os.getenv('BSCSCAN_API_KEY')), - Chain.GNO: APIinfo(base_url="https://api.gnosisscan.io/api", - api_key=lambda: os.getenv('GNOSCAN_API_KEY')), - Chain.MET: APIinfo(base_url="https://api.routescan.io/v2/network/mainnet/evm/1088/etherscan/api", - api_key=lambda: os.getenv('METSCAN_API_KEY', "FREE")), - Chain.OPT: APIinfo(base_url="https://api-optimistic.etherscan.io/api", - api_key=lambda: os.getenv('OPTSCAN_API_KEY')), - Chain.POLY: APIinfo(base_url="https://api.polygonscan.com/api", - api_key=lambda: os.getenv('POLYSCAN_API_KEY')), - Chain.SCR: APIinfo(base_url="https://api.scrollscan.com/api", - api_key=lambda: os.getenv('SCRSCAN_API_KEY')), - Chain.ZK: APIinfo(base_url="https://api-era.zksync.network/api", - api_key=lambda: os.getenv('ZKSCAN_API_KEY')) + # Mapping between Chain enum members and their corresponding Chain IDs + CHAIN_ID_MAP = { + Chain.ETH: 1, + Chain.ARB: 42161, + Chain.AVAX: 43114, + Chain.BASE: 8453, + Chain.BSC: 56, + Chain.GNO: 100, + Chain.OPT: 10, + Chain.POLY: 137, + Chain.SCR: 534352, + Chain.ZK: 324 } + BASE_URL = "https://api.etherscan.io/v2/api?chainid={chain_id}&apikey={api_key}" + def __init__(self, chain: Chain) -> None: """ Initializes the ChainAPI with the appropriate blockchain network's base URL and API key. @@ -69,15 +44,20 @@ def __init__(self, chain: Chain) -> None: Raises: ValueError: If the selected chain is unsupported or the API key is not set. """ - if chain not in self.chain_mapping: - raise ValueError(f"Unsupported chain: {chain}. Available chains: {', '.join([c.name for c in self.chain_mapping.keys()])}") - - api_info = self.chain_mapping[chain] - self.api_key = api_info.api_key() - if not self.api_key: - raise ValueError(f"{chain}SCAN_API_KEY environment variable is not set.") + if chain not in self.CHAIN_ID_MAP and chain != Chain.MET: + raise ValueError(f"Unsupported chain: {chain}. Available chains: {', '.join([c.name for c in self.CHAIN_ID_MAP.keys()])}") + # MET is not supported via ETHScan API + if chain == Chain.MET: + self.base_url = "https://api.routescan.io/v2/network/mainnet/evm/1088/etherscan/api" + else: + chain_id = self.CHAIN_ID_MAP[chain] + api_key = os.getenv("ETHSCAN_API_KEY") + if not api_key: + raise ValueError(f"{chain}SCAN_API_KEY environment variable is not set.") + + self.base_url = self.BASE_URL.format(chain_id=chain_id, api_key=api_key) - self.base_url = f"{api_info.base_url}?apikey={self.api_key}" + self.session = requests.Session() def get_source_code(self, proposal_address: str) -> list[SourceCode]: """ @@ -93,7 +73,7 @@ def get_source_code(self, proposal_address: str) -> list[SourceCode]: ValueError: If the API request fails or the source code could not be retrieved. """ url = f"{self.base_url}&module=contract&action=getsourcecode&address={proposal_address}" - response = requests.get(url) + response = self.session.get(url) response.raise_for_status() data = response.json() @@ -128,7 +108,7 @@ def get_contract_abi(self, contract_address: str) -> list[dict]: ValueError: If the API request fails or the ABI could not be retrieved. """ url = f"{self.base_url}&module=contract&action=getabi&address={contract_address}" - response = requests.get(url) + response = self.session.get(url) response.raise_for_status() data = response.json() @@ -169,7 +149,7 @@ def call_contract_function(self, contract_address: str, function_name: str, argu # Step 5: Make the request to the blockchain explorer eth_call endpoint url = f"{self.base_url}&module=proxy&action=eth_call&to={contract_address}&data={data}&tag=latest" - response = requests.get(url) + response = self.session.get(url) response.raise_for_status() # Step 6: Handle the response diff --git a/Quorum/execution.json b/Quorum/execution.json index 3b4ad6e..7dd16ad 100644 --- a/Quorum/execution.json +++ b/Quorum/execution.json @@ -1,9 +1,7 @@ { "Aave": { "AVAX": { - "Proposals": [ - "0x96cecD5D7A4b740f6a8eF2787fe88E0Bd480d79f" - ] + "Proposals": [] }, "ETH": { "Proposals": [ diff --git a/README.md b/README.md index 6f2d5cf..8d1ca59 100644 --- a/README.md +++ b/README.md @@ -34,37 +34,20 @@ As part of tool process, the tool will use solcx to parse the contract code to A ## Environment Variables -Before using Quorum, you need to configure the following environment variables for API keys corresponding to each blockchain. These keys are necessary to access the respective blockchain explorers: - -- **ETHSCAN_API_KEY:** API key for Etherscan (Ethereum). -- **ARBSCAN_API_KEY:** API key for Arbiscan (Arbitrum). -- **AVAXSCAN_API_KEY:** API key for AvaScan (Avalanche). Defaults to "FREE" if not set. -- **BASESCAN_API_KEY:** API key for BaseScan (Base). -- **BSCSCAN_API_KEY:** API key for BscScan (Binance Smart Chain). -- **GNOSCAN_API_KEY:** API key for GnoScan (Gnosis Chain). -- **METSCAN_API_KEY:** API key for MetScan (Meter). Defaults to "FREE" if not set. -- **OPTSCAN_API_KEY:** API key for OptScan (Optimism). -- **POLYSCAN_API_KEY:** API key for PolygonScan (Polygon). -- **SCRSCAN_API_KEY:** API key for ScrollScan (Scroll). -- **ZKSCAN_API_KEY:** API key for ZKScan (ZKsync). +Before using Quorum, you need to configure the following environment variable for the Etherscan API key. This key is necessary to access the respective blockchain explorers: + +- **ETHSCAN_API_KEY:** API key for Etherscan. + +And for the new advanced new listing first deposit check, you need to configure the ANTHROPIC_API_KEY This key is necessary to access the Antropic API. You can set these environment variables in your shell: ```sh export ETHSCAN_API_KEY="your_etherscan_api_key" -export ARBSCAN_API_KEY="your_arbiscan_api_key" -export AVAXSCAN_API_KEY="your_avaxscan_api_key" -export BASESCAN_API_KEY="your_basescan_api_key" -export BSCSCAN_API_KEY="your_bscscan_api_key" -export GNOSCAN_API_KEY="your_gnoscan_api_key" -export METSCAN_API_KEY="your_metscan_api_key" -export OPTSCAN_API_KEY="your_optscan_api_key" -export POLYSCAN_API_KEY="your_polyscan_api_key" -export SCRSCAN_API_KEY="your_scrscan_api_key" -export ZKSCAN_API_KEY="your_zkscan_api_key" +export ANTHROPIC_API_KEY="your_anthropic_api_key" ``` -Replace `your_etherscan_api_key`, `your_arbiscan_api_key`, etc., with the actual API keys provided by the respective blockchain explorers. +Replace `your_etherscan_api_key`, `your_anthropic_api_key` with your actual API keys. Additionally, set the `QUORUM_PATH` environment variable to specify where the repositories and diffs will be saved: @@ -177,6 +160,7 @@ This configuration is used by the tool to manage the ground truth information fo current supported price feed providers are: - Chainlink - Chronicle +- Coingecko ## Artifacts Structure diff --git a/version b/version index e887104..997f982 100644 --- a/version +++ b/version @@ -1 +1 @@ -20241218.083641.938892 +20241218.131651.794671