How to Calculate Transaction Hash for Ledger Canister's query_blocks in JavaScript?

I’m currently working with the Internet Computer’s Ledger Canister and utilizing the query_blocks function to fetch transaction details. However, I noticed that the returned data lacks the transaction hash, which is readily visible on the Internet Computer Dashboard(

After doing some research, I came across references to the calculation of the transaction hash in the Rosetta API Rust implementation. However, my project is in JavaScript, and I need a JavaScript solution to calculate the transaction hash.

I was wondering if there is a JavaScript implementation of this transaction hash calculation or a straightforward approach to achieve this? Any guidance or code samples would be greatly appreciated.

Thank you in advance for your help!


Comrades, have you found a way?

I am running into the same issue. I would like to store the transaction hash for ckBTC transfers to validate a successful on chain transaction, but afaik the ledger canister methods don’t return the transaction hash, instead it returns the index.

If everything goes well during the submission of the transaction then there is no need to “validate a successful transaction” because the moment you have the index that is returned it means the transaction is already successfully and irrevocably executed. If it wasn’t then you wouldn’t have an index.

If your question is about what to do with half-finished submissions where you application crashed in the middle of the submission and now you want to determine if it was successful or not then the answer is a little more complicated. Then there could be an index but you don’t have it.

If that scenario is a concern for you then you have to look at this explanation for deduplication: ICRC-1/standards/ICRC-1 at main · dfinity/ICRC-1 · GitHub
You have to do deduplication yourself and you have two fields in the transaction available for it that you can choose freely. They are created_at and memo. The ledger deduplicates based on them, i.e. no combination of them can appear twice. So in terms of uniqueness you can think of these fields as a “transaction hash” that you can choose yourself. Unfortunately, not in terms of searchability though. To determine if your transaction was successful you have to search for it based on account first and then you get a list and then you have to search for your created_at and memo in that list.

There is another scenario that applies if you think your application can crash but you are sure it will be back up within 5 minutes. Then you can use the IC’s request id to recover. The request id behaves more like the traditional transaction hash that you are used to but is only useful for 5 minutes because after that the IC will forget about it. If that scenario is of interest then I can elaborate on it as well.

Based on the accepted answer here How to get the hash of Block and Transaction (which you probably already saw during your research) my conclusion is that there is no javascript implementation available and it seems somewhat pointless to try making one. The reason is that transaction hashes (and block hashes) are legacy stuff and ICP-ledger-only. Everything has moved to ICRC-1 and even the ICP-ledger has a dual interface. So anything produced for the ICP ledger’s transaction hashes would remain isolated to the ICP ledger.

You need to take a representationally independent hash of the trx data. You can follow the hashing algo in code in the Mops⠀•⠀Motoko Package Manager library. An implementation of it in an actual icrc3 context can be found here: Mops⠀•⠀Motoko Package Manager

Hey @timo,

Yeah, you are spot on. My question is for the case where the application crashed during submission and there could be an index, but I don’t have it.

Ok, in the case of index not being returned. To confirm deduplication, search through account and look at the transactions created_at and memo.

Thank you again for the guidance. This really helpful.


1 Like