commit 539466ec5d68693475cad50967dc6f1197c0f4fb
parent f9ebd99a7bebae320546762c2a9f42616ea6c6fd
Author: Carlosokumu <carlosokumu254@gmail.com>
Date: Fri, 13 Mar 2026 19:55:25 +0300
add wallet setup logic
Diffstat:
2 files changed, 135 insertions(+), 0 deletions(-)
diff --git a/dummy/usawa/core/setup_wallet.py b/dummy/usawa/core/setup_wallet.py
@@ -0,0 +1,116 @@
+import getpass
+import logging
+import os
+import subprocess
+from nacl.signing import SigningKey
+
+
+logg = logging.getLogger("core.setup_wallet")
+
+GNUPG_DIR = "gnupg"
+PRIVATEKEY_FILE = "privatekey.asc"
+PUBLICKEY_FILE = "publickey.bin"
+
+
+def _generate_gpg_key(gpg_dir, name, email, passphrase=None):
+ env = {**os.environ, "GNUPGHOME": gpg_dir}
+
+ subprocess.run(
+ ["gpg-agent", "--homedir", gpg_dir, "--daemon"],
+ capture_output=True,
+ env=env,
+ )
+
+ batch_input = "\n".join(
+ [
+ "Key-Type: EdDSA",
+ "Key-Curve: ed25519",
+ "Subkey-Type: ECDH",
+ "Subkey-Curve: cv25519",
+ f"Name-Real: {name}",
+ f"Name-Email: {email}",
+ f"Passphrase: {passphrase}" if passphrase else "%no-protection",
+ "%commit",
+ "",
+ ]
+ )
+
+ result = subprocess.run(
+ ["gpg", "--homedir", gpg_dir, "--batch", "--gen-key"],
+ input=batch_input.encode(),
+ capture_output=True,
+ env=env,
+ )
+ if result.returncode != 0:
+ logg.error("key generation failed: %s", result.stderr.decode())
+ return None
+
+ list_result = subprocess.run(
+ ["gpg", "--homedir", gpg_dir, "--with-colons", "--fingerprint", email],
+ capture_output=True,
+ env=env,
+ )
+ for line in list_result.stdout.decode().splitlines():
+ if line.startswith("fpr"):
+ return line.split(":")[9]
+ return None
+
+
+def setup_wallet():
+ # Step 1 - Create gnupg dir
+ gpg_dir = os.path.abspath(GNUPG_DIR)
+ os.makedirs(gpg_dir, mode=0o700, exist_ok=True)
+ logg.debug("gpg directory: %s", gpg_dir)
+
+ env = {**os.environ, "GNUPGHOME": gpg_dir}
+
+ # Step 2 - Prompt user
+ name = input("Enter your name: ")
+ email = input("Enter your email: ")
+ passphrase = getpass.getpass("Enter wallet passphrase: ")
+
+ # Step 3 - Generate keypair via subprocess
+ fingerprint = _generate_gpg_key(gpg_dir, name, email, passphrase)
+ if not fingerprint:
+ logg.error("key generation failed")
+ return 1
+ logg.info("generated key fingerprint: %s", fingerprint)
+
+ # Step 4 - Generate privatekey.asc (32 random bytes encrypted to GPG key)
+ random_bytes = os.urandom(32)
+ result = subprocess.run(
+ [
+ "gpg",
+ "--homedir",
+ gpg_dir,
+ "--armor",
+ "--encrypt",
+ "--trust-model",
+ "always",
+ "-r",
+ fingerprint,
+ ],
+ input=random_bytes,
+ capture_output=True,
+ env=env,
+ )
+ if result.returncode != 0:
+ logg.error("encryption failed: %s", result.stderr.decode())
+ return 1
+ with open(PRIVATEKEY_FILE, "wb") as f:
+ f.write(result.stdout)
+ logg.info("private key material saved to: %s", PRIVATEKEY_FILE)
+
+ # Step 5 - Derive public key
+ sk = SigningKey(random_bytes)
+ pk = sk.verify_key
+ with open(PUBLICKEY_FILE, "wb") as f:
+ f.write(pk.encode())
+ logg.info("public key saved to: %s", PUBLICKEY_FILE)
+
+ # Step 6 - Config summary
+ logg.info("setup complete. add the following to your config:")
+ logg.info(" gpg_dir = %s", gpg_dir)
+ logg.info("public key (hex): %s", pk.encode().hex())
+
+ return 0
diff --git a/dummy/usawa/core/usawa_wallet.py b/dummy/usawa/core/usawa_wallet.py
@@ -0,0 +1,19 @@
+import gnupg
+import logging
+
+from usawa.crypto import DemoWallet
+
+
+logg = logging.getLogger("usawawallet")
+
+
+class UsawaWallet(DemoWallet):
+
+ def __init__(self, keyfile, gpgdir="~/.gnupg", passphrase=None):
+ self.gpg = gnupg.GPG(gnupghome=gpgdir)
+ self.keyfile = keyfile
+ f = open(self.keyfile, "rb")
+ pk = self.gpg.decrypt_file(f, passphrase=passphrase)
+ f.close()
+ logg.debug("decrypted pk with key {}".format(pk.key_id))
+ super(UsawaWallet, self).__init__(privatekey=pk.data)