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))
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
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
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
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)
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
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)
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)
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)
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
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