Turning the asynchronous transaction announcement into synchronous

Turn asynchronous transaction announcement into synchronous with nem2-camel.


Alice is developing an app to send 10 cat.currency to Bob. She wants to know if the transaction has reached the network before sending Bob an email.

When announcing a transaction in NIS1, you had to wait to get the response from the node. Catapult works differently. When a transaction is announced, the REST API server will always return an OK.

As a result, the developer does not have to wait until the server returns a response, being able to make more responsive apps. However, it is the developer’s responsibility to check the status of the transaction and ensure it is confirmed.

On the other hand, keeping track of transactions status adds unnecessary complexity to small projects. It also increases the difficulty when migrating from NIS1.

nem2-camel aims to solve these problems by providing a server that listens to the Catapult REST calls and acts as a proxy. When it detects a transaction announcement, it waits for the confirmation via WebSockets and returns the message to the HTTP call.


The function TransactionHttp.announceSync allows announcing transactions synchronously when using nem2-camel as a proxy. nem2-camel will respond successfully when the transaction has reached the network and had no validation errors. You might still need to wait for several confirmations before executing additional actions.



Let’s get into some code

Running Catapult Service in local

For development and learning purposes, you can run the Catapult Server and Catapult REST using the Catapult Service Bootstrap.

  1. Make sure you have docker and docker compose installed before running the following instructions:
git clone git@github.com:tech-bureau/catapult-service-bootstrap.git
cd catapult-service-bootstrap
docker-compose up
  1. If everything goes well, after the image has been downloaded and the service is running, check if you can get the first block information:
curl localhost:3000/block/1

Getting Alice and Bob addresses

Once the Catapult Service is running, it will generate a set of accounts containing cat.currency.

  1. Find the key pairs which contain cat.currency under the section nemesis_addresses.
cd  build/generated-addresses/
cat raw-addresses.yaml
  1. Take the first key pair as Alice’s account, and copy the private key.
  2. Take the second key pair as Bob’s account, and copy the address.

Installing nem2-camel

nem2-camel acts like a proxy between the application and the REST API.


nem2-camel requires at least Java version 8.

  1. Download the latest nem2-camel jar package release, and run:
java -jar nem2-camel.jar --url http://localhost:3000
  1. After the service is up, use as the new proxy url.

Sending the transfer transaction

  1. Alice creates a Transfer Transaction, sending 10 cat.currency to Bob.
const recipientAddress =  Address.createFromRawAddress('SBHEVGUFDEW22FAT2EFU6UYXRKLTC6HFOPB4CRSE');

const transferTransaction = TransferTransaction.create(

const privateKey = process.env.PRIVATE_KEY as string;
const account = Account.createFromPrivateKey(privateKey,NetworkType.MIJIN_TEST);
const networkGenerationHash = process.env.NETWORK_GENERATION_HASH as string;
const signedTransaction = account.sign(transferTransaction, networkGenerationHash);
  1. Once signed, Alice announces the transaction. Use TransactionHttp.announceSync instead of TransactionHttp.announce to wait until the transaction reaches the network, returning back the Transaction object.
const transactionHttp = new TransactionHttp('');

    .subscribe(x => {
        // TODO: send email to Bob
    err => {

It is important to highlight that this transaction has an unconfirmed status. You might still need to wait for several confirmations before doing additional actions.

In case the Catapult REST server throws an error, the subscribe method will invoke the error function returning a TransactionStatus object.