Merge branch 'master' of gitorious.org:electrum/electrum
|
@ -193,7 +193,23 @@ class BitMap(object):
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
|
def save_qrcode(qr, filename):
|
||||||
|
bitmap = BitMap( 35*8, 35*8 )
|
||||||
|
#print len(bitmap.bitarray)
|
||||||
|
bitmap.bitarray = []
|
||||||
|
k = 33
|
||||||
|
for r in range(35):
|
||||||
|
tmparray = [ 0 ] * 35*8
|
||||||
|
|
||||||
|
if 0 < r < 34:
|
||||||
|
for c in range(k):
|
||||||
|
if qr.isDark(r-1, c):
|
||||||
|
tmparray[ (1+c)*8:(2+c)*8] = [1]*8
|
||||||
|
|
||||||
|
for i in range(8):
|
||||||
|
bitmap.bitarray.append( tmparray[:] )
|
||||||
|
|
||||||
|
bitmap.saveFile( filename )
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -288,7 +288,7 @@ if __name__ == '__main__':
|
||||||
h = wallet.history.get(addr,[])
|
h = wallet.history.get(addr,[])
|
||||||
ni = no = 0
|
ni = no = 0
|
||||||
for item in h:
|
for item in h:
|
||||||
if item['is_in']: ni += 1
|
if item['is_input']: ni += 1
|
||||||
else: no += 1
|
else: no += 1
|
||||||
b = "%d %d %s"%(no, ni, str(Decimal(wallet.get_addr_balance(addr)[0])/100000000))
|
b = "%d %d %s"%(no, ni, str(Decimal(wallet.get_addr_balance(addr)[0])/100000000))
|
||||||
else: b=''
|
else: b=''
|
|
@ -26,7 +26,7 @@ from wallet import format_satoshis
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
import mnemonic
|
import mnemonic
|
||||||
|
|
||||||
import datetime
|
import datetime, re
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -606,6 +606,11 @@ def main_loop():
|
||||||
elif out == "receive":
|
elif out == "receive":
|
||||||
global receive_addr
|
global receive_addr
|
||||||
receive_addr = select_from_addresses()
|
receive_addr = select_from_addresses()
|
||||||
|
if receive_addr:
|
||||||
|
amount = modal_input('Amount', 'Amount you want receive. ', '', "numberDecimal")
|
||||||
|
if amount:
|
||||||
|
receive_addr = 'bitcoin:%s?amount=%s'%(receive_addr, amount)
|
||||||
|
|
||||||
if not receive_addr:
|
if not receive_addr:
|
||||||
out = None
|
out = None
|
||||||
|
|
||||||
|
@ -656,9 +661,16 @@ def payto_loop():
|
||||||
code = droid.scanBarcode()
|
code = droid.scanBarcode()
|
||||||
r = code.result
|
r = code.result
|
||||||
if r:
|
if r:
|
||||||
addr = r['extras']['SCAN_RESULT']
|
data = r['extras']['SCAN_RESULT']
|
||||||
if addr:
|
if data:
|
||||||
droid.fullSetProperty("recipient","text",addr)
|
if re.match('^bitcoin:', data):
|
||||||
|
payto, amount, label, _, _, _, _ = wallet.parse_url(data, None, None)
|
||||||
|
droid.fullSetProperty("recipient", "text",payto)
|
||||||
|
droid.fullSetProperty("amount", "text", amount)
|
||||||
|
droid.fullSetProperty("label", "text", label)
|
||||||
|
else:
|
||||||
|
droid.fullSetProperty("recipient", "text", data)
|
||||||
|
|
||||||
|
|
||||||
elif event["name"] in menu_commands:
|
elif event["name"] in menu_commands:
|
||||||
out = event["name"]
|
out = event["name"]
|
||||||
|
@ -923,28 +935,15 @@ def make_bitmap(addr):
|
||||||
# fixme: this is highly inefficient
|
# fixme: this is highly inefficient
|
||||||
droid.dialogCreateSpinnerProgress("please wait")
|
droid.dialogCreateSpinnerProgress("please wait")
|
||||||
droid.dialogShow()
|
droid.dialogShow()
|
||||||
|
try:
|
||||||
import pyqrnative, bmp
|
import pyqrnative, bmp
|
||||||
qr = pyqrnative.QRCode(4, pyqrnative.QRErrorCorrectLevel.H)
|
qr = pyqrnative.QRCode(4, pyqrnative.QRErrorCorrectLevel.L)
|
||||||
qr.addData(addr)
|
qr.addData(addr)
|
||||||
qr.make()
|
qr.make()
|
||||||
k = qr.getModuleCount()
|
k = qr.getModuleCount()
|
||||||
bitmap = bmp.BitMap( 35*8, 35*8 )
|
|
||||||
print len(bitmap.bitarray)
|
|
||||||
bitmap.bitarray = []
|
|
||||||
assert k == 33
|
assert k == 33
|
||||||
|
bmp.save_qrcode(qr,"/sdcard/sl4a/qrcode.bmp")
|
||||||
for r in range(35):
|
finally:
|
||||||
tmparray = [ 0 ] * 35*8
|
|
||||||
|
|
||||||
if 0 < r < 34:
|
|
||||||
for c in range(k):
|
|
||||||
if qr.isDark(r-1, c):
|
|
||||||
tmparray[ (1+c)*8:(2+c)*8] = [1]*8
|
|
||||||
|
|
||||||
for i in range(8):
|
|
||||||
bitmap.bitarray.append( tmparray[:] )
|
|
||||||
|
|
||||||
bitmap.saveFile( "/sdcard/sl4a/qrcode.bmp" )
|
|
||||||
droid.dialogDismiss()
|
droid.dialogDismiss()
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
|
@ -328,9 +328,6 @@ def run_network_dialog( wallet, parent ):
|
||||||
radio2 = gtk.RadioButton(radio1, "http")
|
radio2 = gtk.RadioButton(radio1, "http")
|
||||||
p_box.pack_start(radio2, True, True, 0)
|
p_box.pack_start(radio2, True, True, 0)
|
||||||
radio2.show()
|
radio2.show()
|
||||||
radio3 = gtk.RadioButton(radio1, "native")
|
|
||||||
p_box.pack_start(radio3, True, True, 0)
|
|
||||||
radio3.show()
|
|
||||||
|
|
||||||
def current_line():
|
def current_line():
|
||||||
return unicode(host_entry.get_text()).split(':')
|
return unicode(host_entry.get_text()).split(':')
|
||||||
|
@ -340,8 +337,6 @@ def run_network_dialog( wallet, parent ):
|
||||||
radio1.set_active(1)
|
radio1.set_active(1)
|
||||||
elif protocol == 'h':
|
elif protocol == 'h':
|
||||||
radio2.set_active(1)
|
radio2.set_active(1)
|
||||||
elif protocol == 'n':
|
|
||||||
radio3.set_active(1)
|
|
||||||
|
|
||||||
def set_protocol(protocol):
|
def set_protocol(protocol):
|
||||||
host = current_line()[0]
|
host = current_line()[0]
|
||||||
|
@ -354,7 +349,6 @@ def run_network_dialog( wallet, parent ):
|
||||||
|
|
||||||
radio1.connect("toggled", lambda x,y:set_protocol('t'), "radio button 1")
|
radio1.connect("toggled", lambda x,y:set_protocol('t'), "radio button 1")
|
||||||
radio2.connect("toggled", lambda x,y:set_protocol('h'), "radio button 1")
|
radio2.connect("toggled", lambda x,y:set_protocol('h'), "radio button 1")
|
||||||
radio3.connect("toggled", lambda x,y:set_protocol('n'), "radio button 1")
|
|
||||||
|
|
||||||
server_list = gtk.ListStore(str)
|
server_list = gtk.ListStore(str)
|
||||||
for host in plist.keys():
|
for host in plist.keys():
|
|
@ -96,11 +96,14 @@ class StatusBarButton(QPushButton):
|
||||||
class QRCodeWidget(QWidget):
|
class QRCodeWidget(QWidget):
|
||||||
|
|
||||||
def __init__(self, addr):
|
def __init__(self, addr):
|
||||||
import pyqrnative
|
|
||||||
super(QRCodeWidget, self).__init__()
|
super(QRCodeWidget, self).__init__()
|
||||||
self.addr = addr
|
|
||||||
self.setGeometry(300, 300, 350, 350)
|
self.setGeometry(300, 300, 350, 350)
|
||||||
self.qr = pyqrnative.QRCode(4, pyqrnative.QRErrorCorrectLevel.H)
|
self.set_addr(addr)
|
||||||
|
|
||||||
|
def set_addr(self, addr):
|
||||||
|
import pyqrnative
|
||||||
|
self.addr = addr
|
||||||
|
self.qr = pyqrnative.QRCode(4, pyqrnative.QRErrorCorrectLevel.L)
|
||||||
self.qr.addData(addr)
|
self.qr.addData(addr)
|
||||||
self.qr.make()
|
self.qr.make()
|
||||||
|
|
||||||
|
@ -527,7 +530,7 @@ class ElectrumWindow(QMainWindow):
|
||||||
addr = unicode( i.text(0) )
|
addr = unicode( i.text(0) )
|
||||||
return addr
|
return addr
|
||||||
|
|
||||||
qrButton = EnterButton("QR",lambda: ElectrumWindow.showqrcode(get_addr(l)))
|
qrButton = EnterButton("QR",lambda: self.show_address_qrcode(get_addr(l)))
|
||||||
|
|
||||||
def copy2clipboard(addr):
|
def copy2clipboard(addr):
|
||||||
self.app.clipboard().setText(addr)
|
self.app.clipboard().setText(addr)
|
||||||
|
@ -659,18 +662,75 @@ class ElectrumWindow(QMainWindow):
|
||||||
+ ' '.join(mnemonic.mn_encode(seed)) + "\""
|
+ ' '.join(mnemonic.mn_encode(seed)) + "\""
|
||||||
|
|
||||||
QMessageBox.information(parent, 'Seed', msg, 'OK')
|
QMessageBox.information(parent, 'Seed', msg, 'OK')
|
||||||
ElectrumWindow.showqrcode(seed)
|
if parent: ElectrumWindow.show_seed_qrcode(seed)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def showqrcode(address):
|
def show_seed_qrcode(seed):
|
||||||
|
if not seed: return
|
||||||
|
d = QDialog(None)
|
||||||
|
d.setModal(1)
|
||||||
|
d.setWindowTitle(seed)
|
||||||
|
d.setMinimumSize(270, 300)
|
||||||
|
vbox = QVBoxLayout()
|
||||||
|
vbox.addWidget(QRCodeWidget(seed))
|
||||||
|
hbox = QHBoxLayout()
|
||||||
|
hbox.addStretch(1)
|
||||||
|
b = QPushButton("OK")
|
||||||
|
hbox.addWidget(b)
|
||||||
|
b.clicked.connect(d.accept)
|
||||||
|
|
||||||
|
vbox.addLayout(hbox)
|
||||||
|
d.setLayout(vbox)
|
||||||
|
d.exec_()
|
||||||
|
|
||||||
|
def show_address_qrcode(self,address):
|
||||||
if not address: return
|
if not address: return
|
||||||
d = QDialog(None)
|
d = QDialog(None)
|
||||||
d.setModal(1)
|
d.setModal(1)
|
||||||
d.setWindowTitle(address)
|
d.setWindowTitle(address)
|
||||||
d.setMinimumSize(270, 300)
|
d.setMinimumSize(270, 350)
|
||||||
vbox = QVBoxLayout()
|
vbox = QVBoxLayout()
|
||||||
vbox.addWidget(QRCodeWidget(address))
|
qrw = QRCodeWidget(address)
|
||||||
vbox.addLayout(ok_cancel_buttons(d))
|
vbox.addWidget(qrw)
|
||||||
|
|
||||||
|
hbox = QHBoxLayout()
|
||||||
|
amount_e = QLineEdit()
|
||||||
|
hbox.addWidget(QLabel('Amount'))
|
||||||
|
hbox.addWidget(amount_e)
|
||||||
|
vbox.addLayout(hbox)
|
||||||
|
|
||||||
|
#hbox = QHBoxLayout()
|
||||||
|
#label_e = QLineEdit()
|
||||||
|
#hbox.addWidget(QLabel('Label'))
|
||||||
|
#hbox.addWidget(label_e)
|
||||||
|
#vbox.addLayout(hbox)
|
||||||
|
|
||||||
|
def amount_changed():
|
||||||
|
amount = numbify(amount_e)
|
||||||
|
#label = str( label_e.getText() )
|
||||||
|
if amount is not None:
|
||||||
|
qrw.set_addr('bitcoin:%s?amount=%s'%(address,str( Decimal(amount) /100000000)))
|
||||||
|
else:
|
||||||
|
qrw.set_addr( address )
|
||||||
|
qrw.repaint()
|
||||||
|
|
||||||
|
def do_save():
|
||||||
|
import bmp
|
||||||
|
bmp.save_qrcode(qrw.qr, "qrcode.bmp")
|
||||||
|
self.show_message("QR code saved to file 'qrcode.bmp'")
|
||||||
|
|
||||||
|
amount_e.textChanged.connect( amount_changed )
|
||||||
|
|
||||||
|
hbox = QHBoxLayout()
|
||||||
|
hbox.addStretch(1)
|
||||||
|
b = QPushButton("Save")
|
||||||
|
b.clicked.connect(do_save)
|
||||||
|
hbox.addWidget(b)
|
||||||
|
b = QPushButton("Close")
|
||||||
|
hbox.addWidget(b)
|
||||||
|
b.clicked.connect(d.accept)
|
||||||
|
|
||||||
|
vbox.addLayout(hbox)
|
||||||
d.setLayout(vbox)
|
d.setLayout(vbox)
|
||||||
d.exec_()
|
d.exec_()
|
||||||
|
|
||||||
|
@ -897,7 +957,6 @@ class ElectrumWindow(QMainWindow):
|
||||||
buttonGroup = QGroupBox("protocol")
|
buttonGroup = QGroupBox("protocol")
|
||||||
radio1 = QRadioButton("tcp", buttonGroup)
|
radio1 = QRadioButton("tcp", buttonGroup)
|
||||||
radio2 = QRadioButton("http", buttonGroup)
|
radio2 = QRadioButton("http", buttonGroup)
|
||||||
radio3 = QRadioButton("native", buttonGroup)
|
|
||||||
|
|
||||||
def current_line():
|
def current_line():
|
||||||
return unicode(host_line.text()).split(':')
|
return unicode(host_line.text()).split(':')
|
||||||
|
@ -907,8 +966,6 @@ class ElectrumWindow(QMainWindow):
|
||||||
radio1.setChecked(1)
|
radio1.setChecked(1)
|
||||||
elif protocol == 'h':
|
elif protocol == 'h':
|
||||||
radio2.setChecked(1)
|
radio2.setChecked(1)
|
||||||
elif protocol == 'n':
|
|
||||||
radio3.setChecked(1)
|
|
||||||
|
|
||||||
def set_protocol(protocol):
|
def set_protocol(protocol):
|
||||||
host = current_line()[0]
|
host = current_line()[0]
|
||||||
|
@ -921,14 +978,12 @@ class ElectrumWindow(QMainWindow):
|
||||||
|
|
||||||
radio1.clicked.connect(lambda x: set_protocol('t') )
|
radio1.clicked.connect(lambda x: set_protocol('t') )
|
||||||
radio2.clicked.connect(lambda x: set_protocol('h') )
|
radio2.clicked.connect(lambda x: set_protocol('h') )
|
||||||
radio3.clicked.connect(lambda x: set_protocol('n') )
|
|
||||||
|
|
||||||
set_button(current_line()[2])
|
set_button(current_line()[2])
|
||||||
|
|
||||||
hbox.addWidget(QLabel('Protocol:'))
|
hbox.addWidget(QLabel('Protocol:'))
|
||||||
hbox.addWidget(radio1)
|
hbox.addWidget(radio1)
|
||||||
hbox.addWidget(radio2)
|
hbox.addWidget(radio2)
|
||||||
hbox.addWidget(radio3)
|
|
||||||
|
|
||||||
vbox.addLayout(hbox)
|
vbox.addLayout(hbox)
|
||||||
|
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 952 B After Width: | Height: | Size: 952 B |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
@ -49,27 +49,43 @@ class Interface(threading.Thread):
|
||||||
#json
|
#json
|
||||||
self.message_id = 0
|
self.message_id = 0
|
||||||
self.responses = Queue.Queue()
|
self.responses = Queue.Queue()
|
||||||
|
self.methods = {}
|
||||||
|
|
||||||
def poke(self):
|
def poke(self):
|
||||||
# push a fake response so that the getting thread exits its loop
|
# push a fake response so that the getting thread exits its loop
|
||||||
self.responses.put(None)
|
self.responses.put(None)
|
||||||
|
|
||||||
def queue_json_response(self, c):
|
def queue_json_response(self, c):
|
||||||
#print repr(c)
|
|
||||||
|
#print "<--",c
|
||||||
msg_id = c.get('id')
|
msg_id = c.get('id')
|
||||||
result = c.get('result')
|
|
||||||
error = c.get('error')
|
error = c.get('error')
|
||||||
params = c.get('params',[])
|
|
||||||
method = c.get('method',None)
|
|
||||||
if not method:
|
|
||||||
return
|
|
||||||
|
|
||||||
if error:
|
if error:
|
||||||
print "received error:", c, method, params
|
print "received error:", c
|
||||||
|
return
|
||||||
|
|
||||||
|
if msg_id is not None:
|
||||||
|
method, params = self.methods.pop(msg_id)
|
||||||
|
result = c.get('result')
|
||||||
else:
|
else:
|
||||||
|
# notification
|
||||||
|
method = c.get('method')
|
||||||
|
params = c.get('params')
|
||||||
|
|
||||||
|
if method == 'blockchain.numblocks.subscribe':
|
||||||
|
result = params[0]
|
||||||
|
params = []
|
||||||
|
|
||||||
|
elif method == 'blockchain.address.subscribe':
|
||||||
|
addr = params[0]
|
||||||
|
result = params[1]
|
||||||
|
params = [addr]
|
||||||
|
|
||||||
self.responses.put({'method':method, 'params':params, 'result':result})
|
self.responses.put({'method':method, 'params':params, 'result':result})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def subscribe(self, addresses):
|
def subscribe(self, addresses):
|
||||||
messages = []
|
messages = []
|
||||||
for addr in addresses:
|
for addr in addresses:
|
||||||
|
@ -148,71 +164,6 @@ class PollingInterface(Interface):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class NativeInterface(PollingInterface):
|
|
||||||
|
|
||||||
def start_session(self, addresses, version):
|
|
||||||
self.send([('session.new', [ version, addresses ])] )
|
|
||||||
self.send([('server.peers.subscribe',[])])
|
|
||||||
|
|
||||||
def poll(self):
|
|
||||||
self.send([('session.poll', [])])
|
|
||||||
|
|
||||||
def send(self, messages):
|
|
||||||
import time
|
|
||||||
cmds = {'session.new':'new_session',
|
|
||||||
'server.peers.subscribe':'peers',
|
|
||||||
'session.poll':'poll',
|
|
||||||
'blockchain.transaction.broadcast':'tx',
|
|
||||||
'blockchain.address.get_history':'h',
|
|
||||||
'blockchain.address.subscribe':'address.subscribe'
|
|
||||||
}
|
|
||||||
|
|
||||||
for m in messages:
|
|
||||||
method, params = m
|
|
||||||
cmd = cmds[method]
|
|
||||||
|
|
||||||
if cmd == 'poll':
|
|
||||||
params = self.session_id
|
|
||||||
|
|
||||||
if cmd == 'address.subscribe':
|
|
||||||
params = [ self.session_id ] + params
|
|
||||||
|
|
||||||
if cmd in ['h', 'tx']:
|
|
||||||
str_params = params[0]
|
|
||||||
elif type(params) != type(''):
|
|
||||||
str_params = repr( params )
|
|
||||||
else:
|
|
||||||
str_params = params
|
|
||||||
t1 = time.time()
|
|
||||||
request = repr ( (cmd, str_params) ) + "#"
|
|
||||||
s = socket.socket( socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
s.settimeout(DEFAULT_TIMEOUT)
|
|
||||||
s.connect(( self.host, self.port) )
|
|
||||||
s.send( request )
|
|
||||||
out = ''
|
|
||||||
while 1:
|
|
||||||
msg = s.recv(1024)
|
|
||||||
if msg: out += msg
|
|
||||||
else: break
|
|
||||||
s.close()
|
|
||||||
self.rtime = time.time() - t1
|
|
||||||
self.is_connected = True
|
|
||||||
|
|
||||||
if cmd == 'h':
|
|
||||||
out = old_to_new(out)
|
|
||||||
|
|
||||||
if cmd in ['peers','h','poll']:
|
|
||||||
out = ast.literal_eval( out )
|
|
||||||
|
|
||||||
if out == '':
|
|
||||||
out = None
|
|
||||||
|
|
||||||
if cmd == 'new_session':
|
|
||||||
self.session_id, msg = ast.literal_eval( out )
|
|
||||||
self.responses.put({'method':'server.banner', 'params':[], 'result':msg})
|
|
||||||
else:
|
|
||||||
self.responses.put({'method':method, 'params':params, 'result':out})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -235,6 +186,7 @@ class HttpStratumInterface(PollingInterface):
|
||||||
method, params = m
|
method, params = m
|
||||||
if type(params) != type([]): params = [params]
|
if type(params) != type([]): params = [params]
|
||||||
data.append( { 'method':method, 'id':self.message_id, 'params':params } )
|
data.append( { 'method':method, 'id':self.message_id, 'params':params } )
|
||||||
|
self.methods[self.message_id] = method, params
|
||||||
self.message_id += 1
|
self.message_id += 1
|
||||||
|
|
||||||
if data:
|
if data:
|
||||||
|
@ -324,6 +276,8 @@ class TcpStratumInterface(Interface):
|
||||||
for m in messages:
|
for m in messages:
|
||||||
method, params = m
|
method, params = m
|
||||||
request = json.dumps( { 'id':self.message_id, 'method':method, 'params':params } )
|
request = json.dumps( { 'id':self.message_id, 'method':method, 'params':params } )
|
||||||
|
self.methods[self.message_id] = method, params
|
||||||
|
#print "-->",request
|
||||||
self.message_id += 1
|
self.message_id += 1
|
||||||
out += request + '\n'
|
out += request + '\n'
|
||||||
self.s.send( out )
|
self.s.send( out )
|
||||||
|
@ -357,16 +311,6 @@ class WalletSynchronizer(threading.Thread):
|
||||||
self.wallet.banner = result
|
self.wallet.banner = result
|
||||||
self.wallet.was_updated = True
|
self.wallet.was_updated = True
|
||||||
|
|
||||||
elif method == 'session.poll':
|
|
||||||
# native poll
|
|
||||||
blocks, changed_addresses = result
|
|
||||||
if blocks == -1: raise BaseException("session not found")
|
|
||||||
self.wallet.blocks = int(blocks)
|
|
||||||
if changed_addresses:
|
|
||||||
self.wallet.was_updated = True
|
|
||||||
for addr, status in changed_addresses.items():
|
|
||||||
self.wallet.receive_status_callback(addr, status)
|
|
||||||
|
|
||||||
elif method == 'server.peers.subscribe':
|
elif method == 'server.peers.subscribe':
|
||||||
servers = []
|
servers = []
|
||||||
for item in result:
|
for item in result:
|
||||||
|
@ -375,18 +319,14 @@ class WalletSynchronizer(threading.Thread):
|
||||||
ports = []
|
ports = []
|
||||||
if len(item)>2:
|
if len(item)>2:
|
||||||
for v in item[2]:
|
for v in item[2]:
|
||||||
if re.match("[thn]\d+",v):
|
if re.match("[th]\d+",v):
|
||||||
ports.append((v[0],v[1:]))
|
ports.append((v[0],v[1:]))
|
||||||
#if not s:
|
|
||||||
# s.append(host+":50000:n")
|
|
||||||
#else:
|
|
||||||
# s.append(host+":50000:n")
|
|
||||||
if ports:
|
if ports:
|
||||||
servers.append( (host, ports) )
|
servers.append( (host, ports) )
|
||||||
self.interface.servers = servers
|
self.interface.servers = servers
|
||||||
|
|
||||||
elif method == 'blockchain.address.subscribe':
|
elif method == 'blockchain.address.subscribe':
|
||||||
addr = params[-1]
|
addr = params[0]
|
||||||
self.wallet.receive_status_callback(addr, result)
|
self.wallet.receive_status_callback(addr, result)
|
||||||
|
|
||||||
elif method == 'blockchain.address.get_history':
|
elif method == 'blockchain.address.get_history':
|
||||||
|
@ -418,15 +358,13 @@ class WalletSynchronizer(threading.Thread):
|
||||||
port = int(port)
|
port = int(port)
|
||||||
|
|
||||||
#print protocol, host, port
|
#print protocol, host, port
|
||||||
if protocol == 'n':
|
if protocol == 't':
|
||||||
InterfaceClass = NativeInterface
|
|
||||||
elif protocol == 't':
|
|
||||||
InterfaceClass = TcpStratumInterface
|
InterfaceClass = TcpStratumInterface
|
||||||
elif protocol == 'h':
|
elif protocol == 'h':
|
||||||
InterfaceClass = HttpStratumInterface
|
InterfaceClass = HttpStratumInterface
|
||||||
else:
|
else:
|
||||||
print "unknown protocol"
|
print "unknown protocol"
|
||||||
InterfaceClass = NativeInterface
|
InterfaceClass = TcpStratumInterface
|
||||||
|
|
||||||
self.interface = InterfaceClass(host, port)
|
self.interface = InterfaceClass(host, port)
|
||||||
self.wallet.interface = self.interface
|
self.wallet.interface = self.interface
|
|
@ -1,2 +1,2 @@
|
||||||
ELECTRUM_VERSION = "0.43e"
|
ELECTRUM_VERSION = "0.45"
|
||||||
SEED_VERSION = 4 # bump this everytime the seed generation is modified
|
SEED_VERSION = 4 # bump this everytime the seed generation is modified
|
|
@ -609,11 +609,8 @@ class Wallet:
|
||||||
|
|
||||||
|
|
||||||
def get_addr_balance(self, addr):
|
def get_addr_balance(self, addr):
|
||||||
if self.is_mine(addr):
|
assert self.is_mine(addr)
|
||||||
h = self.history.get(addr)
|
h = self.history.get(addr,[])
|
||||||
else:
|
|
||||||
h = self.interface.retrieve_history(addr)
|
|
||||||
if not h: return 0,0
|
|
||||||
c = u = 0
|
c = u = 0
|
||||||
for item in h:
|
for item in h:
|
||||||
v = item['value']
|
v = item['value']
|
|
@ -0,0 +1,31 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import interface, sys
|
||||||
|
try:
|
||||||
|
addr = sys.argv[1]
|
||||||
|
except:
|
||||||
|
print "usage: watch_address <bitcoin_address>"
|
||||||
|
|
||||||
|
i = interface.TcpStratumInterface('ecdsa.org', 50001)
|
||||||
|
i.start()
|
||||||
|
i.send([('blockchain.address.subscribe',[addr])])
|
||||||
|
|
||||||
|
while True:
|
||||||
|
r = i.responses.get(True, 100000000000)
|
||||||
|
method = r.get('method')
|
||||||
|
if method == 'blockchain.address.subscribe':
|
||||||
|
i.send([('blockchain.address.get_history',[addr])])
|
||||||
|
elif method == 'blockchain.address.get_history':
|
||||||
|
confirmed = unconfirmed = 0
|
||||||
|
h = r.get('result')
|
||||||
|
if h is None:
|
||||||
|
continue
|
||||||
|
for item in h:
|
||||||
|
v = item['value']
|
||||||
|
if item['height']:
|
||||||
|
confirmed += v
|
||||||
|
else:
|
||||||
|
unconfirmed += v
|
||||||
|
print (confirmed+unconfirmed)/1.e8
|
||||||
|
|
||||||
|
|