Monitoring Transaction Status⚓︎
After announcing a transaction to the Symbol network, it remains unconfirmed until it is included in a block.
Monitoring status changes is essential for building responsive applications that can react to transaction confirmation or failure.
This tutorial shows how to monitor a transaction's status as it moves from unconfirmed to confirmed.
Confirmed transactions can still be reversed
A confirmed transaction has been included in a block but is not yet irreversible. The final state is finalization, which occurs only after the block is finalized by the network. Until then, rollbacks are still possible.
Prerequisites⚓︎
This tutorial uses the Symbol REST API without requiring an SDK. You only need a way to make HTTP requests.
Full Code⚓︎
This tutorial uses polling to check the transaction status. Polling is used here for illustration purposes, but it is not the recommended approach for production applications. WebSockets provide a more responsive solution without the overhead of repeated API calls.
The snippet uses the NODE_URL environment variable to set the Symbol API node.
If no value is provided, a default one is used.
Code Explanation⚓︎
Finding the Transaction Hash⚓︎
To monitor a transaction, you need its hash, which is generated after signing. The hash uniquely identifies the transaction on the Symbol network.
This tutorial uses a sample transaction hash to demonstrate the monitoring.
You can provide your own hash by setting the TRANSACTION_HASH environment variable when running the code.
In practice, you would obtain this hash immediately after signing a transaction (see the Transfer tutorial for an example) and use it to track its status.
Querying the Status Endpoint⚓︎
The wait_for_transaction_confirmation function is the core of this tutorial.
It monitors a transaction until it is confirmed or fails.
It uses a for loop to check the transaction status up to 60 times by default (2 minutes with 2-second intervals
between attempts).
This loop structure ensures that monitoring will eventually stop, even if the transaction never confirms.
On each attempt, the function queries the /transactionStatus/{hash} GET endpoint, which returns information
about the transaction's current state.
The response includes:
-
Group: The transaction's current status group. Possible values:
Group Meaning unconfirmedThe transaction is in the unconfirmed pool waiting to be included in a block. confirmedThe transaction has been included in a block. failedThe transaction failed validation and has been rejected. partialFor bonded aggregate transactions waiting for cosignatures. -
Code: A status code providing more details (for example,
Successor specific error codes). See the TransactionStatusEnum schema for all possible values. - Hash: The transaction hash being monitored.
- Deadline: The transaction's deadline in network time.
The function displays all these fields on each polling attempt so you can see how the transaction progresses through states.
Checking for Confirmation⚓︎
After parsing the response, the function checks the group field.
If it is confirmed, the transaction was successfully included in a block through harvesting, and the function
returns successfully.
Checking for Failure⚓︎
If the transaction status group is failed, the function raises an error with the status code.
Common reasons include insufficient balance, invalid signatures, or deadline expiration. Failed transactions are rejected during validation and will not be included in a block.
See TransactionStatusEnum for all possible codes.
Handling Unknown Status⚓︎
If the endpoint returns HTTP 404, the transaction status is not yet available. This can happen immediately after announcing a transaction, before the node processes it, or if the hash is invalid. The function handles this case by logging the attempt and continuing to poll.
For any other error (such as connectivity issues or failed transactions), the function re-raises the exception immediately.
Waiting Between Attempts⚓︎
Between polling attempts, the function waits for a configurable delay (default: 2 seconds). This prevents overwhelming the node with requests and allows time for network processing.
Handling Timeouts⚓︎
If the transaction is not confirmed after the specified number of attempts, the function raises a RuntimeError
explaining the problem.
This ensures that the calling code is aware that the transaction didn't complete in the expected timeframe and can take appropriate action, such as:
- Retrying the transaction announcement
- Alerting the user
- Logging the issue for investigation
Output⚓︎
The following output shows a typical run monitoring a transaction as it moves from unconfirmed to confirmed:
Using node https://001-sai-dual.symboltest.net:3001
Monitoring transaction: 2B6D3B5232E06B9D32682F518C765301FCF9716BFA1EEEF9523653406E04C7EA
Waiting for transaction confirmation
Polling /transactionStatus/2B6D3B5232E06B9D32682F518C765301FCF9716BFA1EEEF9523653406E04C7EA
Attempt 1: Transaction status not yet available
Attempt 2: Transaction status not yet available
Attempt 3:
Status: unconfirmed
Code: Success
Hash: 2B6D3B5232E06B9D32682F518C765301FCF9716BFA1EEEF9523653406E04C7EA
Deadline: 47578965854
Attempt 4:
Status: unconfirmed
Code: Success
Hash: 2B6D3B5232E06B9D32682F518C765301FCF9716BFA1EEEF9523653406E04C7EA
Deadline: 47578965854
Attempt 5:
Status: confirmed
Code: Success
Hash: 2B6D3B5232E06B9D32682F518C765301FCF9716BFA1EEEF9523653406E04C7EA
Deadline: 47578965854
Transaction confirmed!
The output shows:
- The transaction hash being monitored.
- Multiple polling attempts showing the transaction status, code, hash, and deadline.
- The status changing from
unconfirmedtoconfirmedbetween attempts. - A success message when the transaction is confirmed.
The number of attempts and timing vary depending on network conditions and block production rate.
On the Symbol network, blocks are typically produced every 30 seconds, so you may see several unconfirmed status
responses before the transaction is confirmed.
Once confirmed, you can get additional details such as the block height where the transaction was included by querying
/transactions/confirmed/{transactionId} GET with the transaction hash.
To see the transaction from the network's perspective, visit the Symbol Testnet Explorer and search for the transaction hash.
Conclusion⚓︎
This tutorial showed how to:
| Step | Related documentation |
|---|---|
| Query the status endpoint | /transactionStatus/{hash} GET |
| Check for confirmation | TransactionStatusEnum |
| Check for failure | TransactionStatusEnum |
Next steps⚓︎
For production applications, consider these improvements:
- Wait for finalization: Verify that the block containing the transaction has been finalized
using
/finalization/proof/height/{height}GETto ensure it is truly irreversible. - Query multiple nodes: Check status and finalization across several nodes for greater reliability and protection against single-node issues.
- Use WebSockets: Replace polling with WebSocket subscriptions for real-time updates without repeated API calls.