Commit graph

2575 commits

Author SHA1 Message Date
GaltRanch
dcd9d44cde Restore Rich UI menus lost during clock integration
The clock commit (8e27372) inadvertently reverted Rich Columns menus
(Bitcoin submenu, Lightning, API menus) back to plain ANSI format.
Restored from commit 3062a34 and reapplied clock changes on top:
- artist()/design() delegation to clock.run_clock()
- mainmenuControl unified clock launch
- menuSelection()/menuSelectionLN() using cfg singleton
- Settings D option with clockDisplaySettings()
- TUI startup using cfg.intro_mode

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 09:23:09 -03:00
GaltRanch
92959c67c9 Fix security and concurrency issues in clock data layer
- Use shlex.split() instead of str.split() for bitcoin-cli commands
  to prevent command injection via crafted config values
- Remove partial threading.Lock usage that only guarded writes but
  not reads, relying on Python's GIL for atomic attribute assignment
- Remove unused threading import (Lock)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 09:17:26 -03:00
GaltRanch
0e14cec037 Fix generative art centering to use actual terminal width
The hash_art() function was hardcoding pad based on 80 columns.
Now accepts term_width parameter and the renderer passes the
real terminal width for proper centering.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 09:10:53 -03:00
GaltRanch
4488bd7aac Add 5 visual features to block clock: miner pool, weight, histogram, peers, moon
- Miner pool tag: shows who mined the last block (coinbase decode for local/remote, API for lite)
- Block weight meter: colored fullness bar (green/yellow/red)
- Block time histogram: sparkline of last 14 block intervals with color-coded speed + streak detection
- Peer count: network connections indicator with health coloring
- Moon phase: current lunar phase emoji + name

All toggleable via Settings → D (Clock Display Settings).
Also fixes negative countdown timer (clamp to 0) and countdown row tracking bug.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 09:08:18 -03:00
GaltRanch
8e2737251d Add enhanced block clock with 12 new features for Menu A
New clock/ package replaces the old design() polling loop with a
flicker-free ANSI cursor-positioned renderer. Features include:
countdown timer, epoch/halving progress bar, fee rate indicator,
hashrate sparkline, matrix mining animation, odometer digit transition,
heartbeat pulse, zen mode, UTC time display, fireworks on milestone
blocks, generative hash art, and configurable sound modes.

All features are toggleable via Settings → D (Clock Display Settings).

Also fixes hardcoded config paths in menuSelection(), menuSelectionLN(),
and TUI startup to use the cfg singleton instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 08:35:59 -03:00
GaltRanch
1fa1846790 Add ARM64 build dependencies to Dockerfile for multi-arch support
Install python3-dev, libgmp-dev, libffi-dev needed to compile
psutil and fastecdsa on ARM64 (Raspberry Pi / Umbrel).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 17:31:41 -03:00
GaltRanch
c8c2629ad4 Fix PYBLOCK_MODE to always overwrite + exclude vanity-address from deps
- entrypoint.sh: PYBLOCK_MODE env var now always overwrites intro.conf
  (previously skipped if file existed from a previous run)
- requirements.txt: Comment out vanity-address (not available on all
  platforms, blocks Docker build)

Tested Docker build with simulated Umbrel env vars:
- Bitcoin RPC auto-config: OK
- LND auto-config: OK
- Mode detection: OK
- Health check (port 6969): HTTP 200
- Config file generation: verified inside container

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 16:57:41 -03:00
GaltRanch
d62adafc44 Fix LND ip_port in entrypoint.sh when LND_HOST is unset
When only LND_TLS_CERT_PATH was set (without LND_HOST), the entrypoint
produced ":10009" as ip_port, which is syntactically valid but unusable.
Now matches Python _env_lnd_config behavior: empty string when host is
missing, only builds host:port when LND_HOST is explicitly provided.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 16:48:53 -03:00
GaltRanch
c50a8797fc Add gallery screenshots for Umbrel App Store
4 screenshots showing PyBLOCK in action:
- 1.png: Main menu with Rich panels
- 2.png: Bitcoin submenu with categorized columns
- 3.png: Block visualizer treemap
- 4.png: TUI dashboard

Updated umbrel-app.yml gallery references to .png format.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 16:47:33 -03:00
GaltRanch
42a02ae933 Add PyBLOCK logo PNG to Umbrel app directory
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 16:44:44 -03:00
GaltRanch
b152c96038 Add Umbrel app icon and submission documentation
- icon.svg: 256x256 cyberpunk Bitcoin icon with animated cursor,
  grid lines, Bitcoin B symbol gradient, and PyBLOCK text
- README.md: Testing instructions, submission steps, env var reference,
  and multi-arch Docker build commands

Gallery screenshots (1.jpg, 2.jpg, 3.jpg) to be added after
capturing from a running instance.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 16:38:50 -03:00
GaltRanch
6fad893db8 Update Dockerfile for Umbrel + add multi-arch CI build
Dockerfile changes:
- Use COPY instead of git clone (build from local source)
- Add entrypoint.sh for auto-configuration from env vars
- EXPOSE 6969 and configurable via PYBLOCK_PORT env var
- Create config directory as volume mount point
- ENTRYPOINT replaces CMD for pre-launch setup

New .github/workflows/docker-build.yml:
- Multi-arch build: linux/amd64 + linux/arm64 (Raspberry Pi)
- Triggers on version tags (v*.*.*)
- Pushes to Docker Hub as curly60e/pyblock:version and :latest
- Uses QEMU + Buildx for cross-compilation
- GitHub Actions cache for faster builds

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 16:33:03 -03:00
GaltRanch
667d5b6ae0 Add Umbrel app manifest and docker-compose configuration
umbrel/docker-compose.yml:
- app_proxy service for Umbrel authentication
- Web service with ttyd on port 6969
- Volume mounts: persistent config + read-only LND data
- All Bitcoin RPC and LND env vars from Umbrel's injection
- Auto-mode set to A (Bitcoin + Lightning)

umbrel/umbrel-app.yml:
- App manifest with full description and feature list
- Category: bitcoin
- Dependencies: bitcoin, lightning
- Port: 6969

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 16:32:23 -03:00
GaltRanch
82dc30f706 Add entrypoint.sh for Umbrel/Docker auto-configuration
Shell script that runs before PyBLOCK to:
- Auto-generate bclock.conf from BITCOIN_RPC_* env vars
- Auto-generate blndconnect.conf from LND_* env vars
- Auto-detect mode (A/B/C) from available services
- Create default settings files if missing
- Launch ttyd with configurable port (PYBLOCK_PORT)
- Support optional ttyd auth (PYBLOCK_TTYD_AUTH)

Enables zero-config deployment: set env vars → configs generated → app starts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 16:31:34 -03:00
GaltRanch
7509df10e0 Add environment variable support to config.py for Umbrel/Docker
Config now reads these env vars (with priority over config files):

Bitcoin Core:
  BITCOIN_RPC_HOST, BITCOIN_RPC_PORT, BITCOIN_RPC_USER, BITCOIN_RPC_PASS
  BITCOIN_CLI_PATH

Lightning (LND):
  LND_HOST, LND_GRPC_PORT, LND_TLS_CERT_PATH, LND_MACAROON_PATH
  LND_CLI_PATH

Mode:
  PYBLOCK_MODE (A=Bitcoin+Lightning, B=Bitcoin, C=Lite)

When env vars are set, config files are auto-generated for consistency.
This enables zero-config deployment on Umbrel where credentials are
injected via docker-compose environment.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 16:30:47 -03:00
Satoshi Nakamoto
cb2f4bee16
Merge pull request #729 from GaltRanch/frontend/ux-improvements 2026-04-01 20:48:49 +02:00
GaltRanch
cb89d6fbcf Restore Panel boxes with transparent background (style='on default')
Bring back the Panel borders for sysinfo, status bar, header, and menu
but use style='on default' which inherits the terminal's background
color instead of Rich's default dark gray. border_style='dim' keeps
the borders subtle.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:29:47 -03:00
GaltRanch
db640ac8fc Replace Rich Tables with inline console.print for transparent backgrounds
Tables pad columns with spaces that show a different background color.
Switch sysinfo and menu to console.print() with markup strings instead,
which render with the terminal's native background color.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:28:30 -03:00
GaltRanch
2f60500162 Remove Rich Panel borders from status bar and header
Replace Panel() wrappers with plain text output for status_bar and
header — Panels create a visible background box that clashes with
dark terminal themes. Error/warning panels kept as-is since they
should visually stand out.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:26:29 -03:00
GaltRanch
b86fdcb1ce Fix Rich background colors to match terminal background
- Use transparent backgrounds instead of forced dark grays in panels
- Replace ░ block chars with ─ dashes for progress bar empty space
- Set console highlight=False to prevent unwanted auto-styling
- Remove pyblock.dim style from panels (used default dim instead)

Rich elements now blend seamlessly with the terminal's own background.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:24:28 -03:00
GaltRanch
6b57e9e0f0 Fix Ctrl+C to return to main menu instead of exiting
- artist(): catch KeyboardInterrupt explicitly so Ctrl+C breaks the
  block display loop and returns to caller
- main(): change KeyboardInterrupt handler from sys.exit(0) to
  continue, which loops back to menuSelection()

Users can now press Ctrl+C to exit any screen and return to the menu.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:22:50 -03:00
GaltRanch
4460be7b38 Always fallback to Lite Mode when node config is incomplete
When bitcoincli is empty, go straight to Lite Mode instead of trying
remote mode (which also fails without tls/macaroon). Also validate
remote mode has tls configured before attempting connection.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:18:46 -03:00
GaltRanch
da1f8efc64 Add missing codecs import to PyBlock.py
codecs is used in 10+ places for macaroon encoding but was previously
available only via star imports that were removed in the security audit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:17:58 -03:00
GaltRanch
86aff5bad2 Fix TUI widget lifecycle: use single Static view for content swapping
Replace mount/remove_children pattern (async issues, duplicate IDs)
with a single persistent #section-view Static widget that gets its
content updated via .update(). All sections now render correctly:

- Dashboard: summary table + latest blocks (fetched async from API)
- Bitcoin/Lightning/Platforms/Settings: info panels
- M key: return to main menu

Also added fetch_latest_blocks() and fetch_hashrate() data workers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:15:44 -03:00
GaltRanch
6eecc5750a Wire up TUI menu actions with live data panels
Each menu key now loads real content:
- A (Dashboard): block height, price, hashrate, difficulty, mempool
  stats, and latest 5 blocks table — all from mempool.space API
- B (Bitcoin): submenu with blockchain features
- L (Lightning): channel management overview
- P (Platforms): API integrations list
- S (Settings): current mode and config info
- M: return to main menu from any section

New data fetchers: fetch_latest_blocks(), fetch_hashrate(),
fetch_mempool_info() expanded.

Dashboard loads async via run_worker(thread=True) with live
content replacement in the center panel.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:12:36 -03:00
GaltRanch
8440b7b83b Fix TUI main menu: convert Screen to Widget for proper rendering
MainMenuScreen was a Textual Screen mounted inside a Vertical container,
which doesn't render. Create MainMenu as a Static widget instead:
- New tui/widgets/main_menu.py with Panel+Table menu
- Move keybindings (A/B/L/P/S/Q) to the App level
- Menu now renders correctly in the content area

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:09:32 -03:00
GaltRanch
d842f97de0 Handle both string and dict formats in intro.conf for --tui mode
intro.conf can contain either a plain string ("A"/"B"/"C") or a dict
with keys like fullbtclnd/fullbtc. Handle both formats when detecting
the mode for TUI launch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:07:29 -03:00
GaltRanch
296b59e786 Use lazy import for MainMenuCROPPED to avoid circular import
Move SPV.spvblock import inside the functions that call
MainMenuCROPPED() instead of top-level, preventing circular
dependency issues when SPV modules load before PyBlock globals.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:07:29 -03:00
GaltRanch
e1923ffcff Add missing MainMenuCROPPED import from SPV.spvblock
This function was previously available via the removed star import
'from SPV.spvblock import *'. Add explicit import so Lite Mode
fallback and mode C selection work correctly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:07:29 -03:00
GaltRanch
ffb2b9e72d Validate bitcoincli path before execution, fallback to Lite Mode
When bitcoincli is empty in bclock.conf, instead of crashing with
PermissionError, MainMenu now:
1. Falls back to RPC remote mode if ip_port/rpcuser are configured
2. Redirects to Lite Mode (MainMenuCROPPED) if nothing is configured

Also simplified the fatal error handler in main() to show the error
message visibly before exiting.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:07:29 -03:00
Satoshi Nakamoto
8c9f45e8ed
Merge pull request #728 from GaltRanch 2026-04-01 19:11:27 +02:00
GaltRanch
cc9a5e236e Handle empty bitcoincli path gracefully instead of crashing
When bclock.conf has an empty bitcoincli path, catch the PermissionError
and redirect to introINIT() with a helpful error message instead of
crashing with 'Fatal error: Permission denied'.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:47:26 -03:00
GaltRanch
88b1609100 Fix Rich sysinfo bar rendering raw markup tags
Use Text.from_markup() instead of Text() for the CPU/Memory progress
bars so Rich markup tags ([green], [dim]) are interpreted as styles
rather than displayed as literal text.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:46:35 -03:00
GaltRanch
92b461662c Fix Textual TUI async worker to use run_worker(thread=True)
Replace run_in_thread (not available in Textual 0.89) with
run_worker(fn, thread=True) + call_from_thread for UI updates.
The TUI now launches correctly and fetches live data (block height,
BTC price, fee estimates) on startup and every 30 seconds.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:44:02 -03:00
GaltRanch
b6540b059b Add Textual TUI dashboard (Level 3) with --tui launch flag
New pybitblock/tui/ package providing a modern terminal UI:

Structure:
  tui/app.py           - Main Textual App with CSS layout, auto-refresh
  tui/screens/         - Screen classes (main_menu.py with keybindings)
  tui/widgets/         - StatusBar widget with reactive block/price data
  tui/workers/         - Async data fetchers (block height, price, fees, mempool)

Features:
  - Persistent status bar with mode, block height, BTC price
  - Side panel showing live fee estimates (fast/medium/slow)
  - Keyboard navigation (A=PyBLOCK, B=Bitcoin, L=Lightning, etc.)
  - Auto-refresh every 30 seconds via async workers
  - Dark theme with Bitcoin-inspired color scheme
  - CSS-based responsive layout

Launch: python3 PyBlock.py --tui
Fallback: python3 PyBlock.py (original CLI mode)

Added textual>=0.89 to requirements.txt.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:35:04 -03:00
GaltRanch
3df92e3ef7 Upgrade show_error/warning/success to use Rich panels when available
Error messages now render as styled Rich panels with colored borders:
- Errors: red border panel with "Error" title
- Warnings: yellow border panel with "Warning" title
- Success: green checkmark prefix
Falls back to ANSI output if Rich is not importable.

This affects all 217+ error display points across both PyBlock.py and
SPV/spvblock.py automatically since they all call show_error().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:30:21 -03:00
GaltRanch
f30ba8ea04 Integrate Rich panels, headers, and menus in main menu screens
Replace ANSI escape code menus with Rich-styled components:
- PyBlock.py MainMenu(): Rich status bar, header panel with node info,
  table-based menu with colored keys
- SPV/spvblock.py MainMenuCROPPED(): same Rich integration
- Use rich_prompt() for styled input

The main menu now renders with bordered panels, consistent styling,
and proper terminal-width adaptation via Rich.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:29:40 -03:00
GaltRanch
40a931a25f Upgrade sysinfo() to Rich with color-coded CPU/Memory bars
Replace ANSI-coded system info with Rich table showing:
- CPU: color bar (green/yellow/red based on load) + percentage
- Memory: color bar + percentage
Falls back to original ANSI output if Rich is not available.

This change affects every screen in the app since sysinfo() is called
on most menu renders.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:28:02 -03:00
GaltRanch
db35505284 Add shared/rich_ui.py with Rich-based UI components
Level 2 foundation module providing styled alternatives to ANSI output:
- rich_status_bar(): Panel with mode/block/price using PyBLOCK theme
- rich_sysinfo(): CPU/Memory with color-coded progress bars
- rich_menu(): Table-based menu rendering with styled keys
- rich_header(): Node info panel with alias/block/version
- rich_error/warning/success(): Styled message panels
- rich_loading(): Rich Progress spinner for async operations
- rich_prompt(): Styled input prompt
- PYBLOCK_THEME: Custom Rich theme with bitcoin color scheme

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:27:25 -03:00
GaltRanch
d9b0862a1b Add invalid option feedback to main menu controllers
When users type an unrecognized option, they now see a yellow
"Invalid option 'X'. Try again." message instead of silent no-op.

Applied to:
- PyBlock.py mainmenuControl() and bitcoincoremenuLocalControl()
- SPV/spvblock.py mainmenuLOCALcontrol()

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:15:20 -03:00
GaltRanch
a2c31cd41a Add visible error messages to user instead of silent logging
Add show_error(str(e)) before every logger.debug() call so users see
a red error message when operations fail, instead of silent failures:
- PyBlock.py: 31 instances of "Suppressed error" pattern
- SPV/spvblock.py: 186 instances of "spvblock" error pattern

Users now see "! Error: <message>" in red text before being returned
to the menu, while errors still log to pyblock.log for debugging.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:13:16 -03:00
GaltRanch
458b60fbbc Add status bar with mode, block height, and BTC price to main menus
- PyBlock.py MainMenu(): fetch BTC price from mempool.space API,
  display status_bar() showing mode/block/price before menu header
- SPV/spvblock.py MainMenuCROPPED(): same status_bar integration
- Import shared.ui utilities in both files

The status bar shows at a glance: active mode (Local/Remote/Lite),
current block height, and USD price of Bitcoin.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:09:21 -03:00
GaltRanch
04c0e33efc Rename 'Cropped' mode to 'Lite Mode' in user-facing text
- PyBlock.py: Update intro screen text and option label
- SPV/spvblock.py: Change all n="CROPPED" display labels to "LITE MODE"
- Internal config value 'cropped' in intro.conf unchanged for backward compat

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:07:21 -03:00
GaltRanch
915da7a1d5 Add shared/ui.py with status bar, spinner, error display, and input validation
Foundation module for Level 1 frontend improvements:
- status_bar(): persistent header showing mode, block height, BTC price
- show_error/warning/success(): visible user-facing messages
- Spinner: context manager for loading animations on API calls
- prompt_menu(): input validation with back-button support
- ANSI color constants for consistent styling

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:06:17 -03:00
GaltRanch
42623cfc53 Convert download/install shell chains to list-based subprocess in SPV/spvblock.py
Replace 21 mkdir/cd/wget/tar/unzip/git-clone/chmod shell chains with
os.makedirs() + list-based subprocess.run(cwd=) calls:
- Nostr console 5 platform installers + seed/QR tools
- Mempool-cli x86/ARM installers
- CroppedMiner x86/ARM, Luxor, TinySeed
- Bija, bpytop, Cashu, ColdCore, Warden, Resurrection wallet
- Satellite and terminal_matrix git clones

Replace chmod 777 * with chmod +x on specific binaries.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 12:51:48 -03:00
GaltRanch
455cb986ce Convert download/install shell chains to list-based subprocess in PyBlock.py
Replace 27 mkdir/cd/wget/tar/unzip/git-clone/chmod shell chains with
os.makedirs() + list-based subprocess.run(cwd=) calls:
- Mempool-cli x86/ARM installers
- Phoenix wallet 4 platform installers
- Nostr console 5 platform installers + seed tools
- SatSale, Warden, Bija, Coldcore, Cashu, bpytop, Luxor, UTXOracle

4 remaining shell=True are legitimate pipe chains (bitcoincli|xxd, jq).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 12:51:41 -03:00
GaltRanch
757b38d3de Convert curl API calls to requests library in SPV/ppi.py
Replace 30 subprocess curl API calls with native Python requests:
- LNBits: invoice create/check/pay, paywall CRUD, LNURL withdraw (11)
- OpenNode: balance, charges, withdrawals, status RSS (7)
- TallyCoin: payment requests (2)
- LNPay: invoice status and decode (2)
- Simple GETs: PGP key, bwt banner, weather, rate.sx (5+)

9 remaining shell=True are pipe chains requiring shell processing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 12:32:55 -03:00
GaltRanch
cf69861dcf Convert LNBits, OpenNode, and TallyCoin curl calls to requests library
Replace 23 subprocess curl API calls with native Python requests:
- LNBits: create/check invoice, pay invoice, paywall CRUD, LNURL withdraw
- OpenNode: create charge, list funds, list payments, initiate withdrawal,
  check status (RSS), decode invoice
- TallyCoin: payment requests (2 functions)

Remaining shell=True in ppi.py are pipe chains (curl|grep|html2text)
that require shell for processing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 12:27:41 -03:00
GaltRanch
c0b40e91f7 Convert simple subprocess shell=True to list format with cwd
Replace cd-and-run shell patterns with list-based subprocess.run()
using cwd parameter for directory context:

- Phoenix macOS ARM installer
- Luxor CLI help
- Mempool CLI (2 instances)
- SatSale, Cashu, Warden, bpytop launchers
- Bija docker-compose
- Both SPV/spvblock.py and PyBlock.py

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 12:21:08 -03:00
GaltRanch
935cf809de Eliminate all user-input shell injection vectors in spvblock.py
Convert every remaining subprocess call that interpolates user input
(responseC/D/E, invoice, private keys) from shell=True f-strings to
safe list-based subprocess.run() with cwd parameter:

- Miners (CroppedMiner x86/ARM): user address, password, threads
- Foreman Pickaxe: apiKey and clientId
- LND decodepayreq: invoice string (2 instances)
- TinySeed: seed words
- Nostr console (5 platform variants): private key
- Nostr seed/QR seed: hex input

Zero user-input + shell=True patterns remain in the codebase.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 12:19:36 -03:00