diff --git a/packages/lnbits/src/client.ts b/packages/lnbits/src/client.ts index b820b95..0add0b8 100644 --- a/packages/lnbits/src/client.ts +++ b/packages/lnbits/src/client.ts @@ -366,12 +366,23 @@ export class LnbitsClient { // Build + sign the kind-21000 event ourselves. The server reads our // pubkey directly off the signature, so there's no separate // authIdentifier in the envelope (unlike LightningPubClient). + // + // NIP-40 expiration: 5 minutes past now. Defence-in-depth at the + // relay layer — compliant relays (per NIP-40) drop expired events + // before they reach the LNbits handler. The handler also enforces + // its own max_age window (aiolabs/lnbits e4b5bcd7), so a replay + // attacker can't bypass this by stripping the tag; the tag just + // lets the relay short-circuit earlier. + const now = Math.floor(Date.now() / 1000) const event = finalizeEvent( { kind: LNBITS_KIND_RPC, content: encrypted, - tags: [['p', this.config.serverPubkey]], - created_at: Math.floor(Date.now() / 1000), + tags: [ + ['p', this.config.serverPubkey], + ['expiration', String(now + 300)], + ], + created_at: now, }, this.identity.privateKey, )