def _all(project_path): ethpm_folder = _get_data_folder().joinpath("ethpm") print( f"Visit {color('bright magenta')}https://explorer.ethpm.com/{color}" " for a list of ethPM registries and packages.\n" ) if not list(ethpm_folder.glob("*")): print("No local packages are currently available.") for path in sorted(ethpm_folder.glob("*")): package_list = sorted(path.glob("*")) if not package_list: path.unlink() continue print(f"{color['bright magenta']}erc1319://{path.name}{color}") for package_path in package_list: u = "\u2514" if package_path == package_list[-1] else "\u251c" versions = sorted(package_path.glob("*.json")) if len(versions) == 1: print( f" {color['bright black']}{u}\u2500{color['bright white']}{package_path.stem}" f"{color}@{color['bright white']}{versions[0].stem}{color}" ) continue print( f" {color['bright black']}{u}\u2500{color['bright white']}" f"{package_path.stem}{color}" ) for v in versions: u = "\u2514" if v == versions[-1] else "\u251c" print(f" {color['bright black']}{u}\u2500{color['bright white']}{v.stem}{color}")
def test_delete_provider(): cli_networks._delete_provider("infura") with _get_data_folder().joinpath("providers-config.yaml").open() as fp: providers = yaml.safe_load(fp) assert "infura" not in [providers.keys()]
def package_loader(project_id): if project_id not in _open_projects: path = _get_data_folder().joinpath(f"packages/{project_id}") _open_projects[project_id] = brownie.project.load( path, project_id) return _open_projects[project_id]
def test_import(tmp_path): path = tmp_path.joinpath("exported.yaml") with path.open("w") as fp: yaml.dump( { "live": [{ "name": "FooChain", "networks": [{ "id": "tester", "host": "127.0.0.1", "chainid": 42, "name": "tester" }], }] }, fp, ) cli_networks._import(path.as_posix()) with _get_data_folder().joinpath("network-config.yaml").open() as fp: networks = yaml.safe_load(fp) assert networks["live"][-1] == { "name": "FooChain", "networks": [{ "id": "tester", "host": "127.0.0.1", "chainid": 42, "name": "tester" }], }
def test_update_provider(): name = "infura" url = "test_url" cli_networks._update_provider(name, url) with _get_data_folder().joinpath("providers-config.yaml").open() as fp: providers = yaml.safe_load(fp) assert providers[name]["host"] == url
def _list(verbose=False): if isinstance(verbose, str): verbose = eval(verbose.capitalize()) with _get_data_folder().joinpath("network-config.yaml").open() as fp: networks = yaml.safe_load(fp) print("The following networks are declared:") for chain in networks["live"]: print(f"\n{chain['name']}") for value in chain["networks"]: is_last = value == chain["networks"][-1] if verbose: _print_verbose_network_description(value, is_last) else: _print_simple_network_description(value, is_last) print("\nDevelopment") for value in networks["development"]: is_last = value == networks["development"][-1] if verbose: settings = value.pop("cmd_settings") _print_verbose_network_description( value, value == networks["development"][-1]) _print_verbose_network_description( settings, value == networks["development"][-1], 2) else: _print_simple_network_description(value, is_last)
def test_delete_live(): cli_networks._delete("mainnet") with _get_data_folder().joinpath("network-config.yaml").open() as fp: networks = yaml.safe_load(fp) assert "mainnet" not in [i["id"] for i in networks["live"][0]["networks"]]
def save(self, filename: str, overwrite: bool = False) -> str: """Encrypts the private key and saves it in a keystore json. Attributes: filename: path to keystore file. If no folder is given, saved in ~/.brownie/accounts overwrite: if True, will overwrite an existing file. Returns the absolute path to the keystore file as a string. """ path = _get_data_folder().joinpath("accounts") path.mkdir(exist_ok=True) filename = str(filename) if not filename.endswith(".json"): filename += ".json" if not any(i in r"\/" for i in filename): json_file = path.joinpath(filename).resolve() else: json_file = Path(filename).expanduser().resolve() if not overwrite and json_file.exists(): raise FileExistsError( "Account with this identifier already exists") encrypted = web3.eth.account.encrypt( self.private_key, getpass("Enter the password to encrypt this account with: ")) with json_file.open("w") as fp: json.dump(encrypted, fp) return str(json_file)
def _list(): org_names = [] for path in _get_data_folder().joinpath("packages").iterdir(): if not path.is_dir(): continue elif not list(i for i in path.iterdir() if i.is_dir() and "@" in i.name): shutil.rmtree(path) else: org_names.append(path) if not org_names: print("No packages are currently installed.") else: print("The following packages are currently installed:") for org_path in org_names: packages = list(org_path.iterdir()) print(f"\n{color('bright magenta')}{org_path.name}{color}") for path in packages: u = "\u2514" if path == packages[-1] else "\u251c" name, version = path.name.rsplit("@", maxsplit=1) print( f" {color('bright black')}{u}\u2500{_format_pkg(org_path.name, name, version)}" )
def load(self, filename: str = None) -> Union[List, "LocalAccount"]: """Loads a local account from a keystore file. Args: filename: Keystore filename. If none is given, returns a list of available keystores. Returns: Account instance.""" project_path = _get_data_folder().joinpath("accounts") if not filename: return [i.stem for i in project_path.glob("*.json")] filename = str(filename) if not filename.endswith(".json"): filename += ".json" json_file = Path(filename).expanduser() if not json_file.exists(): json_file = project_path.joinpath(filename) if not json_file.exists(): raise FileNotFoundError(f"Cannot find {json_file}") with json_file.open() as fp: priv_key = web3.eth.account.decrypt( json.load(fp), getpass("Enter the password to unlock this account: ") ) return self.add(priv_key)
def test_delete_development(): cli_networks._delete("development") with _get_data_folder().joinpath("network-config.yaml").open() as fp: networks = yaml.safe_load(fp) assert not networks["development"]
def test_dotenv_imports(config, testproject, env_file, project_settings_with_dotenv): config_path = _get_data_folder().joinpath("brownie-config.yaml") _load_config(config_path) testproject.load_config() assert config.settings["console"]["show_colors"] == False # noqa: E712 assert config.settings["networks"]["development"][ "default_balance"] == "42 miliether"
def _delete_provider(name): with _get_data_folder().joinpath("providers-config.yaml").open() as fp: providers = yaml.safe_load(fp) if name not in providers.keys(): raise ValueError( f"Provider '{color('bright magenta')}{name}{color}' does not exist" ) del providers[name] with _get_data_folder().joinpath("providers-config.yaml").open("w") as fp: yaml.dump(providers, fp) notify( "SUCCESS", f"Provider '{color('bright magenta')}{name}{color}' has been deleted")
def test_delete_development(networks_yaml): for network_name in networks_yaml["development"]: cli_networks._delete(network_name["id"]) with _get_data_folder().joinpath("network-config.yaml").open() as fp: networks = yaml.safe_load(fp) assert not networks["development"]
def test_delete_all_networks_in_prod_environment(): cli_networks._delete("etc") cli_networks._delete("kotti") with _get_data_folder().joinpath("network-config.yaml").open() as fp: networks = yaml.safe_load(fp) assert len(networks["live"]) == 1
def _mk_repo_path(*folder_names): path = _get_data_folder().joinpath("packages") for name in folder_names: path = path.joinpath(name) path.mkdir(exist_ok=True) return path
def test_delete_development(): for network_name in ("development", "mainnet-fork", "bsc-main-fork", "geth-dev"): cli_networks._delete(network_name) with _get_data_folder().joinpath("network-config.yaml").open() as fp: networks = yaml.safe_load(fp) assert not networks["development"]
def _delete(id_): if id_ not in CONFIG.networks: raise ValueError(f"Network '{color('bright magenta')}{id_}{color}' does not exist") with _get_data_folder().joinpath("network-config.yaml").open() as fp: networks = yaml.safe_load(fp) if "cmd" in CONFIG.networks[id_]: networks["development"] = [i for i in networks["development"] if i["id"] != id_] else: target = next(i for i in networks["live"] for x in i["networks"] if x["id"] == id_) target["networks"] = [i for i in target["networks"] if i["id"] != id_] networks["live"] = [i for i in networks["live"] if i["networks"]] with _get_data_folder().joinpath("network-config.yaml").open("w") as fp: yaml.dump(networks, fp) notify("SUCCESS", f"Network '{color('bright magenta')}{id_}{color}' has been deleted")
def test_set_provider(): cli_networks._set_provider("alchemy") with _get_data_folder().joinpath("network-config.yaml").open() as fp: networks = yaml.safe_load(fp) assert (networks["live"][0]["networks"][0]["host"] == "https://eth-mainnet.alchemyapi.io/v2/$WEB3_ALCHEMY_PROJECT_ID") assert networks["live"][0]["networks"][0]["name"] == "Mainnet (Alchemy)" assert networks["live"][0]["networks"][0]["provider"] == "alchemy"
def _delete(package_id): org, repo, version = _split_id(package_id) source_path = _get_data_folder().joinpath( f"packages/{org}/{repo}@{version}") if not source_path.exists(): raise FileNotFoundError( f"Package '{_format_pkg(org, repo, version)}' is not installed") shutil.rmtree(source_path) notify("SUCCESS", f"Package '{_format_pkg(org, repo, version)}' has been deleted")
def test_generate(capfd): path = _get_data_folder().joinpath("accounts/generate.json") assert not path.exists() cli_accounts._generate("generate") assert path.exists() with path.open() as fp: data = json.load(fp) capfd.readouterr() cli_accounts._list() assert data["address"] in capfd.readouterr()[0].lower()
def test_import_from_nothing(tmp_path, config): path = tmp_path.joinpath("exported.yaml") with _get_data_folder().joinpath("network-config.yaml").open() as fp: networks = yaml.safe_load(fp) with path.open("w") as fp: yaml.dump(networks, fp) for key in config.networks.keys(): cli_networks._delete(key) config.networks = {} cli_networks._import(path.as_posix()) with _get_data_folder().joinpath("network-config.yaml").open() as fp: networks = yaml.safe_load(fp) with path.open() as fp: exported = yaml.safe_load(fp) assert networks == exported
def _get_allow_paths(allow_paths: Optional[str], remappings: list) -> str: # generate the final allow_paths field based on path remappings path_list = [] if allow_paths is None else [allow_paths] remapping_paths = [i[i.index("=") + 1 :] for i in remappings] data_path = _get_data_folder().joinpath("packages").as_posix() remapping_paths = [i for i in remapping_paths if not i.startswith(data_path)] path_list = path_list + [data_path] + remapping_paths return ",".join(path_list)
def _add(env, id_, *args): if id_ in CONFIG.networks: raise ValueError( f"Network '{color('bright magenta')}{id_}{color}' already exists") args = _parse_args(args) if "name" not in args: args["name"] = id_ with _get_data_folder().joinpath("network-config.yaml").open() as fp: networks = yaml.safe_load(fp) if env.lower() == "development": new = { "name": args.pop("name"), "id": id_, "cmd": args.pop("cmd"), "host": args.pop("host"), } if "timeout" in args: new["timeout"] = args.pop("timeout") new["cmd_settings"] = args _validate_network(new, DEV_REQUIRED) networks["development"].append(new) else: target = next( (i["networks"] for i in networks["live"] if i["name"].lower() == env.lower()), None) if target is None: networks["live"].append({"name": env, "networks": []}) target = networks["live"][-1]["networks"] new = {"id": id_, **args} _validate_network(new, PROD_REQUIRED) target.append(new) with _get_data_folder().joinpath("network-config.yaml").open("w") as fp: yaml.dump(networks, fp) notify( "SUCCESS", f"A new network '{color('bright magenta')}{new['name']}{color}' has been added" ) _print_verbose_network_description(new, True)
def test_add(): cli_networks._add("ethereum", "tester", "host=127.0.0.1", "chainid=42") with _get_data_folder().joinpath("network-config.yaml").open() as fp: networks = yaml.safe_load(fp) assert networks["live"][0]["networks"][-1] == { "id": "tester", "host": "127.0.0.1", "chainid": 42, "name": "tester", }
def test_export(tmp_path): path = tmp_path.joinpath("exported.yaml") cli_networks._export(path.as_posix()) with _get_data_folder().joinpath("network-config.yaml").open() as fp: networks = yaml.safe_load(fp) with path.open() as fp: exported = yaml.safe_load(fp) assert networks == exported
def _list(): account_paths = sorted(_get_data_folder().glob("accounts/*.json")) print(f"Found {len(account_paths)} account{'s' if len(account_paths)!=1 else ''}:") for path in account_paths: u = "\u2514" if path == account_paths[-1] else "\u251c" with path.open() as fp: data = json.load(fp) print( f" {color('bright black')}{u}\u2500{color('bright blue')}{path.stem}{color}" f": {color('bright magenta')}{to_address(data['address'])}{color}" )
def _modify(id_, *args): if id_ not in CONFIG.networks: raise ValueError( f"Network '{color('bright magenta')}{id_}{color}' does not exist") args = _parse_args(args) with _get_data_folder().joinpath("network-config.yaml").open() as fp: networks = yaml.safe_load(fp) is_dev = "cmd" in CONFIG.networks[id_] if is_dev: target = next(i for i in networks["development"] if i["id"] == id_) else: target = next(x for i in networks["live"] for x in i["networks"] if x["id"] == id_) for key, value in args.items(): t = target if key in DEV_CMD_SETTINGS and is_dev: t = target["cmd_settings"] if value is None: del t[key] else: t[key] = value if is_dev: _validate_network(target, DEV_REQUIRED) else: _validate_network(target, PROD_REQUIRED) if "name" not in target: target["name"] = id_ with _get_data_folder().joinpath("network-config.yaml").open("w") as fp: yaml.dump(networks, fp) notify( "SUCCESS", f"Network '{color('bright magenta')}{target['name']}{color}' has been modified" ) _print_verbose_network_description(target, True)
def _get_alias(contract_name: str, path_str: str) -> str: # Generate an alias for a contract, used when tracking dependencies. # For a contract within the project, the alias == the name. For contracts # imported from a dependency, the alias is set as [PACKAGE]/[NAME] # to avoid namespace collisions. data_path = _get_data_folder().parts path_parts = Path(path_str).parts if path_parts[:len(data_path)] == data_path: idx = len(data_path) + 1 return f"{path_parts[idx]}/{path_parts[idx+1]}/{contract_name}" else: return contract_name
def _get_uri_contents(uri: str) -> str: path = _get_data_folder().joinpath( f"ipfs_cache/{urlparse(uri).netloc}.ipfs") path.parent.mkdir(exist_ok=True) if not path.exists(): data = InfuraIPFSBackend().fetch_uri_contents(uri) with path.open("wb") as fp: fp.write(data) return data.decode("utf-8") with path.open() as fp: data = fp.read() return data