Class VoucherBackupPayload
This class implements secure, private voucher backups using:
- NIP-17: Private Direct Messages (sealed sender pattern)
- NIP-44: Versioned encryption (XChaCha20-Poly1305)
Backup Architecture
Voucher backups are encrypted and stored as private messages to self:
- User creates vouchers with their Nostr identity
- Vouchers are encrypted with user's public key (NIP-44)
- Encrypted payload is stored in kind 4 event (encrypted DM to self)
- Event is published to relays
- Only user can decrypt and restore their vouchers
Privacy Guarantees
- Content encryption: Only user can read voucher data
- Self-addressed: Messages sent to user's own pubkey
- NIP-44 encryption: Modern versioned encryption scheme
Payload Structure
{
"version": "1.0",
"vouchers": [
{
"voucher": <SignedVoucher JSON>,
"backedUpAt": <unix timestamp>
}
],
"metadata": {
"totalCount": 5,
"backupTimestamp": <unix timestamp>
}
}
Usage Example
// Backup vouchers
List<SignedVoucher> vouchers = ...;
String userPrivkey = "...";
String userPubkey = "...";
GenericEvent backupEvent = VoucherBackupPayload.createBackupEvent(
vouchers, userPrivkey, userPubkey
);
// Restore vouchers
List<SignedVoucher> restored = VoucherBackupPayload.extractVouchers(
backupEvent, userPrivkey, userPubkey
);
- See Also:
-
Field Summary
Fields -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic nostr.event.impl.GenericEventcreateBackupEvent(@NonNull List<SignedVoucher> vouchers, @NonNull String userPrivkey, @NonNull String userPubkey) Creates an encrypted backup event for vouchers.static List<SignedVoucher> extractVouchers(@NonNull nostr.event.impl.GenericEvent event, @NonNull String userPrivkey, @NonNull String userPubkey) Extracts vouchers from an encrypted backup event.static booleanisValidBackupEvent(nostr.event.impl.GenericEvent event) Checks if an event is a valid voucher backup event.
-
Field Details
-
PAYLOAD_VERSION
Current payload version.- See Also:
-
KIND_ENCRYPTED_DM
public static final int KIND_ENCRYPTED_DMEvent kind 4.Audit M-30 read this as "backups use deprecated NIP-04". The encryption is NIP-44 (see
nostr.crypto.nip44.EncryptedPayloadsbelow): XChaCha20-Poly1305 with a conversation key, not NIP-04's unauthenticated AES-CBC. What is NIP-04 here is only the event kind, because kind 4 is the number NIP-04 defined and nostr-java exposes it under that name.Kept at 4 deliberately. These are self-addressed backups, so no other client has to interpret them, and existing backups are readable only at this kind: changing it would strand every backup already published. NIP-17's kind 14 with gift wrapping would hide the metadata that kind 4 exposes (that these two keys exchanged something, and when), which is worth doing, but it is a migration with a compatibility window rather than a constant change.
- See Also:
-
TAG_BACKUP
Tag for backup identification.- See Also:
-
-
Constructor Details
-
VoucherBackupPayload
public VoucherBackupPayload()
-
-
Method Details
-
createBackupEvent
public static nostr.event.impl.GenericEvent createBackupEvent(@NonNull @NonNull List<SignedVoucher> vouchers, @NonNull @NonNull String userPrivkey, @NonNull @NonNull String userPubkey) Creates an encrypted backup event for vouchers.This method:
- Serializes vouchers to JSON payload
- Encrypts payload with NIP-44
- Creates kind 4 event (encrypted DM to self)
- Signs with user's private key
- Parameters:
vouchers- list of vouchers to backup (must not be null)userPrivkey- user's Nostr private key (hex, must not be null)userPubkey- user's Nostr public key (hex, must not be null)- Returns:
- encrypted event ready for publishing
- Throws:
VoucherNostrException- if encryption or serialization fails
-
extractVouchers
public static List<SignedVoucher> extractVouchers(@NonNull @NonNull nostr.event.impl.GenericEvent event, @NonNull @NonNull String userPrivkey, @NonNull @NonNull String userPubkey) Extracts vouchers from an encrypted backup event.This method:
- Extracts encrypted content from event
- Decrypts content with NIP-44
- Deserializes JSON payload
- Extracts voucher list
- Parameters:
event- the encrypted backup event (must not be null)userPrivkey- user's Nostr private key for decryption (must not be null)userPubkey- user's Nostr public key for decryption (must not be null)- Returns:
- list of restored vouchers (never null, may be empty)
- Throws:
VoucherNostrException- if decryption or deserialization fails
-
isValidBackupEvent
public static boolean isValidBackupEvent(nostr.event.impl.GenericEvent event) Checks if an event is a valid voucher backup event.- Parameters:
event- the event to check- Returns:
- true if valid backup event, false otherwise
-