diff --git a/frontend/public/vite.svg b/frontend/public/vite.svg
deleted file mode 100644
index e7b8dfb..0000000
--- a/frontend/public/vite.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/frontend/src/assets/react.svg b/frontend/src/assets/react.svg
deleted file mode 100644
index 6c87de9..0000000
--- a/frontend/src/assets/react.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/frontend/src/components/DecryptWallet.jsx b/frontend/src/components/DecryptWallet.jsx
deleted file mode 100644
index e1d402c..0000000
--- a/frontend/src/components/DecryptWallet.jsx
+++ /dev/null
@@ -1,163 +0,0 @@
-import { useState, useRef } from 'react'
-import CopyButton from './CopyButton'
-
-export default function DecryptWallet() {
- const [password, setPassword] = useState('')
- const [wallet, setWallet] = useState(null)
- const [result, setResult] = useState(null)
- const [loading, setLoading] = useState(false)
- const [error, setError] = useState(null)
- const [fileName, setFileName] = useState(null)
- const [seedVisible, setSeedVisible] = useState(false)
- const fileRef = useRef()
-
- const onFile = (e) => {
- const file = e.target.files[0]
- if (!file) return
- setFileName(file.name)
- setResult(null)
- setError(null)
- const reader = new FileReader()
- reader.onload = (ev) => {
- try {
- setWallet(JSON.parse(ev.target.result))
- } catch {
- setError('Invalid JSON file.')
- setWallet(null)
- }
- }
- reader.readAsText(file)
- }
-
- const decrypt = async () => {
- if (!wallet) return
- setLoading(true)
- setError(null)
- setResult(null)
- try {
- setResult(await window.electronAPI.hdDecrypt({ wallet, password }))
- setSeedVisible(false)
- } catch (e) {
- setError(e.message)
- } finally {
- setLoading(false)
- }
- }
-
- const ks = result?.keystore
-
- return (
-
-
Decrypt Wallet
-
Load an encrypted JSON wallet and reveal its private data
-
-
-
Load wallet file
-
-
-
- {fileName && {fileName}}
-
-
-
- {wallet && (
-
- Wallet loaded · encrypted: {wallet.use_encryption ? 'yes' : 'no'}
-
- )}
-
-
-
- setPassword(e.target.value)}
- onKeyDown={e => e.key === 'Enter' && wallet && decrypt()}
- />
-
-
-
-
-
- {error &&
{error}
}
-
- {result && ks && (
- <>
-
-
-
Seed Phrase
-
-
-
-
-
-
- {ks.seed.split(' ').map((w, i) => (
-
- {i + 1}.{w}
-
- ))}
-
-
-
-
-
Keystore
- {[
- ['Derivation', ks.derivation],
- ['Root fingerprint', ks.root_fingerprint],
- ['xpub', ks.xpub],
- ['xprv', ks.xprv],
- ].map(([label, value]) => (
-
- {label}
- {value}
-
-
- ))}
-
-
-
-
Receiving Addresses
-
-
-
- | # |
- Path |
- Address |
- WIF |
- |
-
-
-
- {result.addresses.receiving.map(a => (
-
- | {a.index} |
- {a.path} |
- {a.address} |
-
- {a.private_key_wif}
- |
-
-
-
-
-
- |
-
- ))}
-
-
-
- >
- )}
-
- )
-}
diff --git a/package.json b/package.json
index ac0d063..9b5bc67 100644
--- a/package.json
+++ b/package.json
@@ -1,10 +1,7 @@
{
- "name": "bitcoin-address-generator",
+ "name": "address-gen",
"private": true,
"scripts": {
"dev": "cd frontend && npm run dev"
- },
- "devDependencies": {
- "concurrently": "^9.2.1"
}
}
diff --git a/src/api.py b/src/api.py
deleted file mode 100644
index 8a59ed6..0000000
--- a/src/api.py
+++ /dev/null
@@ -1,160 +0,0 @@
-"""
-FastAPI backend for the Bitcoin Address Generator.
-Exposes all address generation functions as HTTP endpoints.
-"""
-
-from fastapi import FastAPI, HTTPException
-from fastapi.middleware.cors import CORSMiddleware
-from pydantic import BaseModel
-from typing import Any, Dict, Optional
-
-try:
- from src.hd_wallet import generate_hd_wallet, encrypt_wallet, decrypt_wallet
- from src.p2pk import generate_p2pk
- from src.p2pkh import generate_legacy_address
- from src.p2sh import generate_p2sh_multisig
- from src.p2wpkh import generate_segwit_address
- from src.p2tr import generate_p2tr_address
-except ImportError:
- from hd_wallet import generate_hd_wallet, encrypt_wallet, decrypt_wallet
- from p2pk import generate_p2pk
- from p2pkh import generate_legacy_address
- from p2sh import generate_p2sh_multisig
- from p2wpkh import generate_segwit_address
- from p2tr import generate_p2tr_address
-
-app = FastAPI(title="Bitcoin Address Generator API")
-
-app.add_middleware(
- CORSMiddleware,
- allow_origins=["http://localhost:5173", "http://localhost:4173", "file://", "*"],
- allow_methods=["*"],
- allow_headers=["*"],
-)
-
-
-# ── HD Wallet ──────────────────────────────────────────────────────────────────
-
-class HDGenerateRequest(BaseModel):
- network: str = "mainnet"
- bip_type: str = "bip84"
- mnemonic: Optional[str] = None
- passphrase: str = ""
- account: int = 0
- num_addresses: int = 5
-
-
-class HDEncryptRequest(BaseModel):
- wallet: Dict[str, Any]
- password: str
-
-
-class HDDecryptRequest(BaseModel):
- wallet: Dict[str, Any]
- password: str
-
-
-@app.post("/api/hd/generate")
-def hd_generate(req: HDGenerateRequest):
- try:
- return generate_hd_wallet(
- network=req.network,
- bip_type=req.bip_type,
- mnemonic=req.mnemonic or None,
- passphrase=req.passphrase,
- account=req.account,
- num_addresses=req.num_addresses,
- )
- except ValueError as e:
- raise HTTPException(status_code=400, detail=str(e))
-
-
-@app.post("/api/hd/encrypt")
-def hd_encrypt(req: HDEncryptRequest):
- try:
- return encrypt_wallet(req.wallet, req.password)
- except Exception as e:
- raise HTTPException(status_code=400, detail=str(e))
-
-
-@app.post("/api/hd/decrypt")
-def hd_decrypt(req: HDDecryptRequest):
- try:
- return decrypt_wallet(req.wallet, req.password)
- except ValueError as e:
- raise HTTPException(status_code=400, detail=str(e))
-
-
-# ── Single address types ───────────────────────────────────────────────────────
-
-class P2PKRequest(BaseModel):
- network: str = "mainnet"
- compressed: bool = False
-
-
-class P2PKHRequest(BaseModel):
- network: str = "mainnet"
- compressed: bool = True
-
-
-class P2SHRequest(BaseModel):
- network: str = "mainnet"
- m: int = 2
- n: int = 3
- compressed: bool = True
-
-
-class P2WPKHRequest(BaseModel):
- network: str = "mainnet"
- compressed: bool = True
-
-
-class P2TRRequest(BaseModel):
- network: str = "mainnet"
-
-
-@app.post("/api/p2pk")
-def p2pk(req: P2PKRequest):
- try:
- return generate_p2pk(network=req.network, compressed=req.compressed)
- except ValueError as e:
- raise HTTPException(status_code=400, detail=str(e))
-
-
-@app.post("/api/p2pkh")
-def p2pkh(req: P2PKHRequest):
- try:
- return generate_legacy_address(network=req.network, compressed=req.compressed)
- except ValueError as e:
- raise HTTPException(status_code=400, detail=str(e))
-
-
-@app.post("/api/p2sh")
-def p2sh(req: P2SHRequest):
- try:
- return generate_p2sh_multisig(
- network=req.network, m=req.m, n=req.n, compressed=req.compressed
- )
- except ValueError as e:
- raise HTTPException(status_code=400, detail=str(e))
-
-
-@app.post("/api/p2wpkh")
-def p2wpkh(req: P2WPKHRequest):
- try:
- return generate_segwit_address(network=req.network, compressed=req.compressed)
- except ValueError as e:
- raise HTTPException(status_code=400, detail=str(e))
-
-
-@app.post("/api/p2tr")
-def p2tr(req: P2TRRequest):
- try:
- return generate_p2tr_address(network=req.network)
- except ValueError as e:
- raise HTTPException(status_code=400, detail=str(e))
-
-
-@app.get("/api/health")
-def health():
- return {"status": "ok"}