def parse_transaction(b64_tx, success_callback=None, error_callback=None): # we will go to main afterwards show_main() try: raw = a2b_base64(b64_tx) tx = psbt.PSBT.parse(raw) except: gui.error("Failed at transaction parsing") if error_callback is not None: error_callback("invalid argument") return # blue wallet trick - if the fingerprint is 0 we use our fingerprint for scope in [tx.inputs, tx.outputs]: for el in scope: for der in el.bip32_derivations: if el.bip32_derivations[ der].fingerprint == b'\x00\x00\x00\x00': el.bip32_derivations[ der].fingerprint = keystore.fingerprint try: data = keystore.check_psbt(tx) except Exception as e: gui.error("Problem with the transaction: %r" % e) if error_callback is not None: error_callback("invalid argument") return title = "Spending %u\nfrom %s" % (data["spending"], data["wallet"].name) popups.prompt_tx(title, data, ok=cb_with_args(sign_psbt, wallet=data["wallet"], tx=tx, success_callback=success_callback), cancel=cb_with_args(error_callback, "user cancel"))
def parse_transaction(b64_tx, success_callback=None, error_callback=None): # we will go to main afterwards show_main() try: raw = a2b_base64(b64_tx) tx = psbt.PSBT.parse(raw) except: gui.error("Failed at transaction parsing") if error_callback is not None: error_callback("invalid argument") return # blue wallet trick - if the fingerprint is 0 we use our fingerprint for scope in [tx.inputs, tx.outputs]: for el in scope: for der in el.bip32_derivations: if el.bip32_derivations[der].fingerprint == b'\x00\x00\x00\x00': el.bip32_derivations[der].fingerprint = keystore.fingerprint try: data = keystore.check_psbt(tx) except Exception as e: gui.error("Problem with the transaction: %r" % e) if error_callback is not None: error_callback("invalid argument") return # check for address gap limit gap_limit = False w = data["wallet"] wallet_key = b"\xfc\xca\x01" + data["wallet"].fingerprint for el in tx.inputs + tx.outputs: if el.bip32_derivations: # full PSBT for der in el.bip32_derivations: drv = el.bip32_derivations[der].derivation if drv[-1] > w.gap_limit + (w.last_chg_idx if drv[-2] else w.last_rcv_idx): gap_limit = True elif wallet_key in el.unknown: # compressed PSBT idxs = el.unknown[wallet_key] chg = int.from_bytes(idxs[0:4], 'little') idx = int.from_bytes(idxs[4:8], 'little') if idx > w.gap_limit + (w.last_chg_idx if chg else w.last_rcv_idx): gap_limit = True if gap_limit: data["warning"] = ("#ff0000 Possible gap limit exceeded with some#\n" "#ff0000 addresses. Your funds may get locked. #\n " "#ff0000 Proceed at your own risk!#") title = "Spending %u\nfrom %s" % (data["spending"], data["wallet"].name) popups.prompt_tx(title, data, ok=cb_with_args(sign_psbt, wallet=data["wallet"], tx=tx, success_callback=success_callback), cancel=cb_with_args(error_callback, "user cancel") )
def parse_new_wallet(s): show_main() gui.update(30) # wallet format: # name&descriptor arr = s.split("&") if len(arr) != 2: gui.error("Invalid wallet format") return w = keystore.check_new_wallet(*arr) keys_str = [] for key in w.keys: k = ("%r" % key).replace("]", "]\n") if keystore.owns_key(key): keys_str.append("#7ED321 My key: # %s" % k) else: keys_str.append("#F5A623 External key: # %s" % k) keys = "\n\n".join(keys_str) if w.script_type not in SUPPORTED_SCRIPTS.keys(): raise ValueError("Script type \"%s\" is not supported" % w.script_type) sc = w.script_type msg = "Policy: %s\nScript: %s\n%s\n\n%s" % (w.policy, SUPPORTED_SCRIPTS[w.script_type], sc, keys) scr = popups.prompt("Add wallet \"%s\"?" % arr[0], msg, ok=cb_with_args(new_wallet_confirm, name=arr[0], descriptor=arr[1])) scr.message.set_recolor(True)
def settings_menu(): gui.create_menu(buttons=[ ("Show recovery phrase", show_mnemonic), ("Save key to memory", save_entropy), ("Delete key from memory", delete_entropy), ("Security settings", cb_with_args(popups.show_settings, {"usb": USB_ENABLED, "developer": DEV_ENABLED}, save_settings)), ], cb_back=show_main,title="Careful. Think twice.")
def __init__(self, title, message, note=None): super().__init__() self.title = add_label(title, scr=self, style="title") obj = self.title if note is not None: self.note = add_label(note, scr=self, style="hint") self.note.align(self.title, lv.ALIGN.OUT_BOTTOM_MID, 0, 5) obj = self.note self.page = lv.page(self) self.page.set_size(480, 600) self.message = add_label(message, scr=self.page) self.page.align(obj, lv.ALIGN.OUT_BOTTOM_MID, 0, 0) (self.close_button, self.again_button) = add_button_pair( lv.SYMBOL.LEFT + " Back", on_release(cb_with_args(self.set_value, False)), "Roll again", on_release(cb_with_args(self.set_value, True)), scr=self, )
def confirm_new_wallet(s): show_main() gui.update(30) # wallet format: # name&descriptor arr = s.split("&") if len(arr) != 2: gui.error("Invalid wallet format") return try: keystore.check_new_wallet(*arr) except Exception as e: gui.error("%r" % e) return popups.prompt("Add wallet \"%s\"?" % arr[0], arr[1], ok=cb_with_args(new_wallet_confirm, name=arr[0], descriptor=arr[1]))
def __init__(self, title, message, note=None): super().__init__() self.title = add_label(title, scr=self, style="title") obj = self.title if note is not None: self.note = add_label(note, scr=self, style="hint") self.note.align(self.title, lv.ALIGN.OUT_BOTTOM_MID, 0, 5) obj = self.note self.page = lv.page(self) self.page.set_size(480, 600) self.message = add_label(message, scr=self.page) self.page.align(obj, lv.ALIGN.OUT_BOTTOM_MID, 0, -10) self.pips_1 = add_button("1", on_release( cb_with_args(self.set_value, DICE_ROLLED_1)), scr=self) self.pips_1.set_width(130) self.pips_1.align(self.page, lv.ALIGN.OUT_LEFT_MID, 20, 20) self.pips_1.set_x(100) self.pips_2 = add_button("2", on_release( cb_with_args(self.set_value, DICE_ROLLED_2)), scr=self) self.pips_2.set_width(130) self.pips_2.align(self.page, lv.ALIGN.OUT_RIGHT_MID, 20, 20) self.pips_2.set_x(HOR_RES - 230) self.pips_3 = add_button("3", on_release( cb_with_args(self.set_value, DICE_ROLLED_3)), scr=self) self.pips_3.set_width(130) self.pips_3.align(self.page, lv.ALIGN.OUT_LEFT_MID, -20, 110) self.pips_3.set_x(100) self.pips_4 = add_button(u"4", on_release( cb_with_args(self.set_value, DICE_ROLLED_4)), scr=self) self.pips_4.set_width(130) self.pips_4.align(self.page, lv.ALIGN.OUT_RIGHT_MID, 20, 110) self.pips_4.set_x(HOR_RES - 230) self.pips_5 = add_button("5", on_release( cb_with_args(self.set_value, DICE_ROLLED_5)), scr=self) self.pips_5.set_width(130) self.pips_5.align(self.page, lv.ALIGN.OUT_LEFT_MID, -20, 200) self.pips_5.set_x(100) self.pips_6 = add_button("6", on_release( cb_with_args(self.set_value, DICE_ROLLED_6)), scr=self) self.pips_6.set_width(130) self.pips_6.align(self.page, lv.ALIGN.OUT_RIGHT_MID, 20, 200) self.pips_6.set_x(HOR_RES - 230) (self.close_button, self.again_button) = add_button_pair( lv.SYMBOL.LEFT + " Back", on_release(cb_with_args(self.set_value, BACK)), "TODO: Use this seed", on_release(cb_with_args(self.set_value, USE_SEED)), scr=self, )