Exemple #1
0
 def update(self):
     self.menu_actions = [(_('Use'), self.do_use), (_('Details'), self.do_view)]
     wallet = self.app.wallet
     if self.show_change == 0:
         _list = wallet.get_receiving_addresses()
     elif self.show_change == 1:
         _list = wallet.get_change_addresses()
     else:
         _list = wallet.get_addresses()
     search = self.message
     container = self.ids.search_container
     container.clear_widgets()
     n = 0
     for address in _list:
         label = wallet.labels.get(address, '')
         balance = sum(wallet.get_addr_balance(address))
         is_used = wallet.is_used(address)
         if self.show_used == 1 and (balance or is_used):
             continue
         if self.show_used == 2 and balance == 0:
             continue
         if self.show_used == 3 and not is_used:
             continue
         card = self.get_card(address, balance, is_used, label)
         if search and not self.ext_search(card, search):
             continue
         container.add_widget(card)
         n += 1
     if not n:
         msg = _('No address matching your search')
         container.add_widget(EmptyLabel(text=msg))
Exemple #2
0
    def update(self):
        format_amount = self.app.format_amount_and_units
        tx_hash, self.status_str, self.description, self.can_broadcast, self.can_rbf, amount, fee, height, conf, timestamp, exp_n = self.wallet.get_tx_info(
            self.tx)
        self.tx_hash = tx_hash or ''
        if timestamp:
            self.date_label = _('Date')
            self.date_str = datetime.fromtimestamp(timestamp).isoformat(
                ' ')[:-3]
        elif exp_n:
            self.date_label = _('Mempool depth')
            self.date_str = _('{} from tip').format('%.2f MB' %
                                                    (exp_n / 1000000))
        else:
            self.date_label = ''
            self.date_str = ''

        if amount is None:
            self.amount_str = _("Transaction unrelated to your wallet")
        elif amount > 0:
            self.is_mine = False
            self.amount_str = format_amount(amount)
        else:
            self.is_mine = True
            self.amount_str = format_amount(-amount)
        self.fee_str = format_amount(fee) if fee is not None else _('unknown')
        self.can_sign = self.wallet.can_sign(self.tx)
        self.ids.output_list.update(self.tx.outputs())
Exemple #3
0
 def update(self):
     self.menu_actions = [(_('Show'), self.do_show),
                          (_('Delete'), self.do_delete)]
     requests_list = self.ids.requests_container
     requests_list.clear_widgets()
     _list = self.app.wallet.get_sorted_requests(
         self.app.electrum_ganja_config)
     for pr in _list:
         ci = self.get_card(pr)
         requests_list.add_widget(ci)
Exemple #4
0
 def get_card(self, addr, balance, is_used, label):
     ci = self.cards.get(addr)
     if ci is None:
         ci = Factory.AddressItem()
         ci.screen = self
         ci.address = addr
         self.cards[addr] = ci
     ci.memo = label
     ci.amount = self.app.format_amount_and_units(balance)
     ci.status = _('Used') if is_used else _('Funded') if balance > 0 else _('Unused')
     return ci
Exemple #5
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')
     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.confirmations = conf
     if value is not None:
         ri.is_mine = value < 0
         if value < 0: value = -value
         ri.amount = self.app.format_amount_and_units(value)
         if self.app.fiat_unit:
             fx = self.app.fx
             fiat_value = value / Decimal(
                 ganja.COIN) * self.app.wallet.price_at_timestamp(
                     tx_hash, fx.timestamp_rate)
             fiat_value = Fiat(fiat_value, fx.ccy)
             ri.quote_text = str(fiat_value)
     return ri
Exemple #6
0
 def update(self):
     if not self.screen.address:
         self.get_new_address()
     else:
         status = self.app.wallet.get_request_status(self.screen.address)
         self.screen.status = _(
             'Payment received') if status == PR_PAID else ''
Exemple #7
0
 def fx_status(self):
     fx = self.app.fx
     if fx.is_enabled():
         source = fx.exchange.name()
         ccy = fx.get_currency()
         return '%s [%s]' % (ccy, source)
     else:
         return _('None')
Exemple #8
0
 def on_currency(self, ccy):
     b = (ccy != _('None'))
     self.fx.set_enabled(b)
     if b:
         if ccy != self.fx.get_currency():
             self.fx.set_currency(ccy)
         self.app.fiat_unit = ccy
     else:
         self.app.is_fiat = False
     Clock.schedule_once(lambda dt: self.add_exchanges())
Exemple #9
0
 def do_rbf(self):
     from .bump_fee_dialog import BumpFeeDialog
     is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(self.tx)
     if fee is None:
         self.app.show_error(
             _("Can't bump fee: unknown fee for original transaction."))
         return
     size = self.tx.estimated_size()
     d = BumpFeeDialog(self.app, fee, size, self._do_rbf)
     d.open()
Exemple #10
0
    def label_dialog(self, obj):
        from .dialogs.label_dialog import LabelDialog
        key = obj.tx_hash
        text = self.app.wallet.get_label(key)

        def callback(text):
            self.app.wallet.set_label(key, text)
            self.update()

        d = LabelDialog(_('Enter Transaction Label'), text, callback)
        d.open()
Exemple #11
0
    def do_delete(self, obj):
        from .question import Question

        def cb(result):
            if result:
                self.app.wallet.invoices.remove(obj.key)
            self.hide_menu()
            self.update()

        d = Question(_('Delete invoice?'), cb)
        d.open()
Exemple #12
0
    def do_delete(self, req):
        from .question import Question

        def cb(result):
            if result:
                self.app.wallet.remove_payment_request(
                    req.address, self.app.electrum_ganja_config)
                self.hide_menu()
                self.update()

        d = Question(_('Delete request'), cb)
        d.open()
Exemple #13
0
    def coinselect_dialog(self, item, dt):
        if self._coinselect_dialog is None:
            choosers = sorted(coinchooser.COIN_CHOOSERS.keys())
            chooser_name = coinchooser.get_name(self.config)

            def cb(text):
                self.config.set_key('coin_chooser', text)
                item.status = text

            self._coinselect_dialog = ChoiceDialog(_('Coin selection'),
                                                   choosers, chooser_name, cb)
        self._coinselect_dialog.open()
Exemple #14
0
    def language_dialog(self, item, dt):
        if self._language_dialog is None:
            l = self.config.get('language', 'en_UK')

            def cb(key):
                self.config.set_key("language", key, True)
                item.lang = self.get_language_name()
                self.app.language = key

            self._language_dialog = ChoiceDialog(_('Language'), languages, l,
                                                 cb)
        self._language_dialog.open()
Exemple #15
0
    def __init__(self, obj, action_list):
        Bubble.__init__(self)
        self.obj = obj
        for k, v in action_list:
            l = MenuItem()
            l.text = _(k)

            def func(f=v):
                Clock.schedule_once(lambda dt: f(obj), 0.15)

            l.on_release = func
            self.ids.buttons.add_widget(l)
Exemple #16
0
 def do_send(self):
     if self.screen.is_pr:
         if self.payment_request.has_expired():
             self.app.show_error(_('Payment request has expired'))
             return
         outputs = self.payment_request.get_outputs()
     else:
         address = str(self.screen.address)
         if not address:
             self.app.show_error(
                 _('Recipient not specified.') + ' ' +
                 _('Please scan a MRJA address or a payment request'))
             return
         if not ganja.is_address(address):
             self.app.show_error(
                 _('Invalid MRJA Address') + ':\n' + address)
             return
         try:
             amount = self.app.get_amount(self.screen.amount)
         except:
             self.app.show_error(
                 _('Invalid amount') + ':\n' + self.screen.amount)
             return
         outputs = [(ganja.TYPE_ADDRESS, address, amount)]
     message = self.screen.message
     amount = sum(map(lambda x: x[2], outputs))
     if self.app.electrum_ganja_config.get('use_rbf'):
         from .dialogs.question import Question
         d = Question(_('Should this transaction be replaceable?'),
                      lambda b: self._do_send(amount, message, outputs, b))
         d.open()
     else:
         self._do_send(amount, message, outputs, False)
Exemple #17
0
 def _do_send(self, amount, message, outputs, rbf):
     # make unsigned transaction
     config = self.app.electrum_ganja_config
     coins = self.app.wallet.get_spendable_coins(None, config)
     try:
         tx = self.app.wallet.make_unsigned_transaction(
             coins, outputs, config, None)
     except NotEnoughFunds:
         self.app.show_error(_("Not enough funds"))
         return
     except Exception as e:
         traceback.print_exc(file=sys.stdout)
         self.app.show_error(str(e))
         return
     if rbf:
         tx.set_rbf(True)
     fee = tx.get_fee()
     msg = [
         _("Amount to be sent") + ": " +
         self.app.format_amount_and_units(amount),
         _("Mining fee") + ": " + self.app.format_amount_and_units(fee),
     ]
     if fee >= config.get('confirm_fee', 100000):
         msg.append(
             _('Warning') + ': ' +
             _("The fee for this transaction seems unusually high."))
     msg.append(_("Enter your PIN code to proceed"))
     self.app.protected('\n'.join(msg), self.send_tx, (tx, message))
Exemple #18
0
 def get_card(self, pr):
     key = pr.get_id()
     ci = self.cards.get(key)
     if ci is None:
         ci = Factory.InvoiceItem()
         ci.key = key
         ci.screen = self
         self.cards[key] = ci
     ci.requestor = pr.get_requestor()
     ci.memo = pr.get_memo()
     amount = pr.get_amount()
     if amount:
         ci.amount = self.app.format_amount_and_units(amount)
         status = self.app.wallet.invoices.get_status(ci.key)
         ci.status = invoice_text[status]
         ci.icon = pr_icon[status]
     else:
         ci.amount = _('No Amount')
         ci.status = ''
     exp = pr.get_expiration_date()
     ci.date = format_time(exp) if exp else _('Never')
     return ci
Exemple #19
0
 def on_address(self, addr):
     req = self.app.wallet.get_payment_request(
         addr, self.app.electrum_ganja_config)
     self.screen.status = ''
     if req:
         self.screen.message = req.get('memo', '')
         amount = req.get('amount')
         self.screen.amount = self.app.format_amount_and_units(
             amount) if amount else ''
         status = req.get('status', PR_UNKNOWN)
         self.screen.status = _(
             'Payment received') if status == PR_PAID else ''
     Clock.schedule_once(lambda dt: self.update_qr())
Exemple #20
0
    def unit_dialog(self, item, dt):
        if self._unit_dialog is None:

            def cb(text):
                self.app._set_bu(text)
                item.bu = self.app.base_unit

            self._unit_dialog = ChoiceDialog(_('Denomination'),
                                             base_units_list,
                                             self.app.base_unit,
                                             cb,
                                             keep_choice_order=True)
        self._unit_dialog.open()
Exemple #21
0
 def set_URI(self, text):
     import electrum_ganja as electrum
     try:
         uri = electrum_ganja.util.parse_URI(text, self.app.on_pr)
     except:
         self.app.show_info(_("Not a Ganjacoin URI"))
         return
     amount = uri.get('amount')
     self.screen.address = uri.get('address', '')
     self.screen.message = uri.get('message', '')
     self.screen.amount = self.app.format_amount_and_units(
         amount) if amount else ''
     self.payment_request = None
     self.screen.is_pr = False
Exemple #22
0
 def on_password(self, pw):
     if len(pw) == 6:
         if self.check_password(pw):
             if self.is_change == 0:
                 self.success = True
                 self.pw = pw
                 self.message = _('Please wait...')
                 self.dismiss()
             elif self.is_change == 1:
                 self.pw = pw
                 self.message = _('Enter new PIN')
                 self.ids.kb.password = ''
                 self.is_change = 2
             elif self.is_change == 2:
                 self.new_password = pw
                 self.message = _('Confirm new PIN')
                 self.ids.kb.password = ''
                 self.is_change = 3
             elif self.is_change == 3:
                 self.success = pw == self.new_password
                 self.dismiss()
         else:
             self.app.show_error(_('Wrong PIN'))
             self.ids.kb.password = ''
Exemple #23
0
 def save_request(self):
     addr = self.screen.address
     if not addr:
         return False
     amount = self.screen.amount
     message = self.screen.message
     amount = self.app.get_amount(amount) if amount else 0
     req = self.app.wallet.make_payment_request(addr, amount, message, None)
     try:
         self.app.wallet.add_payment_request(req,
                                             self.app.electrum_ganja_config)
         added_request = True
     except Exception as e:
         self.app.show_error(
             _('Error adding payment request') + ':\n' + str(e))
         added_request = False
     finally:
         self.app.update_tab('requests')
     return added_request
Exemple #24
0
 def do_save(self):
     if not self.screen.address:
         return
     if self.screen.is_pr:
         # it should be already saved
         return
     # save address as invoice
     from electrum_ganja.paymentrequest import make_unsigned_request, PaymentRequest
     req = {'address': self.screen.address, 'memo': self.screen.message}
     amount = self.app.get_amount(
         self.screen.amount) if self.screen.amount else 0
     req['amount'] = amount
     pr = make_unsigned_request(req).SerializeToString()
     pr = PaymentRequest(pr)
     self.app.wallet.invoices.add(pr)
     self.app.show_info(_("Invoice saved"))
     if pr.is_pr():
         self.screen.is_pr = True
         self.payment_request = pr
     else:
         self.screen.is_pr = False
         self.payment_request = None
Exemple #25
0
                cols: 1
                id: invoices_container
                size_hint: 1, None
                height: self.minimum_height
                spacing: '2dp'
                padding: '12dp'
''')

from kivy.properties import BooleanProperty
from electrum_ganja_gui.kivy.i18n import _
from electrum_ganja.util import format_time
from electrum_ganja.paymentrequest import PR_UNPAID, PR_PAID, PR_UNKNOWN, PR_EXPIRED
from electrum_ganja_gui.kivy.uix.context_menu import ContextMenu

invoice_text = {
    PR_UNPAID: _('Pending'),
    PR_UNKNOWN: _('Unknown'),
    PR_PAID: _('Paid'),
    PR_EXPIRED: _('Expired')
}
pr_icon = {
    PR_UNPAID: 'atlas://gui/kivy/theming/light/important',
    PR_UNKNOWN: 'atlas://gui/kivy/theming/light/important',
    PR_PAID: 'atlas://gui/kivy/theming/light/confirmed',
    PR_EXPIRED: 'atlas://gui/kivy/theming/light/close'
}


class InvoicesDialog(Factory.Popup):
    def __init__(self, app, screen, callback):
        Factory.Popup.__init__(self)
Exemple #26
0
class ContextMenu(Bubble):

    buttons = ListProperty([_('ok'), _('cancel')])
    '''List of Buttons to be displayed at the bottom'''

    __events__ = ('on_press', 'on_release')

    def __init__(self, **kwargs):
        self._old_buttons = self.buttons
        super(ContextMenu, self).__init__(**kwargs)
        self.on_buttons(self, self.buttons)

    def on_touch_down(self, touch):
        if not self.collide_point(*touch.pos):
            self.hide()
            return
        return super(ContextMenu, self).on_touch_down(touch)

    def on_buttons(self, _menu, value):
        if 'menu_content' not in self.ids.keys():
            return
        if value == self._old_buttons:
            return
        blayout = self.ids.menu_content
        blayout.clear_widgets()
        for btn in value:
            ib = ContextButton(text=btn)
            ib.bind(on_press=partial(self.dispatch, 'on_press'))
            ib.bind(on_release=partial(self.dispatch, 'on_release'))
            blayout.add_widget(ib)
        self._old_buttons = value

    def on_press(self, instance):
        pass

    def on_release(self, instance):
        pass

    def show(self, pos, duration=0):
        Window.add_widget(self)
        # wait for the bubble to adjust it's size according to text then animate
        Clock.schedule_once(lambda dt: self._show(pos, duration))

    def _show(self, pos, duration):
        def on_stop(*l):
            if duration:
                Clock.schedule_once(self.hide, duration + .5)

        self.opacity = 0
        arrow_pos = self.arrow_pos
        if arrow_pos[0] in ('l', 'r'):
            pos = pos[0], pos[1] - (self.height / 2)
        else:
            pos = pos[0] - (self.width / 2), pos[1]

        self.limit_to = Window

        anim = Animation(opacity=1, pos=pos, d=.32)
        anim.bind(on_complete=on_stop)
        anim.cancel_all(self)
        anim.start(self)

    def hide(self, *dt):
        def on_stop(*l):
            Window.remove_widget(self)

        anim = Animation(opacity=0, d=.25)
        anim.bind(on_complete=on_stop)
        anim.cancel_all(self)
        anim.start(self)

    def add_widget(self, widget, index=0):
        if not isinstance(widget, ContextMenuItem):
            super(ContextMenu, self).add_widget(widget, index)
            return
        menu_content.add_widget(widget, index)
Exemple #27
0
 def add_currencies(self):
     currencies = [_('None')] + self.fx.get_currencies(True)
     my_ccy = self.fx.get_currency() if self.fx.is_enabled() else _('None')
     self.ids.ccy.values = currencies
     self.ids.ccy.text = my_ccy
Exemple #28
0
class InfoBubble(Factory.Bubble):
    '''Bubble to be used to display short Help Information'''

    message = StringProperty(_('Nothing set !'))
    '''Message to be displayed; defaults to "nothing set"'''

    icon = StringProperty('')
    ''' Icon to be displayed along with the message defaults to ''

    :attr:`icon` is a  `StringProperty` defaults to `''`
    '''

    fs = BooleanProperty(False)
    ''' Show Bubble in half screen mode

    :attr:`fs` is a `BooleanProperty` defaults to `False`
    '''

    modal = BooleanProperty(False)
    ''' Allow bubble to be hidden on touch.

    :attr:`modal` is a `BooleanProperty` defauult to `False`.
    '''

    exit = BooleanProperty(False)
    '''Indicates whether to exit app after bubble is closed.

    :attr:`exit` is a `BooleanProperty` defaults to False.
    '''

    dim_background = BooleanProperty(False)
    ''' Indicates Whether to draw a background on the windows behind the bubble.

    :attr:`dim` is a `BooleanProperty` defaults to `False`.
    '''

    def on_touch_down(self, touch):
        if self.modal:
            return True
        self.hide()
        if self.collide_point(*touch.pos):
            return True

    def show(self, pos, duration, width=None, modal=False, exit=False):
        '''Animate the bubble into position'''
        self.modal, self.exit = modal, exit
        if width:
            self.width = width
        if self.modal:
            from kivy.uix.modalview import ModalView
            self._modal_view = m = ModalView(background_color=[.5, .5, .5, .2])
            Window.add_widget(m)
            m.add_widget(self)
        else:
            Window.add_widget(self)

        # wait for the bubble to adjust its size according to text then animate
        Clock.schedule_once(lambda dt: self._show(pos, duration))

    def _show(self, pos, duration):

        def on_stop(*l):
            if duration:
                Clock.schedule_once(self.hide, duration + .5)

        self.opacity = 0
        arrow_pos = self.arrow_pos
        if arrow_pos[0] in ('l', 'r'):
            pos = pos[0], pos[1] - (self.height/2)
        else:
            pos = pos[0] - (self.width/2), pos[1]

        self.limit_to = Window

        anim = Factory.Animation(opacity=1, pos=pos, d=.32)
        anim.bind(on_complete=on_stop)
        anim.cancel_all(self)
        anim.start(self)


    def hide(self, now=False):
        ''' Auto fade out the Bubble
        '''
        def on_stop(*l):
            if self.modal:
                m = self._modal_view
                m.remove_widget(self)
                Window.remove_widget(m)
            Window.remove_widget(self)
            if self.exit:
                App.get_running_app().stop()
                import sys
                sys.exit()
            else:
                App.get_running_app().is_exit = False

        if now:
            return on_stop()

        anim = Factory.Animation(opacity=0, d=.25)
        anim.bind(on_complete=on_stop)
        anim.cancel_all(self)
        anim.start(self)
Exemple #29
0
 def do_save(self):
     if self.save_request():
         self.app.show_info(_('Request was saved.'))
Exemple #30
0
 def do_new(self):
     addr = self.get_new_address()
     if not addr:
         self.app.show_info(_('Please use the existing requests first.'))