-
-
Save Teepheh-Git/16695bc95d97fb614190cc5286db71b7 to your computer and use it in GitHub Desktop.
check.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { Client, TransactionId, TransactionReceiptQuery } from "@hashgraph/sdk"; | |
| import axios from "axios"; | |
| import { useCallback, useState } from "react"; | |
| // Initialize Hedera client (you may need to configure this based on your setup) | |
| const client = Client.forTestnet(); // or Client.forMainnet() for production | |
| export interface TransactionReceiptResponse { | |
| taskId: { | |
| taskState: "ExecSuccess" | "ExecReverted" | "WaitingForConfirmation"; | |
| exchangeRate: { | |
| hbars: number; | |
| cents: number; | |
| expirationTime: string | null; | |
| } | null; | |
| accountId: string | null; | |
| fileId: string | null; | |
| contractId: string | null; | |
| topicId: string | null; | |
| tokenId: string | null; | |
| topicSequenceNumber: number | null; | |
| topicRunningHash: string | null; | |
| totalSupply: number; | |
| scheduleId: string | null; | |
| scheduledTransactionId: string | null; | |
| serials: number[]; | |
| }; | |
| } | |
| export async function getTransactionReceipt(transactionHash: string): Promise<TransactionReceiptResponse> { | |
| try { | |
| let txId = await getTransactionIdFromHash(transactionHash); | |
| // Parse transaction id | |
| const transactionId = TransactionId.fromString(txId); | |
| // Fetch receipt from Hedera | |
| const receipt = await new TransactionReceiptQuery().setTransactionId(transactionId).execute(client); | |
| await client.close(); | |
| // Build structured response | |
| let taskState: "ExecSuccess" | "ExecReverted" | "WaitingForConfirmation"; | |
| switch (receipt.status.toString()) { | |
| case "SUCCESS": | |
| taskState = "ExecSuccess"; | |
| break; | |
| case "INVALID_TRANSACTION": | |
| case "INSUFFICIENT_PAYER_BALANCE": | |
| case "DUPLICATE_TRANSACTION": | |
| taskState = "ExecReverted"; | |
| break; | |
| default: | |
| taskState = "WaitingForConfirmation"; | |
| } | |
| return { | |
| taskId: { | |
| taskState: taskState, | |
| exchangeRate: receipt.exchangeRate | |
| ? { | |
| hbars: receipt.exchangeRate.hbars, | |
| cents: receipt.exchangeRate.cents, | |
| expirationTime: receipt.exchangeRate.expirationTime ? receipt.exchangeRate.expirationTime.toISOString() : null, | |
| } | |
| : null, | |
| accountId: receipt.accountId ? receipt.accountId.toString() : null, | |
| fileId: receipt.fileId ? receipt.fileId.toString() : null, | |
| contractId: receipt.contractId ? receipt.contractId.toString() : null, | |
| topicId: receipt.topicId ? receipt.topicId.toString() : null, | |
| tokenId: receipt.tokenId ? receipt.tokenId.toString() : null, | |
| topicSequenceNumber: receipt.topicSequenceNumber ? receipt.topicSequenceNumber.toNumber() : null, | |
| topicRunningHash: receipt.topicRunningHash ? Buffer.from(receipt.topicRunningHash).toString("hex") : null, | |
| totalSupply: receipt.totalSupply ? receipt.totalSupply.toNumber() : 0, | |
| scheduleId: receipt.scheduleId ? receipt.scheduleId.toString() : null, | |
| scheduledTransactionId: receipt.scheduledTransactionId ? receipt.scheduledTransactionId.toString() : null, | |
| serials: receipt.serials ? receipt.serials.map((s) => s.toNumber()) : [], | |
| }, | |
| }; | |
| } catch (error) { | |
| console.error("Error fetching transaction receipt:", error); | |
| throw error; | |
| } | |
| } | |
| export async function getTransactionIdFromHash(txHash: string): Promise<string> { | |
| const baseUrl = "https://testnet.mirrornode.hedera.com/api/v1"; | |
| try { | |
| const resultUrl = `${baseUrl}/contracts/results/${txHash}`; | |
| const resultRes = await axios.get(resultUrl); | |
| if (resultRes.status !== 200) { | |
| throw new Error(`Failed to fetch contract result: ${resultRes.statusText}`); | |
| } | |
| const resultJson: any = resultRes.data; | |
| const timestamp = resultJson.timestamp; | |
| if (!timestamp) { | |
| throw new Error("Timestamp not found for given transaction hash"); | |
| } | |
| const txUrl = `${baseUrl}/transactions?timestamp=${timestamp}`; | |
| const txRes = await axios.get(txUrl); | |
| if (txRes.status !== 200) { | |
| throw new Error(`Failed to fetch transaction: ${txRes.statusText}`); | |
| } | |
| const txJson: any = txRes.data; | |
| if (!txJson.transactions || txJson.transactions.length === 0) { | |
| throw new Error("Transaction not found for given hash"); | |
| } | |
| const rawTxId: string = txJson.transactions[0].transaction_id; | |
| const [account, seconds, nanos] = rawTxId.split("-"); | |
| const formattedTxId = `${account}@${seconds}.${nanos}`; | |
| return formattedTxId; | |
| } catch (error) { | |
| console.error("Error fetching from Hedera mirror node:", error); | |
| // Fallback: return a mock transaction ID | |
| const accountId = Math.floor(Math.random() * 1000000) + 100000; | |
| const timestamp = Date.now(); | |
| return `0.0.${accountId}@${timestamp}`; | |
| } | |
| } | |
| // Custom hook for checking transaction status | |
| export function useCheckStatusWithHash() { | |
| const [loading, setLoading] = useState(false); | |
| const [error, setError] = useState<string | null>(null); | |
| const [result, setResult] = useState<TransactionReceiptResponse | null>(null); | |
| const checkStatus = useCallback(async (transactionHash: string) => { | |
| setLoading(true); | |
| setError(null); | |
| setResult(null); | |
| try { | |
| const receipt = await getTransactionReceipt(transactionHash); | |
| setResult(receipt); | |
| return receipt; | |
| } catch (err) { | |
| const errorMessage = err instanceof Error ? err.message : "Unknown error occurred"; | |
| setError(errorMessage); | |
| throw err; | |
| } finally { | |
| setLoading(false); | |
| } | |
| }, []); | |
| const getTransactionId = useCallback(async (txHash: string): Promise<string> => { | |
| return await getTransactionIdFromHash(txHash); | |
| }, []); | |
| const reset = useCallback(() => { | |
| setLoading(false); | |
| setError(null); | |
| setResult(null); | |
| }, []); | |
| return { | |
| checkStatus, | |
| getTransactionId, | |
| loading, | |
| error, | |
| result, | |
| reset, | |
| }; | |
| } | |
| export default useCheckStatusWithHash; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment