import { encoding, toChainId } from "@wormhole-foundation/sdk-base";
import { deserialize, } from "@wormhole-foundation/sdk-definitions";
import axios from "axios";
import { retry } from "./tasks";
export const WHSCAN_RETRY_INTERVAL = 2000;
/**
 * Gets the bytes of a VAA for a given WormholeMessageId or `null` if the VAA is not available yet.
 * @param apiUrl the url of the wormholescan API
 * @param whm the WormholeMessageId
 * @returns a Uint8Array containing the VAA or `null` if it's not available yet
 * @throws Errors if the service throws an unrecoverable error (e.g. 500)
 */
export async function getVaaBytes(apiUrl, whm) {
    const { chain, emitter, sequence } = whm;
    const chainId = toChainId(chain);
    const emitterAddress = encoding.stripPrefix("0x", emitter.toString());
    const url = `${apiUrl}/v1/signed_vaa/${chainId}/${emitterAddress}/${sequence}`;
    try {
        const { data: { vaaBytes }, } = await axios.get(url);
        return encoding.b64.decode(vaaBytes);
    }
    catch (error) {
        if (!error)
            return null;
        if (typeof error === "object") {
            // A 404 error means the VAA is not yet available
            // since its not available yet, we return null signaling it can be tried again
            if (axios.isAxiosError(error) && error.response?.status === 404)
                return null;
            if ("status" in error && error.status === 404)
                return null;
        }
        throw error;
    }
}
export async function getVaaBytesWithRetry(apiUrl, whm, timeout) {
    const task = () => getVaaBytes(apiUrl, whm);
    return await retry(task, WHSCAN_RETRY_INTERVAL, timeout, "Wormholescan:GetVaaBytes");
}
export async function getVaa(apiUrl, whm, decodeAs) {
    const vaaBytes = await getVaaBytes(apiUrl, whm);
    if (!vaaBytes)
        return null;
    return deserialize(decodeAs, vaaBytes);
}
export async function getVaaWithRetry(apiUrl, whm, decodeAs, timeout) {
    const task = () => getVaa(apiUrl, whm, decodeAs);
    return await retry(task, WHSCAN_RETRY_INTERVAL, timeout, "Wormholescan:GetVaaBytes");
}
/**
 * Gets the status for a transaction given WormholeMessageId or `null` if the VAA is not available yet.
 * @param rpcUrl the url of the wormholescan API
 * @param whm the WormholeMessageId
 * @returns a TransactionStatus or `null` if it's not available yet
 * @throws Errors if the service throws an unrecoverable error (e.g. 500)
 */
export async function getTransactionStatus(rpcUrl, whm) {
    const { chain, emitter, sequence } = whm;
    const chainId = toChainId(chain);
    const emitterAddress = emitter.toUniversalAddress().toString();
    const url = `${rpcUrl}/api/v1/transactions/${chainId}/${emitterAddress}/${sequence}`;
    try {
        const response = await axios.get(url);
        return response.data;
    }
    catch (error) {
        if (!error)
            return null;
        if (typeof error === "object") {
            // A 404 error means the VAA is not yet available
            // since its not available yet, we return null signaling it can be tried again
            if (axios.isAxiosError(error) && error.response?.status === 404)
                return null;
            if ("status" in error && error.status === 404)
                return null;
        }
        throw error;
    }
}
export async function getTransactionStatusWithRetry(rpcUrl, whm, timeout) {
    const task = () => getTransactionStatus(rpcUrl, whm);
    return await retry(task, WHSCAN_RETRY_INTERVAL, timeout, "Wormholescan:GetTransactionStatus");
}
export async function getRelayStatus(rpcUrl, txid) {
    const url = `${rpcUrl}/v1/relays?txHash=${txid}`;
    try {
        const response = await axios.get(url);
        if (response.data.data.to.txHash)
            return response.data.data;
    }
    catch (error) {
        if (!error)
            return null;
        if (typeof error === "object") {
            // A 404 error means the VAA is not yet available
            // since its not available yet, we return null signaling it can be tried again
            if (axios.isAxiosError(error) && error.response?.status === 404)
                return null;
            if ("status" in error && error.status === 404)
                return null;
        }
        throw error;
    }
    return null;
}
export async function getRelayStatusWithRetry(rpcUrl, txid, timeout) {
    const task = () => getRelayStatus(rpcUrl, txid);
    return retry(task, WHSCAN_RETRY_INTERVAL, timeout, "Wormholescan:GetRelayStatus");
}
export async function getVaaByTxHash(rpcUrl, txid) {
    const url = `${rpcUrl}/api/v1/vaas?txHash=${txid}`;
    try {
        const response = await axios.get(url);
        if (response.data.data.length > 0)
            return response.data.data[0];
    }
    catch (error) {
        if (!error)
            return null;
        if (typeof error === "object") {
            // A 404 error means the VAA is not yet available
            // since its not available yet, we return null signaling it can be tried again
            if (axios.isAxiosError(error) && error.response?.status === 404)
                return null;
            if ("status" in error && error.status === 404)
                return null;
        }
        throw error;
    }
    return null;
}
export async function getVaaByTxHashWithRetry(rpcUrl, txid, decodeAs, timeout) {
    const task = () => getVaaByTxHash(rpcUrl, txid);
    const vaa = await retry(task, WHSCAN_RETRY_INTERVAL, timeout, "Wormholescan:GetVaaByTxHash");
    if (!vaa)
        return null;
    return deserialize(decodeAs, encoding.b64.decode(vaa.vaa));
}
export async function getTxsByAddress(rpcUrl, address, pageSize = 50, page = 0) {
    const url = `${rpcUrl}/api/v1/transactions?address=${address}&pageSize=${pageSize}&page=${page}`;
    try {
        const response = await axios.get(url);
        if (response.data.transactions.length > 0)
            return response.data.transactions;
    }
    catch (error) {
        if (!error)
            return null;
        if (typeof error === "object") {
            // A 404 error means the VAA is not yet available
            // since its not available yet, we return null signaling it can be tried again
            if (axios.isAxiosError(error) && error.response?.status === 404)
                return null;
            if ("status" in error && error.status === 404)
                return null;
        }
        throw error;
    }
    return null;
}
export async function getGuardianHeartbeats(rpcUrl) {
    const url = `${rpcUrl}/v1/heartbeats`;
    try {
        const response = await axios.get(url);
        if (response.data && response.data.entries.length > 0)
            return response.data.entries;
    }
    catch { }
    return null;
}
//# sourceMappingURL=whscan-api.js.map