Skip to content

Commit

Permalink
Merge branch 'main' into fix/bad-uri-recursion-error
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey authored Nov 4, 2024
2 parents e337ff3 + 0a227e1 commit f072326
Show file tree
Hide file tree
Showing 11 changed files with 168 additions and 68 deletions.
21 changes: 18 additions & 3 deletions docs/userguides/networks.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Networks

When interacting with a blockchain, you will have to select an ecosystem (e.g. Ethereum, Arbitrum, or Fantom), a network (e.g. Mainnet or Sepolia) and a provider (e.g. Eth-Tester, Node (Geth), or Alchemy).
Networks are part of ecosystems and typically defined in plugins.
For example, the `ape-ethereum` plugin comes with Ape and can be used for handling EVM-like behavior.
The `ape-ethereum` ecosystem and network(s) plugin comes with Ape and can be used for handling EVM-like behavior.
Networks are part of ecosystems and typically defined in plugins or custom-network configurations.
However, Ape works out-of-the-box (in a limited way) with any network defined in the [evmchains](https://github.com/ApeWorX/evmchains) library.

## Selecting a Network

Expand All @@ -25,7 +26,7 @@ ape test --network ethereum:local:foundry
ape console --network arbitrum:testnet:alchemy # NOTICE: All networks, even from other ecosystems, use this.
```

To see all possible values for `--network`, run the command:
To see all networks that work with the `--network` flag (besides those _only_ defined in `evmchains`), run the command:

```shell
ape networks list
Expand Down Expand Up @@ -100,6 +101,20 @@ ape networks list

In the remainder of this guide, any example below using Ethereum, you can replace with an L2 ecosystem's name and network combination.

## evmchains Networks

If a network is in the [evmchains](https://github.com/ApeWorX/evmchains) library, it will work in Ape automatically, even without a plugin or any custom configuration for that network.

```shell
ape console --network moonbeam
```

This works because the `moonbeam` network data is available in the `evmchains` library, and Ape is able to look it up.

```{warning}
Support for networks from evm-chains alone may be limited and require additional configuration to work in production use-cases.
```

## Custom Network Connection

You can add custom networks to Ape without creating a plugin.
Expand Down
34 changes: 27 additions & 7 deletions src/ape/api/networks.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
)
from eth_pydantic_types import HexBytes
from eth_utils import keccak, to_int
from evmchains import PUBLIC_CHAIN_META
from pydantic import model_validator

from ape.exceptions import (
Expand Down Expand Up @@ -109,7 +110,7 @@ def data_folder(self) -> Path:
"""
return self.config_manager.DATA_FOLDER / self.name

@cached_property
@property
def custom_network(self) -> "NetworkAPI":
"""
A :class:`~ape.api.networks.NetworkAPI` for custom networks where the
Expand All @@ -125,13 +126,11 @@ def custom_network(self) -> "NetworkAPI":
if ethereum_class is None:
raise NetworkError("Core Ethereum plugin missing.")

request_header = self.config_manager.REQUEST_HEADER
init_kwargs = {"name": "ethereum", "request_header": request_header}
ethereum = ethereum_class(**init_kwargs) # type: ignore
init_kwargs = {"name": "ethereum"}
evm_ecosystem = ethereum_class(**init_kwargs) # type: ignore
return NetworkAPI(
name="custom",
ecosystem=ethereum,
request_header=request_header,
ecosystem=evm_ecosystem,
_default_provider="node",
_is_custom=True,
)
Expand Down Expand Up @@ -301,6 +300,11 @@ def networks(self) -> dict[str, "NetworkAPI"]:
network_api._is_custom = True
networks[net_name] = network_api

# Add any remaining networks from EVM chains here (but don't override).
# NOTE: Only applicable to EVM-based ecosystems, of course.
# Otherwise, this is a no-op.
networks = {**self._networks_from_evmchains, **networks}

return networks

@cached_property
Expand All @@ -311,6 +315,17 @@ def _networks_from_plugins(self) -> dict[str, "NetworkAPI"]:
if ecosystem_name == self.name
}

@cached_property
def _networks_from_evmchains(self) -> dict[str, "NetworkAPI"]:
# NOTE: Purposely exclude plugins here so we also prefer plugins.
return {
network_name: create_network_type(data["chainId"], data["chainId"])(
name=network_name, ecosystem=self
)
for network_name, data in PUBLIC_CHAIN_META.get(self.name, {}).items()
if network_name not in self._networks_from_plugins
}

def __post_init__(self):
if len(self.networks) == 0:
raise NetworkError("Must define at least one network in ecosystem")
Expand Down Expand Up @@ -1057,7 +1072,6 @@ def providers(self): # -> dict[str, Partial[ProviderAPI]]
Returns:
dict[str, partial[:class:`~ape.api.providers.ProviderAPI`]]
"""

from ape.plugins._utils import clean_plugin_name

providers = {}
Expand Down Expand Up @@ -1089,6 +1103,12 @@ def providers(self): # -> dict[str, Partial[ProviderAPI]]
network=self,
)

# Any EVM-chain works with node provider.
if "node" not in providers and self.name in self.ecosystem._networks_from_evmchains:
# NOTE: Arbitrarily using sepolia to access the Node class.
node_provider_cls = self.network_manager.ethereum.sepolia.get_provider("node").__class__
providers["node"] = partial(node_provider_cls, name="node", network=self)

return providers

def _get_plugin_providers(self):
Expand Down
6 changes: 5 additions & 1 deletion src/ape/contracts/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
from .base import ContractContainer, ContractEvent, ContractInstance, ContractLog, ContractNamespace
def __getattr__(name: str):
import ape.contracts.base as module

return getattr(module, name)


__all__ = [
"ContractContainer",
Expand Down
Loading

0 comments on commit f072326

Please sign in to comment.