feat: name the applied rate in the payout memo
A back-dated payout's sat figure is unexplainable on its own — employee_2's
August backfill paid 18,353 sat and 14,794 sat for the same ten euro, and
only the rate says why. Both wallets now show it:
dev retainer — 2026-08-01 · 10 EUR @ 54,487 EUR/BTC
dev retainer — 2026-08-29 · 10 EUR @ 67,596.6 EUR/BTC
This required moving the `current` mode conversion into payroll as well.
Previously that mode handed create_invoice a fiat amount and let LNbits
convert, so the rate only became knowable by reading it back off the
resulting invoice — after the memo had already been fixed. Now every mode
resolves its rate before invoicing and the memo is accurate in all three,
rather than only for the back-dated ones.
It remains a single conversion, not a second opinion: fiat_amount_as_satoshis
is the same function create_invoice would have called, and the rate is
derived by the same formula calculate_fiat_amounts uses. Because passing
sats means LNbits no longer stamps the fiat metadata itself, payroll now
writes the identical fiat_currency / fiat_amount / fiat_rate / btc_rate keys
onto the payment, so a payroll payment still reads like any other
fiat-priced one in the payments list.
A rate that rounds an amount to zero sats now fails the period rather than
raising a zero-division while deriving the rate.
Memo omits the rate clause for sat-denominated contracts, where there is no
conversion to report.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018jy52j9GRZ6XKa1Zt21LLj
This commit is contained in:
parent
2e6009b612
commit
3b14db3dff
4 changed files with 121 additions and 27 deletions
|
|
@ -84,10 +84,24 @@ The two sources disagree by a couple of percent on the same date (for
|
|||
close versus a cross-exchange average). That is why the ledger records
|
||||
`rate_source` beside `rate` instead of presenting a bare figure as canonical.
|
||||
|
||||
Where payroll converts, it hands `create_invoice` a **sat** amount, because
|
||||
`create_invoice` always prices fiat itself and cannot be told a rate. The
|
||||
rate used and its source are recorded on the payout row either way — in
|
||||
`current` mode read back off the invoice LNbits priced, not recomputed.
|
||||
Payroll does the conversion itself in **every** mode and hands
|
||||
`create_invoice` a sat amount. Not because it has to for `current` mode, but
|
||||
because knowing the rate *before* the invoice exists is what lets the memo
|
||||
name it. It stays a single conversion — `fiat_amount_as_satoshis` is the
|
||||
function `create_invoice` would have called — and payroll stamps the same
|
||||
`fiat_currency` / `fiat_amount` / `fiat_rate` / `btc_rate` keys onto the
|
||||
payment that `calculate_fiat_amounts` would have, so a payroll payment reads
|
||||
like any other fiat-priced one.
|
||||
|
||||
Both wallets therefore show a memo naming the rate applied:
|
||||
|
||||
```
|
||||
dev retainer — 2026-08-01 · 10 EUR @ 54,487 EUR/BTC
|
||||
dev retainer — 2026-08-29 · 10 EUR @ 67,596.6 EUR/BTC
|
||||
```
|
||||
|
||||
Which is the point: 18,353 sat and 14,794 sat are both "ten euro", and only
|
||||
the rate says why they differ.
|
||||
|
||||
**A rate that cannot be established fails the period.** There is deliberately
|
||||
no fallback to today's rate: one that moved 30% since the payday would pay
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue