commit 934c3348fb71f48db933c88fd9f7b79efa1494f3
parent ba4c3c2b080f2e8d7e235bacce82c6150dedd339
Author: lash <dev@holbrook.no>
Date: Sun, 7 Jun 2026 16:08:03 -0600
Remove need for wallet files
Diffstat:
6 files changed, 116 insertions(+), 150 deletions(-)
diff --git a/dummy/usawa/context.py b/dummy/usawa/context.py
@@ -108,16 +108,27 @@ class UsawaContext:
return pw
- def load_wallet(self):
+ def check_wallet(self):
if self.wallet != None:
+ return True
+ self.keystore.get_default_key(DemoWallet)
+ return True
+
+
+ def load_wallet(self, signing=False, replace=False):
+ if self.wallet != None and not replace:
raise AttributeError('wallet set')
- if not self.signing:
+ if not self.signing and not signing:
+ self.wallet = self.keystore.get_default_key(DemoWallet)
+ elif not signing:
self.wallet = self.keystore.get_default_key(DemoWallet)
else:
+ logg.debug('decrypting wallet')
ops = int(self.cfg.get('WALLET_OPSLIMIT', 0))
mem = int(self.cfg.get('WALLET_MEMLIMIT', 0))
pw = self.getpw()
self.wallet = self.keystore.get_key(DemoWallet, passphrase=pw, opslimit=ops, memlimit=mem)
+ logg.debug('have wallet {}'.format(self.wallet))
if self.ledger != None:
self.ledger.set_wallet(self.wallet)
@@ -165,11 +176,11 @@ class UsawaContext:
if store_scope == 'ledger':
self.store = LedgerStore(self.db, self.ledger)
self.keystore = self.store
- elif store_scope == 'asset' or store_scope == 'entry':
+ elif store_scope == 'asset' or store_scope == 'entry' or store_scope == 'key':
self.keystore = KeyStore(self.db)
if store_scope == 'asset':
self.store = AssetStore(self.db)
- else:
+ elif store_scope == 'entry':
self.store = EntryStore(self.db)
diff --git a/dummy/usawa/gui/__init__.py b/dummy/usawa/gui/__init__.py
@@ -14,19 +14,21 @@ logg = logging.getLogger("gui.app")
class Usawa(Adw.Application):
- def __init__(self, *args, **kwargs):
+ def __init__(self, ctx, *args, **kwargs):
super().__init__(
flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE, *args, **kwargs
)
+ self.ctx = ctx
self.win = None
self.ledger_file = None
- self.cfg = None
+ self.cfg = ctx.cfg
self.account_list = None
self.connect("activate", self.on_activate)
signal.signal(signal.SIGINT, self._handle_sigint)
def on_activate(self, app):
- self.win = UsawaMainWindow(application=app, ledger_path=self.ledger_file, account_list=self.account_list)
+ #self.win = UsawaMainWindow(application=app, ledger_path=self.ledger_file, account_list=self.account_list)
+ self.win = UsawaMainWindow(app, self.ctx)
self.win.present()
def _handle_sigint(self, *_):
@@ -34,36 +36,37 @@ class Usawa(Adw.Application):
self.quit()
def do_command_line(self, cli):
- args = cli.get_arguments()
-
- config_dir = None
- filtered_args = []
- i = 1
- while i < len(args):
- if args[i] == "-c":
- if i + 1 < len(args):
- config_dir = args[i + 1]
- i += 2
- else:
- logg.error("-c flag requires a directory argument")
- return 1
- else:
- filtered_args.append(args[i])
- i += 1
- self.cfg = load_config(config_dir=config_dir)
- logg.debug('config-dump:\n{}'.format(self.cfg))
-
- if len(filtered_args) == 0:
- logg.error("missing ledger file argument")
- return 1
-
- if filtered_args[0] == "setup-wallet":
- wallet_dir = filtered_args[1] if len(filtered_args) > 1 else None
- setup_wallet(self.cfg, wallet_dir=wallet_dir)
- return 0
-
- self.ledger_file = filtered_args[0]
- for k in self.cfg.all():
- logg.debug("config {} => {}".format(k, self.cfg.get(k)))
+# args = cli.get_arguments()
+#
+# config_dir = None
+# filtered_args = []
+# i = 1
+# while i < len(args):
+# if args[i] == "-c":
+# if i + 1 < len(args):
+# config_dir = args[i + 1]
+# i += 2
+# else:
+# logg.error("-c flag requires a directory argument")
+# return 1
+# else:
+# filtered_args.append(args[i])
+# i += 1
+# self.cfg = load_config(config_dir=config_dir)
+# logg.debug('config-dump:\n{}'.format(self.cfg))
+#
+# if len(filtered_args) == 0:
+# logg.error("missing ledger file argument")
+# return 1
+#
+# #if filtered_args[0] == "setup-wallet":
+# # wallet_dir = filtered_args[1] if len(filtered_args) > 1 else None
+# # setup_wallet(self.cfg, wallet_dir=wallet_dir)
+# # return 0
+#
+# self.ledger_file = filtered_args[0]
+# for k in self.cfg.all():
+# logg.debug("config {} => {}".format(k, self.cfg.get(k)))
+# self.activate()
self.activate()
return 0
diff --git a/dummy/usawa/gui/main_window.py b/dummy/usawa/gui/main_window.py
@@ -19,17 +19,15 @@ from datetime import datetime
from usawa.store import LedgerStore
from whee.valkey import ValkeyStore
from whee.fs import FsStore
+import usawa.error
logg = logging.getLogger("gui.mainwindow")
class UsawaMainWindow(Adw.ApplicationWindow):
- def __init__(self, application, ledger_path=None, account_list=None, **kwargs):
+ def __init__(self, application, ctx, **kwargs):
super().__init__(application=application, **kwargs)
- logg.debug('foo')
-
- self.account_list = account_list
self.set_title("Usawa")
self.set_default_size(1000, 600)
@@ -47,23 +45,7 @@ class UsawaMainWindow(Adw.ApplicationWindow):
self.toast_overlay = Adw.ToastOverlay()
toolbar_view.set_content(self.toast_overlay)
- self.cfg = self.get_application().cfg
- self.unix_client = UnixClient(path=self.cfg.get("SERVER_SOCKET_FILE_PATH"))
- store_type = self.cfg.get('STORE_TYPE')
- if store_type == 'valkey':
- self.store = ValkeyStore(
- "",
- host=self.cfg.get("VALKEY_HOST"),
- port=self.cfg.get("VALKEY_PORT"),
- )
- elif store_type == 'fs':
- self.store = FsStore(
- base=self.cfg.get('FSSTORE_BASE'),
- )
- else:
- raise ValueError('invalid store type: ' + store_type)
-
- self.ledger_path = ledger_path
+ self.ctx = ctx
self.nav_view = Adw.NavigationView()
self.toast_overlay.set_child(self.nav_view)
@@ -133,7 +115,7 @@ class UsawaMainWindow(Adw.ApplicationWindow):
entries=entries,
refresh_callback=self.refresh_entries,
toast_overlay=self.toast_overlay,
- account_list=self.account_list,
+ #account_list=self.account_list,
)
self.entry_list_view._load_entries()
page.set_child(self.entry_list_view)
@@ -145,43 +127,24 @@ class UsawaMainWindow(Adw.ApplicationWindow):
self.entry_list_view._load_entries()
def _check_wallet_status(self):
- wallet_path = StateManager.get("wallet_path")
- if not wallet_path or not Path(wallet_path).exists():
- logg.info("no wallet in store, showing import dialog")
- dialog = ImportWalletDialog(self)
- dialog.present(self)
- else:
- ledger_tree = load(self.ledger_path)
- ledger = Ledger.from_tree(ledger_tree)
- store = LedgerStore(self.store, ledger)
+ try:
+ self.ctx.load_wallet(replace=True, signing=True)
+ self._init_with_wallet()
+ except usawa.error.VerifyError:
dialog = PassphraseDialog(
- store=store,
+ store=self.ctx.keystore,
wallet_class=DemoWallet,
- on_success=lambda wallet, passphrase: self._init_with_wallet(
- wallet, passphrase, False
- ),
+ on_success=self._init_with_wallet,
on_cancel=self._on_wallet_cancelled,
)
dialog.present(self)
- def _init_with_wallet(self, wallet, passphrase, save_wallet: bool = True):
- """Called after wallet is successfully imported."""
- self.wallet = wallet
-
- repository = LedgerRepository(
- ledger_path=self.ledger_path,
- unix_client=self.unix_client,
- valkey_store=self.store,
- cfg=self.cfg,
- wallet=self.wallet,
- )
+ def _init_with_wallet(self):
+ repository = LedgerRepository(self.ctx)
entry_service = EntryService(repository=repository)
self.entry_controller = EntryController(entry_service=entry_service)
self.entry_controller.add_entry_created_listener(self.refresh_entries)
- if save_wallet:
- self.entry_controller.save_wallet(wallet, passphrase)
-
entry_list_page = self._create_entry_list_page()
self.nav_view.add(entry_list_page)
diff --git a/dummy/usawa/runnable/gui.py b/dummy/usawa/runnable/gui.py
@@ -1,13 +1,35 @@
import logging
import sys
+import argparse
from usawa.gui import Usawa
+import usawa.config
+from usawa.context import UsawaContext
logging.basicConfig(level=logging.DEBUG)
+logg = logging.getLogger()
+
+
+def emptypw():
+ return ''
def main():
- app = Usawa(application_id='org.usawa.app')
+ argp = argparse.ArgumentParser()
+ argp.add_argument('-c', type=str, help='override config dir')
+ argp.add_argument('-i', type=str, help='input ledger state')
+ argp.add_argument('-v', type=str, choices=['info','debug','warning','error'], help='be verbose')
+ args = argp.parse_args()
+
+ if args.v:
+ logg.setLevel(getattr(logging, args.v.upper()))
+
+ cfg = usawa.config.load_config(config_dir=args.c)
+ ctx = UsawaContext(cfg, signing=False, pwgetter=emptypw)
+ ctx.init(args)
+ ctx.askpass = True
+
+ app = Usawa(ctx, application_id='org.usawa.app')
app.run(sys.argv)
diff --git a/dummy/usawa/runnable/server.py b/dummy/usawa/runnable/server.py
@@ -37,35 +37,39 @@ Public keys used to verify entries and ledger states are provided using the -k f
argp.add_argument('-c', type=str, help='override config dir')
argp.add_argument('-u', type=str, default='./usawa.socket', help='UNIX Socket file to listen on')
argp.add_argument('-v', type=str, choices=['info','debug','warning','error'], help='be verbose')
- argp.add_argument('ledger_xml_file', type=str, help='load ledger metadata from XML file')
+ argp.add_argument('-i', type=str, help='input ledger state')
+ #argp.add_argument('ledger_xml_file', type=str, help='load ledger metadata from XML file')
arg = argp.parse_args()
if arg.v:
logg.setLevel(getattr(logging, arg.v.upper()))
- #ctx = UsawaContext(arg)
+ cfg = usawa.config.load_config(config_dir=arg.c)
+ ctx = UsawaContext(cfg)
+ ctx.init(arg)
- acl = ACL()
- for k in arg.k:
- acl.add(k)
+ #acl = ACL()
+ #for k in arg.k:
+ # acl.add(k)
- ledger = None
- ledger_tree = load(arg.ledger_xml_file)
- uidx = UnitIndex.from_tree(ledger_tree)
- ledger = Ledger.from_tree(ledger_tree, acl=acl)
+ #ledger = None
+ #ledger_tree = load(arg.ledger_xml_file)
+ #uidx = UnitIndex.from_tree(ledger_tree)
+ #ledger = Ledger.from_tree(ledger_tree, acl=acl)
#db = ValkeyStore('', host=arg.valkey_host, port=arg.valkey_port)
#srv = TCPServer(db, ledger, acl=acl)
- db = None
- if cfg.get('STORE_TYPE') == 'valkey':
- dbid = cfg.get('VALKEY_ID')
- host = self.cfg.get('VALKEY_HOST')
- port = self.cfg.get('VALKEY_PORT')
- db = ValkeyStore('', host=host, port=port)
- elif self.cfg.get('STORE_TYPE') == 'fs':
- base = self.cfg.get('FSSTORE_BASE')
- db = FsStore(base=base, dbname='usawa')
- srv = UnixServer(db, ledger, acl=acl, path=arg.u)
+# db = None
+# if cfg.get('STORE_TYPE') == 'valkey':
+# dbid = cfg.get('VALKEY_ID')
+# host = self.cfg.get('VALKEY_HOST')
+# port = self.cfg.get('VALKEY_PORT')
+# db = ValkeyStore('', host=host, port=port)
+# elif self.cfg.get('STORE_TYPE') == 'fs':
+# base = self.cfg.get('FSSTORE_BASE')
+# db = FsStore(base=base, dbname='usawa')
+ #srv = UnixServer(ctx.db, ctx.ledger, acl=acl, path=arg.u)
+ srv = UnixServer(ctx.db, ctx.ledger, path=arg.u)
def stop_server(sig, stack):
srv.stop()
diff --git a/dummy/usawa/storage/ledger_repository.py b/dummy/usawa/storage/ledger_repository.py
@@ -29,11 +29,7 @@ class LedgerRepository:
def __init__(
self,
- ledger_path=None,
- unix_client: UnixClient = None,
- valkey_store: ValkeyStore = None,
- cfg=None,
- wallet=None,
+ ctx,
):
"""
Initialize the LedgerRepository.
@@ -45,40 +41,15 @@ class LedgerRepository:
:type unix_client: usawa.UnixClient
"""
- self.valkey_store = valkey_store
- self.unix_client = unix_client
- self._wallet = wallet
+ self.resolver = ctx.resolver
+ self.wallet = ctx.wallet
+ self.store = ctx.store
+ self.ledger = ctx.ledger
- self.ledger_path = ledger_path
- self.cfg = cfg
-
- logg.debug("fs resolver path: %s", self.cfg.get("FS_RESOLVER_STORE_PATH"))
- logg.debug(
- "fs_resolver as URI: %s",
- path_from_uri(self.cfg.get("FS_RESOLVER_STORE_PATH")),
- )
-
- self.resolver = FSResolver(
- path_from_uri(self.cfg.get("FS_RESOLVER_STORE_PATH"))
- )
def _init_store(self, write=False) -> tuple[LedgerStore, Ledger, Wallet]:
- ledger_tree = load(self.ledger_path)
- ledger = Ledger.from_tree(ledger_tree)
-
- if write:
- logg.info("init store for write")
- self.store = LedgerStore(self.valkey_store, ledger)
- else:
- logg.info("init store for read")
- self.store = LedgerStore(self.valkey_store, ledger)
-
- logg.info("wallet ready, pubkey: %s...", self._wallet.pubkey().hex()[:16])
+ return self.store, self.ledger, self.wallet
- ledger.set_wallet(self._wallet)
- ledger.acl = ACL.from_wallet(self._wallet)
- self.store.load(acl=ledger.acl)
- return self.store, ledger, self._wallet
def save(self, domain_entry: LedgerEntry) -> None:
"""
@@ -144,14 +115,6 @@ class LedgerRepository:
logg.debug(f"Failed to save entry: {e}", exc_info=True)
raise
- def save_wallet(self, wallet, passphrase):
- store, _, _ = self._init_store()
- try:
- store.get_key(DemoWallet, passphrase=passphrase)
- logg.info("key already exists in store, skipping")
- except FileNotFoundError:
- logg.info("key written to store")
- store.add_key(wallet, passphrase=passphrase)
def get_all_entries(self) -> List[LedgerEntry]:
"""Get all entries"""