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:
  • Method Details

    • tryRecordRedemption

      boolean tryRecordRedemption(String fingerprint, String voucherId, String redeemedBy)
      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 invalid
      RuntimeException - if storage operation fails
    • isRedeemed

      boolean isRedeemed(String fingerprint)
      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