Esempio n. 1
0
 async def process_host_command(self, stream, show_screen):
     cmd, stream = self.parse_stream(stream)
     if cmd == SIGN_PSBT:
         res = await self.sign_psbt(stream, show_screen)
         if res is not None:
             obj = {
                 "title": "Transaction is signed!",
                 "message": "Scan it with your wallet"
             }
             return res, obj
     if cmd == SIGN_BCUR:
         data = stream.read().split(b"/")[-1].decode()
         b64_psbt = b2a_base64(bcur_decode(data)).strip()
         res = await self.sign_psbt(BytesIO(b64_psbt), show_screen)
         if res is not None:
             data, hsh = bcur_encode(a2b_base64(res.read()))
             bcur_res = b"UR:BYTES/" + hsh.encode().upper(
             ) + "/" + data.encode().upper()
             obj = {
                 "title": "Transaction is signed!",
                 "message": "Scan it with your wallet"
             }
             return BytesIO(bcur_res), obj
     elif cmd == ADD_WALLET:
         # read content, it's small
         desc = stream.read().decode()
         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, idx)
         await show_screen(WalletScreen(w, self.network, idx))
     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 = 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")
Esempio n. 2
0
 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")