User preference: stick with Knots rather than Core. The RPC protocol is
identical so PyBLOCK's behavior is unchanged, but the bundled binary now
matches the Knots flavor Umbrel ships in `umbrel-bitcoin`.
- dockerfile: download bitcoin-cli from
bitcoinknots.org/files/28.x/28.1.knots20250305/ instead of bitcoincore.org.
SHA256SUMS verification preserved.
- umbrel/umbrel-app.yml: clarify release notes mention Knots specifically.
Verified locally: bitcoin-cli.bin --version now reports
"Bitcoin Knots RPC client version v28.1.knots20250305".
Co-Authored-By: kulvex code <noreply@github.com>
PyBLOCK's mode A (Bitcoin + Lightning) and mode B (Bitcoin only) call
bitcoin-cli and lncli directly via subprocess. The Umbrel image did not
ship those binaries, so the startup validation in PyBlock.py:1898-1909
detected the empty CLI paths and silently redirected to Lite Mode against
public APIs — defeating the point of installing PyBLOCK on a node.
Per nmfretz's review on getumbrel/umbrel-apps#5258, this takes the
"bundle the binaries inside the PyBLOCK image" path (option 2):
- dockerfile: download bitcoin-cli (Bitcoin Core 28.1) and lncli (LND
v0.20.1-beta, matching what Umbrel ships) for both linux/amd64 and
linux/arm64. Verifies the Bitcoin Core SHA256SUMS. Real binaries land
at /usr/local/bin/{bitcoin-cli,lncli}.bin.
- umbrel/{bitcoin-cli,lncli}-wrapper.sh: thin shell wrappers installed
as /usr/local/bin/{bitcoin-cli,lncli} that exec the real binary with
-rpcconnect/-rpcuser/-rpcpassword (or --rpcserver/--tlscertpath/
--macaroonpath for lncli) injected from the BITCOIN_RPC_* / LND_*
env vars Umbrel provides via APP_BITCOIN_* / APP_LIGHTNING_*. They
fail loud if those env vars are missing.
- entrypoint.sh: default BITCOIN_CLI_PATH/LND_CLI_PATH to the wrapper
locations when the relevant RPC host env vars are set and the wrapper
is executable, so bclock.conf / blndconnect.conf get the right
bitcoincli / ln paths automatically.
- umbrel/: bump image tag and app version to v4.0.2 with release notes.
Local smoke test on amd64:
bitcoin-cli.bin --version -> Bitcoin Core RPC client version v28.1.0
lncli.bin --version -> lncli version 0.20.1-beta
/usr/local/bin/bitcoin-cli (no env) -> fails with "BITCOIN_RPC_HOST must be set"
/usr/local/bin/bitcoin-cli (env set) -> dispatches to the real binary
Image grows ~70MB (mostly the Go-built lncli).
Co-Authored-By: kulvex code <noreply@github.com>
Port v2.2 analysis features from upstream oraculovision into PyBLOCK's
Rich terminal UI:
- Add Transaction & Address Inspector (menu D) with flow, fees, BIP-110
flags, spam signals, UTXO balance, and mempool exposure
- Refactor bip110.py to pluggable detector architecture with flagged_raw
cache for pruned-node drill-down from Block Detail View
- Extend bitcoin-cli wrapper with getrawtransaction, scantxoutset, etc.
- Add unit tests and PR_ORACLEVISION_V2.2.md documentation
- Renumber Launch Full TUI to menu option E
Upstream: https://github.com/MarcanoFilms/oraculovision v2.2.0a1
- Fix detect_token_patterns to scan decoded ASCII instead of hex strings
- Handle malformed oraclevision.conf without crashing the menu
- Add security.py to validate executables, paths, and RPC method names
- Resolve subprocess targets before launch with nosemgrep audit notes
Integrate lightweight sovereign analysis tools from OracleVision into PyBLOCK's
Bitcoin menu. Adds modular BIP-110 violation scanning, Mempool Glass composition
via getblocktemplate, block detail view, and optional launch of the full
OracleVision TUI. Detection logic is separated from UI for community extension.
The previous range `>=1.0,<2.0` did not exist on PyPI — the only
published version is 0.1.4. This broke `pip install -r requirements.txt`
during Docker image builds. Verified that 0.1.4 exposes the import path
used by `pybitblock/SPV/PyVanityGenerator.py`
(`from vanity_address.vanity_address import VanityAddressGenerator`).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Umbrel forces `user: "1000:1000"` in docker-compose, but the previous
Dockerfile let useradd assign the next-free UID. Since ubuntu:24.04 ships
a pre-existing `ubuntu` user at 1000, `pyblock` ended up as 1001, causing
permission errors on the bind-mounted config dir reported in
getumbrel/umbrel-apps#5258.
- dockerfile: remove the default `ubuntu` user and pin pyblock to UID/GID
1000 so file ownership matches the user Umbrel runs as.
- entrypoint.sh: fail fast with a clear, actionable message when the
config dir is not writable (covers future UID-mismatch regressions).
- umbrel/: bump image tag and app version to v4.0.1 with release notes.
Verified with `docker run --user 1000:1000` and an empty bind-mount:
all 5 config files generated successfully, ttyd serves on :6969.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Replace all shell=True subprocess calls with Python-native processing
(nodeconnection.py, SPV/nodeconnection.py, SPV/ppi.py)
- Mask sensitive inputs (private keys, passwords, tokens) with getpass
- Add threading.Lock to block_explorer.py shared state
- Use json.loads() instead of fragile string splitting in apisnd.py
- Add path validation before file open in apisnd.py
- Replace random.randint with secrets.randbelow for mining nonces
- Fix destructive exception handlers in clone.py and feed.py
- Replace bare except clauses with specific exceptions + logging
- Remove unused imports (psutil, xmltodict, block_visualizer, base64, say)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace all dynamic .split() patterns in subprocess calls with safe
alternatives: shlex.split(), explicit list args, and _run_btc/_run_ln
helpers in PyBlock.py. Covers PyBlock, block_visualizer, clockscript,
lastblockdetail, mempoolclock, nodeconnection, and ai/context.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. Shell injection in readHexBlock/readHexTx (PyBlock.py):
- Validate user input with hex-only regex before use
- Replace shell=True pipe chain with subprocess list + piped stdin
- Same fix for OP_RETURN loop TX decoding
2. Shell injection in weather commands (ppi.py):
- Replace curl shell commands with requests.get()
- User input (city, lang, unit) no longer touches shell
- Upgraded from HTTP to HTTPS
3. Runtime crash in SPV/spvblock.py:
- os.path.isfile() called with 2 args (TypeError)
- Fixed to use 'and' for two separate checks
4. Config files added to .gitignore:
- pybitblock/config/*.conf (RPC creds, API keys, tokens)
- pybitblock/SPV/config/*.conf
- *.log files
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Centralize bitcoin-cli subprocess calls into a single _run_cli()
function with nosemgrep annotation. The cli path is already
sanitized via shlex.split() before reaching this function.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add cyan separator lines (────) before and after AI responses
- Change prompt to 'pyblock>' in yellow to distinguish from AI text
- Balance shown below the closing separator in dim
- Add UTF-8 env vars to entrypoint.sh for ttyd/Docker contexts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rich Console renders to a StringIO buffer, then the result is
encoded as UTF-8 bytes and written directly to sys.stdout.buffer,
bypassing Python's stdout encoding which may not be UTF-8 in all
launch contexts (ttyd, Docker, pipes).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reconfigure sys.stdout to UTF-8 when the ai module loads, ensuring
accented characters (á, é, ñ, ¡, ¿) render correctly regardless
of how PyBLOCK was launched.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Force Rich Console to use UTF-8 output encoding so Spanish
accented characters render correctly in the terminal.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use shlex.split() to safely parse bitcoincli path before passing
to subprocess.run(), same pattern as clock/data.py fix.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The status line after 'U' (usage) showed the old balance instead
of refreshing it from the API. Now calls get_balance() before
displaying the status line.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Major UX improvements inspired by KCode's terminal rendering:
- Continuous chat flow — no screen clearing between messages,
conversation scrolls naturally like a real chat
- Rich Markdown rendering for AI responses — proper tables,
code blocks with syntax highlighting, headers, bold, bullets
- Remove "Press Enter to continue" interruption from chat loop
- Compact status line showing balance + commands inline
- Ctrl+C returns to main menu cleanly
- Balance updates shown inline after each response
- Context refreshed on each query for up-to-date node data
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Client tries the public URL first (api.astrolexis.space), and
falls back to localhost:10400 on 404 or connection errors. This
handles CDN cache issues and provides resilience when the gateway
runs on the same machine as PyBLOCK.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
A function with yield is always a generator in Python, so
chat() with stream=False was returning a generator instead
of a dict. Split into chat() for non-streaming (returns dict)
and _stream_chat() for streaming (yields SSE chunks).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Document the Stripe checkout flow for token generation:
astrolexis.space/pyblock → Stripe → webhook → token on success page.
Remove token generation from open questions (now resolved).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New pybitblock/ai/ package integrating with Astrolexis AI Gateway
at https://api.astrolexis.space:
- client.py: API client for auth, top-up (Lightning), chat (SSE
streaming), and usage tracking
- context.py: Gathers Bitcoin/Lightning node data (via CLI, RPC,
or mempool.space API) for AI context injection
- ui.py: Terminal chat interface with conversation history,
Lightning top-up flow with QR codes, usage stats display,
and first-time token setup
Accessible from Main Menu as "I - AI Assistant". All queries go
through Astrolexis gateway — user pays in sats via Lightning.
Token stored in pyblocksettings.conf.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove 1000-sat Lightning invoice paywalls from LNBits, LNPay, and
OpenNode API integrations. All three now go directly to config setup
(same flow as TippinMe/TallyCoin which were already free).
Changes:
- Replace aaccPPiLNBits/LNPay/OpenNode() payment loops with direct
config-or-setup logic in both PyBlock.py and SPV/spvblock.py
- Change all menu labels from PAID/PREMIUM/LOCKED to FREE
- Remove LNURL file existence checks (lnbitSN.conf gates)
- Remove ~400 lines of payment invoice generation, QR display,
and payment polling code
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>