Interface VoucherRedemptionPort
public interface VoucherRedemptionPort
Port for voucher redemption tracking with duplicate detection.
This port defines the interface for tracking voucher redemptions using cryptographic fingerprints. It provides defense-in-depth against double redemption by maintaining a record of all redemption attempts.
Hexagonal Architecture
This is a port (interface) in hexagonal architecture terminology. Implementations (adapters) can use various storage backends:
- Nostr: Store redemptions as events (NIP-33 or encrypted)
- SQL: Store in a redemptions table
- In-memory: For testing or caching
Security Model
The fingerprint-based tracking provides:
- Duplicate detection: Same voucher produces same fingerprint
- Privacy: Fingerprint doesn't reveal voucher details
- Atomic operations: tryRecordRedemption is idempotent
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeInterfaceDescriptionstatic final recordRedemption record containing details of when and by whom a voucher was redeemed. -
Method Summary
Modifier and TypeMethodDescriptiongetRedemption(String fingerprint) Retrieves redemption details for a fingerprint.booleanisRedeemed(String fingerprint) Checks if a voucher fingerprint has already been redeemed.booleantryRecordRedemption(String fingerprint, String voucherId, String redeemedBy) Attempts to record a voucher redemption atomically.
-
Method Details
-
tryRecordRedemption
Attempts to record a voucher redemption atomically.This is an idempotent operation:
- If fingerprint not seen before: records redemption and returns true
- If fingerprint already recorded: returns false (no change)
This method MUST be atomic to prevent race conditions between concurrent redemption attempts.
- Parameters:
fingerprint- the voucher fingerprint (64-char hex, must not be null)voucherId- the voucher ID for reference (must not be null)redeemedBy- identifier of the redeeming party (must not be null)- Returns:
- true if redemption was recorded (first attempt), false if duplicate
- Throws:
IllegalArgumentException- if parameters are invalidRuntimeException- if storage operation fails
-
isRedeemed
Checks if a voucher fingerprint has already been redeemed.- Parameters:
fingerprint- the voucher fingerprint to check (64-char hex)- Returns:
- true if a redemption record exists for this fingerprint
- Throws:
IllegalArgumentException- if fingerprint is null or invalid
-
getRedemption
Retrieves redemption details for a fingerprint.- Parameters:
fingerprint- the voucher fingerprint (64-char hex)- Returns:
- redemption record if found, empty otherwise
- Throws:
IllegalArgumentException- if fingerprint is null or invalid
-