Interface VoucherLedgerPort
This port defines the interface for publishing and querying voucher status on a public ledger. In the Nostr implementation, this uses NIP-33 (parameterized replaceable events) to maintain a public audit trail of voucher lifecycle.
Hexagonal Architecture
This is a port (interface) in hexagonal architecture terminology. The actual implementation (adapter) is provided by the infrastructure layer (e.g., NostrVoucherLedgerRepository in cashu-voucher-nostr module).
Design Principles
- Infrastructure-agnostic: No dependencies on Nostr or any specific storage
- Pluggable: Can be implemented with Nostr, SQL, IPFS, etc.
- Testable: Easy to mock for unit testing application services
Model B Constraint
The ledger tracks vouchers that are only redeemable at the issuing merchant. Status transitions enforce Model B business rules (no mint redemption).
Example Usage
// Publishing a new voucher SignedVoucher voucher = ...; ledgerPort.publish(voucher, VoucherStatus.ISSUED); // Checking voucher status Optional<VoucherStatus> status = ledgerPort.queryStatus(voucherId); if (status.isPresent() invalid input: '&'invalid input: '&' status.get() == VoucherStatus.ISSUED) { // Voucher is valid for redemption } // Marking voucher as redeemed ledgerPort.updateStatus(voucherId, VoucherStatus.REDEEMED);
- See Also:
-
Method Summary
Modifier and TypeMethodDescriptiondefault booleanChecks if a voucher exists in the ledger.voidpublish(SignedVoucher voucher, VoucherStatus status) Publishes a voucher to the public ledger with the given status.default voidpublish(SignedVoucher voucher, VoucherStatus status, boolean isSplit) Publishes a voucher to the public ledger with the given status and split flag.default voidpublish(SignedVoucher voucher, VoucherStatus status, boolean isSplit, String parentVoucherId) Publishes a voucher to the public ledger with the given status, split flag, and parent voucher ID.queryStatus(String voucherId) Queries the current status of a voucher from the ledger.default Optional<SignedVoucher> queryVoucher(String voucherId) Queries the full voucher details from the ledger.voidupdateStatus(String voucherId, VoucherStatus newStatus) Updates the status of an existing voucher in the ledger.
-
Method Details
-
publish
Publishes a voucher to the public ledger with the given status.This creates a new ledger entry for the voucher. If a voucher with the same ID already exists, the behavior depends on the implementation:
- NIP-33 (Nostr): Replaces the previous entry (replaceable event)
- SQL: May throw exception or update existing record
The voucher's signature should be verified before publishing, but this method does not perform validation (separation of concerns).
- Parameters:
voucher- the signed voucher to publish (must not be null)status- the initial status (typically ISSUED, must not be null)- Throws:
IllegalArgumentException- if parameters are invalidRuntimeException- if publishing fails (network, storage, etc.)
-
publish
Publishes a voucher to the public ledger with the given status and split flag.- Parameters:
voucher- the signed voucher to publish (must not be null)status- the status (must not be null)isSplit- true if this voucher resulted from a split operation
-
publish
default void publish(SignedVoucher voucher, VoucherStatus status, boolean isSplit, String parentVoucherId) Publishes a voucher to the public ledger with the given status, split flag, and parent voucher ID.- Parameters:
voucher- the signed voucher to publish (must not be null)status- the status (must not be null)isSplit- true if this voucher resulted from a split/partial operationparentVoucherId- the parent voucher ID for partial redemptions (null for root vouchers)
-
queryStatus
Queries the current status of a voucher from the ledger.Returns the most recent status of the voucher as recorded in the ledger. If the voucher does not exist in the ledger, returns
Optional.empty().This is a read-only operation and does not modify the ledger state.
- Parameters:
voucherId- the unique voucher identifier (must not be null or blank)- Returns:
- the current status, or empty if voucher not found
- Throws:
IllegalArgumentException- if voucherId is null or blankRuntimeException- if query fails (network, storage, etc.)
-
updateStatus
Updates the status of an existing voucher in the ledger.This method changes the voucher's status, recording a state transition in the public ledger. Common transitions:
- ISSUED → REDEEMED (merchant accepts voucher)
- ISSUED → REVOKED (issuer cancels voucher)
- ISSUED → EXPIRED (time-based expiry)
Terminal states (REDEEMED, REVOKED, EXPIRED) should not be changed once set, but this is enforced at the service layer, not by this port.
- Parameters:
voucherId- the unique voucher identifier (must not be null or blank)newStatus- the new status to set (must not be null)- Throws:
IllegalArgumentException- if parameters are invalidRuntimeException- if update fails (network, storage, voucher not found, etc.)
-
exists
Checks if a voucher exists in the ledger.This is a convenience method equivalent to:
queryStatus(voucherId).isPresent()
- Parameters:
voucherId- the unique voucher identifier (must not be null or blank)- Returns:
- true if the voucher exists in the ledger, false otherwise
- Throws:
IllegalArgumentException- if voucherId is null or blankRuntimeException- if check fails (network, storage, etc.)
-
queryVoucher
Queries the full voucher details from the ledger.This retrieves both the voucher secret and its current status from the ledger. This is useful for validation and verification operations.
Note: This is an optional operation. Implementations may not support retrieving full voucher details from the ledger (e.g., if only status transitions are stored). Default implementation throws UnsupportedOperationException.
- Parameters:
voucherId- the unique voucher identifier (must not be null or blank)- Returns:
- the complete voucher with current status, or empty if not found
- Throws:
UnsupportedOperationException- if implementation doesn't support full retrievalIllegalArgumentException- if voucherId is null or blankRuntimeException- if query fails (network, storage, etc.)
-