def serialize_handler(self): self.btnSerialize.configure(state="disabled") Logger.Clear() Logger.Write("Attempting to serialize JSON transaction...") try: self.serialize_command() except: pass self.colorizeSerialHex(self.entryTxSerial) self.btnSerialize.update() self.btnSerialize.configure(state="normal") Logger.Write("READY.")
def on_click_rawtx(self, *args): idx = self.lst_assets.index(self.lst_assets.curselection()) Logger.Clear() Logger.Write("Retrieving transaction from block %d..."%self.HistItems[idx]["block_num"]) try: trx = getTransactionFromHistoryItem(self.HistItems[idx]) self.tx_json_tkvar.set(json.dumps(trx)) Logger.Write("Transaction JSON is in 'Raw Transactions' tab.") except Exception as e: Logger.Write("Error occurred: %s"%str(e)) pass Logger.Write("READY.")
def address_confirm_handler(self): path = self.textvariable_path.get() Logger.Write("Confirming public key for path %s..."%path) try: address = self.lookup_command([path], False)[0] self.textvariable_key.set(address) Logger.Write("I retrieve key: %s" % address) Logger.Write("Please confirm that this matches the key shown on device...") self.lookup_command([path], True) except: self.textvariable_key.set("") Logger.Write("Could not confirm public key on device. Do not trust unconfirmed keys.")
def sign_handler(self): self.btnSign.configure(state="disabled") self.btnBroadcast.configure(state="disabled") Logger.Clear() Logger.Write("Asking Nano to sign serialized transaction...") try: self.sign_command() Logger.Write("Received signature from Nano. Click \"Broadcast\" when ready to transmit.") except: pass self.btnSign.update() # Eat any clicks that occured while disabled. self.btnSign.configure(state="normal") Logger.Write("READY.")
def button_handler(self): self.button.configure(state="disabled") Logger.Clear() try: account_name = self.textvariable.get() if len(account_name) == 0: Logger.Write("Please provide an account name!") return Logger.Write("Refreshing account balances and history for '%s'..." % account_name) self.button_command() finally: self.button.update() # Eat any clicks that occured while disabled self.button.configure(state="normal") # Return to enabled state Logger.Write("READY.")
def getPublicKeyListFromNano(bip32_paths, confirm_on_device=False): # Captures all exceptions and does not re-raise. Will return an empty or partial # list if we don't suceed in retrieving all keys. To determine success or # (partial) failure, compare length of return list to length of key list. Addresses = [] try: dongle = getDongle(True) except: Logger.Write("Ledger Nano not found! Is it plugged in and unlocked?") return [] for path in bip32_paths: donglePath = parse_bip32_path(path) apdu = binascii.unhexlify("B502" + ("01" if confirm_on_device else "00") + "00" + "{:02x}".format(len(donglePath) + 1) + "{:02x}".format(int(len(donglePath) / 4))) + donglePath try: result = dongle.exchange(apdu) except CommException as e: dongle.close() if e.sw == 0x6e00: Logger.Write( "BitShares App not running on Nano. Please check.") elif e.sw == 0x6985: Logger.Write( "Warning! Address not confirmed by user - may not be valid!" ) raise else: Logger.Write( "Warning! Address not confirmed by user, or other error.") return Addresses except Exception: dongle.close() Logger.Write("An unknown error occured. Was device unplugged?") return Addresses offset = 1 + result[0] address = bytes(result[offset + 1:offset + 1 + result[offset]]).decode("utf-8") ## TODO: Also extract pubkey and assert that it produces same address Addresses.append(address) dongle.close() return Addresses
def appendTransferOpToTx(builder, from_name, to_name, amount, symbol): ## TODO: Cleanup exception catching for better user feedback try: account = Account(from_name, blockchain_instance=blockchain) to = Account(to_name, blockchain_instance=blockchain) amountAsset = Amount(amount, symbol, blockchain_instance=blockchain) except NumRetriesReached: Logger.Write( "ERROR: Can't reach API node: 'NumRetries' reached. Check network connection." ) raise except AssetDoesNotExistsException as e: Logger.Write("ERROR: Asset or token '%s' not known." % str(e)) raise except AccountDoesNotExistsException as e: Logger.Write("ERROR: Account '%s' not known." % str(e)) raise except Exception as e: Logger.Write("Unknown problem constructing Transfer operation: %s" % str(e)) raise memoObj = Memo(from_account=account, to_account=to, blockchain_instance=blockchain) memo_text = "" #"Signed by BitShares App on Ledger Nano S!" op = operations.Transfer( **{ "fee": { "amount": 0, "asset_id": "1.3.0" }, "from": account["id"], "to": to["id"], "amount": { "amount": int(amountAsset), "asset_id": amountAsset.asset["id"] }, "memo": memoObj.encrypt(memo_text), }) builder.appendOps(op) return builder
def btn_copy_handler(self): address = self.textvariable_key.get() self.parent.clipboard_clear() self.parent.clipboard_append(address) Logger.Clear() Logger.Write(("Public key %s copied to clipboard.\n" + "Have you confirmed this key on your hardware device? See Public Keys tab. " + "Do not add to a live account if you have not confirmed on device.") % address)
def getSignatureFromNano(serial_tx_bytes, bip32_path): donglePath = parse_bip32_path(bip32_path) pathSize = int(len(donglePath) / 4) try: dongle = getDongle(True) except: Logger.Write("Ledger Nano not found! Is it plugged in and unlocked?") raise Logger.Write("Please review and confirm transaction on Ledger Nano S...") offset = 0 first = True signSize = len(serial_tx_bytes) while offset != signSize: if signSize - offset > 200: chunk = serial_tx_bytes[offset:offset + 200] else: chunk = serial_tx_bytes[offset:] if first: totalSize = len(donglePath) + 1 + len(chunk) apdu = binascii.unhexlify("B5040000" + "{:02x}".format( totalSize) + "{:02x}".format(pathSize)) + donglePath + chunk first = False else: totalSize = len(chunk) apdu = binascii.unhexlify("B5048000" + "{:02x}".format(totalSize)) + chunk offset += len(chunk) try: result = dongle.exchange(apdu) except CommException as e: dongle.close() if e.sw == 0x6e00: Logger.Write( "BitShares App not running on Nano. Please check.") else: Logger.Write("User declined - transaction not signed.") raise except: dongle.close() Logger.Write("An unknown error occured. Was device unplugged?") raise dongle.close() return result
def broadcastTxWithProvidedSignature(tx_json, sig_bytes): signed_tx = blockchain.new_tx(json.loads(str(tx_json))) signed_tx["signatures"].extend([binascii.hexlify(sig_bytes).decode()]) Logger.Write("Broadcasting transaction...", echo=True) try: print(blockchain.broadcast(tx=signed_tx)) Logger.Write("Success! Transaction has been sent.", echo=True) except RPCError as e: Logger.Write("Could not broadcast transaction!", echo=True) Logger.Write(str(e)) raise except NumRetriesReached: Logger.Write( "ERROR: Could not broadcast transaction: 'NumRetries' reached. Check network connection." ) raise
def on_click_confirm_addr(self): self.button_confirm_addr.configure(state="disabled") Logger.Clear() try: self.address_confirm_handler() finally: self.button_confirm_addr.update() # Eat any clicks that occured while disabled self.button_confirm_addr.configure(state="normal") # Return to enabled state Logger.Write("READY.")
def broadcast_handler(self): self.btnBroadcast.configure(state="disabled") Logger.Clear() try: self.broadcast_command() except: pass self.btnBroadcast.update() # Eat any clicks queued while disabled self.btnBroadcast.configure(state="normal") Logger.Write("READY.")
def account_info_refresh(): try: spending_account = Account(var_from_account_name.get(), blockchain_instance=blockchain) balances = spending_account.balances history = spending_account.history(limit=40) account_id = spending_account.identifier except AccountDoesNotExistsException: Logger.Write("ERROR: Specified account does not exist on BitShares network.") balances = [] history = [] account_id = "" frameAssets.setBalances(balances) frameHistory.setHistory(history, account_id)
def sendTransfer(from_name, to_name, amount, symbol): try: var_tx_json.set("") var_tx_serial.set("") var_tx_signature.set("") Logger.Write("Preparing to send %f %s from \"%s\" to \"%s\"..." % (amount, symbol, from_name, to_name)) tx_json = generateTransferTxJSON(from_name, to_name, amount, symbol) var_tx_json.set(tx_json) serializeTxJSON() signTxHexBytes() broadcastSignedTx() except Exception as e: pass
def serializeTxJSON(): # var_tx_json ->(turn crank)-> var_tx_serial: try: signData = getSerializedTxBytes(var_tx_json.get()) var_tx_serial.set(binascii.hexlify(signData).decode()) except json.decoder.JSONDecodeError as e: var_tx_serial.set("<<TX COULD NOT BE SERIALIZED>>") Logger.Write("JSON Decode Error: " + str(e)) raise except: var_tx_serial.set("<<TX COULD NOT BE SERIALIZED>>") raise finally: pass
def button_send_handler(self): self.button_send.configure(state="disabled") Logger.Clear() try: account_name = self.to_account_name.get() asset_symbol = self.box_asset_to_send.get() amount_str = self.box_amount_to_send.get() if len(account_name) == 0: Logger.Write("Please provide an account name to send to!") return if len(asset_symbol) == 0: Logger.Write("Please specify asset to send!") return if len(amount_str) == 0: Logger.Write("Please specify amount to send!") return self.send_command(account_name, float(amount_str), asset_symbol) except ValueError as e: Logger.Write("ValueError: %s"%str(e)) finally: self.button_send.update() # Eat any clicks that occured while disabled self.button_send.configure(state="normal") # Return to enabled state Logger.Write("READY.")
def lookup_handler(self): self.clear_keys() # Owner Keys: Logger.Write("Querying Owner key paths from Nano...") self.ownerKeys = self.lookup_command(self.ownerPaths, False) self.refresh_keylistbox(self.listOwnerKeys, self.ownerPaths, self.ownerKeys) self.listOwnerKeys.update() if len(self.ownerKeys) < len(self.ownerPaths): return # Active Keys: Logger.Write("Querying Active key paths from Nano...") self.activeKeys = self.lookup_command(self.activePaths, False) self.refresh_keylistbox(self.listActiveKeys, self.activePaths, self.activeKeys) self.listActiveKeys.update() if len(self.activeKeys) < len(self.activePaths): return # Memo Keys: Logger.Write("Querying Memo key paths from Nano...") self.memoKeys = self.lookup_command(self.memoPaths, False) self.refresh_keylistbox(self.listMemoKeys, self.memoPaths, self.memoKeys) self.listMemoKeys.update()
def getHeadBlockBlankTx(): tx_head = blockchain.new_tx() # Pull recent TaPoS try: dummy = tx_head[ 'ref_block_num'] # Somehow this triggers tx_head to populate 'expiration'... (??) except NumRetriesReached: Logger.Write( "ERROR: Can't reach API node: 'NumRetries' reached. Check network connection." ) raise expiration = datetime.strptime(tx_head['expiration'], "%Y-%m-%dT%H:%M:%S") + timedelta(minutes=10) tx_head['expiration'] = expiration.strftime( "%Y-%m-%dT%H:%M:%S%Z" ) # Longer expiration to accomodate device interaction return tx_head
def log_print_startup_message(): #Logger.Write("**** COMMODORE 64 BASIC V2 64K RAM SYSTEM 38911 BASIC BYTES FREE ****", echo=False) #Logger.Clear() Logger.Write("READY.", echo=False)
tabbed_Active.add(form_about, text = 'About') tabbed_Active.pack(padx=(1,8), expand=True, fill="both") ## ## Logging window ## form_activity = ActivityMessageFrame(frame_bottom) form_activity.pack(side="bottom", expand=True, fill="both", padx=8, pady=(2,8)) Logger.SetMessageWidget(form_activity.messages) ## ## ## Startup: ## Logger.Write("Checking if Nano present and querrying public key...") tmp_keys = getPublicKeyListFromNano([var_bip32_path.get()], False) if len(tmp_keys) == 1: var_bip32_key.set(tmp_keys[0]) Logger.Write("Initializing: Looking for BitShares network...") global blockchain blockchain = initBlockchainObject(args.node) var_api_node_url.set(blockchain.rpc.connection.url) var_from_account_name.set(default_sender.strip().lower()) if is_valid_account_name(var_from_account_name.get()): Logger.Write("Getting account info for '%s'..."%var_from_account_name.get()) account_info_refresh() log_print_startup_message() # start the GUI gui.mainloop()