Class VoucherMetadata

java.lang.Object
xyz.tcheeric.cashu.voucher.domain.VoucherMetadata

public final class VoucherMetadata extends Object
Reads voucher metadata from either kind that carries it.

Public because the mint needs it. VoucherSpendingCondition used to reach for instanceof VoucherSecret and skip its checks when that failed, which meant a P2PK_VOUCHER had its expiry and issuer signature silently ignored. Reading through one accessor set removes the opportunity for that class of bug.

Two NUT-10 kinds hold voucher metadata: VOUCHER, and P2PK_VOUCHER for a voucher that is also P2PK-locked. They share the VoucherTags vocabulary, so almost everything is read identically — but they do not share a Java supertype that declares the accessors, and they disagree about one field.

That field is the voucher id. A VOUCHER secret keeps it in data; a P2PK_VOUCHER cannot, because data is where NUT-11 puts the spending key and where a mint looks for the lock, so it moves to a tag. This class is the one place that knows the difference, which keeps every caller from having to.

Reading rather than casting also means signing and verification stay single implementations. Overloading them per kind would have duplicated the cryptography, which is the last thing worth duplicating.

  • Method Summary

    Modifier and Type
    Method
    Description
    static Long
    expiresAt(@NonNull xyz.tcheeric.cashu.common.nut10.WellKnownSecret secret)
    Expiry as a Unix timestamp in seconds, or null when the voucher does not expire.
    static boolean
    isExpired(@NonNull xyz.tcheeric.cashu.common.nut10.WellKnownSecret secret)
    Whether the expiry has passed.
    static boolean
    isSigned(@NonNull xyz.tcheeric.cashu.common.nut10.WellKnownSecret secret)
    Whether both issuer fields are present.
    static String
    issuerId(@NonNull xyz.tcheeric.cashu.common.nut10.WellKnownSecret secret)
    The issuing merchant's identifier, or null.
    static String
    issuerPublicKey(@NonNull xyz.tcheeric.cashu.common.nut10.WellKnownSecret secret)
    The issuer's public key, or null when unset.
    static String
    issuerSignature(@NonNull xyz.tcheeric.cashu.common.nut10.WellKnownSecret secret)
    The issuer's signature over the canonical bytes, or null when unsigned.
    static boolean
    isVoucherCarrying(@NonNull xyz.tcheeric.cashu.common.nut10.WellKnownSecret secret)
    Whether this kind carries voucher metadata at all.
    static String
    voucherId(@NonNull xyz.tcheeric.cashu.common.nut10.WellKnownSecret secret)
    The voucher id, from wherever this kind keeps it, or null.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • isVoucherCarrying

      public static boolean isVoucherCarrying(@NonNull @NonNull xyz.tcheeric.cashu.common.nut10.WellKnownSecret secret)
      Whether this kind carries voucher metadata at all.
    • voucherId

      public static String voucherId(@NonNull @NonNull xyz.tcheeric.cashu.common.nut10.WellKnownSecret secret)
      The voucher id, from wherever this kind keeps it, or null.

      Used for log correlation, so it never throws: a secret too malformed to name is still worth a log line saying so.

    • issuerId

      public static String issuerId(@NonNull @NonNull xyz.tcheeric.cashu.common.nut10.WellKnownSecret secret)
      The issuing merchant's identifier, or null.
    • issuerSignature

      public static String issuerSignature(@NonNull @NonNull xyz.tcheeric.cashu.common.nut10.WellKnownSecret secret)
      The issuer's signature over the canonical bytes, or null when unsigned.
    • issuerPublicKey

      public static String issuerPublicKey(@NonNull @NonNull xyz.tcheeric.cashu.common.nut10.WellKnownSecret secret)
      The issuer's public key, or null when unset.
    • expiresAt

      public static Long expiresAt(@NonNull @NonNull xyz.tcheeric.cashu.common.nut10.WellKnownSecret secret)
      Expiry as a Unix timestamp in seconds, or null when the voucher does not expire.
    • isExpired

      public static boolean isExpired(@NonNull @NonNull xyz.tcheeric.cashu.common.nut10.WellKnownSecret secret)
      Whether the expiry has passed. A voucher with no expiry never expires.
    • isSigned

      public static boolean isSigned(@NonNull @NonNull xyz.tcheeric.cashu.common.nut10.WellKnownSecret secret)
      Whether both issuer fields are present. Presence only; says nothing about validity.