Safely Abandon Transactions on Solana: A How-to Guide

Nirvana
Nirvana Finance
2 min readJul 5, 2022

--

Using the process below you can safely tell your users unambiguously when their transaction was successful, failed or it was abandoned.

Ever had a transaction timeout that left you wondering if your transaction was successful or was dropped?

Did you accidentally duplicate your transaction because you thought the first transaction was abandoned when it actually just took longer than expected?

Well we have good news! You don’t need to live in uncertainty anymore!

Some Solana dapps have an arbitrary timeout after which the client gives up on the transaction without knowing if the transaction was ever processed. This leaves users in the uncomfortable position of having to put on a detective hat and figure out for themselves if they need to try again. This user then either:

  • Accidentally duplicates their transaction.
  • Waits for a long time to be more certain it was abandoned.
  • Gives up on the transaction altogether.

How do we avoid this? Solana 1.9 introduced two new APIs that allow you to check when your transaction is guaranteed to have expired: isBlockhashValid and getLatestBlockhash. You can use either of them to know when the blockhash included in your transaction is no longer valid.

If the transaction has not been confirmed by the time its blockhash expires then that transaction is guaranteed to be completely abandoned.

The client can:

  1. Send the transaction with the latest blockhash
  2. Wait for either a confirmation or for the blockhash to expire
  • If we get a confirmation then the transaction is complete
  • If the transaction blockhash expires then notify the user the transaction was unambiguously abandoned and they are free to try again if they please

Here’s a code snippet of how that looks in practice. First make sure you save the last valid block height when you create your transaction.

const tx = new Transaction()
const latest = await connection.getLatestBlockhash()
tx.recentBlockhash = lastest.blockhash
const lastValidBlockHeight = lastest.lastValidBlockHeight

Now build and send your transaction as you normally would. If the network goes past the last valid block height without confirmation, you can now safely abandon the transaction.

while (true) {
const blockheight = await connection.getBlockHeight()
const confirmed = await connection.getTransaction(txid)
if (confirmed) {
console.log('Transaction completed!')
break
}
if (blockheight > lastValidBlockHeight) {
console.log(‘Transaction abandoned. Please try again.’)
break
}
await sleep(500)
}

And now the uncertainty is gone! We hope this improves your user experience.

--

--

Nirvana
Nirvana Finance

NIRV / ANA are the unity of algorithmic wealth & stability.