diff --git a/client/electrum4a.py b/client/electrum4a.py new file mode 100755 index 000000000..e058dd939 --- /dev/null +++ b/client/electrum4a.py @@ -0,0 +1,511 @@ +#!/usr/bin/env python +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2011 thomasv@gitorious +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + + +import android +from interface import WalletSynchronizer +from wallet import Wallet +from wallet import format_satoshis +from decimal import Decimal + +droid = android.Android() +wallet = Wallet() +wallet.set_path("/sdcard/electrum.dat") +wallet.read() + + +def get_history_layout(n): + lines = wallet.get_tx_history()[-n:] + rows = "" + for line in lines: + import datetime + v = line['value'] + if line.has_key('timestamp'): + dt = datetime.datetime.fromtimestamp( line['timestamp'] ) + if dt.date() == dt.today().date(): + time_str = str( dt.time() ) + else: + time_str = str( dt.date() ) + else: + time_str = 'pending' + + label = line.get('label') + if not label: label = line['tx_hash'] + + rows += """ + + + + + """%(time_str, ' '+ label[0:10]+ '... ', format_satoshis(v)) + + + output = """ + + %s + +"""% rows + return output + + + +def show_addresses(): + droid.dialogCreateAlert("Addresses:") + l = [] + for i in range(len(wallet.addresses)): + addr = wallet.addresses[i] + l.append( wallet.labels.get(addr,'') + ' ' + addr) + + droid.dialogSetItems(l) + droid.dialogShow() + response = droid.dialogGetResponse().result + droid.dialogDismiss() + + # show qr code + print response + + + +main_layout = """ + + + + + + %s + + + + + + + + + + + +"""%get_history_layout(10) + + +payto_layout=""" + + + + + + + + + + + + + + + + + + + + + + + + + + +""" + + +settings_layout = """ + + + + + + + + + + + + + + + +""" + + + +droid.addOptionsMenuItem("Settings","settings",None,"") +droid.addOptionsMenuItem("Quit","quit",None,"") + + +def show_balance(): + c, u = wallet.get_balance() + droid.fullSetProperty("balanceTextView","text","Balance:"+format_satoshis(c)) + + +def recipient_dialog(): + title = 'Pay to:' + message = ('Select recipient') + droid.dialogCreateAlert(title, message) + droid.dialogSetItems(wallet.addressbook) + droid.dialogShow() + response = droid.dialogGetResponse() + result = response.result.get('item') + droid.dialogDismiss() + if result is not None: + addr = wallet.addressbook[result] + return addr + + +def pay_to(recipient, amount, fee, label): + + if wallet.use_encryption: + password = droid.dialogGetPassword('Password').result + print "password", password + else: + password = None + + droid.dialogCreateSpinnerProgress("Electrum", "signing transaction...") + droid.dialogShow() + tx = wallet.mktx( recipient, amount, label, password, fee) + print tx + droid.dialogDismiss() + + if tx: + r, h = wallet.sendtx( tx ) + droid.dialogCreateAlert('tx sent', h) + droid.dialogSetPositiveButtonText('OK') + droid.dialogShow() + response = droid.dialogGetResponse().result + droid.dialogDismiss() + return h + else: + return 'error' + + + + + + + +if not wallet.file_exists: + droid.dialogCreateAlert("wallet file not found") + droid.dialogSetPositiveButtonText('OK') + droid.dialogShow() + resp = droid.dialogGetResponse().result + exit(1) + + + + +droid.dialogCreateSpinnerProgress("Electrum", "synchronizing") +droid.dialogShow() +WalletSynchronizer(wallet,True).start() +wallet.update() +wallet.save() +droid.dialogDismiss() +droid.vibrate() + + + +def main_loop(): + + droid.fullShow(main_layout) + show_balance() + + out = None + while out is None: + + event = droid.eventWait().result + print "got event in main loop", event + + if event["name"]=="click": + id=event["data"]["id"] + if id=="buttonQuit": + out = 'exit' + + elif id=="buttonSend": + out = 'payto' + + elif id=="buttonReceive": + show_addresses() + + elif id=="buttonQuit": + out = 'quit' + + elif event["name"]=="settings": + out = 'settings' + + elif event["name"]=="quit": + out = 'quit' + + #print droid.fullSetProperty("background","backgroundColor","0xff7f0000") + #elif event["name"]=="screen": + # if event["data"]=="destroy": + # out = 'exit' + + #droid.fullDismiss() + return out + +def payto_loop(): + droid.fullShow(payto_layout) + out = None + while out is None: + event = droid.eventWait().result + print "got event in payto loop", event + + if event["name"] == "click": + id = event["data"]["id"] + + if id=="buttonPay": + + droid.fullQuery() + recipient = droid.fullQueryDetail("recipient").result.get('text') + label = droid.fullQueryDetail("label").result.get('text') + amount = droid.fullQueryDetail('amount').result.get('text') + fee = '0.001' + amount = int( 100000000 * Decimal(amount) ) + fee = int( 100000000 * Decimal(fee) ) + result = pay_to(recipient, amount, fee, label) + + droid.dialogCreateAlert('result', result) + droid.dialogSetPositiveButtonText('OK') + droid.dialogShow() + droid.dialogGetResponse() + droid.dialogDismiss() + out = 'main' + + + elif id=="buttonContacts": + addr = recipient_dialog() + droid.fullSetProperty("recipient","text",addr) + + elif id=="buttonCancelSend": + out = 'main' + + elif event["name"]=="settings": + out = 'settings' + + elif event["name"]=="quit": + out = 'quit' + + #elif event["name"]=="screen": + # if event["data"]=="destroy": + # out = 'main' + + #droid.fullDismiss() + return out + + +def history_loop(): + layout = get_history_layout() + droid.fullShow(layout) + out = None + while out is None: + event = droid.eventWait().result + print "got event in history loop", event + if event["name"] == "click": + + if event["data"]["text"] == "OK": + out = 'main' + + elif event["name"] == "key": + print repr(event["data"]["key"]) + if event["data"]["key"] == '4': + out = 'main' + + #elif event["name"]=="screen": + # if event["data"]=="destroy": + # out = 'main' + + #droid.fullQuery() + #print "Data entered =",droid.fullQueryDetail("editText1").result + #droid.fullDismiss() + return out + +def server_dialog(plist): + droid.dialogCreateAlert("servers") + droid.dialogSetItems( plist.keys() ) + droid.dialogShow() + i = droid.dialogGetResponse().result.get('item') + droid.dialogDismiss() + if i is not None: + response = plist.keys()[i] + return response + +def protocol_dialog(plist): + options=["TCP","HTTP","native"] + droid.dialogCreateAlert("Protocol") + droid.dialogSetSingleChoiceItems(options) + + + +def settings_loop(): + droid.fullShow(settings_layout) + droid.fullSetProperty("server","text",wallet.server) + + out = None + while out is None: + event = droid.eventWait().result + if event["name"] == "click": + + id = event["data"]["id"] + + if id=="buttonServer": + plist = {} + for item in wallet.interface.servers: + host, pp = item + z = {} + for item2 in pp: + protocol, port = item2 + z[protocol] = port + plist[host] = z + + host = server_dialog(plist) + p = plist[host] + port = p['t'] + srv = host + ':' + port + ':t' + droid.fullSetProperty("server","text",srv) + + elif id=="buttonSave": + droid.fullQuery() + srv = droid.fullQueryDetail("server").result.get('text') + try: + wallet.set_server(srv) + out = 'main' + except: + droid.dialogCreateAlert('error') + droid.dialogSetPositiveButtonText('OK') + droid.dialogShow() + droid.dialogGetResponse() + droid.dialogDismiss() + + elif id=="buttonCancel": + out = 'main' + + elif event["name"] == "key": + print repr(event["data"]["key"]) + if event["data"]["key"] == '4': + out = 'main' + + elif event["name"]=="quit": + out = 'quit' + + return out + + + + +s = 'main' +while True: + if s == 'main': + s = main_loop() + elif s == 'payto': + s = payto_loop() + elif s == 'settings': + s = settings_loop() + elif s == 'history': + s = history_loop() + elif s == 'contacts': + s = contacts_loop() + else: + break + +droid.fullDismiss() +droid.makeToast("Bye!")