libra/helper
Padreug c174cda48d 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>
2026-05-05 10:24:46 +02:00
..
btc_eur_rates.csv Adds Beancount import helper script 2025-11-08 23:18:42 +01:00
import_beancount.py Rename Castle Accounting extension to Libra 2026-05-05 10:24:46 +02:00
README.md Rename Castle Accounting extension to Libra 2026-05-05 10:24:46 +02:00

Libra Beancount Import Helper

Import Beancount ledger transactions into Libra accounting extension.

📁 Files

  • import_beancount.py - Main import script
  • btc_eur_rates.csv - Daily BTC/EUR rates (create your own)
  • README.md - This file

🚀 Setup

1. Create BTC/EUR Rates CSV

Create btc_eur_rates.csv in this directory with your actual rates:

date,btc_eur_rate
2025-07-01,86500
2025-07-02,87200
2025-07-03,87450

2. Update User Mappings

Edit import_beancount.py and update the USER_MAPPINGS dictionary:

USER_MAPPINGS = {
    "Pat": "actual_wallet_id_for_pat",
    "Alice": "actual_wallet_id_for_alice",
    "Bob": "actual_wallet_id_for_bob",
}

How to get wallet IDs:

  • Check your LNbits admin panel
  • Or query: curl -X GET http://localhost:5000/api/v1/wallet -H "X-Api-Key: user_invoice_key"

3. Set API Key

export LIBRA_ADMIN_KEY="your_lnbits_admin_invoice_key"
export LNBITS_URL="http://localhost:5000"  # Optional

📖 Usage

cd /path/to/libra/helper

# Test with dry run
python import_beancount.py ledger.beancount --dry-run

# Actually import
python import_beancount.py ledger.beancount

📄 Beancount File Format

Your Beancount transactions must have an Equity:<name> account:

2025-07-06 * "Foix market"
  Expenses:Groceries              69.40 EUR
  Equity:Pat

2025-07-07 * "Gas station"
  Expenses:Transport              45.00 EUR
  Equity:Alice

Requirements:

  • Every transaction must have an Equity:<name> account
  • Account names must match exactly what's in Libra
  • The name after Equity: must be in USER_MAPPINGS

🔄 How It Works

  1. Loads rates from btc_eur_rates.csv
  2. Loads accounts from Libra API automatically
  3. Maps users - Extracts user name from Equity:Name accounts
  4. Parses Beancount transactions
  5. Converts EUR → sats using daily rate
  6. Uploads to Libra with metadata

📊 Example Output

$ python import_beancount.py ledger.beancount
======================================================================
🏰 Beancount to Libra Import Script
======================================================================

📊 Loaded 15 daily rates from btc_eur_rates.csv
   Date range: 2025-07-01 to 2025-07-15

🏦 Loaded 28 accounts from Libra

👥 User ID mappings:
   - Pat → wallet_abc123
   - Alice → wallet_def456
   - Bob → wallet_ghi789

📄 Found 25 potential transactions in ledger.beancount

✅ Transaction 1: 2025-07-06 - Foix market (User: Pat) (Rate: 87,891 EUR/BTC)
✅ Transaction 2: 2025-07-07 - Gas station (User: Alice) (Rate: 88,100 EUR/BTC)
✅ Transaction 3: 2025-07-08 - Restaurant (User: Bob) (Rate: 88,350 EUR/BTC)

======================================================================
📊 Summary: 25 succeeded, 0 failed, 0 skipped
======================================================================

✅ Successfully imported 25 transactions to Libra!

Troubleshooting

"No account found in Libra"

Error: No account found in Libra with name 'Expenses:XYZ'

Solution: Create the account in Libra first with that exact name.

"No user ID mapping found"

Error: No user ID mapping found for 'Pat'

Solution: Add Pat to the USER_MAPPINGS dictionary in the script.

"No BTC/EUR rate found"

Error: No BTC/EUR rate found for 2025-07-15

Solution: Add that date to btc_eur_rates.csv.

"Could not determine user ID"

Error: Could not determine user ID for transaction

Solution: Every transaction needs an Equity:<name> account (e.g., Equity:Pat).

📝 Transaction Metadata

Each imported transaction includes:

{
  "meta": {
    "source": "beancount_import",
    "imported_at": "2025-11-08T12:00:00",
    "btc_eur_rate": 87891.0,
    "user_id": "wallet_abc123"
  }
}

And each line includes:

{
  "metadata": {
    "fiat_currency": "EUR",
    "fiat_amount": "69.400",
    "fiat_rate": 1137.88,
    "btc_rate": 87891.0
  }
}

This preserves the original EUR amount and exchange rate for auditing.