# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys, time, datetime, re, threading
-from electrum.i18n import _, set_language
-from electrum.util import print_error, print_msg
+from electrum_nvc.i18n import _, set_language
+from electrum_nvc.util import print_error, print_msg
import os.path, json, ast, traceback
import webbrowser
import shutil
from PyQt4.QtCore import *
import PyQt4.QtCore as QtCore
-from electrum.bitcoin import MIN_RELAY_TX_FEE, is_valid
-from electrum.plugins import run_hook
+from electrum_nvc.bitcoin import MIN_RELAY_TX_FEE, is_valid
+from electrum_nvc.plugins import run_hook
import icons_rc
-from electrum.util import format_satoshis
-from electrum import Transaction
-from electrum import mnemonic
-from electrum import util, bitcoin, commands, Interface, Wallet
-from electrum import SimpleConfig, Wallet, WalletStorage
-from electrum import Imported_Wallet
+from electrum_nvc.util import format_satoshis
+from electrum_nvc import Transaction
+from electrum_nvc import mnemonic
+from electrum_nvc import util, bitcoin, commands, Interface, Wallet
+from electrum_nvc import SimpleConfig, Wallet, WalletStorage
+from electrum_nvc import Imported_Wallet
from amountedit import AmountEdit, BTCAmountEdit, MyLineEdit
from network_dialog import NetworkDialog
PR_ERROR = 4 # could not parse
-from electrum import ELECTRUM_VERSION
+from electrum_nvc import ELECTRUM_VERSION
import re
-from util import *
+from util import MyTreeWidget, HelpButton, EnterButton, line_dialog, text_dialog, ok_cancel_buttons, close_button, WaitingDialog
def format_status(x):
self.create_status_bar()
self.need_update = threading.Event()
- self.decimal_point = config.get('decimal_point', 5)
+ self.decimal_point = config.get('decimal_point', 6)
self.num_zeros = int(config.get('num_zeros',0))
self.invoices = {}
def load_wallet(self, wallet):
- import electrum
+ import electrum_nvc
self.wallet = wallet
self.update_wallet_format()
import installwizard
wallet_folder = os.path.dirname(self.wallet.storage.path)
- filename = unicode( QFileDialog.getSaveFileName(self, _('Enter a new file name'), wallet_folder) )
+ i = 1
+ while True:
+ filename = "wallet_%d"%i
+ if filename in os.listdir(wallet_folder):
+ i += 1
+ else:
+ break
+
+ filename = line_dialog(self, _('New Wallet'), _('Enter file name') + ':', _('OK'), filename)
if not filename:
return
- filename = os.path.join(wallet_folder, filename)
- storage = WalletStorage({'wallet_path': filename})
+ full_path = os.path.join(wallet_folder, filename)
+ storage = WalletStorage({'wallet_path': full_path})
if storage.file_exists:
QMessageBox.critical(None, "Error", _("File exists"))
return
raw_transaction_menu.addAction(_("&From file"), self.do_process_from_file)
raw_transaction_menu.addAction(_("&From text"), self.do_process_from_text)
raw_transaction_menu.addAction(_("&From the blockchain"), self.do_process_from_txid)
+ raw_transaction_menu.addAction(_("&From QR code"), self.read_tx_from_qrcode)
self.raw_transaction_menu = raw_transaction_menu
help_menu = menubar.addMenu(_("&Help"))
self.setMenuBar(menubar)
def show_about(self):
- QMessageBox.about(self, "Electrum",
- _("Version")+" %s" % (self.wallet.electrum_version) + "\n\n" + _("Electrum's focus is speed, with low resource usage and simplifying Bitcoin. You do not need to perform regular backups, because your wallet can be recovered from a secret phrase that you can memorize or write on paper. Startup times are instant because it operates in conjunction with high-performance servers that handle the most complicated parts of the Bitcoin system."))
+ QMessageBox.about(self, "Electrum-NVC",
+ _("Version")+" %s" % (self.wallet.electrum_version) + "\n\n" + _("Electrum's focus is speed, with low resource usage and simplifying Bitcoin. You do not need to perform regular backups, because your wallet can be recovered from a secret phrase that you can memorize or write on paper. Startup times are instant because it operates in conjunction with high-performance servers that handle the most complicated parts of the Novacoin system."))
def show_report_bug(self):
QMessageBox.information(self, "Electrum - " + _("Reporting Bugs"),
self.notify(_("New transaction received. %(amount)s %(unit)s") % { 'amount' : self.format_amount(v), 'unit' : self.base_unit()})
def notify(self, message):
- self.tray.showMessage("Electrum", message, QSystemTrayIcon.Information, 20000)
+ self.tray.showMessage("Electrum-NVC", message, QSystemTrayIcon.Information, 20000)
def base_unit(self):
- assert self.decimal_point in [2, 5, 8]
+ assert self.decimal_point in [2, 3, 6]
if self.decimal_point == 2:
return 'bits'
- if self.decimal_point == 5:
- return 'mBTC'
- if self.decimal_point == 8:
- return 'BTC'
+ if self.decimal_point == 3:
+ return 'mNVC'
+ if self.decimal_point == 6:
+ return 'NVC'
raise Exception('Unknown base unit')
def update_status(self):
def create_history_menu(self, position):
self.history_list.selectedIndexes()
item = self.history_list.currentItem()
- be = self.config.get('block_explorer', 'Blockchain.info')
- if be == 'Blockchain.info':
- block_explorer = 'https://blockchain.info/tx/'
- elif be == 'Blockr.io':
- block_explorer = 'https://blockr.io/tx/info/'
- elif be == 'Insight.is':
- block_explorer = 'http://live.insight.is/tx/'
+ be = self.config.get('block_explorer', 'explorer.novaco.in')
+ if be == 'explorer.novaco.in':
+ block_explorer = 'https://explorer.novaco.in/tx/'
+ elif be == 'novacoin.su':
+ block_explorer = 'http://novacoin.su/tx/'
if not item: return
+
tx_hash = str(item.data(0, Qt.UserRole).toString())
if not tx_hash: return
menu = QMenu()
menu.addAction(_("Copy ID to Clipboard"), lambda: self.app.clipboard().setText(tx_hash))
menu.addAction(_("Details"), lambda: self.show_transaction(self.wallet.transactions.get(tx_hash)))
menu.addAction(_("Edit description"), lambda: self.tx_label_clicked(item,2))
- menu.addAction(_("View on block explorer"), lambda: webbrowser.open(block_explorer + tx_hash))
+ menu.addAction(_("View on explorer"), lambda: webbrowser.open(block_explorer + tx_hash))
menu.exec_(self.contacts_list.viewport().mapToGlobal(position))
def new_receive_address(self):
domain = self.wallet.get_account_addresses(self.current_account, include_change=False)
for addr in domain:
- if not self.wallet.address_is_old(addr) and addr not in self.receive_requests.keys():
+ if not self.wallet.history.get(addr) and addr not in self.receive_requests.keys():
break
else:
if isinstance(self.wallet, Imported_Wallet):
self.receive_requests = self.wallet.storage.get('receive_requests',{})
domain = self.wallet.get_account_addresses(self.current_account, include_change=False)
for addr in domain:
- if not self.wallet.address_is_old(addr) and addr not in self.receive_requests.keys():
+ if not self.wallet.history.get(addr) and addr not in self.receive_requests.keys():
break
else:
addr = ''
from paytoedit import PayToEdit
self.amount_e = BTCAmountEdit(self.get_decimal_point)
self.payto_e = PayToEdit(self)
- self.payto_help = HelpButton(_('Recipient of the funds.') + '\n\n' + _('You may enter a Bitcoin address, a label from your list of contacts (a list of completions will be proposed), or an alias (email-like address that forwards to a Bitcoin address)'))
+ self.payto_help = HelpButton(_('Recipient of the funds.') + '\n\n' + _('You may enter a Novacoin address, a label from your list of contacts (a list of completions will be proposed), or an alias (email-like address that forwards to a Novacoin address)'))
grid.addWidget(QLabel(_('Pay to')), 1, 0)
grid.addWidget(self.payto_e, 1, 1, 1, 3)
grid.addWidget(self.payto_help, 1, 4)
grid.addWidget(QLabel(_('Fee')), 5, 0)
grid.addWidget(self.fee_e, 5, 1, 1, 2)
grid.addWidget(HelpButton(
- _('Bitcoin transactions are in general not free. A transaction fee is paid by the sender of the funds.') + '\n\n'\
+ _('Novacoin transactions are in general not free. A transaction fee is paid by the sender of the funds.') + '\n\n'\
+ _('The amount of fee can be decided freely by the sender. However, transactions with low fees take more time to be processed.') + '\n\n'\
+ _('A suggested fee is automatically added to this field. You may override it. The suggested fee increases with the size of the transaction.')), 5, 3)
for type, addr, amount in outputs:
if addr is None:
- QMessageBox.warning(self, _('Error'), _('Bitcoin Address is None'), _('OK'))
+ QMessageBox.warning(self, _('Error'), _('Novacoin Address is None'), _('OK'))
return
if type == 'op_return':
continue
if type == 'address' and not bitcoin.is_address(addr):
- QMessageBox.warning(self, _('Error'), _('Invalid Bitcoin Address'), _('OK'))
+ QMessageBox.warning(self, _('Error'), _('Invalid Novacoin Address'), _('OK'))
return
if amount is None:
QMessageBox.warning(self, _('Error'), _('Invalid Amount'), _('OK'))
QMessageBox.warning(self, _('Error'), _('Invalid Fee'), _('OK'))
return
- confirm_amount = self.config.get('confirm_amount', 100000000)
+ confirm_amount = self.config.get('confirm_amount', 10000)
if amount >= confirm_amount:
o = '\n'.join(map(lambda x:x[1], outputs))
if not self.question(_("send %(amount)s to %(address)s?")%{ 'amount' : self.format_amount(amount) + ' '+ self.base_unit(), 'address' : o}):
return
- confirm_fee = self.config.get('confirm_fee', 100000)
+ confirm_fee = self.config.get('confirm_fee', 10000)
if fee >= confirm_fee:
if not self.question(_("The fee for this transaction seems unusually high.\nAre you really sure you want to pay %(fee)s in fees?")%{ 'fee' : self.format_amount(fee) + ' '+ self.base_unit()}):
return
try:
address, amount, label, message, request_url = util.parse_URI(URI)
except Exception as e:
- QMessageBox.warning(self, _('Error'), _('Invalid bitcoin URI:') + '\n' + str(e), _('OK'))
+ QMessageBox.warning(self, _('Error'), _('Invalid novacoin URI:') + '\n' + str(e), _('OK'))
return
self.tabs.setCurrentIndex(1)
self.amount_e.setAmount(amount)
return
- from electrum import paymentrequest
+ from electrum_nvc import paymentrequest
def payment_request():
self.payment_request = paymentrequest.PaymentRequest(self.config)
self.payment_request.read(request_url)
def create_invoices_tab(self):
- l, w = self.create_list_tab([_('Requestor'), _('Memo'),_('Amount'), _('Status')])
+ l, w = self.create_list_tab([_('Requestor'), _('Memo'), _('Date'), _('Amount'), _('Status')])
l.setColumnWidth(0, 150)
+ l.setColumnWidth(2, 150)
+ l.setColumnWidth(3, 150)
h = l.header()
h.setStretchLastSection(False)
h.setResizeMode(1, QHeaderView.Stretch)
invoices = self.wallet.storage.get('invoices', {})
l = self.invoices_list
l.clear()
- for key, value in invoices.items():
- try:
- domain, memo, amount, expiration_date, status, tx_hash = value
- except:
- invoices.pop(key)
- continue
+ for key, value in sorted(invoices.items(), key=lambda x: -x[1][3]):
+ domain, memo, amount, expiration_date, status, tx_hash = value
if status == PR_UNPAID and expiration_date and expiration_date < time.time():
status = PR_EXPIRED
- item = QTreeWidgetItem( [ domain, memo, self.format_amount(amount), format_status(status)] )
+ date_str = datetime.datetime.fromtimestamp(expiration_date).isoformat(' ')[:-3]
+ item = QTreeWidgetItem( [ domain, memo, date_str, self.format_amount(amount, whitespaces=True), format_status(status)] )
+ item.setData(0, 32, key)
+ item.setFont(0, QFont(MONOSPACE_FONT))
+ item.setFont(3, QFont(MONOSPACE_FONT))
l.addTopLevelItem(item)
-
l.setCurrentItem(l.topLevelItem(0))
-
-
def delete_imported_key(self, addr):
if self.question(_("Do you want to remove")+" %s "%addr +_("from your wallet?")):
self.wallet.delete_imported_key(addr)
payto_addr = item.data(0,33).toString()
menu.addAction(_("Copy to Clipboard"), lambda: self.app.clipboard().setText(addr))
menu.addAction(_("Pay to"), lambda: self.payto(payto_addr))
- menu.addAction(_("QR code"), lambda: self.show_qrcode("bitcoin:" + addr, _("Address")))
+ menu.addAction(_("QR code"), lambda: self.show_qrcode("novacoin:" + addr, _("Address")))
if is_editable:
menu.addAction(_("Edit label"), lambda: self.edit_label(False))
menu.addAction(_("Delete"), lambda: self.delete_contact(addr))
self.update_invoices_tab()
def show_invoice(self, key):
- from electrum.paymentrequest import PaymentRequest
+ from electrum_nvc.paymentrequest import PaymentRequest
domain, memo, value, expiration, status, tx_hash = self.invoices[key]
pr = PaymentRequest(self.config)
pr.read_file(key)
pr.domain = domain
pr.verify()
- self.show_pr_details(pr)
+ self.show_pr_details(pr, tx_hash)
- def show_pr_details(self, pr):
+ def show_pr_details(self, pr, tx_hash=None):
msg = 'Domain: ' + pr.domain
msg += '\nStatus: ' + pr.get_status()
msg += '\nMemo: ' + pr.get_memo()
msg += '\nPayment URL: ' + pr.payment_url
- msg += '\n\nOutputs:\n' + '\n'.join(map(lambda x: x[0] + ' ' + self.format_amount(x[1])+ self.base_unit(), pr.get_outputs()))
+ msg += '\n\nOutputs:\n' + '\n'.join(map(lambda x: x[1] + ' ' + self.format_amount(x[2])+ self.base_unit(), pr.get_outputs()))
+ if tx_hash:
+ msg += '\n\nTransaction ID: ' + tx_hash
QMessageBox.information(self, 'Invoice', msg , 'OK')
def do_pay_invoice(self, key):
- from electrum.paymentrequest import PaymentRequest
+ from electrum_nvc.paymentrequest import PaymentRequest
domain, memo, value, expiration, status, tx_hash = self.invoices[key]
pr = PaymentRequest(self.config)
pr.read_file(key)
item = self.invoices_list.itemAt(position)
if not item:
return
- k = self.invoices_list.indexOfTopLevelItem(item)
- key = self.invoices.keys()[k]
+ key = str(item.data(0, 32).toString())
domain, memo, value, expiration, status, tx_hash = self.invoices[key]
menu = QMenu()
menu.addAction(_("Details"), lambda: self.show_invoice(key))
vbox.addWidget(QLabel(_('Account name')+':'))
e = QLineEdit()
vbox.addWidget(e)
- msg = _("Note: Newly created accounts are 'pending' until they receive bitcoins.") + " " \
+ msg = _("Note: Newly created accounts are 'pending' until they receive novacoins.") + " " \
+ _("You will need to wait for 2 confirmations until the correct balance is displayed and more addresses are created for that account.")
l = QLabel(msg)
l.setWordWrap(True)
QMessageBox.critical(None, _("Unable to parse transaction"), _("Electrum was unable to parse your transaction"))
+ def read_tx_from_qrcode(self):
+ data = run_hook('scan_qr_hook')
+ if not data:
+ return
+ # transactions are binary, but qrcode seems to return utf8...
+ z = data.decode('utf8')
+ s = ''
+ for b in z:
+ s += chr(ord(b))
+ data = s.encode('hex')
+ tx = self.tx_from_text(data)
+ if not tx:
+ return
+ self.show_transaction(tx)
+
def read_tx_from_file(self):
fileName = self.getOpenFileName(_("Select your transaction file"), "*.txn")
self.show_transaction(tx)
def do_process_from_txid(self):
- from electrum import transaction
+ from electrum_nvc import transaction
txid, ok = QInputDialog.getText(self, _('Lookup transaction'), _('Transaction ID') + ':')
if ok and txid:
r = self.network.synchronous_get([ ('blockchain.transaction.get',[str(txid)]) ])[0]
errors.append((position, address))
continue
amount = Decimal(row[1])
- amount = int(100000000*amount)
+ amount = int(1000000*amount)
outputs.append(('address', address, amount))
except (ValueError, IOError, os.error), reason:
QMessageBox.critical(None, _("Unable to read file or no transaction found"), _("Electrum was unable to open your transaction file") + "\n" + str(reason))
d.setMinimumSize(400, 200)
vbox = QVBoxLayout(d)
- defaultname = os.path.expanduser('~/electrum-history.csv')
+ defaultname = os.path.expanduser('~/electrum-nvc-history.csv')
select_msg = _('Select file to export your wallet transactions to')
hbox, filename_e, csv_button = filename_field(self, self.config, defaultname, select_msg)
lang_label=QLabel(_('Language') + ':')
grid.addWidget(lang_label, 1, 0)
lang_combo = QComboBox()
- from electrum.i18n import languages
+ from electrum_nvc.i18n import languages
lang_combo.addItems(languages.values())
try:
index = languages.keys().index(self.config.get("language",''))
fee_e.setAmount(self.wallet.fee)
grid.addWidget(fee_e, 2, 1)
msg = _('Fee per kilobyte of transaction.') + '\n' \
- + _('Recommended value') + ': ' + self.format_amount(10000) + ' ' + self.base_unit()
+ + _('Recommended value') + ': ' + self.format_amount(1000) + ' ' + self.base_unit()
grid.addWidget(HelpButton(msg), 2, 2)
if not self.config.is_modifiable('fee_per_kb'):
for w in [fee_e, fee_label]: w.setEnabled(False)
- units = ['BTC', 'mBTC', 'bits']
+ units = ['NVC', 'mNVC', 'bits']
unit_label = QLabel(_('Base unit') + ':')
grid.addWidget(unit_label, 3, 0)
unit_combo = QComboBox()
unit_combo.setCurrentIndex(units.index(self.base_unit()))
grid.addWidget(unit_combo, 3, 1)
grid.addWidget(HelpButton(_('Base unit of your wallet.')\
- + '\n1BTC=1000mBTC.\n' \
+ + '\n1NVC=1000mNVC.\n' \
+ _(' These settings affects the fields in the Send tab')+' '), 3, 2)
usechange_cb = QCheckBox(_('Use change addresses'))
grid.addWidget(HelpButton(_('Using change addresses makes it more difficult for other people to track your transactions.')+' '), 4, 2)
if not self.config.is_modifiable('use_change'): usechange_cb.setEnabled(False)
- block_explorers = ['Blockchain.info', 'Blockr.io', 'Insight.is']
+ block_explorers = ['explorer.novaco.in', 'novacoin.su']
block_ex_label = QLabel(_('Online Block Explorer') + ':')
grid.addWidget(block_ex_label, 5, 0)
block_ex_combo = QComboBox()
block_ex_combo.addItems(block_explorers)
- block_ex_combo.setCurrentIndex(block_explorers.index(self.config.get('block_explorer', 'Blockchain.info')))
+ block_ex_combo.setCurrentIndex(block_explorers.index(self.config.get('block_explorer', 'explorer.novaco.in')))
grid.addWidget(block_ex_combo, 5, 1)
grid.addWidget(HelpButton(_('Choose which online block explorer to use for functions that open a web browser')+' '), 5, 2)
unit_result = units[unit_combo.currentIndex()]
if self.base_unit() != unit_result:
- if unit_result == 'BTC':
- self.decimal_point = 8
- elif unit_result == 'mBTC':
- self.decimal_point = 5
+ if unit_result == 'NVC':
+ self.decimal_point = 6
+ elif unit_result == 'mNVC':
+ self.decimal_point = 3
elif unit_result == 'bits':
self.decimal_point = 2
else:
def plugins_dialog(self):
- from electrum.plugins import plugins
+ from electrum_nvc.plugins import plugins
d = QDialog(self)
d.setWindowTitle(_('Electrum Plugins'))