Exemple #1
0
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)
Exemple #2
0
    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)
Exemple #3
0
 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
Exemple #4
0
 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)
Exemple #5
0
 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)
Exemple #6
0
 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)
Exemple #7
0
    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
Exemple #9
0
 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