Ejemplo n.º 1
0
import sys
import time

import click

import coin_info
import marketcap

LOG = logging.getLogger(__name__)

OPTIONAL_KEYS = ("links", "notes", "wallet")
ALLOWED_SUPPORT_STATUS = ("yes", "no", "planned", "soon")

WALLETS = coin_info.load_json("wallets.json")
OVERRIDES = coin_info.load_json("coins_details.override.json")
VERSIONS = coin_info.latest_releases()

# automatic wallet entries
WALLET_SUITE = {"Trezor Suite": "https://suite.trezor.io"}
WALLET_NEM = {
    "Nano Wallet": "https://nem.io/downloads/",
    "Magnum": "https://magnumwallet.co",
}
WALLETS_ETH_3RDPARTY = {
    "MyEtherWallet": "https://www.myetherwallet.com",
    "MyCrypto": "https://mycrypto.com",
}

TREZOR_KNOWN_URLS = (
    "https://suite.trezor.io",
    "https://wallet.trezor.io",
Ejemplo n.º 2
0
def release(
    ctx,
    device: str,
    version,
    git_tag,
    release_missing,
    dry_run,
    soon,
    force,
    add_all,
    verbose,
):
    """Release a new Trezor firmware.

    Update support infos so that all coins have a clear support status.
    By default, marks duplicate tokens as unsupported, and all coins that either
    don't have support info, or they are supported "soon", are set to the
    released firmware version.

    Optionally tags the repository with the given version.

    `device` can be "1", "2", or a string matching `support.json` key. Version
    is autodetected by downloading a list of latest releases and incrementing
    micro version by one, or you can specify `--version` explicitly.

    Unless `--add-all` is specified, the tool will ask you to confirm each added
    coin. ERC20 tokens are added automatically. Use `--verbose` to see them.
    """
    # check condition(s)
    if soon and git_tag:
        raise click.ClickException("Cannot git-tag a 'soon' revision")

    # process `device`
    if device.isnumeric():
        device = f"trezor{device}"

    if not force and device not in coin_info.VERSIONED_SUPPORT_INFO:
        raise click.ClickException(
            f"Non-releasable device {device} (support info is not versioned). "
            "Use --force to proceed anyway.")

    if not soon:
        # guess `version` if not given
        if not version:
            versions = coin_info.latest_releases()
            latest_version = versions.get(device)
            if latest_version is None:
                raise click.ClickException(
                    "Failed to guess version. "
                    "Please use --version to specify it explicitly.")
            else:
                latest_version = list(latest_version)
            latest_version[-1] += 1
            version = ".".join(str(n) for n in latest_version)

        # process `version`
        try:
            version_numbers = list(map(int, version.split(".")))
            expected_device = f"trezor{version_numbers[0]}"
            if not force and device != expected_device:
                raise click.ClickException(
                    f"Device {device} should not be version {version}. "
                    "Use --force to proceed anyway.")
        except ValueError as e:
            if not force:
                raise click.ClickException(
                    f"Failed to parse '{version}' as a version. "
                    "Use --force to proceed anyway.") from e

    if soon:
        version = "soon"
        print(f"Moving {device} missing infos to 'soon'")
    else:
        print(f"Releasing {device} firmware version {version}")

    defs, _ = coin_info.coin_info_with_duplicates()
    coins_dict = defs.as_dict()

    # Invoke data fixup as dry-run. That will modify data internally but won't write
    # changes. We will write changes at the end based on our own `dry_run` value.
    print("Fixing up data...")
    ctx.invoke(fix, dry_run=True)

    def maybe_add(coin, label):
        add = False
        if add_all:
            add = True
        else:
            text = f"Add {label} coin {coin['key']} ({coin['name']})?"
            add = click.confirm(text, default=True)
        if add:
            set_supported(device, coin["key"], version)

    # if we're releasing, process coins marked "soon"
    if not soon:
        supported, _ = support_dicts(device)
        soon_list = [
            coins_dict[key] for key, val in supported.items()
            if val == "soon" and key in coins_dict
        ]
        for coin in soon_list:
            key = coin["key"]
            maybe_add(coin, "soon")

    # process missing (not listed) supportinfos
    if release_missing:
        missing_list = find_unsupported_coins(coins_dict)[device]
        tokens = [coin for coin in missing_list if coin_info.is_token(coin)]
        nontokens = [
            coin for coin in missing_list if not coin_info.is_token(coin)
        ]
        for coin in tokens:
            key = coin["key"]
            # assert not coin.get("duplicate"), key
            if verbose:
                print(f"Adding missing {key} ({coin['name']})")
            set_supported(device, key, version)

        for coin in nontokens:
            maybe_add(coin, "missing")

    tagname = f"{device}-{version}"
    if git_tag:
        if dry_run:
            print(f"Would tag current commit with {tagname}")
        else:
            print(f"Tagging current commit with {tagname}")
            subprocess.check_call(["git", "tag", tagname])

    if not dry_run:
        write_support_info()
    else:
        print("No changes written")
Ejemplo n.º 3
0
import json
import logging
import requests
import sys
import coin_info

import click

LOG = logging.getLogger(__name__)

OPTIONAL_KEYS = ("links", "notes", "wallet")
ALLOWED_SUPPORT_STATUS = ("yes", "no", "planned", "soon")

WALLETS = coin_info.load_json("wallets.json")
OVERRIDES = coin_info.load_json("coins_details.override.json")
VERSIONS = coin_info.latest_releases()

COINMAKETCAP_CACHE = os.path.join(os.path.dirname(__file__), "coinmarketcap.json")
COINMARKETCAP_API_BASE = "https://pro-api.coinmarketcap.com/v1/"

MARKET_CAPS = {}

# automatic wallet entries
WALLET_TREZOR = {"Trezor": "https://wallet.trezor.io"}
WALLET_TREZOR_NEXT = {"Trezor Beta": "https://beta-wallet.trezor.io/next/"}
WALLET_NEM = {"Nano Wallet": "https://nem.io/downloads/"}

WALLETS_ETH_3RDPARTY = {
    "MyEtherWallet": "https://www.myetherwallet.com",
    "MyCrypto": "https://mycrypto.com",
}
Ejemplo n.º 4
0
def release(
    ctx,
    device: str,
    version,
    git_tag,
    release_missing,
    dry_run,
    soon,
    force,
    add_all,
    verbose,
):
    """Release a new Trezor firmware.

    Update support infos so that all coins have a clear support status.
    By default, marks duplicate tokens as unsupported, and all coins that either
    don't have support info, or they are supported "soon", are set to the
    released firmware version.

    Optionally tags the repository with the given version.

    `device` can be "1", "2", or a string matching `support.json` key. Version
    is autodetected by downloading a list of latest releases and incrementing
    micro version by one, or you can specify `--version` explicitly.

    Unless `--add-all` is specified, the tool will ask you to confirm each added
    coin. ERC20 tokens are added automatically. Use `--verbose` to see them.
    """
    # check condition(s)
    if soon and git_tag:
        raise click.ClickException("Cannot git-tag a 'soon' revision")

    # process `device`
    if device.isnumeric():
        device = f"trezor{device}"

    if not force and device not in coin_info.VERSIONED_SUPPORT_INFO:
        raise click.ClickException(
            f"Non-releasable device {device} (support info is not versioned). "
            "Use --force to proceed anyway."
        )

    if not soon:
        # guess `version` if not given
        if not version:
            versions = coin_info.latest_releases()
            latest_version = versions.get(device)
            if latest_version is None:
                raise click.ClickException(
                    "Failed to guess version. "
                    "Please use --version to specify it explicitly."
                )
            else:
                latest_version = list(latest_version)
            latest_version[-1] += 1
            version = ".".join(str(n) for n in latest_version)

        # process `version`
        try:
            version_numbers = list(map(int, version.split(".")))
            expected_device = f"trezor{version_numbers[0]}"
            if not force and device != expected_device:
                raise click.ClickException(
                    f"Device {device} should not be version {version}. "
                    "Use --force to proceed anyway."
                )
        except ValueError as e:
            if not force:
                raise click.ClickException(
                    f"Failed to parse '{version}' as a version. "
                    "Use --force to proceed anyway."
                ) from e

    if soon:
        version = "soon"
        print(f"Moving {device} missing infos to 'soon'")
    else:
        print(f"Releasing {device} firmware version {version}")

    defs, _ = coin_info.coin_info_with_duplicates()
    coins_dict = defs.as_dict()

    # Invoke data fixup as dry-run. That will modify data internally but won't write
    # changes. We will write changes at the end based on our own `dry_run` value.
    print("Fixing up data...")
    ctx.invoke(fix, dry_run=True)

    def maybe_add(coin, label):
        add = False
        if add_all:
            add = True
        else:
            text = f"Add {label} coin {coin['key']} ({coin['name']})?"
            add = click.confirm(text, default=True)
        if add:
            set_supported(device, coin["key"], version)

    # if we're releasing, process coins marked "soon"
    if not soon:
        supported, _ = support_dicts(device)
        soon_list = [
            coins_dict[key]
            for key, val in supported.items()
            if val == "soon" and key in coins_dict
        ]
        for coin in soon_list:
            key = coin["key"]
            maybe_add(coin, "soon")

    # process missing (not listed) supportinfos
    if release_missing:
        missing_list = find_unsupported_coins(coins_dict)[device]
        tokens = [coin for coin in missing_list if coin_info.is_token(coin)]
        nontokens = [coin for coin in missing_list if not coin_info.is_token(coin)]
        for coin in tokens:
            key = coin["key"]
            assert not coin.get("duplicate")
            if verbose:
                print(f"Adding missing {key} ({coin['name']})")
            set_supported(device, key, version)

        for coin in nontokens:
            maybe_add(coin, "missing")

    tagname = f"{device}-{version}"
    if git_tag:
        if dry_run:
            print(f"Would tag current commit with {tagname}")
        else:
            print(f"Tagging current commit with {tagname}")
            subprocess.check_call(["git", "tag", tagname])

    if not dry_run:
        write_support_info()
    else:
        print("No changes written")
Ejemplo n.º 5
0
def release(
    ctx,
    v1,
    v2,
    dry_run,
    force,
    verbose,
    skip_testnets,
):
    """Release a new Trezor firmware.

    Update support infos so that all coins have a clear support status.
    By default, marks duplicate tokens and testnets as unsupported, and all coins that
    don't have support info are set to the released firmware version.

    The tool will ask you to confirm each added coin. ERC20 tokens are added
    automatically. Use `--verbose` to see them.
    """
    latest_releases = coin_info.latest_releases()

    def bump_version(version_tuple):
        version_list = list(version_tuple)
        version_list[-1] += 1
        return ".".join(str(n) for n in version_list)

    # guess `version` if not given
    if not v1:
        v1 = bump_version(latest_releases["trezor1"])
    if not v2:
        v2 = bump_version(latest_releases["trezor2"])

    versions = {"trezor1": v1, "trezor2": v2}

    for number in "1", "2":
        device = f"trezor{number}"
        version = versions[device]
        if not force and not version.startswith(number + "."):
            raise click.ClickException(
                f"Device trezor{device} should not be version {version}. "
                "Use --force to proceed anyway."
            )

        print(f"Releasing {device} firmware version {version}")

    defs, _ = coin_info.coin_info_with_duplicates()
    coins_dict = defs.as_dict()

    # Invoke data fixup as dry-run. That will modify data internally but won't write
    # changes. We will write changes at the end based on our own `dry_run` value.
    print("Fixing up data...")
    ctx.invoke(fix, dry_run=True)

    def maybe_add(coin):
        add = click.confirm(
            f"Add missing coin {coin['key']} ({coin['name']})?", default=True
        )
        if not add:
            unsupport_reason = click.prompt(
                "Enter reason for not supporting (blank to skip)",
                default="",
                show_default=False,
            )
            if not unsupport_reason:
                return

        for device, version in versions.items():
            if add:
                support_setdefault(device, coin["key"], version)
            else:
                support_setdefault(device, coin["key"], False, unsupport_reason)

    # process missing (not listed) supportinfos
    missing_list = []
    unsupported = find_unsupported_coins(coins_dict)
    for val in unsupported.values():
        for coin in val:
            if coin not in missing_list:
                missing_list.append(coin)

    tokens = [coin for coin in missing_list if coin_info.is_token(coin)]
    nontokens = [coin for coin in missing_list if not coin_info.is_token(coin)]
    for coin in tokens:
        key = coin["key"]
        # assert not coin.get("duplicate"), key
        if verbose:
            print(f"Adding missing {key} ({coin['name']})")
        for device, version in versions.items():
            support_setdefault(device, key, version)

    for coin in nontokens:
        if skip_testnets and "testnet" in coin["name"].lower():
            for device, version in versions.items():
                support_setdefault(device, coin["key"], False, "(AUTO) exclude testnet")
        else:
            maybe_add(coin)

    if not dry_run:
        write_support_info()
    else:
        print("No changes written")