"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRefundInformationFromFill = getRefundInformationFromFill;
exports.verifyFillRepayment = verifyFillRepayment;
const tslib_1 = require("tslib");
const lodash_1 = tslib_1.__importDefault(require("lodash"));
const assert_1 = tslib_1.__importDefault(require("assert"));
const ethers_1 = require("ethers");
const utils_1 = require("../../../utils");
function getRefundInformationFromFill(relayData, hubPoolClient, bundleEndBlockForMainnet) {
    const chainToSendRefundTo = _getRepaymentChainId(relayData, hubPoolClient, bundleEndBlockForMainnet);
    if (chainToSendRefundTo === relayData.originChainId) {
        return {
            chainToSendRefundTo,
            repaymentToken: relayData.inputToken,
        };
    }
    const l1TokenCounterpart = hubPoolClient.getL1TokenForL2TokenAtBlock(relayData.inputToken, relayData.originChainId, bundleEndBlockForMainnet);
    (0, assert_1.default)((0, utils_1.isDefined)(l1TokenCounterpart), "getRefundInformationFromFill: l1TokenCounterpart is undefined");
    const repaymentToken = hubPoolClient.getL2TokenForL1TokenAtBlock(l1TokenCounterpart, chainToSendRefundTo, bundleEndBlockForMainnet);
    (0, assert_1.default)((0, utils_1.isDefined)(repaymentToken), "getRefundInformationFromFill: repaymentToken is undefined");
    return {
        chainToSendRefundTo,
        repaymentToken,
    };
}
async function verifyFillRepayment(_fill, destinationChainProvider, matchedDeposit, hubPoolClient, bundleEndBlockForMainnet) {
    const fill = lodash_1.default.cloneDeep(_fill);
    if ((0, utils_1.isSlowFill)(fill)) {
        return fill;
    }
    let repaymentChainId = _getRepaymentChainId({
        ...fill,
        fromLiteChain: matchedDeposit.fromLiteChain,
    }, hubPoolClient, bundleEndBlockForMainnet);
    if (_repaymentAddressNeedsToBeOverwritten(fill)) {
        if ((0, utils_1.chainIsEvm)(fill.destinationChainId)) {
            (0, assert_1.default)(destinationChainProvider instanceof ethers_1.providers.Provider, `BundleDataClient#verifyFillRepayment: unexpected destination chain provider for chain ID ${fill.destinationChainId}`);
            const fillTransaction = await destinationChainProvider.getTransaction(fill.txnRef);
            const destinationRelayer = fillTransaction?.from;
            if (!(0, utils_1.isDefined)(destinationRelayer) || !(0, utils_1.isValidEvmAddress)(destinationRelayer)) {
                return undefined;
            }
            if (!matchedDeposit.fromLiteChain &&
                hubPoolClient.areTokensEquivalent(fill.inputToken, fill.originChainId, fill.outputToken, fill.destinationChainId)) {
                repaymentChainId = fill.destinationChainId;
            }
            else {
                if (!(0, utils_1.chainIsEvm)(repaymentChainId)) {
                    return undefined;
                }
            }
            fill.relayer = (0, utils_1.toAddressType)(destinationRelayer, fill.destinationChainId);
            (0, assert_1.default)(fill.relayer.isValidOn(fill.destinationChainId), `Cannot re-assign fill to msg.sender: ${destinationRelayer}`);
        }
        else {
            return undefined;
        }
    }
    fill.repaymentChainId = repaymentChainId;
    return fill;
}
function _getRepaymentChainId(relayData, hubPoolClient, bundleEndBlockForMainnet) {
    if (relayData.fromLiteChain) {
        (0, assert_1.default)(!(0, utils_1.isSlowFill)(relayData), "getRepaymentChainId: fromLiteChain and slow fill are mutually exclusive");
        return relayData.originChainId;
    }
    if ((0, utils_1.isSlowFill)(relayData)) {
        return relayData.destinationChainId;
    }
    const repaymentTokenIsValid = _repaymentChainTokenIsValid(relayData, hubPoolClient, bundleEndBlockForMainnet);
    const repaymentChainIsValid = !hubPoolClient.configStoreClient
        .getDisabledChainsForBlock(bundleEndBlockForMainnet)
        .includes(relayData.repaymentChainId);
    if (repaymentTokenIsValid && repaymentChainIsValid) {
        return relayData.repaymentChainId;
    }
    return relayData.originChainId;
}
function _repaymentChainTokenIsValid(relayData, hubPoolClient, bundleEndBlockForMainnet) {
    if (!hubPoolClient.l2TokenHasPoolRebalanceRoute(relayData.inputToken, relayData.originChainId, bundleEndBlockForMainnet)) {
        return false;
    }
    const l1TokenCounterpart = hubPoolClient.getL1TokenForL2TokenAtBlock(relayData.inputToken, relayData.originChainId, bundleEndBlockForMainnet);
    if (!l1TokenCounterpart) {
        return false;
    }
    if (!hubPoolClient.l2TokenEnabledForL1TokenAtBlock(l1TokenCounterpart, relayData.repaymentChainId, bundleEndBlockForMainnet)) {
        return false;
    }
    return true;
}
function _repaymentAddressNeedsToBeOverwritten(fill) {
    if ((0, utils_1.isSlowFill)(fill)) {
        return false;
    }
    return !fill.relayer.isValidOn(fill.repaymentChainId);
}
//# sourceMappingURL=FillUtils.js.map