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

@ -2,14 +2,14 @@
**Date**: 2025-01-12
**Prepared By**: Senior Accounting Review
**Subject**: Castle Extension - Lightning Payment Settlement Entries
**Subject**: Libra Extension - Lightning Payment Settlement Entries
**Status**: Technical Review
---
## Executive Summary
This document provides a professional accounting assessment of Castle's net settlement entry pattern used for recording Lightning Network payments that settle fiat-denominated receivables. The analysis identifies areas where the implementation deviates from traditional accounting best practices and provides specific recommendations for improvement.
This document provides a professional accounting assessment of Libra's net settlement entry pattern used for recording Lightning Network payments that settle fiat-denominated receivables. The analysis identifies areas where the implementation deviates from traditional accounting best practices and provides specific recommendations for improvement.
**Key Findings**:
- ✅ Double-entry integrity maintained
@ -23,14 +23,14 @@ This document provides a professional accounting assessment of Castle's net sett
## Background: The Technical Challenge
Castle operates as a Lightning Network-integrated accounting system for collectives (co-living spaces, makerspaces). It faces a unique accounting challenge:
Libra operates as a Lightning Network-integrated accounting system for collectives (co-living spaces, makerspaces). It faces a unique accounting challenge:
**Scenario**: User creates a receivable in EUR (e.g., €200 for room rent), then pays via Lightning Network in satoshis (225,033 sats).
**Challenge**: Record the payment while:
1. Clearing the exact EUR receivable amount
2. Recording the exact satoshi amount received
3. Handling cases where users have both receivables (owe Castle) and payables (Castle owes them)
3. Handling cases where users have both receivables (owe Libra) and payables (Libra owes them)
4. Maintaining Beancount double-entry balance
---
@ -43,7 +43,7 @@ Castle operates as a Lightning Network-integrated accounting system for collecti
; Step 1: Receivable Created
2025-11-12 * "room (200.00 EUR)" #receivable-entry
user-id: "375ec158"
source: "castle-api"
source: "libra-api"
sats-amount: "225033"
Assets:Receivable:User-375ec158 200.00 EUR
sats-equivalent: "225033"
@ -187,7 +187,7 @@ Assets:Receivable:User-375ec158 -200.00 EUR
; No sats-equivalent needed here
```
**Option B - Use EUR positions with metadata** (Castle's current approach):
**Option B - Use EUR positions with metadata** (Libra's current approach):
```beancount
Assets:Bitcoin:Lightning 200.00 EUR
sats-received: "225033"
@ -314,8 +314,8 @@ Assets:Receivable:User-375ec158 -200.00 EUR
**When Net Settlement is Appropriate**:
```
User owes Castle: 555.00 EUR (receivable)
Castle owes User: 38.00 EUR (payable)
User owes Libra: 555.00 EUR (receivable)
Libra owes User: 38.00 EUR (payable)
Net amount due: 517.00 EUR (true settlement)
```
@ -330,8 +330,8 @@ Liabilities:Payable:User 38.00 EUR
**When Two Postings Suffice**:
```
User owes Castle: 200.00 EUR (receivable)
Castle owes User: 0.00 EUR (no payable)
User owes Libra: 200.00 EUR (receivable)
Libra owes User: 0.00 EUR (no payable)
Amount due: 200.00 EUR (simple payment)
```
@ -405,7 +405,7 @@ Assets:Receivable:User -200.00 EUR
```beancount
2025-11-12 * "Net settlement via Lightning"
; User owes 555 EUR, Castle owes 38 EUR, net: 517 EUR
; User owes 555 EUR, Libra owes 38 EUR, net: 517 EUR
Assets:Bitcoin:Lightning 517.00 EUR
sats-received: "565251"
Assets:Receivable:User-375ec158 -555.00 EUR
@ -469,7 +469,7 @@ if total_payable_fiat > 0:
**Decision Required**: Select either position-based OR metadata-based satoshi tracking.
**Option A - Keep Metadata Approach** (recommended for Castle):
**Option A - Keep Metadata Approach** (recommended for Libra):
```python
# In format_net_settlement_entry()
postings = [
@ -506,7 +506,7 @@ postings = [
]
```
**Recommendation**: Choose Option A (metadata) for consistency with Castle's architecture.
**Recommendation**: Choose Option A (metadata) for consistency with Libra's architecture.
---
@ -625,7 +625,7 @@ async def create_payment_entry(
payment_hash=payment_hash
)
else:
# PAYABLE PAYMENT: Castle paying user (different flow)
# PAYABLE PAYMENT: Libra paying user (different flow)
return await format_payable_payment_entry(...)
```
@ -663,7 +663,7 @@ async def create_payment_entry(
1. Most receivables created in EUR
2. Financial reporting requirements typically in fiat
3. Tax obligations calculated in fiat
4. Aligns with current Castle metadata approach
4. Aligns with current Libra metadata approach
---
@ -681,7 +681,7 @@ async def create_payment_entry(
**Cryptocurrency Sub-Ledger** (SATS-denominated):
```beancount
2025-11-12 * "Lightning payment received"
Assets:Bitcoin:Lightning:Castle 225033 SATS
Assets:Bitcoin:Lightning:Libra 225033 SATS
Assets:Bitcoin:Custody:User-375ec 225033 SATS
```
@ -821,7 +821,7 @@ async def create_payment_entry(
**Is this "best practice" accounting?**
**No**, this implementation deviates from traditional accounting standards in several ways.
**Is it acceptable for Castle's use case?**
**Is it acceptable for Libra's use case?**
**Yes, with modifications**, it's a reasonable pragmatic solution for a novel problem (cryptocurrency payments of fiat debts).
**Critical improvements needed**:
@ -829,7 +829,7 @@ async def create_payment_entry(
2. ✅ Implement exchange gain/loss tracking (required for compliance)
3. ✅ Separate payment vs. settlement logic (accuracy and clarity)
**The fundamental challenge**: Traditional accounting wasn't designed for this scenario. There is no established "standard" for recording cryptocurrency payments of fiat-denominated receivables. Castle's approach is functional, but should be refined to align better with accounting principles where possible.
**The fundamental challenge**: Traditional accounting wasn't designed for this scenario. There is no established "standard" for recording cryptocurrency payments of fiat-denominated receivables. Libra's approach is functional, but should be refined to align better with accounting principles where possible.
### Next Steps
@ -847,7 +847,7 @@ async def create_payment_entry(
- **FASB Concept Statement No. 2**: Qualitative Characteristics of Accounting Information
- **ASC 105-10-05**: Substance Over Form
- **Beancount Documentation**: http://furius.ca/beancount/doc/index
- **Castle Extension**: `docs/SATS-EQUIVALENT-METADATA.md`
- **Libra Extension**: `docs/SATS-EQUIVALENT-METADATA.md`
- **BQL Analysis**: `docs/BQL-BALANCE-QUERIES.md`
---
@ -858,4 +858,4 @@ async def create_payment_entry(
---
*This analysis was prepared for internal review and development planning. It represents a professional accounting assessment of the current implementation and should be used to guide improvements to Castle's payment recording system.*
*This analysis was prepared for internal review and development planning. It represents a professional accounting assessment of the current implementation and should be used to guide improvements to Libra's payment recording system.*