def CreateTxDetailWithTx(tx : Transaction, on_label = None, on_appear = None, asModalNav = False) -> ObjCInstance: parent = gui.ElectrumGui.gui wallet = parent.wallet import time tx_hash, status_, label_, can_broadcast, amount, fee, height, conf, timestamp, exp_n = wallet.get_tx_info(tx) size = tx.estimated_size() status_str = "" status = status_ img = None if conf is not None: if tx_hash is not None and height is not None and timestamp is not None: status, status_str = wallet.get_tx_status(tx_hash, height, conf, timestamp) if status is not None and status >= 0 and status < len(StatusImages): img = StatusImages[status] else: conf = 0 timestamp = time.time() if timestamp is None else timestamp doFX = False #fx() and fx().is_enabled() ccy = None #fx().get_currency() if doFX else None fiat_amount_str = None #str(self.fiat.text) if doFX else None #HistoryEntry = namedtuple("HistoryEntry", "extra_data tx_hash status_str label v_str balance_str date ts conf status value fiat_amount fiat_balance fiat_amount_str fiat_balance_str ccy status_image") entry = HistoryEntry(tx,tx_hash,status_str,label_,parent.format_amount(amount) if amount is not None else _("Transaction unrelated to your wallet"), "",timestamp_to_datetime(time.time() if conf <= 0 else timestamp), timestamp,conf,status,amount,None,None,fiat_amount_str,None,ccy,img) return CreateTxDetailWithEntry(entry, on_label = on_label, on_appear = on_appear, asModalNav = asModalNav)
def showTransaction_desc_(self, txraw, desc) -> None: tx = Transaction(txraw, sign_schnorr=parent().prefs_use_schnorr) tx.deserialize() tx_hash, status_, label_, can_broadcast, amount, fee, height, conf, timestamp, exp_n = wallet( ).get_tx_info(tx) #print("send: status_",status_,"label_",label_,"amount",amount,"conf",conf) size = tx.estimated_size() conf = 0 if conf is None else conf timestamp = time.time() if timestamp is None else timestamp status, status_str = ( status_, _("Unsigned") ) #wallet().get_tx_status(tx_hash, height, conf, timestamp) doFX = fx() and fx().is_enabled() ccy = fx().get_currency() if doFX else None fiat_amount_str = str(self.fiat.text) if doFX else None #HistoryEntry = namedtuple("HistoryEntry", "tx tx_hash status_str label v_str balance_str date ts conf status value fiat_amount fiat_balance fiat_amount_str fiat_balance_str ccy status_image") entry = HistoryEntry( tx, tx_hash, status_str, str(desc), self.amt.text, "", timestamp_to_datetime(time.time() if conf <= 0 else timestamp), timestamp, conf, status, amount, None, None, fiat_amount_str, None, ccy, None) def newLabel(l): self.descDel.text = l self.navigationController.pushViewController_animated_( txdetail.CreateTxDetailWithEntry(entry, on_label=newLabel), True)
def get_card(self, tx_hash, height, conf, timestamp, value, balance): status, status_str = self.app.wallet.get_tx_status( tx_hash, height, conf, timestamp) icon = "atlas://gui/kivy/theming/light/" + TX_ICONS[status] label = self.app.wallet.get_label(tx_hash) if tx_hash else _( 'Pruned transaction outputs') date = timestamp_to_datetime(timestamp) ri = self.cards.get(tx_hash) if ri is None: ri = Factory.HistoryItem() ri.screen = self ri.tx_hash = tx_hash self.cards[tx_hash] = ri ri.icon = icon ri.date = status_str ri.message = label ri.value = value or 0 ri.amount = self.app.format_amount(value, True) if value is not None else '--' ri.confirmations = conf if self.app.fiat_unit and date: rate = self.app.fx.history_rate(date) if rate: s = self.app.fx.value_str(value, rate) ri.quote_text = '' if s is None else s + ' ' + self.app.fiat_unit return ri
def on_update(self): self.wallet = self.parent.wallet h = self.wallet.get_history(self.get_domain(), reverse=True) sels = self.selectedItems() current_tx = sels[0].data(0, Qt.UserRole) if sels else None del sels # make sure not to hold stale ref to C++ list of items which will be deleted in clear() call below self.clear() self.has_unknown_balances = False fx = self.parent.fx if fx: fx.history_used_spot = False for h_item in h: tx_hash, height, conf, timestamp, value, balance = h_item label = self.wallet.get_label(tx_hash) should_skip = run_hook("history_list_filter", self, h_item, label, multi=True) or [] if any(should_skip): # For implementation of fast plugin filters (such as CashShuffle # shuffle tx filtering), we short-circuit return. This is # faster than using the MyTreeWidget filter definted in .util continue if value is None or balance is None: # Workaround to the fact that sometimes the wallet doesn't # know the actual balance for history items while it's # downloading history, and we want to flag that situation # and redraw the GUI sometime later when it finishes updating. # This flag is checked in main_window.py, TxUpadteMgr class. self.has_unknown_balances = True status, status_str = self.wallet.get_tx_status(tx_hash, height, conf, timestamp) has_invoice = self.wallet.invoices.paid.get(tx_hash) icon = self._get_icon_for_status(status) v_str = self.parent.format_amount(value, True, whitespaces=True) balance_str = self.parent.format_amount(balance, whitespaces=True) entry = ['', tx_hash, status_str, label, v_str, balance_str] if fx and fx.show_history(): date = timestamp_to_datetime(time.time() if conf <= 0 else timestamp) for amount in [value, balance]: text = fx.historical_value_str(amount, date) entry.append(text) item = SortableTreeWidgetItem(entry) if icon: item.setIcon(0, icon) item.setToolTip(0, str(conf) + " confirmation" + ("s" if conf != 1 else "")) item.setData(0, SortableTreeWidgetItem.DataRole, (status, conf)) if has_invoice: item.setIcon(3, self.invoiceIcon) for i in range(len(entry)): if i>3: item.setTextAlignment(i, Qt.AlignRight | Qt.AlignVCenter) if i!=2: item.setFont(i, self.monospaceFont) if value and value < 0: item.setForeground(3, self.withdrawalBrush) item.setForeground(4, self.withdrawalBrush) item.setForeground(6, self.withdrawalBrush) item.setData(0, Qt.UserRole, tx_hash) self.addTopLevelItem(item, tx_hash) if current_tx == tx_hash: # Note that it's faster to setSelected once the item is in # the tree. Also note that doing setSelected() on the item # itself is much faster than doing setCurrentItem() # which must do a linear search in the tree (wastefully) item.setSelected(True)
def on_update(self): self.wallet = self.parent.wallet h = self.wallet.get_history(self.get_domain(), reverse=True) sels = self.selectedItems() current_tx = sels[0].data(0, Qt.UserRole) if sels else None del sels # make sure not to hold stale ref to C++ list of items which will be deleted in clear() call below self.clear() fx = self.parent.fx if fx: fx.history_used_spot = False for h_item in h: tx_hash, height, conf, timestamp, value, balance = h_item label = self.wallet.get_label(tx_hash) status, status_str = self.wallet.get_tx_status( tx_hash, height, conf, timestamp) has_invoice = self.wallet.invoices.paid.get(tx_hash) icon = self._get_icon_for_status(status) v_str = self.parent.format_amount(value, True, whitespaces=True) balance_str = self.parent.format_amount(balance, whitespaces=True) entry = ['', tx_hash, status_str, label, v_str, balance_str] if fx and fx.show_history(): date = timestamp_to_datetime( time.time() if conf <= 0 else timestamp) for amount in [value, balance]: text = fx.historical_value_str(amount, date) entry.append(text) item = SortableTreeWidgetItem(entry) if icon: item.setIcon(0, icon) item.setToolTip( 0, str(conf) + " confirmation" + ("s" if conf != 1 else "")) item.setData(0, SortableTreeWidgetItem.DataRole, (status, conf)) if has_invoice: item.setIcon(3, self.invoiceIcon) for i in range(len(entry)): if i > 3: item.setTextAlignment(i, Qt.AlignRight | Qt.AlignVCenter) if i != 2: item.setFont(i, self.monospaceFont) if value and value < 0: item.setForeground(3, self.withdrawalBrush) item.setForeground(4, self.withdrawalBrush) item.setData(0, Qt.UserRole, tx_hash) self.addTopLevelItem(item, tx_hash) if current_tx == tx_hash: # Note that it's faster to setSelected once the item is in # the tree. Also note that doing setSelected() on the item # itself is much faster than doing setCurrentItem() # which must do a linear search in the tree (wastefully) item.setSelected(True)
def on_update(self): self.wallet = self.parent.wallet h = self.wallet.get_history(self.get_domain()) item = self.currentItem() current_tx = item.data(0, Qt.UserRole) if item else None self.clear() fx = self.parent.fx if fx: fx.history_used_spot = False for h_item in h: tx_hash, height, conf, timestamp, value, balance = h_item status, status_str = self.wallet.get_tx_status( tx_hash, height, conf, timestamp) has_invoice = self.wallet.invoices.paid.get(tx_hash) if status not in self.statusIcons: self.statusIcons[status] = QIcon(":icons/" + TX_ICONS[status]) icon = self.statusIcons[status] v_str = self.parent.format_amount(value, True, whitespaces=True) balance_str = self.parent.format_amount(balance, whitespaces=True) label = self.wallet.get_label(tx_hash) entry = ['', tx_hash, status_str, label, v_str, balance_str] if fx and fx.show_history(): date = timestamp_to_datetime( time.time() if conf <= 0 else timestamp) for amount in [value, balance]: text = fx.historical_value_str(amount, date) entry.append(text) item = SortableTreeWidgetItem(entry) item.setIcon(0, icon) item.setToolTip( 0, str(conf) + " confirmation" + ("s" if conf != 1 else "")) item.setData(0, SortableTreeWidgetItem.DataRole, (status, conf)) if has_invoice: item.setIcon(3, self.invoiceIcon) for i in range(len(entry)): if i > 3: item.setTextAlignment(i, Qt.AlignRight) if i != 2: item.setFont(i, self.monospaceFont) if value and value < 0: item.setForeground(3, self.withdrawalBrush) item.setForeground(4, self.withdrawalBrush) item.setData(0, Qt.UserRole, tx_hash) self.insertTopLevelItem(0, item) if current_tx == tx_hash: self.setCurrentItem(item)
def tableView_cellForRowAtIndexPath_(self, tv, indexPath): #todo: - allow for label editing (popup menu?) identifier = "TxDetailInOutCell" cell = tv.dequeueReusableCellWithIdentifier_(identifier) parent = gui.ElectrumGui.gui wallet = parent.wallet def format_amount(amt): return parent.format_amount(amt, whitespaces = False) def fx(): return parent.daemon.fx if parent.daemon and parent.daemon.fx and parent.daemon.fx.show_history() else None base_unit = parent.base_unit() try: tx = utils.nspy_get(self) isInput = None x = None if tv.tag == self.tagin: isInput = True x = tx.inputs()[indexPath.row] elif tv.tag == self.tagout: isInput = False x = tx.get_outputs()[indexPath.row] else: raise ValueError("tv tag %d is neither input (%d) or output (%d) tag!"%(int(tv.tag),int(self.tagin),int(self.tagout))) cell.address.text = "" cell.addressType.text = "" cell.detail.text = "" addr = None if isInput: if x['type'] == 'coinbase': cell.addressType.text = "coinbase" cell.address.text = "coinbase" else: prevout_hash = x.get('prevout_hash') prevout_n = x.get('prevout_n') mytxt = "" mytxt += prevout_hash[0:8] + '...' mytxt += prevout_hash[-8:] + (":%-4d " % prevout_n) addr = x['address'] if isinstance(addr, PublicKey): addr = addr.toAddress() if addr is None: addr_text = _('unknown') else: addr_text = addr.to_ui_string() cell.address.text = addr_text if x.get('value') is not None: v_in = x['value'] mytxt += format_amount(v_in) + ' ' + base_unit if fx(): mytxt += ' (' + fx().historical_value_str(v_in,timestamp_to_datetime(self.ts)) + " " + fx().get_currency() + ')' cell.detail.text = mytxt.strip() else: addr, v = x cell.address.text = addr.to_ui_string() if v is not None: cell.detail.text = (format_amount(v) + " " + base_unit + ((' (' + fx().historical_value_str(v,timestamp_to_datetime(self.ts)) + " " + fx().get_currency() + ')') if fx() else '')).strip() typ = '' if isinstance(addr, Address): if wallet.is_mine(addr): if wallet.is_change(addr): typ = _("My Change Address") else: typ = _("My Receiving Address") else: typ = _("External Address") contact = contacts.Find(addr) if contact: typ += ', ' + _('Contact') + ": " + contact.name cell.addressType.text = typ cell.accessoryType = UITableViewCellAccessoryNone #UITableViewCellAccessoryDisclosureIndicator#UITableViewCellAccessoryDetailDisclosureButton#UITableViewCellAccessoryDetailButton # except Exception as e: print("exception in %s: %s"%(__class__.name,str(e))) cell.addressType.text = "" cell.address.text = "Not found" cell.detail.text = "" cell.accessoryType = UITableViewCellAccessoryNone return cell
def get_history(domain: list = None, statusImagesOverride: list = None, forceNoFX: bool = False) -> list: ''' For a given set of addresses (or None for all addresses), builds a list of HistoryEntry ''' sImages = StatusImages if not statusImagesOverride or len( statusImagesOverride) < len(StatusImages) else statusImagesOverride parent = gui.ElectrumGui.gui wallet = parent.wallet daemon = parent.daemon if wallet is None or daemon is None: utils.NSLog( "get_history: wallet and/or daemon was None, returning early") return list() h = wallet.get_history(domain) fx = daemon.fx if daemon.fx and daemon.fx.show_history() else None history = list() ccy = '' for h_item in h: tx_hash, height, conf, timestamp, value, balance = h_item status, status_str = wallet.get_tx_status(tx_hash, height, conf, timestamp) has_invoice = wallet.invoices.paid.get(tx_hash) v_str = parent.format_amount(value, True, whitespaces=True) balance_str = parent.format_amount(balance, whitespaces=True) label = wallet.get_label(tx_hash) date = timestamp_to_datetime(time.time() if conf <= 0 else timestamp) ts = timestamp if conf > 0 else time.time() fiat_amount = 0 fiat_balance = 0 fiat_amount_str = '' fiat_balance_str = '' if fx: fx.history_used_spot = False if not forceNoFX and fx: if not ccy: ccy = fx.get_currency() try: hdate = timestamp_to_datetime( time.time() if conf <= 0 else timestamp) hamount = fx.historical_value(value, hdate) htext = fx.historical_value_str(value, hdate) if hamount else '' fiat_amount = hamount if hamount else fiat_amount fiat_amount_str = htext if htext else fiat_amount_str hamount = fx.historical_value(balance, hdate) if balance else 0 htext = fx.historical_value_str(balance, hdate) if hamount else '' fiat_balance = hamount if hamount else fiat_balance fiat_balance_str = htext if htext else fiat_balance_str except: utils.NSLog( "Exception in get_history computing fiat amounts!\n%s", str(sys.exc_info()[1])) #import traceback #traceback.print_exc(file=sys.stderr) fiat_amount = fiat_balance = 0 fiat_amount_str = fiat_balance_str = '' if status >= 0 and status < len(sImages): img = sImages[status] else: img = None tx = wallet.transactions.get(tx_hash, None) if tx is not None: tx.deserialize() entry = HistoryEntry(tx, tx_hash, status_str, label, v_str, balance_str, date, ts, conf, status, value, fiat_amount, fiat_balance, fiat_amount_str, fiat_balance_str, ccy, img) history.append(entry) # appending is O(1) history.reverse() # finally, reverse the order to keep most recent first return history
def _build_history_entry(h_item, statusImagesOverride, forceNoFX): sImages = StatusImages if not statusImagesOverride or len( statusImagesOverride) < len(StatusImages) else statusImagesOverride parent = gui.ElectrumGui.gui wallet = parent.wallet daemon = parent.daemon if wallet is None or daemon is None: utils.NSLog( "buid_history_entry: wallet and/or daemon was None, returning early" ) return None fx = daemon.fx if daemon.fx and daemon.fx.show_history() else None ccy = '' tx_hash, height, conf, timestamp, value, balance = h_item status, status_str = wallet.get_tx_status(tx_hash, height, conf, timestamp) has_invoice = wallet.invoices.paid.get(tx_hash) v_str = parent.format_amount(value, True, whitespaces=True) balance_str = parent.format_amount(balance, whitespaces=True) label = wallet.get_label(tx_hash) date = timestamp_to_datetime(time.time() if conf <= 0 else timestamp) ts = timestamp if conf > 0 else time.time() fiat_amount = 0 fiat_balance = 0 fiat_amount_str = '' fiat_balance_str = '' if fx: fx.history_used_spot = False if not forceNoFX and fx: if not ccy: ccy = fx.get_currency() try: hdate = timestamp_to_datetime( time.time() if conf <= 0 else timestamp) hamount = fx.historical_value(value, hdate) htext = fx.historical_value_str(value, hdate) if hamount else '' fiat_amount = hamount if hamount else fiat_amount fiat_amount_str = htext if htext else fiat_amount_str hamount = fx.historical_value(balance, hdate) if balance else 0 htext = fx.historical_value_str(balance, hdate) if hamount else '' fiat_balance = hamount if hamount else fiat_balance fiat_balance_str = htext if htext else fiat_balance_str except: utils.NSLog( "Exception in get_history computing fiat amounts!\n%s", str(sys.exc_info()[1])) #import traceback #traceback.print_exc(file=sys.stderr) fiat_amount = fiat_balance = 0 fiat_amount_str = fiat_balance_str = '' if status >= 0 and status < len(sImages): img = sImages[status] else: img = None tx = wallet.transactions.get(tx_hash, None) if tx is not None: tx.deserialize() entry = HistoryEntry(tx, tx_hash, status_str, label, v_str, balance_str, date, ts, conf, status, value, fiat_amount, fiat_balance, fiat_amount_str, fiat_balance_str, ccy, img) return entry