include README LICENCE RELEASE-NOTES AUTHORS
-include electrum.conf.sample
-include electrum.desktop
+include electrum-nvc.conf.sample
+include electrum-nvc.desktop
include *.py
-include electrum
+include electrum-nvc
recursive-include lib *.py
recursive-include gui *.py
recursive-include plugins *.py
-Electrum - lightweight Bitcoin client
+Electrum - lightweight Novacoin client
Licence: GNU GPL v3
Author: Thomas Voegtlin
To run Electrum from this directory, just do:
- ./electrum
+ ./electrum-nvc
If you install Electrum on your system, you can run it from any
directory:
sudo python setup.py install
- electrum
+ electrum-nvc
To start Electrum from your web browser, see
# On brew installs
ARCHFLAGS="-arch i386 -arch x86_64" sudo python setup-release.py py2app --includes sip
- sudo hdiutil create -fs HFS+ -volname "Electrum" -srcfolder dist/Electrum.app dist/electrum-VERSION-macosx.dmg
+ sudo hdiutil create -fs HFS+ -volname "Electrum-NVC" -srcfolder dist/Electrum-NVC.app dist/electrum-nvc-VERSION-macosx.dmg
;General
;Name and file
- Name "Electrum"
+ Name "Electrum-NVC"
OutFile "dist/electrum-setup.exe"
;Default installation folder
- InstallDir "$PROGRAMFILES\Electrum"
+ InstallDir "$PROGRAMFILES\Electrum-NVC"
;Get installation folder from registry if available
- InstallDirRegKey HKCU "Software\Electrum" ""
+ InstallDirRegKey HKCU "Software\Electrum-NVC" ""
;Request application privileges for Windows Vista
RequestExecutionLevel admin
;Start Menu Folder Page Configuration
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCU"
- !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\Electrum"
+ !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\Electrum-NVC"
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
;!insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder
file /r dist\electrum\*.*
;Store installation folder
- WriteRegStr HKCU "Software\Electrum" "" $INSTDIR
+ WriteRegStr HKCU "Software\Electrum-NVC" "" $INSTDIR
;Create uninstaller
WriteUninstaller "$INSTDIR\Uninstall.exe"
CreateShortCut "$DESKTOP\Electrum.lnk" "$INSTDIR\electrum.exe" ""
;create start-menu items
- CreateDirectory "$SMPROGRAMS\Electrum"
+ CreateDirectory "$SMPROGRAMS\Electrum-NVC"
CreateShortCut "$SMPROGRAMS\Electrum\Uninstall.lnk" "$INSTDIR\Uninstall.exe" "" "$INSTDIR\Uninstall.exe" 0
CreateShortCut "$SMPROGRAMS\Electrum\Electrum.lnk" "$INSTDIR\electrum.exe" "" "$INSTDIR\electrum.exe" 0
Delete "$DESKTOP\Electrum.lnk"
Delete "$SMPROGRAMS\Electrum\*.*"
- RmDir "$SMPROGRAMS\Electrum"
+ RmDir "$SMPROGRAMS\Electrum-NVC"
- DeleteRegKey /ifempty HKCU "Software\Electrum"
+ DeleteRegKey /ifempty HKCU "Software\Electrum-NVC"
SectionEnd
# load local module as electrum
if __builtin__.use_local_modules:
import imp
- imp.load_module('electrum', *imp.find_module('lib'))
- imp.load_module('electrum_gui', *imp.find_module('gui'))
+ imp.load_module('electrum_nvc', *imp.find_module('lib'))
+ imp.load_module('electrum_nvc_gui', *imp.find_module('gui'))
if is_local:
sys.path.append('packages')
-from electrum import SimpleConfig, Network, Wallet, WalletStorage, NetworkProxy, Commands, known_commands, pick_random_server
-from electrum.util import print_msg, print_stderr, print_json, set_verbosity
+from electrum_nvc import SimpleConfig, Network, Wallet, WalletStorage, NetworkProxy, Commands, known_commands, pick_random_server
+from electrum_nvc.util import print_msg, print_stderr, print_json, set_verbosity
# get password routine
def prompt_password(prompt, confirm=True):
parser = optparse.OptionParser(usage=usage, add_help_option=False)
parser.add_option("-h", "--help", action="callback", callback=print_help_cb, help="show this help text")
parser.add_option("-g", "--gui", dest="gui", help="User interface: qt, lite, gtk, text or stdio")
- parser.add_option("-w", "--wallet", dest="wallet_path", help="wallet path (default: electrum.dat)")
+ parser.add_option("-w", "--wallet", dest="wallet_path", help="wallet path (default: electrum-nvc.dat)")
parser.add_option("-o", "--offline", action="store_true", dest="offline", default=False, help="remain offline")
parser.add_option("-C", "--concealed", action="store_true", dest="concealed", default=False, help="don't echo seed to console when restoring")
parser.add_option("-a", "--all", action="store_true", dest="show_all", default=False, help="show all addresses")
def print_help(parser):
parser.print_help()
- print_msg("Type 'electrum help <command>' to see the help for a specific command")
- print_msg("Type 'electrum --help' to see the list of options")
+ print_msg("Type 'electrum-nvc help <command>' to see the help for a specific command")
+ print_msg("Type 'electrum-nvc --help' to see the list of options")
run_command(known_commands['help'])
parser = arg_parser()
options, args = parser.parse_args()
if options.portable and options.wallet_path is None:
- options.electrum_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'electrum_data')
+ options.electrum_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'electrum-nvc_data')
# config is an object passed to the various constructors (wallet, interface, gui)
if is_android:
if len(args) == 0:
url = None
cmd = 'gui'
- elif len(args) == 1 and re.match('^bitcoin:', args[0]):
+ elif len(args) == 1 and re.match('^novacoin:', args[0]):
url = args[0]
cmd = 'gui'
else:
if gui_name in ['lite', 'classic']:
gui_name = 'qt'
try:
- gui = __import__('electrum_gui.' + gui_name, fromlist=['electrum_gui'])
+ gui = __import__('electrum_nvc_gui.' + gui_name, fromlist=['electrum_nvc_gui'])
except ImportError:
traceback.print_exc(file=sys.stdout)
sys.exit()
if cmd.name not in ['create', 'restore'] and cmd.requires_wallet and not storage.file_exists:
print_msg("Error: Wallet file not found.")
- print_msg("Type 'electrum create' to create a new wallet, or provide a path to a wallet with the -w option")
+ print_msg("Type 'electrum-nvc create' to create a new wallet, or provide a path to a wallet with the -w option")
sys.exit(0)
# Configuration file for the electrum client
# Settings defined here are shared across wallets
#
-# copy this file to /etc/electrum.conf if you want read-only settings
-# copy it into your ~/.electrum/ directory if you want global settings
+# copy this file to /etc/electrum-nvc.conf if you want read-only settings
+# copy it into your ~/.electrum-nvc/ directory if you want global settings
# that can be rewritten by the client
[client]
-server = electrum.novit.ro:50001:t
+server = 127.0.0.1:50001:t
proxy = None
gap_limit = 5
# booleans use python syntax
gui = qt
num_zeros = 2
# default transaction fee is in Satoshis
-fee = 10000
+fee = 1000
winpos-qt = [799, 226, 877, 435]
# sudo desktop-file-install electrum.desktop
[Desktop Entry]
-Comment=Lightweight Bitcoin Client
+Comment=Lightweight Novacoin Client
Exec=electrum %u
GenericName[en_US]=Electrum
GenericName=Electrum
Icon=/usr/share/app-install/icons/electrum.png
-Name[en_US]=Electrum Bitcoin Wallet
-Name=Electrum Bitcoin Wallet
+Name[en_US]=Electrum Novacoin Wallet
+Name=Electrum Novacoin Wallet
Categories=Network;
StartupNotify=false
Terminal=false
Type=Application
-MimeType=x-scheme-handler/bitcoin
+MimeType=x-scheme-handler/novacoin
from __future__ import absolute_import
import android
-from electrum import SimpleConfig, Wallet, WalletStorage, format_satoshis, mnemonic_encode, mnemonic_decode
-from electrum.bitcoin import is_valid
-from electrum import util
+from electrum_nvc import SimpleConfig, Wallet, WalletStorage, format_satoshis, mnemonic_encode, mnemonic_decode
+from electrum_nvc.bitcoin import is_valid
+from electrum_nvc import util
from decimal import Decimal
import datetime, re
<TextView
android:id="@+id/textElectrum"
- android:text="Electrum"
+ android:text="Electrum-NVC"
android:textSize="7pt"
android:textColor="#ff4444ff"
android:gravity="left"
if r:
data = r['extras']['SCAN_RESULT']
if data:
- if re.match('^bitcoin:', data):
+ if re.match('^novacoin:', data):
address, _, _, _, _ = util.parse_URI(data)
elif is_valid(data):
address = data
amount = droid.fullQueryDetail('amount').result.get('text')
if not is_valid(recipient):
- modal_dialog('Error','Invalid Bitcoin address')
+ modal_dialog('Error','Invalid Novacoin address')
continue
try:
- amount = int( 100000000 * Decimal(amount) )
+ amount = int( 1000000 * Decimal(amount) )
except Exception:
modal_dialog('Error','Invalid amount')
continue
if r:
data = r['extras']['SCAN_RESULT']
if data:
- if re.match('^bitcoin:', data):
+ if re.match('^novacoin:', data):
payto, amount, label, _, _ = util.parse_URI(data)
droid.fullSetProperty("recipient", "text",payto)
droid.fullSetProperty("amount", "text", amount)
def set_listview():
host, port, p = network.default_server.split(':')
- fee = str( Decimal( wallet.fee)/100000000 )
+ fee = str( Decimal( wallet.fee)/1000000 )
is_encrypted = 'yes' if wallet.use_encryption else 'no'
protocol = protocol_name(p)
droid.fullShow(settings_layout)
network_changed = True
elif pos == "3": #fee
- fee = modal_input('Transaction fee', 'The fee will be this amount multiplied by the number of inputs in your transaction. ', str( Decimal( wallet.fee)/100000000 ), "numberDecimal")
+ fee = modal_input('Transaction fee', 'The fee will be this amount multiplied by the number of inputs in your transaction. ', str( Decimal( wallet.fee)/1000000 ), "numberDecimal")
if fee:
try:
- fee = int( 100000000 * Decimal(fee) )
+ fee = int( 1000000 * Decimal(fee) )
except Exception:
modal_dialog('error','invalid fee value')
wallet.set_fee(fee)
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GObject, cairo
from decimal import Decimal
-from electrum.util import print_error
-from electrum.bitcoin import is_valid
-from electrum import mnemonic, WalletStorage, Wallet
+from electrum_nvc.util import print_error
+from electrum_nvc.bitcoin import is_valid
+from electrum_nvc import mnemonic, WalletStorage, Wallet
Gdk.threads_init()
-APP_NAME = "Electrum"
+APP_NAME = "Electrum-NVC"
import platform
MONOSPACE_FONT = 'Lucida Console' if platform.system() == 'Windows' else 'monospace'
-from electrum.util import format_satoshis, parse_URI
-from electrum.network import DEFAULT_SERVERS
-from electrum.bitcoin import MIN_RELAY_TX_FEE
+from electrum_nvc.util import format_satoshis, parse_URI
+from electrum_nvc.network import DEFAULT_SERVERS
+from electrum_nvc.bitcoin import MIN_RELAY_TX_FEE
def numbify(entry, is_int = False):
text = entry.get_text().strip()
s = s.replace('.','')
s = s[:p] + '.' + s[p:p+8]
try:
- amount = int( Decimal(s) * 100000000 )
+ amount = int( Decimal(s) * 1000000 )
except Exception:
amount = None
else:
fee_label.set_size_request(150,10)
fee_label.show()
fee.pack_start(fee_label,False, False, 10)
- fee_entry.set_text( str( Decimal(self.wallet.fee) /100000000 ) )
+ fee_entry.set_text( str( Decimal(self.wallet.fee) /1000000 ) )
fee_entry.connect('changed', numbify, False)
fee_entry.show()
fee.pack_start(fee_entry,False,False, 10)
return
try:
- fee = int( 100000000 * Decimal(fee) )
+ fee = int( 1000000 * Decimal(fee) )
except Exception:
show_message("error")
return
#assume two outputs - one for change
inputs, total, fee = self.wallet.choose_tx_inputs( amount, fee, 2 )
if not is_fee:
- fee_entry.set_text( str( Decimal( fee ) / 100000000 ) )
+ fee_entry.set_text( str( Decimal( fee ) / 1000000 ) )
self.fee_box.show()
if inputs:
amount_entry.modify_text(Gtk.StateType.NORMAL, Gdk.color_parse("#000000"))
to_address = r
if not is_valid(to_address):
- self.show_message( "invalid bitcoin address:\n"+to_address)
+ self.show_message( "invalid novacoin address:\n"+to_address)
return
try:
- amount = int( Decimal(amount_entry.get_text()) * 100000000 )
+ amount = int( Decimal(amount_entry.get_text()) * 1000000 )
except Exception:
self.show_message( "invalid amount")
return
try:
- fee = int( Decimal(fee_entry.get_text()) * 100000000 )
+ fee = int( Decimal(fee_entry.get_text()) * 1000000 )
except Exception:
self.show_message( "invalid fee")
return
treeview.append_column(tvcolumn)
cell = Gtk.CellRendererPixbuf()
tvcolumn.pack_start(cell, False)
- tvcolumn.set_attributes(cell, stock_id=1)
+ tvcolumn.set_attributes(cell, stock_id=1) # here is an exception
tvcolumn = Gtk.TreeViewColumn('Date')
treeview.append_column(tvcolumn)
cell.connect('editing-started', editing_started, self.history_list)
tvcolumn.set_expand(True)
tvcolumn.pack_start(cell, True)
- tvcolumn.set_attributes(cell, text=3, foreground_set = 4)
+ tvcolumn.set_attributes(cell, text=3, foreground_set = 4) # here is an exception
tvcolumn = Gtk.TreeViewColumn('Amount')
treeview.append_column(tvcolumn)
else:
time_str = 'pending'
- inputs = map(lambda x: x.get('address'), tx.inputs)
- outputs = map(lambda x: x[0], tx.get_outputs())
+ inputs = map(lambda x: x.get('address') if not x.get('is_coinbase') else 'Coinbase', tx.inputs)
+ outputs = map(lambda x: x[1] if x[2] != 0 else 'Zero', tx.get_outputs())
tx_details = "Transaction Details" +"\n\n" \
+ "Transaction ID:\n" + tx_hash + "\n\n" \
+ "Status: %d confirmations\n"%conf
# 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.plugins import run_hook
+from electrum_nvc.i18n import _, set_language
+from electrum_nvc.util import print_error, print_msg
+from electrum_nvc.plugins import run_hook
import os.path, json, ast, traceback
import shutil
from PyQt4.QtCore import *
import PyQt4.QtCore as QtCore
-from electrum import WalletStorage, Wallet
-from electrum.i18n import _
-from electrum.bitcoin import MIN_RELAY_TX_FEE
+from electrum_nvc import WalletStorage, Wallet
+from electrum_nvc.i18n import _
+from electrum_nvc.bitcoin import MIN_RELAY_TX_FEE
try:
import icons_rc
from util import *
from main_window import ElectrumWindow
-from electrum.plugins import init_plugins
+from electrum_nvc.plugins import init_plugins
class OpenFileEventFilter(QObject):
self.help_palette = QPalette()
def decimal_point(self):
- return 8
+ return 6
def numbify(self):
text = unicode(self.text()).strip()
def _base_unit(self):
p = self.decimal_point()
- assert p in [2, 5, 8]
- if p == 8:
- return 'BTC'
- if p == 5:
- return 'mBTC'
+ assert p in [2, 3, 6]
+ if p == 6:
+ return 'NVC'
+ if p == 3:
+ return 'mNVC'
if p == 2:
return 'bits'
raise Exception('Unknown base unit')
import traceback, platform
from PyQt4 import QtCore
from PyQt4 import QtGui
-from electrum import util
+from electrum_nvc import util
if platform.system() == 'Windows':
from PyQt4.QtGui import *
-from electrum.i18n import _
+from electrum_nvc.i18n import _
class HistoryWidget(QTreeWidget):
from PyQt4.QtCore import *
import PyQt4.QtCore as QtCore
-from electrum.i18n import _
-from electrum import Wallet, Wallet_2of2, Wallet_2of3
-from electrum import bitcoin
-from electrum import util
+from electrum_nvc.i18n import _
+from electrum_nvc import Wallet, Wallet_2of2, Wallet_2of3
+from electrum_nvc import bitcoin
+from electrum_nvc import util
import seed_dialog
from network_dialog import NetworkDialog
import sys
import threading
-from electrum.plugins import run_hook
+from electrum_nvc.plugins import run_hook
-MSG_ENTER_ANYTHING = _("Please enter a wallet seed, a master public key, a list of Bitcoin addresses, or a list of private keys")
+MSG_ENTER_ANYTHING = _("Please enter a wallet seed, a master public key, a list of Novacoin addresses, or a list of private keys")
MSG_SHOW_MPK = _("This is your master public key")
MSG_ENTER_MPK = _("Please enter your master public key")
MSG_ENTER_COLD_MPK = _("Please enter the master public key of your cosigner wallet")
sys.exit(0)
from decimal import Decimal as D
-from electrum.util import get_resource_path as rsrc
-from electrum.bitcoin import is_valid
-from electrum.i18n import _
+from electrum_nvc.util import get_resource_path as rsrc
+from electrum_nvc.bitcoin import is_valid
+from electrum_nvc.i18n import _
import decimal
import json
import os.path
import random
import re
import time
-from electrum.wallet import Wallet, WalletStorage
+from electrum_nvc.wallet import Wallet, WalletStorage
import webbrowser
import history_widget
import receiving_widget
-from electrum import util
+from electrum_nvc import util
import datetime
-from electrum.version import ELECTRUM_VERSION as electrum_version
-from electrum.util import format_satoshis, age
+from electrum_nvc.version import ELECTRUM_VERSION as electrum_version
+from electrum_nvc.util import format_satoshis, age
from main_window import ElectrumWindow
import shutil
from util import *
-bitcoin = lambda v: v * 100000000
+bitcoin = lambda v: v * 1000000
def IconButton(filename, parent=None):
pixmap = QPixmap(filename)
# Bitcoin address code
self.address_input = QLineEdit()
- self.address_input.setPlaceholderText(_("Enter a Bitcoin address or contact"))
+ self.address_input.setPlaceholderText(_("Enter a Novacoin address or contact"))
self.address_input.setObjectName("address_input")
self.address_input.setFocusPolicy(Qt.ClickFocus)
self.address_input.textChanged.connect(self.address_field_changed)
resize_line_edit_width(self.address_input,
- "1BtaFUr3qVvAmwrsuDuu5zk6e4s2rxd2Gy")
+ "4LJgtjeXMjLA6nVzYMJh1LEkwxMFsRtnP4")
self.address_completions = QStringListModel()
address_completer = QCompleter(self.address_input)
self.toggle_receiving_layout(show_hist)
self.setWindowIcon(QIcon(":icons/electrum.png"))
- self.setWindowTitle("Electrum")
+ self.setWindowTitle("Electrum-NVC")
self.setWindowFlags(Qt.Window|Qt.MSWindowsFixedSizeDialogHint)
self.layout().setSizeConstraint(QLayout.SetFixedSize)
self.setObjectName("main_window")
def create_quote_text(self, btc_balance):
"""Return a string copy of the amount fiat currency the
user has in bitcoins."""
- from electrum.plugins import run_hook
+ from electrum_nvc.plugins import run_hook
r = {}
run_hook('get_fiat_balance_text', btc_balance, r)
return r.get(0,'')
self.close()
def setup(self, address):
- label = QLabel(_("Copied your Bitcoin address to the clipboard!"))
+ label = QLabel(_("Copied your Novacoin address to the clipboard!"))
address_display = QLineEdit(address)
address_display.setReadOnly(True)
resize_line_edit_width(address_display, address)
main_layout.addWidget(address_display)
self.setMouseTracking(True)
- self.setWindowTitle("Electrum - " + _("Receive Bitcoin payment"))
+ self.setWindowTitle("Electrum - " + _("Receive Novacoin payment"))
self.setWindowFlags(Qt.Window|Qt.FramelessWindowHint|
Qt.MSWindowsFixedSizeDialogHint)
self.layout().setSizeConstraint(QLayout.SetFixedSize)
if dest_address is None or not is_valid(dest_address):
QMessageBox.warning(parent_window, _('Error'),
- _('Invalid Bitcoin Address') + ':\n' + address, _('OK'))
+ _('Invalid Novacoin Address') + ':\n' + address, _('OK'))
return False
amount = D(unicode(amount)) * (10*self.g.decimal_point)
password = None
fee = 0
- # 0.1 BTC = 10000000
+ # 0.1 NVC = 100000
if amount < bitcoin(1) / 10:
- # 0.001 BTC
+ # 0.001 NVC
fee = bitcoin(1) / 1000
try:
# 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 MyTreeWidget, HelpButton, EnterButton, line_dialog, text_dialog, ok_cancel_buttons, close_button, WaitingDialog
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()
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))
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)
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)
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)
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)
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'))
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys, time, datetime, re, threading
-from electrum.i18n import _
-from electrum.util import print_error, print_msg
+from electrum_nvc.i18n import _
+from electrum_nvc.util import print_error, print_msg
import os.path, json, ast, traceback
from PyQt4.QtGui import *
from PyQt4.QtCore import *
-from electrum import DEFAULT_SERVERS, DEFAULT_PORTS
+from electrum_nvc import DEFAULT_SERVERS, DEFAULT_PORTS
from util import *
from PyQt4.QtGui import *
from PyQt4.QtCore import *
-from electrum.i18n import _
+from electrum_nvc.i18n import _
from util import *
import re
from decimal import Decimal
-from electrum import bitcoin
+from electrum_nvc import bitcoin
RE_ADDRESS = '[1-9A-HJ-NP-Za-km-z]{26,}'
RE_ALIAS = '(.*?)\s*\<([1-9A-HJ-NP-Za-km-z]{26,})\>'
import os
import qrcode
-import electrum
-from electrum import bmp
-from electrum.i18n import _
+import electrum_nvc
+from electrum_nvc import bmp
+from electrum_nvc.i18n import _
class QRCodeWidget(QWidget):
hbox = QHBoxLayout()
hbox.addStretch(1)
- config = electrum.get_config()
+ config = electrum_nvc.get_config()
if config:
filename = os.path.join(config.path, "qrcode.bmp")
-from electrum.i18n import _
+from electrum_nvc.i18n import _
from PyQt4.QtGui import *
from PyQt4.QtCore import *
QRDialog(str(self.toPlainText())).exec_()
def qr_input(self):
- from electrum.plugins import run_hook
+ from electrum_nvc.plugins import run_hook
data = run_hook('scan_qr_hook')
if type(data) != str:
return
from PyQt4.QtGui import *
from PyQt4.QtCore import *
-from electrum.i18n import _
+from electrum_nvc.i18n import _
class ReceivingWidget(QTreeWidget):
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import PyQt4.QtCore as QtCore
-from electrum.i18n import _
-from electrum import mnemonic
+from electrum_nvc.i18n import _
+from electrum_nvc import mnemonic
from qrcodewidget import QRCodeWidget, QRDialog
from util import close_button
from qrtextedit import QRTextEdit
# 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 shutil
import StringIO
from PyQt4.QtCore import *
import PyQt4.QtCore as QtCore
-from electrum import transaction
-from electrum.plugins import run_hook
+from electrum_nvc import transaction
+from electrum_nvc.plugins import run_hook
from util import MyTreeWidget
vbox.addWidget(i_text)
vbox.addWidget(QLabel(_("Outputs")))
- lines = map(lambda x: x[0] + u'\t\t' + self.parent.format_amount(x[1]), self.tx.get_outputs())
+ lines = map(lambda x: x[1] + u'\t\t' + self.parent.format_amount(x[2]), self.tx.get_outputs())
o_text = QTextEdit()
o_text.setText('\n'.join(lines))
o_text.setReadOnly(True)
-from electrum.i18n import _
+from electrum_nvc.i18n import _
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import os.path
from PyQt4.QtCore import *
import PyQt4.QtCore as QtCore
-from electrum.i18n import _
-from electrum import ELECTRUM_VERSION, print_error
+from electrum_nvc.i18n import _
+from electrum_nvc import ELECTRUM_VERSION, print_error
class VersionGetter(threading.Thread):
from decimal import Decimal
_ = lambda x:x
#from i18n import _
-from electrum import mnemonic_encode, WalletStorage, Wallet
-from electrum.util import format_satoshis, set_verbosity
-from electrum.bitcoin import is_valid
-from electrum.network import filter_protocol
+from electrum_nvc import mnemonic_encode, WalletStorage, Wallet
+from electrum_nvc.util import format_satoshis, set_verbosity
+from electrum_nvc.bitcoin import is_valid
+from electrum_nvc.network import filter_protocol
import sys, getpass, datetime
# minimal fdisk like gui for console usage
self.config = config
storage = WalletStorage(config)
if not storage.file_exists:
- print "Wallet not found. try 'electrum create'"
+ print "Wallet not found. try 'electrum-nvc create'"
exit()
self.done = 0
msg = _( "Synchronizing..." )
else:
c, u = self.wallet.get_balance()
- msg = _("Balance")+": %f "%(Decimal( c ) / 100000000)
- if u: msg += " [%f unconfirmed]"%(Decimal( u ) / 100000000)
+ msg = _("Balance")+": %f "%(Decimal( c ) / 1000000)
+ if u: msg += " [%f unconfirmed]"%(Decimal( u ) / 1000000)
else:
msg = _( "Not connected" )
def do_send(self):
if not is_valid(self.str_recipient):
- print(_('Invalid Bitcoin address'))
+ print(_('Invalid Novacoin address'))
return
try:
- amount = int( Decimal( self.str_amount) * 100000000 )
+ amount = int( Decimal( self.str_amount) * 1000000 )
except Exception:
print(_('Invalid Amount'))
return
try:
- fee = int( Decimal( self.str_fee) * 100000000 )
+ fee = int( Decimal( self.str_fee) * 1000000 )
except Exception:
print(_('Invalid Fee'))
return
print(_('Error'))
def network_dialog(self):
- print("use 'electrum setconfig server/proxy' to change your network settings")
+ print("use 'electrum-nvc setconfig server/proxy' to change your network settings")
return True
def settings_dialog(self):
- print("use 'electrum setconfig' to change your settings")
+ print("use 'electrum-nvc setconfig' to change your settings")
return True
def password_dialog(self):
from decimal import Decimal
_ = lambda x:x
#from i18n import _
-from electrum.util import format_satoshis, set_verbosity
-from electrum.bitcoin import is_valid
+from electrum_nvc.util import format_satoshis, set_verbosity
+from electrum_nvc.bitcoin import is_valid
-from electrum import Wallet, WalletStorage
+from electrum_nvc import Wallet, WalletStorage
import tty, sys
self.network = network
storage = WalletStorage(config)
if not storage.file_exists:
- print "Wallet not found. try 'electrum create'"
+ print "Wallet not found. try 'electrum-nvc create'"
exit()
self.wallet = Wallet(storage)
msg = _("Synchronizing...")
else:
c, u = self.wallet.get_balance()
- msg = _("Balance")+": %f "%(Decimal( c ) / 100000000)
- if u: msg += " [%f unconfirmed]"%(Decimal( u ) / 100000000)
+ msg = _("Balance")+": %f "%(Decimal( c ) / 1000000)
+ if u: msg += " [%f unconfirmed]"%(Decimal( u ) / 1000000)
else:
msg = _("Not connected")
def do_send(self):
if not is_valid(self.str_recipient):
- self.show_message(_('Invalid Bitcoin address'))
+ self.show_message(_('Invalid Novacoin address'))
return
try:
- amount = int( Decimal( self.str_amount) * 100000000 )
+ amount = int( Decimal( self.str_amount) * 1000000 )
except Exception:
self.show_message(_('Invalid Amount'))
return
try:
- fee = int( Decimal( self.str_fee) * 100000000 )
+ fee = int( Decimal( self.str_fee) * 1000000 )
except Exception:
self.show_message(_('Invalid Fee'))
return
def pubkeys_to_address(self, pubkeys):
redeem_script = Transaction.multisig_script(sorted(pubkeys), 2)
- address = hash_160_to_bc_address(hash_160(redeem_script.decode('hex')), 5)
+ address = hash_160_to_bc_address(hash_160(redeem_script.decode('hex')), 20)
return address
def get_address(self, for_change, n):
h160 = hash_160(public_key)
return hash_160_to_bc_address(h160)
-def hash_160_to_bc_address(h160, addrtype = 0):
+def hash_160_to_bc_address(h160, addrtype = 8):
vh160 = chr(addrtype) + h160
h = Hash(vh160)
addr = vh160 + h[0:4]
return privkey[9:9+32]
-def SecretToASecret(secret, compressed=False, addrtype=0):
+def SecretToASecret(secret, compressed=False, addrtype=8):
vchIn = chr((addrtype+128)&255) + secret
if compressed: vchIn += '\01'
return EncodeBase58Check(vchIn)
-def ASecretToSecret(key, addrtype=0):
+def ASecretToSecret(key, addrtype=8):
vch = DecodeBase58Check(key)
if vch and vch[0] == chr((addrtype+128)&255):
return vch[1:]
def msg_magic(message):
varint = var_int(len(message))
encoded_varint = "".join([chr(int(varint[i:i+2], 16)) for i in xrange(0, len(varint), 2)])
- return "\x18Bitcoin Signed Message:\n" + encoded_varint + message
+ return "\x18Novacoin Signed Message:\n" + encoded_varint + message
def verify_message(address, signature, message):
def sign_message(self, message, compressed, address):
private_key = ecdsa.SigningKey.from_secret_exponent( self.secret, curve = SECP256k1 )
public_key = private_key.get_verifying_key()
- signature = private_key.sign_digest_deterministic( Hash( msg_magic(message) ), hashfunc=hashlib.sha256, sigencode = ecdsa.util.sigencode_string )
+ signature = private_key.sign_digest_deterministic( Hash( msg_magic(message) ), hashfunc=hashlib.sha256, sigencode = ecdsa.util.sigencode_string_canonize )
assert public_key.verify_digest( signature, Hash( msg_magic(message) ), sigdecode = ecdsa.util.sigdecode_string)
for i in range(4):
sig = base64.b64encode( chr(27 + i + (4 if compressed else 0)) + signature )
import hmac
header_pub, header_priv = _get_headers(testnet)
seed = seed.decode('hex')
- I = hmac.new("Bitcoin seed", seed, hashlib.sha512).digest()
+ I = hmac.new("Novacoin seed", seed, hashlib.sha512).digest()
master_k = I[0:32]
master_c = I[32:]
K, cK = get_pubkeys_from_secret(master_k)
from util import user_dir, appdata_dir, print_error
from bitcoin import *
+try:
+ from ltc_scrypt import getPoWHash
+except ImportError:
+ print_msg("Warning: scrypt not available, using fallback")
+ from scrypt import scrypt_1024_1_1_80 as getPoWHash
class Blockchain(threading.Thread):
self.lock = threading.Lock()
self.local_height = 0
self.running = False
- self.headers_url = 'http://headers.electrum.org/blockchain_headers'
+ self.headers_url = 'http://novacoin.su/static/blockchain_headers'
self.set_local_height()
self.queue = Queue.Queue()
-
+ def calculate_target(self, bits):
+ # convert to bignum
+ MM = 256*256*256
+ a = bits%MM
+ if a < 0x8000:
+ a *= 256
+ return (a) * pow(2, 8 * (bits/MM - 3))
+
+
def verify_chain(self, chain):
first_header = chain[0]
height = header.get('block_height')
prev_hash = self.hash_header(prev_header)
- bits, target = self.get_target(height/2016, chain)
- _hash = self.hash_header(header)
+ header_hash = self.hash_header(header)
+
try:
assert prev_hash == header.get('prev_block_hash')
- assert bits == header.get('bits')
- assert int('0x'+_hash,16) < target
+ if header.get('nonce') != 0:
+ assert int('0x'+_hash,16) < self.calculate_target(header.get('bits'))
except Exception:
return False
else:
prev_header = self.read_header(index*2016-1)
if prev_header is None: raise
- previous_hash = self.hash_header(prev_header)
-
- bits, target = self.get_target(index)
+ _hash = self.hash_header(prev_header)
for i in range(num):
height = index*2016 + i
raw_header = data[i*80:(i+1)*80]
header = self.header_from_string(raw_header)
- _hash = self.hash_header(header)
+ header_hash = self.hash_header(header)
+
assert previous_hash == header.get('prev_block_hash')
- assert bits == header.get('bits')
- assert int('0x'+_hash,16) < target
+ if header.get('nonce') != 0:
+ assert int('0x'+header_hash,16) < calculate_target(header.get('bits'))
previous_header = header
- previous_hash = _hash
+ previous_hash = header_hash
self.save_chunk(index, data)
print_error("validated chunk %d"%height)
return h
def hash_header(self, header):
- return rev_hex(Hash(self.header_to_string(header).decode('hex')).encode('hex'))
+ return rev_hex(getPoWHash(self.header_to_string(header).decode('hex')).encode('hex'))
def path(self):
return os.path.join( self.config.path, 'blockchain_headers')
h = self.header_from_string(h)
return h
-
- def get_target(self, index, chain=None):
- if chain is None:
- chain = [] # Do not use mutables as default values!
-
- max_target = 0x00000000FFFF0000000000000000000000000000000000000000000000000000
- if index == 0: return 0x1d00ffff, max_target
-
- first = self.read_header((index-1)*2016)
- last = self.read_header(index*2016-1)
- if last is None:
- for h in chain:
- if h.get('block_height') == index*2016-1:
- last = h
-
- nActualTimespan = last.get('timestamp') - first.get('timestamp')
- nTargetTimespan = 14*24*60*60
- nActualTimespan = max(nActualTimespan, nTargetTimespan/4)
- nActualTimespan = min(nActualTimespan, nTargetTimespan*4)
-
- bits = last.get('bits')
- # convert to bignum
- MM = 256*256*256
- a = bits%MM
- if a < 0x8000:
- a *= 256
- target = (a) * pow(2, 8 * (bits/MM - 3))
-
- # new target
- new_target = min( max_target, (target * nActualTimespan)/nTargetTimespan )
-
- # convert it to bits
- c = ("%064X"%new_target)[2:]
- i = 31
- while c[0:2]=="00":
- c = c[2:]
- i -= 1
-
- c = int('0x'+c[0:6],16)
- if c >= 0x800000:
- c /= 256
- i += 1
-
- new_bits = c + MM * i
- return new_bits, new_target
-
-
def request_header(self, i, h, queue):
print_error("requesting header %d from %s"%(h, i.server))
i.send([ ('blockchain.block.get_header',[h])], lambda i,r: queue.put((i,r)))
listaddr_options = " -a: show all addresses, including change addresses\n -l: include labels in results"
restore_options = " accepts a seed or master public key."
mksendmany_syntax = 'mksendmanytx <recipient> <amount> [<recipient> <amount> ...]'
-payto_syntax = "payto <recipient> <amount> [label]\n<recipient> can be a bitcoin address or a label"
-paytomany_syntax = "paytomany <recipient> <amount> [<recipient> <amount> ...]\n<recipient> can be a bitcoin address or a label"
+payto_syntax = "payto <recipient> <amount> [label]\n<recipient> can be a novacoin address or a label"
+paytomany_syntax = "paytomany <recipient> <amount> [<recipient> <amount> ...]\n<recipient> can be a novacoin address or a label"
signmessage_syntax = 'signmessage <address> <message>\nIf you want to lead or end a message with spaces, or want double spaces inside the message make sure you quote the string. I.e. " Hello This is a weird String "'
verifymessage_syntax = 'verifymessage <address> <signature> <message>\nIf you want to lead or end a message with spaces, or want double spaces inside the message make sure you quote the string. I.e. " Hello This is a weird String "'
# requires_password
register_command('contacts', 0, 0, False, True, False, 'Show your list of contacts')
register_command('create', 0, 0, False, True, False, 'Create a new wallet')
-register_command('createmultisig', 2, 2, False, True, False, 'similar to bitcoind\'s command')
-register_command('createrawtransaction', 2, 2, False, True, False, 'similar to bitcoind\'s command')
+register_command('createmultisig', 2, 2, False, True, False, 'similar to novacoind\'s command')
+register_command('createrawtransaction', 2, 2, False, True, False, 'similar to novacoind\'s command')
register_command('deseed', 0, 0, False, True, False, 'Remove seed from wallet, creating a seedless, watching-only wallet.')
-register_command('decoderawtransaction', 1, 1, False, False, False, 'similar to bitcoind\'s command')
-register_command('getprivatekeys', 1, 1, False, True, True, 'Get the private keys of a given address', 'getprivatekeys <bitcoin address>')
+register_command('decoderawtransaction', 1, 1, False, False, False, 'similar to novacoind\'s command')
+register_command('getprivatekeys', 1, 1, False, True, True, 'Get the private keys of a given address', 'getprivatekeys <novacoin address>')
register_command('dumpprivkeys', 0, 0, False, True, True, 'Dump all private keys in your wallet')
register_command('freeze', 1, 1, False, True, True, 'Freeze the funds at one of your wallet\'s addresses', 'freeze <address>')
register_command('getbalance', 0, 1, True, True, False, 'Return the balance of your wallet, or of one account in your wallet', 'getbalance [<account>]')
register_command('getaddressbalance', 1, 1, True, False, False, 'Return the balance of an address', 'getaddressbalance <address>')
register_command('getaddresshistory', 1, 1, True, False, False, 'Return the transaction history of a wallet address', 'getaddresshistory <address>')
register_command('getconfig', 1, 1, False, False, False, 'Return a configuration variable', 'getconfig <name>')
-register_command('getpubkeys', 1, 1, False, True, False, 'Return the public keys for a wallet address', 'getpubkeys <bitcoin address>')
+register_command('getpubkeys', 1, 1, False, True, False, 'Return the public keys for a wallet address', 'getpubkeys <novacoin address>')
register_command('getrawtransaction', 1, 1, True, False, False, 'Retrieve a transaction', 'getrawtransaction <txhash>')
register_command('getseed', 0, 0, False, True, True, 'Print the generation seed of your wallet.')
register_command('getmpk', 0, 0, False, True, False, 'Return your wallet\'s master public key', 'getmpk')
def listunspent(self):
l = copy.deepcopy(self.wallet.get_unspent_coins())
- for i in l: i["value"] = str(Decimal(i["value"])/100000000)
+ for i in l: i["value"] = str(Decimal(i["value"])/1000000)
return l
def getaddressunspent(self, addr):
i['prevout_hash'] = i['txid']
i['prevout_n'] = i['vout']
outputs = map(lambda x: (x[0],int(1e8*x[1])), outputs.items())
- tx = Transaction(inputs, outputs)
+ tx = Transaction(int(time.time()), inputs, outputs)
return tx
def signrawtransaction(self, raw_tx, private_keys):
def createmultisig(self, num, pubkeys):
assert isinstance(pubkeys, list)
redeem_script = Transaction.multisig_script(pubkeys, num)
- address = hash_160_to_bc_address(hash_160(redeem_script.decode('hex')), 5)
+ address = hash_160_to_bc_address(hash_160(redeem_script.decode('hex')), 20)
return {'address':address, 'redeemScript':redeem_script}
def freeze(self,addr):
else:
c, u = self.wallet.get_account_balance(account)
- out = { "confirmed": str(Decimal(c)/100000000) }
- if u: out["unconfirmed"] = str(Decimal(u)/100000000)
+ out = { "confirmed": str(Decimal(c)/1000000) }
+ if u: out["unconfirmed"] = str(Decimal(u)/1000000)
return out
def getaddressbalance(self, addr):
out = self.network.synchronous_get([ ('blockchain.address.get_balance',[addr]) ])[0]
- out["confirmed"] = str(Decimal(out["confirmed"])/100000000)
- out["unconfirmed"] = str(Decimal(out["unconfirmed"])/100000000)
+ out["confirmed"] = str(Decimal(out["confirmed"])/1000000)
+ out["unconfirmed"] = str(Decimal(out["unconfirmed"])/1000000)
return out
def getproof(self, addr):
return self.network.get_servers()
def getversion(self):
- import electrum # Needs to stay here to prevent ciruclar imports
+ import electrum_nvc # Needs to stay here to prevent ciruclar imports
return electrum.ELECTRUM_VERSION
def getmpk(self):
return out
def sweep(self, privkey, to_address, fee = 0.0001):
- fee = int(Decimal(fee)*100000000)
+ fee = int(Decimal(fee)*1000000)
return Transaction.sweep([privkey], self.network, to_address, fee)
def signmessage(self, address, message):
def _mktx(self, outputs, fee = None, change_addr = None, domain = None):
for to_address, amount in outputs:
if not is_valid(to_address):
- raise Exception("Invalid Bitcoin address", to_address)
+ raise Exception("Invalid Novacoin address", to_address)
if change_addr:
if not is_valid(change_addr):
- raise Exception("Invalid Bitcoin address", change_addr)
+ raise Exception("Invalid Novacoin address", change_addr)
if domain is not None:
for addr in domain:
if not is_valid(addr):
- raise Exception("invalid Bitcoin address", addr)
+ raise Exception("invalid Novacoin address", addr)
if not self.wallet.is_mine(addr):
raise Exception("address not in wallet", addr)
print_msg("alias", to_address)
break
- amount = int(100000000*amount)
+ amount = int(1000000*amount)
final_outputs.append(('address', to_address, amount))
- if fee: fee = int(100000000*fee)
+ if fee: fee = int(1000000*fee)
return self.wallet.mktx(final_outputs, self.password, fee , change_addr, domain)
def mktx(self, to_address, amount, fee = None, change_addr = None, domain = None):
def _(x):
global language
- return language.ugettext(x)
+ dic = [('Bitcoin', 'Novacoin'), ('bitcoin', 'novacoin')]
+ for b, l in dic:
+ x = x.replace(l, b)
+ t = language.ugettext(x)
+ for b, l in dic:
+ t = t.replace(b, l)
+ return t
def set_language(x):
global language
DEFAULT_PORTS = {'t':'50001', 's':'50002', 'h':'8081', 'g':'8082'}
DEFAULT_SERVERS = {
- 'ecdsa.org': DEFAULT_PORTS,
- 'ecdsa.net': DEFAULT_PORTS,
- 'electrum.hachre.de': DEFAULT_PORTS,
- 'electrum.novit.ro': DEFAULT_PORTS,
- 'electrum.coinwallet.me': DEFAULT_PORTS,
- 'cube.l0g.in': DEFAULT_PORTS,
- 'bitcoin.epicinet.net': DEFAULT_PORTS,
- 'h.1209k.com': DEFAULT_PORTS,
- 'electrum.electricnewyear.net': DEFAULT_PORTS,
- 'erbium.sytes.net': DEFAULT_PORTS,
- 'e2.pdmc.net':DEFAULT_PORTS,
- 'electrum.no-ip.org':{'h': '80', 's': '50002', 't': '50001', 'g': '443'},
- 'electrum.thwg.org':DEFAULT_PORTS,
- 'electrum.stepkrav.pw':DEFAULT_PORTS,
+ '127.0.0.1': DEFAULT_PORTS,
}
uri = sys.argv[1]
except:
print "usage: %s url"%sys.argv[0]
- print "example url: \"bitcoin:17KjQgnXC96jakzJe9yo8zxqerhqNptmhq?amount=0.0018&r=https%3A%2F%2Fbitpay.com%2Fi%2FMXc7qTM5f87EC62SWiS94z\""
+ print "example url: \"novacoin:4LJgtjeXMjLA6nVzYMJh1LEkwxMFsRtnP4?amount=0.0018&r=https%3A%2F%2Fsite.com%2F\""
sys.exit(1)
address, amount, label, message, request_url = util.parse_URI(uri)
fp, pathname, description = imp.find_module('plugins')
plugin_names = [name for a, name, b in pkgutil.iter_modules([pathname])]
plugin_names = filter( lambda name: os.path.exists(os.path.join(pathname,name+'.py')), plugin_names)
- imp.load_module('electrum_plugins', fp, pathname, description)
- plugin_modules = map(lambda name: imp.load_source('electrum_plugins.'+name, os.path.join(pathname,name+'.py')), plugin_names)
+ imp.load_module('electrum_nvc_plugins', fp, pathname, description)
+ plugin_modules = map(lambda name: imp.load_source('electrum_nvc_plugins.'+name, os.path.join(pathname,name+'.py')), plugin_names)
else:
- import electrum_plugins
- plugin_names = [name for a, name, b in pkgutil.iter_modules(electrum_plugins.__path__)]
- plugin_modules = [ __import__('electrum_plugins.'+name, fromlist=['electrum_plugins']) for name in plugin_names]
+ import electrum_nvc_plugins
+ plugin_names = [name for a, name, b in pkgutil.iter_modules(electrum_nvc_plugins.__path__)]
+ plugin_modules = [ __import__('electrum_nvc_plugins.'+name, fromlist=['electrum_nvc_plugins']) for name in plugin_names]
for name, p in zip(plugin_names, plugin_modules):
try:
from util import user_dir, print_error, print_msg
-SYSTEM_CONFIG_PATH = "/etc/electrum.conf"
+SYSTEM_CONFIG_PATH = "/etc/electrum-nvc.conf"
config = None
def set_key(self, key, value, save = True):
if not self.is_modifiable(key):
print "Warning: not changing key '%s' because it is not modifiable" \
- " (passed as command line option or defined in /etc/electrum.conf)"%key
+ " (passed as command line option or defined in /etc/electrum-nvc.conf)"%key
return
with self.lock:
os.chmod(path, stat.S_IREAD | stat.S_IWRITE)
def read_system_config(path=SYSTEM_CONFIG_PATH):
- """Parse and return the system config settings in /etc/electrum.conf."""
+ """Parse and return the system config settings in /etc/electrum-nvc.conf."""
result = {}
if os.path.exists(path):
try:
import ConfigParser
except ImportError:
- print "cannot parse electrum.conf. please install ConfigParser"
+ print "cannot parse electrum-nvc.conf. please install ConfigParser"
return
p = ConfigParser.ConfigParser()
return result
def read_user_config(path):
- """Parse and store the user config settings in electrum.conf into user_config[]."""
+ """Parse and store the user config settings in electrum-nvc.conf into user_config[]."""
if not path: return {} # Return a dict, since we will call update() on it.
config_path = os.path.join(path, "config")
os.remove(self.thefile)
def test_read_system_config_file_does_not_exist(self):
- somefile = "/foo/I/do/not/exist/electrum.conf"
+ somefile = "/foo/I/do/not/exist/electrum-nvc.conf"
result = read_system_config(somefile)
self.assertEqual({}, result)
d['pubkeys'] = pubkeys
redeemScript = Transaction.multisig_script(pubkeys,2)
d['redeemScript'] = redeemScript
- d['address'] = hash_160_to_bc_address(hash_160(redeemScript.decode('hex')), 5)
+ d['address'] = hash_160_to_bc_address(hash_160(redeemScript.decode('hex')), 20)
# p2sh
match = [ opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUAL ]
if match_decoded(decoded, match):
- return 'address', hash_160_to_bc_address(decoded[1][1],5)
+ return 'address', hash_160_to_bc_address(decoded[1][1],20)
return "(None)", "(None)"
d = {}
start = vds.read_cursor
d['version'] = vds.read_int32()
+ d['timestamp'] = vds.read_int32()
n_vin = vds.read_compact_size()
d['inputs'] = []
for i in xrange(n_vin):
def __str__(self):
if self.raw is None:
- self.raw = self.serialize(self.inputs, self.outputs, for_sig = None) # for_sig=-1 means do not sign
+ self.raw = self.serialize(self.timestamp, self.inputs, self.outputs, for_sig = None) # for_sig=-1 means do not sign
return self.raw
- def __init__(self, inputs, outputs, locktime=0):
+ def __init__(self, timestamp, inputs, outputs, locktime=0):
+ self.timestamp = timestamp
self.inputs = inputs
self.outputs = outputs
self.locktime = locktime
@classmethod
def deserialize(klass, raw):
- self = klass([],[])
+ self = klass(0, [],[])
self.update(raw)
return self
def update(self, raw):
d = deserialize(raw)
self.raw = raw
+ self.timestamp = d['timestamp']
self.inputs = d['inputs']
self.outputs = map(lambda x: (x['type'], x['address'], x['value']), d['outputs'])
self.locktime = d['lockTime']
-
@classmethod
def sweep(klass, privkeys, network, to_address, fee):
inputs = []
@classmethod
- def pay_script(self, type, addr):
+ def pay_script(self, type, payto):
+ assert type == 'address' or type == 'pubkey' or type == 'op_return'
+
if type == 'op_return':
- h = addr.encode('hex')
+ h = payto.encode('hex')
return '6a' + push_script(h)
+ elif type == 'pubkey':
+ script = push_script(payto)
+ script += 'ac' # op_checksig
+ return script
else:
- assert type == 'address'
- addrtype, hash_160 = bc_address_to_hash_160(addr)
- if addrtype == 0:
- script = '76a9' # op_dup, op_hash_160
- script += push_script(hash_160.encode('hex'))
- script += '88ac' # op_equalverify, op_checksig
- elif addrtype == 5:
- script = 'a9' # op_hash_160
- script += push_script(hash_160.encode('hex'))
- script += '87' # op_equal
- else:
- raise
- return script
+ addrtype, hash_160 = bc_address_to_hash_160(payto)
+ if addrtype == 8:
+ script = '76a9' # op_dup, op_hash_160
+ script += push_script(hash_160.encode('hex'))
+ script += '88ac' # op_equalverify, op_checksig
+ elif addrtype == 20:
+ script = 'a9' # op_hash_160
+ script += push_script(hash_160.encode('hex'))
+ script += '87' # op_equal
+ else:
+ raise
+ return script
@classmethod
- def serialize(klass, inputs, outputs, for_sig = None ):
-
+ def serialize(klass, timestamp, inputs, outputs, for_sig = None ):
s = int_to_hex(1,4) # version
+ s += int_to_hex(timestamp, 4) # timestamp
s += var_int( len(inputs) ) # number of inputs
for i in range(len(inputs)):
txin = inputs[i]
p2sh = txin.get('redeemScript') is not None
num_sig = txin['num_sig']
- address = txin['address']
+ payto = txin['address'] if txin["type"] == 'address' else txin['pubkeys'][0]
x_signatures = txin['signatures']
signatures = filter(lambda x: x is not None, x_signatures)
sig_list = ''.join( map( lambda x: push_script(x), sig_list))
if not p2sh:
script = sig_list
- script += push_script(pubkeys[0])
+ if txin["type"] != 'pubkey':
+ script += push_script(pubkeys[0])
else:
script = '00' # op_0
script += sig_list
script += push_script(redeem_script)
elif for_sig==i:
- script = txin['redeemScript'] if p2sh else klass.pay_script('address', address)
+ script = txin['redeemScript'] if p2sh else klass.pay_script(txin["type"], payto)
+ print script
else:
script = ''
s += var_int( len(script)/2 ) # script length
def tx_for_sig(self,i):
- return self.serialize(self.inputs, self.outputs, for_sig = i)
+ return self.serialize(self.timestamp, self.inputs, self.outputs, for_sig = i)
def hash(self):
txin['signatures'][ii] = sig
txin['x_pubkeys'][ii] = pubkey
self.inputs[i] = txin
- self.raw = self.serialize(self.inputs, self.outputs)
+ self.raw = self.serialize(self.timestamp, self.inputs, self.outputs)
def signature_count(self):
secexp = pkey.secret
private_key = ecdsa.SigningKey.from_secret_exponent( secexp, curve = SECP256k1 )
public_key = private_key.get_verifying_key()
- sig = private_key.sign_digest_deterministic( for_sig, hashfunc=hashlib.sha256, sigencode = ecdsa.util.sigencode_der )
+ sig = private_key.sign_digest_deterministic( for_sig, hashfunc=hashlib.sha256, sigencode = ecdsa.util.sigencode_der_canonize )
+
assert public_key.verify_digest( sig, for_sig, sigdecode = ecdsa.util.sigdecode_der)
self.add_signature(i, pubkey, sig.encode('hex'))
-
print_error("is_complete", self.is_complete())
- self.raw = self.serialize( self.inputs, self.outputs )
+ self.raw = self.serialize( self.timestamp, self.inputs, self.outputs )
def add_pubkey_addresses(self, txlist):
for i in self.inputs:
+ i["pubkey"] = False
if i.get("address") == "(pubkey)":
prev_tx = txlist.get(i.get('prevout_hash'))
if prev_tx:
- address, value = prev_tx.get_outputs()[i.get('prevout_n')]
+ type, address, value = prev_tx.get_outputs()[i.get('prevout_n')]
print_error("found pay-to-pubkey address:", address)
i["address"] = address
+ i["type"] = type
def get_outputs(self):
addr = public_key_to_bc_address(x.decode('hex'))
else:
addr = "(None)"
- o.append((addr,v))
+ o.append((type,addr,v))
+# print o
return o
def get_output_addresses(self):
- return map(lambda x:x[0], self.get_outputs())
+ return map(lambda x:x[1], self.get_outputs())
def has_address(self, addr):
if not is_send: is_partial = False
- for addr, value in self.get_outputs():
+ for type, addr, value in self.get_outputs():
v_out += value
if addr in addresses:
v_out_mine += value
def requires_fee(self, verifier):
- # see https://en.bitcoin.it/wiki/Transaction_fees
threshold = 57600000
size = len(self.raw)/2
- if size >= 10000:
+ if size >= 1000:
return True
for o in self.get_outputs():
- value = o[1]
- if value < 1000000:
+ value = o[2]
+ if value < 10000:
return True
sum = 0
for i in self.inputs:
def user_dir():
if "HOME" in os.environ:
- return os.path.join(os.environ["HOME"], ".electrum")
+ return os.path.join(os.environ["HOME"], ".electrum-nvc")
elif "APPDATA" in os.environ:
- return os.path.join(os.environ["APPDATA"], "Electrum")
+ return os.path.join(os.environ["APPDATA"], "Electrum-NVC")
elif "LOCALAPPDATA" in os.environ:
- return os.path.join(os.environ["LOCALAPPDATA"], "Electrum")
+ return os.path.join(os.environ["LOCALAPPDATA"], "Electrum-NVC")
elif 'ANDROID_DATA' in os.environ:
return "/sdcard/electrum/"
else:
def appdata_dir():
"""Find the path to the application data directory; add an electrum folder and return path."""
if platform.system() == "Windows":
- return os.path.join(os.environ["APPDATA"], "Electrum")
+ return os.path.join(os.environ["APPDATA"], "Electrum-NVC")
elif platform.system() == "Linux":
- return os.path.join(sys.prefix, "share", "electrum")
+ return os.path.join(sys.prefix, "share", "electrum-nvc")
elif (platform.system() == "Darwin" or
platform.system() == "DragonFly" or
platform.system() == "OpenBSD" or
platform.system() == "FreeBSD" or
platform.system() == "NetBSD"):
- return "/Library/Application Support/Electrum"
+ return "/Library/Application Support/Electrum-NVC"
else:
raise Exception("Unknown system")
return local_data
-def format_satoshis(x, is_diff=False, num_zeros = 0, decimal_point = 8, whitespaces=False):
+def format_satoshis(x, is_diff=False, num_zeros = 0, decimal_point = 6, whitespaces=False):
from decimal import Decimal
s = Decimal(x)
sign, digits, exp = s.as_tuple()
k = int(m.group(2)) - 8
amount = Decimal(m.group(1)) * pow( Decimal(10) , k)
else:
- amount = Decimal(am) * 100000000
+ amount = Decimal(am) * 1000000
if 'message' in pq:
message = pq['message'][0]
if 'label' in pq:
import bitcoin
from synchronizer import WalletSynchronizer
-COINBASE_MATURITY = 100
-DUST_THRESHOLD = 5430
+COINBASE_MATURITY = 500
+DUST_THRESHOLD = 1000
# internal ID for imported account
IMPORTED_ACCOUNT = '/x'
new_path = os.path.join(config.path, "wallets", "default_wallet")
# default path in pre 1.9 versions
- old_path = os.path.join(config.path, "electrum.dat")
+ old_path = os.path.join(config.path, "electrum-nvc.dat")
if os.path.exists(old_path) and not os.path.exists(new_path):
os.rename(old_path, new_path)
self.history = storage.get('addr_history',{}) # address -> list(txid, height)
- self.fee = int(storage.get('fee_per_kb', 10000))
+ self.fee = int(storage.get('fee_per_kb', 1000))
self.next_addresses = storage.get('next_addresses',{})
for k, raw in tx_list.items():
try:
tx = Transaction.deserialize(raw)
- except Exception:
+ except Exception, e:
print_msg("Warning: Cannot deserialize transactions. skipping")
continue
self.add_pubkey_addresses(tx)
def update_tx_outputs(self, tx_hash):
tx = self.transactions.get(tx_hash)
- for i, (addr, value) in enumerate(tx.get_outputs()):
+ for i, (type, addr, value) in enumerate(tx.get_outputs()):
key = tx_hash+ ':%d'%i
self.prevout_values[key] = value
tx = self.transactions.get(tx_hash)
if not tx: continue
- for i, (addr, value) in enumerate(tx.get_outputs()):
+ for i, (type, addr, value) in enumerate(tx.get_outputs()):
if addr == address:
key = tx_hash + ':%d'%i
received_coins.append(key)
if key in received_coins:
v -= value
- for i, (addr, value) in enumerate(tx.get_outputs()):
+ for i, (type, addr, value) in enumerate(tx.get_outputs()):
key = tx_hash + ':%d'%i
if addr == address:
v += value
for tx_hash, tx_height in h:
tx = self.transactions.get(tx_hash)
if tx is None: raise Exception("Wallet not synchronized")
+ outputs = tx.get_outputs()
+
is_coinbase = tx.inputs[0].get('prevout_hash') == '0'*64
- for i, (address, value) in enumerate(tx.get_outputs()):
+ is_coinstake = outputs[0][2] == 0
+
+ #print is_coinstake
+
+ for i, (type, address, value) in enumerate(outputs):
output = {'address':address, 'value':value, 'prevout_n':i}
if address != addr: continue
key = tx_hash + ":%d"%i
output['prevout_hash'] = tx_hash
output['height'] = tx_height
output['coinbase'] = is_coinbase
+ output['coinstake'] = is_coinstake
+ output["type"] = type
coins.append((tx_height, output))
# sort by age
inputs = []
for item in coins:
- if item.get('coinbase') and item.get('height') + COINBASE_MATURITY > self.network.get_local_height():
+ if (item.get('coinbase') or item.get('coinstake')) and item.get('height') + COINBASE_MATURITY < self.network.get_local_height():
continue
v = item.get('value')
total += v
for txin in inputs:
self.add_input_info(txin)
outputs = self.add_tx_change(inputs, outputs, amount, fee, total, change_addr)
- return Transaction(inputs, outputs)
+ return Transaction(int(time.time()), inputs, outputs)
def mktx(self, outputs, password, fee=None, change_addr=None, domain= None, coins = None ):
tx = self.make_unsigned_transaction(outputs, fee, change_addr, domain, coins)
os.system("pyrcc4 icons.qrc -o gui/qt/icons_rc.py")
os.system("python setup.py sdist --format=zip,gztar")
- _tgz="Electrum-%s.tar.gz"%version
- _zip="Electrum-%s.zip"%version
+ _tgz="Electrum-NVC-%s.tar.gz"%version
+ _zip="Electrum-NVC-%s.zip"%version
# android
- os.system('rm -rf dist/e4a-%s'%version)
- os.mkdir('dist/e4a-%s'%version)
- shutil.copyfile("electrum",'dist/e4a-%s/e4a.py'%version)
- shutil.copytree("packages",'dist/e4a-%s/packages'%version)
- shutil.copytree("lib",'dist/e4a-%s/lib'%version)
- os.mkdir('dist/e4a-%s/gui'%version)
+ os.system('rm -rf dist/en4a-%s'%version)
+ os.mkdir('dist/en4a-%s'%version)
+ shutil.copyfile("electrum-nvc",'dist/en4a-%s/en4a.py'%version)
+ shutil.copytree("packages",'dist/en4a-%s/packages'%version)
+ shutil.copytree("lib",'dist/en4a-%s/lib'%version)
+ os.mkdir('dist/en4a-%s/gui'%version)
for n in ['android.py']:
- shutil.copy("gui/%s"%n,'dist/e4a-%s/gui'%version)
- open('dist/e4a-%s/gui/__init__.py'%version,'w').close()
+ shutil.copy("gui/%s"%n,'dist/en4a-%s/gui'%version)
+ open('dist/en4a-%s/gui/__init__.py'%version,'w').close()
os.chdir("dist")
# create the zip file
- os.system( "zip -r e4a-%s.zip e4a-%s"%(version, version) )
- os.system( "rm -rf e4a-%s"%(version) )
+ os.system( "zip -r e4na-%s.zip en4a-%s"%(version, version) )
+ os.system( "rm -rf en4a-%s"%(version) )
# change filename because some 3G carriers do not allow users to download a zip file...
- e4a_name = "e4a-%s.zip"%version
+ e4a_name = "en4a-%s.zip"%version
e4a_name2 = e4a_name.replace(".","")
os.system( "mv %s %s"%(e4a_name, e4a_name2) )
+++ /dev/null
-import PyQt4
-import sys
-
-import PyQt4.QtCore as QtCore
-import base64
-import urllib
-import re
-import time
-import os
-import httplib
-import datetime
-import json
-import string
-
-from urllib import urlencode
-
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
-try:
- from PyQt4.QtWebKit import QWebView
- loaded_qweb = True
-except ImportError as e:
- loaded_qweb = False
-
-from electrum import BasePlugin
-from electrum.i18n import _, set_language
-from electrum.util import user_dir
-from electrum.util import appdata_dir
-from electrum.util import format_satoshis
-from electrum_gui.qt import ElectrumGui
-
-SATOSHIS_PER_BTC = float(100000000)
-COINBASE_ENDPOINT = 'https://coinbase.com'
-SCOPE = 'buy'
-REDIRECT_URI = 'urn:ietf:wg:oauth:2.0:oob'
-TOKEN_URI = 'https://coinbase.com/oauth/token'
-CLIENT_ID = '0a930a48b5a6ea10fb9f7a9fec3d093a6c9062ef8a7eeab20681274feabdab06'
-CLIENT_SECRET = 'f515989e8819f1822b3ac7a7ef7e57f755c9b12aee8f22de6b340a99fd0fd617'
-# Expiry is stored in RFC3339 UTC format
-EXPIRY_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
-
-class Plugin(BasePlugin):
-
- def fullname(self): return 'Coinbase BuyBack'
-
- def description(self): return 'After sending bitcoin, prompt the user with the option to rebuy them via Coinbase.\n\nMarcell Ortutay, 1FNGQvm29tKM7y3niq63RKi7Qbg7oZ3jrB'
-
- def __init__(self, gui, name):
- BasePlugin.__init__(self, gui, name)
- self._is_available = self._init()
-
- def _init(self):
- return loaded_qweb
-
- def is_available(self):
- return self._is_available
-
- def enable(self):
- return BasePlugin.enable(self)
-
- def receive_tx(self, tx, wallet):
- domain = wallet.get_account_addresses(None)
- is_relevant, is_send, v, fee = tx.get_value(domain, wallet.prevout_values)
- if isinstance(self.gui, ElectrumGui):
- try:
- web = propose_rebuy_qt(abs(v))
- except OAuth2Exception as e:
- rm_local_oauth_credentials()
- # TODO(ortutay): android flow
-
-
-def propose_rebuy_qt(amount):
- web = QWebView()
- box = QMessageBox()
- box.setFixedSize(200, 200)
-
- credentials = read_local_oauth_credentials()
- questionText = _('Rebuy ') + format_satoshis(amount) + _(' BTC?')
- if credentials:
- credentials.refresh()
- if credentials and not credentials.invalid:
- credentials.store_locally()
- totalPrice = get_coinbase_total_price(credentials, amount)
- questionText += _('\n(Price: ') + totalPrice + _(')')
-
- if not question(box, questionText):
- return
-
- if credentials:
- do_buy(credentials, amount)
- else:
- do_oauth_flow(web, amount)
- return web
-
-def do_buy(credentials, amount):
- conn = httplib.HTTPSConnection('coinbase.com')
- credentials.authorize(conn)
- params = {
- 'qty': float(amount)/SATOSHIS_PER_BTC,
- 'agree_btc_amount_varies': False
- }
- resp = conn.auth_request('POST', '/api/v1/buys', urlencode(params), None)
-
- if resp.status != 200:
- message(_('Error, could not buy bitcoin'))
- return
- content = json.loads(resp.read())
- if content['success']:
- message(_('Success!\n') + content['transfer']['description'])
- else:
- if content['errors']:
- message(_('Error: ') + string.join(content['errors'], '\n'))
- else:
- message(_('Error, could not buy bitcoin'))
-
-def get_coinbase_total_price(credentials, amount):
- conn = httplib.HTTPSConnection('coinbase.com')
- params={'qty': amount/SATOSHIS_PER_BTC}
- conn.request('GET', '/api/v1/prices/buy?' + urlencode(params))
- resp = conn.getresponse()
- if resp.status != 200:
- return 'unavailable'
- content = json.loads(resp.read())
- return '$' + content['total']['amount']
-
-def do_oauth_flow(web, amount):
- # QT expects un-escaped URL
- auth_uri = step1_get_authorize_url()
- web.load(QUrl(auth_uri))
- web.setFixedSize(500, 700)
- web.show()
- web.titleChanged.connect(lambda(title): complete_oauth_flow(title, web, amount) if re.search('^[a-z0-9]+$', title) else False)
-
-def complete_oauth_flow(token, web, amount):
- web.close()
- credentials = step2_exchange(str(token))
- credentials.store_locally()
- do_buy(credentials, amount)
-
-def token_path():
- dir = user_dir() + '/coinbase_buyback'
- if not os.access(dir, os.F_OK):
- os.mkdir(dir)
- return dir + '/token'
-
-def read_local_oauth_credentials():
- if not os.access(token_path(), os.F_OK):
- return None
- f = open(token_path(), 'r')
- data = f.read()
- f.close()
- try:
- credentials = Credentials.from_json(data)
- return credentials
- except Exception as e:
- return None
-
-def rm_local_oauth_credentials():
- os.remove(token_path())
-
-def step1_get_authorize_url():
- return ('https://coinbase.com/oauth/authorize'
- + '?scope=' + SCOPE
- + '&redirect_uri=' + REDIRECT_URI
- + '&response_type=code'
- + '&client_id=' + CLIENT_ID
- + '&access_type=offline')
-
-def step2_exchange(code):
- body = urllib.urlencode({
- 'grant_type': 'authorization_code',
- 'client_id': CLIENT_ID,
- 'client_secret': CLIENT_SECRET,
- 'code': code,
- 'redirect_uri': REDIRECT_URI,
- 'scope': SCOPE,
- })
- headers = {
- 'content-type': 'application/x-www-form-urlencoded',
- }
-
- conn = httplib.HTTPSConnection('coinbase.com')
- conn.request('POST', TOKEN_URI, body, headers)
- resp = conn.getresponse()
- if resp.status == 200:
- d = json.loads(resp.read())
- access_token = d['access_token']
- refresh_token = d.get('refresh_token', None)
- token_expiry = None
- if 'expires_in' in d:
- token_expiry = datetime.datetime.utcnow() + datetime.timedelta(
- seconds=int(d['expires_in']))
- return Credentials(access_token, refresh_token, token_expiry)
- else:
- raise OAuth2Exception(content)
-
-class OAuth2Exception(Exception):
- """An error related to OAuth2"""
-
-class Credentials(object):
- def __init__(self, access_token, refresh_token, token_expiry):
- self.access_token = access_token
- self.refresh_token = refresh_token
- self.token_expiry = token_expiry
-
- # Indicates a failed refresh
- self.invalid = False
-
- def to_json(self):
- token_expiry = self.token_expiry
- if (token_expiry and isinstance(token_expiry, datetime.datetime)):
- token_expiry = token_expiry.strftime(EXPIRY_FORMAT)
-
- d = {
- 'access_token': self.access_token,
- 'refresh_token': self.refresh_token,
- 'token_expiry': token_expiry,
- }
- return json.dumps(d)
-
- def store_locally(self):
- f = open(token_path(), 'w')
- f.write(self.to_json())
- f.close()
-
- @classmethod
- def from_json(cls, s):
- data = json.loads(s)
- if ('token_expiry' in data
- and not isinstance(data['token_expiry'], datetime.datetime)):
- try:
- data['token_expiry'] = datetime.datetime.strptime(
- data['token_expiry'], EXPIRY_FORMAT)
- except:
- data['token_expiry'] = None
- retval = Credentials(
- data['access_token'],
- data['refresh_token'],
- data['token_expiry'])
- return retval
-
- def apply(self, headers):
- headers['Authorization'] = 'Bearer ' + self.access_token
-
- def authorize(self, conn):
- request_orig = conn.request
-
- def new_request(method, uri, params, headers):
- if headers == None:
- headers = {}
- self.apply(headers)
- request_orig(method, uri, params, headers)
- resp = conn.getresponse()
- if resp.status == 401:
- # Refresh and try again
- self._refresh(request_orig)
- self.store_locally()
- self.apply(headers)
- request_orig(method, uri, params, headers)
- return conn.getresponse()
- else:
- return resp
-
- conn.auth_request = new_request
- return conn
-
- def refresh(self):
- try:
- self._refresh()
- except OAuth2Exception as e:
- rm_local_oauth_credentials()
- self.invalid = True
- raise e
-
- def _refresh(self):
- conn = httplib.HTTPSConnection('coinbase.com')
- body = urllib.urlencode({
- 'grant_type': 'refresh_token',
- 'refresh_token': self.refresh_token,
- 'client_id': CLIENT_ID,
- 'client_secret': CLIENT_SECRET,
- })
- headers = {
- 'content-type': 'application/x-www-form-urlencoded',
- }
- conn.request('POST', TOKEN_URI, body, headers)
- resp = conn.getresponse()
- if resp.status == 200:
- d = json.loads(resp.read())
- self.token_response = d
- self.access_token = d['access_token']
- self.refresh_token = d.get('refresh_token', self.refresh_token)
- if 'expires_in' in d:
- self.token_expiry = datetime.timedelta(
- seconds=int(d['expires_in'])) + datetime.datetime.utcnow()
- else:
- raise OAuth2Exception('Refresh failed, ' + content)
-
-def message(msg):
- box = QMessageBox()
- box.setFixedSize(200, 200)
- return QMessageBox.information(box, _('Message'), msg)
-
-def question(widget, msg):
- return (QMessageBox.question(
- widget, _('Message'), msg, QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
- == QMessageBox.Yes)
-
-def main():
- app = QApplication(sys.argv)
- print sys.argv[1]
- propose_rebuy_qt(int(sys.argv[1]))
- sys.exit(app.exec_())
-
-if __name__ == "__main__":
- main()
+++ /dev/null
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
-
-import datetime
-import decimal
-import httplib
-import json
-import threading
-import time
-import re
-from decimal import Decimal
-from electrum.plugins import BasePlugin
-from electrum.i18n import _
-from electrum_gui.qt.util import *
-from electrum_gui.qt.amountedit import AmountEdit
-
-
-EXCHANGES = ["BitcoinAverage",
- "BitcoinVenezuela",
- "Bitcurex",
- "Bitmarket",
- "BitPay",
- "Blockchain",
- "BTCChina",
- "CaVirtEx",
- "Coinbase",
- "CoinDesk",
- "LocalBitcoins",
- "Winkdex"]
-
-
-class Exchanger(threading.Thread):
-
- def __init__(self, parent):
- threading.Thread.__init__(self)
- self.daemon = True
- self.parent = parent
- self.quote_currencies = None
- self.lock = threading.Lock()
- self.query_rates = threading.Event()
- self.use_exchange = self.parent.config.get('use_exchange', "Blockchain")
- self.parent.exchanges = EXCHANGES
- self.parent.currencies = ["EUR","GBP","USD","PLN"]
- self.parent.win.emit(SIGNAL("refresh_exchanges_combo()"))
- self.parent.win.emit(SIGNAL("refresh_currencies_combo()"))
- self.is_running = False
-
- def get_json(self, site, get_string):
- try:
- connection = httplib.HTTPSConnection(site)
- connection.request("GET", get_string)
- except Exception:
- raise
- resp = connection.getresponse()
- if resp.reason == httplib.responses[httplib.NOT_FOUND]:
- raise
- try:
- json_resp = json.loads(resp.read())
- except Exception:
- raise
- return json_resp
-
-
- def exchange(self, btc_amount, quote_currency):
- with self.lock:
- if self.quote_currencies is None:
- return None
- quote_currencies = self.quote_currencies.copy()
- if quote_currency not in quote_currencies:
- return None
- if self.use_exchange == "CoinDesk":
- try:
- resp_rate = self.get_json('api.coindesk.com', "/v1/bpi/currentprice/" + str(quote_currency) + ".json")
- except Exception:
- return
- return btc_amount * decimal.Decimal(str(resp_rate["bpi"][str(quote_currency)]["rate_float"]))
- return btc_amount * decimal.Decimal(str(quote_currencies[quote_currency]))
-
- def stop(self):
- self.is_running = False
-
- def update_rate(self):
- self.use_exchange = self.parent.config.get('use_exchange', "Blockchain")
- update_rates = {
- "BitcoinAverage": self.update_ba,
- "BitcoinVenezuela": self.update_bv,
- "Bitcurex": self.update_bx,
- "Bitmarket": self.update_bm,
- "BitPay": self.update_bp,
- "Blockchain": self.update_bc,
- "BTCChina": self.update_CNY,
- "CaVirtEx": self.update_cv,
- "CoinDesk": self.update_cd,
- "Coinbase": self.update_cb,
- "LocalBitcoins": self.update_lb,
- "Winkdex": self.update_wd,
- }
- try:
- update_rates[self.use_exchange]()
- except KeyError:
- return
-
- def run(self):
- self.is_running = True
- while self.is_running:
- self.query_rates.clear()
- self.update_rate()
- self.query_rates.wait(150)
-
-
- def update_cd(self):
- try:
- resp_currencies = self.get_json('api.coindesk.com', "/v1/bpi/supported-currencies.json")
- except Exception:
- return
-
- quote_currencies = {}
- for cur in resp_currencies:
- quote_currencies[str(cur["currency"])] = 0.0
- with self.lock:
- self.quote_currencies = quote_currencies
- self.parent.set_currencies(quote_currencies)
-
- def update_wd(self):
- try:
- winkresp = self.get_json('winkdex.com', "/static/data/0_600_288.json")
- ####could need nonce value in GET, no Docs available
- except Exception:
- return
- quote_currencies = {"USD": 0.0}
- ####get y of highest x in "prices"
- lenprices = len(winkresp["prices"])
- usdprice = winkresp["prices"][lenprices-1]["y"]
- try:
- quote_currencies["USD"] = decimal.Decimal(str(usdprice))
- with self.lock:
- self.quote_currencies = quote_currencies
- except KeyError:
- pass
- self.parent.set_currencies(quote_currencies)
-
- def update_cv(self):
- try:
- jsonresp = self.get_json('www.cavirtex.com', "/api/CAD/ticker.json")
- except Exception:
- return
- quote_currencies = {"CAD": 0.0}
- cadprice = jsonresp["last"]
- try:
- quote_currencies["CAD"] = decimal.Decimal(str(cadprice))
- with self.lock:
- self.quote_currencies = quote_currencies
- except KeyError:
- pass
- self.parent.set_currencies(quote_currencies)
-
- def update_bm(self):
- try:
- jsonresp = self.get_json('www.bitmarket.pl', "/json/BTCPLN/ticker.json")
- except Exception:
- return
- quote_currencies = {"PLN": 0.0}
- pln_price = jsonresp["last"]
- try:
- quote_currencies["PLN"] = decimal.Decimal(str(pln_price))
- with self.lock:
- self.quote_currencies = quote_currencies
- except KeyError:
- pass
- self.parent.set_currencies(quote_currencies)
-
- def update_bx(self):
- try:
- jsonresp = self.get_json('pln.bitcurex.com', "/data/ticker.json")
- except Exception:
- return
- quote_currencies = {"PLN": 0.0}
- pln_price = jsonresp["last"]
- try:
- quote_currencies["PLN"] = decimal.Decimal(str(pln_price))
- with self.lock:
- self.quote_currencies = quote_currencies
- except KeyError:
- pass
- self.parent.set_currencies(quote_currencies)
-
- def update_CNY(self):
- try:
- jsonresp = self.get_json('data.btcchina.com', "/data/ticker")
- except Exception:
- return
- quote_currencies = {"CNY": 0.0}
- cnyprice = jsonresp["ticker"]["last"]
- try:
- quote_currencies["CNY"] = decimal.Decimal(str(cnyprice))
- with self.lock:
- self.quote_currencies = quote_currencies
- except KeyError:
- pass
- self.parent.set_currencies(quote_currencies)
-
- def update_bp(self):
- try:
- jsonresp = self.get_json('bitpay.com', "/api/rates")
- except Exception:
- return
- quote_currencies = {}
- try:
- for r in jsonresp:
- quote_currencies[str(r["code"])] = decimal.Decimal(r["rate"])
- with self.lock:
- self.quote_currencies = quote_currencies
- except KeyError:
- pass
- self.parent.set_currencies(quote_currencies)
-
- def update_cb(self):
- try:
- jsonresp = self.get_json('coinbase.com', "/api/v1/currencies/exchange_rates")
- except Exception:
- return
-
- quote_currencies = {}
- try:
- for r in jsonresp:
- if r[:7] == "btc_to_":
- quote_currencies[r[7:].upper()] = self._lookup_rate_cb(jsonresp, r)
- with self.lock:
- self.quote_currencies = quote_currencies
- except KeyError:
- pass
- self.parent.set_currencies(quote_currencies)
-
-
- def update_bc(self):
- try:
- jsonresp = self.get_json('blockchain.info', "/ticker")
- except Exception:
- return
- quote_currencies = {}
- try:
- for r in jsonresp:
- quote_currencies[r] = self._lookup_rate(jsonresp, r)
- with self.lock:
- self.quote_currencies = quote_currencies
- except KeyError:
- pass
- self.parent.set_currencies(quote_currencies)
- # print "updating exchange rate", self.quote_currencies["USD"]
-
- def update_lb(self):
- try:
- jsonresp = self.get_json('localbitcoins.com', "/bitcoinaverage/ticker-all-currencies/")
- except Exception:
- return
- quote_currencies = {}
- try:
- for r in jsonresp:
- quote_currencies[r] = self._lookup_rate_lb(jsonresp, r)
- with self.lock:
- self.quote_currencies = quote_currencies
- except KeyError:
- pass
- self.parent.set_currencies(quote_currencies)
-
-
- def update_bv(self):
- try:
- jsonresp = self.get_json('api.bitcoinvenezuela.com', "/")
- except Exception:
- return
- quote_currencies = {}
- try:
- for r in jsonresp["BTC"]:
- quote_currencies[r] = Decimal(jsonresp["BTC"][r])
- with self.lock:
- self.quote_currencies = quote_currencies
- except KeyError:
- pass
- self.parent.set_currencies(quote_currencies)
-
-
- def update_ba(self):
- try:
- jsonresp = self.get_json('api.bitcoinaverage.com', "/ticker/global/all")
- except Exception:
- return
- quote_currencies = {}
- try:
- for r in jsonresp:
- if not r == "timestamp":
- quote_currencies[r] = self._lookup_rate_ba(jsonresp, r)
- with self.lock:
- self.quote_currencies = quote_currencies
- except KeyError:
- pass
- self.parent.set_currencies(quote_currencies)
-
-
- def get_currencies(self):
- return [] if self.quote_currencies == None else sorted(self.quote_currencies.keys())
-
- def _lookup_rate(self, response, quote_id):
- return decimal.Decimal(str(response[str(quote_id)]["15m"]))
- def _lookup_rate_cb(self, response, quote_id):
- return decimal.Decimal(str(response[str(quote_id)]))
- def _lookup_rate_ba(self, response, quote_id):
- return decimal.Decimal(response[str(quote_id)]["last"])
- def _lookup_rate_lb(self, response, quote_id):
- return decimal.Decimal(response[str(quote_id)]["rates"]["last"])
-
-
-class Plugin(BasePlugin):
-
- def fullname(self):
- return "Exchange rates"
-
- def description(self):
- return """exchange rates, retrieved from blockchain.info, CoinDesk, or Coinbase"""
-
-
- def __init__(self,a,b):
- BasePlugin.__init__(self,a,b)
- self.currencies = [self.fiat_unit()]
- self.exchanges = [self.config.get('use_exchange', "Blockchain")]
-
- def init(self):
- self.win = self.gui.main_window
- self.win.connect(self.win, SIGNAL("refresh_currencies()"), self.win.update_status)
- self.btc_rate = Decimal("0.0")
- # Do price discovery
- self.exchanger = Exchanger(self)
- self.exchanger.start()
- self.gui.exchanger = self.exchanger #
- self.add_fiat_edit()
-
- def set_currencies(self, currency_options):
- self.currencies = sorted(currency_options)
- self.win.emit(SIGNAL("refresh_currencies()"))
- self.win.emit(SIGNAL("refresh_currencies_combo()"))
-
- def get_fiat_balance_text(self, btc_balance, r):
- # return balance as: 1.23 USD
- r[0] = self.create_fiat_balance_text(Decimal(btc_balance) / 100000000)
-
- def get_fiat_price_text(self, r):
- # return BTC price as: 123.45 USD
- r[0] = self.create_fiat_balance_text(1)
- quote = r[0]
- if quote:
- r[0] = "%s"%quote
-
- def get_fiat_status_text(self, btc_balance, r2):
- # return status as: (1.23 USD) 1 BTC~123.45 USD
- text = ""
- r = {}
- self.get_fiat_price_text(r)
- quote = r.get(0)
- if quote:
- price_text = "1 BTC~%s"%quote
- fiat_currency = quote[-3:]
- btc_price = self.btc_rate
- fiat_balance = Decimal(btc_price) * (Decimal(btc_balance)/100000000)
- balance_text = "(%.2f %s)" % (fiat_balance,fiat_currency)
- text = " " + balance_text + " " + price_text + " "
- r2[0] = text
-
- def create_fiat_balance_text(self, btc_balance):
- quote_currency = self.fiat_unit()
- self.exchanger.use_exchange = self.config.get("use_exchange", "Blockchain")
- cur_rate = self.exchanger.exchange(Decimal("1.0"), quote_currency)
- if cur_rate is None:
- quote_text = ""
- else:
- quote_balance = btc_balance * Decimal(cur_rate)
- self.btc_rate = cur_rate
- quote_text = "%.2f %s" % (quote_balance, quote_currency)
- return quote_text
-
- def load_wallet(self, wallet):
- self.wallet = wallet
- tx_list = {}
- for item in self.wallet.get_tx_history(self.wallet.storage.get("current_account", None)):
- tx_hash, conf, is_mine, value, fee, balance, timestamp = item
- tx_list[tx_hash] = {'value': value, 'timestamp': timestamp, 'balance': balance}
-
- self.tx_list = tx_list
-
-
- def requires_settings(self):
- return True
-
-
- def toggle(self):
- enabled = BasePlugin.toggle(self)
- self.win.update_status()
- self.win.tabs.removeTab(1)
- new_send_tab = self.gui.main_window.create_send_tab()
- self.win.tabs.insertTab(1, new_send_tab, _('Send'))
- if enabled:
- self.add_fiat_edit()
- return enabled
-
-
- def close(self):
- self.exchanger.stop()
-
- def history_tab_update(self):
- if self.config.get('history_rates', 'unchecked') == "checked":
- cur_exchange = self.config.get('use_exchange', "Blockchain")
- try:
- tx_list = self.tx_list
- except Exception:
- return
-
- try:
- mintimestr = datetime.datetime.fromtimestamp(int(min(tx_list.items(), key=lambda x: x[1]['timestamp'])[1]['timestamp'])).strftime('%Y-%m-%d')
- except Exception:
- return
- maxtimestr = datetime.datetime.now().strftime('%Y-%m-%d')
-
- if cur_exchange == "CoinDesk":
- try:
- resp_hist = self.exchanger.get_json('api.coindesk.com', "/v1/bpi/historical/close.json?start=" + mintimestr + "&end=" + maxtimestr)
- except Exception:
- return
- elif cur_exchange == "Winkdex":
- try:
- resp_hist = self.exchanger.get_json('winkdex.com', "/static/data/0_86400_730.json")['prices']
- except Exception:
- return
- elif cur_exchange == "BitcoinVenezuela":
- cur_currency = self.fiat_unit()
- if cur_currency == "VEF":
- try:
- resp_hist = self.exchanger.get_json('api.bitcoinvenezuela.com', "/historical/index.php?coin=BTC")['VEF_BTC']
- except Exception:
- return
- elif cur_currency == "ARS":
- try:
- resp_hist = self.exchanger.get_json('api.bitcoinvenezuela.com', "/historical/index.php?coin=BTC")['ARS_BTC']
- except Exception:
- return
- else:
- return
-
- self.gui.main_window.is_edit = True
- self.gui.main_window.history_list.setColumnCount(6)
- self.gui.main_window.history_list.setHeaderLabels( [ '', _('Date'), _('Description') , _('Amount'), _('Balance'), _('Fiat Amount')] )
- root = self.gui.main_window.history_list.invisibleRootItem()
- childcount = root.childCount()
- for i in range(childcount):
- item = root.child(i)
- try:
- tx_info = tx_list[str(item.data(0, Qt.UserRole).toPyObject())]
- except Exception:
- newtx = self.wallet.get_tx_history()
- v = newtx[[x[0] for x in newtx].index(str(item.data(0, Qt.UserRole).toPyObject()))][3]
-
- tx_info = {'timestamp':int(time.time()), 'value': v }
- pass
- tx_time = int(tx_info['timestamp'])
- if cur_exchange == "CoinDesk":
- tx_time_str = datetime.datetime.fromtimestamp(tx_time).strftime('%Y-%m-%d')
- try:
- tx_USD_val = "%.2f %s" % (Decimal(str(tx_info['value'])) / 100000000 * Decimal(resp_hist['bpi'][tx_time_str]), "USD")
- except KeyError:
- tx_USD_val = "%.2f %s" % (self.btc_rate * Decimal(str(tx_info['value']))/100000000 , "USD")
- elif cur_exchange == "Winkdex":
- tx_time_str = int(tx_time) - (int(tx_time) % (60 * 60 * 24))
- try:
- tx_rate = resp_hist[[x['x'] for x in resp_hist].index(tx_time_str)]['y']
- tx_USD_val = "%.2f %s" % (Decimal(tx_info['value']) / 100000000 * Decimal(tx_rate), "USD")
- except ValueError:
- tx_USD_val = "%.2f %s" % (self.btc_rate * Decimal(tx_info['value'])/100000000 , "USD")
- elif cur_exchange == "BitcoinVenezuela":
- tx_time_str = datetime.datetime.fromtimestamp(tx_time).strftime('%Y-%m-%d')
- try:
- num = resp_hist[tx_time_str].replace(',','')
- tx_BTCVEN_val = "%.2f %s" % (Decimal(str(tx_info['value'])) / 100000000 * Decimal(num), cur_currency)
- except KeyError:
- tx_BTCVEN_val = _("No data")
-
- if cur_exchange == "CoinDesk" or cur_exchange == "Winkdex":
- item.setText(5, tx_USD_val)
- elif cur_exchange == "BitcoinVenezuela":
- item.setText(5, tx_BTCVEN_val)
- if Decimal(str(tx_info['value'])) < 0:
- item.setForeground(5, QBrush(QColor("#BC1E1E")))
-
- for i, width in enumerate(self.gui.main_window.column_widths['history']):
- self.gui.main_window.history_list.setColumnWidth(i, width)
- self.gui.main_window.history_list.setColumnWidth(4, 140)
- self.gui.main_window.history_list.setColumnWidth(5, 120)
- self.gui.main_window.is_edit = False
-
-
- def settings_widget(self, window):
- return EnterButton(_('Settings'), self.settings_dialog)
-
- def settings_dialog(self):
- d = QDialog()
- d.setWindowTitle("Settings")
- layout = QGridLayout(d)
- layout.addWidget(QLabel(_('Exchange rate API: ')), 0, 0)
- layout.addWidget(QLabel(_('Currency: ')), 1, 0)
- layout.addWidget(QLabel(_('History Rates: ')), 2, 0)
- combo = QComboBox()
- combo_ex = QComboBox()
- hist_checkbox = QCheckBox()
- hist_checkbox.setEnabled(False)
- if self.config.get('history_rates', 'unchecked') == 'unchecked':
- hist_checkbox.setChecked(False)
- else:
- hist_checkbox.setChecked(True)
- ok_button = QPushButton(_("OK"))
-
- def on_change(x):
- try:
- cur_request = str(self.currencies[x])
- except Exception:
- return
- if cur_request != self.fiat_unit():
- self.config.set_key('currency', cur_request, True)
- cur_exchange = self.config.get('use_exchange', "Blockchain")
- if cur_request == "USD" and (cur_exchange == "CoinDesk" or cur_exchange == "Winkdex"):
- hist_checkbox.setEnabled(True)
- elif cur_request == "VEF" and (cur_exchange == "BitcoinVenezuela"):
- hist_checkbox.setEnabled(True)
- elif cur_request == "ARS" and (cur_exchange == "BitcoinVenezuela"):
- hist_checkbox.setEnabled(True)
- else:
- hist_checkbox.setChecked(False)
- hist_checkbox.setEnabled(False)
- self.win.update_status()
- try:
- self.fiat_button
- except:
- pass
- else:
- self.fiat_button.setText(cur_request)
-
- def disable_check():
- hist_checkbox.setChecked(False)
- hist_checkbox.setEnabled(False)
-
- def on_change_ex(x):
- cur_request = str(self.exchanges[x])
- if cur_request != self.config.get('use_exchange', "Blockchain"):
- self.config.set_key('use_exchange', cur_request, True)
- self.currencies = []
- combo.clear()
- self.exchanger.query_rates.set()
- cur_currency = self.fiat_unit()
- if cur_request == "CoinDesk" or cur_request == "Winkdex":
- if cur_currency == "USD":
- hist_checkbox.setEnabled(True)
- else:
- disable_check()
- elif cur_request == "BitcoinVenezuela":
- if cur_currency == "VEF" or cur_currency == "ARS":
- hist_checkbox.setEnabled(True)
- else:
- disable_check()
- else:
- disable_check()
- set_currencies(combo)
- self.win.update_status()
-
- def on_change_hist(checked):
- if checked:
- self.config.set_key('history_rates', 'checked')
- self.history_tab_update()
- else:
- self.config.set_key('history_rates', 'unchecked')
- self.gui.main_window.history_list.setHeaderLabels( [ '', _('Date'), _('Description') , _('Amount'), _('Balance')] )
- self.gui.main_window.history_list.setColumnCount(5)
- for i,width in enumerate(self.gui.main_window.column_widths['history']):
- self.gui.main_window.history_list.setColumnWidth(i, width)
-
- def set_hist_check(hist_checkbox):
- cur_exchange = self.config.get('use_exchange', "Blockchain")
- if cur_exchange == "CoinDesk" or cur_exchange == "Winkdex":
- hist_checkbox.setEnabled(True)
- elif cur_exchange == "BitcoinVenezuela":
- hist_checkbox.setEnabled(True)
- else:
- hist_checkbox.setEnabled(False)
-
- def set_currencies(combo):
- current_currency = self.fiat_unit()
- try:
- combo.clear()
- except Exception:
- return
- combo.addItems(self.currencies)
- try:
- index = self.currencies.index(current_currency)
- except Exception:
- index = 0
- combo.setCurrentIndex(index)
-
- def set_exchanges(combo_ex):
- try:
- combo_ex.clear()
- except Exception:
- return
- combo_ex.addItems(self.exchanges)
- try:
- index = self.exchanges.index(self.config.get('use_exchange', "Blockchain"))
- except Exception:
- index = 0
- combo_ex.setCurrentIndex(index)
-
- def ok_clicked():
- d.accept();
-
- set_exchanges(combo_ex)
- set_currencies(combo)
- set_hist_check(hist_checkbox)
- combo.currentIndexChanged.connect(on_change)
- combo_ex.currentIndexChanged.connect(on_change_ex)
- hist_checkbox.stateChanged.connect(on_change_hist)
- combo.connect(self.win, SIGNAL('refresh_currencies_combo()'), lambda: set_currencies(combo))
- combo_ex.connect(d, SIGNAL('refresh_exchanges_combo()'), lambda: set_exchanges(combo_ex))
- ok_button.clicked.connect(lambda: ok_clicked())
- layout.addWidget(combo,1,1)
- layout.addWidget(combo_ex,0,1)
- layout.addWidget(hist_checkbox,2,1)
- layout.addWidget(ok_button,3,1)
-
- if d.exec_():
- return True
- else:
- return False
-
- def fiat_unit(self):
- return self.config.get("currency", "EUR")
-
- def add_fiat_edit(self):
- self.fiat_e = AmountEdit(self.fiat_unit)
- self.btc_e = self.win.amount_e
- grid = self.btc_e.parent()
- def fiat_changed():
- try:
- fiat_amount = Decimal(str(self.fiat_e.text()))
- except:
- self.btc_e.setText("")
- return
- exchange_rate = self.exchanger.exchange(Decimal("1.0"), self.fiat_unit())
- if exchange_rate is not None:
- btc_amount = fiat_amount/exchange_rate
- self.btc_e.setAmount(int(btc_amount*Decimal(100000000)))
- self.fiat_e.textEdited.connect(fiat_changed)
- def btc_changed():
- btc_amount = self.btc_e.get_amount()
- if btc_amount is None:
- self.fiat_e.setText("")
- return
- fiat_amount = self.exchanger.exchange(Decimal(btc_amount)/Decimal(100000000), self.fiat_unit())
- if fiat_amount is not None:
- self.fiat_e.setText("%.2f"%fiat_amount)
- self.btc_e.textEdited.connect(btc_changed)
- self.btc_e.frozen.connect(lambda: self.fiat_e.setFrozen(self.btc_e.isReadOnly()))
- self.win.send_grid.addWidget(self.fiat_e, 4, 3, Qt.AlignHCenter)
+++ /dev/null
-from electrum.util import print_error
-
-import httplib, urllib
-import socket
-import hashlib
-import json
-from urlparse import urlparse, parse_qs
-try:
- import PyQt4
-except Exception:
- sys.exit("Error: Could not import PyQt4 on Linux systems, you may try 'sudo apt-get install python-qt4'")
-
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
-import PyQt4.QtCore as QtCore
-import PyQt4.QtGui as QtGui
-import aes
-import base64
-from electrum.plugins import BasePlugin
-from electrum.i18n import _
-
-from electrum_gui.qt import HelpButton, EnterButton
-
-class Plugin(BasePlugin):
-
- def fullname(self):
- return _('Label Sync')
-
- def description(self):
- return '%s\n\n%s%s%s' % (_("This plugin can sync your labels across multiple Electrum installs by using a remote database to save your data. Labels, transactions and addresses are all sent and stored encrypted on the remote server. This code might increase the load of your wallet with a few microseconds as it will sync labels on each startup."), _("To get started visit"), " http://labelectrum.herokuapp.com/ ", _(" to sign up for an account."))
-
- def version(self):
- return "0.2.1"
-
- def encode(self, message):
- encrypted = aes.encryptData(self.encode_password, unicode(message))
- encoded_message = base64.b64encode(encrypted)
-
- return encoded_message
-
- def decode(self, message):
- decoded_message = aes.decryptData(self.encode_password, base64.b64decode(unicode(message)) )
-
- return decoded_message
-
-
- def init(self):
- self.target_host = 'labelectrum.herokuapp.com'
- self.window = self.gui.main_window
-
- def load_wallet(self, wallet):
- self.wallet = wallet
- if self.wallet.get_master_public_key():
- mpk = self.wallet.get_master_public_key()
- else:
- mpk = self.wallet.master_public_keys["m/0'/"][1]
- self.encode_password = hashlib.sha1(mpk).digest().encode('hex')[:32]
- self.wallet_id = hashlib.sha256(mpk).digest().encode('hex')
-
- addresses = []
- for account in self.wallet.accounts.values():
- for address in account.get_addresses(0):
- addresses.append(address)
-
- self.addresses = addresses
-
- if self.auth_token():
- # If there is an auth token we can try to actually start syncing
- self.full_pull()
-
- def auth_token(self):
- return self.config.get("plugin_label_api_key")
-
- def is_available(self):
- return True
-
- def requires_settings(self):
- return True
-
- def set_label(self, item,label, changed):
- if not changed:
- return
- try:
- bundle = {"label": {"external_id": self.encode(item), "text": self.encode(label)}}
- params = json.dumps(bundle)
- connection = httplib.HTTPConnection(self.target_host)
- connection.request("POST", ("/api/wallets/%s/labels.json?auth_token=%s" % (self.wallet_id, self.auth_token())), params, {'Content-Type': 'application/json'})
-
- response = connection.getresponse()
- if response.reason == httplib.responses[httplib.NOT_FOUND]:
- return
- response = json.loads(response.read())
- except socket.gaierror as e:
- print_error('Error connecting to service: %s ' % e)
- return False
-
- def settings_widget(self, window):
- return EnterButton(_('Settings'), self.settings_dialog)
-
- def settings_dialog(self):
- def check_for_api_key(api_key):
- if api_key and len(api_key) > 12:
- self.config.set_key("plugin_label_api_key", str(self.auth_token_edit.text()))
- self.upload.setEnabled(True)
- self.download.setEnabled(True)
- self.accept.setEnabled(True)
- else:
- self.upload.setEnabled(False)
- self.download.setEnabled(False)
- self.accept.setEnabled(False)
-
- d = QDialog()
- layout = QGridLayout(d)
- layout.addWidget(QLabel("API Key: "),0,0)
-
- self.auth_token_edit = QLineEdit(self.auth_token())
- self.auth_token_edit.textChanged.connect(check_for_api_key)
-
- layout.addWidget(QLabel("Label sync options: "),2,0)
- layout.addWidget(self.auth_token_edit, 0,1,1,2)
-
- decrypt_key_text = QLineEdit(self.encode_password)
- decrypt_key_text.setReadOnly(True)
- layout.addWidget(decrypt_key_text, 1,1)
- layout.addWidget(QLabel("Decryption key: "),1,0)
- layout.addWidget(HelpButton("This key can be used on the LabElectrum website to decrypt your data in case you want to review it online."),1,2)
-
- self.upload = QPushButton("Force upload")
- self.upload.clicked.connect(self.full_push)
- layout.addWidget(self.upload, 2,1)
-
- self.download = QPushButton("Force download")
- self.download.clicked.connect(lambda: self.full_pull(True))
- layout.addWidget(self.download, 2,2)
-
- c = QPushButton(_("Cancel"))
- c.clicked.connect(d.reject)
-
- self.accept = QPushButton(_("Done"))
- self.accept.clicked.connect(d.accept)
-
- layout.addWidget(c,3,1)
- layout.addWidget(self.accept,3,2)
-
- check_for_api_key(self.auth_token())
-
- if d.exec_():
- return True
- else:
- return False
-
- def enable(self):
- if not self.auth_token(): # First run, throw plugin settings in your face
- self.init()
- self.load_wallet(self.gui.main_window.wallet)
- if self.settings_dialog():
- self.set_enabled(True)
- return True
- else:
- self.set_enabled(False)
- return False
-
- self.set_enabled(True)
- return True
-
-
- def full_push(self):
- if self.do_full_push():
- QMessageBox.information(None, _("Labels uploaded"), _("Your labels have been uploaded."))
-
- def full_pull(self, force = False):
- if self.do_full_pull(force) and force:
- QMessageBox.information(None, _("Labels synchronized"), _("Your labels have been synchronized."))
- self.window.update_history_tab()
- self.window.update_completions()
- self.window.update_receive_tab()
- self.window.update_contacts_tab()
-
- def do_full_push(self):
- try:
- bundle = {"labels": {}}
- for key, value in self.wallet.labels.iteritems():
- encoded = self.encode(key)
- bundle["labels"][encoded] = self.encode(value)
-
- params = json.dumps(bundle)
- connection = httplib.HTTPConnection(self.target_host)
- connection.request("POST", ("/api/wallets/%s/labels/batch.json?auth_token=%s" % (self.wallet_id, self.auth_token())), params, {'Content-Type': 'application/json'})
-
- response = connection.getresponse()
- if response.reason == httplib.responses[httplib.NOT_FOUND]:
- return
- try:
- response = json.loads(response.read())
- except ValueError as e:
- return False
-
- if "error" in response:
- QMessageBox.warning(None, _("Error"),_("Could not sync labels: %s" % response["error"]))
- return False
-
- return True
- except socket.gaierror as e:
- print_error('Error connecting to service: %s ' % e)
- return False
-
- def do_full_pull(self, force = False):
- try:
- connection = httplib.HTTPConnection(self.target_host)
- connection.request("GET", ("/api/wallets/%s/labels.json?auth_token=%s" % (self.wallet_id, self.auth_token())),"", {'Content-Type': 'application/json'})
- response = connection.getresponse()
- if response.reason == httplib.responses[httplib.NOT_FOUND]:
- return
- try:
- response = json.loads(response.read())
- except ValueError as e:
- return False
-
- if "error" in response:
- QMessageBox.warning(None, _("Error"),_("Could not sync labels: %s" % response["error"]))
- return False
-
- for label in response:
- decoded_key = self.decode(label["external_id"])
- decoded_label = self.decode(label["text"])
- if force or not self.wallet.labels.get(decoded_key):
- self.wallet.labels[decoded_key] = decoded_label
- return True
- except socket.gaierror as e:
- print_error('Error connecting to service: %s ' % e)
- return False
+++ /dev/null
-import re
-import platform
-from decimal import Decimal
-from urllib import quote
-
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
-import PyQt4.QtCore as QtCore
-import PyQt4.QtGui as QtGui
-
-from electrum_gui.qt.qrcodewidget import QRCodeWidget
-from electrum import BasePlugin
-from electrum.i18n import _
-
-
-if platform.system() == 'Windows':
- MONOSPACE_FONT = 'Lucida Console'
-elif platform.system() == 'Darwin':
- MONOSPACE_FONT = 'Monaco'
-else:
- MONOSPACE_FONT = 'monospace'
-
-column_index = 4
-
-class QR_Window(QWidget):
-
- def __init__(self, win):
- QWidget.__init__(self)
- self.win = win
- self.setWindowTitle('Electrum - '+_('Invoice'))
- self.setMinimumSize(800, 250)
- self.address = ''
- self.label = ''
- self.amount = 0
- self.setFocusPolicy(QtCore.Qt.NoFocus)
-
- main_box = QHBoxLayout()
-
- self.qrw = QRCodeWidget()
- main_box.addWidget(self.qrw, 1)
-
- vbox = QVBoxLayout()
- main_box.addLayout(vbox)
-
- self.address_label = QLabel("")
- #self.address_label.setFont(QFont(MONOSPACE_FONT))
- vbox.addWidget(self.address_label)
-
- self.label_label = QLabel("")
- vbox.addWidget(self.label_label)
-
- self.amount_label = QLabel("")
- vbox.addWidget(self.amount_label)
-
- vbox.addStretch(1)
- self.setLayout(main_box)
-
-
- def set_content(self, address, amount, message, url):
- address_text = "<span style='font-size: 18pt'>%s</span>" % address if address else ""
- self.address_label.setText(address_text)
- if amount:
- amount = self.win.format_amount(amount)
- amount_text = "<span style='font-size: 21pt'>%s</span> <span style='font-size: 16pt'>%s</span> " % (amount, self.win.base_unit())
- else:
- amount_text = ''
- self.amount_label.setText(amount_text)
- label_text = "<span style='font-size: 21pt'>%s</span>" % message if message else ""
- self.label_label.setText(label_text)
- self.qrw.setData(url)
-
-
-
-
-class Plugin(BasePlugin):
-
- def fullname(self):
- return 'Point of Sale'
-
-
- def description(self):
- return _('Show payment requests in a large, separate window.')
-
-
- def init(self):
- self.window = self.gui.main_window
- self.qr_window = None
- self.toggle_QR_window(True)
-
-
- def close(self):
- self.toggle_QR_window(False)
-
-
- def close_main_window(self):
- if self.qr_window:
- self.qr_window.close()
- self.qr_window = None
-
-
- def update_receive_qr(self, address, amount, message, url):
- self.qr_window.set_content( address, amount, message, url )
-
-
- def toggle_QR_window(self, show):
- if show and not self.qr_window:
- self.qr_window = QR_Window(self.gui.main_window)
- self.qr_window.setVisible(True)
- self.qr_window_geometry = self.qr_window.geometry()
-
- elif show and self.qr_window and not self.qr_window.isVisible():
- self.qr_window.setVisible(True)
- self.qr_window.setGeometry(self.qr_window_geometry)
-
- elif not show and self.qr_window and self.qr_window.isVisible():
- self.qr_window_geometry = self.qr_window.geometry()
- self.qr_window.setVisible(False)
-
-
-
-
-from electrum.util import print_error
+from electrum_nvc.util import print_error
from urlparse import urlparse, parse_qs
from PyQt4.QtGui import QPushButton, QMessageBox, QDialog, QVBoxLayout, QHBoxLayout, QGridLayout, QLabel, QLineEdit, QComboBox
from PyQt4.QtCore import Qt
-from electrum.i18n import _
+from electrum_nvc.i18n import _
import re
import os
-from electrum import Transaction
-from electrum.bitcoin import MIN_RELAY_TX_FEE, is_valid
-from electrum_gui.qt.qrcodewidget import QRCodeWidget
-from electrum import bmp
-from electrum_gui.qt import HelpButton, EnterButton
+from electrum_nvc import Transaction
+from electrum_nvc.bitcoin import MIN_RELAY_TX_FEE, is_valid
+from electrum_nvc_gui.qt.qrcodewidget import QRCodeWidget
+from electrum_nvc import bmp
+from electrum_nvc_gui.qt import HelpButton, EnterButton
import json
try:
except ImportError:
zbar = None
-from electrum import BasePlugin
+from electrum_nvc import BasePlugin
class Plugin(BasePlugin):
def fullname(self): return 'QR scans'
except zbar.SystemError:
# Cannot open video device
pass
- #return False
return True
from PyQt4.QtGui import *
-from electrum import BasePlugin
-from electrum.i18n import _
+from electrum_nvc import BasePlugin
+from electrum_nvc.i18n import _
class Plugin(BasePlugin):
#!/usr/bin/env python
import sys
-from electrum import NetworkProxy, print_json
+from electrum_nvc import NetworkProxy, print_json
try:
addr = sys.argv[1]
except Exception:
- print "usage: get_history <bitcoin_address>"
+ print "usage: get_history <novacoin_address>"
sys.exit(1)
n = NetworkProxy()
import urllib2,json
import Queue
import sqlite3
-from electrum import Wallet, WalletStorage, SimpleConfig, Network, set_verbosity
+from electrum_nvc import Wallet, WalletStorage, SimpleConfig, Network, set_verbosity
set_verbosity(False)
import ConfigParser
#!/usr/bin/env python
-import time, electrum, Queue
-from electrum import Interface, SimpleConfig
-from electrum.network import filter_protocol, parse_servers
+import time, electrum_nvc, Queue
+from electrum_nvc import Interface, SimpleConfig
+from electrum_nvc.network import filter_protocol, parse_servers
from collections import defaultdict
# 1. start interface and wait for connection
-interface = electrum.Interface('ecdsa.net:50002:s')
+interface = electrum.Interface('127.0.0.1:50002:s')
interface.start(wait = True)
if not interface.is_connected:
print "not connected"
#!/usr/bin/env python
-from electrum import Interface, SimpleConfig, set_verbosity
-from electrum.network import DEFAULT_SERVERS, filter_protocol
+from electrum_nvc import Interface, SimpleConfig, set_verbosity
+from electrum_nvc.network import DEFAULT_SERVERS, filter_protocol
import time, Queue
from collections import defaultdict
#!/usr/bin/env python
-import sys, time, electrum
+import sys, time, electrum_nvc
try:
addr = sys.argv[1]
"""
-py2app/py2exe build script for Electrum Litecoin
+py2app/py2exe build script for Electrum Novacoin
Usage (Mac OS X):
python setup.py py2app
from lib.version import ELECTRUM_VERSION as version
-name = "Electrum"
-mainscript = 'electrum'
+name = "Electrum-NVC"
+mainscript = 'electrum-nvc'
if sys.version_info[:3] < (2, 6, 0):
print_error("Error: " + name + " requires Python version >= 2.6.0...")
if (len(sys.argv) > 1 and (sys.argv[1] == "sdist")) or (platform.system() != 'Windows' and platform.system() != 'Darwin'):
print "Including all files"
data_files += [
- (os.path.join(usr_share, 'applications/'), ['electrum.desktop']),
+ (os.path.join(usr_share, 'applications/'), ['electrum-nvc.desktop']),
(os.path.join(usr_share, 'app-install', 'icons/'), ['icons/electrum.png'])
]
if not os.path.exists('locale'):
appdata_dir = util.appdata_dir()
if not os.access(appdata_dir, os.W_OK):
- appdata_dir = os.path.join(usr_share, "electrum")
+ appdata_dir = os.path.join(usr_share, "electrum-nvc")
data_files += [
(appdata_dir, ["data/README"]),
setup(
- name="Electrum",
+ name="Electrum-NVC",
version=version.ELECTRUM_VERSION,
- install_requires=['slowaes', 'ecdsa>=0.9', 'pbkdf2', 'requests', 'pyasn1', 'pyasn1-modules', 'tlslite>=0.4.5', 'qrcode'],
+ install_requires=['slowaes', 'ecdsa>=0.9', 'pbkdf2', 'requests', 'pyasn1', 'pyasn1-modules', 'tlslite>=0.4.5', 'qrcode', 'ltc_scrypt'],
package_dir={
- 'electrum': 'lib',
- 'electrum_gui': 'gui',
- 'electrum_plugins': 'plugins',
+ 'electrum_nvc': 'lib',
+ 'electrum_nvc_gui': 'gui',
+ 'electrum_nvc_plugins': 'plugins',
},
scripts=['electrum'],
data_files=data_files,
py_modules=[
- 'electrum.account',
- 'electrum.bitcoin',
- 'electrum.blockchain',
- 'electrum.bmp',
- 'electrum.commands',
- 'electrum.daemon',
- 'electrum.i18n',
- 'electrum.interface',
- 'electrum.mnemonic',
- 'electrum.msqr',
- 'electrum.network',
- 'electrum.paymentrequest',
- 'electrum.paymentrequest_pb2',
- 'electrum.plugins',
- 'electrum.simple_config',
- 'electrum.socks',
- 'electrum.synchronizer',
- 'electrum.transaction',
- 'electrum.util',
- 'electrum.verifier',
- 'electrum.version',
- 'electrum.wallet',
- 'electrum.wallet_bitkey',
- 'electrum.x509',
- 'electrum_gui.gtk',
- 'electrum_gui.qt.__init__',
- 'electrum_gui.qt.amountedit',
- 'electrum_gui.qt.console',
- 'electrum_gui.qt.history_widget',
- 'electrum_gui.qt.icons_rc',
- 'electrum_gui.qt.installwizard',
- 'electrum_gui.qt.lite_window',
- 'electrum_gui.qt.main_window',
- 'electrum_gui.qt.network_dialog',
- 'electrum_gui.qt.password_dialog',
- 'electrum_gui.qt.paytoedit',
- 'electrum_gui.qt.qrcodewidget',
- 'electrum_gui.qt.qrtextedit',
- 'electrum_gui.qt.receiving_widget',
- 'electrum_gui.qt.seed_dialog',
- 'electrum_gui.qt.transaction_dialog',
- 'electrum_gui.qt.util',
- 'electrum_gui.qt.version_getter',
- 'electrum_gui.stdio',
- 'electrum_gui.text',
- 'electrum_plugins.aliases',
- 'electrum_plugins.coinbase_buyback',
- 'electrum_plugins.exchange_rate',
- 'electrum_plugins.labels',
- 'electrum_plugins.pointofsale',
- 'electrum_plugins.qrscanner',
- 'electrum_plugins.virtualkeyboard',
+ 'electrum_nvc.account',
+ 'electrum_nvc.bitcoin',
+ 'electrum_nvc.blockchain',
+ 'electrum_nvc.bmp',
+ 'electrum_nvc.commands',
+ 'electrum_nvc.daemon',
+ 'electrum_nvc.i18n',
+ 'electrum_nvc.interface',
+ 'electrum_nvc.mnemonic',
+ 'electrum_nvc.msqr',
+ 'electrum_nvc.network',
+ 'electrum_nvc.paymentrequest',
+ 'electrum_nvc.paymentrequest_pb2',
+ 'electrum_nvc.plugins',
+ 'electrum_nvc.scrypt',
+ 'electrum_nvc.simple_config',
+ 'electrum_nvc.socks',
+ 'electrum_nvc.synchronizer',
+ 'electrum_nvc.transaction',
+ 'electrum_nvc.util',
+ 'electrum_nvc.verifier',
+ 'electrum_nvc.version',
+ 'electrum_nvc.wallet',
+ 'electrum_nvc.wallet_bitkey',
+ 'electrum_nvc.x509',
+ 'electrum_nvc_gui.gtk',
+ 'electrum_nvc_gui.qt.__init__',
+ 'electrum_nvc_gui.qt.amountedit',
+ 'electrum_nvc_gui.qt.console',
+ 'electrum_nvc_gui.qt.history_widget',
+ 'electrum_nvc_gui.qt.icons_rc',
+ 'electrum_nvc_gui.qt.installwizard',
+ 'electrum_nvc_gui.qt.lite_window',
+ 'electrum_nvc_gui.qt.main_window',
+ 'electrum_nvc_gui.qt.network_dialog',
+ 'electrum_nvc_gui.qt.password_dialog',
+ 'electrum_nvc_gui.qt.paytoedit',
+ 'electrum_nvc_gui.qt.qrcodewidget',
+ 'electrum_nvc_gui.qt.qrtextedit',
+ 'electrum_nvc_gui.qt.receiving_widget',
+ 'electrum_nvc_gui.qt.seed_dialog',
+ 'electrum_nvc_gui.qt.transaction_dialog',
+ 'electrum_nvc_gui.qt.util',
+ 'electrum_nvc_gui.qt.version_getter',
+ 'electrum_nvc_gui.stdio',
+ 'electrum_nvc_gui.text',
+ 'electrum_nvc_plugins.qrscanner',
+ 'electrum_nvc_plugins.virtualkeyboard',
],
- description="Lightweight Bitcoin Wallet",
+ description="Lightweight Novacoin Wallet",
author="Thomas Voegtlin",
author_email="thomasv1@gmx.de",
license="GNU GPLv3",
url="https://electrum.org",
- long_description="""Lightweight Bitcoin Wallet"""
+ long_description="""Lightweight Novacoin Wallet"""
)