Rename Castle Accounting extension to Libra

Full identifier rename: module path lnbits.extensions.castle →
lnbits.extensions.libra, DB ext_castle → ext_libra, URL prefix
/castle/ → /libra/, manifest id castle → libra, fava ledger slug
default castle-ledger → libra-ledger, Beancount source metadata
castle-api → libra-api and link prefixes castle-{entry,tx}- →
libra-{entry,tx}-, column castle_wallet_id → libra_wallet_id, all
Python/JS/HTML identifiers (castle_ext, CastleSettings,
castle_reference, castleWalletConfigured, etc.).

Display name "Castle Accounting" → "Libra" (the scales/balance
metaphor — fits double-entry bookkeeping).

No backward compat: production hosts will be force-updated. Old
castle-prefixed Beancount metadata in existing Fava ledgers is
historical; new entries use libra-* prefixes going forward.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Padreug 2026-05-05 10:24:46 +02:00
commit c174cda48d
44 changed files with 953 additions and 953 deletions

View file

@ -1,5 +1,5 @@
"""
Fava API client for Castle.
Fava API client for Libra.
This module provides an async HTTP client for interacting with Fava's JSON API.
All accounting logic is delegated to Fava/Beancount.
@ -46,7 +46,7 @@ class FavaClient:
Args:
fava_url: Base URL of Fava server (e.g., http://localhost:3333)
ledger_slug: URL-safe ledger identifier (e.g., castle-accounting)
ledger_slug: URL-safe ledger identifier (e.g., libra-accounting)
timeout: Request timeout in seconds
"""
self.fava_url = fava_url.rstrip('/')
@ -169,7 +169,7 @@ class FavaClient:
Args:
entry: Beancount entry dict (same format as add_entry)
idempotency_key: Unique key for this operation (e.g., "castle-{uuid}" or "ln-{payment_hash}")
idempotency_key: Unique key for this operation (e.g., "libra-{uuid}" or "ln-{payment_hash}")
Returns:
Response from Fava if entry was created, or existing entry data if already exists
@ -289,18 +289,18 @@ class FavaClient:
async def get_user_balance(self, user_id: str) -> Dict[str, Any]:
"""
Get user's balance from castle's perspective.
Get user's balance from libra's perspective.
Aggregates:
- Liabilities:Payable:User-{user_id} (negative = castle owes user)
- Assets:Receivable:User-{user_id} (positive = user owes castle)
- Liabilities:Payable:User-{user_id} (negative = libra owes user)
- Assets:Receivable:User-{user_id} (positive = user owes libra)
Args:
user_id: User ID
Returns:
{
"balance": int (sats, positive = user owes castle, negative = castle owes user),
"balance": int (sats, positive = user owes libra, negative = libra owes user),
"fiat_balances": {"EUR": Decimal("100.50")},
"accounts": [list of account dicts with balances]
}
@ -676,12 +676,12 @@ class FavaClient:
Use this for efficient aggregations, filtering, and data retrieval.
LIMITATION: BQL can only query position amounts and transaction-level data.
It CANNOT access posting metadata (like 'sats-equivalent'). For Castle's current
It CANNOT access posting metadata (like 'sats-equivalent'). For Libra's current
ledger format where SATS are stored in metadata, manual aggregation is required.
See: docs/BQL-BALANCE-QUERIES.md for detailed analysis and test results.
FUTURE CONSIDERATION: If Castle's ledger format changes to use SATS as position
FUTURE CONSIDERATION: If Libra's ledger format changes to use SATS as position
amounts (instead of metadata), BQL could provide significant performance benefits.
Args:
@ -1031,7 +1031,7 @@ class FavaClient:
Get total expense contributions per user using BQL.
Uses sum(weight) to aggregate all expenses each user has submitted
that created liabilities (castle owes user).
that created liabilities (libra owes user).
Returns:
List of user contribution summaries:
@ -1601,8 +1601,8 @@ class FavaClient:
Args:
user_id: User ID (first 8 characters used for account matching)
entry_type: "expense" (payables - castle owes user) or
"receivable" (user owes castle)
entry_type: "expense" (payables - libra owes user) or
"receivable" (user owes libra)
Returns:
List of unsettled entries with:
@ -1742,8 +1742,8 @@ class FavaClient:
Args:
user_id: User ID (first 8 characters used for account matching)
entry_type: "expense" (payables - castle owes user) or
"receivable" (user owes castle)
entry_type: "expense" (payables - libra owes user) or
"receivable" (user owes libra)
Returns:
List of unsettled entries with:
@ -1896,6 +1896,6 @@ def get_fava_client() -> FavaClient:
if _fava_client is None:
raise RuntimeError(
"Fava client not initialized. Call init_fava_client() first. "
"Castle requires Fava for all accounting operations."
"Libra requires Fava for all accounting operations."
)
return _fava_client