The matured dev-env backport removed dev.sh (which provided `dev up/down/logs/shell`) but the seeded CLAUDE.md files still told users — and Claude sessions, since these symlink into ~/dev/ — to run those commands. `dev` is now just a nav function (cd $DEV_ROOT), so `dev up` silently cd'd and started nothing. Rewrite both Quick-commands / Default-dev-workflow sections to the real command set (lb/prb/dev-status/regtest-start/dev-deploy) and document that FakeWallet startup is manual — there is no `dev up` wrapper.
3.7 KiB
~/dev/lnbits — LNbits dev orientation
Per-project CLAUDE.md for the LNbits worktree subtree. Workspace-level
orientation is at ~/dev/CLAUDE.md (when wired). Full reference
material lives in your lnbits-sensei checkout under docs/.
This file is a symlink to
files/lnbits-CLAUDE.mdin your lnbits-sensei checkout. Edits should happen there.
Critical gotchas (read first)
Settings: .env seeds the DB on first boot, then DB wins
After first boot, editing .env and restarting changes nothing
for editable fields. Only ReadOnlySettings (host, port,
lnbits_path, lnbits_data_folder, lnbits_extensions_path,
lnbits_database_url, auth_secret_key, first_install_token,
lnbits_title, lnbits_admin_ui, lnbits_allowed_funding_sources)
re-read env every boot.
Editable settings (site title, fees, watchdog, funding-source credentials, the whole Admin UI form) change only via:
PUT /api/v1/settings(Admin UI), or- Clearing the relevant rows in the
system_settingstable.
Deploy-side: declarative env vars are a seed for editable fields, not authoritative. Plan accordingly.
Full reference: docs/lnbits-workspace-notes.md → "Settings precedence".
Frontend templates: NO self-closing tags
LNbits pages load Vue 3 + Quasar 2 as UMD globals. The browser's HTML parser doesn't honor self-close on non-void elements — the close tag gets implied at the wrong place and subsequent siblings end up inside the prior component.
<q-input v-model="foo" label="Foo"></q-input> <!-- ✓ correct -->
<q-input v-model="foo" label="Foo" /> <!-- ✗ silently broken -->
Applies to lnbits/templates/*.html, every extension's templates/,
every fork. Fine in .vue SFCs (the build step rewrites them) — if
you copy a snippet from a Vue SFC repo into an LNbits template,
expand all self-closing tags before saving.
Auth decorators
Easy to confuse. Different scopes:
| Decorator | Auth scope |
|---|---|
require_invoice_key |
Wallet invoice key — read access |
require_admin_key |
Wallet admin key — write to own wallet only |
check_admin |
LNbits instance admin (super_user / admin users) |
check_super_user |
LNbits super user only |
require_admin_key ≠ check_admin. Use check_admin for
cross-user / admin-only endpoints.
Upstream PRs target dev, not main
PRs to github.com/lnbits/lnbits go to dev. main only moves on
release merges. Use lowercase conventional-commit titles
(feat:, fix:, chore:, chore(deps):, docs:, ci:).
Full reference: docs/lnbits-upstream-flow.md.
Default dev workflow
There is no dev up wrapper. Start lnbits directly from a worktree:
lb dev # cd ~/dev/lnbits/dev
LNBITS_BACKEND_WALLET_CLASS=FakeWallet <lnbits run command> # instant, no docker
For real channels/payments, use the regtest stack (gated on
devEnv.regtest.enable; needs docker):
regtest-start dev # build lnbits from ~/dev/lnbits/dev, bring the stack up
regtest-stop
Use FakeWallet for extension CRUD / UI / API work. Spin up regtest only when actual channel/payment behavior is under test.
Key paths
~/dev/lnbits/main/— worktree onmain(your fork's day-to-day)~/dev/lnbits/dev/— worktree ondev(integration / staging)~/dev/upstream-prs/lnbits-<topic>/— PR worktrees branched fromupstream/main~/dev/repos/lnbits.git— the bare repo all the above point at
When in doubt
The canonical reference for any of the above lives in your
lnbits-sensei checkout's docs/. Trust the docs over this file when
they diverge — this CLAUDE.md is a quick-reference; the docs are the
source of truth.