Extension: Castle (Accounting) #12
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Implement a Nostr-native double-entry accounting extension for Lightning.Pub, replacing the LNbits
castleextension. This is the most complex extension to port and should be approached incrementally.Motivation
Castle provides double-entry bookkeeping for collectives (co-living spaces, makerspaces, community projects). The LNbits version depends on an external Fava/Beancount Python service for all accounting calculations — an awkward dependency that ties it to HTTP and a separate process.
A Lightning.Pub extension could:
Key Design Decision: Fava Dependency
The LNbits version delegates all accounting math to Fava/Beancount. Options for LP:
Phased Implementation
Phase 1: SATS-only accounting (MVP)
Phase 2: Multi-currency + hierarchy
:separator (Expenses:Food:Groceries)Phase 3: Full feature parity
Scope (Full)
RPC Methods:
Data Model:
Account— name, type (Asset/Liability/Equity/Revenue/Expense), parent, metadataJournalEntry— date, description, flag (cleared/pending/void), reference, creator_pubkeyEntryLine— entry_id, account_id, amount_sats, fiat_amount, fiat_currency, fiat_rateAccountPermission— account_id, user_pubkey, permission_type, expires_at, granted_byPaymentRequest— user_pubkey, amount, description, status, approved_byCore Accounting Invariants:
Complexity
HIGH — ~5000-8000 lines total across all phases. 2-4 weeks for full implementation.
The accounting logic itself is well-defined (double-entry is centuries old), but currency handling, permission hierarchies, and reconciliation features add significant scope.
Nostr-Native Advantages
Reference
lnbits/extensions/castle/castle/beancount_format.pycastle/docs/PERMISSIONS-SYSTEM.mdcastle/docs/BQL-BALANCE-QUERIES.mdNIP Review: Applicable Standards for Castle Extension
Castle has the richest NIP surface area of the three extensions. The Nostr protocol provides building blocks for every major accounting concern: authorization, audit trails, encrypted communication, role management, and payment settlement.
Core NIPs to Implement
NIP-47: Nostr Wallet Connect — SETTLEMENT ENGINE
Kinds: 13194, 23194, 23195, 23197
Maps directly to accounting operations:
make_invoicepay_invoicelist_transactionsget_balancemake_hold_invoice/settle_hold_invoiceKey insight: Hold invoices enable proper accrual accounting. Create hold invoice = record receivable; settle = recognize cash receipt. Cancel = write off. This maps directly to Castle's "pending → cleared" journal entry lifecycle.
The
fees_paidfield from responses directly populates the expense ledger for Lightning network costs — no manual fee tracking needed.NIP-78: Application-Specific Data — CHART OF ACCOUNTS
Kind: 30078
Store the entire chart of accounts and Castle configuration as encrypted addressable events:
Also use separate
dtags for settings (castle/settings), reporting period snapshots, and journal entry templates. Being addressable and replaceable means the chart evolves without event proliferation.NIP-17: Private Direct Messages — APPROVAL WORKFLOWS
Kinds: 14 (chat), 15 (file), 1059 (gift wrap), 13 (seal)
This is how Castle replaces its web-only approval UI with a protocol-native workflow:
The three-layer structure (rumor → seal → gift wrap) means relays never see who is approving what — critical for financial privacy.
NIP-59: Gift Wrap — METADATA PROTECTION
Kinds: 13 (seal), 1059 (gift wrap)
Wraps all sensitive financial communications. Temporal obfuscation (randomized
created_atup to 2 days) prevents correlation attacks like "payment arrived → 2 minutes later approval was sent." Each approval gets a unique ephemeral key.NIP-58: Badges — ROLE-BASED ACCESS CONTROL
Kinds: 30009 (badge definition), 8 (badge award), 30008 (profile badges)
Replace Castle's database RBAC with Nostr-native roles:
Roles to define:
castle-admin— Full access (super user)castle-accountant— Record entries, view balancescastle-approver— Approve expenses and payment requestscastle-viewer— Read-only balance and report accessBadges are non-transferable and cryptographically signed — audit-proof role assignment.
NIP-32: Labeling — TRANSACTION CLASSIFICATION
Kind: 1985
Tag journal entries with accounting metadata:
Enables slicing the ledger by cost center, department, vendor, project — all queryable via standard Nostr filters.
Supplementary NIPs
Double-Entry Architecture Using NIPs
Journal entry as a composite Nostr structure:
#e,#p,#a,#l)Settlement flow:
What replaces Fava/Beancount:
:separator parsed in TypeScript, permission inheritance via string prefix matchingSummary
Castle benefits from the most NIPs because accounting touches identity (NIP-58), communication (NIP-17/59), payments (NIP-47/57), data storage (NIP-78), classification (NIP-32), and access control (NIP-51). The protocol provides every primitive needed — the extension's job is to enforce double-entry invariants and orchestrate the workflow.