diff --git a/docs/feature-ideas.md b/docs/feature-ideas.md new file mode 100644 index 0000000..797ecae --- /dev/null +++ b/docs/feature-ideas.md @@ -0,0 +1,112 @@ +# AccBot — Nápady na nové funkce + +Přehled potenciálních vylepšení na základě kompletní analýzy celého codebase (iOS, Android, .NET backend, Docker, Avalonia wizard). + +--- + +## Quick Wins (malý effort, okamžitá hodnota) + +### 1. Streak counter — série úspěšných nákupů +Zobrazit na Dashboardu počet po sobě jdoucích úspěšných DCA exekucí ("Jsi na 47denní sérii!"). Milestone badges za 7, 30, 100, 365, 1000 dní. + +**Proč:** DCA je o dlouhodobé disciplíně. Vizuální série motivují ke konzistenci — stejná psychologie jako Duolingo streaky nebo GitHub contribution graph. Udržuje uživatele v aplikaci. + +### 2. Sats-per-dollar indikátor +Ukázat, kolik satoshi (nebo crypto jednotek) uživatel dostane za 1 $/1 EUR dnes vs. jeho historický průměr. "Dnes: 1 823 sats/€ — o 12 % více než tvůj průměr!" + +**Proč:** Dělá abstraktní čísla hmatatelná. Posiluje pocit, že nakupovat při dip je výhodné. Jednoduchý výpočet z aktuální ceny vs. průměrná nákupní cena. + +### 3. Exchange API health indikátor +Zobrazit stav API burzy na Exchange Management — zelená/žlutá/červená. Logovat timestamp posledního úspěšného API callu. + +**Proč:** Když nákup selže, uživatel neví, jestli je problém v jeho credentials nebo na straně burzy. Proaktivní status šetří čas při debugování. + +### 4. Šablony plánů v onboardingu +Předpřipravené šablony: "Konzervativní BTC Spořič" (týdenní, classic), "Agresivní Dip Buyer" (denní, F&G strategie), "Multi-Coin Diverzifikátor" (více plánů). Setup na jedno kliknutí. + +**Proč:** Snižuje rozhodovací paralýzu u nových uživatelů. Zrychluje onboarding — uživatel nemusí rozumět všem parametrům hned. + +--- + +## Strategické funkce (střední effort, vysoký dopad) + +### 5. DCA vs. Lump Sum porovnání +"Co kdyby?" karta ukazující, jak DCA strategie performovala vs. investování stejné celkové částky najednou v den prvního nákupu. Zobrazit rozdíl v ROI %. + +**Proč:** Validuje uživatelův přístup k DCA během volatilních trhů. Edukační — pomáhá pochopit, kdy DCA vítězí a kdy ne. Potřebuje historickou cenu v den prvního nákupu + aktuální hodnotu portfolia. + +### 6. Projekce akumulace +Na základě aktuálního nastavení plánu (částka, frekvence) projektovat dopředu: "Při tomto tempu budeš mít X BTC za 1/5/10 let." Volitelně overlay cenových scénářů (medvědí/neutrální/býčí). + +**Proč:** Vizualizace cíle pohání motivaci. Uživatelé chtějí vidět konečný bod své strategie. Čistě matematický výpočet + jednoduchá UI karta. + +### 7. Bohatší týdenní/měsíční souhrn +Periodická souhrnná karta (nebo push notifikace) s: celkem investováno tento týden/měsíc, nakoupeno crypto, průměrná cena, nejlepší/nejhorší nákup, změna portfolia. + +**Proč:** Uživatelé chtějí periodické check-iny bez nutnosti otevírat appku denně. Typ `weeklySummary` notifikace už existuje jako toggle, ale samotná generace souhrnu by mohla být mnohem bohatší. + +### 8. Export pro daňové účely +Export transakcí ve formátech kompatibilních s daňovým software (CoinTracker CSV, Koinly CSV, generický FIFO/LIFO report). Zobrazit realizované/nerealizované zisky. + +**Proč:** Daňová compliance je hlavní bolest crypto uživatelů. Aktuální CSV export je generický — formáty specifické pro daňové nástroje přidávají reálnou hodnotu. V ČR relevantní s ohledem na 3leté daňové osvobození. + +### 9. Kontrola fiat zůstatku na burze +Kontrolovat fiat zůstatek na burze před exekucí. Pokud je nedostatečný, varovat uživatele předem ("Tvůj EUR zůstatek dojde za ~3 dny"). + +**Proč:** Funkce "low balance warning" už existuje, ale je založená na odhadech. Skutečná kontrola zůstatku přes API by byla přesnější a spolehlivější. + +### 10. Price alerty +Volitelné cenové alerty: "Upozorni mě, když BTC klesne pod X €" nebo "Alert, když BTC je >20 % pod ATH." Mohlo by triggerovat manuální "Buy Now" prompt. + +**Proč:** Doplňuje DCA o oportunistické nakupování. Uživatelé už ceny sledují — integrace přímo do appky šetří přepínání mezi apps. + +### 11. Návrhy na rebalancování +Pokud má uživatel více crypto plánů, zobrazit rozložení alokace (60 % BTC, 30 % ETH, 10 % SOL) a navrhnout rebalancování, pokud drift překročí práh. + +**Proč:** Multi-crypto DCA uživatelé potřebují povědomí o alokaci. Pasivní rebalancování je přirozené rozšíření DCA strategie. + +--- + +## Ambiciózní funkce (velký effort, diferenciující) + +### 12. Historická DCA simulace +Před vytvořením plánu simulovat: "Kdyby ses DCAčkoval za 100 €/týden do BTC poslední 2 roky, měl bys X BTC v hodnotě Y € (Z % ROI)." S reálnými historickými daty. + +**Proč:** Pomáhá novým uživatelům rozhodnout se o částkách a frekvencích. Silný onboarding nástroj. Potřebuje historická cenová data + simulační engine. + +### 13. Home screen widgety (iOS/Android) +Widgety na domovskou obrazovku: hodnota portfolia, odpočet do další exekuce, streak counter, dnešní sats-per-euro. + +**Proč:** Pasivní engagement bez otevírání appky. Vysoká hodnota pro denní DCA uživatele. Ale velký scope — platformově specifické implementace. + +### 14. Execution log / Debug konzole +Detailní log každého pokusu o DCA exekuci: timestamp, odpověď burzy, order ID, fill cena, poplatky, chyby. Zobrazitelný v Settings > Debug. + +**Proč:** Když něco nefunguje, uživatelé potřebují troubleshootovat. Aktuálně se chyby zobrazují na transakcích, ale celý execution flow není viditelný. + +### 15. Sdílení DCA journey +"Sdílej svou DCA cestu" — vygenerovat sdílitelnou kartu/obrázek se statistikami (celkem akumulováno, streak, ROI) bez odhalení absolutních částek. Privacy-first sdílení. + +**Proč:** Organický růst. Bitcoin komunita ráda sdílí svůj stacking progress. Anonymizované statistiky (jen %) zachovávají soukromí. + +--- + +## Shrnutí priorit + +| Priorita | Feature | Effort | Dopad | +|----------|---------|--------|-------| +| 1 | Streak counter | Malý | Vysoký | +| 2 | Sats-per-dollar | Malý | Střední | +| 3 | Exchange health | Malý | Střední | +| 4 | Šablony plánů | Malý | Vysoký | +| 5 | DCA vs Lump Sum | Střední | Vysoký | +| 6 | Projekce akumulace | Střední | Vysoký | +| 7 | Bohatší souhrny | Střední | Střední | +| 8 | Daňový export | Střední | Vysoký | +| 9 | Fiat balance check | Střední | Střední | +| 10 | Price alerty | Střední | Střední | +| 11 | Rebalancování | Střední | Střední | +| 12 | Historická simulace | Velký | Vysoký | +| 13 | Widgety | Velký | Vysoký | +| 14 | Debug konzole | Malý-Střední | Střední | +| 15 | Sdílení journey | Střední | Střední | diff --git a/docs/index.html b/docs/index.html index d07cb59..9e63e93 100644 --- a/docs/index.html +++ b/docs/index.html @@ -615,6 +615,41 @@

QR Code Setup

Point camera at QR code
Scanning will happen automatically
+ + +
+
+

Encrypted Backup

+

Back up your DCA plans, transaction history, and optionally API credentials with a single tap. Backups are encrypted with your password using AES-256-GCM. Restore on a new phone in seconds — no account needed, no data lost.

+
+
+
+
+ + accbot-backup-2026-03.enc +
+
+ AES-256-GCM + Password-encrypted +
+
+
+ + 3 DCA plans +
+
+ + 847 transactions +
+
+ + API credentials (optional) +
+
+
+
+
+ diff --git a/docs/locales/cs.json b/docs/locales/cs.json index 5a919fb..96764e9 100644 --- a/docs/locales/cs.json +++ b/docs/locales/cs.json @@ -46,6 +46,9 @@ "features_qr_title": "Nastavení přes QR kód", "features_qr_desc": "Skenujte API klíče a adresy peněženek fotoaparátem. Žádné ruční zadávání dlouhých alfanumerických řetězců.", + "features_backup_title": "Šifrovaná záloha", + "features_backup_desc": "Zálohujte DCA plány, historii transakcí a volitelně i API přihlašovací údaje jedním klepnutím. Zálohy jsou šifrovány vaším heslem pomocí AES-256-GCM. Obnovení na novém telefonu je otázka pár sekund — žádný účet, žádná ztráta dat.", + "exchanges_title": "Podporované burzy", "exchanges_subtitle": "Připojte se k libovolné ze 7 hlavních burz. Vytvořte více DCA plánů napříč různými burzami a obchodními páry.", diff --git a/docs/locales/en.json b/docs/locales/en.json index 9e4b496..7be234f 100644 --- a/docs/locales/en.json +++ b/docs/locales/en.json @@ -46,6 +46,9 @@ "features_qr_title": "QR Code Setup", "features_qr_desc": "Scan your API keys and wallet addresses with your camera. No more error-prone manual entry of long alphanumeric strings.", + "features_backup_title": "Encrypted Backup", + "features_backup_desc": "Back up your DCA plans, transaction history, and optionally API credentials with a single tap. Backups are encrypted with your password using AES-256-GCM. Restore on a new phone in seconds — no account needed, no data lost.", + "exchanges_title": "Supported Exchanges", "exchanges_subtitle": "Connect to any of 7 major exchanges. Create multiple DCA plans across different exchanges and trading pairs.", diff --git a/scripts/sideload-ipa.py b/scripts/sideload-ipa.py new file mode 100644 index 0000000..d1fd56e --- /dev/null +++ b/scripts/sideload-ipa.py @@ -0,0 +1,166 @@ +#!/usr/bin/env python3 +"""Install .ipa on iPad via Sideloader CLI using wexpect PTY emulation. + +Usage: + python scripts/sideload-ipa.py + # Triggers 2FA, then polls 2fa-code.txt for the code. + # Write "resend" to 2fa-code.txt to request SMS resend. +""" + +import os +import sys +import re +import time +import wexpect + +LOCALAPPDATA = os.environ["LOCALAPPDATA"] +SIDELOADER = os.path.join(LOCALAPPDATA, "Sideloader", "sideloader-cli-x86_64-windows-msvc.exe") +SCRIPT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +IPA = os.path.join(SCRIPT_DIR, "ipa-download", "AccBot-unsigned.ipa") +TFA_FILE = os.path.join(SCRIPT_DIR, "2fa-code.txt") + +os.environ["SIDELOADER_ANISETTE_URL"] = "http://localhost:6969" + +if len(sys.argv) < 3: + print(f"Usage: {sys.argv[0]} ") + sys.exit(1) + +apple_id = sys.argv[1] +password = sys.argv[2] + +if not os.path.isfile(SIDELOADER): + print(f"ERROR: Sideloader not found: {SIDELOADER}") + sys.exit(1) +if not os.path.isfile(IPA): + print(f"ERROR: IPA not found: {IPA}") + sys.exit(1) + +# Clean up old 2FA file +if os.path.exists(TFA_FILE): + os.remove(TFA_FILE) + +cmd = f'"{SIDELOADER}" install -i "{IPA}"' +print(f"Running Sideloader...") +sys.stdout.flush() + +child = wexpect.spawn(cmd, timeout=300) +all_output = "" + +def wait_and_log(patterns, timeout=60): + global all_output + idx = child.expect(patterns, timeout=timeout) + all_output += str(child.before or "") + return idx + +# Apple ID +idx = wait_and_log(["Apple ID:", wexpect.EOF, wexpect.TIMEOUT], timeout=30) +if idx == 0: + child.sendline(apple_id) + print("Sent Apple ID") + sys.stdout.flush() +else: + print(f"Failed at Apple ID prompt") + sys.exit(1) + +# Password +idx = wait_and_log(["password", "Password", wexpect.EOF, wexpect.TIMEOUT], timeout=30) +if idx in (0, 1): + child.sendline(password) + print("Sent password") + sys.stdout.flush() +else: + print(f"Failed at password prompt") + sys.exit(1) + +# Check if 2FA or direct success +idx = wait_and_log([ + "code", # 0 - 2FA + "DeveloperSession created successfully", # 1 - no 2FA + "correct password", # 2 + wexpect.EOF, # 3 + wexpect.TIMEOUT # 4 +], timeout=60) + +if idx == 0: + print("2FA_NEEDED") + sys.stdout.flush() + + # Poll for 2FA code file — support "resend" command + print(f"Waiting for 2FA code in {TFA_FILE} ...") + sys.stdout.flush() + deadline = time.time() + 180 # 3 min timeout + tfa_code = None + while time.time() < deadline: + if os.path.exists(TFA_FILE): + with open(TFA_FILE, "r") as f: + content = f.read().strip() + if content: + os.remove(TFA_FILE) + if content.lower() == "resend": + print("Sending 'resend' to Sideloader...") + sys.stdout.flush() + child.sendline("resend") + # Wait for re-send confirmation, then keep polling + time.sleep(3) + print("Resend requested. Waiting for new code...") + sys.stdout.flush() + continue + else: + tfa_code = content + break + time.sleep(1) + + if not tfa_code: + print("ERROR: 2FA code not provided within 3 minutes.") + sys.exit(2) + + print(f"Sending 2FA code...") + sys.stdout.flush() + child.sendline(tfa_code) + + # Wait for login success + idx2 = wait_and_log([ + "DeveloperSession created successfully", + "correct password", + "ERROR", + wexpect.EOF, + wexpect.TIMEOUT + ], timeout=60) + if idx2 != 0: + print(f"Login failed after 2FA.\n{all_output}") + sys.exit(1) + print("Login successful!") + sys.stdout.flush() +elif idx == 1: + print("Login successful (no 2FA)!") + sys.stdout.flush() +elif idx == 2: + print("ERROR: Wrong password!") + sys.exit(1) +else: + print(f"Login failed.\n{all_output}") + sys.exit(1) + +# Wait for install to complete +print("Installing (signing + uploading to device)...") +sys.stdout.flush() +try: + child.expect(wexpect.EOF, timeout=300) + all_output += str(child.before or "") +except (wexpect.TIMEOUT, wexpect.EOF): + all_output += str(child.before or "") + +# Print cleaned output +clean = re.sub(r'\x1b\[[0-9;]*m', '', all_output) +clean = re.sub(r'\x1b\[\?25[lh]', '', clean) +clean = re.sub(r'\x1b\[K', '', clean) +for line in clean.split('\n'): + line = line.strip() + if line: + print(f" {line}") + +if "error" in all_output.lower() and "installed" not in all_output.lower(): + print("\nInstallation failed.") + sys.exit(1) +else: + print("\nDone!")