예제 #1
0
    def delete_key_by_fingerprint(self, fingerprint: int):
        """
        Deletes all keys which have the given public key fingerprint.
        """

        index = 0
        key_hex = self._get_stored_entropy(self._get_private_key_user(index))

        while key_hex is not None and len(key_hex) > 0:
            key = ExtendedPrivateKey.from_bytes(hexstr_to_bytes(key_hex))
            if key.get_public_key().get_fingerprint() == fingerprint:
                keyring.delete_password(
                    self._get_service(), self._get_private_key_user(index)
                )
            index += 1
            key_hex = self._get_stored_entropy(self._get_private_key_user(index))

        index = 0
        seed_hex = self._get_stored_entropy(self._get_private_key_seed_user(index))
        while seed_hex is not None and len(seed_hex) > 0:
            key = ExtendedPrivateKey.from_seed(hexstr_to_bytes(seed_hex))
            if key.get_public_key().get_fingerprint() == fingerprint:
                keyring.delete_password(
                    self._get_service(), self._get_private_key_seed_user(index)
                )
            index += 1
            seed_hex = self._get_stored_entropy(self._get_private_key_seed_user(index))
예제 #2
0
    async def create(
        config: Dict,
        key_config: Dict,
        wallet_state_manager: Any,
        info: WalletInfo,
        wallet: Wallet,
        name: str = None,
    ):
        self = RLWallet()
        self.config = config
        self.key_config = key_config
        sk_hex = self.key_config["wallet_sk"]
        self.private_key = ExtendedPrivateKey.from_bytes(bytes.fromhex(sk_hex))
        if name:
            self.log = logging.getLogger(name)
        else:
            self.log = logging.getLogger(__name__)

        self.wallet_state_manager = wallet_state_manager

        self.server = None

        self.wallet_info = info
        self.standard_wallet = wallet
        self.rl_info = RLInfo.from_json_dict(json.loads(info.data))
        return self
예제 #3
0
    def get_all_private_keys(self) -> List[Tuple[ExtendedPrivateKey, Optional[bytes]]]:
        """
        Returns all private keys (both seed-derived keys and raw ExtendedPrivateKeys), and
        the second value in the tuple is the bytes seed if it exists, otherwise None.
        """
        all_keys: List[Tuple[ExtendedPrivateKey, Optional[bytes]]] = []

        # Keys that have a seed are added first
        index = 0
        seed_hex = self._get_stored_entropy(self._get_private_key_seed_user(index))
        while seed_hex is not None and len(seed_hex) > 0:
            key = ExtendedPrivateKey.from_seed(hexstr_to_bytes(seed_hex))
            all_keys.append((key, hexstr_to_bytes(seed_hex)))
            index += 1
            seed_hex = self._get_stored_entropy(self._get_private_key_seed_user(index))

        # Keys without a seed are added after
        index = 0
        key_hex = self._get_stored_entropy(self._get_private_key_user(index))
        while key_hex is not None and len(key_hex) > 0:
            key = ExtendedPrivateKey.from_bytes(hexstr_to_bytes(key_hex))
            all_keys.append((key, None))
            index += 1
            key_hex = self._get_stored_entropy(self._get_private_key_user(index))
        return all_keys
예제 #4
0
    async def add_key(self, request):
        if "mnemonic" in request:
            # Adding a key from 24 word mnemonic
            mnemonic = request["mnemonic"]
            seed = seed_from_mnemonic(mnemonic)
            self.keychain.add_private_key_seed(seed)
            esk = ExtendedPrivateKey.from_seed(seed)
        elif "hexkey" in request:
            # Adding a key from hex private key string. Two cases: extended private key (HD)
            # which is 77 bytes, and int private key which is 32 bytes.
            if len(request["hexkey"]) != 154 and len(request["hexkey"]) != 64:
                return {"success": False}
            if len(request["hexkey"]) == 64:
                sk = PrivateKey.from_bytes(bytes.fromhex(request["hexkey"]))
                self.keychain.add_private_key_not_extended(sk)
                key_bytes = bytes(sk)
                new_extended_bytes = bytearray(
                    bytes(ExtendedPrivateKey.from_seed(token_bytes(32))))
                final_extended_bytes = bytes(
                    new_extended_bytes[:-len(key_bytes)] + key_bytes)
                esk = ExtendedPrivateKey.from_bytes(final_extended_bytes)
            else:
                esk = ExtendedPrivateKey.from_bytes(
                    bytes.fromhex(request["hexkey"]))
                self.keychain.add_private_key(esk)

        else:
            return {"success": False}

        fingerprint = esk.get_public_key().get_fingerprint()
        await self.stop_wallet()
        # Makes sure the new key is added to config properly
        check_keys(self.root_path)

        # Starts the wallet with the new key selected
        started = await self.start_wallet(fingerprint)

        response = {"success": started}
        return response
예제 #5
0
def add_private_key(args):
    """
    Adds a private key to the keyring, without a seed (with the raw private key bytes).
    """
    if args.key is None:
        print("Please specify the key argument -k")
        quit()
    key_hex = args.key
    assert key_hex is not None
    extended_key = ExtendedPrivateKey.from_bytes(bytes.fromhex(key_hex))
    print(
        f"Adding private_key: {extended_key} with fingerprint {extended_key.get_public_key().get_fingerprint()}"
    )
    keychain.add_private_key(extended_key)
예제 #6
0
    async def create_rl_user(
        config: Dict,
        key_config: Dict,
        wallet_state_manager: Any,
        wallet: Wallet,
        name: str = None,
    ):
        async with wallet_state_manager.puzzle_store.lock:
            unused: Optional[
                uint32] = await wallet_state_manager.puzzle_store.get_unused_derivation_path(
                )
            if unused is None:
                await wallet_state_manager.create_more_puzzle_hashes()
            unused = (
                await
                wallet_state_manager.puzzle_store.get_unused_derivation_path())
            assert unused is not None

            sk_hex = key_config["wallet_sk"]
            private_key = ExtendedPrivateKey.from_bytes(bytes.fromhex(sk_hex))
            pubkey_bytes: bytes = bytes(
                private_key.public_child(unused).get_public_key())

            rl_info = RLInfo("user", None, pubkey_bytes, None, None, None,
                             None, None)
            info_as_string = json.dumps(rl_info.to_json_dict())
            await wallet_state_manager.user_store.create_wallet(
                "RL User", WalletType.RATE_LIMITED, info_as_string)
            wallet_info = await wallet_state_manager.user_store.get_last_wallet(
            )
            if wallet_info is None:
                raise

            self = await RLWallet.create(config, key_config,
                                         wallet_state_manager, wallet_info,
                                         wallet, name)

            await wallet_state_manager.puzzle_store.add_derivation_paths([
                DerivationRecord(
                    unused,
                    token_bytes(),
                    pubkey_bytes,
                    WalletType.RATE_LIMITED,
                    wallet_info.id,
                )
            ])
            await wallet_state_manager.puzzle_store.set_used_up_to(unused)

        return self
예제 #7
0
def check_keys(new_root):
    print("\nchecking keys.yaml")
    keys_config = load_config(new_root, "keys.yaml")

    wallet_sk = ExtendedPrivateKey.from_bytes(
        bytes.fromhex(keys_config["wallet_sk"]))
    wallet_target = create_puzzlehash_for_pk(
        BLSPublicKey(bytes(wallet_sk.public_child(0).get_public_key())))
    if (wallet_target.hex() != keys_config["wallet_target"]
            or wallet_target.hex() != keys_config["pool_target"]):
        keys_config["wallet_target"] = wallet_target.hex()
        keys_config["pool_target"] = wallet_target.hex()
        print(
            f"updating wallet target and pool target to {wallet_target.hex()}")
        save_config(new_root, "keys.yaml", keys_config)
예제 #8
0
    def add_private_key_not_extended(self, key_not_extended: PrivateKey):
        """
        Creates a new key, and takes only the prefix information (chain code, version, etc).
        This is used to migrate pool_sks from keys.yaml, which are not extended. Then adds
        the key to the keychain.
        """

        key_bytes = bytes(key_not_extended)
        new_extended_bytes = bytearray(
            bytes(ExtendedPrivateKey.from_seed(token_bytes(32)))
        )
        final_extended_bytes = bytes(new_extended_bytes[: -len(key_bytes)] + key_bytes)
        key = ExtendedPrivateKey.from_bytes(final_extended_bytes)
        assert len(final_extended_bytes) == len(new_extended_bytes)
        assert key.get_private_key() == key_not_extended
        self.add_private_key(key)
예제 #9
0
def migrate_to_keychain(old_root, new_root):
    # Transfer the keys from the old root config folder into the keychain.
    # Also set the right public keys in the config files for farming.

    print("\nMigrating keys.yaml to keychain")
    keychain: Keychain = Keychain()

    # Migrate wallet sk
    try:
        keys_config = load_config(old_root, "keys.yaml", exit_on_error=False)
        wallet_key_bytes = bytes.fromhex(keys_config["wallet_sk"])
        wallet_sk = ExtendedPrivateKey.from_bytes(wallet_key_bytes)
        keychain.add_private_key(wallet_sk)

        # Migrate pool sks
        pool_sks_bytes = [bytes.fromhex(h) for h in keys_config["pool_sks"]]
        for k_bytes in pool_sks_bytes:
            keychain.add_private_key_not_extended(PrivateKey.from_bytes(k_bytes))
    except ValueError:
        print("No keys.yaml to migrate from.")

    check_keys(new_root)
예제 #10
0
    async def create(
        config: Dict,
        key_config: Dict,
        wallet_state_manager: Any,
        info: WalletInfo,
        name: str = None,
    ):
        self = Wallet()
        self.config = config
        self.key_config = key_config
        sk_hex = self.key_config["wallet_sk"]
        self.private_key = ExtendedPrivateKey.from_bytes(bytes.fromhex(sk_hex))
        if name:
            self.log = logging.getLogger(name)
        else:
            self.log = logging.getLogger(__name__)

        self.wallet_state_manager = wallet_state_manager

        self.wallet_info = info

        return self
예제 #11
0
def migrate_from(
    old_root: Path, new_root: Path, manifest: List[str], do_not_migrate_keys: List[str]
):
    """
    Copy all the files in "manifest" to the new config directory.
    """
    if old_root == new_root:
        print(f"same as new path, exiting")
        return 1
    if not old_root.is_dir():
        print(f"{old_root} not found")
        return 0
    print(f"\n{old_root} found")
    print(f"Copying files from {old_root} to {new_root}\n")
    not_found = []
    for f in manifest:
        old_path = old_root / f
        new_path = new_root / f
        if old_path.is_file():
            print(f"{new_path}")
            mkdir(new_path.parent)
            shutil.copy(old_path, new_path)
        else:
            not_found.append(f)
            print(f"{old_path} not found, skipping")
    # update config yaml with new keys
    config: Dict = load_config(new_root, "config.yaml")
    config_str: str = initial_config_file("config.yaml")
    default_config: Dict = yaml.safe_load(config_str)
    flattened_keys = unflatten_properties({k: "" for k in do_not_migrate_keys})
    dict_add_new_default(config, default_config, flattened_keys)

    save_config(new_root, "config.yaml", config)

    # migrate plots
    # for now, we simply leave them where they are
    # and make what may have been relative paths absolute
    if "config/trusted.key" in not_found or "config/trusted.key" in not_found:
        initialize_ssl(new_root)

    plots_config: Dict = load_config(new_root, "plots.yaml")

    plot_root = (
        load_config(new_root, "config.yaml").get("harvester", {}).get("plot_root", ".")
    )

    old_plots_root: Path = path_from_root(old_root, plot_root)
    new_plots_root: Path = path_from_root(new_root, plot_root)

    old_plot_paths = plots_config.get("plots", {})
    if len(old_plot_paths) == 0:
        print("no plots found, no plots migrated")
        return 1

    print("\nmigrating plots.yaml")

    new_plot_paths: Dict = {}
    for path, values in old_plot_paths.items():
        old_path_full = path_from_root(old_plots_root, path)
        new_path_relative = make_path_relative(old_path_full, new_plots_root)
        print(f"rewriting {path}\n as {new_path_relative}")
        new_plot_paths[str(new_path_relative)] = values
    plots_config_new: Dict = {"plots": new_plot_paths}
    save_config(new_root, "plots.yaml", plots_config_new)
    print("\nUpdated plots.yaml to point to where your existing plots are.")
    print(
        "\nYour plots have not been moved so be careful deleting old preferences folders."
    )

    print("\nmigrating keys.yaml")
    keys_config = load_config(new_root, "keys.yaml")

    wallet_sk = ExtendedPrivateKey.from_bytes(bytes.fromhex(keys_config["wallet_sk"]))
    wallet_target = create_puzzlehash_for_pk(
        BLSPublicKey(bytes(wallet_sk.public_child(0).get_public_key()))
    )
    if (
        wallet_target.hex() != keys_config["wallet_target"]
        or wallet_target.hex() != keys_config["pool_target"]
    ):
        keys_config["wallet_target"] = wallet_target.hex()
        keys_config["pool_target"] = wallet_target.hex()
        print(f"updating wallet target and pool target to {wallet_target.hex()}")
        save_config(new_root, "keys.yaml", keys_config)

    print("\nIf you want to move your plot files, you should also modify")
    print(f"{config_path_for_filename(new_root, 'plots.yaml')}")
    return 1