forked from bitcoinafterlife/bal-electrum-plugin
wallet utils
This commit is contained in:
69
wallet_util/bal_wallet_utils.py
Executable file
69
wallet_util/bal_wallet_utils.py
Executable file
@@ -0,0 +1,69 @@
|
||||
#!env/bin/python3
|
||||
from electrum.storage import WalletStorage
|
||||
from electrum.util import MyEncoder
|
||||
import json
|
||||
import sys
|
||||
import getpass
|
||||
import os
|
||||
|
||||
default_fees= 100
|
||||
|
||||
def fix_will_settings_tx_fees(json_wallet):
|
||||
tx_fees = json_wallet.get('will_settings',{}).get('tx_fees',False)
|
||||
have_to_update=False
|
||||
if tx_fees:
|
||||
json_wallet['will_settings']['baltx_fees']=tx_fees
|
||||
del json_wallet['will_settings']['tx_fees']
|
||||
have_to_update=True
|
||||
for txid,willitem in json_wallet['will'].items():
|
||||
tx_fees=willitem.get('tx_fees',False)
|
||||
if tx_fees:
|
||||
json_wallet['will'][txid]['baltx_fees']=tx_fees
|
||||
del json_wallet['will'][txid]['tx_fees']
|
||||
have_to_update=True
|
||||
return have_to_update
|
||||
|
||||
def uninstall_bal(json_wallet):
|
||||
del json_wallet['will_settings']
|
||||
del json_wallet['will']
|
||||
del json_wallet['heirs']
|
||||
return True
|
||||
|
||||
def save(json_wallet,storage):
|
||||
human_readable=not storage.is_encrypted()
|
||||
storage.write(json.dumps(
|
||||
json_wallet,
|
||||
indent=4 if human_readable else None,
|
||||
sort_keys=bool(human_readable),
|
||||
cls=MyEncoder,
|
||||
))
|
||||
def read_wallet(path,password=False):
|
||||
storage=WalletStorage(path)
|
||||
if storage.is_encrypted():
|
||||
if password==False:
|
||||
password = getpass.getpass("Enter wallet password: ", stream = None)
|
||||
storage.decrypt(password)
|
||||
data=storage.read()
|
||||
json_wallet=json.loads('['+data+']')[0]
|
||||
return json_wallet
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) <3:
|
||||
print("usage: ./bal_wallet_utils <command> <wallet path>")
|
||||
print("available commands: uninstall, fix")
|
||||
exit(1)
|
||||
if not os.path.exists(sys.argv[2]):
|
||||
print("Error: wallet not found")
|
||||
exit(1)
|
||||
command = sys.argv[1]
|
||||
path = sys.argv[2]
|
||||
json_wallet = read_wallet(path)
|
||||
have_to_save=False
|
||||
if command == 'fix':
|
||||
have_to_save = fix_will_settings_tx_fees(json_wallet)
|
||||
if command == 'uninstall':
|
||||
have_to_save = uninstall_bal(json_wallet)
|
||||
if have_to_save:
|
||||
save(json_wallet,storage)
|
||||
else:
|
||||
print("nothing to do")
|
||||
188
wallet_util/bal_wallet_utils_qt.py
Executable file
188
wallet_util/bal_wallet_utils_qt.py
Executable file
@@ -0,0 +1,188 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
from PyQt6.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QHBoxLayout,
|
||||
QLabel, QLineEdit, QPushButton, QWidget, QFileDialog,
|
||||
QGroupBox, QTextEdit)
|
||||
from PyQt6.QtCore import Qt
|
||||
from electrum.storage import WalletStorage
|
||||
from electrum.util import MyEncoder
|
||||
from bal_wallet_utils import fix_will_settings_tx_fees,uninstall_bal,read_wallet
|
||||
|
||||
class WalletUtilityGUI(QMainWindow):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.initUI()
|
||||
|
||||
def initUI(self):
|
||||
self.setWindowTitle('BAL Wallet Utility')
|
||||
self.setFixedSize(500, 400)
|
||||
|
||||
# Central widget
|
||||
central_widget = QWidget()
|
||||
self.setCentralWidget(central_widget)
|
||||
|
||||
# Main layout
|
||||
layout = QVBoxLayout(central_widget)
|
||||
|
||||
# Wallet input group
|
||||
wallet_group = QGroupBox("Wallet Settings")
|
||||
wallet_layout = QVBoxLayout(wallet_group)
|
||||
|
||||
# Wallet path
|
||||
wallet_path_layout = QHBoxLayout()
|
||||
wallet_path_layout.addWidget(QLabel("Wallet Path:"))
|
||||
self.wallet_path_edit = QLineEdit()
|
||||
self.wallet_path_edit.setPlaceholderText("Select wallet path...")
|
||||
wallet_path_layout.addWidget(self.wallet_path_edit)
|
||||
|
||||
self.browse_btn = QPushButton("Browse...")
|
||||
self.browse_btn.clicked.connect(self.browse_wallet)
|
||||
wallet_path_layout.addWidget(self.browse_btn)
|
||||
|
||||
wallet_layout.addLayout(wallet_path_layout)
|
||||
|
||||
# Password
|
||||
password_layout = QHBoxLayout()
|
||||
password_layout.addWidget(QLabel("Password:"))
|
||||
self.password_edit = QLineEdit()
|
||||
self.password_edit.setEchoMode(QLineEdit.EchoMode.Password)
|
||||
self.password_edit.setPlaceholderText("Enter password (if encrypted)")
|
||||
password_layout.addWidget(self.password_edit)
|
||||
|
||||
wallet_layout.addLayout(password_layout)
|
||||
|
||||
layout.addWidget(wallet_group)
|
||||
|
||||
# Output area
|
||||
output_group = QGroupBox("Output")
|
||||
output_layout = QVBoxLayout(output_group)
|
||||
|
||||
self.output_text = QTextEdit()
|
||||
self.output_text.setReadOnly(True)
|
||||
output_layout.addWidget(self.output_text)
|
||||
|
||||
layout.addWidget(output_group)
|
||||
|
||||
# Action buttons
|
||||
buttons_layout = QHBoxLayout()
|
||||
|
||||
self.fix_btn = QPushButton("Fix")
|
||||
self.fix_btn.clicked.connect(self.fix_wallet)
|
||||
self.fix_btn.setEnabled(False)
|
||||
buttons_layout.addWidget(self.fix_btn)
|
||||
|
||||
self.uninstall_btn = QPushButton("Uninstall")
|
||||
self.uninstall_btn.clicked.connect(self.uninstall_wallet)
|
||||
self.uninstall_btn.setEnabled(False)
|
||||
buttons_layout.addWidget(self.uninstall_btn)
|
||||
|
||||
layout.addLayout(buttons_layout)
|
||||
|
||||
# Connections to enable buttons when path is entered
|
||||
self.wallet_path_edit.textChanged.connect(self.check_inputs)
|
||||
|
||||
def browse_wallet(self):
|
||||
file_path, _ = QFileDialog.getOpenFileName(
|
||||
self,
|
||||
"Select Wallet",
|
||||
"*",
|
||||
"Electrum Wallet (*)"
|
||||
)
|
||||
if file_path:
|
||||
self.wallet_path_edit.setText(file_path)
|
||||
|
||||
def check_inputs(self):
|
||||
wallet_path = self.wallet_path_edit.text().strip()
|
||||
has_path = bool(wallet_path) and os.path.exists(wallet_path)
|
||||
|
||||
self.fix_btn.setEnabled(has_path)
|
||||
self.uninstall_btn.setEnabled(has_path)
|
||||
|
||||
def log_message(self, message):
|
||||
self.output_text.append(message)
|
||||
|
||||
def fix_wallet(self):
|
||||
self.process_wallet('fix')
|
||||
|
||||
def uninstall_wallet(self):
|
||||
self.log_message("WARNING: This will remove all BAL settings. This operation cannot be undone.")
|
||||
self.process_wallet('uninstall')
|
||||
|
||||
def process_wallet(self, command):
|
||||
wallet_path = self.wallet_path_edit.text().strip()
|
||||
password = self.password_edit.text()
|
||||
|
||||
if not wallet_path:
|
||||
self.log_message("ERROR: Please enter wallet path")
|
||||
return
|
||||
|
||||
if not os.path.exists(wallet_path):
|
||||
self.log_message("ERROR: Wallet not found")
|
||||
return
|
||||
|
||||
try:
|
||||
self.log_message(f"Processing wallet: {wallet_path}")
|
||||
|
||||
storage = WalletStorage(wallet_path)
|
||||
|
||||
# Decrypt if necessary
|
||||
if storage.is_encrypted():
|
||||
if not password:
|
||||
self.log_message("ERROR: Wallet is encrypted, please enter password")
|
||||
return
|
||||
|
||||
try:
|
||||
storage.decrypt(password)
|
||||
self.log_message("Wallet decrypted successfully")
|
||||
except Exception as e:
|
||||
self.log_message(f"ERROR: Wrong password: {str(e)}")
|
||||
return
|
||||
|
||||
# Read wallet
|
||||
data = storage.read()
|
||||
json_wallet = json.loads('[' + data + ']')[0]
|
||||
|
||||
have_to_save = False
|
||||
message = ""
|
||||
|
||||
if command == 'fix':
|
||||
have_to_save = fix_will_settings_tx_fees(json_wallet)
|
||||
message = "Fix applied successfully" if have_to_save else "No fix needed"
|
||||
|
||||
elif command == 'uninstall':
|
||||
have_to_save = uninstall_bal(json_wallet)
|
||||
message = "BAL uninstalled successfully" if have_to_save else "No BAL settings found to uninstall"
|
||||
|
||||
if have_to_save:
|
||||
try:
|
||||
save_wallet(json_wallet, storage)
|
||||
self.log_message(f"SUCCESS: {message}")
|
||||
except Exception as e:
|
||||
self.log_message(f"Save error: {str(e)}")
|
||||
else:
|
||||
self.log_message(f"INFO: {message}")
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"ERROR: Processing failed: {str(e)}"
|
||||
self.log_message(error_msg)
|
||||
|
||||
def main():
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
# Check if dependencies are available
|
||||
try:
|
||||
from electrum.storage import WalletStorage
|
||||
from electrum.util import MyEncoder
|
||||
except ImportError as e:
|
||||
print(f"ERROR: Cannot import Electrum dependencies: {str(e)}")
|
||||
return 1
|
||||
|
||||
window = WalletUtilityGUI()
|
||||
window.show()
|
||||
|
||||
return app.exec()
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user