Skip to content

Commit

Permalink
Refactor Sourcify Client
Browse files Browse the repository at this point in the history
- Rename `Sourcify` to `SourcifyClient`
- Add method to check networks not supported
- Raise a `SourcifyClientConfigurationProblem` if network is not supported
  • Loading branch information
Uxio0 committed Dec 12, 2023
1 parent 981485f commit c486e4a
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 14 deletions.
4 changes: 2 additions & 2 deletions docs/source/gnosis.eth.clients.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ gnosis.eth.clients.etherscan\_client module
:undoc-members:
:show-inheritance:

gnosis.eth.clients.sourcify module
gnosis.eth.clients.sourcify_client module
----------------------------------

.. automodule:: gnosis.eth.clients.sourcify
.. automodule:: gnosis.eth.clients.sourcify_client
:members:
:undoc-members:
:show-inheritance:
Expand Down
12 changes: 9 additions & 3 deletions gnosis/eth/clients/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,22 @@
EtherscanClientException,
EtherscanRateLimitError,
)
from .sourcify import Sourcify
from .sourcify_client import (
SourcifyClient,
SourcifyClientConfigurationProblem,
SourcifyClientException,
)

__all__ = [
"BlockScoutConfigurationProblem",
"BlockscoutClient",
"BlockscoutClientException",
"BlockScoutConfigurationProblem",
"ContractMetadata",
"EtherscanClient",
"EtherscanClientConfigurationProblem",
"EtherscanClientException",
"EtherscanRateLimitError",
"Sourcify",
"SourcifyClient",
"SourcifyClientConfigurationProblem",
"SourcifyClientException",
]
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,22 @@

import requests

from gnosis.util import cache

from .. import EthereumNetwork
from ..utils import fast_is_checksum_address
from .contract_metadata import ContractMetadata


class Sourcify:
class SourcifyClientException(Exception):
pass


class SourcifyClientConfigurationProblem(Exception):
pass


class SourcifyClient:
"""
Get contract metadata from Sourcify. Matches can be full or partial:
Expand All @@ -23,14 +33,21 @@ class Sourcify:
def __init__(
self,
network: EthereumNetwork = EthereumNetwork.MAINNET,
base_url: str = "https://repo.sourcify.dev/",
base_url_api: str = "https://sourcify.dev",
base_url_repo: str = "https://repo.sourcify.dev/",
request_timeout: int = 10,
):
self.network = network
self.base_url = base_url
self.base_url_api = base_url_api
self.base_url_repo = base_url_repo
self.http_session = self._prepare_http_session()
self.request_timeout = request_timeout

if not self.is_chain_supported(network.value):
raise SourcifyClientConfigurationProblem(
f"Network {network.name} - {network.value} not supported"
)

def _prepare_http_session(self) -> requests.Session:
"""
Prepare http session with custom pooling. See:
Expand Down Expand Up @@ -63,6 +80,14 @@ def _do_request(self, url: str) -> Optional[Dict[str, Any]]:

return response.json()

def is_chain_supported(self, chain_id: int) -> bool:
return chain_id in (int(chain["chainId"]) for chain in self.get_chains())

@cache
def get_chains(self) -> Dict[str, Any]:
url = urljoin(self.base_url_api, "/server/chains")
return self._do_request(url)

def get_contract_metadata(
self, contract_address: str
) -> Optional[ContractMetadata]:
Expand All @@ -72,7 +97,7 @@ def get_contract_metadata(

for match_type in ("full_match", "partial_match"):
url = urljoin(
self.base_url,
self.base_url_repo,
f"/contracts/{match_type}/{self.network.value}/{contract_address}/metadata.json",
)
metadata = self._do_request(url)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,27 @@
from django.test import TestCase

from ... import EthereumNetwork
from ...clients import Sourcify
from ...clients import SourcifyClient
from ...clients.sourcify_client import SourcifyClientConfigurationProblem


class TestSourcify(TestCase):
def test_sourcify_get_contract_metadata(self):
sourcify = Sourcify()
class TestSourcifyClient(TestCase):
def test_init(self):
with self.assertRaises(SourcifyClientConfigurationProblem):
SourcifyClient(EthereumNetwork.OLYMPIC)

self.assertIsInstance(SourcifyClient(), SourcifyClient)
self.assertIsInstance(SourcifyClient(EthereumNetwork.GNOSIS), SourcifyClient)

def test_is_chain_supported(self):
sourcify = SourcifyClient()

self.assertTrue(sourcify.is_chain_supported(EthereumNetwork.MAINNET.value))
self.assertTrue(sourcify.is_chain_supported(EthereumNetwork.GNOSIS.value))
self.assertFalse(sourcify.is_chain_supported(2))

def test_get_contract_metadata(self):
sourcify = SourcifyClient()
safe_contract_address = "0x6851D6fDFAfD08c0295C392436245E5bc78B0185"
try:
contract_metadata = sourcify.get_contract_metadata(safe_contract_address)
Expand All @@ -18,7 +33,7 @@ def test_sourcify_get_contract_metadata(self):
self.assertIsInstance(contract_metadata.abi, List)
self.assertTrue(contract_metadata.abi)
self.assertFalse(contract_metadata.partial_match)
contract_metadata_rinkeby = Sourcify(
contract_metadata_rinkeby = SourcifyClient(
EthereumNetwork.RINKEBY
).get_contract_metadata(safe_contract_address)
self.assertEqual(contract_metadata, contract_metadata_rinkeby)
Expand Down

0 comments on commit c486e4a

Please sign in to comment.