Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
PatrickAlphaC committed Sep 14, 2024
1 parent 004ec68 commit b2203c8
Show file tree
Hide file tree
Showing 8 changed files with 189 additions and 95 deletions.
13 changes: 11 additions & 2 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,18 @@ format:
format-check:
uv run ruff check .

# Run tests, fail on first test failure
# Run unit and CLI tests, fail on first test failure
test:
uv run pytest -x -s --ignore=tests/data/
uv run pytest -x -s --ignore=tests/data/ --ignore=tests/integration/

# Run integration tests, read the README.md in the tests/integration directory for more information
test-i:
uv run pytest tests/integration -x -s --ignore=tests/data/

# Run both unit and integration tests
test-all:
@just test
@just test-i

# Run tests, fail on first test failure, enter debugger on failure
test-pdb:
Expand Down
89 changes: 50 additions & 39 deletions moccasin/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@
"c": "compile",
"script": "run",
"config": "config_",
"from-explorer": "from_explorer",
}

PRINT_HELP_ON_NO_SUB_COMMAND = ["run", "wallet", "from_explorer"]
PRINT_HELP_ON_NO_SUB_COMMAND = ["run", "wallet", "explorer"]


def main(argv: list) -> int:
Expand All @@ -33,9 +32,9 @@ def main(argv: list) -> int:

main_parser, sub_parsers = generate_main_parser_and_sub_parsers()

######################
### PARSING STARTS ###
######################
# ------------------------------------------------------------------
# PARSING STARTS
# ------------------------------------------------------------------
if len(argv) == 0 or (len(argv) == 1 and (argv[0] == "-h" or argv[0] == "--help")):
main_parser.print_help()
return 0
Expand Down Expand Up @@ -72,8 +71,9 @@ def generate_main_parser_and_sub_parsers() -> (
)
sub_parsers = main_parser.add_subparsers(dest="command")

# Init command
# ========================================================================
# ------------------------------------------------------------------
# INIT COMMAND
# ------------------------------------------------------------------
init_parser = sub_parsers.add_parser(
"init",
help="Initialize a new project.",
Expand Down Expand Up @@ -111,8 +111,9 @@ def generate_main_parser_and_sub_parsers() -> (
"--vscode", help="Add a .vscode/settings.json file.", action="store_true"
)

# Compile command
# ========================================================================
# ------------------------------------------------------------------
# COMPILE COMMAND
# ------------------------------------------------------------------
sub_parsers.add_parser(
"compile",
help="Compiles the project.",
Expand All @@ -128,8 +129,9 @@ def generate_main_parser_and_sub_parsers() -> (
parents=[parent_parser],
)

# Test command
# ========================================================================
# ------------------------------------------------------------------
# TEST COMMAND
# ------------------------------------------------------------------
test_parser = sub_parsers.add_parser(
"test",
help="Runs all tests in the project.",
Expand Down Expand Up @@ -202,8 +204,9 @@ def generate_main_parser_and_sub_parsers() -> (
help="Start the debugger for each test that fails.",
)

# Run command
# ========================================================================
# ------------------------------------------------------------------
# RUN COMMAND
# ------------------------------------------------------------------
run_parser = sub_parsers.add_parser(
"run",
help="Runs a script with the project's context.",
Expand Down Expand Up @@ -241,8 +244,9 @@ def generate_main_parser_and_sub_parsers() -> (
action=RequirePasswordAction,
)

# Wallet command
# ========================================================================
# ------------------------------------------------------------------
# WALLET COMMAND
# ------------------------------------------------------------------
wallet_parser = sub_parsers.add_parser(
"wallet",
help="Wallet management utilities.",
Expand Down Expand Up @@ -320,8 +324,9 @@ def generate_main_parser_and_sub_parsers() -> (
)
delete_parser.add_argument("keystore_file_name", help="Name of keystore file")

# Console command
# ========================================================================
# ------------------------------------------------------------------
# CONSOLE COMMAND
# ------------------------------------------------------------------
console_parser = sub_parsers.add_parser(
"console",
help="BETA, USE AT YOUR OWN RISK: Interact with the network in a python shell.",
Expand All @@ -330,8 +335,9 @@ def generate_main_parser_and_sub_parsers() -> (
)
add_network_args_to_parser(console_parser)

# Install command
# ========================================================================
# ------------------------------------------------------------------
# INSTALL COMMAND
# ------------------------------------------------------------------
install_parser = sub_parsers.add_parser(
"install",
help="Installs the project's dependencies.",
Expand Down Expand Up @@ -360,8 +366,9 @@ def generate_main_parser_and_sub_parsers() -> (
nargs="*",
)

# Purge command
# ========================================================================
# ------------------------------------------------------------------
# PURGE COMMAND
# ------------------------------------------------------------------
purge_parser = sub_parsers.add_parser(
"purge",
help="Purge a given dependency",
Expand All @@ -375,29 +382,32 @@ def generate_main_parser_and_sub_parsers() -> (
nargs="+",
)

# Config command
# ========================================================================
# ------------------------------------------------------------------
# CONFIG COMMAND
# ------------------------------------------------------------------
sub_parsers.add_parser(
"config",
help="View the Moccasin configuration.",
description="View the Moccasin configuration.",
parents=[parent_parser],
)

# from-explorer command
# ========================================================================
# ------------------------------------------------------------------
# EXPLORER COMMAND
# ------------------------------------------------------------------
explorer_parser = sub_parsers.add_parser(
"from-explorer",
"explorer",
help="Work with block explorers to get data.",
description="Work with block explorers to get data.",
parents=[parent_parser],
)
# Create subparsers under 'from-explorer'
# Create subparsers under 'explorer'
explorer_subparsers = explorer_parser.add_subparsers(dest="explorer_command")

## Explorer command: get
## Explorer command: fetch
get_parser = explorer_subparsers.add_parser(
"get",
"fetch",
aliases=["get"],
help="Retrieve the ABI of a contract from a block explorer.",
description="""Retreive the ABI of a contract from a block explorer.
Expand All @@ -423,21 +433,22 @@ def generate_main_parser_and_sub_parsers() -> (
)
get_parser.add_argument(
"--save-abi-path",
help="If added, the returned abi will be saved to the file path selected.",
help="Location to save the returned abi. This will only be applied if you also add the '--save' flag.",
type=str,
)
get_parser.add_argument(
"--save",
help="If added, the ABI will be saved to the 'save-abi-path' given in the command line or config.",
action="store_true",
)

network_uri_or_chain = get_parser.add_mutually_exclusive_group()
network_uri_or_chain.add_argument(
"--uri", help="API URI endpoint for explorer.", type=str
)
network_uri_or_chain.add_argument(
"--network", help=f"Alias of the network (from the {CONFIG_NAME}).", type=str
)
network_uri_or_chain.add_argument(
"--chain",
"-c",
help="The chain name or chain id. Using this flag will set ignore-config to true. Moccasin will use it's internal mapping to map the chain to the moccasin natively supported block explorer.",
"--network",
help=f"Name/alias of the network (from the {CONFIG_NAME}). If chain_id is set in the config, you may also use that.",
type=str,
)

Expand All @@ -457,9 +468,9 @@ def generate_main_parser_and_sub_parsers() -> (
return main_parser, sub_parsers


######################
## Helper Functions ##
######################
# ------------------------------------------------------------------
# HELPER FUNCTIONS
# ------------------------------------------------------------------
def add_network_args_to_parser(parser: argparse.ArgumentParser):
parser.add_argument(
"--fork", action="store_true", help="If you want to fork the RPC."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,26 @@
DEFAULT_NETWORKS_BY_CHAIN_ID,
)
from moccasin.logging import logger, set_log_level
from moccasin.config import get_config
from moccasin.config import get_config, Network

ALIAS_TO_COMMAND = {"get": "fetch"}


def main(args: Namespace) -> int:
if args.explorer_command == "list":
explorer_command = ALIAS_TO_COMMAND.get(
args.explorer_command, args.explorer_command
)
if explorer_command == "list":
list_supported_explorers(args.by_id, json=args.json)
elif args.explorer_command == "get":
elif explorer_command == "fetch":
boa_get_abi_from_explorer(
args.address,
name=args.name,
uri=args.uri,
api_key=args.api_key,
save_abi_path=args.save_abi_path,
ignore_config=args.ignore_config,
chain=args.chain,
network=args.network,
network_name_or_id=args.network,
)
else:
logger.warning(f"Unknown explorer command: {args.explorer_command}")
Expand All @@ -37,45 +41,49 @@ def boa_get_abi_from_explorer(
uri: str | None = None,
api_key: str | None = None,
save_abi_path: str | None = None,
save: bool = False,
ignore_config: bool = False,
chain: str | None = None,
network: str | None = None,
network_name_or_id: str | None = None,
quiet: bool = False, # This is for when this function is used as a library
) -> list:
if quiet:
set_log_level(quiet=True)

if not api_key:
api_key = os.getenv(DEFAULT_API_KEY_ENV_VAR)

if chain is not None:
ignore_config = True
if chain.isdigit():
chain_id = int(chain)
uri = DEFAULT_NETWORKS_BY_CHAIN_ID.get(chain_id, {}).get("explorer")
else:
uri = DEFAULT_NETWORKS_BY_NAME.get(chain, {}).get("explorer")

network: Network | None = None
# 1. If not ignore_config, grab stuff from the config
if not ignore_config:
config = get_config()
if network:
config.networks.set_active_network(network)
active_network = config.get_active_network()
if network_name_or_id:
network = config.networks.get_network(network_name_or_id)
if network.chain_id:
network_name_or_id = str(network.chain_id)
if not uri:
uri = active_network.explorer_uri
uri = network.explorer_uri
if not api_key:
api_key = active_network.explorer_api_key
api_key = network.explorer_api_key
if not save_abi_path:
save_abi_path = active_network.save_abi_path
save_abi_path = network.save_abi_path

# 2. If you still don't have a uri, check the default networks
if not uri:
if str(network_name_or_id).isdigit():
chain_id = int(network_name_or_id)
uri = DEFAULT_NETWORKS_BY_CHAIN_ID.get(chain_id, {}).get("explorer")
else:
uri = DEFAULT_NETWORKS_BY_NAME.get(network_name_or_id, {}).get("explorer")

# 3. Only for api, finally, check ENV variable
if not api_key:
api_key = os.getenv(DEFAULT_API_KEY_ENV_VAR)

if not api_key:
raise ValueError(
f"No API key provided. Please provide one in the command line with --api-key or set the environment variable:\n{DEFAULT_API_KEY_ENV_VAR}"
)

if save_abi_path and not name:
if (save and save_abi_path and not name) or (save and not save_abi_path):
raise ValueError(
"If you provide a save path, you must also provide a name for the ABI file via --save-abi-path."
"If you wish to save the ABI, you must also provide both a --name and a --save-abi-path."
)

abi: list = []
Expand All @@ -86,7 +94,7 @@ def boa_get_abi_from_explorer(
logger.warning(f"No ABI found for address: {address}")
return abi

if save_abi_path:
if save_abi_path and save:
name = str(name)
if not name.endswith(".json"):
name = name + ".json"
Expand Down
Loading

0 comments on commit b2203c8

Please sign in to comment.