async def process_host_command(self, stream, show_screen): platform.delete_recursively(self.tempdir) cmd, stream = self.parse_stream(stream) if cmd == SIGN_PSBT: encoding = BASE64_STREAM if stream.read(5) == b"psbt\xff": encoding = RAW_STREAM stream.seek(-5, 1) res = await self.sign_psbt(stream, show_screen, encoding) if res is not None: obj = { "title": "Transaction is signed!", "message": "Scan it with your wallet", } return res, obj return if cmd == SIGN_BCUR: # move to the end of UR:BYTES/ stream.seek(9, 1) # move to the end of hash if it's there d = stream.read(70) if b"/" in d: pos = d.index(b"/") stream.seek(pos - len(d) + 1, 1) else: stream.seek(-len(d), 1) with open(self.tempdir + "/raw", "wb") as f: bcur_decode_stream(stream, f) gc.collect() with open(self.tempdir + "/raw", "rb") as f: res = await self.sign_psbt(f, show_screen, encoding=RAW_STREAM) platform.delete_recursively(self.tempdir) if res is not None: data, hsh = bcur_encode(res.read(), upper=True) bcur_res = (b"UR:BYTES/" + hsh + "/" + data) obj = { "title": "Transaction is signed!", "message": "Scan it with your wallet", } gc.collect() return BytesIO(bcur_res), obj return elif cmd == ADD_WALLET: # read content, it's small desc = stream.read().decode().strip() w = self.parse_wallet(desc) res = await self.confirm_new_wallet(w, show_screen) if res: self.add_wallet(w) return elif cmd == VERIFY_ADDRESS: data = stream.read().decode().replace("bitcoin:", "") # should be of the form addr?index=N or similar if "index=" not in data or "?" not in data: raise WalletError("Can't verify address with unknown index") addr, rest = data.split("?") args = rest.split("&") idx = None for arg in args: if arg.startswith("index="): idx = int(arg[6:]) break w, _ = self.find_wallet_from_address(addr, index=idx) await show_screen(WalletScreen(w, self.network, idx)) return elif cmd == DERIVE_ADDRESS: arr = stream.read().split(b" ") redeem_script = None if len(arr) == 2: script_type, path = arr elif len(arr) == 3: script_type, path, redeem_script = arr else: raise WalletError("Too many arguments") paths = [p.decode() for p in path.split(b",")] if len(paths) == 0: raise WalletError("Invalid path argument") res = await self.showaddr(paths, script_type, redeem_script, show_screen=show_screen) return BytesIO(res), {} else: raise WalletError("Unknown command")
async def process_host_command(self, stream, show_screen): platform.delete_recursively(self.tempdir) cmd, stream = self.parse_stream(stream) if cmd == SIGN_PSBT: magic = stream.read(len(self.PSBTViewClass.MAGIC)) if magic == self.PSBTViewClass.MAGIC: encoding = RAW_STREAM elif magic.startswith(self.B64PSBT_PREFIX): encoding = BASE64_STREAM else: raise WalletError("Invalid PSBT magic!") stream.seek(-len(magic), 1) res = await self.sign_psbt(stream, show_screen, encoding) if res is not None: obj = { "title": "Transaction is signed!", "message": "Scan it with your wallet", } return res, obj return if cmd == SIGN_BCUR: # move to the end of UR:BYTES/ stream.seek(9, 1) # move to the end of hash if it's there d = stream.read(70) if b"/" in d: pos = d.index(b"/") stream.seek(pos-len(d)+1, 1) else: stream.seek(-len(d), 1) with open(self.tempdir+"/raw", "wb") as f: bcur_decode_stream(stream, f) gc.collect() with open(self.tempdir+"/raw", "rb") as f: res = await self.sign_psbt(f, show_screen, encoding=RAW_STREAM) if res is not None: # bcur-encode to temp data file with open(self.tempdir+"/bcur_data", "wb") as fout: if isinstance(res, str): with open(res, "rb") as fin: l, hsh = bcur_encode_stream(fin, fout, upper=True) else: l, hsh = bcur_encode_stream(res, fout, upper=True) # add prefix and hash with open(self.tempdir+"/bcur_full", "wb") as fout: fout.write(b"UR:BYTES/") fout.write(hsh) fout.write(b"/") with open(self.tempdir+"/bcur_data", "rb") as fin: b = bytearray(100) while True: l = fin.readinto(b) if l == 0: break fout.write(b, l) obj = { "title": "Transaction is signed!", "message": "Scan it with your wallet", } gc.collect() return self.tempdir+"/bcur_full", obj return elif cmd == LIST_WALLETS: wnames = json.dumps([w.name for w in self.wallets]) return BytesIO(wnames.encode()), {} elif cmd == ADD_WALLET: # read content, it's small desc = stream.read().decode().strip() w = self.parse_wallet(desc) res = await self.confirm_new_wallet(w, show_screen) if res: self.add_wallet(w) return elif cmd == VERIFY_ADDRESS: data = stream.read().decode().replace("bitcoin:", "") # should be of the form addr?index=N or similar if "index=" not in data or "?" not in data: raise WalletError("Can't verify address with unknown index") addr, rest = data.split("?") args = rest.split("&") idx = None for arg in args: if arg.startswith("index="): idx = int(arg[6:]) break w, _ = self.find_wallet_from_address(addr, index=idx) await show_screen(WalletScreen(w, self.network, idx)) return elif cmd == DERIVE_ADDRESS: arr = stream.read().split(b" ") redeem_script = None if len(arr) == 2: script_type, path = arr elif len(arr) == 3: script_type, path, redeem_script = arr else: raise WalletError("Too many arguments") paths = [p.decode() for p in path.split(b",")] if len(paths) == 0: raise WalletError("Invalid path argument") res = await self.showaddr( paths, script_type, redeem_script, show_screen=show_screen ) return BytesIO(res), {} else: raise WalletError("Unknown command")