Skip to content
Discussions/App Development/How can I "Listen" to the TransactionTree in JavaForum ↗

How can I "Listen" to the TransactionTree in Java

App Development7 posts308 viewsLast activity Mar 2023
CO
cohen.avrahamOP
Mar 2023

G-d willing

Looking at the PingPong example, can someone please address me to the component that actually subscribes in order to listen to the Daml events? How is it being done exactly?

Thanks,

CO
cocreature
Mar 2023

The part that subscribes to transactions can be found here.

It calls the GetTransactions endpoint which returns a stream and then the onNext method will be called for each stream element.

CO
cohen.avraham
Mar 2023

Thanks @cocreature
And isn’t supposed to be a filter for specific templates that are visible to particular parties? Where is that being set?

CO
cocreature
Mar 2023

It’s set here ex-java-bindings/PingPongProcessor.java at 89052898bbdf9828f08ea039c87095bf65bf679b · digital-asset/ex-java-bindings · GitHub. The filter being used here does not restrict the templates so it will return all contracts visible to party regardless of the template.

CO
cohen.avraham
Mar 2023

G-d willing

So, if I am getting that correctly, I first need to define the request for the “listener” and then activate the listener according to it. Right?

Last, how can I restrict by template?

CO
cocreature
Mar 2023

I wouldn’t define it as two steps, in the end you make a single call to getTransactions and pass two arguments:

  1. Your request, which defines mainly filters and offsets.
  2. Your streamobserver which will get called for each element in the response.

To filter by templates replace the Filters.defaultInstance with something like this:

        TransactionFilterOuterClass.InclusiveFilters.newBuilder()
            .addAllTemplateIds(templateIds)
            .build();
        TransactionFilterOuterClass.Filters.newBuilder().setInclusive(inclusiveFilter).build()
CO
cohen.avraham
Mar 2023

Thanks @cocreature for the answer.
Regarding the two steps, it’s because in the code it is being done in 2 steps as well.
The step, which is defining the request with the filters, is the first one:

        GetTransactionsRequest transactionsRequest = GetTransactionsRequest.newBuilder()
                .setLedgerId(ledgerId)
                .setBegin(LedgerOffset.newBuilder().setBoundary(LedgerBoundary.LEDGER_BEGIN))
                // we use the default filter since we don't want to filter out any contracts
                .setFilter(TransactionFilter.newBuilder().putFiltersByParty(party, Filters.getDefaultInstance()))
                .setVerbose(true)
                .build();

And the second step is creating the observer stream:

        // this StreamObserver reacts to transactions and prints a message if an error occurs or the stream gets closed
        StreamObserver<GetTransactionsResponse> transactionObserver = new StreamObserver<GetTransactionsResponse>() {
            @Override
            public void onNext(GetTransactionsResponse value) {
                value.getTransactionsList().forEach(PingPongProcessor.this::processTransaction);
            }

            @Override
            public void onError(Throwable t) {
                System.err.printf("%s encountered an error while processing transactions!\n", party);
                t.printStackTrace();
            }

            @Override
            public void onCompleted() {
                System.out.printf("%s's transactions stream completed.\n", party);
            }
        };
← Back to Discussions