def load_wallets(self, network_name): self.network = NETWORKS[network_name] fingerprint = hexlify(self.fingerprint).decode() self.storage_path = "%s/%s/%s" % (self.storage_root, network_name, fingerprint) # FIXME: refactor with for loop try: # create network folder d = "/".join(self.storage_path.split("/")[:-1]) os.mkdir(d) except: pass try: os.mkdir(self.storage_path) except: pass files = [ f[0] for f in os.ilistdir(self.storage_path) if f[0].endswith("_wallet.json") ] self._wallets = [] for fname in files: fname = self.storage_path + "/" + fname with open(fname) as f: content = f.read() with open(fname.replace(".json", ".sig"), "rb") as f: sig = ec.Signature.parse(f.read()) if self.idkey.verify(sig, hashes.sha256(content)): self._wallets.append( Wallet.parse(content, self.network, fname=fname)) else: raise RuntimeError("Invalid signature for wallet")
def create_wallet(self, name, descriptor): for w in self._wallets: if w.name == name: raise ValueError("Wallet '%s' already exists", name) fname = self.get_wallet_fname() w = Wallet(name, descriptor, self.network, fname=fname) data = w.save(fname) h = hashes.sha256(data) sig = self.idkey.sign(h) with open(fname.replace(".json", ".sig"), "wb") as f: f.write(sig.serialize()) self._wallets.append(w)
def update_wallet_indexes(self, w, tx): """ Update receive and change indexes if bigger """ assert w.owns(tx.inputs[0]) fname = w.fname max_rcv_idx = w.last_rcv_idx max_chg_idx = w.last_chg_idx for inp in tx.inputs: for pub in inp.bip32_derivations: if inp.bip32_derivations[pub].derivation[-2]: chg_idx = inp.bip32_derivations[pub].derivation[-1] max_chg_idx = max(max_chg_idx, chg_idx) else: rcv_idx = inp.bip32_derivations[pub].derivation[-1] max_rcv_idx = max(max_rcv_idx, rcv_idx) for out in tx.outputs: for pub in out.bip32_derivations: if out.bip32_derivations[pub].derivation[-2]: chg_idx = out.bip32_derivations[pub].derivation[-1] max_chg_idx = max(max_chg_idx, chg_idx) else: rcv_idx = out.bip32_derivations[pub].derivation[-1] max_rcv_idx = max(max_rcv_idx, rcv_idx) if w.last_rcv_idx == max_rcv_idx and w.last_chg_idx == max_chg_idx: return w.last_rcv_idx = max_rcv_idx w.last_chg_idx = max_chg_idx data = w.save(fname) h = hashes.sha256(data) sig = self.idkey.sign(h) with open(fname.replace(".json", ".sig"), "wb") as f: f.write(sig.serialize()) # update keystore for i, w_tmp in enumerate(self.wallets): if w_tmp.name == w.name: self._wallets[i] = w break