S3 — NIP-57-style signed settlement receipts (preimage attestation) #11
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?
Part of #8. Closes gaps G2 (Payment.extra is unauthenticated) and G7 (no signed attestation).
Problem
Today
dca_settlementsis the source of truth. If the LNbits DB is ever tampered with — by a super skim, an insider, or a hostile host — there's no out-of-band record. Payment.extra is mutable JSON; auditors have no cryptographic anchor.Fix
After every settlement's three leg groups complete, LNbits publishes a signed event (NIP-57-style zap-receipt shape, possibly a custom kind in the 21001–21002 range) carrying:
The preimage is the unforgeable anchor: it hashes to
payment_hashon everydca_settlementsrow. Mismatch ⇒ forged settlement.Changes
LNbits side (
aiolabs/lnbits)kind:13194).lnbits.core.services.nostr_attestation.publish_settlement_receipt(payment, sender_pubkey, operator_pubkey).This repo (
aiolabs/satmachineadmin)tasks.py: subscribes to kind:9735 with#P=<atm_npub>filter for every active machine.dca_settlements.receipt_event_idandreceipt_relays(JSON).dca_settlementsrow, verifysha256(preimage_from_receipt) == payment_hash. Mismatch ⇒ alert.Open question
Use
kind:9735(NIP-57) verbatim or a new kind? NIP-57's receipt shape fits, but the semantics are "this was a zap of a Nostr event." We're attesting a payment, not a zap. Suggest: new kind21001("bitSpire settlement attestation") with the same tag shape. Decision in design review before implementation.Acceptance
dca_settlements.payment_hash.UPDATE dca_settlements SET gross_sats=…), reconciliation flags the row as drifted from the receipt.Reference
NIP-57 spec:
~/dev/nostr-protocol/nips/57.md.Design doc:
docs/security-pathway-v1.md§5.1 (end-state diagram), §6.S3.