Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add Arbitrum, Optimism and Polygon support #46

Merged
merged 10 commits into from
Sep 9, 2022
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ venv/
ENV/
env.bak/
venv.bak/
.idea/

# mkdocs documentation
/site
Expand Down
34 changes: 25 additions & 9 deletions ape_infura/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,32 @@

from .providers import Infura

NETWORKS = [
"mainnet",
"ropsten",
"rinkeby",
"kovan",
"goerli",
]
NETWORKS = {
"ethereum": [
"mainnet",
"ropsten",
"rinkeby",
"kovan",
"goerli",
],
"arbitrum": [
"mainnet",
"tesnet",
],
"optimism": [
"mainnet",
"kovan",
"goerli",
],
"polygon": [
"mainnet",
"mumbai",
],
}


@plugins.register(plugins.ProviderPlugin)
def providers():
for network_name in NETWORKS:
yield "ethereum", network_name, Infura
for ecosystem_name in NETWORKS:
for network_name in NETWORKS[ecosystem_name]:
yield ecosystem_name, network_name, Infura
47 changes: 35 additions & 12 deletions ape_infura/providers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import os
from typing import Dict
from typing import Dict, Tuple

from ape.api import UpstreamProvider, Web3Provider
from ape.exceptions import ContractLogicError, ProviderError, VirtualMachineError
Expand All @@ -8,7 +8,24 @@
from web3.gas_strategies.rpc import rpc_gas_price_strategy
from web3.middleware import geth_poa_middleware

_ENVIRONMENT_VARIABLE_NAMES = ("WEB3_INFURA_PROJECT_ID", "WEB3_INFURA_API_KEY")
_ENVIRONMENT_VARIABLE_OPTIONS = {
"ethereum": (
"WEB3_INFURA_PROJECT_ID",
"WEB3_INFURA_API_KEY",
),
"arbitrum": (
"WEB3_ARBITRUM_INFURA_PROJECT_ID",
"WEB3_ARBITRUM_INFURA_API_KEY",
),
"optimism": (
"WEB3_OPTIMISM_INFURA_PROJECT_ID",
"WEB3_OPTIMISM_INFURA_API_KEY",
),
"polygon": (
"WEB3_POLYGON_INFURA_PROJECT_ID",
"WEB3_POLYGON_INFURA_API_KEY",
),
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noticed this. You actually don't need this change because Infura uses just one project ID for all of it's RPC endpoints, unlike Alchemy which uses one per network

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for clarifying.
fixed the issue. tests work locally for me, so shall be good in CI as well



class InfuraProviderError(ProviderError):
Expand All @@ -18,32 +35,38 @@ class InfuraProviderError(ProviderError):


class MissingProjectKeyError(InfuraProviderError):
def __init__(self):
env_var_str = ", ".join([f"${n}" for n in _ENVIRONMENT_VARIABLE_NAMES])
def __init__(self, options: Tuple[str, str]):
env_var_str = ", ".join([f"${n}" for n in options])
super().__init__(f"Must set one of {env_var_str}")


class Infura(Web3Provider, UpstreamProvider):
network_uris: Dict[str, str] = {}
network_uris: Dict[Tuple[str, str], str] = {}

@property
def uri(self) -> str:
ecosystem_name = self.network.ecosystem.name
network_name = self.network.name
if network_name in self.network_uris:
return self.network_uris[network_name]
if (ecosystem_name, network_name) in self.network_uris:
return self.network_uris[(ecosystem_name, network_name)]

key = None
for env_var_name in _ENVIRONMENT_VARIABLE_NAMES:
options = _ENVIRONMENT_VARIABLE_OPTIONS[ecosystem_name]
for env_var_name in options:
env_var = os.environ.get(env_var_name)
if env_var:
key = env_var
break

if not key:
raise MissingProjectKeyError()

network_uri = f"https://{self.network.name}.infura.io/v3/{key}"
self.network_uris[network_name] = network_uri
raise MissingProjectKeyError(options)

prefix = f"{ecosystem_name}-" if ecosystem_name != "ethereum" else ""
network = self.network.name
if ecosystem_name == 'arbitrum' and self.network.name == 'testnet':
network = 'rinkeby' # currently only "testnet is supported on arbitrum"
network_uri = f"https://{prefix}{self.network.name}.infura.io/v3/{key}"
fubuloubu marked this conversation as resolved.
Show resolved Hide resolved
self.network_uris[(ecosystem_name, network_name)] = network_uri
return network_uri

@property
Expand Down
22 changes: 22 additions & 0 deletions tests/test_provider.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os
from ape import networks

from ape_infura.providers import Infura
Expand All @@ -7,3 +8,24 @@ def test_provider_works():
with networks.ethereum.mainnet.use_provider("infura") as provider:
assert isinstance(provider, Infura)
assert provider.get_balance("0x0000000000000000000000000000000000000000") > 0
assert provider.uri.startswith(f"https://mainnet.infura.io/v3/")
# tests for different chains, commentefd due to missing requirements
eliseygusev marked this conversation as resolved.
Show resolved Hide resolved
# with networks.arbitrum.mainnet.use_provider("infura") as provider:
# assert isinstance(provider, Infura)
# assert provider.get_balance("0x0000000000000000000000000000000000000000") > 0
# assert provider.uri.startswith(f"https://arbitrum-mainnet.infura.io/v3/")
#
# with networks.arbitrum.testnet.use_provider("infura") as provider:
# assert isinstance(provider, Infura)
# assert provider.get_balance("0x0000000000000000000000000000000000000000") > 0
# assert provider.uri.startswith(f"https://arbitrum-rinkeby.infura.io/v3/")
#
# with networks.optimism.mainnet.use_provider("infura") as provider:
# assert isinstance(provider, Infura)
# assert provider.get_balance("0x0000000000000000000000000000000000000000") > 0
# assert provider.uri.startswith(f"https://optimism-mainnet.infura.io/v3/")
#
# with networks.polygon.mumbai.use_provider("infura") as provider:
# assert isinstance(provider, Infura)
# assert provider.get_balance("0x0000000000000000000000000000000000000000") > 0
# assert provider.uri.startswith(f"https://polygon-mumbai.infura.io/v3/")