This repository has been archived by the owner on Jun 6, 2024. It is now read-only.
generated from ApeWorX/project-template
-
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from ApeWorX/feat/starknet
feat: starknet ecosystem support
- Loading branch information
Showing
27 changed files
with
2,206 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,49 @@ | ||
# Add module top-level imports here | ||
from ape import plugins | ||
from ape.api.networks import LOCAL_NETWORK_NAME, NetworkAPI, create_network_type | ||
from ape.types import AddressType | ||
|
||
from ape_starknet._utils import NETWORKS, PLUGIN_NAME | ||
from ape_starknet.accounts import StarknetAccountContracts, StarknetKeyfileAccount | ||
from ape_starknet.config import StarknetConfig | ||
from ape_starknet.conversion import StarknetAddressConverter | ||
from ape_starknet.ecosystems import Starknet | ||
from ape_starknet.provider import StarknetProvider | ||
from ape_starknet.tokens import TokenManager | ||
|
||
tokens = TokenManager() | ||
|
||
|
||
@plugins.register(plugins.ConversionPlugin) | ||
def converters(): | ||
yield AddressType, StarknetAddressConverter | ||
|
||
|
||
@plugins.register(plugins.Config) | ||
def config_class(): | ||
return StarknetConfig | ||
|
||
|
||
@plugins.register(plugins.EcosystemPlugin) | ||
def ecosystems(): | ||
yield Starknet | ||
|
||
|
||
@plugins.register(plugins.NetworkPlugin) | ||
def networks(): | ||
for network_name, network_params in NETWORKS.items(): | ||
yield PLUGIN_NAME, network_name, create_network_type(*network_params) | ||
|
||
# NOTE: This works for development providers, as they get chain_id from themselves | ||
yield PLUGIN_NAME, LOCAL_NETWORK_NAME, NetworkAPI | ||
|
||
|
||
@plugins.register(plugins.ProviderPlugin) | ||
def providers(): | ||
network_names = [LOCAL_NETWORK_NAME] + [k for k in NETWORKS.keys()] | ||
for network_name in network_names: | ||
yield PLUGIN_NAME, network_name, StarknetProvider | ||
|
||
|
||
@plugins.register(plugins.AccountPlugin) | ||
def account_types(): | ||
return StarknetAccountContracts, StarknetKeyfileAccount |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import click | ||
|
||
from ape_starknet.accounts._cli import accounts | ||
|
||
|
||
@click.group() | ||
def cli(): | ||
"""Starknet ecosystem commands""" | ||
|
||
|
||
cli.add_command(accounts) # type: ignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import re | ||
from typing import Any, Union | ||
|
||
from ape.api.networks import LOCAL_NETWORK_NAME | ||
from ape.exceptions import AddressError, ApeException, ProviderError, VirtualMachineError | ||
from ape.types import AddressType, RawAddress | ||
from eth_typing import HexAddress, HexStr | ||
from eth_utils import ( | ||
add_0x_prefix, | ||
encode_hex, | ||
hexstr_if_str, | ||
is_text, | ||
keccak, | ||
remove_0x_prefix, | ||
to_hex, | ||
) | ||
from starknet_py.net.client import BadRequest # type: ignore | ||
from starkware.starknet.definitions.general_config import StarknetChainId # type: ignore | ||
|
||
PLUGIN_NAME = "starknet" | ||
NETWORKS = { | ||
# chain_id, network_id | ||
"mainnet": (StarknetChainId.MAINNET.value, StarknetChainId.MAINNET.value), | ||
"testnet": (StarknetChainId.TESTNET.value, StarknetChainId.TESTNET.value), | ||
} | ||
_HEX_ADDRESS_REG_EXP = re.compile("(0x)?[0-9a-f]*", re.IGNORECASE | re.ASCII) | ||
"""Same as from eth-utils except not limited length.""" | ||
|
||
|
||
def get_chain_id(network_id: Union[str, int]) -> StarknetChainId: | ||
if isinstance(network_id, int): | ||
return StarknetChainId(network_id) | ||
|
||
if network_id == LOCAL_NETWORK_NAME: | ||
return StarknetChainId.TESTNET # Use TESTNET chain ID for local network | ||
|
||
if network_id not in NETWORKS: | ||
raise ValueError(f"Unknown network '{network_id}'.") | ||
|
||
return StarknetChainId(NETWORKS[network_id][0]) | ||
|
||
|
||
def to_checksum_address(address: RawAddress) -> AddressType: | ||
try: | ||
hex_address = hexstr_if_str(to_hex, address).lower() | ||
except AttributeError: | ||
raise AddressError(f"Value must be any string, instead got type {type(address)}") | ||
|
||
cleaned_address = remove_0x_prefix(HexStr(hex_address)) | ||
address_hash = encode_hex(keccak(text=cleaned_address)) | ||
|
||
checksum_address = add_0x_prefix( | ||
HexStr( | ||
"".join( | ||
(hex_address[i].upper() if int(address_hash[i], 16) > 7 else hex_address[i]) | ||
for i in range(2, len(hex_address)) | ||
) | ||
) | ||
) | ||
|
||
hex_address = HexAddress(checksum_address) | ||
return AddressType(hex_address) | ||
|
||
|
||
def is_hex_address(value: Any) -> bool: | ||
if not is_text(value): | ||
return False | ||
|
||
return _HEX_ADDRESS_REG_EXP.fullmatch(value) is not None | ||
|
||
|
||
def handle_client_errors(f): | ||
def func(*args, **kwargs): | ||
try: | ||
result = f(*args, **kwargs) | ||
if isinstance(result, dict) and result.get("error"): | ||
message = result["error"].get("message") or "Transaction failed" | ||
raise ProviderError(message) | ||
|
||
return result | ||
|
||
except BadRequest as err: | ||
msg = err.text if hasattr(err, "text") else str(err) | ||
raise ProviderError(msg) from err | ||
except ApeException: | ||
# Don't catch ApeExceptions, let them raise as they would. | ||
raise | ||
except Exception as err: | ||
if "rejected" in str(err): | ||
raise VirtualMachineError(base_err=err) from err | ||
|
||
raise # Original exception | ||
|
||
return func |
Oops, something went wrong.