Package xyz.tcheeric.cashu.voucher.app
Class VoucherService
java.lang.Object
xyz.tcheeric.cashu.voucher.app.VoucherService
Main voucher service that orchestrates use cases.
This service provides the primary business logic for voucher operations, coordinating between the domain layer (voucher creation, signing, validation) and the infrastructure layer (storage via ports).
Responsibilities
- Issue new vouchers (create, sign, publish to ledger)
- Query voucher status from the public ledger
- Update voucher status (state transitions)
- Orchestrate backup and restore operations
- Serialize vouchers to Cashu token format
Architecture
This service follows hexagonal architecture principles:
- Depends on ports (interfaces) not concrete implementations
- Uses domain entities (VoucherSecret, SignedVoucher)
- Returns DTOs for API boundaries
- Infrastructure-agnostic (no knowledge of Nostr, SQL, etc.)
Usage Example
// Setup (typically in Spring/Guice configuration)
VoucherLedgerPort ledger = new NostrVoucherLedgerRepository(...);
VoucherBackupPort backup = new NostrVoucherBackupRepository(...);
VoucherService service = new VoucherService(ledger, backup, privKey, pubKey);
// Issue a voucher
IssueVoucherRequest request = IssueVoucherRequest.builder()
.issuerId("merchant123")
.unit("sat")
.amount(10000L)
.expiresInDays(365)
.memo("Birthday gift")
.build();
IssueVoucherResponse response = service.issue(request);
System.out.println("Token: " + response.getToken());
// Query status
Optional<VoucherStatus> status = service.queryStatus(response.getVoucherId());
// Backup vouchers
service.backup(List.of(response.getVoucher()), userNostrPrivateKey);
- See Also:
-
Constructor Summary
ConstructorsConstructorDescriptionVoucherService(@NonNull VoucherLedgerPort ledgerPort, @NonNull VoucherBackupPort backupPort, @NonNull String mintIssuerPrivateKey, @NonNull String mintIssuerPublicKey) Constructs a VoucherService with the required dependencies. -
Method Summary
Modifier and TypeMethodDescriptionvoidbackup(@NonNull List<SignedVoucher> vouchers, @NonNull String userPrivateKey) Backs up vouchers to private user storage.booleanChecks if a voucher exists in the public ledger.issue(@NonNull IssueVoucherRequest request) Issues a new voucher.queryStatus(@NonNull String voucherId) Queries the current status of a voucher from the public ledger.Restores vouchers from private user storage.voidupdateStatus(@NonNull String voucherId, @NonNull VoucherStatus newStatus) Updates the status of a voucher in the public ledger.
-
Constructor Details
-
VoucherService
public VoucherService(@NonNull @NonNull VoucherLedgerPort ledgerPort, @NonNull @NonNull VoucherBackupPort backupPort, @NonNull @NonNull String mintIssuerPrivateKey, @NonNull @NonNull String mintIssuerPublicKey) Constructs a VoucherService with the required dependencies.- Parameters:
ledgerPort- the port for public ledger operations (must not be null)backupPort- the port for private backup operations (must not be null)mintIssuerPrivateKey- the mint's private key for signing vouchers (hex-encoded, must not be null)mintIssuerPublicKey- the mint's public key for voucher verification (hex-encoded, must not be null)
-
-
Method Details
-
issue
Issues a new voucher.This method performs the following operations:
- Calculates expiry timestamp (if specified)
- Creates a VoucherSecret with the provided parameters
- Signs the voucher with the mint's private key
- Publishes the voucher to the public ledger with ISSUED status
- Serializes to Cashu token format
- Returns response with voucher and token
- Parameters:
request- the voucher issuance request (must not be null)- Returns:
- the issuance response containing the voucher and token
- Throws:
IllegalArgumentException- if request parameters are invalidRuntimeException- if signing or publishing fails
-
queryStatus
Queries the current status of a voucher from the public ledger.- Parameters:
voucherId- the unique voucher identifier (must not be null or blank)- Returns:
- the current status, or empty if voucher not found in ledger
- Throws:
IllegalArgumentException- if voucherId is null or blankRuntimeException- if ledger query fails
-
updateStatus
public void updateStatus(@NonNull @NonNull String voucherId, @NonNull @NonNull VoucherStatus newStatus) Updates the status of a voucher in the public ledger.This method records a state transition in the ledger. Common transitions:
- ISSUED → REDEEMED
- ISSUED → REVOKED
- ISSUED → EXPIRED
- 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 ledger update fails
-
backup
public void backup(@NonNull @NonNull List<SignedVoucher> vouchers, @NonNull @NonNull String userPrivateKey) Backs up vouchers to private user storage.This method encrypts and stores the vouchers in a way that only the user can retrieve them using their private key.
- Parameters:
vouchers- the list of vouchers to backup (must not be null, can be empty)userPrivateKey- the user's private key for encryption (must not be null or blank)- Throws:
IllegalArgumentException- if parameters are invalidRuntimeException- if backup fails
-
restore
Restores vouchers from private user storage.This method retrieves and decrypts all voucher backups associated with the user's private key.
- Parameters:
userPrivateKey- the user's private key for decryption (must not be null or blank)- Returns:
- list of restored vouchers (never null, but may be empty)
- Throws:
IllegalArgumentException- if userPrivateKey is invalidRuntimeException- if restore fails
-
exists
Checks if a voucher exists in the public ledger.- 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 ledger query fails
-