Check Transaction State
This example demonstrates how to check the status of a blockchain transaction
public void CheckTransactionState()
{
// Initialize PhantasmaAPI instance
var api = new PhantasmaAPI("https://testnet.phantasma.info/rpc");
// Transaction hash to monitor
var txHash = "9749DCDAA37A53397AFB4EA30547C40BBF6ACC5B89B0234737C7A5AF71B0D4F2";
// Start coroutine that will keep checking the transaction status until it's complete or times out
StartCoroutine(CheckTxStateLoop(api, txHash, null));
}
// Coroutine that monitors the state of a transaction; invokes callback with status and result when complete.
// Callback is optional.
// If we could not determine state of tx, null will be passed as first callback argument
public static IEnumerator CheckTxStateLoop(PhantasmaAPI api, string txHash, Action<ExecutionState?, string, string> callback)
{
// Flag to stop polling loop once the transaction is finalized
bool done = false;
// Counter for how many times we've polled for transaction status
uint txStatusQueryAttempts = 0;
// Counter for how many times we've attempted to get failure debug details, if needed
uint failureDetailsQueryAttempts = 0;
while (!done)
{
// Make RPC call to fetch transaction info from the chain
yield return api.GetTransaction(txHash,
(txResult) =>
{
// Log the current execution state: Running, Halt (success), or other (failure)
Debug.Log($"Transaction state is: {txResult.State}");
switch (txResult.State)
{
case PhantasmaPhoenix.Protocol.ExecutionState.Running:
// Transaction is still being processed by the chain
Debug.Log("Transaction is still processing...");
break;
case PhantasmaPhoenix.Protocol.ExecutionState.Halt:
// Transaction completed successfully (execution halted without errors)
// Check if any result string is available (may be empty if not applicable)
if (string.IsNullOrEmpty(txResult.Result))
{
Debug.Log($"Transaction executed successfully, no result available.");
}
else
{
Debug.Log($"Transaction executed successfully with result '{txResult.Result}'.");
}
done = true;
// Notify success with result value and no error info
callback?.Invoke(txResult.State, txResult.Result, null);
break;
default:
// Transaction failed. We check if we have additional details about failure available.
// If failure details are not yet available, and we haven't tried too many times - wait and retry
if (txResult.DebugComment == null && failureDetailsQueryAttempts < 6)
{
// Inform user that we're retrying in case debug info hasn't yet been indexed on the node
Debug.Log($"Waiting for failure details... Attempt {failureDetailsQueryAttempts + 1}/6");
failureDetailsQueryAttempts++;
break;
}
// Final failure state reached, log failure details and return via callback
Debug.LogWarning($"Transaction failed with state: {txResult.State}. Result: {txResult.Result}. Details: {txResult.DebugComment}");
done = true;
// Notify failure with state, raw result, and debug comment if available
callback?.Invoke(txResult.State, txResult.Result, txResult.DebugComment);
break;
}
},
// Error handler for network or RPC-level errors
(errorCode, errorMessage) =>
{
// Log API error such as invalid hash, RPC timeout, etc
// "Transaction not found" also gets here
Debug.LogError($"[Error][{errorCode}] {errorMessage}");
});
// If still running (or DebugComment is unavailable), wait 1 second before checking again
if (!done)
{
// Stop retrying if status check exceeded max allowed attempts
if (txStatusQueryAttempts == 30)
{
Debug.LogWarning($"Query attempts exhausted after {txStatusQueryAttempts} attempts, tx state could not be confirmed");
// Notify that the transaction status could not be confirmed at all (timeout case)
callback?.Invoke(null, null, null);
break;
}
else
{
yield return new WaitForSeconds(1f);
txStatusQueryAttempts++;
}
}
}
}
Last updated