class PrivateTransactionLocator {

  public Optional<ExecutedPrivateTransaction> findByPmtHash(
      final Hash pmtHash, final String enclaveKey) {
    final Optional<TransactionLocation> maybePmtLocation =
        blockchain.getTransactionLocation(pmtHash);
    if (maybePmtLocation.isEmpty()) {
      return Optional.empty();
    }

    final TransactionLocation pmtLocation = maybePmtLocation.get();
    final Transaction pmt = blockchain.getTransactionByHash(pmtHash).orElseThrow();
    final BlockHeader blockHeader =
        blockchain.getBlockHeader(pmtLocation.getBlockHash()).orElseThrow();
    final String payloadKey = readPayloadKeyFromPmt(pmt);

    return tryFetchingPrivateTransactionFromEnclave(payloadKey, enclaveKey)
        .or(() -> tryFetchingTransactionFromAddBlob(blockHeader.getHash(), pmtHash, enclaveKey))
        .map(
            tx ->
                new ExecutedPrivateTransaction(
                    blockHeader.getHash(),
                    blockHeader.getNumber(),
                    pmt.getHash(),
                    pmtLocation.getTransactionIndex(),
                    tx.getInternalPrivacyGroupId(),
                    tx.getPrivateTransaction()));
  }

  public  PrivateTransactionLocator(
      final Blockchain blockchain,
      final Enclave enclave,
      final PrivateStateStorage privateStateStorage);

}