2011-11-04 18:00:37 +01:00
#!/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 <http://www.gnu.org/licenses/>.
2012-08-23 17:05:07 -07:00
import re
import sys
2012-08-25 14:11:50 -07:00
# import argparse
import optparse
2012-08-23 17:05:07 -07:00
2012-07-07 19:53:54 +01:00
try :
from lib . util import print_error
except ImportError :
from electrum . util import print_error
2011-11-06 11:13:58 +01:00
2012-05-14 14:09:50 +02:00
try :
import ecdsa
2012-08-19 15:10:17 -07:00
except ImportError :
sys . exit ( " Error: python-ecdsa does not seem to be installed. Try ' sudo pip install ecdsa ' " )
2012-05-14 14:09:50 +02:00
try :
import aes
2012-08-19 15:10:17 -07:00
except ImportError :
sys . exit ( " Error: AES does not seem to be installed. Try ' sudo pip install slowaes ' " )
2012-05-14 14:09:50 +02:00
2012-05-30 16:46:04 +02:00
try :
2012-09-19 17:37:20 +07:00
from lib import Wallet , WalletSynchronizer , format_satoshis , mnemonic , prompt_password , parse_proxy_options , SimpleConfig
2012-06-07 19:47:00 +02:00
except ImportError :
2012-09-19 17:37:20 +07:00
from electrum import Wallet , WalletSynchronizer , format_satoshis , mnemonic , prompt_password , parse_proxy_options , SimpleConfig
2012-08-30 00:03:38 +02:00
2012-02-06 07:48:52 +01:00
from decimal import Decimal
2012-02-03 08:02:12 +01:00
2012-06-06 19:52:52 +02:00
known_commands = {
2012-06-18 22:19:47 +02:00
' help ' : ' Prints this help ' ,
' validateaddress ' : ' Check that the address is valid ' ,
' balance ' : " Display the balance of your wallet or of an address. \n Syntax: balance [<address>] " ,
2012-06-06 19:52:52 +02:00
' contacts ' : " Show your list of contacts " ,
2012-06-18 22:19:47 +02:00
' create ' : ' Create a wallet ' ,
' restore ' : ' Restore a wallet ' ,
' payto ' : """ Create and broadcast a transaction.
Syntax: payto <recipient> <amount> [label]
<recipient> can be a bitcoin address or a label
options: \n --fee, -f: set transaction fee \n --fromaddr, -s: send from address - \n --changeaddr, -c: send change to address
2012-06-06 19:52:52 +02:00
""" ,
' sendtx ' :
2012-06-18 22:19:47 +02:00
' Broadcasts a transaction to the network. \n Syntax: sendtx <tx> \n <tx> must be in hexadecimal. ' ,
2012-06-06 19:52:52 +02:00
' password ' :
2012-06-18 22:19:47 +02:00
" Changes your password " ,
2012-06-06 19:52:52 +02:00
' addresses ' :
2012-06-18 22:19:47 +02:00
""" Shows your list of addresses.
options:
-a: show all addresses, including change addresses
-k: show private keys
-b: show the balance of addresses """ ,
' history ' : " Shows the transaction history " ,
' label ' : ' Assign a label to an item \n Syntax: label <tx_hash> <label> ' ,
2012-06-06 19:52:52 +02:00
' mktx ' :
2012-06-18 22:19:47 +02:00
""" Create a signed transaction, password protected.
Syntax: mktx <recipient> <amount> [label]
options: \n --fee, -f: set transaction fee \n --fromaddr, -s: send from address - \n --changeaddr, -c: send change to address
2012-06-06 19:52:52 +02:00
""" ,
' seed ' :
2012-06-18 22:19:47 +02:00
" Print the generation seed of your wallet. " ,
2012-06-06 19:52:52 +02:00
' import ' :
2012-06-18 22:19:47 +02:00
' Imports a key pair \n Syntax: import <address>:<privatekey> ' ,
2012-06-06 19:52:52 +02:00
' signmessage ' :
2012-08-26 22:15:09 +02:00
' Signs a message with a key \n Syntax: signmessage <address> <message> \n If 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 " ' ,
2012-06-06 19:52:52 +02:00
' verifymessage ' :
2012-08-26 22:15:09 +02:00
' Verifies a signature \n Syntax: verifymessage <address> <signature> <message> \n If 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 " ' ,
2012-06-06 19:52:52 +02:00
' eval ' :
" Run python eval() on an object \n Syntax: eval <expression> \n Example: eval \" wallet.aliases \" " ,
' deseed ' :
2012-06-18 22:19:47 +02:00
" Remove seed from the wallet. The seed is stored in a file that has the name of the wallet plus ' .seed ' " ,
2012-06-06 19:52:52 +02:00
' reseed ' :
2012-06-18 22:19:47 +02:00
" Restore seed of the wallet. The wallet must have no seed, and the seed must match the wallet ' s master public key. " ,
2012-06-06 19:52:52 +02:00
' freeze ' : ' ' ,
' unfreeze ' : ' ' ,
' prioritize ' : ' ' ,
' unprioritize ' : ' ' ,
}
2012-06-06 19:26:05 +02:00
offline_commands = [ ' password ' , ' mktx ' , ' label ' , ' contacts ' , ' help ' , ' validateaddress ' , ' signmessage ' , ' verifymessage ' , ' eval ' , ' create ' , ' addresses ' , ' import ' , ' seed ' , ' deseed ' , ' reseed ' , ' freeze ' , ' unfreeze ' , ' prioritize ' , ' unprioritize ' ]
2012-03-23 13:55:27 +01:00
protected_commands = [ ' payto ' , ' password ' , ' mktx ' , ' seed ' , ' import ' , ' signmessage ' ]
2011-11-04 18:00:37 +01:00
if __name__ == ' __main__ ' :
2011-11-14 20:35:54 +01:00
2012-08-30 00:03:38 +02:00
# Load simple config class
simple_config = SimpleConfig ( )
2012-05-14 17:35:38 +02:00
usage = " usage: % prog [options] command \n Commands: " + ( ' , ' . join ( known_commands ) )
2012-08-25 14:16:21 -07:00
parser = optparse . OptionParser ( prog = usage )
2012-08-30 00:03:38 +02:00
parser . add_option ( " -g " , " --gui " , dest = " gui " , default = simple_config . config [ " gui " ] , help = " gui " )
2011-11-29 11:23:49 +01:00
parser . add_option ( " -w " , " --wallet " , dest = " wallet_path " , help = " wallet path (default: electrum.dat) " )
2012-05-13 10:19:28 +02:00
parser . add_option ( " -o " , " --offline " , action = " store_true " , dest = " offline " , default = False , help = " remain offline " )
2011-11-14 20:35:54 +01:00
parser . add_option ( " -a " , " --all " , action = " store_true " , dest = " show_all " , default = False , help = " show all addresses " )
parser . add_option ( " -b " , " --balance " , action = " store_true " , dest = " show_balance " , default = False , help = " show the balance at listed addresses " )
parser . add_option ( " -k " , " --keys " , action = " store_true " , dest = " show_keys " , default = False , help = " show the private keys of listed addresses " )
2011-12-18 22:49:33 +01:00
parser . add_option ( " -f " , " --fee " , dest = " tx_fee " , default = " 0.005 " , help = " set tx fee " )
2012-02-08 09:36:19 +01:00
parser . add_option ( " -s " , " --fromaddr " , dest = " from_addr " , default = None , help = " set source address for payto/mktx. if it isn ' t in the wallet, it will ask for the private key unless supplied in the format public_key:private_key. It ' s not saved in the wallet. " )
parser . add_option ( " -c " , " --changeaddr " , dest = " change_addr " , default = None , help = " set the change address for payto/mktx. default is a spare address, or the source address if it ' s not in the wallet " )
2012-02-22 15:39:06 +01:00
parser . add_option ( " -r " , " --remote " , dest = " remote_url " , default = None , help = " URL of a remote wallet " )
2012-09-19 17:37:20 +07:00
parser . add_option ( " -p " , " --proxy " , dest = " proxy " , default = simple_config . config [ " proxy " ] , help = " set proxy [type:]host[:port], where type is socks4,socks5 or http " )
2011-11-14 20:35:54 +01:00
options , args = parser . parse_args ( )
2011-11-04 18:00:37 +01:00
2012-09-19 17:37:20 +07:00
if type ( options . proxy ) == type ( ' ' ) :
options . proxy = parse_proxy_options ( options . proxy )
2012-08-30 00:03:38 +02:00
2012-03-12 17:55:33 +01:00
wallet = Wallet ( )
2011-12-19 13:48:51 +01:00
wallet . set_path ( options . wallet_path )
2012-03-12 17:55:33 +01:00
wallet . read ( )
2012-02-22 16:17:24 +01:00
wallet . remote_url = options . remote_url
2012-03-12 17:55:33 +01:00
2012-02-14 12:45:39 +01:00
if len ( args ) == 0 :
url = None
cmd = ' gui '
elif len ( args ) == 1 and re . match ( ' ^bitcoin: ' , args [ 0 ] ) :
url = args [ 0 ]
cmd = ' gui '
else :
cmd = args [ 0 ]
firstarg = args [ 1 ] if len ( args ) > 1 else ' '
2012-08-22 11:36:04 -07:00
#this entire if/else block is just concerned with importing the
#right GUI toolkit based the GUI command line option given
2012-02-14 12:45:39 +01:00
if cmd == ' gui ' :
2012-08-16 11:28:20 +02:00
2012-02-14 12:45:39 +01:00
if options . gui == ' gtk ' :
2012-06-06 15:18:03 +02:00
try :
import lib . gui as gui
2012-06-07 19:47:00 +02:00
except ImportError :
2012-06-06 15:18:03 +02:00
import electrum . gui as gui
2012-02-14 12:45:39 +01:00
elif options . gui == ' qt ' :
2012-06-06 15:18:03 +02:00
try :
2012-06-07 14:13:51 +02:00
import lib . gui_qt as gui
2012-06-07 19:47:00 +02:00
except ImportError :
2012-06-06 15:18:03 +02:00
import electrum . gui_qt as gui
2012-06-27 22:24:58 +02:00
elif options . gui == ' lite ' :
2012-08-16 11:28:20 +02:00
# Let's do some dep checking and handle missing ones gracefully
try :
from PyQt4 . QtCore import *
from PyQt4 . QtGui import *
except ImportError :
print " You need to have PyQT installed to run Electrum in graphical mode. "
print " If you have pip installed try ' sudo pip install pyqt ' if you are on Debian/Ubuntu try ' sudo apt-get install python-qt4 ' . "
sys . exit ( 0 )
qtVersion = qVersion ( )
if not ( int ( qtVersion [ 0 ] ) > = 4 and int ( qtVersion [ 2 ] ) > = 7 ) :
app = QApplication ( sys . argv )
2012-08-30 19:57:32 +02:00
QMessageBox . warning ( None , " Could not start Lite GUI. " , " Electrum was unable to load the ' Lite GUI ' because it needs Qt version >= 4.7. \n Electrum is now setup to load the Pro GUI. " )
2012-08-30 00:11:50 +02:00
2012-08-30 17:52:03 +02:00
simple_config . set_key ( " gui " , " qt " )
2012-08-30 00:11:50 +02:00
2012-08-18 10:20:35 +02:00
try :
import lib . gui_qt as gui
except ImportError :
import electrum . gui_qt as gui
else :
2012-08-29 22:54:44 +02:00
#use the lite version if no toolkit specified
2012-08-18 10:20:35 +02:00
try :
2012-06-27 22:24:58 +02:00
import lib . gui_lite as gui
2012-08-18 10:20:35 +02:00
except ImportError :
2012-06-27 23:06:00 +02:00
import electrum . gui_lite as gui
2012-02-14 12:45:39 +01:00
else :
2012-08-23 10:06:21 +01:00
sys . exit ( " Error: Unknown GUI: " + options . gui )
2012-02-11 13:14:12 +01:00
2012-02-14 09:52:03 +01:00
gui = gui . ElectrumGui ( wallet )
2012-09-19 17:37:20 +07:00
interface = WalletSynchronizer ( wallet , True , gui . server_list_changed , options . proxy )
2012-08-29 20:49:31 +01:00
interface . start ( )
2012-02-14 09:52:03 +01:00
2012-02-11 13:14:12 +01:00
try :
2012-03-12 17:55:33 +01:00
found = wallet . file_exists
2012-02-11 13:14:12 +01:00
if not found :
2012-02-14 09:52:03 +01:00
found = gui . restore_or_create ( )
2012-03-23 19:32:16 +01:00
except SystemExit , e :
exit ( e )
2012-02-11 13:14:12 +01:00
except BaseException , e :
2012-02-14 09:52:03 +01:00
import traceback
traceback . print_exc ( file = sys . stdout )
#gui.show_message(e.message)
2012-02-11 13:14:12 +01:00
exit ( 1 )
2012-02-14 09:52:03 +01:00
2012-06-27 22:24:58 +02:00
if not found :
exit ( 1 )
2012-02-14 12:45:39 +01:00
gui . main ( url )
2011-11-09 23:21:27 +01:00
wallet . save ( )
2011-11-10 09:34:27 +01:00
sys . exit ( 0 )
2011-11-04 18:00:37 +01:00
2012-01-15 18:45:30 +01:00
if cmd not in known_commands :
cmd = ' help '
2012-03-12 17:55:33 +01:00
if not wallet . file_exists and cmd not in [ ' help ' , ' create ' , ' restore ' ] :
2012-08-19 16:00:46 -07:00
print " Error: Wallet file not found. "
print " Type ' electrum create ' to create a new wallet, or provide a path to a wallet with the -w option "
2011-11-16 18:26:06 +03:00
sys . exit ( 0 )
2012-02-21 14:36:45 +01:00
if cmd in [ ' create ' , ' restore ' ] :
2012-03-12 17:55:33 +01:00
if wallet . file_exists :
2012-08-19 17:16:35 -07:00
sys . exit ( " Error: Remove the existing wallet first! " )
2012-07-06 21:45:57 -07:00
password = prompt_password ( " Password (hit return if you do not wish to encrypt your wallet): " )
2011-11-04 18:00:37 +01:00
2012-03-31 06:39:23 +02:00
w_host , w_port , w_protocol = wallet . server . split ( ' : ' )
host = raw_input ( " server (default: %s ): " % w_host )
port = raw_input ( " port (default: %s ): " % w_port )
protocol = raw_input ( " protocol [t=tcp;h=http;n=native] (default: %s ): " % w_protocol )
2012-02-06 07:48:52 +01:00
fee = raw_input ( " fee (default: %s ): " % ( str ( Decimal ( wallet . fee ) / 100000000 ) ) )
2012-02-19 14:31:21 +02:00
gap = raw_input ( " gap limit (default 5): " )
2012-03-31 06:39:23 +02:00
if host : w_host = host
if port : w_port = port
if protocol : w_protocol = protocol
wallet . server = w_host + ' : ' + w_port + ' : ' + w_protocol
2012-02-21 14:36:45 +01:00
if fee : wallet . fee = float ( fee )
2012-02-19 14:31:21 +02:00
if gap : wallet . gap_limit = int ( gap )
2012-02-21 14:36:45 +01:00
if cmd == ' restore ' :
seed = raw_input ( " seed: " )
try :
seed . decode ( ' hex ' )
except :
2012-07-07 09:24:52 -07:00
print_error ( " Warning: Not hex, trying decode. " )
2012-02-21 14:36:45 +01:00
seed = mnemonic . mn_decode ( seed . split ( ' ' ) )
if not seed :
2012-08-19 17:17:47 -07:00
sys . exit ( " Error: No seed " )
2012-02-21 14:36:45 +01:00
wallet . seed = str ( seed )
2012-03-23 20:58:54 +01:00
wallet . init_mpk ( wallet . seed )
2012-05-13 10:19:28 +02:00
if not options . offline :
WalletSynchronizer ( wallet ) . start ( )
2012-07-07 06:39:25 -07:00
print " Recovering wallet... "
2012-05-13 10:19:28 +02:00
wallet . up_to_date_event . clear ( )
wallet . up_to_date = False
wallet . update ( )
if wallet . is_found ( ) :
2012-07-07 06:39:25 -07:00
print " Recovery successful "
2012-05-13 10:19:28 +02:00
else :
2012-07-07 09:24:52 -07:00
print_error ( " Warning: Found no history for this wallet " )
2012-09-20 16:46:11 +07:00
else :
wallet . synchronize ( )
2012-05-13 10:19:28 +02:00
wallet . fill_addressbook ( )
wallet . save ( )
2012-07-07 09:24:52 -07:00
print_error ( " Wallet saved in ' " + wallet . path )
2011-11-06 11:13:58 +01:00
else :
wallet . new_seed ( None )
2012-03-23 20:58:54 +01:00
wallet . init_mpk ( wallet . seed )
wallet . synchronize ( ) # there is no wallet thread
2012-02-21 17:13:34 +01:00
wallet . save ( )
2012-02-21 14:36:45 +01:00
print " Your wallet generation seed is: " + wallet . seed
print " Please keep it in a safe place; if you lose it, you will not be able to restore your wallet. "
print " Equivalently, your wallet seed can be stored and recovered with the following mnemonic code: "
print " \" " + ' ' . join ( mnemonic . mn_encode ( wallet . seed ) ) + " \" "
2012-05-15 07:23:29 +02:00
print " Wallet saved in ' %s ' " % wallet . path
2012-05-17 08:49:30 +02:00
if password :
wallet . update_password ( wallet . seed , None , password )
2011-11-04 18:00:37 +01:00
2011-11-12 00:07:41 +01:00
# check syntax
2012-02-08 09:36:19 +01:00
if cmd in [ ' payto ' , ' mktx ' ] :
2011-11-12 00:07:41 +01:00
try :
2012-02-08 09:36:19 +01:00
to_address = args [ 1 ]
amount = int ( 100000000 * Decimal ( args [ 2 ] ) )
2012-02-08 04:22:18 +01:00
change_addr = None
2012-02-08 09:36:19 +01:00
label = ' ' . join ( args [ 3 : ] )
2011-12-18 22:49:33 +01:00
if options . tx_fee :
options . tx_fee = int ( 100000000 * Decimal ( options . tx_fee ) )
2011-11-12 00:07:41 +01:00
except :
2011-11-16 18:12:13 +03:00
firstarg = cmd
cmd = ' help '
2011-11-12 00:07:41 +01:00
2011-11-14 20:35:54 +01:00
# open session
2012-05-13 10:19:28 +02:00
if cmd not in offline_commands and not options . offline :
2012-03-31 11:47:16 +02:00
WalletSynchronizer ( wallet ) . start ( )
2012-03-23 16:34:34 +01:00
wallet . update ( )
2011-11-14 20:35:54 +01:00
wallet . save ( )
2012-02-11 06:48:44 +01:00
# check if --from_addr not in wallet (for mktx/payto)
is_temporary = False
from_addr = None
if options . from_addr :
from_addr = options . from_addr
if from_addr not in wallet . all_addresses ( ) :
is_temporary = True
2011-11-14 20:35:54 +01:00
# commands needing password
2012-03-23 13:55:27 +01:00
if cmd in protected_commands or ( cmd == ' addresses ' and options . show_keys ) :
2012-08-01 21:51:40 +02:00
password = prompt_password ( ' Password: ' , False ) if wallet . use_encryption and not is_temporary else None
2011-12-20 14:22:31 +01:00
# check password
2011-12-20 12:37:48 +01:00
try :
2011-12-20 14:22:31 +01:00
wallet . pw_decode ( wallet . seed , password )
2011-12-20 12:37:48 +01:00
except :
2012-07-07 09:24:52 -07:00
print_error ( " Error: This password does not decode this wallet. " )
2011-12-20 12:37:48 +01:00
exit ( 1 )
2011-12-20 14:22:31 +01:00
if cmd == ' import ' :
2012-08-01 21:52:52 +02:00
# See if they specificed a key on the cmd line, if not prompt
if len ( args ) > 1 :
keypair = args [ 1 ]
else :
keypair = prompt_password ( ' Enter Address:PrivateKey (will not echo): ' , False )
2012-05-30 14:42:30 +02:00
try :
wallet . import_key ( keypair , password )
wallet . save ( )
2012-07-07 06:39:25 -07:00
print " Keypair imported "
2012-05-30 14:42:30 +02:00
except BaseException , e :
2012-07-07 09:24:52 -07:00
print_error ( " Error: Keypair import failed: " + str ( e ) )
2011-12-20 12:37:48 +01:00
2012-07-17 22:50:20 +02:00
if cmd == ' help ' :
2011-11-16 18:12:13 +03:00
cmd2 = firstarg
if cmd2 not in known_commands :
2012-07-17 22:50:20 +02:00
parser . print_help ( )
2012-07-07 06:39:25 -07:00
print " Type ' electrum help <command> ' to see the help for a specific command "
print " Type ' electrum --help ' to see the list of options "
print " List of commands: " , ' , ' . join ( known_commands )
2012-06-06 19:52:52 +02:00
else :
print known_commands [ cmd2 ]
2011-11-16 18:12:13 +03:00
elif cmd == ' seed ' :
2011-11-18 13:07:28 +01:00
seed = wallet . pw_decode ( wallet . seed , password )
2012-05-16 19:33:42 +02:00
print seed + ' " ' + ' ' . join ( mnemonic . mn_encode ( seed ) ) + ' " '
2011-11-14 20:35:54 +01:00
2012-05-13 00:43:22 +02:00
elif cmd == ' deseed ' :
2012-05-13 01:32:28 +02:00
if not wallet . seed :
2012-07-07 09:24:52 -07:00
print_error ( " Error: This wallet has no seed " )
2012-05-13 02:36:44 +02:00
elif wallet . use_encryption :
2012-07-07 09:24:52 -07:00
print_error ( " Error: This wallet is encrypted " )
2012-05-13 00:43:22 +02:00
else :
2012-05-16 19:49:41 +02:00
ns = wallet . path + ' .seed '
print " Warning: you are going to extract the seed from ' %s ' \n The seed will be saved in ' %s ' " % ( wallet . path , ns )
2012-05-13 01:32:28 +02:00
if raw_input ( " Are you sure you want to continue? (y/n) " ) in [ ' y ' , ' Y ' , ' yes ' ] :
f = open ( ns , ' w ' )
2012-05-17 18:10:36 +02:00
f . write ( repr ( { ' seed ' : wallet . seed , ' imported_keys ' : wallet . imported_keys } ) + " \n " )
2012-05-13 01:32:28 +02:00
f . close ( )
wallet . seed = ' '
2012-05-17 18:10:36 +02:00
for k in wallet . imported_keys . keys ( ) : wallet . imported_keys [ k ] = ' '
2012-05-13 01:32:28 +02:00
wallet . save ( )
print " Done. "
else :
2012-07-07 09:24:52 -07:00
print_error ( " Action canceled. " )
2012-05-13 01:32:28 +02:00
elif cmd == ' reseed ' :
if wallet . seed :
2012-07-07 06:39:25 -07:00
print " Warning: This wallet already has a seed " , wallet . seed
2012-05-13 01:32:28 +02:00
else :
2012-05-16 19:49:41 +02:00
ns = wallet . path + ' .seed '
2012-05-13 01:32:28 +02:00
try :
f = open ( ns , ' r ' )
2012-05-17 18:10:36 +02:00
data = f . read ( )
2012-05-13 01:32:28 +02:00
f . close ( )
2012-08-19 18:19:59 -07:00
except IOError :
sys . exit ( " Error: Seed file not found " )
2012-05-17 18:10:36 +02:00
try :
import ast
d = ast . literal_eval ( data )
seed = d [ ' seed ' ]
imported_keys = d . get ( ' imported_keys ' , { } )
except :
2012-08-19 18:19:59 -07:00
sys . exit ( " Error: Error with seed file " )
2012-05-13 01:32:28 +02:00
mpk = wallet . master_public_key
wallet . seed = seed
2012-05-17 18:10:36 +02:00
wallet . imported_keys = imported_keys
2012-05-13 01:32:28 +02:00
wallet . use_encryption = False
wallet . init_mpk ( seed )
if mpk == wallet . master_public_key :
wallet . save ( )
2012-05-16 19:51:00 +02:00
print " Done: " + wallet . path
2012-05-13 01:32:28 +02:00
else :
2012-07-07 09:24:52 -07:00
print_error ( " Error: Master public key does not match " )
2012-05-13 01:32:28 +02:00
2011-11-17 01:55:29 +01:00
elif cmd == ' validateaddress ' :
addr = args [ 1 ]
print wallet . is_valid ( addr )
2011-11-16 17:16:36 +03:00
elif cmd == ' balance ' :
2012-01-16 02:02:48 +02:00
try :
addrs = args [ 1 : ]
except :
pass
if addrs == [ ] :
c , u = wallet . get_balance ( )
if u :
2012-02-06 07:48:52 +01:00
print Decimal ( c ) / 100000000 , Decimal ( u ) / 100000000
2012-01-16 02:02:48 +02:00
else :
2012-02-06 07:48:52 +01:00
print Decimal ( c ) / 100000000
2011-11-04 18:00:37 +01:00
else :
2012-01-16 02:02:48 +02:00
for addr in addrs :
c , u = wallet . get_addr_balance ( addr )
if u :
2012-02-06 07:48:52 +01:00
print " %s %s , %s " % ( addr , str ( Decimal ( c ) / 100000000 ) , str ( Decimal ( u ) / 100000000 ) )
2012-01-16 02:02:48 +02:00
else :
2012-02-06 07:48:52 +01:00
print " %s %s " % ( addr , str ( Decimal ( c ) / 100000000 ) )
2011-11-04 18:00:37 +01:00
2011-11-14 20:35:54 +01:00
elif cmd in [ ' contacts ' ] :
2011-11-12 00:07:41 +01:00
for addr in wallet . addressbook :
print addr , " " , wallet . labels . get ( addr )
2012-02-06 18:13:33 +01:00
elif cmd == ' eval ' :
print eval ( args [ 1 ] )
2012-02-06 18:55:25 +01:00
wallet . save ( )
2012-02-03 17:38:43 +01:00
2011-11-14 20:35:54 +01:00
elif cmd in [ ' addresses ' ] :
2011-12-18 22:49:33 +01:00
for addr in wallet . all_addresses ( ) :
2011-11-14 20:35:54 +01:00
if options . show_all or not wallet . is_change ( addr ) :
2012-06-07 11:03:13 +02:00
2012-06-07 16:14:08 +02:00
flags = wallet . get_address_flags ( addr )
2012-06-07 11:03:13 +02:00
label = wallet . labels . get ( addr , ' ' )
2012-06-07 16:14:08 +02:00
2012-06-07 11:03:13 +02:00
if label : label = " \" %s \" " % label
2011-11-14 20:35:54 +01:00
if options . show_balance :
2011-12-21 17:58:14 +01:00
h = wallet . history . get ( addr , [ ] )
2012-06-07 11:03:13 +02:00
#ni = no = 0
#for item in h:
# if item['is_input']: ni += 1
# else: no += 1
b = format_satoshis ( wallet . get_addr_balance ( addr ) [ 0 ] )
2011-11-14 20:35:54 +01:00
else : b = ' '
2012-06-08 20:51:10 +02:00
m_addr = " %34s " % addr
2011-12-20 14:07:37 +01:00
if options . show_keys :
2012-06-08 20:51:10 +02:00
m_addr + = ' : ' + str ( wallet . get_private_key_base58 ( addr , password ) )
print flags , m_addr , b , label
2011-11-04 18:00:37 +01:00
if cmd == ' history ' :
lines = wallet . get_tx_history ( )
b = 0
for line in lines :
import datetime
2012-02-06 07:48:52 +01:00
v = line [ ' value ' ]
2011-11-04 18:00:37 +01:00
b + = v
try :
2012-04-03 09:29:36 +02:00
time_str = str ( datetime . datetime . fromtimestamp ( line [ ' timestamp ' ] ) )
2011-11-04 18:00:37 +01:00
except :
2012-04-03 09:29:36 +02:00
print line [ ' timestamp ' ]
2011-11-04 18:00:37 +01:00
time_str = ' pending '
label = line . get ( ' label ' )
if not label : label = line [ ' tx_hash ' ]
else : label = label + ' ' * ( 64 - len ( label ) )
2012-02-06 07:48:52 +01:00
print time_str , " " + label + " " + format_satoshis ( v ) + " " + format_satoshis ( b )
print " # balance: " , format_satoshis ( b )
2011-11-04 18:00:37 +01:00
elif cmd == ' label ' :
try :
2011-11-14 20:35:54 +01:00
tx = args [ 1 ]
label = ' ' . join ( args [ 2 : ] )
2011-11-04 18:00:37 +01:00
except :
2012-07-07 09:24:52 -07:00
print_error ( " Error. Syntax: label <tx_hash> <text> " )
2011-11-10 09:34:27 +01:00
sys . exit ( 1 )
2011-11-04 18:00:37 +01:00
wallet . labels [ tx ] = label
wallet . save ( )
2012-02-08 09:36:19 +01:00
elif cmd in [ ' payto ' , ' mktx ' ] :
2012-02-11 06:48:44 +01:00
if from_addr and is_temporary :
if from_addr . find ( " : " ) == - 1 :
2012-07-06 21:45:57 -07:00
keypair = from_addr + " : " + prompt_password ( ' Private key: ' , False )
2012-02-11 06:48:44 +01:00
else :
keypair = from_addr
from_addr = keypair . split ( ' : ' ) [ 0 ]
if not wallet . import_key ( keypair , password ) :
2012-07-07 09:24:52 -07:00
print_error ( " Error: Invalid key pair " )
2012-02-11 06:48:44 +01:00
exit ( 1 )
wallet . history [ from_addr ] = interface . retrieve_history ( from_addr )
wallet . update_tx_history ( )
change_addr = from_addr
2012-02-10 13:23:39 +01:00
2012-02-08 09:36:19 +01:00
if options . change_addr :
change_addr = options . change_addr
2012-02-10 13:23:39 +01:00
2011-11-12 00:07:41 +01:00
for k , v in wallet . labels . items ( ) :
if v == to_address :
to_address = k
2011-11-17 01:55:29 +01:00
print " alias " , to_address
2011-11-12 00:07:41 +01:00
break
2012-02-08 04:22:18 +01:00
if change_addr and v == change_addr :
change_addr = k
2011-12-18 22:49:33 +01:00
try :
2012-02-08 04:22:18 +01:00
tx = wallet . mktx ( to_address , amount , label , password ,
2012-02-10 13:23:39 +01:00
fee = options . tx_fee , change_addr = change_addr , from_addr = from_addr )
except :
import traceback
traceback . print_exc ( file = sys . stdout )
2011-12-18 22:49:33 +01:00
tx = None
2012-02-08 09:36:19 +01:00
if tx and cmd == ' payto ' :
2011-11-16 17:16:36 +03:00
r , h = wallet . sendtx ( tx )
print h
else :
2011-12-18 22:49:33 +01:00
print tx
2011-11-16 17:16:36 +03:00
2012-02-10 13:23:39 +01:00
if is_temporary :
wallet . imported_keys . pop ( from_addr )
2012-02-11 05:50:07 +01:00
del ( wallet . history [ from_addr ] )
2012-02-10 13:23:39 +01:00
wallet . save ( )
2011-12-15 15:41:50 +01:00
elif cmd == ' sendtx ' :
2011-11-16 17:16:36 +03:00
tx = args [ 1 ]
r , h = wallet . sendtx ( tx )
print h
2011-11-04 18:00:37 +01:00
elif cmd == ' password ' :
try :
2011-11-05 15:06:43 +01:00
seed = wallet . pw_decode ( wallet . seed , password )
2012-08-27 03:10:28 +02:00
except ValueError :
2012-08-19 18:24:02 -07:00
sys . exit ( " Error: Password does not decrypt this wallet. " )
2012-07-06 21:45:57 -07:00
new_password = prompt_password ( ' New password: ' )
wallet . update_password ( seed , password , new_password )
2011-11-04 18:00:37 +01:00
2012-02-01 20:27:03 +01:00
elif cmd == ' signmessage ' :
2012-07-17 22:53:06 +02:00
if len ( args ) < 3 :
print_error ( " Error: Invalid usage of signmessage. " )
print known_commands [ cmd ]
sys . exit ( 1 )
2012-06-12 10:46:21 +02:00
address = args [ 1 ]
message = ' ' . join ( args [ 2 : ] )
if len ( args ) > 3 :
print " Warning: Message was reconstructed from several arguments: " , repr ( message )
2012-02-01 20:27:03 +01:00
print wallet . sign_message ( address , message , password )
elif cmd == ' verifymessage ' :
2012-06-18 22:23:52 +02:00
try :
address = args [ 1 ]
signature = args [ 2 ]
message = ' ' . join ( args [ 3 : ] )
except :
2012-07-07 09:24:52 -07:00
print_error ( " Error: Not all parameters were given, displaying help instead. " )
2012-06-18 22:23:52 +02:00
print known_commands [ cmd ]
sys . exit ( 1 )
2012-06-12 10:46:21 +02:00
if len ( args ) > 4 :
print " Warning: Message was reconstructed from several arguments: " , repr ( message )
2012-02-03 11:48:09 +01:00
try :
wallet . verify_message ( address , signature , message )
print True
2012-08-26 23:35:38 +02:00
except BaseException as e :
print " Verification error: {0} " . format ( e )
2012-02-03 11:48:09 +01:00
print False
2012-06-06 19:26:05 +02:00
elif cmd == ' freeze ' :
addr = args [ 1 ]
2012-06-07 11:18:11 +02:00
print self . wallet . freeze ( addr )
2012-06-06 19:26:05 +02:00
elif cmd == ' unfreeze ' :
addr = args [ 1 ]
2012-06-07 11:18:11 +02:00
print self . wallet . unfreeze ( addr )
2012-06-06 19:26:05 +02:00
elif cmd == ' prioritize ' :
addr = args [ 1 ]
2012-06-07 11:18:11 +02:00
print self . wallet . prioritize ( addr )
2012-06-06 19:26:05 +02:00
elif cmd == ' unprioritize ' :
addr = args [ 1 ]
2012-06-07 11:18:11 +02:00
print self . wallet . unprioritize ( addr )
2012-02-01 20:27:03 +01:00