fix(core): read the routing fee from fee, not the absent fee_msat #171
No reviewers
Labels
No labels
app:activities
app:chat
app:chatelet
app:events
app:forum
app:libra
app:market
app:restaurant
app:tasks
app:wallet
app:webapp
bug
enhancement
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
aiolabs/webapp!171
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/fee-field-name"
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?
Closes #170.
LNbits payment payloads carry
fee, signed millisats likeamount. There is nofee_msatfield, so three modules were readingundefined.PaymentService.PaymentResultfee_msat: number, a field the API never sends, so the compiler vouched for a number that was always undefinedmarket/useLightningPaymentfeeMsat: undefinedonto paid orders, on a propertyOrderdid not declareevents/LnbitsPaymentProviderdata.fee_msat ?? 0— the fallback masked the miss, so every payment recorded a zero feeApproach
payInvoicenow normalizes at the boundary instead of returning the raw payload, mappingfeeto a positivefeeMsat. Doing it once there means no call site can pick the wrong field name or forget that outgoing amounts are signed, andPaymentResultfinally describes what callers actually receive.Ordernow declaresfeeMsat?: number.updateOrdertakesPartial<Order>and the write goes through an inferred variable, so the excess-property check never fired — the fee market persists was landing in the store invisible to the type system, and stayed that way even once the value was correct.Verification
Against a live pay-invoice response, plus a synthetic payment carrying a real routing fee. Internal LNbits transfers are fee-free, so the live case cannot exercise a non-zero fee:
Builds pass for the hub and for the events, market and wallet standalones;
vue-tsc -bis clean across the project.Nothing read these values downstream, so no totals were ever miscomputed. The fee was simply recorded as missing or zero.
Context
This came out of a wider satoshi/millisatoshi audit against the LNbits source, which I'll summarise separately. The headline from that:
GET /api/v1/walletreturnsbalancein millisats while the WebSocket'swallet_balanceis in sats — same name, 1000x apart. Both of our code paths happen to handle their own correctly.fee, not the absentfee_msat7d4cb3d49d