3

I need to reliably validate in an API whether a call to the Solana program made by a user has been successful. I use the confirmTransaction function (in devnet) as follows:

import { web3 } from "@project-serum/anchor";

const signature = program.rpc.programCall...
let connection = new web3.Connection(web3.clusterApiUrl('devnet'));
let confirmedTx = await connection.confirmTransaction(signature, "confirmed"); // sometimes return errors

// When I get an error here I reconnect and try again
connection = new web3.Connection(web3.clusterApiUrl('devnet'));
confirmedTx = await connection.confirmTransaction(signature, "confirmed"); // sometimes return errors

// If the error persists I reconnect to a quicknode node and try again
connection = new web3.Connection(web3.clusterApiUrl('https://name.solana-devnet.discover.quiknode.pro...'));
confirmedTx = await connection.confirmTransaction(signature, "confirmed"); // sometimes return errors

// If the error persists I assume that the tx was not completed and the program call was failed.

Is this a reliable way to check if the tx has been completed successfully? Is there another way to do this?

When the network is congested this way of confirming txs fails even if the tx was successful. Is there any way to confirm txs when the network is congested?

Thanks in advance :)

1
  • I believe the new VersionTransaction has better support for this, allowing you to see if the tx fails when a certain block height is reached. Example: ``` const connection = new Connection(clusterApiUrl("devnet"), "confirmed"); let latestBlockHash = await connection.getLatestBlockhash(); const instructions = [ SystemProgram.transfer({ fromPubkey: provider.wallet.publicKey, toPubkey: wallet.publicKey, lamports: 10 * LAMPORTS_PER_SOL, }), ]; const message = new TransactionMessage({ payerKey: provider.wallet.publicKey, recentBlockhash: latestBlockHash.blockhash, instructions, }).compileToV0Messag
    – Whiteseal
    Nov 30, 2022 at 18:49

2 Answers 2

2

Reliability

One of the major sources of transaction confirmation unreliability had to do with missing the signature status subscription notification for an otherwise confirmed transaction. This has been improved in @solana/web3.js 1.66.3. Now, the confirmation algorithm makes a point-in-time query for the signature status before treating its signature subscription as the source of truth. You can read all of the details of this upgrade, here.

Cancellation

As of version 1.69.0 of @solana/web3.js you now have an API to cancel ongoing transaction confirmations. If you would like to cancel (ie. stop waiting for) a pending confirmation, use an AbortController

const abortController = new AbortController();
try {
  await connection.confirmTransaction({
    abortSignal: abortController.signal,
    /* other confirmation parameters */
  });
} catch(e) {
  if (e.name === 'AbortError') {
    // The confirmation was manually aborted.
  }
}

…then some time later, you can abort the confirmation process by calling abort() on the controller.

abortController.abort();
0

Using new version of confirmTransaction

The problem with the new version of confirmTransaction (as far as I know) is that it will always wait 60 seconds if the signature is not correct (I can't afford this). Instead when using the deprecated version of confirmTransaction the timeout can be modified when creating the connection in the following way:

const connection = new web3.Connection( 
web3.clusterApiUrl('devnet'), 
{ confirmTransactionInitialTimeout: 5000 });

For this reason I use the deprecated version. I want to know if there is another, more reliable method of transaction validation. Is the method I use the right way to do it?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.