Exemple #1
0
def test_can_install_same_package_twice_if_aliased(config, owned_pkg,
                                                   test_assets_dir):
    aliased_pkg = Package(
        Namespace(
            uri=OWNED_MANIFEST_IPFS_URI,
            alias="owned-alias",
        ),
        config.ipfs_backend,
    )
    install_package(owned_pkg, config)
    install_package(aliased_pkg, config)

    assert (config.ethpm_dir / "owned").is_dir()
    assert check_dir_trees_equal(
        config.ethpm_dir / "owned",
        test_assets_dir / "owned" / "ipfs_uri" / ETHPM_PACKAGES_DIR / "owned",
    )
    assert (config.ethpm_dir / "owned-alias").is_dir()
    assert check_dir_trees_equal(
        config.ethpm_dir / "owned-alias",
        test_assets_dir / "owned"  # noqa: W503
        / "ipfs_uri_alias"  # noqa: W503
        / ETHPM_PACKAGES_DIR  # noqa: W503
        / "owned-alias",  # noqa: W503
    )
Exemple #2
0
def test_install_package(args, pkg_name, install_type, config,
                         test_assets_dir):
    pkg = Package(args, config.ipfs_backend)
    install_package(pkg, config)

    expected_package = test_assets_dir / pkg_name / install_type / ETHPM_PACKAGES_DIR
    assert check_dir_trees_equal(config.ethpm_dir, expected_package)
Exemple #3
0
def test_can_install_same_package_twice_if_aliased(config, owned_pkg,
                                                   test_assets_dir):
    aliased_pkg = Package(
        Namespace(
            uri="ipfs://QmbeVyFLSuEUxiXKwSsEjef6icpdTdA4kGG9BcrJXKNKUW",
            alias="owned-alias",
        ),
        config.ipfs_backend,
    )
    install_package(owned_pkg, config)
    install_package(aliased_pkg, config)

    assert (config.ethpm_dir / "owned").is_dir()
    assert check_dir_trees_equal(
        config.ethpm_dir / "owned",
        test_assets_dir / "owned" / "ipfs_uri" / ETHPM_PACKAGES_DIR / "owned",
    )
    assert (config.ethpm_dir / "owned-alias").is_dir()
    assert check_dir_trees_equal(
        config.ethpm_dir / "owned-alias",
        test_assets_dir / "owned"  # noqa: W503
        / "ipfs_uri_alias"  # noqa: W503
        / ETHPM_PACKAGES_DIR  # noqa: W503
        / "owned-alias",  # noqa: W503
    )
Exemple #4
0
def test_install_package_with_ens_in_registry_uri(config):
    uri = Namespace(uri="erc1319://ens.snakecharmers.eth:1/[email protected]")
    pkg = Package(uri, config.ipfs_backend)
    install_package(pkg, config)

    assert (config.ethpm_dir).is_dir()
    assert (config.ethpm_dir / "ens").is_dir()
    assert (config.ethpm_dir / "ens" / "_src" / "ENS.sol").is_file()
Exemple #5
0
def test_install_package_with_ens_in_registry_uri(config):
    uri = Namespace(
        uri="erc1319://0x3F0ED4f69f21ca9d8748c860Ecd0aB6da44BA75a:1/[email protected]")
    pkg = Package(uri, config.ipfs_backend)
    install_package(pkg, config)

    assert (config.ethpm_dir).is_dir()
    assert (config.ethpm_dir / "ens").is_dir()
    assert (config.ethpm_dir / "ens" / "_src" / "ENS.sol").is_file()
Exemple #6
0
def install_to_ethpm_lock(package: Package, ethpm_lock: Path) -> None:
    if ethpm_lock.is_file():
        old_lock = json.loads(ethpm_lock.read_text())
    else:
        old_lock = {}
        ethpm_lock.touch()
    new_package_data = package.generate_ethpm_lock()
    new_lock = assoc(old_lock, package.alias, new_package_data)
    ethpm_lock.write_text(
        f"{json.dumps(new_lock, sort_keys=True, indent=4)}\n")
Exemple #7
0
def test_package_with_registry_uri_with_alias(owned_pkg_data, ipfs_backend):
    args = Namespace(uri=owned_pkg_data["registry_uri"], alias="owned-alias")
    package = Package(args, ipfs_backend)

    assert package.alias == "owned-alias"
    assert package.install_uri == owned_pkg_data["registry_uri"]
    assert package.manifest_uri == owned_pkg_data["ipfs_uri"]
    assert package.registry_address == owned_pkg_data["registry_address"]
    assert package.resolved_content_hash == owned_pkg_data["content_hash"]
    assert package.raw_manifest == owned_pkg_data["raw_manifest"]
    assert package.manifest == owned_pkg_data["manifest"]
Exemple #8
0
def test_package(owned_pkg_data, ipfs_backend):
    args = Namespace(uri=owned_pkg_data["ipfs_uri"])
    package = Package(args, ipfs_backend)

    assert package.alias == "owned"
    assert package.install_uri == owned_pkg_data["ipfs_uri"]
    assert package.manifest_uri == owned_pkg_data["ipfs_uri"]
    assert package.registry_address is None
    assert package.resolved_content_hash == owned_pkg_data["content_hash"]
    assert package.raw_manifest == owned_pkg_data["raw_manifest"]
    assert package.manifest == owned_pkg_data["manifest"]
Exemple #9
0
def install_action(args: argparse.Namespace) -> None:
    validate_install_cli_args(args)
    config = Config(args)
    package = Package(args, config.ipfs_backend)
    install_package(package, config)
    cli_logger.info(
        "%s package sourced from %s installed to %s.",
        package.alias,
        args.uri,
        config.ethpm_dir,
    )
Exemple #10
0
def write_build_deps_to_disk(package: Package, package_dir: Path,
                             ipfs_backend: BaseIPFSBackend) -> None:
    if "build_dependencies" in package.manifest:
        child_ethpm_dir = package_dir / ETHPM_PACKAGES_DIR
        child_ethpm_dir.mkdir()
        for name, uri in package.manifest["build_dependencies"].items():
            dep_package = Package(Namespace(uri=uri, alias=""), ipfs_backend)
            tmp_dep_dir = child_ethpm_dir / name
            tmp_dep_dir.mkdir()
            validate_parent_directory(package_dir, tmp_dep_dir)
            write_package_installation_files(dep_package, tmp_dep_dir,
                                             ipfs_backend)
Exemple #11
0
def get_manifest(args: argparse.Namespace, config: Config) -> None:
    package = Package(args, config.ipfs_backend)
    manifest = json.loads(package.raw_manifest)
    if args.pretty:
        pretty_print_raw_manifest(manifest)
    elif args.output_file:
        if args.output_file.exists() or not args.output_file.parent.is_dir():
            raise InstallError(
                f"Invalid output file: {args.output_file}. Output file must not exist "
                "and live inside a valid parent directory.")
        args.output_file.touch()
        args.output_file.write_bytes(package.raw_manifest)
        cli_logger.info(
            f"Manifest sourced from: {args.uri} written to {args.output_file}."
        )
    else:
        cli_logger.info(manifest)
Exemple #12
0
def activate_package(args: Namespace, config: Config) -> None:
    # support: etherscan / ipfs / github / erc1319
    url = parse.urlparse(args.package_or_uri)
    if url.scheme:
        if url.scheme not in SUPPORTED_SCHEMES:
            raise UriNotSupportedError(
                f"URIs with a scheme of {url.scheme} are not supported. "
                f"Currently supported schemes include: {SUPPORTED_SCHEMES}")
        try:
            args.package_name = "etherscan"  # for etherscan URIs
            args.package_version = "1.0.0"  # for etherscan URIs
            args.uri = args.package_or_uri
            cli_pkg = Package(args, config.ipfs_backend)
            manifest = cli_pkg.manifest
        except UriNotSupportedError:
            raise UriNotSupportedError(
                f"{args.package_or_uri} is not a supported URI. The only URIs currently supported "
                "are Registry, Github Blob, Etherscan and IPFS")
    else:
        if not is_package_installed(args.package_or_uri, config):
            raise InstallError(
                f"Package: {args.package_or_uri} not installed in ethPM dir: {config.ethpm_dir}."
            )
        manifest = json.loads((config.ethpm_dir / args.package_or_uri /
                               "manifest.json").read_text())

    pkg = ethpmPackage(manifest, config.w3)

    activation_banner = (
        f"{(LIGHTNING_EMOJI + PACKAGE_EMOJI) * 4}{LIGHTNING_EMOJI}\n"
        f"{bold_white('Activating package')}: {bold_blue(pkg.name)}@{bold_green(pkg.version)}\n"
        f"{(LIGHTNING_EMOJI + PACKAGE_EMOJI) * 4}{LIGHTNING_EMOJI}\n")
    cli_logger.info(activation_banner)

    if "contractTypes" in pkg.manifest:
        num_contract_types = len(pkg.manifest["contractTypes"])
    else:
        num_contract_types = 0

    if "deployments" in pkg.manifest:
        num_deployments = sum(
            len(deps) for _, deps in pkg.manifest["deployments"].items())
    else:
        num_deployments = 0

    if num_contract_types > 0:
        available_factories = generate_contract_factories(pkg)
        if len(available_factories) > 0:
            formatted_factories = list_keys_for_display(available_factories)
            factories_banner = (
                f"Successfully generated {len(available_factories)} contract "
                f"{pluralize(len(available_factories), 'factory')} on mainnet from "
                f"{num_contract_types} detected contract {pluralize(num_contract_types, 'type')}.\n"
                f"{''.join(formatted_factories)}\n"
                "To get a contract factory on a different chain, call "
                f"`{bold_white('get_factory(target_factory, target_w3)')}`\n"
                "using the available contract fatories and Web3 instances.\n\n"
            )
        else:
            factories_banner = "\n"
    else:
        available_factories = {}
        factories_banner = "No detected contract types.\n"

    if num_deployments > 0:
        available_instances = generate_deployments(pkg, config)
        formatted_instances = list_keys_for_display(available_instances)
        deployments_banner = (
            f"Successfully generated {len(available_instances)} contract "
            f"{pluralize(len(available_instances), 'instance')} from {num_deployments} detected "
            f"{pluralize(num_deployments, 'deployment')}.\n"
            f"{''.join(formatted_instances)}\n")
    else:
        available_instances = {}
        deployments_banner = "No detected deployments.\n"

    if config.private_key:
        auth_banner = (
            f"Deployments configured to sign for: {config.w3.eth.defaultAccount}\n"
        )
    else:
        auth_banner = (
            "Contract instances and web3 instances have not been configured with an account.\n"
            "Use the --keyfile-password flag to enable automatic signing.\n")

    available_w3s = get_w3s(config)
    formatted_w3s = list_keys_for_display(available_w3s)
    web3_banner = "Available Web3 Instances\n" f"{''.join(formatted_w3s)}\n"

    banner = (
        f"{factories_banner}{deployments_banner}{web3_banner}{auth_banner}\n"
        "The API for web3.py contract factories and instances can be found here:\n"
        f"{bold_white('https://web3py.readthedocs.io/en/stable/contracts.html')}\n\n"
        "Starting IPython console... ")
    helper_fns = {"get_factory": get_factory}
    embed(
        user_ns={
            **available_factories,
            **available_instances,
            # ignore b/c conflicting types w/in dict values
            **available_w3s,  # type: ignore
            **helper_fns,  # type: ignore
        },
        banner1=banner,
        colors="neutral",
    )
Exemple #13
0
def wallet_pkg(config):
    args = Namespace(uri=WALLET_MANIFEST_IPFS_URI)
    return Package(args, config.ipfs_backend)
Exemple #14
0
def update_package(args: Namespace, config: Config) -> None:
    if not is_package_installed(args.package, config):
        check_for_aliased_package(args.package, config)
        return

    installed_package = resolve_installed_package_by_id(args.package, config)
    active_registry = get_active_registry(config.xdg_ethpmcli_root /
                                          REGISTRY_STORE)
    if is_valid_registry_uri(installed_package.install_uri):
        validate_same_registry(installed_package.install_uri,
                               active_registry.uri)

    connected_chain_id = config.w3.eth.chainId
    active_registry_uri = parse_registry_uri(active_registry.uri)
    if not to_int(text=active_registry_uri.chain_id) == connected_chain_id:
        raise InstallError(
            f"Registry URI chain: {active_registry_uri.chain_id} doesn't match "
            f"connected web3: {connected_chain_id}.")

    config.w3.pm.set_registry(active_registry_uri.address)
    all_package_names = config.w3.pm.get_all_package_names()
    if installed_package.resolved_package_name not in all_package_names:
        raise InstallError(
            f"{installed_package.resolved_package_name} is not available on the active registry "
            f"{active_registry.uri}. Available packages include: {all_package_names}."
        )

    all_release_data = config.w3.pm.get_all_package_releases(
        installed_package.resolved_package_name)
    all_versions = [version for version, _ in all_release_data]

    if installed_package.resolved_version not in all_versions:
        raise InstallError(
            f"{installed_package.resolved_package_name}@{installed_package.resolved_version} not "
            f"found on the active registry {active_registry.uri}.")

    on_chain_install_uri = pluck_release_data(
        all_release_data, installed_package.resolved_version)
    if on_chain_install_uri != installed_package.resolved_uri:
        raise InstallError(
            f"Install URI found on active registry for {installed_package.resolved_package_name}@"
            f"{installed_package.resolved_version}: {on_chain_install_uri} does not match the "
            f"install URI found in local lockfile: {installed_package.resolved_uri}."
        )

    cli_logger.info(
        f"{len(all_versions)} versions of {installed_package.resolved_package_name} "
        f"found: {all_versions} \n"
        f"On the active registry: {active_registry.uri}")
    count = 0
    while True:
        count += 1
        target_version = input(
            "Please enter the version you want to install. ")
        if count > 5:
            raise InstallError("Max attempts (5) reached. ")
        elif target_version == installed_package.resolved_version:
            cli_logger.info(f"Version already installed: {target_version}. ")
        elif target_version not in all_versions:
            cli_logger.info(f"Version unavailable: {target_version}. ")
        else:
            break

    # Create an updated args/Package for new install
    updated_args = copy.deepcopy(args)
    if installed_package.resolved_package_name != args.package:
        updated_args.alias = args.package
    updated_args.uri = pluck_release_data(all_release_data, target_version)
    updated_args.package_version = target_version
    updated_package = Package(updated_args, config.ipfs_backend)

    # atomic replace
    with tempfile.TemporaryDirectory() as tmpdir:
        tmp_ethpm_dir = Path(tmpdir) / ETHPM_PACKAGES_DIR
        shutil.copytree(config.ethpm_dir, tmp_ethpm_dir)
        tmp_config = copy.copy(config)
        tmp_config.ethpm_dir = tmp_ethpm_dir
        uninstall_package(args.package, tmp_config)
        install_package(updated_package, tmp_config)
        shutil.rmtree(config.ethpm_dir)
        tmp_ethpm_dir.replace(config.ethpm_dir)

    cli_logger.info(f"{updated_args.package} successfully updated to version "
                    f"{updated_args.package_version}.")
Exemple #15
0
def owned_pkg(config):
    args = Namespace(uri=OWNED_MANIFEST_IPFS_URI)
    return Package(args, config.ipfs_backend)
Exemple #16
0
def wallet_pkg(config):
    args = Namespace(
        uri="ipfs://QmRMSm4k37mr2T3A2MGxAj2eAHGR5veibVt1t9Leh5waV1")
    return Package(args, config.ipfs_backend)
Exemple #17
0
def owned_pkg(config):
    args = Namespace(
        uri="ipfs://QmbeVyFLSuEUxiXKwSsEjef6icpdTdA4kGG9BcrJXKNKUW")
    return Package(args, config.ipfs_backend)