import { isSolanaError, SVM_SLOT_SKIPPED, SVM_LONG_TERM_STORAGE_SLOT_SKIPPED, SVM_TRANSACTION_PREFLIGHT_FAILURE, } from "../../arch/svm";
/**
 * Render an RPC error for log/wrap messages. For SolanaErrors, includes the numeric JSON-RPC
 * code alongside the server message; otherwise falls back to stack/toString.
 */
export function formatRpcError(error) {
    if (isSolanaError(error)) {
        const { __code: code, __serverMessage: serverMessage } = error.context;
        const message = serverMessage ?? error.message ?? "";
        return `SolanaError [${code}]: ${message}`;
    }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    return error?.stack || error?.toString?.() || String(error);
}
/**
 * Determine whether a Solana RPC error indicates an unrecoverable error that should not be retried.
 * @param method RPC method name.
 * @param error Error object from the RPC call.
 * @returns True if the request should be aborted immediately, otherwise false.
 */
export function shouldFailImmediate(method, error) {
    if (!isSolanaError(error)) {
        return false;
    }
    // JSON-RPC errors: https://www.quicknode.com/docs/solana/error-references
    const { __code: code } = error.context;
    switch (method) {
        case "getBlock":
        case "getBlockTime":
            // No block at the requested slot. This may not be correct for blocks > 1 year old.
            return [SVM_SLOT_SKIPPED, SVM_LONG_TERM_STORAGE_SLOT_SKIPPED].includes(code);
        case "sendTransaction":
            // Preflight failures are deterministic across providers; falling back only succeeds on RPCs that skip preflight.
            return code === SVM_TRANSACTION_PREFLIGHT_FAILURE;
        default:
            return false;
    }
}
/**
 * Subset of `shouldFailImmediate` for errors that are deterministic *across the entire network*,
 * not just for the provider that returned them. Used to decide whether to skip fallback providers
 * after a required provider rejects.
 *
 * Excludes SVM_LONG_TERM_STORAGE_SLOT_SKIPPED: that code can mean "the slot is missing from this
 * provider's long-term storage" rather than "the slot was skipped on the network", so an archival
 * fallback may still be able to answer.
 */
export function isChainWideFailure(method, error) {
    if (!isSolanaError(error)) {
        return false;
    }
    const { __code: code } = error.context;
    switch (method) {
        case "getBlock":
        case "getBlockTime":
            return code === SVM_SLOT_SKIPPED;
        case "sendTransaction":
            return code === SVM_TRANSACTION_PREFLIGHT_FAILURE;
        default:
            return false;
    }
}
//# sourceMappingURL=utils.js.map