- React
- Browser SDK
- React Native
Report incorrect code
Copy
Ask AI
import { Connection } from "@solana/web3.js";
import { useEffect, useState } from "react";
type TransactionStatus = "pending" | "confirmed" | "finalized" | "failed";
function TransactionStatus({ signature }: { signature: string }) {
const [status, setStatus] = useState<TransactionStatus>("pending");
const [transaction, setTransaction] = useState<any>(null);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const connection = new Connection("https://api.mainnet-beta.solana.com");
const checkStatus = async () => {
try {
// Get transaction status
const txStatus = await connection.getSignatureStatus(signature);
if (txStatus.value?.err) {
setStatus("failed");
setError(JSON.stringify(txStatus.value.err));
return;
}
if (txStatus.value?.confirmationStatus === "finalized") {
setStatus("finalized");
} else if (txStatus.value?.confirmationStatus === "confirmed") {
setStatus("confirmed");
} else {
setStatus("pending");
}
// Get full transaction details
const txDetails = await connection.getTransaction(signature, {
maxSupportedTransactionVersion: 0,
});
setTransaction(txDetails);
} catch (err) {
setError(err instanceof Error ? err.message : "Unknown error");
}
};
// Check immediately
checkStatus();
// Poll every 2 seconds until finalized
const interval = setInterval(() => {
if (status !== "finalized" && status !== "failed") {
checkStatus();
} else {
clearInterval(interval);
}
}, 2000);
return () => clearInterval(interval);
}, [signature, status]);
return (
<div>
<h3>Transaction Status</h3>
<p>
<strong>Signature:</strong> {signature}
</p>
<p>
<strong>Status:</strong> {status}
</p>
{error && <p style={{ color: "red" }}>Error: {error}</p>}
{transaction && (
<div>
<p>
<strong>Slot:</strong> {transaction.slot}
</p>
<p>
<strong>Block Time:</strong>{" "}
{transaction.blockTime
? new Date(transaction.blockTime * 1000).toLocaleString()
: "N/A"}
</p>
<a
href={`https://explorer.solana.com/tx/${signature}`}
target="_blank"
rel="noopener noreferrer"
>
View on Explorer
</a>
</div>
)}
</div>
);
}
// Usage
function SendTransaction() {
const [txSignature, setTxSignature] = useState<string | null>(null);
const sendTx = async () => {
// ... send transaction logic
// const { hash } = await solana.signAndSendTransaction(transaction);
// setTxSignature(hash);
};
return (
<div>
<button onClick={sendTx}>Send Transaction</button>
{txSignature && <TransactionStatus signature={txSignature} />}
</div>
);
}
Report incorrect code
Copy
Ask AI
import { Connection } from "@solana/web3.js";
type TransactionStatus = "pending" | "confirmed" | "finalized" | "failed";
async function checkTransactionStatus(
signature: string,
connection: Connection
): Promise<{ status: TransactionStatus; transaction: any; error?: string }> {
try {
const txStatus = await connection.getSignatureStatus(signature);
if (txStatus.value?.err) {
return {
status: "failed",
transaction: null,
error: JSON.stringify(txStatus.value.err),
};
}
let status: TransactionStatus = "pending";
if (txStatus.value?.confirmationStatus === "finalized") {
status = "finalized";
} else if (txStatus.value?.confirmationStatus === "confirmed") {
status = "confirmed";
}
const txDetails = await connection.getTransaction(signature, {
maxSupportedTransactionVersion: 0,
});
return { status, transaction: txDetails };
} catch (error) {
return {
status: "failed",
transaction: null,
error: error instanceof Error ? error.message : "Unknown error",
};
}
}
// Poll until finalized
async function waitForConfirmation(
signature: string,
connection: Connection,
maxAttempts: number = 30
): Promise<TransactionStatus> {
for (let i = 0; i < maxAttempts; i++) {
const { status } = await checkTransactionStatus(signature, connection);
if (status === "finalized" || status === "failed") {
return status;
}
// Wait 2 seconds before next check
await new Promise((resolve) => setTimeout(resolve, 2000));
}
return "pending"; // Timeout
}
// Usage
const connection = new Connection("https://api.mainnet-beta.solana.com");
const signature = "your-transaction-signature";
const finalStatus = await waitForConfirmation(signature, connection);
console.log(`Transaction ${finalStatus}`);
Report incorrect code
Copy
Ask AI
import { Connection } from "@solana/web3.js";
import { View, Text, StyleSheet, Linking, ActivityIndicator } from "react-native";
import { useEffect, useState } from "react";
type TransactionStatus = "pending" | "confirmed" | "finalized" | "failed";
function TransactionStatus({ signature }: { signature: string }) {
const [status, setStatus] = useState<TransactionStatus>("pending");
const [transaction, setTransaction] = useState<any>(null);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const connection = new Connection("https://api.mainnet-beta.solana.com");
const checkStatus = async () => {
try {
const txStatus = await connection.getSignatureStatus(signature);
if (txStatus.value?.err) {
setStatus("failed");
setError(JSON.stringify(txStatus.value.err));
return;
}
if (txStatus.value?.confirmationStatus === "finalized") {
setStatus("finalized");
} else if (txStatus.value?.confirmationStatus === "confirmed") {
setStatus("confirmed");
} else {
setStatus("pending");
}
const txDetails = await connection.getTransaction(signature, {
maxSupportedTransactionVersion: 0,
});
setTransaction(txDetails);
} catch (err) {
setError(err instanceof Error ? err.message : "Unknown error");
}
};
checkStatus();
const interval = setInterval(() => {
if (status !== "finalized" && status !== "failed") {
checkStatus();
} else {
clearInterval(interval);
}
}, 2000);
return () => clearInterval(interval);
}, [signature, status]);
return (
<View style={styles.container}>
<Text style={styles.title}>Transaction Status</Text>
<Text style={styles.signature}>{signature}</Text>
<Text style={styles.status}>Status: {status}</Text>
{error && <Text style={styles.error}>Error: {error}</Text>}
{status === "pending" && <ActivityIndicator size="small" />}
{transaction && (
<View style={styles.details}>
<Text>Slot: {transaction.slot}</Text>
<Text>
Block Time:{" "}
{transaction.blockTime
? new Date(transaction.blockTime * 1000).toLocaleString()
: "N/A"}
</Text>
<Text
style={styles.link}
onPress={() =>
Linking.openURL(`https://explorer.solana.com/tx/${signature}`)
}
>
View on Explorer
</Text>
</View>
)}
</View>
);
}
const styles = StyleSheet.create({
container: {
padding: 20,
},
title: {
fontSize: 20,
fontWeight: "bold",
marginBottom: 10,
},
signature: {
fontSize: 12,
color: "#666",
marginBottom: 10,
},
status: {
fontSize: 16,
fontWeight: "600",
marginBottom: 10,
},
error: {
color: "red",
marginTop: 10,
},
details: {
marginTop: 20,
padding: 15,
backgroundColor: "#f5f5f5",
borderRadius: 8,
},
link: {
color: "#0ea5e9",
marginTop: 10,
textDecorationLine: "underline",
},
});
Confirmation statuses
Solana transactions have three confirmation statuses:- Pending: Transaction has been submitted but not yet confirmed
- Confirmed: Transaction has been confirmed by the cluster (not yet finalized)
- Finalized: Transaction has been finalized and cannot be rolled back
Transactions are typically confirmed within 1-2 seconds and finalized within ~30 seconds on mainnet. Use “confirmed” status for most UI updates, and “finalized” for critical operations.