S2 — NIP-46 connection-token enforcement on kind-21000 RPC (was: NIP-26 delegation) #10
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 G3 (rest, after S0) and G7 (no signed-request primitive). Primary work is in
aiolabs/lnbitsnostr-transport — this issue tracks it from satmachineadmin's side.2026-05-26 — pivot from NIP-26 to NIP-46
NIP-26 has been explicitly removed from the lnbits security plan. From
aiolabs/lnbits#9:The replacement primitive is NIP-46 connection tokens issued by a sidecar
nsecbunkerd. Seeaiolabs/lnbits#18§F — the satmachineadmin ATM is called out by name as the canonical test case:So S2 is no longer "validate a NIP-26 delegation tag on every event." It's "verify the inbound kind-21000 came from a sender pubkey whose
create_new_tokencredential is still live in the bunker."What the handler must do (revised)
For every inbound kind-21000:
["expiration"]tag (NIP-40) — S1.sender_pubkey→ bunker token record. The handler asks the bunker (or a cache populated from the bunker) whethersender_pubkeyis a valid, unrevoked, unexpired connection token authorized to callsign_event:21000.X_alice, the user's LNbits account identity).operator_pubkeyontoPayment.extraso satmachineadmin can resolve the operator at settlement-land time without re-walking the chain. (Depends on S5.)The ATM is therefore a NIP-46 client connecting through its scoped token, not a delegated signer. It signs kind-21000 with its own ephemeral pubkey (the token's client identity), and the bunker enforces the kind/expiry policy at the LNbits-handler boundary.
Why this is simpler than NIP-26 turned out to be
revoke_user/ futurerevoke_token); LNbits queries the bunker directly. No "wait for the old token'screated_at <window to close" semantics.SigningCondition); we don't invent a new format.kind-24133/24134events over NIP-44 v2 on the internal relay).Changes in this repo (unchanged in shape)
After the handler lands
operator_pubkeyonPayment.extra:tasks.py:_handle_paymentreadspayment.extra["operator_pubkey"], matches it againstmachine.operator_user_id(vialnbits.core.crud.get_account_by_pubkey), and refuses to record a settlement if the chain doesn't close.Acceptance (revised)
sign_event:1(not 21000) → handler rejects.Sequencing
Blocked on
aiolabs/lnbits#18— the bunker integration and per-device token plumbing must land first. Until then, S2 work in this repo can't move. The S2 effort in satmachineadmin shrinks correspondingly: readoperator_pubkeyoffPayment.extraand join against the machine row. The hard work moves into the lnbits bunker client.Reference
aiolabs/lnbits#9— operator-IdP framing (reframed 2026-05-25).aiolabs/lnbits#18— sidecar bunker integration; §F is the satmachineadmin alignment.~/dev/nostr-protocol/nips/46.md.docs/security-pathway-v1.md§5.1, §6.S2 — needs a follow-up edit reflecting this pivot.