@Override
  public List<APITransaction> getInputTransactions(TID txId) throws BCSAPIException {
    log.trace("get input transactions " + txId);
    ConnectorMessage m;
    try (ConnectorSession session = connection.createSession()) {
      ConnectorProducer transactionRequestProducer =
          session.createProducer(session.createQueue("inputTransactionsRequest"));

      m = session.createMessage();
      BCSAPIMessage.Hash.Builder builder = BCSAPIMessage.Hash.newBuilder();
      builder.addHash(ByteString.copyFrom(txId.unsafeGetArray()));
      m.setPayload(builder.build().toByteArray());
      byte[] response = synchronousRequest(session, transactionRequestProducer, m);
      if (response != null) {
        List<BCSAPIMessage.OPTIONAL_TX> txsList =
            BCSAPIMessage.TXS.parseFrom(response).getTxsList();
        List<APITransaction> txs = new ArrayList<>(txsList.size());
        for (BCSAPIMessage.OPTIONAL_TX tx : txsList) {
          if (tx.getIsNull()) {
            txs.add(null);
          } else {
            txs.add(APITransaction.fromProtobuf(tx.getTransaction()));
          }
        }
        return txs;
      }
    } catch (ConnectorException | HyperLedgerException | InvalidProtocolBufferException e) {
      throw new BCSAPIException(e);
    }

    return null;
  }
  @Override
  public void spendingTransactions(List<TID> tids, final TransactionListener listener)
      throws BCSAPIException {
    try (ConnectorSession session = connection.createSession()) {
      ConnectorMessage m = session.createMessage();

      ConnectorProducer scanAccountProducer =
          session.createProducer(session.createQueue("spendingTransactions"));
      BCSAPIMessage.Hash.Builder builder = BCSAPIMessage.Hash.newBuilder();
      for (TID tid : tids) {
        builder.addHash(ByteString.copyFrom(tid.unsafeGetArray()));
      }
      m.setPayload(builder.build().toByteArray());

      final ConnectorTemporaryQueue answerQueue = session.createTemporaryQueue();
      final ConnectorConsumer consumer = session.createConsumer(answerQueue);
      m.setReplyTo(answerQueue);
      final Semaphore ready = new Semaphore(0);
      consumer.setMessageListener(
          message -> {
            try {
              byte[] body = message.getPayload();
              if (body != null) {
                APITransaction t = APITransaction.fromProtobuf(BCSAPIMessage.TX.parseFrom(body));
                listener.process(t);
              } else {
                consumer.close();
                answerQueue.delete();
                ready.release();
              }
            } catch (ConnectorException | HyperLedgerException | InvalidProtocolBufferException e) {
              log.error("Malformed message received for spendingt ransactions request", e);
            }
          });

      scanAccountProducer.send(m);
      ready.acquireUninterruptibly();
    } catch (ConnectorException e) {
      throw new BCSAPIException(e);
    }
  }
  @Override
  public APITransaction getTransaction(TID hash) throws BCSAPIException {
    log.trace("get transaction " + hash);
    ConnectorMessage m;
    try (ConnectorSession session = connection.createSession()) {
      ConnectorProducer transactionRequestProducer =
          session.createProducer(session.createQueue("transactionRequest"));

      m = session.createMessage();
      BCSAPIMessage.Hash.Builder builder = BCSAPIMessage.Hash.newBuilder();
      builder.addHash(ByteString.copyFrom(hash.unsafeGetArray()));
      m.setPayload(builder.build().toByteArray());
      byte[] response = synchronousRequest(session, transactionRequestProducer, m);
      if (response != null) {
        APITransaction t;
        t = APITransaction.fromProtobuf(BCSAPIMessage.TX.parseFrom(response));
        return t;
      }
    } catch (ConnectorException | HyperLedgerException | InvalidProtocolBufferException e) {
      throw new BCSAPIException(e);
    }

    return null;
  }