@ -16,7 +16,7 @@ from jmclient import (get_network, WALLET_IMPLEMENTATIONS, Storage, podle,
jm_single , BitcoinCoreInterface , JsonRpcError , sync_wallet , WalletError ,
VolatileStorage , StoragePasswordError ,
is_segwit_mode , SegwitLegacyWallet , LegacyWallet )
from jmbase . support import get_password
from jmbase . support import get_password , jmprint
from . cryptoengine import TYPE_P2PKH , TYPE_P2SH_P2WPKH
import jmbitcoin as btc
@ -456,7 +456,7 @@ def cli_get_wallet_passphrase_check():
password = get_password ( ' Enter wallet file encryption passphrase: ' )
password2 = get_password ( ' Reenter wallet file encryption passphrase: ' )
if password != password2 :
print ( ' ERROR. Passwords did not match ' )
jm print( ' ERROR. Passwords did not match ' , " error " )
return False
return password
@ -467,7 +467,7 @@ def cli_display_user_words(words, mnemonic_extension):
text = ' Write down this wallet recovery mnemonic \n \n ' + words + ' \n '
if mnemonic_extension :
text + = ' \n And this mnemonic extension: ' + mnemonic_extension + ' \n '
print ( text )
jm print( text , " important " )
def cli_user_mnemonic_entry ( ) :
mnemonic_phrase = input ( " Input mnemonic recovery phrase: " )
@ -480,9 +480,10 @@ def cli_get_mnemonic_extension():
uin = input ( " Would you like to use a two-factor mnemonic recovery "
" phrase? write ' n ' if you don ' t know what this is (y/n): " )
if len ( uin ) == 0 or uin [ 0 ] != ' y ' :
print ( " Not using mnemonic extension " )
jm print( " Not using mnemonic extension " , " info " )
return None #no mnemonic extension
print ( " Note: This will be stored in a reversible way. Do not reuse! " )
jmprint ( " Note: This will be stored in a reversible way. Do not reuse! " ,
" info " )
return input ( " Enter mnemonic extension: " )
@ -554,7 +555,7 @@ def wallet_generate_recover(method, walletspath,
try :
entropy = LegacyWallet . entropy_from_mnemonic ( seed )
except WalletError as e :
print ( " Unable to restore seed: {} " . format ( e . message ) )
jm print( " Unable to restore seed: {} " . format ( e . message ) , " error " )
return False
elif method != ' generate ' :
raise Exception ( " unknown method for wallet creation: ' {} ' "
@ -571,8 +572,8 @@ def wallet_generate_recover(method, walletspath,
wallet = create_wallet ( wallet_path , password , mixdepth ,
wallet_cls = LegacyWallet , entropy = entropy )
print ( " Write down and safely store this wallet recovery seed \n \n {} \n "
. format ( wallet . get_mnemonic_words ( ) [ 0 ] ) )
jm print( " Write down and safely store this wallet recovery seed \n \n {} \n "
. format ( wallet . get_mnemonic_words ( ) [ 0 ] ) , " important " )
wallet . close ( )
return True
@ -628,7 +629,7 @@ def wallet_fetch_history(wallet, options):
sat_to_str ( balance ) , skip_n1 ( cj_n ) , sat_to_str ( miner_fees ) ,
' % 3d ' % utxo_count , skip_n1 ( mixdepth_src ) , skip_n1 ( mixdepth_dst ) ]
if options . verbosity % 2 == 0 : data + = [ txid ]
print ( s ( ) . join ( map ( ' " {} " ' . format , data ) ) )
jm print( s ( ) . join ( map ( ' " {} " ' . format , data ) ) , " info " )
field_names = [ ' tx# ' , ' timestamp ' , ' type ' , ' amount/btc ' ,
@ -636,9 +637,9 @@ def wallet_fetch_history(wallet, options):
' utxo-count ' , ' mixdepth-from ' , ' mixdepth-to ' ]
if options . verbosity % 2 == 0 : field_names + = [ ' txid ' ]
if options . csv :
print ( ' Bumping verbosity level to 4 due to --csv flag ' )
jm print( ' Bumping verbosity level to 4 due to --csv flag ' , " debug " )
options . verbosity = 4
if options . verbosity > 0 : print ( s ( ) . join ( field_names ) )
if options . verbosity > 0 : jm print( s ( ) . join ( field_names ) , " info " )
if options . verbosity < = 2 : cj_batch = [ 0 ] * 8 + [ [ ] ] * 2
balance = 0
utxo_count = 0
@ -722,7 +723,7 @@ def wallet_fetch_history(wallet, options):
#payment to self
out_value = sum ( [ output_script_values [ a ] for a in our_output_scripts ] )
if not is_coinjoin :
print ( ' this is wrong TODO handle non-coinjoin internal ' )
jm print( ' this is wrong TODO handle non-coinjoin internal ' , " warning " )
tx_type = ' cj internal '
amount = cj_amount
delta_balance = out_value - our_input_value
@ -732,7 +733,7 @@ def wallet_fetch_history(wallet, options):
mixdepth_dst = wallet . get_script_mixdepth ( cj_script )
else :
tx_type = ' unknown type '
print ( ' our utxos: ' + str ( len ( our_input_scripts ) ) \
jm print( ' our utxos: ' + str ( len ( our_input_scripts ) ) \
+ ' in, ' + str ( len ( our_output_scripts ) ) + ' out ' )
balance + = delta_balance
utxo_count + = ( len ( our_output_scripts ) - utxos_consumed )
@ -790,10 +791,10 @@ def wallet_fetch_history(wallet, options):
) [ ' time ' ]
except JsonRpcError :
now = jm_single ( ) . bc_interface . rpc ( ' getblock ' , [ bestblockhash ] ) [ ' time ' ]
print ( ' %s best block is %s ' % ( datetime . fromtimestamp ( now )
jm print( ' %s best block is %s ' % ( datetime . fromtimestamp ( now )
. strftime ( " % Y- % m- %d % H: % M " ) , bestblockhash ) )
total_profit = float ( balance - sum ( deposits ) ) / float ( 100000000 )
print ( ' total profit = %.8f BTC ' % total_profit )
jm print( ' total profit = %.8f BTC ' % total_profit )
if abs ( total_profit ) > 0 :
try :
@ -808,21 +809,21 @@ def wallet_fetch_history(wallet, options):
return np . sum ( np . exp ( ( now - deposit_times ) / 60.0 / 60 / 24 /
365 ) * * r * deposits ) - final_balance
r = brentq ( f , a = 1 , b = - 1 , args = ( deposits , deposit_times , now , balance ) )
print ( ' continuously compounded equivalent annual interest rate = ' +
jm print( ' continuously compounded equivalent annual interest rate = ' +
str ( r * 100 ) + ' % ' )
print ( ' (as if yield generator was a bank account) ' )
jm print( ' (as if yield generator was a bank account) ' )
except ImportError :
print ( ' scipy not installed, unable to predict accumulation rate ' )
print ( ' to add it to this virtualenv, use `pip install scipy` ' )
jm print( ' scipy not installed, unable to predict accumulation rate ' )
jm print( ' to add it to this virtualenv, use `pip install scipy` ' )
total_wallet_balance = sum ( wallet . get_balance_by_mixdepth ( ) . values ( ) )
if balance != total_wallet_balance :
print ( ( ' BUG ERROR: wallet balance ( %s ) does not match balance from ' +
jm print( ( ' BUG ERROR: wallet balance ( %s ) does not match balance from ' +
' history ( %s ) ' ) % ( sat_to_str ( total_wallet_balance ) ,
sat_to_str ( balance ) ) )
wallet_utxo_count = sum ( map ( len , wallet . get_utxos_by_mixdepth_ ( ) . values ( ) ) )
if utxo_count != wallet_utxo_count :
print ( ( ' BUG ERROR: wallet utxo count ( %d ) does not match utxo count from ' +
jm print( ( ' BUG ERROR: wallet utxo count ( %d ) does not match utxo count from ' +
' history ( %s ) ' ) % ( wallet_utxo_count , utxo_count ) )
@ -835,11 +836,11 @@ def wallet_showseed(wallet):
def wallet_importprivkey ( wallet , mixdepth , key_type ) :
print ( " WARNING: This imported key will not be recoverable with your 12 "
" word mnemonic phrase. Make sure you have backups. " )
print ( " WARNING: Handling of raw ECDSA bitcoin private keys can lead to "
jm print( " WARNING: This imported key will not be recoverable with your 12 "
" word mnemonic phrase. Make sure you have backups. " , " warning " )
jm print( " WARNING: Handling of raw ECDSA bitcoin private keys can lead to "
" non-intuitive behaviour and loss of funds. \n Recommended instead "
" is to use the \' sweep \' feature of sendpayment.py. " )
" is to use the \' sweep \' feature of sendpayment.py. " , " warning " )
privkeys = input ( " Enter private key(s) to import: " )
privkeys = privkeys . split ( ' , ' ) if ' , ' in privkeys else privkeys . split ( )
imported_addr = [ ]
@ -857,20 +858,22 @@ def wallet_importprivkey(wallet, mixdepth, key_type):
imported_addr . append ( wallet . get_addr_path ( path ) )
if not imported_addr :
print ( " Warning: No keys imported! " )
jm print( " Warning: No keys imported! " , " error " )
return
wallet . save ( )
# show addresses to user so they can verify everything went as expected
print ( " Imported keys for addresses: \n {} " . format ( ' \n ' . join ( imported_addr ) ) )
jmprint ( " Imported keys for addresses: \n {} " . format ( ' \n ' . join ( imported_addr ) ) ,
" success " )
if import_failed :
print ( " Warning: failed to import {} keys " . format ( import_failed ) )
jmprint ( " Warning: failed to import {} keys " . format ( import_failed ) ,
" error " )
def wallet_dumpprivkey ( wallet , hdpath ) :
if not hdpath :
print ( " Error: no hd wallet path supplied " )
jm print( " Error: no hd wallet path supplied " , " error " )
return False
path = wallet . path_repr_to_path ( hdpath )
return wallet . get_wif_path ( path ) # will raise exception on invalid path
@ -992,10 +995,11 @@ def open_wallet(path, ask_for_password=True, password=None, read_only=False,
pwd = get_password ( " Enter wallet decryption passphrase: " ) or None
storage = Storage ( path , password = pwd , read_only = read_only )
except StoragePasswordError :
print ( " Wrong password, try again. " )
jm print( " Wrong password, try again. " , " warning " )
continue
except Exception as e :
print ( " Failed to load wallet, error message: " + repr ( e ) )
jmprint ( " Failed to load wallet, error message: " + repr ( e ) ,
" error " )
raise e
break
else :
@ -1081,8 +1085,8 @@ def wallet_tool_main(wallet_root_path):
return wallet_display ( wallet , options . gaplimit , options . showprivkey , summarized = True )
elif method == " history " :
if not isinstance ( jm_single ( ) . bc_interface , BitcoinCoreInterface ) :
print ( ' showing history only available when using the Bitcoin Core ' +
' blockchain interface ' )
jm print( ' showing history only available when using the Bitcoin Core ' +
' blockchain interface ' , " error " )
sys . exit ( 0 )
else :
return wallet_fetch_history ( wallet , options )
@ -1133,5 +1137,5 @@ if __name__ == "__main__":
acctlist . append ( WalletViewAccount ( rootpath , a , branches = branches ) )
wallet = WalletView ( rootpath + " / " + str ( walletbranch ) ,
accounts = acctlist )
print ( wallet . serialize ( ) )
jm print( wallet . serialize ( ) , " success " )