Class VoucherSecret

java.lang.Object
xyz.tcheeric.cashu.common.BaseKey
xyz.tcheeric.cashu.voucher.domain.VoucherSecret
All Implemented Interfaces:
xyz.tcheeric.cashu.common.Secret

public final class VoucherSecret extends xyz.tcheeric.cashu.common.BaseKey implements xyz.tcheeric.cashu.common.Secret
Gift card voucher secret (Model B - spendable only at issuing merchant).

VoucherSecret represents a non-deterministic gift card voucher that follows the Cashu protocol's secret structure. Unlike DeterministicSecret, vouchers are NOT deterministic and MUST be backed up to Nostr (or other storage) for recovery.

Model B Constraint

Vouchers cannot be redeemed at the mint. They are only redeemable with the issuing merchant. Any attempt to use voucher secrets in mint swap/melt operations must be rejected.

Immutability

This class is immutable once created. All fields are final and the canonical byte representation is deterministic for signature generation.

Serialization

VoucherSecret uses canonical CBOR serialization (via VoucherSerializationUtils) to ensure deterministic byte representation for ED25519 signature generation. Field ordering is alphabetical to guarantee consistency.

Jackson JSON serialization uses VoucherSecretSerializer to serialize as hex string.

See Also:
  • Field Summary

    Fields inherited from class xyz.tcheeric.cashu.common.BaseKey

    PRIVATE_KEY_LENGTH, PUBLIC_KEY_LENGTH_COMPRESSED, PUBLIC_KEY_LENGTH_UNCOMPRESSED, SECRET_LENGTH
  • Method Summary

    Modifier and Type
    Method
    Description
    create(@NonNull String issuerId, @NonNull String unit, long faceValue, Long expiresAt, String memo)
    Creates a new voucher with auto-generated UUID.
    create(@NonNull String voucherId, @NonNull String issuerId, @NonNull String unit, long faceValue, Long expiresAt, String memo)
    Creates a voucher with specified voucher ID.
    boolean
     
    byte[]
    Returns canonical bytes for Secret interface.
    int
     
    boolean
    Checks if this voucher has expired.
    boolean
    Checks if this voucher is valid (not expired).
    void
    setData(@lombok.NonNull byte[] data)
    VoucherSecret is immutable - data cannot be modified after creation.
    byte[]
    Alias for toCanonicalBytes() for Secret interface.
    byte[]
    Canonical serialization for deterministic signing.
    Returns hex-encoded canonical representation.
    Returns hex-encoded string representation.
    Returns a detailed string representation including metadata.

    Methods inherited from class xyz.tcheeric.cashu.common.BaseKey

    canEqual, equalsIgnoreCase, getBytes, setBytes

    Methods inherited from class java.lang.Object

    clone, finalize, getClass, notify, notifyAll, wait, wait, wait
  • Method Details

    • create

      public static VoucherSecret create(@NonNull @NonNull String issuerId, @NonNull @NonNull String unit, long faceValue, Long expiresAt, String memo)
      Creates a new voucher with auto-generated UUID.
      Parameters:
      issuerId - issuer identifier
      unit - currency unit
      faceValue - face value (must be positive)
      expiresAt - optional expiry timestamp (Unix epoch seconds)
      memo - optional memo
      Returns:
      new VoucherSecret instance
      Throws:
      IllegalArgumentException - if parameters are invalid
    • create

      public static VoucherSecret create(@NonNull @NonNull String voucherId, @NonNull @NonNull String issuerId, @NonNull @NonNull String unit, long faceValue, Long expiresAt, String memo)
      Creates a voucher with specified voucher ID.

      This method is primarily for deserialization and testing. Production code should prefer create(String, String, long, Long, String).

      Parameters:
      voucherId - voucher identifier
      issuerId - issuer identifier
      unit - currency unit
      faceValue - face value (must be positive)
      expiresAt - optional expiry timestamp (Unix epoch seconds)
      memo - optional memo
      Returns:
      new VoucherSecret instance
      Throws:
      IllegalArgumentException - if parameters are invalid
    • toCanonicalBytes

      public byte[] toCanonicalBytes()
      Canonical serialization for deterministic signing.

      Fields are serialized to CBOR in alphabetical order:

      1. expiresAt (if present)
      2. faceValue
      3. issuerId
      4. memo (if present)
      5. unit
      6. voucherId
      Returns:
      CBOR-encoded bytes representing this voucher
    • toHexString

      public String toHexString()
      Returns hex-encoded canonical representation.

      This is the serialization format used in Cashu tokens. For JSON serialization, see VoucherSecretSerializer.

      Returns:
      hex-encoded string of canonical CBOR bytes
    • toBytes

      public byte[] toBytes()
      Alias for toCanonicalBytes() for Secret interface.
      Specified by:
      toBytes in interface xyz.tcheeric.cashu.common.Secret
      Overrides:
      toBytes in class xyz.tcheeric.cashu.common.BaseKey
      Returns:
      canonical CBOR bytes
    • getData

      public byte[] getData()
      Returns canonical bytes for Secret interface.
      Specified by:
      getData in interface xyz.tcheeric.cashu.common.Secret
      Returns:
      canonical CBOR bytes
    • setData

      public void setData(@NonNull @lombok.NonNull byte[] data)
      VoucherSecret is immutable - data cannot be modified after creation.
      Specified by:
      setData in interface xyz.tcheeric.cashu.common.Secret
      Parameters:
      data - ignored
      Throws:
      UnsupportedOperationException - always thrown
    • isExpired

      public boolean isExpired()
      Checks if this voucher has expired.
      Returns:
      true if expired, false if valid or no expiry set
    • isValid

      public boolean isValid()
      Checks if this voucher is valid (not expired).
      Returns:
      true if not expired or no expiry set, false if expired
    • toString

      public String toString()
      Returns hex-encoded string representation.

      Note: JSON serialization uses VoucherSecretSerializer instead.

      Overrides:
      toString in class xyz.tcheeric.cashu.common.BaseKey
      Returns:
      hex string for display/logging (without sensitive data)
    • toStringWithMetadata

      public String toStringWithMetadata()
      Returns a detailed string representation including metadata. Useful for debugging and logging.
      Returns:
      human-readable string with voucher metadata
    • equals

      public boolean equals(Object o)
      Overrides:
      equals in class xyz.tcheeric.cashu.common.BaseKey
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class xyz.tcheeric.cashu.common.BaseKey