"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getUserOperationError = getUserOperationError;
const base_js_1 = require("../../../errors/base.js");
const contract_js_1 = require("../../../errors/contract.js");
const decodeErrorResult_js_1 = require("../../../utils/abi/decodeErrorResult.js");
const bundler_js_1 = require("../../errors/bundler.js");
const userOperation_js_1 = require("../../errors/userOperation.js");
const getBundlerError_js_1 = require("./getBundlerError.js");
function getUserOperationError(err, { calls, docsPath, ...args }) {
    const cause = (() => {
        const cause = (0, getBundlerError_js_1.getBundlerError)(err, args);
        if (calls && cause instanceof bundler_js_1.ExecutionRevertedError) {
            const revertData = getRevertData(cause);
            const contractCalls = calls?.filter((call) => call.abi);
            if (revertData && contractCalls.length > 0)
                return getContractError({ calls: contractCalls, revertData });
        }
        return cause;
    })();
    return new userOperation_js_1.UserOperationExecutionError(cause, {
        docsPath,
        ...args,
    });
}
function getRevertData(error) {
    let revertData;
    error.walk((e) => {
        const error = e;
        if (typeof error.data === 'string' ||
            typeof error.data?.revertData === 'string' ||
            (!(error instanceof base_js_1.BaseError) && typeof error.message === 'string')) {
            const match = (error.data?.revertData ||
                error.data ||
                error.message).match?.(/(0x[A-Za-z0-9]*)/);
            if (match) {
                revertData = match[1];
                return true;
            }
        }
        return false;
    });
    return revertData;
}
function getContractError(parameters) {
    const { calls, revertData } = parameters;
    const { abi, functionName, args, to } = (() => {
        const contractCalls = calls?.filter((call) => Boolean(call.abi));
        if (contractCalls.length === 1)
            return contractCalls[0];
        const compatContractCalls = contractCalls.filter((call) => {
            try {
                return Boolean((0, decodeErrorResult_js_1.decodeErrorResult)({
                    abi: call.abi,
                    data: revertData,
                }));
            }
            catch {
                return false;
            }
        });
        if (compatContractCalls.length === 1)
            return compatContractCalls[0];
        return {
            abi: [],
            functionName: contractCalls.reduce((acc, call) => `${acc ? `${acc} | ` : ''}${call.functionName}`, ''),
            args: undefined,
            to: undefined,
        };
    })();
    const cause = (() => {
        if (revertData === '0x')
            return new contract_js_1.ContractFunctionZeroDataError({ functionName });
        return new contract_js_1.ContractFunctionRevertedError({
            abi,
            data: revertData,
            functionName,
        });
    })();
    return new contract_js_1.ContractFunctionExecutionError(cause, {
        abi,
        args,
        contractAddress: to,
        functionName,
    });
}
//# sourceMappingURL=getUserOperationError.js.map